blob: 8c97b1f407ff5e9c1ca1d3ea3b8dc5d600f4b34f [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Flavio Castro96646c62015-11-16 15:05:43 -050017"""
18
19A set of inter-test utility functions for dealing with OF-DPA
20
21
22"""
23
Flavio Castrob01d0aa2016-07-20 16:14:48 -070024import logging, subprocess, time
Flavio Castro96646c62015-11-16 15:05:43 -050025import ofp
26
27from oftest import config
28from oftest.testutils import *
29
Flavio Castrob01d0aa2016-07-20 16:14:48 -070030def forceOfdpaRestart( user ):
31 output = 1;
32 credential = user;
33 test = subprocess.Popen(["ssh", credential, "service ofdpa restart &> /dev/null"]);
34 time.sleep(1);
35 while output < 10:
36 output = int(subprocess.check_output(["ssh", credential, "client_cfg_purge | wc -l"]));
37 time.sleep(1);
38 subprocess.Popen(["ssh", credential, "brcm-indigo-ofdpa-ofagent -t 10.128.0.220 &> /dev/null"], stdout=subprocess.PIPE);
39
40def forceOfdpaStop( user ):
41 subprocess.Popen(["ssh", user, "ps ax | grep 'brcm-indigo-ofdpa-ofagent' | awk '{print $1}' | xargs sudo kill"], stdout=subprocess.PIPE);
Flavio Castro96646c62015-11-16 15:05:43 -050042
43
44class table(object):
45 """ Metadata on each OFDPA table """
46 def __init__(self, table_id, table_name):
47 self.table_id = table_id
48 self.table_name = table_name
49 # TODO consider adding type checking verification here
50
51INGRESS_TABLE = table(0, "Ingress")
52VLAN_TABLE = table(10, "VLAN")
53MACTERM_TABLE = table(20, "MacTerm")
54UNICAST_ROUTING_TABLE = table(30, "Unicast Routing")
55MULTICAST_ROUTING_TABLE = table(40, "Multicast Routing")
56BRIDGING_TABLE = table(50, "Bridging Table")
57ACL_TABLE = table(60, "ACL Policy Table")
58#.... FIXME add all tables
59
60DEFAULT_VLAN = 1
61
62def enableVlanOnPort(controller, vlan, port=ofp.OFPP_ALL, priority=0):
63 if port == ofp.OFPP_ALL:
64 ports = sorted(config["port_map"].keys())
65 else:
66 ports = [port]
67 for port in ports:
68 tagged_match = ofp.match([
69 ofp.oxm.in_port(port),
70 ofp.oxm.vlan_vid(vlan | ofp.OFPVID_PRESENT)
71 ])
72
73 request = ofp.message.flow_add(
74 table_id = VLAN_TABLE.table_id,
75 cookie = 0xdead,
76 match = tagged_match,
77 instructions = [
78 ofp.instruction.goto_table(MACTERM_TABLE.table_id),
79# ofp.instruction.apply_actions(
80# actions=[
81# ofp.action.push_vlan(ethertype=0x8100), # DO NOT PUT THIS FOR OF-DPA 2.0 EA1 - seems to not matter for EA2
82# ofp.action.set_field(ofp.oxm.vlan_vid( ofp.OFPVID_PRESENT | vlan))
83# ]),
84 ],
85 buffer_id = ofp.OFP_NO_BUFFER,
86 priority = priority)
87
88 logging.info("Inserting vlan rule allowing tagged vlan %d on port %d" % (vlan, port))
89 controller.message_send(request)
90 do_barrier(controller)
91 verify_no_errors(controller)
92
93
94def installDefaultVlan(controller, vlan=DEFAULT_VLAN, port=ofp.OFPP_ALL, priority=0):
95 """ Insert a rule that maps all untagged traffic to vlan $vlan
96
97 In OFDPA, table 10 (the vlan table) requires that all traffic be
98 mapped to an internal vlan else the packets be dropped. This function
99 sets up a default vlan mapping all untagged traffic to an internal VLAN.
100
101 With OF-DPA, before you can insert a 'untagged to X' rule on a
102 port, you must first insert a 'X --> X' rule for the same port.
103
104 Further, the 'X --> X' rule must set ofp.OFPVID_PRESENT even
105 though 'X' is non-zero.
106
107 The 'controller' variable is self.controller from a test
108 """
109 # OFDPA seems to be dumb and wants each port set individually
110 # Can't set all ports by using OFPP_ALL
111 if port == ofp.OFPP_ALL:
112 ports = sorted(config["port_map"].keys())
113 else:
114 ports = [port]
115
116 for port in ports:
117 # enable this vlan on this port before we can map untagged packets to the vlan
118 enableVlanOnPort(controller, vlan, port)
119
120 untagged_match = ofp.match([
121 ofp.oxm.in_port(port),
122 # OFDPA 2.0 says untagged is vlan_id=0, mask=ofp.OFPVID_PRESENT
123 ofp.oxm.vlan_vid_masked(0,ofp.OFPVID_PRESENT) # WTF OFDPA 2.0EA2 -- really!?
124 ])
125
126 request = ofp.message.flow_add(
127 table_id = VLAN_TABLE.table_id,
128 cookie = 0xbeef,
129 match = untagged_match,
130 instructions = [
131 ofp.instruction.apply_actions(
132 actions=[
133 #ofp.action.push_vlan(ethertype=0x8100),
134 ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan))
135 ]),
136 ofp.instruction.goto_table(MACTERM_TABLE.table_id)
137 ],
138 buffer_id = ofp.OFP_NO_BUFFER,
139 priority = priority)
140
141 logging.info("Inserting default vlan sending all untagged traffic to vlan %d on port %d" % (vlan, port))
142 controller.message_send(request)
143 do_barrier(controller)
144 verify_no_errors(controller)
145
146
147_group_types = {
148 "L2 Interface": 0,
149 "L2 Rewrite" : 1,
150 "L3 Unicast" : 2,
151 "L2 Multicast" : 3,
152 "L2 Flood" : 4,
153 "L3 Interface" : 5,
154 "L3 Multicast": 6,
155 "L3 ECMP": 7,
156 "L2 Data Center Overlay": 8,
157 "MPLS Label" : 9,
158 "MPLS Forwarding" :10,
159 "L2 Unfiltered Interface": 11,
160 "L2 Loopback": 12,
161}
162
163
164def makeGroupID(groupType, local_id):
165 """ Group IDs in OF-DPA have rich meaning
166
167 @param groupType is a key in _group_types
168 @param local_id is an integer 0<= local_id < 2**27,
169 but it may have more semantic meaning depending on the
170 groupType
171
172
173 Read Section 4.3 of the OF-DPA manual on groups for
174 details
175 """
176 if groupType not in _group_types:
177 raise KeyError("%s not a valid OF-DPA group type" % groupType)
178 if local_id < 0 or local_id >=134217728:
179 raise ValueError("local_id %d must be 0<= local_id < 2**27" % local_id)
180 return (_group_types[groupType] << 28) + local_id
181
182
183def delete_all_recursive_groups(controller):
184 pass