blob: 4fa4d0a3321d53adeacd1dfd8288db0df63cb235 [file] [log] [blame]
Flavio Castro96646c62015-11-16 15:05:43 -05001"""
2
3A set of inter-test utility functions for dealing with OF-DPA
4
5
6"""
7
8import logging
9import ofp
10
11from oftest import config
12from oftest.testutils import *
13
14
15
16class table(object):
17 """ Metadata on each OFDPA table """
18 def __init__(self, table_id, table_name):
19 self.table_id = table_id
20 self.table_name = table_name
21 # TODO consider adding type checking verification here
22
23INGRESS_TABLE = table(0, "Ingress")
24VLAN_TABLE = table(10, "VLAN")
25MACTERM_TABLE = table(20, "MacTerm")
26UNICAST_ROUTING_TABLE = table(30, "Unicast Routing")
27MULTICAST_ROUTING_TABLE = table(40, "Multicast Routing")
28BRIDGING_TABLE = table(50, "Bridging Table")
29ACL_TABLE = table(60, "ACL Policy Table")
30#.... FIXME add all tables
31
32DEFAULT_VLAN = 1
33
34def enableVlanOnPort(controller, vlan, port=ofp.OFPP_ALL, priority=0):
35 if port == ofp.OFPP_ALL:
36 ports = sorted(config["port_map"].keys())
37 else:
38 ports = [port]
39 for port in ports:
40 tagged_match = ofp.match([
41 ofp.oxm.in_port(port),
42 ofp.oxm.vlan_vid(vlan | ofp.OFPVID_PRESENT)
43 ])
44
45 request = ofp.message.flow_add(
46 table_id = VLAN_TABLE.table_id,
47 cookie = 0xdead,
48 match = tagged_match,
49 instructions = [
50 ofp.instruction.goto_table(MACTERM_TABLE.table_id),
51# ofp.instruction.apply_actions(
52# actions=[
53# ofp.action.push_vlan(ethertype=0x8100), # DO NOT PUT THIS FOR OF-DPA 2.0 EA1 - seems to not matter for EA2
54# ofp.action.set_field(ofp.oxm.vlan_vid( ofp.OFPVID_PRESENT | vlan))
55# ]),
56 ],
57 buffer_id = ofp.OFP_NO_BUFFER,
58 priority = priority)
59
60 logging.info("Inserting vlan rule allowing tagged vlan %d on port %d" % (vlan, port))
61 controller.message_send(request)
62 do_barrier(controller)
63 verify_no_errors(controller)
64
65
66def installDefaultVlan(controller, vlan=DEFAULT_VLAN, port=ofp.OFPP_ALL, priority=0):
67 """ Insert a rule that maps all untagged traffic to vlan $vlan
68
69 In OFDPA, table 10 (the vlan table) requires that all traffic be
70 mapped to an internal vlan else the packets be dropped. This function
71 sets up a default vlan mapping all untagged traffic to an internal VLAN.
72
73 With OF-DPA, before you can insert a 'untagged to X' rule on a
74 port, you must first insert a 'X --> X' rule for the same port.
75
76 Further, the 'X --> X' rule must set ofp.OFPVID_PRESENT even
77 though 'X' is non-zero.
78
79 The 'controller' variable is self.controller from a test
80 """
81 # OFDPA seems to be dumb and wants each port set individually
82 # Can't set all ports by using OFPP_ALL
83 if port == ofp.OFPP_ALL:
84 ports = sorted(config["port_map"].keys())
85 else:
86 ports = [port]
87
88 for port in ports:
89 # enable this vlan on this port before we can map untagged packets to the vlan
90 enableVlanOnPort(controller, vlan, port)
91
92 untagged_match = ofp.match([
93 ofp.oxm.in_port(port),
94 # OFDPA 2.0 says untagged is vlan_id=0, mask=ofp.OFPVID_PRESENT
95 ofp.oxm.vlan_vid_masked(0,ofp.OFPVID_PRESENT) # WTF OFDPA 2.0EA2 -- really!?
96 ])
97
98 request = ofp.message.flow_add(
99 table_id = VLAN_TABLE.table_id,
100 cookie = 0xbeef,
101 match = untagged_match,
102 instructions = [
103 ofp.instruction.apply_actions(
104 actions=[
105 #ofp.action.push_vlan(ethertype=0x8100),
106 ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan))
107 ]),
108 ofp.instruction.goto_table(MACTERM_TABLE.table_id)
109 ],
110 buffer_id = ofp.OFP_NO_BUFFER,
111 priority = priority)
112
113 logging.info("Inserting default vlan sending all untagged traffic to vlan %d on port %d" % (vlan, port))
114 controller.message_send(request)
115 do_barrier(controller)
116 verify_no_errors(controller)
117
118
119_group_types = {
120 "L2 Interface": 0,
121 "L2 Rewrite" : 1,
122 "L3 Unicast" : 2,
123 "L2 Multicast" : 3,
124 "L2 Flood" : 4,
125 "L3 Interface" : 5,
126 "L3 Multicast": 6,
127 "L3 ECMP": 7,
128 "L2 Data Center Overlay": 8,
129 "MPLS Label" : 9,
130 "MPLS Forwarding" :10,
131 "L2 Unfiltered Interface": 11,
132 "L2 Loopback": 12,
133}
134
135
136def makeGroupID(groupType, local_id):
137 """ Group IDs in OF-DPA have rich meaning
138
139 @param groupType is a key in _group_types
140 @param local_id is an integer 0<= local_id < 2**27,
141 but it may have more semantic meaning depending on the
142 groupType
143
144
145 Read Section 4.3 of the OF-DPA manual on groups for
146 details
147 """
148 if groupType not in _group_types:
149 raise KeyError("%s not a valid OF-DPA group type" % groupType)
150 if local_id < 0 or local_id >=134217728:
151 raise ValueError("local_id %d must be 0<= local_id < 2**27" % local_id)
152 return (_group_types[groupType] << 28) + local_id
153
154
155def delete_all_recursive_groups(controller):
156 pass