blob: 14e540c1ec2185739dc8e6f03ff85a2d97b675a1 [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
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700175 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700176 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800177 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700178 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800179 str(rcv_port))
180 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
181 self.assertEqual(str(pkt), str(rcv_pkt),
182 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700183
Rich Lane51c23b32012-07-27 16:37:25 -0700184class DirectPacketController(basic.SimpleDataPlane):
185 """
186 Send packet to the controller port
187
188 Generate a packet
189 Generate and install a matching flow
190 Add action to direct the packet to the controller port
191 Send the packet to ingress dataplane port
192 Verify the packet is received at the controller port
193 """
194 def runTest(self):
195 self.handleFlow()
196
197 def handleFlow(self, pkttype='TCP'):
198 of_ports = pa_port_map.keys()
199 of_ports.sort()
200 self.assertTrue(len(of_ports) > 0, "Not enough ports for test")
201
202 if (pkttype == 'ICMP'):
203 pkt = simple_icmp_packet()
204 else:
205 pkt = simple_tcp_packet()
206 match = parse.packet_to_flow_match(pkt)
207 match.wildcards &= ~ofp.OFPFW_IN_PORT
208 self.assertTrue(match is not None,
209 "Could not generate flow match from pkt")
210 act = action.action_output()
211
212 rv = delete_all_flows(self.controller, pa_logger)
213 self.assertEqual(rv, 0, "Failed to delete all flows")
214
215 ingress_port = of_ports[0]
216 match.in_port = ingress_port
217
218 request = message.flow_mod()
219 request.match = match
220
221 request.buffer_id = 0xffffffff
222 act.port = ofp.OFPP_CONTROLLER
223 act.max_len = 65535
224 self.assertTrue(request.actions.add(act), "Could not add action")
225
226 pa_logger.info("Inserting flow")
227 rv = self.controller.message_send(request)
228 self.assertTrue(rv != -1, "Error installing flow mod")
229 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
230
231 pa_logger.info("Sending packet to dp port " +
232 str(ingress_port))
233 self.dataplane.send(ingress_port, str(pkt))
234
235 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
236
237 self.assertTrue(response is not None,
238 'Packet in message not received by controller')
239 if not dataplane.match_exp_pkt(pkt, response.data):
240 pa_logger.debug("Sent %s" % format_packet(pkt))
241 pa_logger.debug("Resp %s" % format_packet(response.data))
242 self.assertTrue(False,
243 'Response packet does not match send packet' +
244 ' for controller port')
245
Howard Pershf97840f2012-04-10 16:30:42 -0700246
247class DirectPacketQueue(basic.SimpleDataPlane):
248 """
249 Send packet to single queue on single egress port
250
251 Generate a packet
252 Generate and install a matching flow
253 Add action to direct the packet to an egress port and queue
254 Send the packet to ingress dataplane port
255 Verify the packet is received at the egress port only
256 """
257 def runTest(self):
258 self.handleFlow()
259
Howard Persh670b5672012-04-13 09:08:29 -0700260 def portQueuesGet(self, queue_stats, port_num):
261 result = []
262 for qs in queue_stats.stats:
263 if qs.port_no != port_num:
264 continue
265 result.append(qs.queue_id)
266 return result
267
Howard Pershf97840f2012-04-10 16:30:42 -0700268 def handleFlow(self, pkttype='TCP'):
269 of_ports = pa_port_map.keys()
270 of_ports.sort()
271 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
272
273 if (pkttype == 'ICMP'):
274 pkt = simple_icmp_packet()
275 else:
276 pkt = simple_tcp_packet()
277 match = parse.packet_to_flow_match(pkt)
278 match.wildcards &= ~ofp.OFPFW_IN_PORT
279 self.assertTrue(match is not None,
280 "Could not generate flow match from pkt")
281
Howard Persh670b5672012-04-13 09:08:29 -0700282 # Get queue stats from switch
283
284 request = message.queue_stats_request()
285 request.port_no = ofp.OFPP_ALL
286 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700287 (queue_stats, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700288 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
289
290 act = action.action_enqueue()
Howard Pershf97840f2012-04-10 16:30:42 -0700291
292 for idx in range(len(of_ports)):
Howard Pershf97840f2012-04-10 16:30:42 -0700293 ingress_port = of_ports[idx]
294 egress_port = of_ports[(idx + 1) % len(of_ports)]
Howard Pershf97840f2012-04-10 16:30:42 -0700295
Howard Persh670b5672012-04-13 09:08:29 -0700296 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
297 pa_logger.info("Ingress " + str(ingress_port)
298 + " to egress " + str(egress_port)
299 + " queue " + str(egress_queue_id)
300 )
Howard Pershf97840f2012-04-10 16:30:42 -0700301
Howard Persh670b5672012-04-13 09:08:29 -0700302 rv = delete_all_flows(self.controller, pa_logger)
303 self.assertEqual(rv, 0, "Failed to delete all flows")
Howard Pershf97840f2012-04-10 16:30:42 -0700304
Howard Persh670b5672012-04-13 09:08:29 -0700305 match.in_port = ingress_port
306
307 request = message.flow_mod()
308 request.match = match
Howard Pershf97840f2012-04-10 16:30:42 -0700309
Howard Persh670b5672012-04-13 09:08:29 -0700310 request.buffer_id = 0xffffffff
311 act.port = egress_port
312 act.queue_id = egress_queue_id
313 self.assertTrue(request.actions.add(act), "Could not add action")
Howard Pershf97840f2012-04-10 16:30:42 -0700314
Howard Persh670b5672012-04-13 09:08:29 -0700315 pa_logger.info("Inserting flow")
316 rv = self.controller.message_send(request)
317 self.assertTrue(rv != -1, "Error installing flow mod")
318 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Howard Pershf97840f2012-04-10 16:30:42 -0700319
Howard Persh670b5672012-04-13 09:08:29 -0700320 # Get current stats for selected egress queue
Howard Pershf97840f2012-04-10 16:30:42 -0700321
Howard Persh670b5672012-04-13 09:08:29 -0700322 request = message.queue_stats_request()
323 request.port_no = egress_port
324 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700325 (qs_before, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700326 self.assertNotEqual(qs_before, None, "Queue stats request failed")
327
328 pa_logger.info("Sending packet to dp port " +
329 str(ingress_port))
330 self.dataplane.send(ingress_port, str(pkt))
331
332 exp_pkt_arg = None
333 exp_port = None
334 if pa_config["relax"]:
335 exp_pkt_arg = pkt
336 exp_port = egress_port
337
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700338 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Howard Persh670b5672012-04-13 09:08:29 -0700339 exp_pkt=exp_pkt_arg)
340 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
341 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
342 str(rcv_port))
343 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
344 self.assertEqual(str(pkt), str(rcv_pkt),
345 'Response packet does not match send packet')
346
Ed Swierkb8a86512012-04-18 18:45:58 -0700347 # FIXME: instead of sleeping, keep requesting queue stats until
348 # the expected queue counter increases or some large timeout is
349 # reached
350 time.sleep(2)
351
Howard Persh670b5672012-04-13 09:08:29 -0700352 # Get current stats for selected egress queue again
353
354 request = message.queue_stats_request()
355 request.port_no = egress_port
356 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700357 (qs_after, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700358 self.assertNotEqual(qs_after, None, "Queue stats request failed")
359
360 # Make sure that tx packet counter for selected egress queue was
361 # incremented
362
Ed Swierk22f59152012-04-17 16:36:47 -0700363 self.assertEqual(qs_after.stats[0].tx_packets, \
364 qs_before.stats[0].tx_packets + 1, \
Howard Persh670b5672012-04-13 09:08:29 -0700365 "Verification of egress queue tx packet count failed"
366 )
367
368
Ken Chiang899ff8e2012-05-23 18:26:12 -0700369class DirectPacketControllerQueue(basic.SimpleDataPlane):
370 """
371 Send a packet from each of the openflow ports
372 to each of the queues configured on the controller port.
373 If no queues have been configured, no packets are sent.
Howard Pershf97840f2012-04-10 16:30:42 -0700374
Ken Chiang899ff8e2012-05-23 18:26:12 -0700375 Generate a packet
376 Generate and install a matching flow
377 Add action to direct the packet to one of the controller port queues
378 Send the packet to ingress dataplane port
379 Verify the packet is received on the controller port queue
380 """
381 def runTest(self):
382 self.handleFlow()
383
384 def portQueuesGet(self, queue_stats, port_num):
385 result = []
386 for qs in queue_stats.stats:
387 if qs.port_no != port_num:
388 continue
389 result.append(qs.queue_id)
390 return result
391
392 def handleFlow(self, pkttype='TCP'):
393 of_ports = pa_port_map.keys()
394 of_ports.sort()
395 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
396
397 if (pkttype == 'ICMP'):
398 pkt = simple_icmp_packet()
399 else:
400 pkt = simple_tcp_packet()
401 match = parse.packet_to_flow_match(pkt)
402 match.wildcards &= ~ofp.OFPFW_IN_PORT
403 self.assertTrue(match is not None,
404 "Could not generate flow match from pkt")
405
406 # Get queue stats from switch
407
408 request = message.queue_stats_request()
409 request.port_no = ofp.OFPP_CONTROLLER
410 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700411 (queue_stats, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700412 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
413
414 act = action.action_enqueue()
415
416 for idx in range(len(of_ports)):
417 ingress_port = of_ports[idx]
418 egress_port = ofp.OFPP_CONTROLLER
419
420 pa_logger.info("Ingress port " + str(ingress_port)
421 + ", controller port queues "
422 + str(self.portQueuesGet(queue_stats, egress_port)))
423
424 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
425 pa_logger.info("Ingress " + str(ingress_port)
426 + " to egress " + str(egress_port)
427 + " queue " + str(egress_queue_id)
428 )
429
430 rv = delete_all_flows(self.controller, pa_logger)
431 self.assertEqual(rv, 0, "Failed to delete all flows")
432
433 match.in_port = ingress_port
434
435 request = message.flow_mod()
436 request.match = match
437
438 request.buffer_id = 0xffffffff
439 act.port = egress_port
440 act.queue_id = egress_queue_id
441 self.assertTrue(request.actions.add(act), "Could not add action")
442
443 pa_logger.info("Inserting flow")
444 rv = self.controller.message_send(request)
445 self.assertTrue(rv != -1, "Error installing flow mod")
446 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
447
448 # Get current stats for selected egress queue
449
450 request = message.queue_stats_request()
451 request.port_no = egress_port
452 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700453 (qs_before, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700454 self.assertNotEqual(qs_before, None, "Queue stats request failed")
455
456 pa_logger.info("Sending packet to dp port " +
457 str(ingress_port))
458 self.dataplane.send(ingress_port, str(pkt))
459
460 exp_pkt_arg = None
461 exp_port = None
462
463 while True:
464 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN, 2)
465 if not response: # Timeout
466 break
467 if dataplane.match_exp_pkt(pkt, response.data): # Got match
468 break
469 if not basic_config["relax"]: # Only one attempt to match
470 break
471 count += 1
472 if count > 10: # Too many tries
473 break
474
475 self.assertTrue(response is not None,
476 'Packet in message not received by controller')
477 if not dataplane.match_exp_pkt(pkt, response.data):
478 basic_logger.debug("Sent %s" % format_packet(pkt))
479 basic_logger.debug("Resp %s" % format_packet(response.data))
480 self.assertTrue(False,
481 'Response packet does not match send packet' +
482 ' for controller port')
483
484 # FIXME: instead of sleeping, keep requesting queue stats until
485 # the expected queue counter increases or some large timeout is
486 # reached
487 time.sleep(2)
488
489 # Get current stats for selected egress queue again
490
491 request = message.queue_stats_request()
492 request.port_no = egress_port
493 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700494 (qs_after, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700495 self.assertNotEqual(qs_after, None, "Queue stats request failed")
496
497 # Make sure that tx packet counter for selected egress queue was
498 # incremented
499
500 self.assertEqual(qs_after.stats[0].tx_packets, \
501 qs_before.stats[0].tx_packets + 1, \
502 "Verification of egress queue tx packet count failed"
503 )
504
Howard Pershf97840f2012-04-10 16:30:42 -0700505
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700506class DirectPacketICMP(DirectPacket):
507 """
508 Send ICMP packet to single egress port
509
510 Generate a ICMP packet
511 Generate and install a matching flow
512 Add action to direct the packet to an egress port
513 Send the packet to ingress dataplane port
514 Verify the packet is received at the egress port only
515 Difference from DirectPacket test is that sent packet is ICMP
516 """
517 def runTest(self):
518 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700519
520class DirectTwoPorts(basic.SimpleDataPlane):
521 """
522 Send packet to two egress ports
523
524 Generate a packet
525 Generate and install a matching flow
526 Add action to direct the packet to two egress ports
527 Send the packet to ingress dataplane port
528 Verify the packet is received at the two egress ports
529 """
530 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -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 Talayco2d0d49a2010-05-11 15:29:08 -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
542 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700543 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 Talayco2d0d49a2010-05-11 15:29:08 -0700546 ingress_port = of_ports[idx]
547 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
548 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
549 pa_logger.info("Ingress " + str(ingress_port) +
550 " to egress " + str(egress_port1) + " and " +
551 str(egress_port2))
552
553 match.in_port = ingress_port
554
555 request = message.flow_mod()
556 request.match = match
557 request.buffer_id = 0xffffffff
558 act.port = egress_port1
559 self.assertTrue(request.actions.add(act), "Could not add action1")
560 act.port = egress_port2
561 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700562 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700563
564 pa_logger.info("Inserting flow")
565 rv = self.controller.message_send(request)
566 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700567 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700568
569 pa_logger.info("Sending packet to dp port " +
570 str(ingress_port))
571 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700572 yes_ports = set([egress_port1, egress_port2])
573 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700574
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700575 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700576 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700577
578class DirectMCNonIngress(basic.SimpleDataPlane):
579 """
580 Multicast to all non-ingress ports
581
582 Generate a packet
583 Generate and install a matching flow
584 Add action to direct the packet to all non-ingress ports
585 Send the packet to ingress dataplane port
586 Verify the packet is received at all non-ingress ports
587
588 Does not use the flood action
589 """
590 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700591 of_ports = pa_port_map.keys()
592 of_ports.sort()
593 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
594
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700595 pkt = simple_tcp_packet()
596 match = parse.packet_to_flow_match(pkt)
597 match.wildcards &= ~ofp.OFPFW_IN_PORT
598 self.assertTrue(match is not None,
599 "Could not generate flow match from pkt")
600 act = action.action_output()
601
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700602 for ingress_port in of_ports:
603 rv = delete_all_flows(self.controller, pa_logger)
604 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700605
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700606 pa_logger.info("Ingress " + str(ingress_port) +
607 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700608 match.in_port = ingress_port
609
610 request = message.flow_mod()
611 request.match = match
612 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700613 for egress_port in of_ports:
614 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700615 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700616 act.port = egress_port
617 self.assertTrue(request.actions.add(act),
618 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700619 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700620
621 pa_logger.info("Inserting flow")
622 rv = self.controller.message_send(request)
623 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700624 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700625
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700626 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700627 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700628 yes_ports = set(of_ports).difference([ingress_port])
629 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700630 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700631
Dan Talayco32fa6542010-05-11 15:54:08 -0700632
633class DirectMC(basic.SimpleDataPlane):
634 """
635 Multicast to all ports including ingress
636
637 Generate a packet
638 Generate and install a matching flow
639 Add action to direct the packet to all non-ingress ports
640 Send the packet to ingress dataplane port
641 Verify the packet is received at all ports
642
643 Does not use the flood action
644 """
645 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700646 of_ports = pa_port_map.keys()
647 of_ports.sort()
648 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
649
Dan Talayco32fa6542010-05-11 15:54:08 -0700650 pkt = simple_tcp_packet()
651 match = parse.packet_to_flow_match(pkt)
652 match.wildcards &= ~ofp.OFPFW_IN_PORT
653 self.assertTrue(match is not None,
654 "Could not generate flow match from pkt")
655 act = action.action_output()
656
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700657 for ingress_port in of_ports:
658 rv = delete_all_flows(self.controller, pa_logger)
659 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700660
Dan Talayco32fa6542010-05-11 15:54:08 -0700661 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700662 match.in_port = ingress_port
663
664 request = message.flow_mod()
665 request.match = match
666 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700667 for egress_port in of_ports:
668 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700669 act.port = ofp.OFPP_IN_PORT
670 else:
671 act.port = egress_port
672 self.assertTrue(request.actions.add(act),
673 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700674 # pa_logger.info(request.show())
675
676 pa_logger.info("Inserting flow")
677 rv = self.controller.message_send(request)
678 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700679 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2e77a842010-05-12 15:39:46 -0700680
681 pa_logger.info("Sending packet to dp port " + str(ingress_port))
682 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700683 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700684 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700685
686class Flood(basic.SimpleDataPlane):
687 """
688 Flood to all ports except ingress
689
690 Generate a packet
691 Generate and install a matching flow
692 Add action to flood the packet
693 Send the packet to ingress dataplane port
694 Verify the packet is received at all other ports
695 """
696 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700697 of_ports = pa_port_map.keys()
698 of_ports.sort()
699 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
700
701 pkt = simple_tcp_packet()
702 match = parse.packet_to_flow_match(pkt)
703 match.wildcards &= ~ofp.OFPFW_IN_PORT
704 self.assertTrue(match is not None,
705 "Could not generate flow match from pkt")
706 act = action.action_output()
707
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700708 for ingress_port in of_ports:
709 rv = delete_all_flows(self.controller, pa_logger)
710 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700711
Dan Talayco2e77a842010-05-12 15:39:46 -0700712 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700713 match.in_port = ingress_port
714
715 request = message.flow_mod()
716 request.match = match
717 request.buffer_id = 0xffffffff
718 act.port = ofp.OFPP_FLOOD
719 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700720 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700721 pa_logger.info(request.show())
722
723 pa_logger.info("Inserting flow")
724 rv = self.controller.message_send(request)
725 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700726 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco32fa6542010-05-11 15:54:08 -0700727
728 pa_logger.info("Sending packet to dp port " + str(ingress_port))
729 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700730 yes_ports = set(of_ports).difference([ingress_port])
731 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700732 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700733
Dan Talayco3be5b062010-05-12 15:46:21 -0700734class FloodPlusIngress(basic.SimpleDataPlane):
735 """
736 Flood to all ports plus send to ingress port
737
738 Generate a packet
739 Generate and install a matching flow
740 Add action to flood the packet
741 Add action to send to ingress port
742 Send the packet to ingress dataplane port
743 Verify the packet is received at all other ports
744 """
745 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700746 of_ports = pa_port_map.keys()
747 of_ports.sort()
748 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
749
750 pkt = simple_tcp_packet()
751 match = parse.packet_to_flow_match(pkt)
752 match.wildcards &= ~ofp.OFPFW_IN_PORT
753 self.assertTrue(match is not None,
754 "Could not generate flow match from pkt")
755 act = action.action_output()
756
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700757 for ingress_port in of_ports:
758 rv = delete_all_flows(self.controller, pa_logger)
759 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700760
Dan Talayco3be5b062010-05-12 15:46:21 -0700761 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700762 match.in_port = ingress_port
763
764 request = message.flow_mod()
765 request.match = match
766 request.buffer_id = 0xffffffff
767 act.port = ofp.OFPP_FLOOD
768 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700769 "Could not add flood port action")
770 act.port = ofp.OFPP_IN_PORT
771 self.assertTrue(request.actions.add(act),
772 "Could not add ingress port for output")
773 pa_logger.info(request.show())
774
775 pa_logger.info("Inserting flow")
776 rv = self.controller.message_send(request)
777 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700778 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700779
780 pa_logger.info("Sending packet to dp port " + str(ingress_port))
781 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700782 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700783 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700784
785class All(basic.SimpleDataPlane):
786 """
787 Send to OFPP_ALL port
788
789 Generate a packet
790 Generate and install a matching flow
791 Add action to forward to OFPP_ALL
792 Send the packet to ingress dataplane port
793 Verify the packet is received at all other ports
794 """
795 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700796 of_ports = pa_port_map.keys()
797 of_ports.sort()
798 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
799
800 pkt = simple_tcp_packet()
801 match = parse.packet_to_flow_match(pkt)
802 match.wildcards &= ~ofp.OFPFW_IN_PORT
803 self.assertTrue(match is not None,
804 "Could not generate flow match from pkt")
805 act = action.action_output()
806
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700807 for ingress_port in of_ports:
808 rv = delete_all_flows(self.controller, pa_logger)
809 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700810
Dan Talayco4aa13122010-05-12 15:54:44 -0700811 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700812 match.in_port = ingress_port
813
814 request = message.flow_mod()
815 request.match = match
816 request.buffer_id = 0xffffffff
817 act.port = ofp.OFPP_ALL
818 self.assertTrue(request.actions.add(act),
819 "Could not add ALL port action")
820 pa_logger.info(request.show())
821
822 pa_logger.info("Inserting flow")
823 rv = self.controller.message_send(request)
824 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700825 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700826
827 pa_logger.info("Sending packet to dp port " + str(ingress_port))
828 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700829 yes_ports = set(of_ports).difference([ingress_port])
830 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700831 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700832
833class AllPlusIngress(basic.SimpleDataPlane):
834 """
835 Send to OFPP_ALL port and ingress port
836
837 Generate a packet
838 Generate and install a matching flow
839 Add action to forward to OFPP_ALL
840 Add action to forward to ingress port
841 Send the packet to ingress dataplane port
842 Verify the packet is received at all other ports
843 """
844 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700845 of_ports = pa_port_map.keys()
846 of_ports.sort()
847 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
848
849 pkt = simple_tcp_packet()
850 match = parse.packet_to_flow_match(pkt)
851 match.wildcards &= ~ofp.OFPFW_IN_PORT
852 self.assertTrue(match is not None,
853 "Could not generate flow match from pkt")
854 act = action.action_output()
855
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700856 for ingress_port in of_ports:
857 rv = delete_all_flows(self.controller, pa_logger)
858 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700859
Dan Talayco4aa13122010-05-12 15:54:44 -0700860 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700861 match.in_port = ingress_port
862
863 request = message.flow_mod()
864 request.match = match
865 request.buffer_id = 0xffffffff
866 act.port = ofp.OFPP_ALL
867 self.assertTrue(request.actions.add(act),
868 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700869 act.port = ofp.OFPP_IN_PORT
870 self.assertTrue(request.actions.add(act),
871 "Could not add ingress port for output")
872 pa_logger.info(request.show())
873
874 pa_logger.info("Inserting flow")
875 rv = self.controller.message_send(request)
876 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700877 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco3be5b062010-05-12 15:46:21 -0700878
879 pa_logger.info("Sending packet to dp port " + str(ingress_port))
880 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700881 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700882 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700883
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700884class FloodMinusPort(basic.SimpleDataPlane):
885 """
886 Config port with No_Flood and test Flood action
887
888 Generate a packet
889 Generate a matching flow
890 Add action to forward to OFPP_ALL
891 Set port to no-flood
892 Send the packet to ingress dataplane port
893 Verify the packet is received at all other ports except
894 the ingress port and the no_flood port
895 """
896 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700897 of_ports = pa_port_map.keys()
898 of_ports.sort()
899 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
900
901 pkt = simple_tcp_packet()
902 match = parse.packet_to_flow_match(pkt)
903 match.wildcards &= ~ofp.OFPFW_IN_PORT
904 self.assertTrue(match is not None,
905 "Could not generate flow match from pkt")
906 act = action.action_output()
907
908 for idx in range(len(of_ports)):
909 rv = delete_all_flows(self.controller, pa_logger)
910 self.assertEqual(rv, 0, "Failed to delete all flows")
911
912 ingress_port = of_ports[idx]
913 no_flood_idx = (idx + 1) % len(of_ports)
914 no_flood_port = of_ports[no_flood_idx]
915 rv = port_config_set(self.controller, no_flood_port,
916 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
917 pa_logger)
918 self.assertEqual(rv, 0, "Failed to set port config")
919
920 match.in_port = ingress_port
921
922 request = message.flow_mod()
923 request.match = match
924 request.buffer_id = 0xffffffff
925 act.port = ofp.OFPP_FLOOD
926 self.assertTrue(request.actions.add(act),
927 "Could not add flood port action")
928 pa_logger.info(request.show())
929
930 pa_logger.info("Inserting flow")
931 rv = self.controller.message_send(request)
932 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700933 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700934
935 pa_logger.info("Sending packet to dp port " + str(ingress_port))
936 pa_logger.info("No flood port is " + str(no_flood_port))
937 self.dataplane.send(ingress_port, str(pkt))
938 no_ports = set([ingress_port, no_flood_port])
939 yes_ports = set(of_ports).difference(no_ports)
940 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700941 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700942
943 # Turn no flood off again
944 rv = port_config_set(self.controller, no_flood_port,
945 0, ofp.OFPPC_NO_FLOOD, pa_logger)
946 self.assertEqual(rv, 0, "Failed to reset port config")
947
948 #@todo Should check no other packets received
949
Dan Talayco21381562010-07-17 00:34:47 -0700950
951
Dan Talayco551befa2010-07-15 17:05:32 -0700952################################################################
953
954class BaseMatchCase(basic.SimpleDataPlane):
955 def setUp(self):
956 basic.SimpleDataPlane.setUp(self)
957 self.logger = pa_logger
958 def runTest(self):
959 self.logger.info("BaseMatchCase")
960
961class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700962 """
Dan Talayco551befa2010-07-15 17:05:32 -0700963 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700964
965 Generate a packet
966 Generate and install a matching flow without wildcard mask
967 Add action to forward to a port
968 Send the packet to the port
969 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700970 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700971
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700972 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700973 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700974
Dan Talayco551befa2010-07-15 17:05:32 -0700975class ExactMatchTagged(BaseMatchCase):
976 """
977 Exact match for all port pairs with tagged pkts
978 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700979
Dan Talayco551befa2010-07-15 17:05:32 -0700980 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700981 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700982 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700983
Dan Talayco551befa2010-07-15 17:05:32 -0700984class ExactMatchTaggedMany(BaseMatchCase):
985 """
986 ExactMatchTagged with many VLANS
987 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700988
Dan Talayco551befa2010-07-15 17:05:32 -0700989 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700990 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700991 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
992 for vid in range(100,4000,389):
993 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
994 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700995
Dan Talayco551befa2010-07-15 17:05:32 -0700996# Don't run by default
997test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700998
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700999
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001000class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001001 """
1002 SingleWildcardMatchPriority
1003 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001004
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001005 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001006 self.pkt = simple_tcp_packet()
1007 self.flowMsgs = {}
1008
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001009 def _ClearTable(self):
1010 rc = delete_all_flows(self.controller, self.logger)
1011 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001012 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001013
1014 def runTest(self):
1015
1016 self._Init()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001017 of_ports = pa_port_map.keys()
1018 of_ports.sort()
1019
1020 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001021 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001022
1023 # Run several combinations, each at lower priority settings.
1024 # At the end of each call to runPrioFlows(), the table should
1025 # be empty. If its not, we'll catch it as the priorities decreases
1026 portA = of_ports[0]
1027 portB = of_ports[1]
1028 portC = of_ports[2]
1029
1030 # TODO -- these priority numbers should be validated somehow?
1031 self.runPrioFlows(portA, portB, portC, 1000, 999)
1032 self.runPrioFlows(portB, portC, portA, 998, 997)
1033 self.runPrioFlows(portC, portA, portB, 996, 995)
1034 self.runPrioFlows(portA, portC, portB, 994, 993)
1035
1036
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001037
1038 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
1039 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001040
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001041 if clearTable:
1042 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001043
1044 # Sanity check flow at lower priority from pA to pB
1045 self.logger.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
1046 % (portA, portB, portC, prioHigher, prioLower))
1047
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001048 # Sanity check flow at lower priority from pA to pC
1049 self.installFlow(prioLower, portA, portC)
1050 self.verifyFlow(portA, portC)
1051 self.removeFlow(prioLower)
1052
1053 # Install and verify pA->pB @ prioLower
1054 self.installFlow(prioLower, portA, portB)
1055 self.verifyFlow(portA, portB)
1056
1057 # Install and verify pA->pC @ prioHigher, should override pA->pB
1058 self.installFlow(prioHigher, portA, portC)
1059 self.verifyFlow(portA, portC)
1060 # remove pA->pC
1061 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001062 # Old flow pA -> pB @ prioLower should still be active
1063 self.verifyFlow(portA, portB)
1064 self.removeFlow(prioLower)
1065
1066 # Table should be empty at this point, leave it alone as
1067 # an assumption for future test runs
1068
1069
1070
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001071 def installFlow(self, prio, inp, egp,
1072 wildcards=ofp.OFPFW_DL_SRC):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001073 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001074 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001075 egr_ports=egp)
1076 request.priority = prio
Ken Chiang38d7a152012-05-24 15:33:50 -07001077 self.logger.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001078 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001079 self.flowMsgs[prio] = request
1080
1081 def removeFlow(self, prio):
1082 if self.flowMsgs.has_key(prio):
1083 msg = self.flowMsgs[prio]
1084 msg.command = ofp.OFPFC_DELETE_STRICT
1085 # This *must* be set for DELETE
1086 msg.out_port = ofp.OFPP_NONE
Ken Chiang38d7a152012-05-24 15:33:50 -07001087 self.logger.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001088 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001089 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001090 else:
1091 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001092
1093
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001094 def verifyFlow(self, inp, egp, pkt=None):
1095 if pkt == None:
1096 pkt = self.pkt
1097
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001098 self.logger.info("Pkt match test: " + str(inp) +
1099 " to " + str(egp))
1100 self.logger.debug("Send packet: " + str(inp) + " to "
1101 + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001102 self.dataplane.send(inp, str(pkt))
1103 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001104
1105
1106
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001107class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1108
1109 def runTest(self):
1110
1111 self._Init()
1112
1113 of_ports = pa_port_map.keys()
1114 of_ports.sort()
1115
1116 # Install an entry from 0 -> 1 @ prio 1000
1117 self._ClearTable()
1118 self.installFlow(1000, of_ports[0], of_ports[1])
1119 self.verifyFlow(of_ports[0], of_ports[1])
1120 self.installFlow(1000, of_ports[1], of_ports[0])
1121 self.verifyFlow(of_ports[1], of_ports[0])
1122 self.installFlow(1001, of_ports[0], of_ports[1])
1123 self.verifyFlow(of_ports[0], of_ports[1])
1124 self.installFlow(1001, of_ports[1], of_ports[0])
1125 self.verifyFlow(of_ports[1], of_ports[0])
1126 self.removeFlow(1001)
1127 self.verifyFlow(of_ports[0], of_ports[1])
1128 self.removeFlow(1000)
1129
1130
1131
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001132class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001133 """
1134 1. Add wildcard flow, verify packet received.
1135 2. Add exact match flow with higher priority, verify packet received
1136 on port specified by this flow.
1137 3. Add wildcard flow with even higher priority, verify packet received
1138 on port specified by this flow.
1139 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001140
1141 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001142
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001143 self._Init()
1144
1145 of_ports = pa_port_map.keys()
1146 of_ports.sort()
1147
1148 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001149
1150 # Install a flow with wildcards
1151 self.installFlow(999, of_ports[0], of_ports[1],
1152 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001153 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001154 # Install a flow with no wildcards for our packet
1155 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001156 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001157 # Install a flow with wildcards for our packet with higher
1158 # priority
1159 self.installFlow(1001, of_ports[0], of_ports[3])
1160 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001161
1162
Ken Chiang3978f242012-06-13 14:14:09 -07001163class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001164 """
1165 1. Add exact match flow, verify packet received.
1166 2. Add wildcard flow with higher priority, verify packet received on port
1167 specified by this flow.
1168 3. Add exact match flow with even higher priority, verify packet received
1169 on port specified by this flow.
1170 4. Delete lowest priority flow, verify packet received on port specified
1171 by highest priority flow.
1172 5. Delete highest priority flow, verify packet received on port specified
1173 by remaining flow.
1174 """
1175
1176 def runTest(self):
1177
1178 self._Init()
1179
1180 of_ports = pa_port_map.keys()
1181 of_ports.sort()
1182
1183 self._ClearTable()
1184
1185 # Install an exact match flow
1186 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1187 self.verifyFlow(of_ports[0], of_ports[1])
1188 # Install a flow with wildcards of higher priority
1189 self.installFlow(1250, of_ports[0], of_ports[2],
1190 wildcards=ofp.OFPFW_DL_DST)
1191 self.verifyFlow(of_ports[0], of_ports[2])
1192 # Install an exact match flow with even higher priority
1193 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1194 self.verifyFlow(of_ports[0], of_ports[3])
1195 # Delete lowest priority flow
1196 self.removeFlow(250)
1197 self.verifyFlow(of_ports[0], of_ports[3])
1198 # Delete highest priority flow
1199 self.removeFlow(2001)
1200 self.verifyFlow(of_ports[0], of_ports[2])
1201
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001202
Dan Talayco551befa2010-07-15 17:05:32 -07001203class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001204 """
1205 Exercise wildcard matching for all ports
1206
1207 Generate a packet
1208 Generate and install a matching flow with wildcard mask
1209 Add action to forward to a port
1210 Send the packet to the port
1211 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001212 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001213 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001214 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001215 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001216 for wc in WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001217 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001218 # Set nonzero VLAN id to avoid sending priority-tagged packet
1219 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001220 else:
1221 dl_vlan = -1
1222 flow_match_test(self, pa_port_map, wildcards=wc,
1223 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001224
Dan Talayco551befa2010-07-15 17:05:32 -07001225class SingleWildcardMatchTagged(BaseMatchCase):
1226 """
1227 SingleWildcardMatch with tagged packets
1228 """
1229 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001230 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001231 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001232 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001233 max_test=10)
1234
1235class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001236 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001237 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001238
1239 Generate a packet
1240 Generate and install a matching flow with wildcard all except one filed
1241 Add action to forward to a port
1242 Send the packet to the port
1243 Verify the packet is received at all other ports (one port at a time)
1244 Verify flow_expiration message is correct when command option is set
1245 """
1246 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001247 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001248 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001249 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001250 # Set nonzero VLAN id to avoid sending priority-tagged packet
1251 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001252 else:
1253 dl_vlan = -1
1254 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1255 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001256
Dan Talayco551befa2010-07-15 17:05:32 -07001257class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1258 """
1259 Match one field with tagged packets
1260 """
1261 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001262 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001263 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001264 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1265 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001266
1267class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001268 """
1269 Create Wildcard-all flow and exercise for all ports
1270
1271 Generate a packet
1272 Generate and install a matching flow with wildcard-all
1273 Add action to forward to a port
1274 Send the packet to the port
1275 Verify the packet is received at all other ports (one port at a time)
1276 Verify flow_expiration message is correct when command option is set
1277 """
1278 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -07001279 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001280
Dan Talayco551befa2010-07-15 17:05:32 -07001281class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001282 """
Dan Talayco551befa2010-07-15 17:05:32 -07001283 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001284 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001285 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001286 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -07001287 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
1288 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001289
Dan Talaycoba3745c2010-07-21 21:51:08 -07001290
Dan Talayco551befa2010-07-15 17:05:32 -07001291class AddVLANTag(BaseMatchCase):
1292 """
1293 Add a VLAN tag to an untagged packet
1294 """
1295 def runTest(self):
1296 new_vid = 2
1297 sup_acts = supported_actions_get(self)
1298 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001299 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001300 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001301
Dan Talayco551befa2010-07-15 17:05:32 -07001302 len = 100
1303 len_w_vid = 104
1304 pkt = simple_tcp_packet(pktlen=len)
1305 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1306 dl_vlan=new_vid)
1307 vid_act = action.action_set_vlan_vid()
1308 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001309
Dan Talayco551befa2010-07-15 17:05:32 -07001310 flow_match_test(self, pa_port_map, pkt=pkt,
1311 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001312
Dan Talayco551befa2010-07-15 17:05:32 -07001313class PacketOnly(basic.DataPlaneOnly):
1314 """
1315 Just send a packet thru the switch
1316 """
1317 def runTest(self):
1318 pkt = simple_tcp_packet()
1319 of_ports = pa_port_map.keys()
1320 of_ports.sort()
1321 ing_port = of_ports[0]
1322 pa_logger.info("Sending packet to " + str(ing_port))
1323 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1324 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001325
Dan Talayco551befa2010-07-15 17:05:32 -07001326class PacketOnlyTagged(basic.DataPlaneOnly):
1327 """
1328 Just send a packet thru the switch
1329 """
1330 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001331 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001332 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
1333 of_ports = pa_port_map.keys()
1334 of_ports.sort()
1335 ing_port = of_ports[0]
1336 pa_logger.info("Sending packet to " + str(ing_port))
1337 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1338 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001339
Dan Talayco551befa2010-07-15 17:05:32 -07001340test_prio["PacketOnly"] = -1
1341test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001342
Dan Talayco551befa2010-07-15 17:05:32 -07001343class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001344 """
1345 Modify the VLAN ID in the VLAN tag of a tagged packet
1346 """
Dan Talayco551befa2010-07-15 17:05:32 -07001347 def runTest(self):
1348 old_vid = 2
1349 new_vid = 3
1350 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001351 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001352 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001353 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001354
Dan Talayco551befa2010-07-15 17:05:32 -07001355 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1356 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1357 vid_act = action.action_set_vlan_vid()
1358 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001359
Dan Talayco551befa2010-07-15 17:05:32 -07001360 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1361 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001362
Ken Chiange9a211d2012-04-20 14:52:11 -07001363class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1364 """
1365 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1366 The same flow should match on both untagged and tagged packets.
1367 """
1368 def runTest(self):
1369 old_vid = 2
1370 new_vid = 3
1371 sup_acts = supported_actions_get(self)
1372 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1373 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1374 return
1375
1376 of_ports = pa_port_map.keys()
1377 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1378 ing_port = of_ports[0]
1379 egr_ports = of_ports[1]
1380
1381 rv = delete_all_flows(self.controller, pa_logger)
1382 self.assertEqual(rv, 0, "Failed to delete all flows")
1383
1384 len_untagged = 100
1385 len_w_vid = 104
1386 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1387 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1388 dl_vlan_enable=True, dl_vlan=old_vid)
1389 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1390 dl_vlan=new_vid)
1391 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP
1392 vid_act = action.action_set_vlan_vid()
1393 vid_act.vlan_vid = new_vid
1394 request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
1395 wildcards=wildcards, egr_ports=egr_ports,
1396 action_list=[vid_act])
1397 flow_msg_install(self, request)
1398
1399 pa_logger.debug("Send untagged packet: " + str(ing_port) + " to " +
1400 str(egr_ports))
1401 self.dataplane.send(ing_port, str(untagged_pkt))
1402 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1403
1404 pa_logger.debug("Send tagged packet: " + str(ing_port) + " to " +
1405 str(egr_ports))
1406 self.dataplane.send(ing_port, str(tagged_pkt))
1407 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1408
Howard Pershc1199d52012-04-11 14:21:32 -07001409class ModifyVlanPcp(BaseMatchCase):
1410 """
1411 Modify the priority field of the VLAN tag of a tagged packet
1412 """
1413 def runTest(self):
1414 vid = 123
1415 old_vlan_pcp = 2
1416 new_vlan_pcp = 3
1417 sup_acts = supported_actions_get(self)
Ed Swierk8c3af7f2012-04-24 14:19:17 -07001418 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_PCP):
1419 skip_message_emit(self, "Modify VLAN priority test")
Howard Pershc1199d52012-04-11 14:21:32 -07001420 return
1421
1422 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=old_vlan_pcp)
1423 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=new_vlan_pcp)
1424 vid_act = action.action_set_vlan_pcp()
1425 vid_act.vlan_pcp = new_vlan_pcp
1426
1427 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1428 action_list=[vid_act])
1429
Dan Talayco551befa2010-07-15 17:05:32 -07001430class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001431 """
1432 Strip the VLAN tag from a tagged packet
1433 """
Dan Talayco551befa2010-07-15 17:05:32 -07001434 def runTest(self):
1435 old_vid = 2
1436 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001437 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001438 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001439 return
Dan Talaycof36f1082010-07-13 13:57:17 -07001440
Dan Talayco551befa2010-07-15 17:05:32 -07001441 len_w_vid = 104
1442 len = 100
1443 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1444 dl_vlan=old_vid)
1445 exp_pkt = simple_tcp_packet(pktlen=len)
1446 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001447
Dan Talayco551befa2010-07-15 17:05:32 -07001448 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1449 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001450
Ken Chiange9a211d2012-04-20 14:52:11 -07001451class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
1452 """
1453 Strip the VLAN tag from a tagged packet.
1454 Differs from StripVLANTag in that VID and PCP are both wildcarded.
1455 """
1456 def runTest(self):
1457 old_vid = 2
1458 sup_acts = supported_actions_get(self)
1459 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
1460 skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
1461 return
1462
1463 len_w_vid = 104
1464 len_untagged = 100
1465 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1466 dl_vlan=old_vid)
1467 exp_pkt = simple_tcp_packet(pktlen=len_untagged)
1468 vid_act = action.action_strip_vlan()
1469
1470 flow_match_test(self, pa_port_map,
1471 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP,
1472 pkt=pkt, exp_pkt=exp_pkt,
1473 action_list=[vid_act])
1474
Dan Talayco4b2bee62010-07-20 14:10:05 -07001475def init_pkt_args():
1476 """
1477 Pass back a dictionary with default packet arguments
1478 """
1479 args = {}
1480 args["dl_src"] = '00:23:45:67:89:AB'
1481
1482 dl_vlan_enable=False
1483 dl_vlan=-1
1484 if pa_config["test-params"]["vid"]:
1485 dl_vlan_enable=True
1486 dl_vlan = pa_config["test-params"]["vid"]
1487
1488# Unpack operator is ** on a dictionary
1489
1490 return args
1491
Dan Talayco551befa2010-07-15 17:05:32 -07001492class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001493 """
1494 Modify the source MAC address (TP1)
1495 """
Dan Talayco551befa2010-07-15 17:05:32 -07001496 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001497 sup_acts = supported_actions_get(self)
1498 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001499 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001500 return
1501
1502 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1503 check_test_params=True)
1504 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1505 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001506
Dan Talayco551befa2010-07-15 17:05:32 -07001507class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001508 """
1509 Modify the dest MAC address (TP1)
1510 """
Dan Talayco551befa2010-07-15 17:05:32 -07001511 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001512 sup_acts = supported_actions_get(self)
1513 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001514 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001515 return
1516
1517 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1518 check_test_params=True)
1519 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1520 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001521
Dan Talayco551befa2010-07-15 17:05:32 -07001522class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001523 """
1524 Modify the source IP address of an IP packet (TP1)
1525 """
Dan Talayco551befa2010-07-15 17:05:32 -07001526 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001527 sup_acts = supported_actions_get(self)
1528 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001529 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001530 return
1531
1532 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1533 check_test_params=True)
1534 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1535 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001536
Dan Talayco551befa2010-07-15 17:05:32 -07001537class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001538 """
1539 Modify the dest IP address of an IP packet (TP1)
1540 """
Dan Talayco551befa2010-07-15 17:05:32 -07001541 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001542 sup_acts = supported_actions_get(self)
1543 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001544 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001545 return
1546
1547 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1548 check_test_params=True)
1549 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1550 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001551
1552class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001553 """
1554 Modify the source TCP port of a TCP packet (TP1)
1555 """
Dan Talayco551befa2010-07-15 17:05:32 -07001556 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001557 sup_acts = supported_actions_get(self)
1558 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001559 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001560 return
1561
1562 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1563 check_test_params=True)
1564 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1565 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001566
1567class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001568 """
1569 Modify the dest TCP port of a TCP packet (TP1)
1570 """
Dan Talayco551befa2010-07-15 17:05:32 -07001571 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001572 sup_acts = supported_actions_get(self)
1573 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001574 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001575 return
1576
1577 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1578 check_test_params=True)
1579 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1580 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001581
1582class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001583 """
1584 Modify the IP type of service of an IP packet (TP1)
1585 """
Dan Talayco551befa2010-07-15 17:05:32 -07001586 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001587 sup_acts = supported_actions_get(self)
1588 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001589 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001590 return
Dan Talayco551befa2010-07-15 17:05:32 -07001591
Dan Talayco4b2bee62010-07-20 14:10:05 -07001592 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1593 check_test_params=True)
1594 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001595 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001596
Dan Talaycof6e76c02012-03-23 10:56:12 -07001597class ModifyL2DstMC(BaseMatchCase):
1598 """
1599 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001600 """
1601 def runTest(self):
1602 sup_acts = supported_actions_get(self)
1603 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001604 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001605 return
1606
Dan Talaycof6e76c02012-03-23 10:56:12 -07001607 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1608 check_test_params=True)
1609 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001610 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001611
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001612class ModifyL2DstIngress(BaseMatchCase):
1613 """
1614 Modify the L2 dest and send to the ingress port
1615 """
1616 def runTest(self):
1617 sup_acts = supported_actions_get(self)
1618 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001619 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001620 return
1621
1622 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1623 check_test_params=True)
1624 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1625 action_list=acts, max_test=2, egr_count=0,
1626 ing_port=True)
1627
Dan Talaycod8ae7582012-03-23 12:24:56 -07001628class ModifyL2DstIngressMC(BaseMatchCase):
1629 """
1630 Modify the L2 dest and send to the ingress port
1631 """
1632 def runTest(self):
1633 sup_acts = supported_actions_get(self)
1634 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1635 skip_message_emit(self, "ModifyL2dstMC test")
1636 return
1637
1638 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1639 check_test_params=True)
1640 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1641 action_list=acts, max_test=2, egr_count=-1,
1642 ing_port=True)
1643
Dan Talaycof6e76c02012-03-23 10:56:12 -07001644class ModifyL2SrcMC(BaseMatchCase):
1645 """
1646 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001647 """
1648 def runTest(self):
1649 sup_acts = supported_actions_get(self)
1650 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001651 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001652 return
1653
Dan Talaycof6e76c02012-03-23 10:56:12 -07001654 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1655 check_test_params=True)
1656 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001657 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001658
1659class ModifyL2SrcDstMC(BaseMatchCase):
1660 """
1661 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001662 """
1663 def runTest(self):
1664 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001665 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1666 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1667 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001668 return
1669
Dan Talaycof6e76c02012-03-23 10:56:12 -07001670 mod_fields = ['dl_dst', 'dl_src']
1671 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1672 check_test_params=True)
1673 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001674 action_list=acts, max_test=2, egr_count=-1)
1675
1676class ModifyL2DstVIDMC(BaseMatchCase):
1677 """
1678 Modify the L2 dest and send to 2 ports
1679 """
1680 def runTest(self):
1681 sup_acts = supported_actions_get(self)
1682 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1683 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1684 skip_message_emit(self, "ModifyL2DstVIDMC test")
1685 return
1686
1687 mod_fields = ['dl_dst', 'dl_vlan']
1688 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1689 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1690 check_test_params=True)
1691 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1692 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001693
Dan Talaycofa6454f2012-04-05 10:04:13 -07001694class FlowToggle(BaseMatchCase):
1695 """
1696 Add flows to the table and modify them repeatedly
Dan Talaycof7c41312012-07-23 12:53:19 -07001697
1698 This is done by using only "add" flow messages. Since the check overlap
1699 flag is not set, the switch is supposed to modify the existing flow if
1700 the match already exists.
1701
1702 Would probably be better to exercise more of the flow modify commands
1703 (add, modify, delete +/- strict).
Dan Talaycofa6454f2012-04-05 10:04:13 -07001704 """
1705 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001706 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1707 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001708
1709 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1710 (flow_count, iter_count))
1711 acts = []
1712 acts.append(action.action_output())
1713 acts.append(action.action_output())
1714
1715 of_ports = pa_port_map.keys()
1716 if len(of_ports) < 3:
1717 self.assertTrue(False, "Too few ports for test")
1718
1719 for idx in range(2):
1720 acts[idx].port = of_ports[idx]
1721
1722 flows = []
1723 flows.append([])
1724 flows.append([])
1725
Dan Talayco50be7672012-04-05 11:38:08 -07001726 wildcards = ofp.OFPFW_DL_SRC | ofp.OFPFW_DL_DST
Dan Talaycofa6454f2012-04-05 10:04:13 -07001727 # Create up the flows in an array
1728 for toggle in range(2):
1729 for f_idx in range(flow_count):
1730 pkt = simple_tcp_packet(tcp_sport=f_idx)
1731 msg = message.flow_mod()
1732 match = parse.packet_to_flow_match(pkt)
Shudong Zhou031373c2012-07-19 17:37:42 -07001733 match.in_port = of_ports[2]
Dan Talayco50be7672012-04-05 11:38:08 -07001734 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001735 msg.match = match
1736 msg.buffer_id = 0xffffffff
Dan Talaycof7c41312012-07-23 12:53:19 -07001737 msg.command = ofp.OFPFC_ADD
Dan Talaycofa6454f2012-04-05 10:04:13 -07001738 msg.actions.add(acts[toggle])
1739 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001740
1741 # Show two sample flows
1742 pa_logger.debug(flows[0][0].show())
1743 pa_logger.debug(flows[1][0].show())
1744
Dan Talaycofa6454f2012-04-05 10:04:13 -07001745 # Install the first set of flows
1746 for f_idx in range(flow_count):
1747 rv = self.controller.message_send(flows[0][f_idx])
1748 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001749 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001750
1751 pa_logger.info("Installed %d flows" % flow_count)
1752
1753 # Repeatedly modify all the flows back and forth
1754 updates = 0
1755 # Report status about 5 times
1756 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001757 start = time.time()
1758 for iter_idx in range(iter_count):
1759 if not iter_idx % mod_val:
1760 pa_logger.info("Flow Toggle: iter %d of %d. " %
1761 (iter_idx, iter_count) +
1762 "%d updates in %d secs" %
1763 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001764 for toggle in range(2):
1765 t_idx = 1 - toggle
1766 for f_idx in range(flow_count):
1767 rv = self.controller.message_send(flows[t_idx][f_idx])
1768 updates += 1
1769 self.assertTrue(rv != -1, "Error modifying flow %d" %
1770 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001771 self.assertEqual(do_barrier(self.controller), 0,
1772 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001773
1774 end = time.time()
1775 divisor = end - start or (end - start + 1)
1776 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1777 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1778 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001779
1780
Dan Talayco8a64e332012-03-28 14:53:20 -07001781# You can pick and choose these by commenting tests in or out
1782iter_classes = [
1783 basic.PacketIn,
1784 basic.PacketOut,
1785 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001786 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001787 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001788 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001789 AllWildcardMatch,
1790 AllWildcardMatchTagged,
1791 SingleWildcardMatch,
1792 SingleWildcardMatchTagged,
1793 ExactMatch,
1794 ExactMatchTagged,
1795 SingleWildcardMatch,
1796 ModifyL2Src,
1797 ModifyL2Dst,
1798 ModifyL2SrcMC,
1799 ModifyL2DstMC,
1800 ModifyL2SrcDstMC
1801 ]
1802
1803class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001804 """
1805 Iterate over a bunch of test cases
1806
1807 The cases come from the list above
1808 """
1809
Dan Talayco8a64e332012-03-28 14:53:20 -07001810 def runTest(self):
1811 count = test_param_get(self.config, 'iter_count', default=10)
1812 tests_done = 0
1813 pa_logger.info("Running iteration test " + str(count) + " times")
1814 start = time.time()
1815 last = start
1816 for idx in range(count):
1817 pa_logger.info("Iteration " + str(idx + 1))
1818 for cls in iter_classes:
1819 test = cls()
1820 test.inheritSetup(self)
1821 test.runTest()
1822 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001823 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001824 if time.time() - last > 60:
1825 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001826 pa_logger.info(
1827 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1828 (idx, count, tests_done, last - start) +
1829 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001830 stats = all_stats_get(self)
1831 last = time.time()
1832 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1833 (tests_done, last - start))
1834 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1835 (stats["flows"], stats["packets"], stats["bytes"]))
1836 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1837 (stats["active"], stats["lookups"], stats["matched"]))
1838
1839# Don't run by default
1840test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001841
Dan Talayco4b2bee62010-07-20 14:10:05 -07001842#@todo Need to implement tagged versions of the above tests
1843#
1844#@todo Implement a test case that strips tag 2, adds tag 3
1845# and modifies tag 4 to tag 5. Then verify (in addition) that
1846# tag 6 does not get modified.
1847
1848class MixedVLAN(BaseMatchCase):
1849 """
1850 Test mixture of VLAN tag actions
1851
1852 Strip tag 2 on port 1, send to port 2
1853 Add tag 3 on port 1, send to port 2
1854 Modify tag 4 to 5 on port 1, send to port 2
1855 All other traffic from port 1, send to port 3
1856 All traffic from port 2 sent to port 4
1857 Use exact matches with different packets for all mods
1858 Verify the following: (port, vid)
1859 (port 1, vid 2) => VLAN tag stripped, out port 2
1860 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1861 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1862 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1863 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1864 (port 2, no tag) => untagged packet out port 4
1865 (port 2, vid 2-6) => unmodified packet out port 4
1866
1867 Variation: Might try sending VID 5 to port 3 and check.
1868 If only VID 5 distinguishes pkt, this will fail on some platforms
1869 """
1870
1871test_prio["MixedVLAN"] = -1
1872
Dan Talayco551befa2010-07-15 17:05:32 -07001873def supported_actions_get(parent, use_cache=True):
1874 """
1875 Get the bitmap of supported actions from the switch
1876 If use_cache is false, the cached value will be updated
1877 """
1878 global cached_supported_actions
1879 if cached_supported_actions is None or not use_cache:
1880 request = message.features_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -07001881 (reply, pkt) = parent.controller.transact(request)
Dan Talayco551befa2010-07-15 17:05:32 -07001882 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1883 cached_supported_actions = reply.actions
1884 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1885
1886 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001887
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001888if __name__ == "__main__":
1889 print "Please run through oft script: ./oft --test_spec=basic"