blob: 78bdab726ecf61681cdbe7e27fcf974e6b0c5470 [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 Townsend50c82462012-03-28 18:26:14 -07001048 self.installFlow(prioHigher, portA, portC)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001049 self.installFlow(prioLower, portA, portB)
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001050
1051 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001052 self.verifyFlow(portA, portB)
1053 self.removeFlow(prioLower)
1054 # Sanity check flow at lower priority from pA to pC
1055 self.installFlow(prioLower, portA, portC)
1056 self.verifyFlow(portA, portC)
1057 self.removeFlow(prioLower)
1058
1059 # Install and verify pA->pB @ prioLower
1060 self.installFlow(prioLower, portA, portB)
1061 self.verifyFlow(portA, portB)
1062
1063 # Install and verify pA->pC @ prioHigher, should override pA->pB
1064 self.installFlow(prioHigher, portA, portC)
1065 self.verifyFlow(portA, portC)
1066 # remove pA->pC
1067 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001068 # Old flow pA -> pB @ prioLower should still be active
1069 self.verifyFlow(portA, portB)
1070 self.removeFlow(prioLower)
1071
1072 # Table should be empty at this point, leave it alone as
1073 # an assumption for future test runs
1074
1075
1076
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001077 def installFlow(self, prio, inp, egp,
1078 wildcards=ofp.OFPFW_DL_SRC):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001079 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001080 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001081 egr_ports=egp)
1082 request.priority = prio
Ken Chiang38d7a152012-05-24 15:33:50 -07001083 self.logger.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001084 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001085 self.flowMsgs[prio] = request
1086
1087 def removeFlow(self, prio):
1088 if self.flowMsgs.has_key(prio):
1089 msg = self.flowMsgs[prio]
1090 msg.command = ofp.OFPFC_DELETE_STRICT
1091 # This *must* be set for DELETE
1092 msg.out_port = ofp.OFPP_NONE
Ken Chiang38d7a152012-05-24 15:33:50 -07001093 self.logger.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001094 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001095 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001096 else:
1097 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001098
1099
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001100 def verifyFlow(self, inp, egp, pkt=None):
1101 if pkt == None:
1102 pkt = self.pkt
1103
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001104 self.logger.info("Pkt match test: " + str(inp) +
1105 " to " + str(egp))
1106 self.logger.debug("Send packet: " + str(inp) + " to "
1107 + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001108 self.dataplane.send(inp, str(pkt))
1109 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001110
1111
1112
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001113class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1114
1115 def runTest(self):
1116
1117 self._Init()
1118
1119 of_ports = pa_port_map.keys()
1120 of_ports.sort()
1121
1122 # Install an entry from 0 -> 1 @ prio 1000
1123 self._ClearTable()
1124 self.installFlow(1000, of_ports[0], of_ports[1])
1125 self.verifyFlow(of_ports[0], of_ports[1])
1126 self.installFlow(1000, of_ports[1], of_ports[0])
1127 self.verifyFlow(of_ports[1], of_ports[0])
1128 self.installFlow(1001, of_ports[0], of_ports[1])
1129 self.verifyFlow(of_ports[0], of_ports[1])
1130 self.installFlow(1001, of_ports[1], of_ports[0])
1131 self.verifyFlow(of_ports[1], of_ports[0])
1132 self.removeFlow(1001)
1133 self.verifyFlow(of_ports[0], of_ports[1])
1134 self.removeFlow(1000)
1135
1136
1137
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001138class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001139 """
1140 1. Add wildcard flow, verify packet received.
1141 2. Add exact match flow with higher priority, verify packet received
1142 on port specified by this flow.
1143 3. Add wildcard flow with even higher priority, verify packet received
1144 on port specified by this flow.
1145 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001146
1147 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001148
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001149 self._Init()
1150
1151 of_ports = pa_port_map.keys()
1152 of_ports.sort()
1153
1154 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001155
1156 # Install a flow with wildcards
1157 self.installFlow(999, of_ports[0], of_ports[1],
1158 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001159 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001160 # Install a flow with no wildcards for our packet
1161 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001162 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001163 # Install a flow with wildcards for our packet with higher
1164 # priority
1165 self.installFlow(1001, of_ports[0], of_ports[3])
1166 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001167
1168
Ken Chiang3978f242012-06-13 14:14:09 -07001169class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001170 """
1171 1. Add exact match flow, verify packet received.
1172 2. Add wildcard flow with higher priority, verify packet received on port
1173 specified by this flow.
1174 3. Add exact match flow with even higher priority, verify packet received
1175 on port specified by this flow.
1176 4. Delete lowest priority flow, verify packet received on port specified
1177 by highest priority flow.
1178 5. Delete highest priority flow, verify packet received on port specified
1179 by remaining flow.
1180 """
1181
1182 def runTest(self):
1183
1184 self._Init()
1185
1186 of_ports = pa_port_map.keys()
1187 of_ports.sort()
1188
1189 self._ClearTable()
1190
1191 # Install an exact match flow
1192 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1193 self.verifyFlow(of_ports[0], of_ports[1])
1194 # Install a flow with wildcards of higher priority
1195 self.installFlow(1250, of_ports[0], of_ports[2],
1196 wildcards=ofp.OFPFW_DL_DST)
1197 self.verifyFlow(of_ports[0], of_ports[2])
1198 # Install an exact match flow with even higher priority
1199 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1200 self.verifyFlow(of_ports[0], of_ports[3])
1201 # Delete lowest priority flow
1202 self.removeFlow(250)
1203 self.verifyFlow(of_ports[0], of_ports[3])
1204 # Delete highest priority flow
1205 self.removeFlow(2001)
1206 self.verifyFlow(of_ports[0], of_ports[2])
1207
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001208
Dan Talayco551befa2010-07-15 17:05:32 -07001209class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001210 """
1211 Exercise wildcard matching for all ports
1212
1213 Generate a packet
1214 Generate and install a matching flow with wildcard mask
1215 Add action to forward to a port
1216 Send the packet to the port
1217 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001218 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001219 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001220 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001221 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001222 for wc in WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001223 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001224 # Set nonzero VLAN id to avoid sending priority-tagged packet
1225 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001226 else:
1227 dl_vlan = -1
1228 flow_match_test(self, pa_port_map, wildcards=wc,
1229 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001230
Dan Talayco551befa2010-07-15 17:05:32 -07001231class SingleWildcardMatchTagged(BaseMatchCase):
1232 """
1233 SingleWildcardMatch with tagged packets
1234 """
1235 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001236 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001237 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001238 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001239 max_test=10)
1240
1241class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001242 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001243 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001244
1245 Generate a packet
1246 Generate and install a matching flow with wildcard all except one filed
1247 Add action to forward to a port
1248 Send the packet to the port
1249 Verify the packet is received at all other ports (one port at a time)
1250 Verify flow_expiration message is correct when command option is set
1251 """
1252 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001253 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001254 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001255 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001256 # Set nonzero VLAN id to avoid sending priority-tagged packet
1257 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001258 else:
1259 dl_vlan = -1
1260 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1261 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001262
Dan Talayco551befa2010-07-15 17:05:32 -07001263class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1264 """
1265 Match one field with tagged packets
1266 """
1267 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001268 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001269 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001270 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1271 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001272
1273class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001274 """
1275 Create Wildcard-all flow and exercise for all ports
1276
1277 Generate a packet
1278 Generate and install a matching flow with wildcard-all
1279 Add action to forward to a port
1280 Send the packet to the port
1281 Verify the packet is received at all other ports (one port at a time)
1282 Verify flow_expiration message is correct when command option is set
1283 """
1284 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -07001285 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001286
Dan Talayco551befa2010-07-15 17:05:32 -07001287class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001288 """
Dan Talayco551befa2010-07-15 17:05:32 -07001289 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001290 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001291 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001292 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -07001293 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
1294 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001295
Dan Talaycoba3745c2010-07-21 21:51:08 -07001296
Dan Talayco551befa2010-07-15 17:05:32 -07001297class AddVLANTag(BaseMatchCase):
1298 """
1299 Add a VLAN tag to an untagged packet
1300 """
1301 def runTest(self):
1302 new_vid = 2
1303 sup_acts = supported_actions_get(self)
1304 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001305 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001306 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001307
Dan Talayco551befa2010-07-15 17:05:32 -07001308 len = 100
1309 len_w_vid = 104
1310 pkt = simple_tcp_packet(pktlen=len)
1311 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1312 dl_vlan=new_vid)
1313 vid_act = action.action_set_vlan_vid()
1314 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001315
Dan Talayco551befa2010-07-15 17:05:32 -07001316 flow_match_test(self, pa_port_map, pkt=pkt,
1317 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001318
Dan Talayco551befa2010-07-15 17:05:32 -07001319class PacketOnly(basic.DataPlaneOnly):
1320 """
1321 Just send a packet thru the switch
1322 """
1323 def runTest(self):
1324 pkt = simple_tcp_packet()
1325 of_ports = pa_port_map.keys()
1326 of_ports.sort()
1327 ing_port = of_ports[0]
1328 pa_logger.info("Sending packet to " + str(ing_port))
1329 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1330 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001331
Dan Talayco551befa2010-07-15 17:05:32 -07001332class PacketOnlyTagged(basic.DataPlaneOnly):
1333 """
1334 Just send a packet thru the switch
1335 """
1336 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001337 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001338 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
1339 of_ports = pa_port_map.keys()
1340 of_ports.sort()
1341 ing_port = of_ports[0]
1342 pa_logger.info("Sending packet to " + str(ing_port))
1343 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1344 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001345
Dan Talayco551befa2010-07-15 17:05:32 -07001346test_prio["PacketOnly"] = -1
1347test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001348
Dan Talayco551befa2010-07-15 17:05:32 -07001349class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001350 """
1351 Modify the VLAN ID in the VLAN tag of a tagged packet
1352 """
Dan Talayco551befa2010-07-15 17:05:32 -07001353 def runTest(self):
1354 old_vid = 2
1355 new_vid = 3
1356 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001357 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001358 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001359 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001360
Dan Talayco551befa2010-07-15 17:05:32 -07001361 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1362 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1363 vid_act = action.action_set_vlan_vid()
1364 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001365
Dan Talayco551befa2010-07-15 17:05:32 -07001366 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1367 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001368
Ken Chiange9a211d2012-04-20 14:52:11 -07001369class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1370 """
1371 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1372 The same flow should match on both untagged and tagged packets.
1373 """
1374 def runTest(self):
1375 old_vid = 2
1376 new_vid = 3
1377 sup_acts = supported_actions_get(self)
1378 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1379 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1380 return
1381
1382 of_ports = pa_port_map.keys()
1383 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1384 ing_port = of_ports[0]
1385 egr_ports = of_ports[1]
1386
1387 rv = delete_all_flows(self.controller, pa_logger)
1388 self.assertEqual(rv, 0, "Failed to delete all flows")
1389
1390 len_untagged = 100
1391 len_w_vid = 104
1392 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1393 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1394 dl_vlan_enable=True, dl_vlan=old_vid)
1395 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1396 dl_vlan=new_vid)
1397 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP
1398 vid_act = action.action_set_vlan_vid()
1399 vid_act.vlan_vid = new_vid
1400 request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
1401 wildcards=wildcards, egr_ports=egr_ports,
1402 action_list=[vid_act])
1403 flow_msg_install(self, request)
1404
1405 pa_logger.debug("Send untagged packet: " + str(ing_port) + " to " +
1406 str(egr_ports))
1407 self.dataplane.send(ing_port, str(untagged_pkt))
1408 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1409
1410 pa_logger.debug("Send tagged packet: " + str(ing_port) + " to " +
1411 str(egr_ports))
1412 self.dataplane.send(ing_port, str(tagged_pkt))
1413 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1414
Howard Pershc1199d52012-04-11 14:21:32 -07001415class ModifyVlanPcp(BaseMatchCase):
1416 """
1417 Modify the priority field of the VLAN tag of a tagged packet
1418 """
1419 def runTest(self):
1420 vid = 123
1421 old_vlan_pcp = 2
1422 new_vlan_pcp = 3
1423 sup_acts = supported_actions_get(self)
Ed Swierk8c3af7f2012-04-24 14:19:17 -07001424 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_PCP):
1425 skip_message_emit(self, "Modify VLAN priority test")
Howard Pershc1199d52012-04-11 14:21:32 -07001426 return
1427
1428 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=old_vlan_pcp)
1429 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=new_vlan_pcp)
1430 vid_act = action.action_set_vlan_pcp()
1431 vid_act.vlan_pcp = new_vlan_pcp
1432
1433 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1434 action_list=[vid_act])
1435
Dan Talayco551befa2010-07-15 17:05:32 -07001436class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001437 """
1438 Strip the VLAN tag from a tagged packet
1439 """
Dan Talayco551befa2010-07-15 17:05:32 -07001440 def runTest(self):
1441 old_vid = 2
1442 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001443 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001444 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001445 return
Dan Talaycof36f1082010-07-13 13:57:17 -07001446
Dan Talayco551befa2010-07-15 17:05:32 -07001447 len_w_vid = 104
1448 len = 100
1449 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1450 dl_vlan=old_vid)
1451 exp_pkt = simple_tcp_packet(pktlen=len)
1452 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001453
Dan Talayco551befa2010-07-15 17:05:32 -07001454 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1455 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001456
Ken Chiange9a211d2012-04-20 14:52:11 -07001457class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
1458 """
1459 Strip the VLAN tag from a tagged packet.
1460 Differs from StripVLANTag in that VID and PCP are both wildcarded.
1461 """
1462 def runTest(self):
1463 old_vid = 2
1464 sup_acts = supported_actions_get(self)
1465 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
1466 skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
1467 return
1468
1469 len_w_vid = 104
1470 len_untagged = 100
1471 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1472 dl_vlan=old_vid)
1473 exp_pkt = simple_tcp_packet(pktlen=len_untagged)
1474 vid_act = action.action_strip_vlan()
1475
1476 flow_match_test(self, pa_port_map,
1477 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP,
1478 pkt=pkt, exp_pkt=exp_pkt,
1479 action_list=[vid_act])
1480
Dan Talayco4b2bee62010-07-20 14:10:05 -07001481def init_pkt_args():
1482 """
1483 Pass back a dictionary with default packet arguments
1484 """
1485 args = {}
1486 args["dl_src"] = '00:23:45:67:89:AB'
1487
1488 dl_vlan_enable=False
1489 dl_vlan=-1
1490 if pa_config["test-params"]["vid"]:
1491 dl_vlan_enable=True
1492 dl_vlan = pa_config["test-params"]["vid"]
1493
1494# Unpack operator is ** on a dictionary
1495
1496 return args
1497
Dan Talayco551befa2010-07-15 17:05:32 -07001498class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001499 """
1500 Modify the source MAC address (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_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001505 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001506 return
1507
1508 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
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)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001512
Dan Talayco551befa2010-07-15 17:05:32 -07001513class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001514 """
1515 Modify the dest MAC address (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_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001520 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001521 return
1522
1523 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
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)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001527
Dan Talayco551befa2010-07-15 17:05:32 -07001528class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001529 """
1530 Modify the source IP address 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_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001535 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001536 return
1537
1538 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1539 check_test_params=True)
1540 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1541 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001542
Dan Talayco551befa2010-07-15 17:05:32 -07001543class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001544 """
1545 Modify the dest IP address of an IP packet (TP1)
1546 """
Dan Talayco551befa2010-07-15 17:05:32 -07001547 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001548 sup_acts = supported_actions_get(self)
1549 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001550 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001551 return
1552
1553 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1554 check_test_params=True)
1555 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1556 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001557
1558class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001559 """
1560 Modify the source TCP port of a TCP packet (TP1)
1561 """
Dan Talayco551befa2010-07-15 17:05:32 -07001562 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001563 sup_acts = supported_actions_get(self)
1564 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001565 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001566 return
1567
1568 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
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)
Dan Talayco551befa2010-07-15 17:05:32 -07001572
1573class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001574 """
1575 Modify the dest TCP port of a TCP packet (TP1)
1576 """
Dan Talayco551befa2010-07-15 17:05:32 -07001577 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001578 sup_acts = supported_actions_get(self)
1579 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001580 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001581 return
1582
1583 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1584 check_test_params=True)
1585 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1586 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001587
1588class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001589 """
1590 Modify the IP type of service of an IP packet (TP1)
1591 """
Dan Talayco551befa2010-07-15 17:05:32 -07001592 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001593 sup_acts = supported_actions_get(self)
1594 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001595 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001596 return
Dan Talayco551befa2010-07-15 17:05:32 -07001597
Dan Talayco4b2bee62010-07-20 14:10:05 -07001598 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1599 check_test_params=True)
1600 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001601 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001602
Dan Talaycof6e76c02012-03-23 10:56:12 -07001603class ModifyL2DstMC(BaseMatchCase):
1604 """
1605 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001606 """
1607 def runTest(self):
1608 sup_acts = supported_actions_get(self)
1609 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001610 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001611 return
1612
Dan Talaycof6e76c02012-03-23 10:56:12 -07001613 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1614 check_test_params=True)
1615 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001616 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001617
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001618class ModifyL2DstIngress(BaseMatchCase):
1619 """
1620 Modify the L2 dest and send to the ingress port
1621 """
1622 def runTest(self):
1623 sup_acts = supported_actions_get(self)
1624 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001625 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001626 return
1627
1628 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1629 check_test_params=True)
1630 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1631 action_list=acts, max_test=2, egr_count=0,
1632 ing_port=True)
1633
Dan Talaycod8ae7582012-03-23 12:24:56 -07001634class ModifyL2DstIngressMC(BaseMatchCase):
1635 """
1636 Modify the L2 dest and send to the ingress port
1637 """
1638 def runTest(self):
1639 sup_acts = supported_actions_get(self)
1640 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1641 skip_message_emit(self, "ModifyL2dstMC test")
1642 return
1643
1644 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1645 check_test_params=True)
1646 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1647 action_list=acts, max_test=2, egr_count=-1,
1648 ing_port=True)
1649
Dan Talaycof6e76c02012-03-23 10:56:12 -07001650class ModifyL2SrcMC(BaseMatchCase):
1651 """
1652 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001653 """
1654 def runTest(self):
1655 sup_acts = supported_actions_get(self)
1656 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001657 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001658 return
1659
Dan Talaycof6e76c02012-03-23 10:56:12 -07001660 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1661 check_test_params=True)
1662 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001663 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001664
1665class ModifyL2SrcDstMC(BaseMatchCase):
1666 """
1667 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001668 """
1669 def runTest(self):
1670 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001671 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1672 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1673 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001674 return
1675
Dan Talaycof6e76c02012-03-23 10:56:12 -07001676 mod_fields = ['dl_dst', 'dl_src']
1677 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1678 check_test_params=True)
1679 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001680 action_list=acts, max_test=2, egr_count=-1)
1681
1682class ModifyL2DstVIDMC(BaseMatchCase):
1683 """
1684 Modify the L2 dest and send to 2 ports
1685 """
1686 def runTest(self):
1687 sup_acts = supported_actions_get(self)
1688 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1689 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1690 skip_message_emit(self, "ModifyL2DstVIDMC test")
1691 return
1692
1693 mod_fields = ['dl_dst', 'dl_vlan']
1694 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1695 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1696 check_test_params=True)
1697 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1698 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001699
Dan Talaycofa6454f2012-04-05 10:04:13 -07001700class FlowToggle(BaseMatchCase):
1701 """
1702 Add flows to the table and modify them repeatedly
Dan Talaycof7c41312012-07-23 12:53:19 -07001703
1704 This is done by using only "add" flow messages. Since the check overlap
1705 flag is not set, the switch is supposed to modify the existing flow if
1706 the match already exists.
1707
1708 Would probably be better to exercise more of the flow modify commands
1709 (add, modify, delete +/- strict).
Dan Talaycofa6454f2012-04-05 10:04:13 -07001710 """
1711 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001712 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1713 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001714
1715 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1716 (flow_count, iter_count))
1717 acts = []
1718 acts.append(action.action_output())
1719 acts.append(action.action_output())
1720
1721 of_ports = pa_port_map.keys()
1722 if len(of_ports) < 3:
1723 self.assertTrue(False, "Too few ports for test")
1724
1725 for idx in range(2):
1726 acts[idx].port = of_ports[idx]
1727
1728 flows = []
1729 flows.append([])
1730 flows.append([])
1731
Dan Talayco50be7672012-04-05 11:38:08 -07001732 wildcards = ofp.OFPFW_DL_SRC | ofp.OFPFW_DL_DST
Dan Talaycofa6454f2012-04-05 10:04:13 -07001733 # Create up the flows in an array
1734 for toggle in range(2):
1735 for f_idx in range(flow_count):
1736 pkt = simple_tcp_packet(tcp_sport=f_idx)
1737 msg = message.flow_mod()
1738 match = parse.packet_to_flow_match(pkt)
Shudong Zhou031373c2012-07-19 17:37:42 -07001739 match.in_port = of_ports[2]
Dan Talayco50be7672012-04-05 11:38:08 -07001740 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001741 msg.match = match
1742 msg.buffer_id = 0xffffffff
Dan Talaycof7c41312012-07-23 12:53:19 -07001743 msg.command = ofp.OFPFC_ADD
Dan Talaycofa6454f2012-04-05 10:04:13 -07001744 msg.actions.add(acts[toggle])
1745 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001746
1747 # Show two sample flows
1748 pa_logger.debug(flows[0][0].show())
1749 pa_logger.debug(flows[1][0].show())
1750
Dan Talaycofa6454f2012-04-05 10:04:13 -07001751 # Install the first set of flows
1752 for f_idx in range(flow_count):
1753 rv = self.controller.message_send(flows[0][f_idx])
1754 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001755 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001756
1757 pa_logger.info("Installed %d flows" % flow_count)
1758
1759 # Repeatedly modify all the flows back and forth
1760 updates = 0
1761 # Report status about 5 times
1762 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001763 start = time.time()
1764 for iter_idx in range(iter_count):
1765 if not iter_idx % mod_val:
1766 pa_logger.info("Flow Toggle: iter %d of %d. " %
1767 (iter_idx, iter_count) +
1768 "%d updates in %d secs" %
1769 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001770 for toggle in range(2):
1771 t_idx = 1 - toggle
1772 for f_idx in range(flow_count):
1773 rv = self.controller.message_send(flows[t_idx][f_idx])
1774 updates += 1
1775 self.assertTrue(rv != -1, "Error modifying flow %d" %
1776 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001777 self.assertEqual(do_barrier(self.controller), 0,
1778 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001779
1780 end = time.time()
1781 divisor = end - start or (end - start + 1)
1782 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1783 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1784 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001785
1786
Dan Talayco8a64e332012-03-28 14:53:20 -07001787# You can pick and choose these by commenting tests in or out
1788iter_classes = [
1789 basic.PacketIn,
1790 basic.PacketOut,
1791 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001792 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001793 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001794 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001795 AllWildcardMatch,
1796 AllWildcardMatchTagged,
1797 SingleWildcardMatch,
1798 SingleWildcardMatchTagged,
1799 ExactMatch,
1800 ExactMatchTagged,
1801 SingleWildcardMatch,
1802 ModifyL2Src,
1803 ModifyL2Dst,
1804 ModifyL2SrcMC,
1805 ModifyL2DstMC,
1806 ModifyL2SrcDstMC
1807 ]
1808
1809class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001810 """
1811 Iterate over a bunch of test cases
1812
1813 The cases come from the list above
1814 """
1815
Dan Talayco8a64e332012-03-28 14:53:20 -07001816 def runTest(self):
1817 count = test_param_get(self.config, 'iter_count', default=10)
1818 tests_done = 0
1819 pa_logger.info("Running iteration test " + str(count) + " times")
1820 start = time.time()
1821 last = start
1822 for idx in range(count):
1823 pa_logger.info("Iteration " + str(idx + 1))
1824 for cls in iter_classes:
1825 test = cls()
1826 test.inheritSetup(self)
1827 test.runTest()
1828 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001829 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001830 if time.time() - last > 60:
1831 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001832 pa_logger.info(
1833 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1834 (idx, count, tests_done, last - start) +
1835 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001836 stats = all_stats_get(self)
1837 last = time.time()
1838 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1839 (tests_done, last - start))
1840 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1841 (stats["flows"], stats["packets"], stats["bytes"]))
1842 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1843 (stats["active"], stats["lookups"], stats["matched"]))
1844
1845# Don't run by default
1846test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001847
Dan Talayco4b2bee62010-07-20 14:10:05 -07001848#@todo Need to implement tagged versions of the above tests
1849#
1850#@todo Implement a test case that strips tag 2, adds tag 3
1851# and modifies tag 4 to tag 5. Then verify (in addition) that
1852# tag 6 does not get modified.
1853
1854class MixedVLAN(BaseMatchCase):
1855 """
1856 Test mixture of VLAN tag actions
1857
1858 Strip tag 2 on port 1, send to port 2
1859 Add tag 3 on port 1, send to port 2
1860 Modify tag 4 to 5 on port 1, send to port 2
1861 All other traffic from port 1, send to port 3
1862 All traffic from port 2 sent to port 4
1863 Use exact matches with different packets for all mods
1864 Verify the following: (port, vid)
1865 (port 1, vid 2) => VLAN tag stripped, out port 2
1866 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1867 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1868 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1869 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1870 (port 2, no tag) => untagged packet out port 4
1871 (port 2, vid 2-6) => unmodified packet out port 4
1872
1873 Variation: Might try sending VID 5 to port 3 and check.
1874 If only VID 5 distinguishes pkt, this will fail on some platforms
1875 """
1876
1877test_prio["MixedVLAN"] = -1
1878
Dan Talayco551befa2010-07-15 17:05:32 -07001879def supported_actions_get(parent, use_cache=True):
1880 """
1881 Get the bitmap of supported actions from the switch
1882 If use_cache is false, the cached value will be updated
1883 """
1884 global cached_supported_actions
1885 if cached_supported_actions is None or not use_cache:
1886 request = message.features_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -07001887 (reply, pkt) = parent.controller.transact(request)
Dan Talayco551befa2010-07-15 17:05:32 -07001888 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1889 cached_supported_actions = reply.actions
1890 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1891
1892 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001893
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001894if __name__ == "__main__":
1895 print "Please run through oft script: ./oft --test_spec=basic"