blob: b53f13b426a2b7f29e61d98744b7e68413685f07 [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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700136 match = packet_to_flow_match(self, 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700206 match = packet_to_flow_match(self, pkt)
Rich Lane51c23b32012-07-27 16:37:25 -0700207 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700277 match = packet_to_flow_match(self, pkt)
Howard Pershf97840f2012-04-10 16:30:42 -0700278 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700401 match = packet_to_flow_match(self, pkt)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700402 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700536 match = packet_to_flow_match(self, pkt)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700537 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700596 match = packet_to_flow_match(self, pkt)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700597 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700651 match = packet_to_flow_match(self, pkt)
Dan Talayco32fa6542010-05-11 15:54:08 -0700652 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700702 match = packet_to_flow_match(self, pkt)
Dan Talayco2e77a842010-05-12 15:39:46 -0700703 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700751 match = packet_to_flow_match(self, pkt)
Dan Talayco3be5b062010-05-12 15:46:21 -0700752 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700801 match = packet_to_flow_match(self, pkt)
Dan Talayco4aa13122010-05-12 15:54:44 -0700802 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700850 match = packet_to_flow_match(self, pkt)
Dan Talayco4aa13122010-05-12 15:54:44 -0700851 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()
Ed Swierk99a74de2012-08-22 06:40:54 -0700902 match = packet_to_flow_match(self, pkt)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700903 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
Ed Swierk99a74de2012-08-22 06:40:54 -07001071 def installFlow(self, prio, inp, egp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001072 wildcards=ofp.OFPFW_DL_SRC):
Ed Swierk99a74de2012-08-22 06:40:54 -07001073 wildcards |= required_wildcards(self)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001074 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001075 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001076 egr_ports=egp)
1077 request.priority = prio
Ken Chiang38d7a152012-05-24 15:33:50 -07001078 self.logger.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001079 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001080 self.flowMsgs[prio] = request
1081
1082 def removeFlow(self, prio):
1083 if self.flowMsgs.has_key(prio):
1084 msg = self.flowMsgs[prio]
1085 msg.command = ofp.OFPFC_DELETE_STRICT
1086 # This *must* be set for DELETE
1087 msg.out_port = ofp.OFPP_NONE
Ken Chiang38d7a152012-05-24 15:33:50 -07001088 self.logger.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001089 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001090 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001091 else:
1092 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001093
1094
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001095 def verifyFlow(self, inp, egp, pkt=None):
1096 if pkt == None:
1097 pkt = self.pkt
1098
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001099 self.logger.info("Pkt match test: " + str(inp) +
1100 " to " + str(egp))
1101 self.logger.debug("Send packet: " + str(inp) + " to "
1102 + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001103 self.dataplane.send(inp, str(pkt))
1104 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001105
1106
1107
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001108class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1109
1110 def runTest(self):
1111
1112 self._Init()
1113
1114 of_ports = pa_port_map.keys()
1115 of_ports.sort()
1116
1117 # Install an entry from 0 -> 1 @ prio 1000
1118 self._ClearTable()
1119 self.installFlow(1000, of_ports[0], of_ports[1])
1120 self.verifyFlow(of_ports[0], of_ports[1])
1121 self.installFlow(1000, of_ports[1], of_ports[0])
1122 self.verifyFlow(of_ports[1], of_ports[0])
1123 self.installFlow(1001, of_ports[0], of_ports[1])
1124 self.verifyFlow(of_ports[0], of_ports[1])
1125 self.installFlow(1001, of_ports[1], of_ports[0])
1126 self.verifyFlow(of_ports[1], of_ports[0])
1127 self.removeFlow(1001)
1128 self.verifyFlow(of_ports[0], of_ports[1])
1129 self.removeFlow(1000)
1130
1131
1132
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001133class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001134 """
1135 1. Add wildcard flow, verify packet received.
1136 2. Add exact match flow with higher priority, verify packet received
1137 on port specified by this flow.
1138 3. Add wildcard flow with even higher priority, verify packet received
1139 on port specified by this flow.
1140 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001141
1142 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001143
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001144 self._Init()
1145
1146 of_ports = pa_port_map.keys()
1147 of_ports.sort()
1148
1149 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001150
1151 # Install a flow with wildcards
1152 self.installFlow(999, of_ports[0], of_ports[1],
1153 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001154 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001155 # Install a flow with no wildcards for our packet
1156 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001157 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001158 # Install a flow with wildcards for our packet with higher
1159 # priority
1160 self.installFlow(1001, of_ports[0], of_ports[3])
1161 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001162
1163
Ken Chiang3978f242012-06-13 14:14:09 -07001164class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001165 """
1166 1. Add exact match flow, verify packet received.
1167 2. Add wildcard flow with higher priority, verify packet received on port
1168 specified by this flow.
1169 3. Add exact match flow with even higher priority, verify packet received
1170 on port specified by this flow.
1171 4. Delete lowest priority flow, verify packet received on port specified
1172 by highest priority flow.
1173 5. Delete highest priority flow, verify packet received on port specified
1174 by remaining flow.
1175 """
1176
1177 def runTest(self):
1178
1179 self._Init()
1180
1181 of_ports = pa_port_map.keys()
1182 of_ports.sort()
1183
1184 self._ClearTable()
1185
1186 # Install an exact match flow
1187 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1188 self.verifyFlow(of_ports[0], of_ports[1])
1189 # Install a flow with wildcards of higher priority
1190 self.installFlow(1250, of_ports[0], of_ports[2],
1191 wildcards=ofp.OFPFW_DL_DST)
1192 self.verifyFlow(of_ports[0], of_ports[2])
1193 # Install an exact match flow with even higher priority
1194 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1195 self.verifyFlow(of_ports[0], of_ports[3])
1196 # Delete lowest priority flow
1197 self.removeFlow(250)
1198 self.verifyFlow(of_ports[0], of_ports[3])
1199 # Delete highest priority flow
1200 self.removeFlow(2001)
1201 self.verifyFlow(of_ports[0], of_ports[2])
1202
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001203
Dan Talayco551befa2010-07-15 17:05:32 -07001204class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001205 """
1206 Exercise wildcard matching for all ports
1207
1208 Generate a packet
1209 Generate and install a matching flow with wildcard mask
1210 Add action to forward to a port
1211 Send the packet to the port
1212 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001213 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001214 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001215 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001216 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001217 for wc in WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001218 wc |= required_wildcards(self)
Dan Talayco4431d542012-03-21 16:42:16 -07001219 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001220 # Set nonzero VLAN id to avoid sending priority-tagged packet
1221 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001222 else:
1223 dl_vlan = -1
1224 flow_match_test(self, pa_port_map, wildcards=wc,
1225 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001226
Dan Talayco551befa2010-07-15 17:05:32 -07001227class SingleWildcardMatchTagged(BaseMatchCase):
1228 """
1229 SingleWildcardMatch with tagged packets
1230 """
1231 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001232 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001233 for wc in WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001234 wc |= required_wildcards(self)
Dan Talayco21381562010-07-17 00:34:47 -07001235 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001236 max_test=10)
1237
1238class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001239 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001240 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001241
1242 Generate a packet
1243 Generate and install a matching flow with wildcard all except one filed
1244 Add action to forward to a port
1245 Send the packet to the port
1246 Verify the packet is received at all other ports (one port at a time)
1247 Verify flow_expiration message is correct when command option is set
1248 """
1249 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001250 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001251 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001252 all_exp_one_wildcard |= required_wildcards(self)
Dan Talayco4431d542012-03-21 16:42:16 -07001253 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001254 # Set nonzero VLAN id to avoid sending priority-tagged packet
1255 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001256 else:
1257 dl_vlan = -1
1258 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1259 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001260
Dan Talayco551befa2010-07-15 17:05:32 -07001261class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1262 """
1263 Match one field with tagged packets
1264 """
1265 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001266 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001267 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001268 all_exp_one_wildcard |= required_wildcards(self)
Dan Talayco21381562010-07-17 00:34:47 -07001269 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1270 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001271
1272class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001273 """
1274 Create Wildcard-all flow and exercise for all ports
1275
1276 Generate a packet
1277 Generate and install a matching flow with wildcard-all
1278 Add action to forward to a port
1279 Send the packet to the port
1280 Verify the packet is received at all other ports (one port at a time)
1281 Verify flow_expiration message is correct when command option is set
1282 """
1283 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -07001284 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001285
Dan Talayco551befa2010-07-15 17:05:32 -07001286class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001287 """
Dan Talayco551befa2010-07-15 17:05:32 -07001288 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001289 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001290 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001291 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -07001292 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
1293 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001294
Dan Talaycoba3745c2010-07-21 21:51:08 -07001295
Dan Talayco551befa2010-07-15 17:05:32 -07001296class AddVLANTag(BaseMatchCase):
1297 """
1298 Add a VLAN tag to an untagged packet
1299 """
1300 def runTest(self):
1301 new_vid = 2
1302 sup_acts = supported_actions_get(self)
1303 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001304 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001305 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001306
Dan Talayco551befa2010-07-15 17:05:32 -07001307 len = 100
1308 len_w_vid = 104
1309 pkt = simple_tcp_packet(pktlen=len)
1310 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1311 dl_vlan=new_vid)
1312 vid_act = action.action_set_vlan_vid()
1313 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001314
Dan Talayco551befa2010-07-15 17:05:32 -07001315 flow_match_test(self, pa_port_map, pkt=pkt,
1316 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001317
Dan Talayco551befa2010-07-15 17:05:32 -07001318class PacketOnly(basic.DataPlaneOnly):
1319 """
1320 Just send a packet thru the switch
1321 """
1322 def runTest(self):
1323 pkt = simple_tcp_packet()
1324 of_ports = pa_port_map.keys()
1325 of_ports.sort()
1326 ing_port = of_ports[0]
1327 pa_logger.info("Sending packet to " + str(ing_port))
1328 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1329 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001330
Dan Talayco551befa2010-07-15 17:05:32 -07001331class PacketOnlyTagged(basic.DataPlaneOnly):
1332 """
1333 Just send a packet thru the switch
1334 """
1335 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001336 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001337 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
1338 of_ports = pa_port_map.keys()
1339 of_ports.sort()
1340 ing_port = of_ports[0]
1341 pa_logger.info("Sending packet to " + str(ing_port))
1342 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1343 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001344
Dan Talayco551befa2010-07-15 17:05:32 -07001345test_prio["PacketOnly"] = -1
1346test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001347
Dan Talayco551befa2010-07-15 17:05:32 -07001348class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001349 """
1350 Modify the VLAN ID in the VLAN tag of a tagged packet
1351 """
Dan Talayco551befa2010-07-15 17:05:32 -07001352 def runTest(self):
1353 old_vid = 2
1354 new_vid = 3
1355 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001356 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001357 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001358 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001359
Dan Talayco551befa2010-07-15 17:05:32 -07001360 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1361 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1362 vid_act = action.action_set_vlan_vid()
1363 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001364
Dan Talayco551befa2010-07-15 17:05:32 -07001365 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1366 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001367
Ken Chiange9a211d2012-04-20 14:52:11 -07001368class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1369 """
1370 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1371 The same flow should match on both untagged and tagged packets.
1372 """
1373 def runTest(self):
1374 old_vid = 2
1375 new_vid = 3
1376 sup_acts = supported_actions_get(self)
1377 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1378 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1379 return
1380
1381 of_ports = pa_port_map.keys()
1382 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1383 ing_port = of_ports[0]
1384 egr_ports = of_ports[1]
1385
1386 rv = delete_all_flows(self.controller, pa_logger)
1387 self.assertEqual(rv, 0, "Failed to delete all flows")
1388
1389 len_untagged = 100
1390 len_w_vid = 104
1391 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1392 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1393 dl_vlan_enable=True, dl_vlan=old_vid)
1394 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1395 dl_vlan=new_vid)
Ed Swierk99a74de2012-08-22 06:40:54 -07001396 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_VLAN |
1397 ofp.OFPFW_DL_VLAN_PCP)
Ken Chiange9a211d2012-04-20 14:52:11 -07001398 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)
Ed Swierk99a74de2012-08-22 06:40:54 -07001474 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_VLAN |
1475 ofp.OFPFW_DL_VLAN_PCP)
Ken Chiange9a211d2012-04-20 14:52:11 -07001476 vid_act = action.action_strip_vlan()
1477
1478 flow_match_test(self, pa_port_map,
Ed Swierk99a74de2012-08-22 06:40:54 -07001479 wildcards=wildcards,
Ken Chiange9a211d2012-04-20 14:52:11 -07001480 pkt=pkt, exp_pkt=exp_pkt,
1481 action_list=[vid_act])
1482
Dan Talayco4b2bee62010-07-20 14:10:05 -07001483def init_pkt_args():
1484 """
1485 Pass back a dictionary with default packet arguments
1486 """
1487 args = {}
1488 args["dl_src"] = '00:23:45:67:89:AB'
1489
1490 dl_vlan_enable=False
1491 dl_vlan=-1
1492 if pa_config["test-params"]["vid"]:
1493 dl_vlan_enable=True
1494 dl_vlan = pa_config["test-params"]["vid"]
1495
1496# Unpack operator is ** on a dictionary
1497
1498 return args
1499
Dan Talayco551befa2010-07-15 17:05:32 -07001500class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001501 """
1502 Modify the source MAC address (TP1)
1503 """
Dan Talayco551befa2010-07-15 17:05:32 -07001504 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001505 sup_acts = supported_actions_get(self)
1506 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001507 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001508 return
1509
1510 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1511 check_test_params=True)
1512 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1513 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001514
Dan Talayco551befa2010-07-15 17:05:32 -07001515class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001516 """
1517 Modify the dest MAC address (TP1)
1518 """
Dan Talayco551befa2010-07-15 17:05:32 -07001519 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001520 sup_acts = supported_actions_get(self)
1521 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001522 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001523 return
1524
1525 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1526 check_test_params=True)
1527 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1528 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001529
Dan Talayco551befa2010-07-15 17:05:32 -07001530class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001531 """
1532 Modify the source IP address of an IP packet (TP1)
1533 """
Dan Talayco551befa2010-07-15 17:05:32 -07001534 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001535 sup_acts = supported_actions_get(self)
1536 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001537 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001538 return
1539
1540 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1541 check_test_params=True)
1542 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1543 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001544
Dan Talayco551befa2010-07-15 17:05:32 -07001545class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001546 """
1547 Modify the dest IP address of an IP packet (TP1)
1548 """
Dan Talayco551befa2010-07-15 17:05:32 -07001549 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001550 sup_acts = supported_actions_get(self)
1551 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001552 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001553 return
1554
1555 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1556 check_test_params=True)
1557 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1558 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001559
1560class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001561 """
1562 Modify the source TCP port of a TCP packet (TP1)
1563 """
Dan Talayco551befa2010-07-15 17:05:32 -07001564 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001565 sup_acts = supported_actions_get(self)
1566 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001567 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001568 return
1569
1570 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1571 check_test_params=True)
1572 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1573 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001574
1575class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001576 """
1577 Modify the dest TCP port of a TCP packet (TP1)
1578 """
Dan Talayco551befa2010-07-15 17:05:32 -07001579 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001580 sup_acts = supported_actions_get(self)
1581 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001582 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001583 return
1584
1585 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1586 check_test_params=True)
1587 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1588 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001589
1590class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001591 """
1592 Modify the IP type of service of an IP packet (TP1)
1593 """
Dan Talayco551befa2010-07-15 17:05:32 -07001594 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001595 sup_acts = supported_actions_get(self)
1596 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001597 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001598 return
Dan Talayco551befa2010-07-15 17:05:32 -07001599
Dan Talayco4b2bee62010-07-20 14:10:05 -07001600 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1601 check_test_params=True)
1602 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001603 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001604
Dan Talaycof6e76c02012-03-23 10:56:12 -07001605class ModifyL2DstMC(BaseMatchCase):
1606 """
1607 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001608 """
1609 def runTest(self):
1610 sup_acts = supported_actions_get(self)
1611 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001612 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001613 return
1614
Dan Talaycof6e76c02012-03-23 10:56:12 -07001615 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1616 check_test_params=True)
1617 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001618 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001619
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001620class ModifyL2DstIngress(BaseMatchCase):
1621 """
1622 Modify the L2 dest and send to the ingress port
1623 """
1624 def runTest(self):
1625 sup_acts = supported_actions_get(self)
1626 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001627 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001628 return
1629
1630 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1631 check_test_params=True)
1632 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1633 action_list=acts, max_test=2, egr_count=0,
1634 ing_port=True)
1635
Dan Talaycod8ae7582012-03-23 12:24:56 -07001636class ModifyL2DstIngressMC(BaseMatchCase):
1637 """
1638 Modify the L2 dest and send to the ingress port
1639 """
1640 def runTest(self):
1641 sup_acts = supported_actions_get(self)
1642 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1643 skip_message_emit(self, "ModifyL2dstMC test")
1644 return
1645
1646 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1647 check_test_params=True)
1648 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1649 action_list=acts, max_test=2, egr_count=-1,
1650 ing_port=True)
1651
Dan Talaycof6e76c02012-03-23 10:56:12 -07001652class ModifyL2SrcMC(BaseMatchCase):
1653 """
1654 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001655 """
1656 def runTest(self):
1657 sup_acts = supported_actions_get(self)
1658 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001659 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001660 return
1661
Dan Talaycof6e76c02012-03-23 10:56:12 -07001662 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1663 check_test_params=True)
1664 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001665 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001666
1667class ModifyL2SrcDstMC(BaseMatchCase):
1668 """
1669 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001670 """
1671 def runTest(self):
1672 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001673 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1674 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1675 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001676 return
1677
Dan Talaycof6e76c02012-03-23 10:56:12 -07001678 mod_fields = ['dl_dst', 'dl_src']
1679 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1680 check_test_params=True)
1681 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001682 action_list=acts, max_test=2, egr_count=-1)
1683
1684class ModifyL2DstVIDMC(BaseMatchCase):
1685 """
1686 Modify the L2 dest and send to 2 ports
1687 """
1688 def runTest(self):
1689 sup_acts = supported_actions_get(self)
1690 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1691 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1692 skip_message_emit(self, "ModifyL2DstVIDMC test")
1693 return
1694
1695 mod_fields = ['dl_dst', 'dl_vlan']
1696 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1697 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1698 check_test_params=True)
1699 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1700 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001701
Dan Talaycofa6454f2012-04-05 10:04:13 -07001702class FlowToggle(BaseMatchCase):
1703 """
1704 Add flows to the table and modify them repeatedly
Dan Talaycof7c41312012-07-23 12:53:19 -07001705
1706 This is done by using only "add" flow messages. Since the check overlap
1707 flag is not set, the switch is supposed to modify the existing flow if
1708 the match already exists.
1709
1710 Would probably be better to exercise more of the flow modify commands
1711 (add, modify, delete +/- strict).
Dan Talaycofa6454f2012-04-05 10:04:13 -07001712 """
1713 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001714 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1715 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001716
1717 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1718 (flow_count, iter_count))
1719 acts = []
1720 acts.append(action.action_output())
1721 acts.append(action.action_output())
1722
1723 of_ports = pa_port_map.keys()
1724 if len(of_ports) < 3:
1725 self.assertTrue(False, "Too few ports for test")
1726
1727 for idx in range(2):
1728 acts[idx].port = of_ports[idx]
1729
1730 flows = []
1731 flows.append([])
1732 flows.append([])
1733
Ed Swierk99a74de2012-08-22 06:40:54 -07001734 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_SRC |
1735 ofp.OFPFW_DL_DST)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001736 # Create up the flows in an array
1737 for toggle in range(2):
1738 for f_idx in range(flow_count):
1739 pkt = simple_tcp_packet(tcp_sport=f_idx)
1740 msg = message.flow_mod()
Ed Swierk99a74de2012-08-22 06:40:54 -07001741 match = packet_to_flow_match(self, pkt)
Shudong Zhou031373c2012-07-19 17:37:42 -07001742 match.in_port = of_ports[2]
Dan Talayco50be7672012-04-05 11:38:08 -07001743 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001744 msg.match = match
1745 msg.buffer_id = 0xffffffff
Dan Talaycof7c41312012-07-23 12:53:19 -07001746 msg.command = ofp.OFPFC_ADD
Dan Talaycofa6454f2012-04-05 10:04:13 -07001747 msg.actions.add(acts[toggle])
1748 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001749
1750 # Show two sample flows
1751 pa_logger.debug(flows[0][0].show())
1752 pa_logger.debug(flows[1][0].show())
1753
Dan Talaycofa6454f2012-04-05 10:04:13 -07001754 # Install the first set of flows
1755 for f_idx in range(flow_count):
1756 rv = self.controller.message_send(flows[0][f_idx])
1757 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001758 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001759
1760 pa_logger.info("Installed %d flows" % flow_count)
1761
1762 # Repeatedly modify all the flows back and forth
1763 updates = 0
1764 # Report status about 5 times
1765 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001766 start = time.time()
1767 for iter_idx in range(iter_count):
1768 if not iter_idx % mod_val:
1769 pa_logger.info("Flow Toggle: iter %d of %d. " %
1770 (iter_idx, iter_count) +
1771 "%d updates in %d secs" %
1772 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001773 for toggle in range(2):
1774 t_idx = 1 - toggle
1775 for f_idx in range(flow_count):
1776 rv = self.controller.message_send(flows[t_idx][f_idx])
1777 updates += 1
1778 self.assertTrue(rv != -1, "Error modifying flow %d" %
1779 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001780 self.assertEqual(do_barrier(self.controller), 0,
1781 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001782
1783 end = time.time()
1784 divisor = end - start or (end - start + 1)
1785 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1786 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1787 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001788
1789
Dan Talayco8a64e332012-03-28 14:53:20 -07001790# You can pick and choose these by commenting tests in or out
1791iter_classes = [
1792 basic.PacketIn,
1793 basic.PacketOut,
1794 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001795 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001796 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001797 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001798 AllWildcardMatch,
1799 AllWildcardMatchTagged,
1800 SingleWildcardMatch,
1801 SingleWildcardMatchTagged,
1802 ExactMatch,
1803 ExactMatchTagged,
1804 SingleWildcardMatch,
1805 ModifyL2Src,
1806 ModifyL2Dst,
1807 ModifyL2SrcMC,
1808 ModifyL2DstMC,
1809 ModifyL2SrcDstMC
1810 ]
1811
1812class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001813 """
1814 Iterate over a bunch of test cases
1815
1816 The cases come from the list above
1817 """
1818
Dan Talayco8a64e332012-03-28 14:53:20 -07001819 def runTest(self):
1820 count = test_param_get(self.config, 'iter_count', default=10)
1821 tests_done = 0
1822 pa_logger.info("Running iteration test " + str(count) + " times")
1823 start = time.time()
1824 last = start
1825 for idx in range(count):
1826 pa_logger.info("Iteration " + str(idx + 1))
1827 for cls in iter_classes:
1828 test = cls()
1829 test.inheritSetup(self)
1830 test.runTest()
1831 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001832 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001833 if time.time() - last > 60:
1834 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001835 pa_logger.info(
1836 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1837 (idx, count, tests_done, last - start) +
1838 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001839 stats = all_stats_get(self)
1840 last = time.time()
1841 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1842 (tests_done, last - start))
1843 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1844 (stats["flows"], stats["packets"], stats["bytes"]))
1845 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1846 (stats["active"], stats["lookups"], stats["matched"]))
1847
1848# Don't run by default
1849test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001850
Dan Talayco4b2bee62010-07-20 14:10:05 -07001851#@todo Need to implement tagged versions of the above tests
1852#
1853#@todo Implement a test case that strips tag 2, adds tag 3
1854# and modifies tag 4 to tag 5. Then verify (in addition) that
1855# tag 6 does not get modified.
1856
1857class MixedVLAN(BaseMatchCase):
1858 """
1859 Test mixture of VLAN tag actions
1860
1861 Strip tag 2 on port 1, send to port 2
1862 Add tag 3 on port 1, send to port 2
1863 Modify tag 4 to 5 on port 1, send to port 2
1864 All other traffic from port 1, send to port 3
1865 All traffic from port 2 sent to port 4
1866 Use exact matches with different packets for all mods
1867 Verify the following: (port, vid)
1868 (port 1, vid 2) => VLAN tag stripped, out port 2
1869 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1870 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1871 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1872 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1873 (port 2, no tag) => untagged packet out port 4
1874 (port 2, vid 2-6) => unmodified packet out port 4
1875
1876 Variation: Might try sending VID 5 to port 3 and check.
1877 If only VID 5 distinguishes pkt, this will fail on some platforms
1878 """
1879
1880test_prio["MixedVLAN"] = -1
1881
Dan Talayco551befa2010-07-15 17:05:32 -07001882def supported_actions_get(parent, use_cache=True):
1883 """
1884 Get the bitmap of supported actions from the switch
1885 If use_cache is false, the cached value will be updated
1886 """
1887 global cached_supported_actions
1888 if cached_supported_actions is None or not use_cache:
1889 request = message.features_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -07001890 (reply, pkt) = parent.controller.transact(request)
Dan Talayco551befa2010-07-15 17:05:32 -07001891 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1892 cached_supported_actions = reply.actions
1893 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1894
1895 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001896
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001897if __name__ == "__main__":
1898 print "Please run through oft script: ./oft --test_spec=basic"