blob: 653c3c26fd54197363f7e6bf0b1acebc030a7ff2 [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,
Dan Talayco488fbc52012-04-09 16:30:41 -070048 ofp.OFPFW_DL_VLAN | ofp.OFPFW_DL_VLAN_PCP,
Dan Talayco551befa2010-07-15 17:05:32 -070049 ofp.OFPFW_DL_SRC,
50 ofp.OFPFW_DL_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070051 (ofp.OFPFW_DL_TYPE | ofp.OFPFW_NW_SRC_ALL |
52 ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS | ofp.OFPFW_NW_PROTO |
53 ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
54 (ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
Dan Talayco551befa2010-07-15 17:05:32 -070055 ofp.OFPFW_TP_SRC,
56 ofp.OFPFW_TP_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070057 ofp.OFPFW_NW_SRC_MASK,
58 ofp.OFPFW_NW_DST_MASK,
Dan Talayco551befa2010-07-15 17:05:32 -070059 ofp.OFPFW_DL_VLAN_PCP,
60 ofp.OFPFW_NW_TOS]
61
Dan Talayco488fbc52012-04-09 16:30:41 -070062NO_WILDCARD_VALUES = [(ofp.OFPFW_ALL ^ ofp.OFPFW_IN_PORT),
63 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_VLAN),
64 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_SRC),
65 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_DST),
66 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE),
67 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO),
68 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
69 ofp.OFPFW_TP_SRC),
70 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
71 ofp.OFPFW_TP_DST),
72 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
73 ofp.OFPFW_NW_SRC_MASK),
74 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
75 ofp.OFPFW_NW_DST_MASK),
76 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_VLAN ^ ofp.OFPFW_DL_VLAN_PCP),
77 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
78 ofp.OFPFW_NW_TOS)]
79
Dan Talayco551befa2010-07-15 17:05:32 -070080MODIFY_ACTION_VALUES = [ofp.OFPAT_SET_VLAN_VID,
81 ofp.OFPAT_SET_VLAN_PCP,
82 ofp.OFPAT_STRIP_VLAN,
83 ofp.OFPAT_SET_DL_SRC,
84 ofp.OFPAT_SET_DL_DST,
85 ofp.OFPAT_SET_NW_SRC,
86 ofp.OFPAT_SET_NW_DST,
87 ofp.OFPAT_SET_NW_TOS,
88 ofp.OFPAT_SET_TP_SRC,
89 ofp.OFPAT_SET_TP_DST]
90
91# Cache supported features to avoid transaction overhead
92cached_supported_actions = None
93
Dan Talayco21381562010-07-17 00:34:47 -070094TEST_VID_DEFAULT = 2
95
Dan Talayco5eba8442010-03-10 13:58:43 -080096def test_set_init(config):
97 """
98 Set up function for packet action test classes
99
100 @param config The configuration dictionary; see oft
101 """
102
Ed Swierk89f78352012-03-29 12:32:32 -0700103 basic.test_set_init(config)
104
Dan Talayco5eba8442010-03-10 13:58:43 -0800105 global pa_port_map
106 global pa_logger
107 global pa_config
108
109 pa_logger = logging.getLogger("pkt_act")
110 pa_logger.info("Initializing test set")
111 pa_port_map = config["port_map"]
112 pa_config = config
113
114class DirectPacket(basic.SimpleDataPlane):
115 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700116 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -0800117
118 Generate a packet
119 Generate and install a matching flow
120 Add action to direct the packet to an egress port
121 Send the packet to ingress dataplane port
122 Verify the packet is received at the egress port only
123 """
124 def runTest(self):
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700125 self.handleFlow()
126
127 def handleFlow(self, pkttype='TCP'):
Dan Talayco5eba8442010-03-10 13:58:43 -0800128 of_ports = pa_port_map.keys()
129 of_ports.sort()
130 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
131
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700132 if (pkttype == 'ICMP'):
133 pkt = simple_icmp_packet()
134 else:
135 pkt = simple_tcp_packet()
Dan Talayco5eba8442010-03-10 13:58:43 -0800136 match = parse.packet_to_flow_match(pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -0700137 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -0800138 self.assertTrue(match is not None,
139 "Could not generate flow match from pkt")
140 act = action.action_output()
141
142 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700143 rv = delete_all_flows(self.controller, pa_logger)
144 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700145
Dan Talayco5eba8442010-03-10 13:58:43 -0800146 ingress_port = of_ports[idx]
147 egress_port = of_ports[(idx + 1) % len(of_ports)]
148 pa_logger.info("Ingress " + str(ingress_port) +
Dan Talayco551befa2010-07-15 17:05:32 -0700149 " to egress " + str(egress_port))
Dan Talayco5eba8442010-03-10 13:58:43 -0800150
151 match.in_port = ingress_port
152
153 request = message.flow_mod()
154 request.match = match
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700155
Dan Talayco5eba8442010-03-10 13:58:43 -0800156 request.buffer_id = 0xffffffff
157 act.port = egress_port
158 self.assertTrue(request.actions.add(act), "Could not add action")
159
160 pa_logger.info("Inserting flow")
161 rv = self.controller.message_send(request)
162 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700163 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco5eba8442010-03-10 13:58:43 -0800164
165 pa_logger.info("Sending packet to dp port " +
166 str(ingress_port))
167 self.dataplane.send(ingress_port, str(pkt))
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700168
169 exp_pkt_arg = None
170 exp_port = None
171 if pa_config["relax"]:
172 exp_pkt_arg = pkt
173 exp_port = egress_port
174
175 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1,
176 port_number=exp_port,
177 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800178 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700179 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800180 str(rcv_port))
181 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
182 self.assertEqual(str(pkt), str(rcv_pkt),
183 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700184
Howard Pershf97840f2012-04-10 16:30:42 -0700185
186class DirectPacketQueue(basic.SimpleDataPlane):
187 """
188 Send packet to single queue on single egress port
189
190 Generate a packet
191 Generate and install a matching flow
192 Add action to direct the packet to an egress port and queue
193 Send the packet to ingress dataplane port
194 Verify the packet is received at the egress port only
195 """
196 def runTest(self):
197 self.handleFlow()
198
Howard Persh670b5672012-04-13 09:08:29 -0700199 def portQueuesGet(self, queue_stats, port_num):
200 result = []
201 for qs in queue_stats.stats:
202 if qs.port_no != port_num:
203 continue
204 result.append(qs.queue_id)
205 return result
206
Howard Pershf97840f2012-04-10 16:30:42 -0700207 def handleFlow(self, pkttype='TCP'):
208 of_ports = pa_port_map.keys()
209 of_ports.sort()
210 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
211
212 if (pkttype == 'ICMP'):
213 pkt = simple_icmp_packet()
214 else:
215 pkt = simple_tcp_packet()
216 match = parse.packet_to_flow_match(pkt)
217 match.wildcards &= ~ofp.OFPFW_IN_PORT
218 self.assertTrue(match is not None,
219 "Could not generate flow match from pkt")
220
Howard Persh670b5672012-04-13 09:08:29 -0700221 # Get queue stats from switch
222
223 request = message.queue_stats_request()
224 request.port_no = ofp.OFPP_ALL
225 request.queue_id = ofp.OFPQ_ALL
Ed Swierk065a2db2012-04-17 16:35:52 -0700226 (queue_stats, p) = self.controller.transact(request, timeout=2)
Howard Persh670b5672012-04-13 09:08:29 -0700227 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
228
229 act = action.action_enqueue()
Howard Pershf97840f2012-04-10 16:30:42 -0700230
231 for idx in range(len(of_ports)):
Howard Pershf97840f2012-04-10 16:30:42 -0700232 ingress_port = of_ports[idx]
233 egress_port = of_ports[(idx + 1) % len(of_ports)]
Howard Pershf97840f2012-04-10 16:30:42 -0700234
Howard Persh670b5672012-04-13 09:08:29 -0700235 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
236 pa_logger.info("Ingress " + str(ingress_port)
237 + " to egress " + str(egress_port)
238 + " queue " + str(egress_queue_id)
239 )
Howard Pershf97840f2012-04-10 16:30:42 -0700240
Howard Persh670b5672012-04-13 09:08:29 -0700241 rv = delete_all_flows(self.controller, pa_logger)
242 self.assertEqual(rv, 0, "Failed to delete all flows")
Howard Pershf97840f2012-04-10 16:30:42 -0700243
Howard Persh670b5672012-04-13 09:08:29 -0700244 match.in_port = ingress_port
245
246 request = message.flow_mod()
247 request.match = match
Howard Pershf97840f2012-04-10 16:30:42 -0700248
Howard Persh670b5672012-04-13 09:08:29 -0700249 request.buffer_id = 0xffffffff
250 act.port = egress_port
251 act.queue_id = egress_queue_id
252 self.assertTrue(request.actions.add(act), "Could not add action")
Howard Pershf97840f2012-04-10 16:30:42 -0700253
Howard Persh670b5672012-04-13 09:08:29 -0700254 pa_logger.info("Inserting flow")
255 rv = self.controller.message_send(request)
256 self.assertTrue(rv != -1, "Error installing flow mod")
257 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Howard Pershf97840f2012-04-10 16:30:42 -0700258
Howard Persh670b5672012-04-13 09:08:29 -0700259 # Get current stats for selected egress queue
Howard Pershf97840f2012-04-10 16:30:42 -0700260
Howard Persh670b5672012-04-13 09:08:29 -0700261 request = message.queue_stats_request()
262 request.port_no = egress_port
263 request.queue_id = egress_queue_id
Ed Swierk065a2db2012-04-17 16:35:52 -0700264 (qs_before, p) = self.controller.transact(request, timeout=2)
Howard Persh670b5672012-04-13 09:08:29 -0700265 self.assertNotEqual(qs_before, None, "Queue stats request failed")
266
267 pa_logger.info("Sending packet to dp port " +
268 str(ingress_port))
269 self.dataplane.send(ingress_port, str(pkt))
270
271 exp_pkt_arg = None
272 exp_port = None
273 if pa_config["relax"]:
274 exp_pkt_arg = pkt
275 exp_port = egress_port
276
277 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1,
278 port_number=exp_port,
279 exp_pkt=exp_pkt_arg)
280 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
281 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
282 str(rcv_port))
283 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
284 self.assertEqual(str(pkt), str(rcv_pkt),
285 'Response packet does not match send packet')
286
Ed Swierkb8a86512012-04-18 18:45:58 -0700287 # FIXME: instead of sleeping, keep requesting queue stats until
288 # the expected queue counter increases or some large timeout is
289 # reached
290 time.sleep(2)
291
Howard Persh670b5672012-04-13 09:08:29 -0700292 # Get current stats for selected egress queue again
293
294 request = message.queue_stats_request()
295 request.port_no = egress_port
296 request.queue_id = egress_queue_id
Ed Swierk065a2db2012-04-17 16:35:52 -0700297 (qs_after, p) = self.controller.transact(request, timeout=2)
Howard Persh670b5672012-04-13 09:08:29 -0700298 self.assertNotEqual(qs_after, None, "Queue stats request failed")
299
300 # Make sure that tx packet counter for selected egress queue was
301 # incremented
302
Ed Swierk22f59152012-04-17 16:36:47 -0700303 self.assertEqual(qs_after.stats[0].tx_packets, \
304 qs_before.stats[0].tx_packets + 1, \
Howard Persh670b5672012-04-13 09:08:29 -0700305 "Verification of egress queue tx packet count failed"
306 )
307
308
Ken Chiang899ff8e2012-05-23 18:26:12 -0700309class DirectPacketControllerQueue(basic.SimpleDataPlane):
310 """
311 Send a packet from each of the openflow ports
312 to each of the queues configured on the controller port.
313 If no queues have been configured, no packets are sent.
Howard Pershf97840f2012-04-10 16:30:42 -0700314
Ken Chiang899ff8e2012-05-23 18:26:12 -0700315 Generate a packet
316 Generate and install a matching flow
317 Add action to direct the packet to one of the controller port queues
318 Send the packet to ingress dataplane port
319 Verify the packet is received on the controller port queue
320 """
321 def runTest(self):
322 self.handleFlow()
323
324 def portQueuesGet(self, queue_stats, port_num):
325 result = []
326 for qs in queue_stats.stats:
327 if qs.port_no != port_num:
328 continue
329 result.append(qs.queue_id)
330 return result
331
332 def handleFlow(self, pkttype='TCP'):
333 of_ports = pa_port_map.keys()
334 of_ports.sort()
335 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
336
337 if (pkttype == 'ICMP'):
338 pkt = simple_icmp_packet()
339 else:
340 pkt = simple_tcp_packet()
341 match = parse.packet_to_flow_match(pkt)
342 match.wildcards &= ~ofp.OFPFW_IN_PORT
343 self.assertTrue(match is not None,
344 "Could not generate flow match from pkt")
345
346 # Get queue stats from switch
347
348 request = message.queue_stats_request()
349 request.port_no = ofp.OFPP_CONTROLLER
350 request.queue_id = ofp.OFPQ_ALL
351 (queue_stats, p) = self.controller.transact(request, timeout=2)
352 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
353
354 act = action.action_enqueue()
355
356 for idx in range(len(of_ports)):
357 ingress_port = of_ports[idx]
358 egress_port = ofp.OFPP_CONTROLLER
359
360 pa_logger.info("Ingress port " + str(ingress_port)
361 + ", controller port queues "
362 + str(self.portQueuesGet(queue_stats, egress_port)))
363
364 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
365 pa_logger.info("Ingress " + str(ingress_port)
366 + " to egress " + str(egress_port)
367 + " queue " + str(egress_queue_id)
368 )
369
370 rv = delete_all_flows(self.controller, pa_logger)
371 self.assertEqual(rv, 0, "Failed to delete all flows")
372
373 match.in_port = ingress_port
374
375 request = message.flow_mod()
376 request.match = match
377
378 request.buffer_id = 0xffffffff
379 act.port = egress_port
380 act.queue_id = egress_queue_id
381 self.assertTrue(request.actions.add(act), "Could not add action")
382
383 pa_logger.info("Inserting flow")
384 rv = self.controller.message_send(request)
385 self.assertTrue(rv != -1, "Error installing flow mod")
386 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
387
388 # Get current stats for selected egress queue
389
390 request = message.queue_stats_request()
391 request.port_no = egress_port
392 request.queue_id = egress_queue_id
393 (qs_before, p) = self.controller.transact(request, timeout=2)
394 self.assertNotEqual(qs_before, None, "Queue stats request failed")
395
396 pa_logger.info("Sending packet to dp port " +
397 str(ingress_port))
398 self.dataplane.send(ingress_port, str(pkt))
399
400 exp_pkt_arg = None
401 exp_port = None
402
403 while True:
404 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN, 2)
405 if not response: # Timeout
406 break
407 if dataplane.match_exp_pkt(pkt, response.data): # Got match
408 break
409 if not basic_config["relax"]: # Only one attempt to match
410 break
411 count += 1
412 if count > 10: # Too many tries
413 break
414
415 self.assertTrue(response is not None,
416 'Packet in message not received by controller')
417 if not dataplane.match_exp_pkt(pkt, response.data):
418 basic_logger.debug("Sent %s" % format_packet(pkt))
419 basic_logger.debug("Resp %s" % format_packet(response.data))
420 self.assertTrue(False,
421 'Response packet does not match send packet' +
422 ' for controller port')
423
424 # FIXME: instead of sleeping, keep requesting queue stats until
425 # the expected queue counter increases or some large timeout is
426 # reached
427 time.sleep(2)
428
429 # Get current stats for selected egress queue again
430
431 request = message.queue_stats_request()
432 request.port_no = egress_port
433 request.queue_id = egress_queue_id
434 (qs_after, p) = self.controller.transact(request, timeout=2)
435 self.assertNotEqual(qs_after, None, "Queue stats request failed")
436
437 # Make sure that tx packet counter for selected egress queue was
438 # incremented
439
440 self.assertEqual(qs_after.stats[0].tx_packets, \
441 qs_before.stats[0].tx_packets + 1, \
442 "Verification of egress queue tx packet count failed"
443 )
444
Howard Pershf97840f2012-04-10 16:30:42 -0700445
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700446class DirectPacketICMP(DirectPacket):
447 """
448 Send ICMP packet to single egress port
449
450 Generate a ICMP packet
451 Generate and install a matching flow
452 Add action to direct the packet to an egress port
453 Send the packet to ingress dataplane port
454 Verify the packet is received at the egress port only
455 Difference from DirectPacket test is that sent packet is ICMP
456 """
457 def runTest(self):
458 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700459
460class DirectTwoPorts(basic.SimpleDataPlane):
461 """
462 Send packet to two egress ports
463
464 Generate a packet
465 Generate and install a matching flow
466 Add action to direct the packet to two egress ports
467 Send the packet to ingress dataplane port
468 Verify the packet is received at the two egress ports
469 """
470 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700471 of_ports = pa_port_map.keys()
472 of_ports.sort()
473 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
474
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700475 pkt = simple_tcp_packet()
476 match = parse.packet_to_flow_match(pkt)
477 match.wildcards &= ~ofp.OFPFW_IN_PORT
478 self.assertTrue(match is not None,
479 "Could not generate flow match from pkt")
480 act = action.action_output()
481
482 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700483 rv = delete_all_flows(self.controller, pa_logger)
484 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700485
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700486 ingress_port = of_ports[idx]
487 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
488 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
489 pa_logger.info("Ingress " + str(ingress_port) +
490 " to egress " + str(egress_port1) + " and " +
491 str(egress_port2))
492
493 match.in_port = ingress_port
494
495 request = message.flow_mod()
496 request.match = match
497 request.buffer_id = 0xffffffff
498 act.port = egress_port1
499 self.assertTrue(request.actions.add(act), "Could not add action1")
500 act.port = egress_port2
501 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700502 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700503
504 pa_logger.info("Inserting flow")
505 rv = self.controller.message_send(request)
506 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700507 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700508
509 pa_logger.info("Sending packet to dp port " +
510 str(ingress_port))
511 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700512 yes_ports = set([egress_port1, egress_port2])
513 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700514
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700515 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700516 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700517
518class DirectMCNonIngress(basic.SimpleDataPlane):
519 """
520 Multicast to all non-ingress ports
521
522 Generate a packet
523 Generate and install a matching flow
524 Add action to direct the packet to all non-ingress ports
525 Send the packet to ingress dataplane port
526 Verify the packet is received at all non-ingress ports
527
528 Does not use the flood action
529 """
530 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700531 of_ports = pa_port_map.keys()
532 of_ports.sort()
533 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
534
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700535 pkt = simple_tcp_packet()
536 match = parse.packet_to_flow_match(pkt)
537 match.wildcards &= ~ofp.OFPFW_IN_PORT
538 self.assertTrue(match is not None,
539 "Could not generate flow match from pkt")
540 act = action.action_output()
541
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700542 for ingress_port in of_ports:
543 rv = delete_all_flows(self.controller, pa_logger)
544 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700545
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700546 pa_logger.info("Ingress " + str(ingress_port) +
547 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700548 match.in_port = ingress_port
549
550 request = message.flow_mod()
551 request.match = match
552 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700553 for egress_port in of_ports:
554 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700555 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700556 act.port = egress_port
557 self.assertTrue(request.actions.add(act),
558 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700559 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700560
561 pa_logger.info("Inserting flow")
562 rv = self.controller.message_send(request)
563 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700564 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700565
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700566 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700567 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700568 yes_ports = set(of_ports).difference([ingress_port])
569 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700570 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700571
Dan Talayco32fa6542010-05-11 15:54:08 -0700572
573class DirectMC(basic.SimpleDataPlane):
574 """
575 Multicast to all ports including ingress
576
577 Generate a packet
578 Generate and install a matching flow
579 Add action to direct the packet to all non-ingress ports
580 Send the packet to ingress dataplane port
581 Verify the packet is received at all ports
582
583 Does not use the flood action
584 """
585 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700586 of_ports = pa_port_map.keys()
587 of_ports.sort()
588 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
589
Dan Talayco32fa6542010-05-11 15:54:08 -0700590 pkt = simple_tcp_packet()
591 match = parse.packet_to_flow_match(pkt)
592 match.wildcards &= ~ofp.OFPFW_IN_PORT
593 self.assertTrue(match is not None,
594 "Could not generate flow match from pkt")
595 act = action.action_output()
596
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700597 for ingress_port in of_ports:
598 rv = delete_all_flows(self.controller, pa_logger)
599 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700600
Dan Talayco32fa6542010-05-11 15:54:08 -0700601 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700602 match.in_port = ingress_port
603
604 request = message.flow_mod()
605 request.match = match
606 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700607 for egress_port in of_ports:
608 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700609 act.port = ofp.OFPP_IN_PORT
610 else:
611 act.port = egress_port
612 self.assertTrue(request.actions.add(act),
613 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700614 # pa_logger.info(request.show())
615
616 pa_logger.info("Inserting flow")
617 rv = self.controller.message_send(request)
618 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700619 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2e77a842010-05-12 15:39:46 -0700620
621 pa_logger.info("Sending packet to dp port " + str(ingress_port))
622 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700623 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700624 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700625
626class Flood(basic.SimpleDataPlane):
627 """
628 Flood to all ports except ingress
629
630 Generate a packet
631 Generate and install a matching flow
632 Add action to flood the packet
633 Send the packet to ingress dataplane port
634 Verify the packet is received at all other ports
635 """
636 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700637 of_ports = pa_port_map.keys()
638 of_ports.sort()
639 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
640
641 pkt = simple_tcp_packet()
642 match = parse.packet_to_flow_match(pkt)
643 match.wildcards &= ~ofp.OFPFW_IN_PORT
644 self.assertTrue(match is not None,
645 "Could not generate flow match from pkt")
646 act = action.action_output()
647
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700648 for ingress_port in of_ports:
649 rv = delete_all_flows(self.controller, pa_logger)
650 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700651
Dan Talayco2e77a842010-05-12 15:39:46 -0700652 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700653 match.in_port = ingress_port
654
655 request = message.flow_mod()
656 request.match = match
657 request.buffer_id = 0xffffffff
658 act.port = ofp.OFPP_FLOOD
659 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700660 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700661 pa_logger.info(request.show())
662
663 pa_logger.info("Inserting flow")
664 rv = self.controller.message_send(request)
665 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700666 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco32fa6542010-05-11 15:54:08 -0700667
668 pa_logger.info("Sending packet to dp port " + str(ingress_port))
669 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700670 yes_ports = set(of_ports).difference([ingress_port])
671 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700672 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700673
Dan Talayco3be5b062010-05-12 15:46:21 -0700674class FloodPlusIngress(basic.SimpleDataPlane):
675 """
676 Flood to all ports plus send to ingress port
677
678 Generate a packet
679 Generate and install a matching flow
680 Add action to flood the packet
681 Add action to send to ingress port
682 Send the packet to ingress dataplane port
683 Verify the packet is received at all other ports
684 """
685 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700686 of_ports = pa_port_map.keys()
687 of_ports.sort()
688 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
689
690 pkt = simple_tcp_packet()
691 match = parse.packet_to_flow_match(pkt)
692 match.wildcards &= ~ofp.OFPFW_IN_PORT
693 self.assertTrue(match is not None,
694 "Could not generate flow match from pkt")
695 act = action.action_output()
696
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700697 for ingress_port in of_ports:
698 rv = delete_all_flows(self.controller, pa_logger)
699 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700700
Dan Talayco3be5b062010-05-12 15:46:21 -0700701 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700702 match.in_port = ingress_port
703
704 request = message.flow_mod()
705 request.match = match
706 request.buffer_id = 0xffffffff
707 act.port = ofp.OFPP_FLOOD
708 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700709 "Could not add flood port action")
710 act.port = ofp.OFPP_IN_PORT
711 self.assertTrue(request.actions.add(act),
712 "Could not add ingress port for output")
713 pa_logger.info(request.show())
714
715 pa_logger.info("Inserting flow")
716 rv = self.controller.message_send(request)
717 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700718 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700719
720 pa_logger.info("Sending packet to dp port " + str(ingress_port))
721 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700722 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700723 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700724
725class All(basic.SimpleDataPlane):
726 """
727 Send to OFPP_ALL port
728
729 Generate a packet
730 Generate and install a matching flow
731 Add action to forward to OFPP_ALL
732 Send the packet to ingress dataplane port
733 Verify the packet is received at all other ports
734 """
735 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700736 of_ports = pa_port_map.keys()
737 of_ports.sort()
738 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
739
740 pkt = simple_tcp_packet()
741 match = parse.packet_to_flow_match(pkt)
742 match.wildcards &= ~ofp.OFPFW_IN_PORT
743 self.assertTrue(match is not None,
744 "Could not generate flow match from pkt")
745 act = action.action_output()
746
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700747 for ingress_port in of_ports:
748 rv = delete_all_flows(self.controller, pa_logger)
749 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700750
Dan Talayco4aa13122010-05-12 15:54:44 -0700751 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700752 match.in_port = ingress_port
753
754 request = message.flow_mod()
755 request.match = match
756 request.buffer_id = 0xffffffff
757 act.port = ofp.OFPP_ALL
758 self.assertTrue(request.actions.add(act),
759 "Could not add ALL port action")
760 pa_logger.info(request.show())
761
762 pa_logger.info("Inserting flow")
763 rv = self.controller.message_send(request)
764 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700765 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700766
767 pa_logger.info("Sending packet to dp port " + str(ingress_port))
768 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700769 yes_ports = set(of_ports).difference([ingress_port])
770 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700771 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700772
773class AllPlusIngress(basic.SimpleDataPlane):
774 """
775 Send to OFPP_ALL port and ingress port
776
777 Generate a packet
778 Generate and install a matching flow
779 Add action to forward to OFPP_ALL
780 Add action to forward to ingress port
781 Send the packet to ingress dataplane port
782 Verify the packet is received at all other ports
783 """
784 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700785 of_ports = pa_port_map.keys()
786 of_ports.sort()
787 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
788
789 pkt = simple_tcp_packet()
790 match = parse.packet_to_flow_match(pkt)
791 match.wildcards &= ~ofp.OFPFW_IN_PORT
792 self.assertTrue(match is not None,
793 "Could not generate flow match from pkt")
794 act = action.action_output()
795
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700796 for ingress_port in of_ports:
797 rv = delete_all_flows(self.controller, pa_logger)
798 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700799
Dan Talayco4aa13122010-05-12 15:54:44 -0700800 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700801 match.in_port = ingress_port
802
803 request = message.flow_mod()
804 request.match = match
805 request.buffer_id = 0xffffffff
806 act.port = ofp.OFPP_ALL
807 self.assertTrue(request.actions.add(act),
808 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700809 act.port = ofp.OFPP_IN_PORT
810 self.assertTrue(request.actions.add(act),
811 "Could not add ingress port for output")
812 pa_logger.info(request.show())
813
814 pa_logger.info("Inserting flow")
815 rv = self.controller.message_send(request)
816 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700817 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco3be5b062010-05-12 15:46:21 -0700818
819 pa_logger.info("Sending packet to dp port " + str(ingress_port))
820 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700821 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700822 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700823
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700824class FloodMinusPort(basic.SimpleDataPlane):
825 """
826 Config port with No_Flood and test Flood action
827
828 Generate a packet
829 Generate a matching flow
830 Add action to forward to OFPP_ALL
831 Set port to no-flood
832 Send the packet to ingress dataplane port
833 Verify the packet is received at all other ports except
834 the ingress port and the no_flood port
835 """
836 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700837 of_ports = pa_port_map.keys()
838 of_ports.sort()
839 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
840
841 pkt = simple_tcp_packet()
842 match = parse.packet_to_flow_match(pkt)
843 match.wildcards &= ~ofp.OFPFW_IN_PORT
844 self.assertTrue(match is not None,
845 "Could not generate flow match from pkt")
846 act = action.action_output()
847
848 for idx in range(len(of_ports)):
849 rv = delete_all_flows(self.controller, pa_logger)
850 self.assertEqual(rv, 0, "Failed to delete all flows")
851
852 ingress_port = of_ports[idx]
853 no_flood_idx = (idx + 1) % len(of_ports)
854 no_flood_port = of_ports[no_flood_idx]
855 rv = port_config_set(self.controller, no_flood_port,
856 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
857 pa_logger)
858 self.assertEqual(rv, 0, "Failed to set port config")
859
860 match.in_port = ingress_port
861
862 request = message.flow_mod()
863 request.match = match
864 request.buffer_id = 0xffffffff
865 act.port = ofp.OFPP_FLOOD
866 self.assertTrue(request.actions.add(act),
867 "Could not add flood port action")
868 pa_logger.info(request.show())
869
870 pa_logger.info("Inserting flow")
871 rv = self.controller.message_send(request)
872 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700873 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700874
875 pa_logger.info("Sending packet to dp port " + str(ingress_port))
876 pa_logger.info("No flood port is " + str(no_flood_port))
877 self.dataplane.send(ingress_port, str(pkt))
878 no_ports = set([ingress_port, no_flood_port])
879 yes_ports = set(of_ports).difference(no_ports)
880 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700881 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700882
883 # Turn no flood off again
884 rv = port_config_set(self.controller, no_flood_port,
885 0, ofp.OFPPC_NO_FLOOD, pa_logger)
886 self.assertEqual(rv, 0, "Failed to reset port config")
887
888 #@todo Should check no other packets received
889
Dan Talayco21381562010-07-17 00:34:47 -0700890
891
Dan Talayco551befa2010-07-15 17:05:32 -0700892################################################################
893
894class BaseMatchCase(basic.SimpleDataPlane):
895 def setUp(self):
896 basic.SimpleDataPlane.setUp(self)
897 self.logger = pa_logger
898 def runTest(self):
899 self.logger.info("BaseMatchCase")
900
901class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700902 """
Dan Talayco551befa2010-07-15 17:05:32 -0700903 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700904
905 Generate a packet
906 Generate and install a matching flow without wildcard mask
907 Add action to forward to a port
908 Send the packet to the port
909 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700910 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700911
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700912 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700913 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700914
Dan Talayco551befa2010-07-15 17:05:32 -0700915class ExactMatchTagged(BaseMatchCase):
916 """
917 Exact match for all port pairs with tagged pkts
918 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700919
Dan Talayco551befa2010-07-15 17:05:32 -0700920 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700921 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700922 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700923
Dan Talayco551befa2010-07-15 17:05:32 -0700924class ExactMatchTaggedMany(BaseMatchCase):
925 """
926 ExactMatchTagged with many VLANS
927 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700928
Dan Talayco551befa2010-07-15 17:05:32 -0700929 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700930 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700931 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
932 for vid in range(100,4000,389):
933 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
934 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700935
Dan Talayco551befa2010-07-15 17:05:32 -0700936# Don't run by default
937test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700938
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700939
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700940class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700941 """
942 SingleWildcardMatchPriority
943 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700944
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700945 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700946 self.pkt = simple_tcp_packet()
947 self.flowMsgs = {}
948
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700949 def _ClearTable(self):
950 rc = delete_all_flows(self.controller, self.logger)
951 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700952 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700953
954 def runTest(self):
955
956 self._Init()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700957 of_ports = pa_port_map.keys()
958 of_ports.sort()
959
960 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700961 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700962
963 # Run several combinations, each at lower priority settings.
964 # At the end of each call to runPrioFlows(), the table should
965 # be empty. If its not, we'll catch it as the priorities decreases
966 portA = of_ports[0]
967 portB = of_ports[1]
968 portC = of_ports[2]
969
970 # TODO -- these priority numbers should be validated somehow?
971 self.runPrioFlows(portA, portB, portC, 1000, 999)
972 self.runPrioFlows(portB, portC, portA, 998, 997)
973 self.runPrioFlows(portC, portA, portB, 996, 995)
974 self.runPrioFlows(portA, portC, portB, 994, 993)
975
976
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700977
978 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
979 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700980
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700981 if clearTable:
982 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700983
984 # Sanity check flow at lower priority from pA to pB
985 self.logger.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
986 % (portA, portB, portC, prioHigher, prioLower))
987
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700988 self.installFlow(prioHigher, portA, portC)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700989 self.installFlow(prioLower, portA, portB)
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700990
991 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700992 self.verifyFlow(portA, portB)
993 self.removeFlow(prioLower)
994 # Sanity check flow at lower priority from pA to pC
995 self.installFlow(prioLower, portA, portC)
996 self.verifyFlow(portA, portC)
997 self.removeFlow(prioLower)
998
999 # Install and verify pA->pB @ prioLower
1000 self.installFlow(prioLower, portA, portB)
1001 self.verifyFlow(portA, portB)
1002
1003 # Install and verify pA->pC @ prioHigher, should override pA->pB
1004 self.installFlow(prioHigher, portA, portC)
1005 self.verifyFlow(portA, portC)
1006 # remove pA->pC
1007 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001008 # Old flow pA -> pB @ prioLower should still be active
1009 self.verifyFlow(portA, portB)
1010 self.removeFlow(prioLower)
1011
1012 # Table should be empty at this point, leave it alone as
1013 # an assumption for future test runs
1014
1015
1016
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001017 def installFlow(self, prio, inp, egp,
1018 wildcards=ofp.OFPFW_DL_SRC):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001019 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001020 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001021 egr_ports=egp)
1022 request.priority = prio
Ken Chiang38d7a152012-05-24 15:33:50 -07001023 self.logger.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001024 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001025 self.flowMsgs[prio] = request
1026
1027 def removeFlow(self, prio):
1028 if self.flowMsgs.has_key(prio):
1029 msg = self.flowMsgs[prio]
1030 msg.command = ofp.OFPFC_DELETE_STRICT
1031 # This *must* be set for DELETE
1032 msg.out_port = ofp.OFPP_NONE
Ken Chiang38d7a152012-05-24 15:33:50 -07001033 self.logger.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001034 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001035 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001036 else:
1037 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001038
1039
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001040 def verifyFlow(self, inp, egp, pkt=None):
1041 if pkt == None:
1042 pkt = self.pkt
1043
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001044 self.logger.info("Pkt match test: " + str(inp) +
1045 " to " + str(egp))
1046 self.logger.debug("Send packet: " + str(inp) + " to "
1047 + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001048 self.dataplane.send(inp, str(pkt))
1049 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001050
1051
1052
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001053class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1054
1055 def runTest(self):
1056
1057 self._Init()
1058
1059 of_ports = pa_port_map.keys()
1060 of_ports.sort()
1061
1062 # Install an entry from 0 -> 1 @ prio 1000
1063 self._ClearTable()
1064 self.installFlow(1000, of_ports[0], of_ports[1])
1065 self.verifyFlow(of_ports[0], of_ports[1])
1066 self.installFlow(1000, of_ports[1], of_ports[0])
1067 self.verifyFlow(of_ports[1], of_ports[0])
1068 self.installFlow(1001, of_ports[0], of_ports[1])
1069 self.verifyFlow(of_ports[0], of_ports[1])
1070 self.installFlow(1001, of_ports[1], of_ports[0])
1071 self.verifyFlow(of_ports[1], of_ports[0])
1072 self.removeFlow(1001)
1073 self.verifyFlow(of_ports[0], of_ports[1])
1074 self.removeFlow(1000)
1075
1076
1077
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001078class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001079 """
1080 1. Add wildcard flow, verify packet received.
1081 2. Add exact match flow with higher priority, verify packet received
1082 on port specified by this flow.
1083 3. Add wildcard flow with even higher priority, verify packet received
1084 on port specified by this flow.
1085 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001086
1087 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001088
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001089 self._Init()
1090
1091 of_ports = pa_port_map.keys()
1092 of_ports.sort()
1093
1094 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001095
1096 # Install a flow with wildcards
1097 self.installFlow(999, of_ports[0], of_ports[1],
1098 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001099 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001100 # Install a flow with no wildcards for our packet
1101 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001102 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001103 # Install a flow with wildcards for our packet with higher
1104 # priority
1105 self.installFlow(1001, of_ports[0], of_ports[3])
1106 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001107
1108
Ken Chiang3978f242012-06-13 14:14:09 -07001109class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001110 """
1111 1. Add exact match flow, verify packet received.
1112 2. Add wildcard flow with higher priority, verify packet received on port
1113 specified by this flow.
1114 3. Add exact match flow with even higher priority, verify packet received
1115 on port specified by this flow.
1116 4. Delete lowest priority flow, verify packet received on port specified
1117 by highest priority flow.
1118 5. Delete highest priority flow, verify packet received on port specified
1119 by remaining flow.
1120 """
1121
1122 def runTest(self):
1123
1124 self._Init()
1125
1126 of_ports = pa_port_map.keys()
1127 of_ports.sort()
1128
1129 self._ClearTable()
1130
1131 # Install an exact match flow
1132 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1133 self.verifyFlow(of_ports[0], of_ports[1])
1134 # Install a flow with wildcards of higher priority
1135 self.installFlow(1250, of_ports[0], of_ports[2],
1136 wildcards=ofp.OFPFW_DL_DST)
1137 self.verifyFlow(of_ports[0], of_ports[2])
1138 # Install an exact match flow with even higher priority
1139 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1140 self.verifyFlow(of_ports[0], of_ports[3])
1141 # Delete lowest priority flow
1142 self.removeFlow(250)
1143 self.verifyFlow(of_ports[0], of_ports[3])
1144 # Delete highest priority flow
1145 self.removeFlow(2001)
1146 self.verifyFlow(of_ports[0], of_ports[2])
1147
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001148
Dan Talayco551befa2010-07-15 17:05:32 -07001149class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001150 """
1151 Exercise wildcard matching for all ports
1152
1153 Generate a packet
1154 Generate and install a matching flow with wildcard mask
1155 Add action to forward to a port
1156 Send the packet to the port
1157 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001158 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001159 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001160 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001161 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001162 for wc in WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001163 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001164 # Set nonzero VLAN id to avoid sending priority-tagged packet
1165 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001166 else:
1167 dl_vlan = -1
1168 flow_match_test(self, pa_port_map, wildcards=wc,
1169 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001170
Dan Talayco551befa2010-07-15 17:05:32 -07001171class SingleWildcardMatchTagged(BaseMatchCase):
1172 """
1173 SingleWildcardMatch with tagged packets
1174 """
1175 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001176 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001177 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001178 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001179 max_test=10)
1180
1181class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001182 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001183 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001184
1185 Generate a packet
1186 Generate and install a matching flow with wildcard all except one filed
1187 Add action to forward to a port
1188 Send the packet to the port
1189 Verify the packet is received at all other ports (one port at a time)
1190 Verify flow_expiration message is correct when command option is set
1191 """
1192 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001193 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001194 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001195 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001196 # Set nonzero VLAN id to avoid sending priority-tagged packet
1197 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001198 else:
1199 dl_vlan = -1
1200 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1201 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001202
Dan Talayco551befa2010-07-15 17:05:32 -07001203class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1204 """
1205 Match one field with tagged packets
1206 """
1207 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001208 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001209 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001210 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1211 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001212
1213class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001214 """
1215 Create Wildcard-all flow and exercise for all ports
1216
1217 Generate a packet
1218 Generate and install a matching flow with wildcard-all
1219 Add action to forward to a port
1220 Send the packet to the port
1221 Verify the packet is received at all other ports (one port at a time)
1222 Verify flow_expiration message is correct when command option is set
1223 """
1224 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -07001225 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001226
Dan Talayco551befa2010-07-15 17:05:32 -07001227class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001228 """
Dan Talayco551befa2010-07-15 17:05:32 -07001229 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001230 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001231 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001232 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -07001233 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
1234 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001235
Dan Talaycoba3745c2010-07-21 21:51:08 -07001236
Dan Talayco551befa2010-07-15 17:05:32 -07001237class AddVLANTag(BaseMatchCase):
1238 """
1239 Add a VLAN tag to an untagged packet
1240 """
1241 def runTest(self):
1242 new_vid = 2
1243 sup_acts = supported_actions_get(self)
1244 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001245 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001246 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001247
Dan Talayco551befa2010-07-15 17:05:32 -07001248 len = 100
1249 len_w_vid = 104
1250 pkt = simple_tcp_packet(pktlen=len)
1251 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1252 dl_vlan=new_vid)
1253 vid_act = action.action_set_vlan_vid()
1254 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001255
Dan Talayco551befa2010-07-15 17:05:32 -07001256 flow_match_test(self, pa_port_map, pkt=pkt,
1257 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001258
Dan Talayco551befa2010-07-15 17:05:32 -07001259class PacketOnly(basic.DataPlaneOnly):
1260 """
1261 Just send a packet thru the switch
1262 """
1263 def runTest(self):
1264 pkt = simple_tcp_packet()
1265 of_ports = pa_port_map.keys()
1266 of_ports.sort()
1267 ing_port = of_ports[0]
1268 pa_logger.info("Sending packet to " + str(ing_port))
1269 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1270 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001271
Dan Talayco551befa2010-07-15 17:05:32 -07001272class PacketOnlyTagged(basic.DataPlaneOnly):
1273 """
1274 Just send a packet thru the switch
1275 """
1276 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001277 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001278 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
1279 of_ports = pa_port_map.keys()
1280 of_ports.sort()
1281 ing_port = of_ports[0]
1282 pa_logger.info("Sending packet to " + str(ing_port))
1283 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1284 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001285
Dan Talayco551befa2010-07-15 17:05:32 -07001286test_prio["PacketOnly"] = -1
1287test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001288
Dan Talayco551befa2010-07-15 17:05:32 -07001289class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001290 """
1291 Modify the VLAN ID in the VLAN tag of a tagged packet
1292 """
Dan Talayco551befa2010-07-15 17:05:32 -07001293 def runTest(self):
1294 old_vid = 2
1295 new_vid = 3
1296 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001297 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001298 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001299 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001300
Dan Talayco551befa2010-07-15 17:05:32 -07001301 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1302 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1303 vid_act = action.action_set_vlan_vid()
1304 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001305
Dan Talayco551befa2010-07-15 17:05:32 -07001306 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1307 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001308
Ken Chiange9a211d2012-04-20 14:52:11 -07001309class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1310 """
1311 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1312 The same flow should match on both untagged and tagged packets.
1313 """
1314 def runTest(self):
1315 old_vid = 2
1316 new_vid = 3
1317 sup_acts = supported_actions_get(self)
1318 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1319 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1320 return
1321
1322 of_ports = pa_port_map.keys()
1323 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1324 ing_port = of_ports[0]
1325 egr_ports = of_ports[1]
1326
1327 rv = delete_all_flows(self.controller, pa_logger)
1328 self.assertEqual(rv, 0, "Failed to delete all flows")
1329
1330 len_untagged = 100
1331 len_w_vid = 104
1332 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1333 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1334 dl_vlan_enable=True, dl_vlan=old_vid)
1335 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1336 dl_vlan=new_vid)
1337 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP
1338 vid_act = action.action_set_vlan_vid()
1339 vid_act.vlan_vid = new_vid
1340 request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
1341 wildcards=wildcards, egr_ports=egr_ports,
1342 action_list=[vid_act])
1343 flow_msg_install(self, request)
1344
1345 pa_logger.debug("Send untagged packet: " + str(ing_port) + " to " +
1346 str(egr_ports))
1347 self.dataplane.send(ing_port, str(untagged_pkt))
1348 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1349
1350 pa_logger.debug("Send tagged packet: " + str(ing_port) + " to " +
1351 str(egr_ports))
1352 self.dataplane.send(ing_port, str(tagged_pkt))
1353 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1354
Howard Pershc1199d52012-04-11 14:21:32 -07001355class ModifyVlanPcp(BaseMatchCase):
1356 """
1357 Modify the priority field of the VLAN tag of a tagged packet
1358 """
1359 def runTest(self):
1360 vid = 123
1361 old_vlan_pcp = 2
1362 new_vlan_pcp = 3
1363 sup_acts = supported_actions_get(self)
1364 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1365 skip_message_emit(self, "Modify VLAN tag test")
1366 return
1367
1368 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=old_vlan_pcp)
1369 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=new_vlan_pcp)
1370 vid_act = action.action_set_vlan_pcp()
1371 vid_act.vlan_pcp = new_vlan_pcp
1372
1373 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1374 action_list=[vid_act])
1375
Dan Talayco551befa2010-07-15 17:05:32 -07001376class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001377 """
1378 Strip the VLAN tag from a tagged packet
1379 """
Dan Talayco551befa2010-07-15 17:05:32 -07001380 def runTest(self):
1381 old_vid = 2
1382 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001383 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001384 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001385 return
Dan Talaycof36f1082010-07-13 13:57:17 -07001386
Dan Talayco551befa2010-07-15 17:05:32 -07001387 len_w_vid = 104
1388 len = 100
1389 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1390 dl_vlan=old_vid)
1391 exp_pkt = simple_tcp_packet(pktlen=len)
1392 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001393
Dan Talayco551befa2010-07-15 17:05:32 -07001394 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1395 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001396
Ken Chiange9a211d2012-04-20 14:52:11 -07001397class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
1398 """
1399 Strip the VLAN tag from a tagged packet.
1400 Differs from StripVLANTag in that VID and PCP are both wildcarded.
1401 """
1402 def runTest(self):
1403 old_vid = 2
1404 sup_acts = supported_actions_get(self)
1405 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
1406 skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
1407 return
1408
1409 len_w_vid = 104
1410 len_untagged = 100
1411 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1412 dl_vlan=old_vid)
1413 exp_pkt = simple_tcp_packet(pktlen=len_untagged)
1414 vid_act = action.action_strip_vlan()
1415
1416 flow_match_test(self, pa_port_map,
1417 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP,
1418 pkt=pkt, exp_pkt=exp_pkt,
1419 action_list=[vid_act])
1420
Dan Talayco4b2bee62010-07-20 14:10:05 -07001421def init_pkt_args():
1422 """
1423 Pass back a dictionary with default packet arguments
1424 """
1425 args = {}
1426 args["dl_src"] = '00:23:45:67:89:AB'
1427
1428 dl_vlan_enable=False
1429 dl_vlan=-1
1430 if pa_config["test-params"]["vid"]:
1431 dl_vlan_enable=True
1432 dl_vlan = pa_config["test-params"]["vid"]
1433
1434# Unpack operator is ** on a dictionary
1435
1436 return args
1437
Dan Talayco551befa2010-07-15 17:05:32 -07001438class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001439 """
1440 Modify the source MAC address (TP1)
1441 """
Dan Talayco551befa2010-07-15 17:05:32 -07001442 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001443 sup_acts = supported_actions_get(self)
1444 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001445 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001446 return
1447
1448 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1449 check_test_params=True)
1450 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1451 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001452
Dan Talayco551befa2010-07-15 17:05:32 -07001453class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001454 """
1455 Modify the dest MAC address (TP1)
1456 """
Dan Talayco551befa2010-07-15 17:05:32 -07001457 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001458 sup_acts = supported_actions_get(self)
1459 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001460 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001461 return
1462
1463 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1464 check_test_params=True)
1465 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1466 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001467
Dan Talayco551befa2010-07-15 17:05:32 -07001468class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001469 """
1470 Modify the source IP address of an IP packet (TP1)
1471 """
Dan Talayco551befa2010-07-15 17:05:32 -07001472 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001473 sup_acts = supported_actions_get(self)
1474 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001475 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001476 return
1477
1478 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1479 check_test_params=True)
1480 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1481 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001482
Dan Talayco551befa2010-07-15 17:05:32 -07001483class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001484 """
1485 Modify the dest IP address of an IP packet (TP1)
1486 """
Dan Talayco551befa2010-07-15 17:05:32 -07001487 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001488 sup_acts = supported_actions_get(self)
1489 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001490 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001491 return
1492
1493 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1494 check_test_params=True)
1495 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1496 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001497
1498class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001499 """
1500 Modify the source TCP port of a TCP packet (TP1)
1501 """
Dan Talayco551befa2010-07-15 17:05:32 -07001502 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001503 sup_acts = supported_actions_get(self)
1504 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001505 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001506 return
1507
1508 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1509 check_test_params=True)
1510 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1511 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001512
1513class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001514 """
1515 Modify the dest TCP port of a TCP packet (TP1)
1516 """
Dan Talayco551befa2010-07-15 17:05:32 -07001517 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001518 sup_acts = supported_actions_get(self)
1519 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001520 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001521 return
1522
1523 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1524 check_test_params=True)
1525 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1526 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001527
1528class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001529 """
1530 Modify the IP type of service of an IP packet (TP1)
1531 """
Dan Talayco551befa2010-07-15 17:05:32 -07001532 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001533 sup_acts = supported_actions_get(self)
1534 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001535 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001536 return
Dan Talayco551befa2010-07-15 17:05:32 -07001537
Dan Talayco4b2bee62010-07-20 14:10:05 -07001538 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1539 check_test_params=True)
1540 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001541 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001542
Dan Talaycof6e76c02012-03-23 10:56:12 -07001543class ModifyL2DstMC(BaseMatchCase):
1544 """
1545 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001546 """
1547 def runTest(self):
1548 sup_acts = supported_actions_get(self)
1549 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001550 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001551 return
1552
Dan Talaycof6e76c02012-03-23 10:56:12 -07001553 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1554 check_test_params=True)
1555 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001556 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001557
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001558class ModifyL2DstIngress(BaseMatchCase):
1559 """
1560 Modify the L2 dest and send to the ingress port
1561 """
1562 def runTest(self):
1563 sup_acts = supported_actions_get(self)
1564 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001565 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001566 return
1567
1568 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1569 check_test_params=True)
1570 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1571 action_list=acts, max_test=2, egr_count=0,
1572 ing_port=True)
1573
Dan Talaycod8ae7582012-03-23 12:24:56 -07001574class ModifyL2DstIngressMC(BaseMatchCase):
1575 """
1576 Modify the L2 dest and send to the ingress port
1577 """
1578 def runTest(self):
1579 sup_acts = supported_actions_get(self)
1580 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1581 skip_message_emit(self, "ModifyL2dstMC test")
1582 return
1583
1584 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1585 check_test_params=True)
1586 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1587 action_list=acts, max_test=2, egr_count=-1,
1588 ing_port=True)
1589
Dan Talaycof6e76c02012-03-23 10:56:12 -07001590class ModifyL2SrcMC(BaseMatchCase):
1591 """
1592 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001593 """
1594 def runTest(self):
1595 sup_acts = supported_actions_get(self)
1596 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001597 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001598 return
1599
Dan Talaycof6e76c02012-03-23 10:56:12 -07001600 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1601 check_test_params=True)
1602 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001603 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001604
1605class ModifyL2SrcDstMC(BaseMatchCase):
1606 """
1607 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001608 """
1609 def runTest(self):
1610 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001611 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1612 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1613 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001614 return
1615
Dan Talaycof6e76c02012-03-23 10:56:12 -07001616 mod_fields = ['dl_dst', 'dl_src']
1617 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1618 check_test_params=True)
1619 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001620 action_list=acts, max_test=2, egr_count=-1)
1621
1622class ModifyL2DstVIDMC(BaseMatchCase):
1623 """
1624 Modify the L2 dest and send to 2 ports
1625 """
1626 def runTest(self):
1627 sup_acts = supported_actions_get(self)
1628 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1629 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1630 skip_message_emit(self, "ModifyL2DstVIDMC test")
1631 return
1632
1633 mod_fields = ['dl_dst', 'dl_vlan']
1634 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1635 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1636 check_test_params=True)
1637 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1638 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001639
Dan Talaycofa6454f2012-04-05 10:04:13 -07001640class FlowToggle(BaseMatchCase):
1641 """
1642 Add flows to the table and modify them repeatedly
1643 """
1644 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001645 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1646 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001647
1648 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1649 (flow_count, iter_count))
1650 acts = []
1651 acts.append(action.action_output())
1652 acts.append(action.action_output())
1653
1654 of_ports = pa_port_map.keys()
1655 if len(of_ports) < 3:
1656 self.assertTrue(False, "Too few ports for test")
1657
1658 for idx in range(2):
1659 acts[idx].port = of_ports[idx]
1660
1661 flows = []
1662 flows.append([])
1663 flows.append([])
1664
Dan Talayco50be7672012-04-05 11:38:08 -07001665 wildcards = ofp.OFPFW_DL_SRC | ofp.OFPFW_DL_DST
Dan Talaycofa6454f2012-04-05 10:04:13 -07001666 # Create up the flows in an array
1667 for toggle in range(2):
1668 for f_idx in range(flow_count):
1669 pkt = simple_tcp_packet(tcp_sport=f_idx)
1670 msg = message.flow_mod()
1671 match = parse.packet_to_flow_match(pkt)
1672 match.in_port = of_ports[3]
Dan Talayco50be7672012-04-05 11:38:08 -07001673 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001674 msg.match = match
1675 msg.buffer_id = 0xffffffff
1676 msg.actions.add(acts[toggle])
1677 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001678
1679 # Show two sample flows
1680 pa_logger.debug(flows[0][0].show())
1681 pa_logger.debug(flows[1][0].show())
1682
Dan Talaycofa6454f2012-04-05 10:04:13 -07001683 # Install the first set of flows
1684 for f_idx in range(flow_count):
1685 rv = self.controller.message_send(flows[0][f_idx])
1686 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001687 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001688
1689 pa_logger.info("Installed %d flows" % flow_count)
1690
1691 # Repeatedly modify all the flows back and forth
1692 updates = 0
1693 # Report status about 5 times
1694 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001695 start = time.time()
1696 for iter_idx in range(iter_count):
1697 if not iter_idx % mod_val:
1698 pa_logger.info("Flow Toggle: iter %d of %d. " %
1699 (iter_idx, iter_count) +
1700 "%d updates in %d secs" %
1701 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001702 for toggle in range(2):
1703 t_idx = 1 - toggle
1704 for f_idx in range(flow_count):
1705 rv = self.controller.message_send(flows[t_idx][f_idx])
1706 updates += 1
1707 self.assertTrue(rv != -1, "Error modifying flow %d" %
1708 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001709 self.assertEqual(do_barrier(self.controller), 0,
1710 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001711
1712 end = time.time()
1713 divisor = end - start or (end - start + 1)
1714 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1715 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1716 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001717
1718
Dan Talayco8a64e332012-03-28 14:53:20 -07001719# You can pick and choose these by commenting tests in or out
1720iter_classes = [
1721 basic.PacketIn,
1722 basic.PacketOut,
1723 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001724 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001725 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001726 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001727 AllWildcardMatch,
1728 AllWildcardMatchTagged,
1729 SingleWildcardMatch,
1730 SingleWildcardMatchTagged,
1731 ExactMatch,
1732 ExactMatchTagged,
1733 SingleWildcardMatch,
1734 ModifyL2Src,
1735 ModifyL2Dst,
1736 ModifyL2SrcMC,
1737 ModifyL2DstMC,
1738 ModifyL2SrcDstMC
1739 ]
1740
1741class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001742 """
1743 Iterate over a bunch of test cases
1744
1745 The cases come from the list above
1746 """
1747
Dan Talayco8a64e332012-03-28 14:53:20 -07001748 def runTest(self):
1749 count = test_param_get(self.config, 'iter_count', default=10)
1750 tests_done = 0
1751 pa_logger.info("Running iteration test " + str(count) + " times")
1752 start = time.time()
1753 last = start
1754 for idx in range(count):
1755 pa_logger.info("Iteration " + str(idx + 1))
1756 for cls in iter_classes:
1757 test = cls()
1758 test.inheritSetup(self)
1759 test.runTest()
1760 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001761 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001762 if time.time() - last > 60:
1763 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001764 pa_logger.info(
1765 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1766 (idx, count, tests_done, last - start) +
1767 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001768 stats = all_stats_get(self)
1769 last = time.time()
1770 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1771 (tests_done, last - start))
1772 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1773 (stats["flows"], stats["packets"], stats["bytes"]))
1774 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1775 (stats["active"], stats["lookups"], stats["matched"]))
1776
1777# Don't run by default
1778test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001779
Dan Talayco4b2bee62010-07-20 14:10:05 -07001780#@todo Need to implement tagged versions of the above tests
1781#
1782#@todo Implement a test case that strips tag 2, adds tag 3
1783# and modifies tag 4 to tag 5. Then verify (in addition) that
1784# tag 6 does not get modified.
1785
1786class MixedVLAN(BaseMatchCase):
1787 """
1788 Test mixture of VLAN tag actions
1789
1790 Strip tag 2 on port 1, send to port 2
1791 Add tag 3 on port 1, send to port 2
1792 Modify tag 4 to 5 on port 1, send to port 2
1793 All other traffic from port 1, send to port 3
1794 All traffic from port 2 sent to port 4
1795 Use exact matches with different packets for all mods
1796 Verify the following: (port, vid)
1797 (port 1, vid 2) => VLAN tag stripped, out port 2
1798 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1799 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1800 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1801 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1802 (port 2, no tag) => untagged packet out port 4
1803 (port 2, vid 2-6) => unmodified packet out port 4
1804
1805 Variation: Might try sending VID 5 to port 3 and check.
1806 If only VID 5 distinguishes pkt, this will fail on some platforms
1807 """
1808
1809test_prio["MixedVLAN"] = -1
1810
Dan Talayco551befa2010-07-15 17:05:32 -07001811def supported_actions_get(parent, use_cache=True):
1812 """
1813 Get the bitmap of supported actions from the switch
1814 If use_cache is false, the cached value will be updated
1815 """
1816 global cached_supported_actions
1817 if cached_supported_actions is None or not use_cache:
1818 request = message.features_request()
1819 (reply, pkt) = parent.controller.transact(request, timeout=2)
1820 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1821 cached_supported_actions = reply.actions
1822 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1823
1824 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001825
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001826if __name__ == "__main__":
1827 print "Please run through oft script: ./oft --test_spec=basic"