blob: 693293b17342a925c0f1b0cf39676396965b4c11 [file] [log] [blame]
Dan Talayco5eba8442010-03-10 13:58:43 -08001"""
2Test cases for testing actions taken on packets
3
4See basic.py for other info.
5
6It is recommended that these definitions be kept in their own
7namespace as different groups of tests will likely define
8similar identifiers.
9
10 The function test_set_init is called with a complete configuration
11dictionary prior to the invocation of any tests from this file.
12
13 The switch is actively attempting to contact the controller at the address
14indicated oin oft_config
15
16"""
17
Dan Talayco9f47f4d2010-06-03 13:54:37 -070018import copy
19
Dan Talayco5eba8442010-03-10 13:58:43 -080020import logging
21
22import unittest
23
24import oftest.controller as controller
25import oftest.cstruct as ofp
26import oftest.message as message
27import oftest.dataplane as dataplane
28import oftest.action as action
29import oftest.parse as parse
30import basic
Dan Talayco8a64e332012-03-28 14:53:20 -070031import time
Dan Talayco5eba8442010-03-10 13:58:43 -080032
33from testutils import *
34
35#@var port_map Local copy of the configuration map from OF port
36# numbers to OS interfaces
37pa_port_map = None
38#@var pa_logger Local logger object
39pa_logger = None
40#@var pa_config Local copy of global configuration data
41pa_config = None
42
Dan Talayco551befa2010-07-15 17:05:32 -070043# For test priority
44#@var test_prio Set test priority for local tests
45test_prio = {}
46
47WILDCARD_VALUES = [ofp.OFPFW_IN_PORT,
48 ofp.OFPFW_DL_VLAN,
49 ofp.OFPFW_DL_SRC,
50 ofp.OFPFW_DL_DST,
51 ofp.OFPFW_DL_TYPE,
52 ofp.OFPFW_NW_PROTO,
53 ofp.OFPFW_TP_SRC,
54 ofp.OFPFW_TP_DST,
55 0x3F << ofp.OFPFW_NW_SRC_SHIFT,
56 0x3F << ofp.OFPFW_NW_DST_SHIFT,
57 ofp.OFPFW_DL_VLAN_PCP,
58 ofp.OFPFW_NW_TOS]
59
60MODIFY_ACTION_VALUES = [ofp.OFPAT_SET_VLAN_VID,
61 ofp.OFPAT_SET_VLAN_PCP,
62 ofp.OFPAT_STRIP_VLAN,
63 ofp.OFPAT_SET_DL_SRC,
64 ofp.OFPAT_SET_DL_DST,
65 ofp.OFPAT_SET_NW_SRC,
66 ofp.OFPAT_SET_NW_DST,
67 ofp.OFPAT_SET_NW_TOS,
68 ofp.OFPAT_SET_TP_SRC,
69 ofp.OFPAT_SET_TP_DST]
70
71# Cache supported features to avoid transaction overhead
72cached_supported_actions = None
73
Dan Talayco21381562010-07-17 00:34:47 -070074TEST_VID_DEFAULT = 2
75
Dan Talayco5eba8442010-03-10 13:58:43 -080076def test_set_init(config):
77 """
78 Set up function for packet action test classes
79
80 @param config The configuration dictionary; see oft
81 """
82
Ed Swierk89f78352012-03-29 12:32:32 -070083 basic.test_set_init(config)
84
Dan Talayco5eba8442010-03-10 13:58:43 -080085 global pa_port_map
86 global pa_logger
87 global pa_config
88
89 pa_logger = logging.getLogger("pkt_act")
90 pa_logger.info("Initializing test set")
91 pa_port_map = config["port_map"]
92 pa_config = config
93
94class DirectPacket(basic.SimpleDataPlane):
95 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -070096 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -080097
98 Generate a packet
99 Generate and install a matching flow
100 Add action to direct the packet to an egress port
101 Send the packet to ingress dataplane port
102 Verify the packet is received at the egress port only
103 """
104 def runTest(self):
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700105 self.handleFlow()
106
107 def handleFlow(self, pkttype='TCP'):
Dan Talayco5eba8442010-03-10 13:58:43 -0800108 of_ports = pa_port_map.keys()
109 of_ports.sort()
110 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
111
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700112 if (pkttype == 'ICMP'):
113 pkt = simple_icmp_packet()
114 else:
115 pkt = simple_tcp_packet()
Dan Talayco5eba8442010-03-10 13:58:43 -0800116 match = parse.packet_to_flow_match(pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -0700117 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -0800118 self.assertTrue(match is not None,
119 "Could not generate flow match from pkt")
120 act = action.action_output()
121
122 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700123 rv = delete_all_flows(self.controller, pa_logger)
124 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700125
Dan Talayco5eba8442010-03-10 13:58:43 -0800126 ingress_port = of_ports[idx]
127 egress_port = of_ports[(idx + 1) % len(of_ports)]
128 pa_logger.info("Ingress " + str(ingress_port) +
Dan Talayco551befa2010-07-15 17:05:32 -0700129 " to egress " + str(egress_port))
Dan Talayco5eba8442010-03-10 13:58:43 -0800130
131 match.in_port = ingress_port
132
133 request = message.flow_mod()
134 request.match = match
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700135
Dan Talayco5eba8442010-03-10 13:58:43 -0800136 request.buffer_id = 0xffffffff
137 act.port = egress_port
138 self.assertTrue(request.actions.add(act), "Could not add action")
139
140 pa_logger.info("Inserting flow")
141 rv = self.controller.message_send(request)
142 self.assertTrue(rv != -1, "Error installing flow mod")
143 do_barrier(self.controller)
144
145 pa_logger.info("Sending packet to dp port " +
146 str(ingress_port))
147 self.dataplane.send(ingress_port, str(pkt))
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700148
149 exp_pkt_arg = None
150 exp_port = None
151 if pa_config["relax"]:
152 exp_pkt_arg = pkt
153 exp_port = egress_port
154
155 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1,
156 port_number=exp_port,
157 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800158 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700159 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800160 str(rcv_port))
161 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
162 self.assertEqual(str(pkt), str(rcv_pkt),
163 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700164
165class DirectPacketICMP(DirectPacket):
166 """
167 Send ICMP packet to single egress port
168
169 Generate a ICMP packet
170 Generate and install a matching flow
171 Add action to direct the packet to an egress port
172 Send the packet to ingress dataplane port
173 Verify the packet is received at the egress port only
174 Difference from DirectPacket test is that sent packet is ICMP
175 """
176 def runTest(self):
177 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700178
179class DirectTwoPorts(basic.SimpleDataPlane):
180 """
181 Send packet to two egress ports
182
183 Generate a packet
184 Generate and install a matching flow
185 Add action to direct the packet to two egress ports
186 Send the packet to ingress dataplane port
187 Verify the packet is received at the two egress ports
188 """
189 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700190 of_ports = pa_port_map.keys()
191 of_ports.sort()
192 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
193
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700194 pkt = simple_tcp_packet()
195 match = parse.packet_to_flow_match(pkt)
196 match.wildcards &= ~ofp.OFPFW_IN_PORT
197 self.assertTrue(match is not None,
198 "Could not generate flow match from pkt")
199 act = action.action_output()
200
201 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700202 rv = delete_all_flows(self.controller, pa_logger)
203 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700204
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700205 ingress_port = of_ports[idx]
206 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
207 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
208 pa_logger.info("Ingress " + str(ingress_port) +
209 " to egress " + str(egress_port1) + " and " +
210 str(egress_port2))
211
212 match.in_port = ingress_port
213
214 request = message.flow_mod()
215 request.match = match
216 request.buffer_id = 0xffffffff
217 act.port = egress_port1
218 self.assertTrue(request.actions.add(act), "Could not add action1")
219 act.port = egress_port2
220 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700221 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700222
223 pa_logger.info("Inserting flow")
224 rv = self.controller.message_send(request)
225 self.assertTrue(rv != -1, "Error installing flow mod")
226 do_barrier(self.controller)
227
228 pa_logger.info("Sending packet to dp port " +
229 str(ingress_port))
230 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700231 yes_ports = set([egress_port1, egress_port2])
232 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700233
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700234 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700235 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700236
237class DirectMCNonIngress(basic.SimpleDataPlane):
238 """
239 Multicast to all non-ingress ports
240
241 Generate a packet
242 Generate and install a matching flow
243 Add action to direct the packet to all non-ingress ports
244 Send the packet to ingress dataplane port
245 Verify the packet is received at all non-ingress ports
246
247 Does not use the flood action
248 """
249 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700250 of_ports = pa_port_map.keys()
251 of_ports.sort()
252 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
253
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700254 pkt = simple_tcp_packet()
255 match = parse.packet_to_flow_match(pkt)
256 match.wildcards &= ~ofp.OFPFW_IN_PORT
257 self.assertTrue(match is not None,
258 "Could not generate flow match from pkt")
259 act = action.action_output()
260
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700261 for ingress_port in of_ports:
262 rv = delete_all_flows(self.controller, pa_logger)
263 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700264
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700265 pa_logger.info("Ingress " + str(ingress_port) +
266 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700267 match.in_port = ingress_port
268
269 request = message.flow_mod()
270 request.match = match
271 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700272 for egress_port in of_ports:
273 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700274 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700275 act.port = egress_port
276 self.assertTrue(request.actions.add(act),
277 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700278 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700279
280 pa_logger.info("Inserting flow")
281 rv = self.controller.message_send(request)
282 self.assertTrue(rv != -1, "Error installing flow mod")
283 do_barrier(self.controller)
284
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700285 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700286 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700287 yes_ports = set(of_ports).difference([ingress_port])
288 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700289 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700290
Dan Talayco32fa6542010-05-11 15:54:08 -0700291
292class DirectMC(basic.SimpleDataPlane):
293 """
294 Multicast to all ports including ingress
295
296 Generate a packet
297 Generate and install a matching flow
298 Add action to direct the packet to all non-ingress ports
299 Send the packet to ingress dataplane port
300 Verify the packet is received at all ports
301
302 Does not use the flood action
303 """
304 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700305 of_ports = pa_port_map.keys()
306 of_ports.sort()
307 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
308
Dan Talayco32fa6542010-05-11 15:54:08 -0700309 pkt = simple_tcp_packet()
310 match = parse.packet_to_flow_match(pkt)
311 match.wildcards &= ~ofp.OFPFW_IN_PORT
312 self.assertTrue(match is not None,
313 "Could not generate flow match from pkt")
314 act = action.action_output()
315
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700316 for ingress_port in of_ports:
317 rv = delete_all_flows(self.controller, pa_logger)
318 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700319
Dan Talayco32fa6542010-05-11 15:54:08 -0700320 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700321 match.in_port = ingress_port
322
323 request = message.flow_mod()
324 request.match = match
325 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700326 for egress_port in of_ports:
327 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700328 act.port = ofp.OFPP_IN_PORT
329 else:
330 act.port = egress_port
331 self.assertTrue(request.actions.add(act),
332 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700333 # pa_logger.info(request.show())
334
335 pa_logger.info("Inserting flow")
336 rv = self.controller.message_send(request)
337 self.assertTrue(rv != -1, "Error installing flow mod")
338 do_barrier(self.controller)
339
340 pa_logger.info("Sending packet to dp port " + str(ingress_port))
341 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700342 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700343 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700344
345class Flood(basic.SimpleDataPlane):
346 """
347 Flood to all ports except ingress
348
349 Generate a packet
350 Generate and install a matching flow
351 Add action to flood the packet
352 Send the packet to ingress dataplane port
353 Verify the packet is received at all other ports
354 """
355 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700356 of_ports = pa_port_map.keys()
357 of_ports.sort()
358 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
359
360 pkt = simple_tcp_packet()
361 match = parse.packet_to_flow_match(pkt)
362 match.wildcards &= ~ofp.OFPFW_IN_PORT
363 self.assertTrue(match is not None,
364 "Could not generate flow match from pkt")
365 act = action.action_output()
366
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700367 for ingress_port in of_ports:
368 rv = delete_all_flows(self.controller, pa_logger)
369 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700370
Dan Talayco2e77a842010-05-12 15:39:46 -0700371 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700372 match.in_port = ingress_port
373
374 request = message.flow_mod()
375 request.match = match
376 request.buffer_id = 0xffffffff
377 act.port = ofp.OFPP_FLOOD
378 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700379 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700380 pa_logger.info(request.show())
381
382 pa_logger.info("Inserting flow")
383 rv = self.controller.message_send(request)
384 self.assertTrue(rv != -1, "Error installing flow mod")
385 do_barrier(self.controller)
386
387 pa_logger.info("Sending packet to dp port " + str(ingress_port))
388 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700389 yes_ports = set(of_ports).difference([ingress_port])
390 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700391 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700392
Dan Talayco3be5b062010-05-12 15:46:21 -0700393class FloodPlusIngress(basic.SimpleDataPlane):
394 """
395 Flood to all ports plus send to ingress port
396
397 Generate a packet
398 Generate and install a matching flow
399 Add action to flood the packet
400 Add action to send to ingress port
401 Send the packet to ingress dataplane port
402 Verify the packet is received at all other ports
403 """
404 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700405 of_ports = pa_port_map.keys()
406 of_ports.sort()
407 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
408
409 pkt = simple_tcp_packet()
410 match = parse.packet_to_flow_match(pkt)
411 match.wildcards &= ~ofp.OFPFW_IN_PORT
412 self.assertTrue(match is not None,
413 "Could not generate flow match from pkt")
414 act = action.action_output()
415
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700416 for ingress_port in of_ports:
417 rv = delete_all_flows(self.controller, pa_logger)
418 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700419
Dan Talayco3be5b062010-05-12 15:46:21 -0700420 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700421 match.in_port = ingress_port
422
423 request = message.flow_mod()
424 request.match = match
425 request.buffer_id = 0xffffffff
426 act.port = ofp.OFPP_FLOOD
427 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700428 "Could not add flood port action")
429 act.port = ofp.OFPP_IN_PORT
430 self.assertTrue(request.actions.add(act),
431 "Could not add ingress port for output")
432 pa_logger.info(request.show())
433
434 pa_logger.info("Inserting flow")
435 rv = self.controller.message_send(request)
436 self.assertTrue(rv != -1, "Error installing flow mod")
437 do_barrier(self.controller)
438
439 pa_logger.info("Sending packet to dp port " + str(ingress_port))
440 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700441 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700442 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700443
444class All(basic.SimpleDataPlane):
445 """
446 Send to OFPP_ALL port
447
448 Generate a packet
449 Generate and install a matching flow
450 Add action to forward to OFPP_ALL
451 Send the packet to ingress dataplane port
452 Verify the packet is received at all other ports
453 """
454 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700455 of_ports = pa_port_map.keys()
456 of_ports.sort()
457 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
458
459 pkt = simple_tcp_packet()
460 match = parse.packet_to_flow_match(pkt)
461 match.wildcards &= ~ofp.OFPFW_IN_PORT
462 self.assertTrue(match is not None,
463 "Could not generate flow match from pkt")
464 act = action.action_output()
465
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700466 for ingress_port in of_ports:
467 rv = delete_all_flows(self.controller, pa_logger)
468 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700469
Dan Talayco4aa13122010-05-12 15:54:44 -0700470 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700471 match.in_port = ingress_port
472
473 request = message.flow_mod()
474 request.match = match
475 request.buffer_id = 0xffffffff
476 act.port = ofp.OFPP_ALL
477 self.assertTrue(request.actions.add(act),
478 "Could not add ALL port action")
479 pa_logger.info(request.show())
480
481 pa_logger.info("Inserting flow")
482 rv = self.controller.message_send(request)
483 self.assertTrue(rv != -1, "Error installing flow mod")
484 do_barrier(self.controller)
485
486 pa_logger.info("Sending packet to dp port " + str(ingress_port))
487 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700488 yes_ports = set(of_ports).difference([ingress_port])
489 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700490 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700491
492class AllPlusIngress(basic.SimpleDataPlane):
493 """
494 Send to OFPP_ALL port and ingress port
495
496 Generate a packet
497 Generate and install a matching flow
498 Add action to forward to OFPP_ALL
499 Add action to forward to ingress port
500 Send the packet to ingress dataplane port
501 Verify the packet is received at all other ports
502 """
503 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700504 of_ports = pa_port_map.keys()
505 of_ports.sort()
506 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
507
508 pkt = simple_tcp_packet()
509 match = parse.packet_to_flow_match(pkt)
510 match.wildcards &= ~ofp.OFPFW_IN_PORT
511 self.assertTrue(match is not None,
512 "Could not generate flow match from pkt")
513 act = action.action_output()
514
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700515 for ingress_port in of_ports:
516 rv = delete_all_flows(self.controller, pa_logger)
517 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700518
Dan Talayco4aa13122010-05-12 15:54:44 -0700519 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700520 match.in_port = ingress_port
521
522 request = message.flow_mod()
523 request.match = match
524 request.buffer_id = 0xffffffff
525 act.port = ofp.OFPP_ALL
526 self.assertTrue(request.actions.add(act),
527 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700528 act.port = ofp.OFPP_IN_PORT
529 self.assertTrue(request.actions.add(act),
530 "Could not add ingress port for output")
531 pa_logger.info(request.show())
532
533 pa_logger.info("Inserting flow")
534 rv = self.controller.message_send(request)
535 self.assertTrue(rv != -1, "Error installing flow mod")
536 do_barrier(self.controller)
537
538 pa_logger.info("Sending packet to dp port " + str(ingress_port))
539 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700540 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700541 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700542
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700543class FloodMinusPort(basic.SimpleDataPlane):
544 """
545 Config port with No_Flood and test Flood action
546
547 Generate a packet
548 Generate a matching flow
549 Add action to forward to OFPP_ALL
550 Set port to no-flood
551 Send the packet to ingress dataplane port
552 Verify the packet is received at all other ports except
553 the ingress port and the no_flood port
554 """
555 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700556 of_ports = pa_port_map.keys()
557 of_ports.sort()
558 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
559
560 pkt = simple_tcp_packet()
561 match = parse.packet_to_flow_match(pkt)
562 match.wildcards &= ~ofp.OFPFW_IN_PORT
563 self.assertTrue(match is not None,
564 "Could not generate flow match from pkt")
565 act = action.action_output()
566
567 for idx in range(len(of_ports)):
568 rv = delete_all_flows(self.controller, pa_logger)
569 self.assertEqual(rv, 0, "Failed to delete all flows")
570
571 ingress_port = of_ports[idx]
572 no_flood_idx = (idx + 1) % len(of_ports)
573 no_flood_port = of_ports[no_flood_idx]
574 rv = port_config_set(self.controller, no_flood_port,
575 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
576 pa_logger)
577 self.assertEqual(rv, 0, "Failed to set port config")
578
579 match.in_port = ingress_port
580
581 request = message.flow_mod()
582 request.match = match
583 request.buffer_id = 0xffffffff
584 act.port = ofp.OFPP_FLOOD
585 self.assertTrue(request.actions.add(act),
586 "Could not add flood port action")
587 pa_logger.info(request.show())
588
589 pa_logger.info("Inserting flow")
590 rv = self.controller.message_send(request)
591 self.assertTrue(rv != -1, "Error installing flow mod")
592 do_barrier(self.controller)
593
594 pa_logger.info("Sending packet to dp port " + str(ingress_port))
595 pa_logger.info("No flood port is " + str(no_flood_port))
596 self.dataplane.send(ingress_port, str(pkt))
597 no_ports = set([ingress_port, no_flood_port])
598 yes_ports = set(of_ports).difference(no_ports)
599 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700600 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700601
602 # Turn no flood off again
603 rv = port_config_set(self.controller, no_flood_port,
604 0, ofp.OFPPC_NO_FLOOD, pa_logger)
605 self.assertEqual(rv, 0, "Failed to reset port config")
606
607 #@todo Should check no other packets received
608
Dan Talayco21381562010-07-17 00:34:47 -0700609
610
Dan Talayco551befa2010-07-15 17:05:32 -0700611################################################################
612
613class BaseMatchCase(basic.SimpleDataPlane):
614 def setUp(self):
615 basic.SimpleDataPlane.setUp(self)
616 self.logger = pa_logger
617 def runTest(self):
618 self.logger.info("BaseMatchCase")
619
620class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700621 """
Dan Talayco551befa2010-07-15 17:05:32 -0700622 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700623
624 Generate a packet
625 Generate and install a matching flow without wildcard mask
626 Add action to forward to a port
627 Send the packet to the port
628 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700629 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700630
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700631 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700632 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700633
Dan Talayco551befa2010-07-15 17:05:32 -0700634class ExactMatchTagged(BaseMatchCase):
635 """
636 Exact match for all port pairs with tagged pkts
637 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700638
Dan Talayco551befa2010-07-15 17:05:32 -0700639 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700640 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700641 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700642
Dan Talayco551befa2010-07-15 17:05:32 -0700643class ExactMatchTaggedMany(BaseMatchCase):
644 """
645 ExactMatchTagged with many VLANS
646 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700647
Dan Talayco551befa2010-07-15 17:05:32 -0700648 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700649 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700650 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
651 for vid in range(100,4000,389):
652 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
653 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700654
Dan Talayco551befa2010-07-15 17:05:32 -0700655# Don't run by default
656test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700657
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700658
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700659class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700660 """
661 SingleWildcardMatchPriority
662 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700663
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700664 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700665 self.pkt = simple_tcp_packet()
666 self.flowMsgs = {}
667
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700668 def _ClearTable(self):
669 rc = delete_all_flows(self.controller, self.logger)
670 self.assertEqual(rc, 0, "Failed to delete all flows")
671 do_barrier(self.controller)
672
673 def runTest(self):
674
675 self._Init()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700676 of_ports = pa_port_map.keys()
677 of_ports.sort()
678
679 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700680 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700681
682 # Run several combinations, each at lower priority settings.
683 # At the end of each call to runPrioFlows(), the table should
684 # be empty. If its not, we'll catch it as the priorities decreases
685 portA = of_ports[0]
686 portB = of_ports[1]
687 portC = of_ports[2]
688
689 # TODO -- these priority numbers should be validated somehow?
690 self.runPrioFlows(portA, portB, portC, 1000, 999)
691 self.runPrioFlows(portB, portC, portA, 998, 997)
692 self.runPrioFlows(portC, portA, portB, 996, 995)
693 self.runPrioFlows(portA, portC, portB, 994, 993)
694
695
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700696
697 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
698 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700699
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700700 if clearTable:
701 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700702
703 # Sanity check flow at lower priority from pA to pB
704 self.logger.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
705 % (portA, portB, portC, prioHigher, prioLower))
706
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700707 self.installFlow(prioHigher, portA, portC)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700708 self.installFlow(prioLower, portA, portB)
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700709
710 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700711 self.verifyFlow(portA, portB)
712 self.removeFlow(prioLower)
713 # Sanity check flow at lower priority from pA to pC
714 self.installFlow(prioLower, portA, portC)
715 self.verifyFlow(portA, portC)
716 self.removeFlow(prioLower)
717
718 # Install and verify pA->pB @ prioLower
719 self.installFlow(prioLower, portA, portB)
720 self.verifyFlow(portA, portB)
721
722 # Install and verify pA->pC @ prioHigher, should override pA->pB
723 self.installFlow(prioHigher, portA, portC)
724 self.verifyFlow(portA, portC)
725 # remove pA->pC
726 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700727 # Old flow pA -> pB @ prioLower should still be active
728 self.verifyFlow(portA, portB)
729 self.removeFlow(prioLower)
730
731 # Table should be empty at this point, leave it alone as
732 # an assumption for future test runs
733
734
735
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700736 def installFlow(self, prio, inp, egp):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700737 request = flow_msg_create(self, self.pkt, ing_port=inp,
738 wildcards=ofp.OFPFW_DL_SRC,
739 egr_ports=egp)
740 request.priority = prio
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700741 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700742 self.flowMsgs[prio] = request
743
744 def removeFlow(self, prio):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700745 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700746 if self.flowMsgs.has_key(prio):
747 msg = self.flowMsgs[prio]
748 msg.command = ofp.OFPFC_DELETE_STRICT
749 # This *must* be set for DELETE
750 msg.out_port = ofp.OFPP_NONE
751 self.controller.message_send(msg)
752 do_barrier(self.controller)
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700753 else:
754 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700755
756
757 def verifyFlow(self, inp, egp):
758 self.logger.info("Pkt match test: " + str(inp) +
759 " to " + str(egp))
760 self.logger.debug("Send packet: " + str(inp) + " to "
761 + str(egp))
762 self.dataplane.send(inp, str(self.pkt))
763 receive_pkt_verify(self, egp, self.pkt, inp)
764
765
766
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700767class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
768
769 def runTest(self):
770
771 self._Init()
772
773 of_ports = pa_port_map.keys()
774 of_ports.sort()
775
776 # Install an entry from 0 -> 1 @ prio 1000
777 self._ClearTable()
778 self.installFlow(1000, of_ports[0], of_ports[1])
779 self.verifyFlow(of_ports[0], of_ports[1])
780 self.installFlow(1000, of_ports[1], of_ports[0])
781 self.verifyFlow(of_ports[1], of_ports[0])
782 self.installFlow(1001, of_ports[0], of_ports[1])
783 self.verifyFlow(of_ports[0], of_ports[1])
784 self.installFlow(1001, of_ports[1], of_ports[0])
785 self.verifyFlow(of_ports[1], of_ports[0])
786 self.removeFlow(1001)
787 self.verifyFlow(of_ports[0], of_ports[1])
788 self.removeFlow(1000)
789
790
791
792
Dan Talayco551befa2010-07-15 17:05:32 -0700793class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700794 """
795 Exercise wildcard matching for all ports
796
797 Generate a packet
798 Generate and install a matching flow with wildcard mask
799 Add action to forward to a port
800 Send the packet to the port
801 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700802 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700803 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700804 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -0700805 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700806 for wc in WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -0700807 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -0700808 # Set nonzero VLAN id to avoid sending priority-tagged packet
809 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -0700810 else:
811 dl_vlan = -1
812 flow_match_test(self, pa_port_map, wildcards=wc,
813 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700814
Dan Talayco551befa2010-07-15 17:05:32 -0700815class SingleWildcardMatchTagged(BaseMatchCase):
816 """
817 SingleWildcardMatch with tagged packets
818 """
819 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700820 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700821 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -0700822 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -0700823 max_test=10)
824
825class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700826 """
Dan Talayco80b54ed2010-07-13 09:48:35 -0700827 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700828
829 Generate a packet
830 Generate and install a matching flow with wildcard all except one filed
831 Add action to forward to a port
832 Send the packet to the port
833 Verify the packet is received at all other ports (one port at a time)
834 Verify flow_expiration message is correct when command option is set
835 """
836 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -0700837 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700838 for wc in WILDCARD_VALUES:
839 all_exp_one_wildcard = ofp.OFPFW_ALL ^ wc
Dan Talayco4431d542012-03-21 16:42:16 -0700840 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -0700841 # Set nonzero VLAN id to avoid sending priority-tagged packet
842 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -0700843 else:
844 dl_vlan = -1
845 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
846 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -0700847
Dan Talayco551befa2010-07-15 17:05:32 -0700848class AllExceptOneWildcardMatchTagged(BaseMatchCase):
849 """
850 Match one field with tagged packets
851 """
852 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700853 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700854 for wc in WILDCARD_VALUES:
855 all_exp_one_wildcard = ofp.OFPFW_ALL ^ wc
Dan Talayco21381562010-07-17 00:34:47 -0700856 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
857 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -0700858
859class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -0700860 """
861 Create Wildcard-all flow and exercise for all ports
862
863 Generate a packet
864 Generate and install a matching flow with wildcard-all
865 Add action to forward to a port
866 Send the packet to the port
867 Verify the packet is received at all other ports (one port at a time)
868 Verify flow_expiration message is correct when command option is set
869 """
870 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700871 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700872
Dan Talayco551befa2010-07-15 17:05:32 -0700873class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700874 """
Dan Talayco551befa2010-07-15 17:05:32 -0700875 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700876 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700877 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700878 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700879 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
880 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700881
Dan Talaycoba3745c2010-07-21 21:51:08 -0700882
Dan Talayco551befa2010-07-15 17:05:32 -0700883class AddVLANTag(BaseMatchCase):
884 """
885 Add a VLAN tag to an untagged packet
886 """
887 def runTest(self):
888 new_vid = 2
889 sup_acts = supported_actions_get(self)
890 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700891 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -0700892 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -0700893
Dan Talayco551befa2010-07-15 17:05:32 -0700894 len = 100
895 len_w_vid = 104
896 pkt = simple_tcp_packet(pktlen=len)
897 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
898 dl_vlan=new_vid)
899 vid_act = action.action_set_vlan_vid()
900 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700901
Dan Talayco551befa2010-07-15 17:05:32 -0700902 flow_match_test(self, pa_port_map, pkt=pkt,
903 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700904
Dan Talayco551befa2010-07-15 17:05:32 -0700905class PacketOnly(basic.DataPlaneOnly):
906 """
907 Just send a packet thru the switch
908 """
909 def runTest(self):
910 pkt = simple_tcp_packet()
911 of_ports = pa_port_map.keys()
912 of_ports.sort()
913 ing_port = of_ports[0]
914 pa_logger.info("Sending packet to " + str(ing_port))
915 pa_logger.debug("Data: " + str(pkt).encode('hex'))
916 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700917
Dan Talayco551befa2010-07-15 17:05:32 -0700918class PacketOnlyTagged(basic.DataPlaneOnly):
919 """
920 Just send a packet thru the switch
921 """
922 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700923 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700924 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
925 of_ports = pa_port_map.keys()
926 of_ports.sort()
927 ing_port = of_ports[0]
928 pa_logger.info("Sending packet to " + str(ing_port))
929 pa_logger.debug("Data: " + str(pkt).encode('hex'))
930 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700931
Dan Talayco551befa2010-07-15 17:05:32 -0700932test_prio["PacketOnly"] = -1
933test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700934
Dan Talayco551befa2010-07-15 17:05:32 -0700935class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700936 """
937 Modify the VLAN ID in the VLAN tag of a tagged packet
938 """
Dan Talayco551befa2010-07-15 17:05:32 -0700939 def runTest(self):
940 old_vid = 2
941 new_vid = 3
942 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -0700943 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700944 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -0700945 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700946
Dan Talayco551befa2010-07-15 17:05:32 -0700947 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
948 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
949 vid_act = action.action_set_vlan_vid()
950 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700951
Dan Talayco551befa2010-07-15 17:05:32 -0700952 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
953 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700954
Dan Talayco551befa2010-07-15 17:05:32 -0700955class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700956 """
957 Strip the VLAN tag from a tagged packet
958 """
Dan Talayco551befa2010-07-15 17:05:32 -0700959 def runTest(self):
960 old_vid = 2
961 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -0700962 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700963 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -0700964 return
Dan Talaycof36f1082010-07-13 13:57:17 -0700965
Dan Talayco551befa2010-07-15 17:05:32 -0700966 len_w_vid = 104
967 len = 100
968 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
969 dl_vlan=old_vid)
970 exp_pkt = simple_tcp_packet(pktlen=len)
971 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700972
Dan Talayco551befa2010-07-15 17:05:32 -0700973 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
974 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700975
Dan Talayco4b2bee62010-07-20 14:10:05 -0700976def init_pkt_args():
977 """
978 Pass back a dictionary with default packet arguments
979 """
980 args = {}
981 args["dl_src"] = '00:23:45:67:89:AB'
982
983 dl_vlan_enable=False
984 dl_vlan=-1
985 if pa_config["test-params"]["vid"]:
986 dl_vlan_enable=True
987 dl_vlan = pa_config["test-params"]["vid"]
988
989# Unpack operator is ** on a dictionary
990
991 return args
992
Dan Talayco551befa2010-07-15 17:05:32 -0700993class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700994 """
995 Modify the source MAC address (TP1)
996 """
Dan Talayco551befa2010-07-15 17:05:32 -0700997 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700998 sup_acts = supported_actions_get(self)
999 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001000 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001001 return
1002
1003 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1004 check_test_params=True)
1005 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1006 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001007
Dan Talayco551befa2010-07-15 17:05:32 -07001008class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001009 """
1010 Modify the dest MAC address (TP1)
1011 """
Dan Talayco551befa2010-07-15 17:05:32 -07001012 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001013 sup_acts = supported_actions_get(self)
1014 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001015 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001016 return
1017
1018 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1019 check_test_params=True)
1020 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1021 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001022
Dan Talayco551befa2010-07-15 17:05:32 -07001023class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001024 """
1025 Modify the source IP address of an IP packet (TP1)
1026 """
Dan Talayco551befa2010-07-15 17:05:32 -07001027 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001028 sup_acts = supported_actions_get(self)
1029 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001030 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001031 return
1032
1033 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1034 check_test_params=True)
1035 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1036 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001037
Dan Talayco551befa2010-07-15 17:05:32 -07001038class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001039 """
1040 Modify the dest IP address of an IP packet (TP1)
1041 """
Dan Talayco551befa2010-07-15 17:05:32 -07001042 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001043 sup_acts = supported_actions_get(self)
1044 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001045 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001046 return
1047
1048 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1049 check_test_params=True)
1050 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1051 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001052
1053class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001054 """
1055 Modify the source TCP port of a TCP packet (TP1)
1056 """
Dan Talayco551befa2010-07-15 17:05:32 -07001057 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001058 sup_acts = supported_actions_get(self)
1059 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001060 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001061 return
1062
1063 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1064 check_test_params=True)
1065 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1066 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001067
1068class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001069 """
1070 Modify the dest TCP port of a TCP packet (TP1)
1071 """
Dan Talayco551befa2010-07-15 17:05:32 -07001072 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001073 sup_acts = supported_actions_get(self)
1074 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001075 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001076 return
1077
1078 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1079 check_test_params=True)
1080 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1081 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001082
1083class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001084 """
1085 Modify the IP type of service of an IP packet (TP1)
1086 """
Dan Talayco551befa2010-07-15 17:05:32 -07001087 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001088 sup_acts = supported_actions_get(self)
1089 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001090 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001091 return
Dan Talayco551befa2010-07-15 17:05:32 -07001092
Dan Talayco4b2bee62010-07-20 14:10:05 -07001093 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1094 check_test_params=True)
1095 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001096 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001097
Dan Talaycof6e76c02012-03-23 10:56:12 -07001098class ModifyL2DstMC(BaseMatchCase):
1099 """
1100 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001101 """
1102 def runTest(self):
1103 sup_acts = supported_actions_get(self)
1104 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001105 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001106 return
1107
Dan Talaycof6e76c02012-03-23 10:56:12 -07001108 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1109 check_test_params=True)
1110 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001111 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001112
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001113class ModifyL2DstIngress(BaseMatchCase):
1114 """
1115 Modify the L2 dest and send to the ingress port
1116 """
1117 def runTest(self):
1118 sup_acts = supported_actions_get(self)
1119 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001120 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001121 return
1122
1123 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1124 check_test_params=True)
1125 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1126 action_list=acts, max_test=2, egr_count=0,
1127 ing_port=True)
1128
Dan Talaycod8ae7582012-03-23 12:24:56 -07001129class ModifyL2DstIngressMC(BaseMatchCase):
1130 """
1131 Modify the L2 dest and send to the ingress port
1132 """
1133 def runTest(self):
1134 sup_acts = supported_actions_get(self)
1135 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1136 skip_message_emit(self, "ModifyL2dstMC test")
1137 return
1138
1139 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1140 check_test_params=True)
1141 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1142 action_list=acts, max_test=2, egr_count=-1,
1143 ing_port=True)
1144
Dan Talaycof6e76c02012-03-23 10:56:12 -07001145class ModifyL2SrcMC(BaseMatchCase):
1146 """
1147 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001148 """
1149 def runTest(self):
1150 sup_acts = supported_actions_get(self)
1151 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001152 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001153 return
1154
Dan Talaycof6e76c02012-03-23 10:56:12 -07001155 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1156 check_test_params=True)
1157 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001158 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001159
1160class ModifyL2SrcDstMC(BaseMatchCase):
1161 """
1162 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001163 """
1164 def runTest(self):
1165 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001166 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1167 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1168 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001169 return
1170
Dan Talaycof6e76c02012-03-23 10:56:12 -07001171 mod_fields = ['dl_dst', 'dl_src']
1172 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1173 check_test_params=True)
1174 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001175 action_list=acts, max_test=2, egr_count=-1)
1176
1177class ModifyL2DstVIDMC(BaseMatchCase):
1178 """
1179 Modify the L2 dest and send to 2 ports
1180 """
1181 def runTest(self):
1182 sup_acts = supported_actions_get(self)
1183 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1184 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1185 skip_message_emit(self, "ModifyL2DstVIDMC test")
1186 return
1187
1188 mod_fields = ['dl_dst', 'dl_vlan']
1189 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1190 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1191 check_test_params=True)
1192 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1193 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001194
Dan Talaycofa6454f2012-04-05 10:04:13 -07001195class FlowToggle(BaseMatchCase):
1196 """
1197 Add flows to the table and modify them repeatedly
1198 """
1199 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001200 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1201 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001202
1203 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1204 (flow_count, iter_count))
1205 acts = []
1206 acts.append(action.action_output())
1207 acts.append(action.action_output())
1208
1209 of_ports = pa_port_map.keys()
1210 if len(of_ports) < 3:
1211 self.assertTrue(False, "Too few ports for test")
1212
1213 for idx in range(2):
1214 acts[idx].port = of_ports[idx]
1215
1216 flows = []
1217 flows.append([])
1218 flows.append([])
1219
Dan Talayco50be7672012-04-05 11:38:08 -07001220 wildcards = ofp.OFPFW_DL_SRC | ofp.OFPFW_DL_DST
Dan Talaycofa6454f2012-04-05 10:04:13 -07001221 # Create up the flows in an array
1222 for toggle in range(2):
1223 for f_idx in range(flow_count):
1224 pkt = simple_tcp_packet(tcp_sport=f_idx)
1225 msg = message.flow_mod()
1226 match = parse.packet_to_flow_match(pkt)
1227 match.in_port = of_ports[3]
Dan Talayco50be7672012-04-05 11:38:08 -07001228 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001229 msg.match = match
1230 msg.buffer_id = 0xffffffff
1231 msg.actions.add(acts[toggle])
1232 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001233
1234 # Show two sample flows
1235 pa_logger.debug(flows[0][0].show())
1236 pa_logger.debug(flows[1][0].show())
1237
Dan Talaycofa6454f2012-04-05 10:04:13 -07001238 # Install the first set of flows
1239 for f_idx in range(flow_count):
1240 rv = self.controller.message_send(flows[0][f_idx])
1241 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
1242 do_barrier(self.controller)
1243
1244 pa_logger.info("Installed %d flows" % flow_count)
1245
1246 # Repeatedly modify all the flows back and forth
1247 updates = 0
1248 # Report status about 5 times
1249 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001250 start = time.time()
1251 for iter_idx in range(iter_count):
1252 if not iter_idx % mod_val:
1253 pa_logger.info("Flow Toggle: iter %d of %d. " %
1254 (iter_idx, iter_count) +
1255 "%d updates in %d secs" %
1256 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001257 for toggle in range(2):
1258 t_idx = 1 - toggle
1259 for f_idx in range(flow_count):
1260 rv = self.controller.message_send(flows[t_idx][f_idx])
1261 updates += 1
1262 self.assertTrue(rv != -1, "Error modifying flow %d" %
1263 f_idx)
1264 do_barrier(self.controller)
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001265
1266 end = time.time()
1267 divisor = end - start or (end - start + 1)
1268 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1269 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1270 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001271
1272
Dan Talayco8a64e332012-03-28 14:53:20 -07001273# You can pick and choose these by commenting tests in or out
1274iter_classes = [
1275 basic.PacketIn,
1276 basic.PacketOut,
1277 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001278 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001279 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001280 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001281 AllWildcardMatch,
1282 AllWildcardMatchTagged,
1283 SingleWildcardMatch,
1284 SingleWildcardMatchTagged,
1285 ExactMatch,
1286 ExactMatchTagged,
1287 SingleWildcardMatch,
1288 ModifyL2Src,
1289 ModifyL2Dst,
1290 ModifyL2SrcMC,
1291 ModifyL2DstMC,
1292 ModifyL2SrcDstMC
1293 ]
1294
1295class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001296 """
1297 Iterate over a bunch of test cases
1298
1299 The cases come from the list above
1300 """
1301
Dan Talayco8a64e332012-03-28 14:53:20 -07001302 def runTest(self):
1303 count = test_param_get(self.config, 'iter_count', default=10)
1304 tests_done = 0
1305 pa_logger.info("Running iteration test " + str(count) + " times")
1306 start = time.time()
1307 last = start
1308 for idx in range(count):
1309 pa_logger.info("Iteration " + str(idx + 1))
1310 for cls in iter_classes:
1311 test = cls()
1312 test.inheritSetup(self)
1313 test.runTest()
1314 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001315 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001316 if time.time() - last > 60:
1317 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001318 pa_logger.info(
1319 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1320 (idx, count, tests_done, last - start) +
1321 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001322 stats = all_stats_get(self)
1323 last = time.time()
1324 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1325 (tests_done, last - start))
1326 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1327 (stats["flows"], stats["packets"], stats["bytes"]))
1328 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1329 (stats["active"], stats["lookups"], stats["matched"]))
1330
1331# Don't run by default
1332test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001333
Dan Talayco4b2bee62010-07-20 14:10:05 -07001334#@todo Need to implement tagged versions of the above tests
1335#
1336#@todo Implement a test case that strips tag 2, adds tag 3
1337# and modifies tag 4 to tag 5. Then verify (in addition) that
1338# tag 6 does not get modified.
1339
1340class MixedVLAN(BaseMatchCase):
1341 """
1342 Test mixture of VLAN tag actions
1343
1344 Strip tag 2 on port 1, send to port 2
1345 Add tag 3 on port 1, send to port 2
1346 Modify tag 4 to 5 on port 1, send to port 2
1347 All other traffic from port 1, send to port 3
1348 All traffic from port 2 sent to port 4
1349 Use exact matches with different packets for all mods
1350 Verify the following: (port, vid)
1351 (port 1, vid 2) => VLAN tag stripped, out port 2
1352 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1353 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1354 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1355 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1356 (port 2, no tag) => untagged packet out port 4
1357 (port 2, vid 2-6) => unmodified packet out port 4
1358
1359 Variation: Might try sending VID 5 to port 3 and check.
1360 If only VID 5 distinguishes pkt, this will fail on some platforms
1361 """
1362
1363test_prio["MixedVLAN"] = -1
1364
Dan Talayco551befa2010-07-15 17:05:32 -07001365def supported_actions_get(parent, use_cache=True):
1366 """
1367 Get the bitmap of supported actions from the switch
1368 If use_cache is false, the cached value will be updated
1369 """
1370 global cached_supported_actions
1371 if cached_supported_actions is None or not use_cache:
1372 request = message.features_request()
1373 (reply, pkt) = parent.controller.transact(request, timeout=2)
1374 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1375 cached_supported_actions = reply.actions
1376 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1377
1378 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001379
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001380if __name__ == "__main__":
1381 print "Please run through oft script: ./oft --test_spec=basic"