blob: 023e1ca89ef8d05d19522f5b25b381b6bd3cd80b [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
Dan Talayco21381562010-07-17 00:34:47 -070091TEST_VID_DEFAULT = 2
92
Dan Talayco5eba8442010-03-10 13:58:43 -080093def test_set_init(config):
94 """
95 Set up function for packet action test classes
96
97 @param config The configuration dictionary; see oft
98 """
99
Ed Swierk89f78352012-03-29 12:32:32 -0700100 basic.test_set_init(config)
101
Dan Talayco5eba8442010-03-10 13:58:43 -0800102 global pa_port_map
103 global pa_logger
104 global pa_config
105
106 pa_logger = logging.getLogger("pkt_act")
107 pa_logger.info("Initializing test set")
108 pa_port_map = config["port_map"]
109 pa_config = config
110
111class DirectPacket(basic.SimpleDataPlane):
112 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700113 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -0800114
115 Generate a packet
116 Generate and install a matching flow
117 Add action to direct the packet to an egress port
118 Send the packet to ingress dataplane port
119 Verify the packet is received at the egress port only
120 """
121 def runTest(self):
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700122 self.handleFlow()
123
124 def handleFlow(self, pkttype='TCP'):
Dan Talayco5eba8442010-03-10 13:58:43 -0800125 of_ports = pa_port_map.keys()
126 of_ports.sort()
127 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
128
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700129 if (pkttype == 'ICMP'):
130 pkt = simple_icmp_packet()
131 else:
132 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700133 match = packet_to_flow_match(self, pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -0700134 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -0800135 self.assertTrue(match is not None,
136 "Could not generate flow match from pkt")
137 act = action.action_output()
138
139 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700140 rv = delete_all_flows(self.controller, pa_logger)
141 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700142
Dan Talayco5eba8442010-03-10 13:58:43 -0800143 ingress_port = of_ports[idx]
144 egress_port = of_ports[(idx + 1) % len(of_ports)]
145 pa_logger.info("Ingress " + str(ingress_port) +
Dan Talayco551befa2010-07-15 17:05:32 -0700146 " to egress " + str(egress_port))
Dan Talayco5eba8442010-03-10 13:58:43 -0800147
148 match.in_port = ingress_port
149
150 request = message.flow_mod()
151 request.match = match
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700152
Dan Talayco5eba8442010-03-10 13:58:43 -0800153 request.buffer_id = 0xffffffff
154 act.port = egress_port
155 self.assertTrue(request.actions.add(act), "Could not add action")
156
157 pa_logger.info("Inserting flow")
158 rv = self.controller.message_send(request)
159 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700160 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco5eba8442010-03-10 13:58:43 -0800161
162 pa_logger.info("Sending packet to dp port " +
163 str(ingress_port))
164 self.dataplane.send(ingress_port, str(pkt))
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700165
166 exp_pkt_arg = None
167 exp_port = None
168 if pa_config["relax"]:
169 exp_pkt_arg = pkt
170 exp_port = egress_port
171
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700172 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700173 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800174 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700175 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800176 str(rcv_port))
177 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
178 self.assertEqual(str(pkt), str(rcv_pkt),
179 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700180
Rich Lane51c23b32012-07-27 16:37:25 -0700181class DirectPacketController(basic.SimpleDataPlane):
182 """
183 Send packet to the controller port
184
185 Generate a packet
186 Generate and install a matching flow
187 Add action to direct the packet to the controller port
188 Send the packet to ingress dataplane port
189 Verify the packet is received at the controller port
190 """
191 def runTest(self):
192 self.handleFlow()
193
194 def handleFlow(self, pkttype='TCP'):
195 of_ports = pa_port_map.keys()
196 of_ports.sort()
197 self.assertTrue(len(of_ports) > 0, "Not enough ports for test")
198
199 if (pkttype == 'ICMP'):
200 pkt = simple_icmp_packet()
201 else:
202 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700203 match = packet_to_flow_match(self, pkt)
Rich Lane51c23b32012-07-27 16:37:25 -0700204 match.wildcards &= ~ofp.OFPFW_IN_PORT
205 self.assertTrue(match is not None,
206 "Could not generate flow match from pkt")
207 act = action.action_output()
208
209 rv = delete_all_flows(self.controller, pa_logger)
210 self.assertEqual(rv, 0, "Failed to delete all flows")
211
212 ingress_port = of_ports[0]
213 match.in_port = ingress_port
214
215 request = message.flow_mod()
216 request.match = match
217
218 request.buffer_id = 0xffffffff
219 act.port = ofp.OFPP_CONTROLLER
220 act.max_len = 65535
221 self.assertTrue(request.actions.add(act), "Could not add action")
222
223 pa_logger.info("Inserting flow")
224 rv = self.controller.message_send(request)
225 self.assertTrue(rv != -1, "Error installing flow mod")
226 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
227
228 pa_logger.info("Sending packet to dp port " +
229 str(ingress_port))
230 self.dataplane.send(ingress_port, str(pkt))
231
232 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
233
234 self.assertTrue(response is not None,
235 'Packet in message not received by controller')
236 if not dataplane.match_exp_pkt(pkt, response.data):
237 pa_logger.debug("Sent %s" % format_packet(pkt))
238 pa_logger.debug("Resp %s" % format_packet(response.data))
239 self.assertTrue(False,
240 'Response packet does not match send packet' +
241 ' for controller port')
242
Howard Pershf97840f2012-04-10 16:30:42 -0700243
244class DirectPacketQueue(basic.SimpleDataPlane):
245 """
246 Send packet to single queue on single egress port
247
248 Generate a packet
249 Generate and install a matching flow
250 Add action to direct the packet to an egress port and queue
251 Send the packet to ingress dataplane port
252 Verify the packet is received at the egress port only
253 """
254 def runTest(self):
255 self.handleFlow()
256
Howard Persh670b5672012-04-13 09:08:29 -0700257 def portQueuesGet(self, queue_stats, port_num):
258 result = []
259 for qs in queue_stats.stats:
260 if qs.port_no != port_num:
261 continue
262 result.append(qs.queue_id)
263 return result
264
Howard Pershf97840f2012-04-10 16:30:42 -0700265 def handleFlow(self, pkttype='TCP'):
266 of_ports = pa_port_map.keys()
267 of_ports.sort()
268 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
269
270 if (pkttype == 'ICMP'):
271 pkt = simple_icmp_packet()
272 else:
273 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700274 match = packet_to_flow_match(self, pkt)
Howard Pershf97840f2012-04-10 16:30:42 -0700275 match.wildcards &= ~ofp.OFPFW_IN_PORT
276 self.assertTrue(match is not None,
277 "Could not generate flow match from pkt")
278
Howard Persh670b5672012-04-13 09:08:29 -0700279 # Get queue stats from switch
280
281 request = message.queue_stats_request()
282 request.port_no = ofp.OFPP_ALL
283 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700284 (queue_stats, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700285 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
286
287 act = action.action_enqueue()
Howard Pershf97840f2012-04-10 16:30:42 -0700288
289 for idx in range(len(of_ports)):
Howard Pershf97840f2012-04-10 16:30:42 -0700290 ingress_port = of_ports[idx]
291 egress_port = of_ports[(idx + 1) % len(of_ports)]
Howard Pershf97840f2012-04-10 16:30:42 -0700292
Howard Persh670b5672012-04-13 09:08:29 -0700293 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
294 pa_logger.info("Ingress " + str(ingress_port)
295 + " to egress " + str(egress_port)
296 + " queue " + str(egress_queue_id)
297 )
Howard Pershf97840f2012-04-10 16:30:42 -0700298
Howard Persh670b5672012-04-13 09:08:29 -0700299 rv = delete_all_flows(self.controller, pa_logger)
300 self.assertEqual(rv, 0, "Failed to delete all flows")
Howard Pershf97840f2012-04-10 16:30:42 -0700301
Howard Persh670b5672012-04-13 09:08:29 -0700302 match.in_port = ingress_port
303
304 request = message.flow_mod()
305 request.match = match
Howard Pershf97840f2012-04-10 16:30:42 -0700306
Howard Persh670b5672012-04-13 09:08:29 -0700307 request.buffer_id = 0xffffffff
308 act.port = egress_port
309 act.queue_id = egress_queue_id
310 self.assertTrue(request.actions.add(act), "Could not add action")
Howard Pershf97840f2012-04-10 16:30:42 -0700311
Howard Persh670b5672012-04-13 09:08:29 -0700312 pa_logger.info("Inserting flow")
313 rv = self.controller.message_send(request)
314 self.assertTrue(rv != -1, "Error installing flow mod")
315 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Howard Pershf97840f2012-04-10 16:30:42 -0700316
Howard Persh670b5672012-04-13 09:08:29 -0700317 # Get current stats for selected egress queue
Howard Pershf97840f2012-04-10 16:30:42 -0700318
Howard Persh670b5672012-04-13 09:08:29 -0700319 request = message.queue_stats_request()
320 request.port_no = egress_port
321 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700322 (qs_before, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700323 self.assertNotEqual(qs_before, None, "Queue stats request failed")
324
325 pa_logger.info("Sending packet to dp port " +
326 str(ingress_port))
327 self.dataplane.send(ingress_port, str(pkt))
328
329 exp_pkt_arg = None
330 exp_port = None
331 if pa_config["relax"]:
332 exp_pkt_arg = pkt
333 exp_port = egress_port
334
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700335 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Howard Persh670b5672012-04-13 09:08:29 -0700336 exp_pkt=exp_pkt_arg)
337 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
338 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
339 str(rcv_port))
340 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
341 self.assertEqual(str(pkt), str(rcv_pkt),
342 'Response packet does not match send packet')
343
Ed Swierkb8a86512012-04-18 18:45:58 -0700344 # FIXME: instead of sleeping, keep requesting queue stats until
345 # the expected queue counter increases or some large timeout is
346 # reached
347 time.sleep(2)
348
Howard Persh670b5672012-04-13 09:08:29 -0700349 # Get current stats for selected egress queue again
350
351 request = message.queue_stats_request()
352 request.port_no = egress_port
353 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700354 (qs_after, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700355 self.assertNotEqual(qs_after, None, "Queue stats request failed")
356
357 # Make sure that tx packet counter for selected egress queue was
358 # incremented
359
Ed Swierk22f59152012-04-17 16:36:47 -0700360 self.assertEqual(qs_after.stats[0].tx_packets, \
361 qs_before.stats[0].tx_packets + 1, \
Howard Persh670b5672012-04-13 09:08:29 -0700362 "Verification of egress queue tx packet count failed"
363 )
364
365
Ken Chiang899ff8e2012-05-23 18:26:12 -0700366class DirectPacketControllerQueue(basic.SimpleDataPlane):
367 """
368 Send a packet from each of the openflow ports
369 to each of the queues configured on the controller port.
370 If no queues have been configured, no packets are sent.
Howard Pershf97840f2012-04-10 16:30:42 -0700371
Ken Chiang899ff8e2012-05-23 18:26:12 -0700372 Generate a packet
373 Generate and install a matching flow
374 Add action to direct the packet to one of the controller port queues
375 Send the packet to ingress dataplane port
376 Verify the packet is received on the controller port queue
377 """
378 def runTest(self):
379 self.handleFlow()
380
381 def portQueuesGet(self, queue_stats, port_num):
382 result = []
383 for qs in queue_stats.stats:
384 if qs.port_no != port_num:
385 continue
386 result.append(qs.queue_id)
387 return result
388
389 def handleFlow(self, pkttype='TCP'):
390 of_ports = pa_port_map.keys()
391 of_ports.sort()
392 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
393
394 if (pkttype == 'ICMP'):
395 pkt = simple_icmp_packet()
396 else:
397 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700398 match = packet_to_flow_match(self, pkt)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700399 match.wildcards &= ~ofp.OFPFW_IN_PORT
400 self.assertTrue(match is not None,
401 "Could not generate flow match from pkt")
402
403 # Get queue stats from switch
404
405 request = message.queue_stats_request()
406 request.port_no = ofp.OFPP_CONTROLLER
407 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700408 (queue_stats, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700409 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
410
411 act = action.action_enqueue()
412
413 for idx in range(len(of_ports)):
414 ingress_port = of_ports[idx]
415 egress_port = ofp.OFPP_CONTROLLER
416
417 pa_logger.info("Ingress port " + str(ingress_port)
418 + ", controller port queues "
419 + str(self.portQueuesGet(queue_stats, egress_port)))
420
421 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
422 pa_logger.info("Ingress " + str(ingress_port)
423 + " to egress " + str(egress_port)
424 + " queue " + str(egress_queue_id)
425 )
426
427 rv = delete_all_flows(self.controller, pa_logger)
428 self.assertEqual(rv, 0, "Failed to delete all flows")
429
430 match.in_port = ingress_port
431
432 request = message.flow_mod()
433 request.match = match
434
435 request.buffer_id = 0xffffffff
436 act.port = egress_port
437 act.queue_id = egress_queue_id
438 self.assertTrue(request.actions.add(act), "Could not add action")
439
440 pa_logger.info("Inserting flow")
441 rv = self.controller.message_send(request)
442 self.assertTrue(rv != -1, "Error installing flow mod")
443 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
444
445 # Get current stats for selected egress queue
446
447 request = message.queue_stats_request()
448 request.port_no = egress_port
449 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700450 (qs_before, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700451 self.assertNotEqual(qs_before, None, "Queue stats request failed")
452
453 pa_logger.info("Sending packet to dp port " +
454 str(ingress_port))
455 self.dataplane.send(ingress_port, str(pkt))
456
457 exp_pkt_arg = None
458 exp_port = None
459
460 while True:
461 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN, 2)
462 if not response: # Timeout
463 break
464 if dataplane.match_exp_pkt(pkt, response.data): # Got match
465 break
466 if not basic_config["relax"]: # Only one attempt to match
467 break
468 count += 1
469 if count > 10: # Too many tries
470 break
471
472 self.assertTrue(response is not None,
473 'Packet in message not received by controller')
474 if not dataplane.match_exp_pkt(pkt, response.data):
475 basic_logger.debug("Sent %s" % format_packet(pkt))
476 basic_logger.debug("Resp %s" % format_packet(response.data))
477 self.assertTrue(False,
478 'Response packet does not match send packet' +
479 ' for controller port')
480
481 # FIXME: instead of sleeping, keep requesting queue stats until
482 # the expected queue counter increases or some large timeout is
483 # reached
484 time.sleep(2)
485
486 # Get current stats for selected egress queue again
487
488 request = message.queue_stats_request()
489 request.port_no = egress_port
490 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700491 (qs_after, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700492 self.assertNotEqual(qs_after, None, "Queue stats request failed")
493
494 # Make sure that tx packet counter for selected egress queue was
495 # incremented
496
497 self.assertEqual(qs_after.stats[0].tx_packets, \
498 qs_before.stats[0].tx_packets + 1, \
499 "Verification of egress queue tx packet count failed"
500 )
501
Howard Pershf97840f2012-04-10 16:30:42 -0700502
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700503class DirectPacketICMP(DirectPacket):
504 """
505 Send ICMP packet to single egress port
506
507 Generate a ICMP packet
508 Generate and install a matching flow
509 Add action to direct the packet to an egress port
510 Send the packet to ingress dataplane port
511 Verify the packet is received at the egress port only
512 Difference from DirectPacket test is that sent packet is ICMP
513 """
514 def runTest(self):
515 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700516
517class DirectTwoPorts(basic.SimpleDataPlane):
518 """
519 Send packet to two egress ports
520
521 Generate a packet
522 Generate and install a matching flow
523 Add action to direct the packet to two egress ports
524 Send the packet to ingress dataplane port
525 Verify the packet is received at the two egress ports
526 """
527 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700528 of_ports = pa_port_map.keys()
529 of_ports.sort()
530 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
531
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700532 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700533 match = packet_to_flow_match(self, pkt)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700534 match.wildcards &= ~ofp.OFPFW_IN_PORT
535 self.assertTrue(match is not None,
536 "Could not generate flow match from pkt")
537 act = action.action_output()
538
539 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700540 rv = delete_all_flows(self.controller, pa_logger)
541 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700542
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700543 ingress_port = of_ports[idx]
544 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
545 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
546 pa_logger.info("Ingress " + str(ingress_port) +
547 " to egress " + str(egress_port1) + " and " +
548 str(egress_port2))
549
550 match.in_port = ingress_port
551
552 request = message.flow_mod()
553 request.match = match
554 request.buffer_id = 0xffffffff
555 act.port = egress_port1
556 self.assertTrue(request.actions.add(act), "Could not add action1")
557 act.port = egress_port2
558 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700559 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700560
561 pa_logger.info("Inserting flow")
562 rv = self.controller.message_send(request)
563 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700564 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700565
566 pa_logger.info("Sending packet to dp port " +
567 str(ingress_port))
568 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700569 yes_ports = set([egress_port1, egress_port2])
570 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700571
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700572 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700573 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700574
575class DirectMCNonIngress(basic.SimpleDataPlane):
576 """
577 Multicast to all non-ingress ports
578
579 Generate a packet
580 Generate and install a matching flow
581 Add action to direct the packet to all non-ingress ports
582 Send the packet to ingress dataplane port
583 Verify the packet is received at all non-ingress ports
584
585 Does not use the flood action
586 """
587 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700588 of_ports = pa_port_map.keys()
589 of_ports.sort()
590 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
591
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700592 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700593 match = packet_to_flow_match(self, pkt)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700594 match.wildcards &= ~ofp.OFPFW_IN_PORT
595 self.assertTrue(match is not None,
596 "Could not generate flow match from pkt")
597 act = action.action_output()
598
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700599 for ingress_port in of_ports:
600 rv = delete_all_flows(self.controller, pa_logger)
601 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700602
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700603 pa_logger.info("Ingress " + str(ingress_port) +
604 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700605 match.in_port = ingress_port
606
607 request = message.flow_mod()
608 request.match = match
609 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700610 for egress_port in of_ports:
611 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700612 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700613 act.port = egress_port
614 self.assertTrue(request.actions.add(act),
615 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700616 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700617
618 pa_logger.info("Inserting flow")
619 rv = self.controller.message_send(request)
620 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700621 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700622
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700623 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700624 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700625 yes_ports = set(of_ports).difference([ingress_port])
626 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700627 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700628
Dan Talayco32fa6542010-05-11 15:54:08 -0700629
630class DirectMC(basic.SimpleDataPlane):
631 """
632 Multicast to all ports including ingress
633
634 Generate a packet
635 Generate and install a matching flow
636 Add action to direct the packet to all non-ingress ports
637 Send the packet to ingress dataplane port
638 Verify the packet is received at all ports
639
640 Does not use the flood action
641 """
642 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700643 of_ports = pa_port_map.keys()
644 of_ports.sort()
645 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
646
Dan Talayco32fa6542010-05-11 15:54:08 -0700647 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700648 match = packet_to_flow_match(self, pkt)
Dan Talayco32fa6542010-05-11 15:54:08 -0700649 match.wildcards &= ~ofp.OFPFW_IN_PORT
650 self.assertTrue(match is not None,
651 "Could not generate flow match from pkt")
652 act = action.action_output()
653
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700654 for ingress_port in of_ports:
655 rv = delete_all_flows(self.controller, pa_logger)
656 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700657
Dan Talayco32fa6542010-05-11 15:54:08 -0700658 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700659 match.in_port = ingress_port
660
661 request = message.flow_mod()
662 request.match = match
663 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700664 for egress_port in of_ports:
665 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700666 act.port = ofp.OFPP_IN_PORT
667 else:
668 act.port = egress_port
669 self.assertTrue(request.actions.add(act),
670 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700671 # pa_logger.info(request.show())
672
673 pa_logger.info("Inserting flow")
674 rv = self.controller.message_send(request)
675 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700676 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2e77a842010-05-12 15:39:46 -0700677
678 pa_logger.info("Sending packet to dp port " + str(ingress_port))
679 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700680 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700681 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700682
683class Flood(basic.SimpleDataPlane):
684 """
685 Flood to all ports except ingress
686
687 Generate a packet
688 Generate and install a matching flow
689 Add action to flood the packet
690 Send the packet to ingress dataplane port
691 Verify the packet is received at all other ports
692 """
693 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700694 of_ports = pa_port_map.keys()
695 of_ports.sort()
696 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
697
698 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700699 match = packet_to_flow_match(self, pkt)
Dan Talayco2e77a842010-05-12 15:39:46 -0700700 match.wildcards &= ~ofp.OFPFW_IN_PORT
701 self.assertTrue(match is not None,
702 "Could not generate flow match from pkt")
703 act = action.action_output()
704
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700705 for ingress_port in of_ports:
706 rv = delete_all_flows(self.controller, pa_logger)
707 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700708
Dan Talayco2e77a842010-05-12 15:39:46 -0700709 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700710 match.in_port = ingress_port
711
712 request = message.flow_mod()
713 request.match = match
714 request.buffer_id = 0xffffffff
715 act.port = ofp.OFPP_FLOOD
716 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700717 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700718 pa_logger.info(request.show())
719
720 pa_logger.info("Inserting flow")
721 rv = self.controller.message_send(request)
722 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700723 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco32fa6542010-05-11 15:54:08 -0700724
725 pa_logger.info("Sending packet to dp port " + str(ingress_port))
726 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700727 yes_ports = set(of_ports).difference([ingress_port])
728 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700729 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700730
Dan Talayco3be5b062010-05-12 15:46:21 -0700731class FloodPlusIngress(basic.SimpleDataPlane):
732 """
733 Flood to all ports plus send to ingress port
734
735 Generate a packet
736 Generate and install a matching flow
737 Add action to flood the packet
738 Add action to send to ingress port
739 Send the packet to ingress dataplane port
740 Verify the packet is received at all other ports
741 """
742 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700743 of_ports = pa_port_map.keys()
744 of_ports.sort()
745 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
746
747 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700748 match = packet_to_flow_match(self, pkt)
Dan Talayco3be5b062010-05-12 15:46:21 -0700749 match.wildcards &= ~ofp.OFPFW_IN_PORT
750 self.assertTrue(match is not None,
751 "Could not generate flow match from pkt")
752 act = action.action_output()
753
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700754 for ingress_port in of_ports:
755 rv = delete_all_flows(self.controller, pa_logger)
756 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700757
Dan Talayco3be5b062010-05-12 15:46:21 -0700758 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700759 match.in_port = ingress_port
760
761 request = message.flow_mod()
762 request.match = match
763 request.buffer_id = 0xffffffff
764 act.port = ofp.OFPP_FLOOD
765 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700766 "Could not add flood port action")
767 act.port = ofp.OFPP_IN_PORT
768 self.assertTrue(request.actions.add(act),
769 "Could not add ingress port for output")
770 pa_logger.info(request.show())
771
772 pa_logger.info("Inserting flow")
773 rv = self.controller.message_send(request)
774 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700775 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700776
777 pa_logger.info("Sending packet to dp port " + str(ingress_port))
778 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700779 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700780 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700781
782class All(basic.SimpleDataPlane):
783 """
784 Send to OFPP_ALL port
785
786 Generate a packet
787 Generate and install a matching flow
788 Add action to forward to OFPP_ALL
789 Send the packet to ingress dataplane port
790 Verify the packet is received at all other ports
791 """
792 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700793 of_ports = pa_port_map.keys()
794 of_ports.sort()
795 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
796
797 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700798 match = packet_to_flow_match(self, pkt)
Dan Talayco4aa13122010-05-12 15:54:44 -0700799 match.wildcards &= ~ofp.OFPFW_IN_PORT
800 self.assertTrue(match is not None,
801 "Could not generate flow match from pkt")
802 act = action.action_output()
803
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700804 for ingress_port in of_ports:
805 rv = delete_all_flows(self.controller, pa_logger)
806 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700807
Dan Talayco4aa13122010-05-12 15:54:44 -0700808 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700809 match.in_port = ingress_port
810
811 request = message.flow_mod()
812 request.match = match
813 request.buffer_id = 0xffffffff
814 act.port = ofp.OFPP_ALL
815 self.assertTrue(request.actions.add(act),
816 "Could not add ALL port action")
817 pa_logger.info(request.show())
818
819 pa_logger.info("Inserting flow")
820 rv = self.controller.message_send(request)
821 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700822 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700823
824 pa_logger.info("Sending packet to dp port " + str(ingress_port))
825 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700826 yes_ports = set(of_ports).difference([ingress_port])
827 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700828 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700829
830class AllPlusIngress(basic.SimpleDataPlane):
831 """
832 Send to OFPP_ALL port and ingress port
833
834 Generate a packet
835 Generate and install a matching flow
836 Add action to forward to OFPP_ALL
837 Add action to forward to ingress port
838 Send the packet to ingress dataplane port
839 Verify the packet is received at all other ports
840 """
841 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700842 of_ports = pa_port_map.keys()
843 of_ports.sort()
844 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
845
846 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700847 match = packet_to_flow_match(self, pkt)
Dan Talayco4aa13122010-05-12 15:54:44 -0700848 match.wildcards &= ~ofp.OFPFW_IN_PORT
849 self.assertTrue(match is not None,
850 "Could not generate flow match from pkt")
851 act = action.action_output()
852
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700853 for ingress_port in of_ports:
854 rv = delete_all_flows(self.controller, pa_logger)
855 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700856
Dan Talayco4aa13122010-05-12 15:54:44 -0700857 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700858 match.in_port = ingress_port
859
860 request = message.flow_mod()
861 request.match = match
862 request.buffer_id = 0xffffffff
863 act.port = ofp.OFPP_ALL
864 self.assertTrue(request.actions.add(act),
865 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700866 act.port = ofp.OFPP_IN_PORT
867 self.assertTrue(request.actions.add(act),
868 "Could not add ingress port for output")
869 pa_logger.info(request.show())
870
871 pa_logger.info("Inserting flow")
872 rv = self.controller.message_send(request)
873 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700874 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco3be5b062010-05-12 15:46:21 -0700875
876 pa_logger.info("Sending packet to dp port " + str(ingress_port))
877 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700878 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700879 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700880
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700881class FloodMinusPort(basic.SimpleDataPlane):
882 """
883 Config port with No_Flood and test Flood action
884
885 Generate a packet
886 Generate a matching flow
887 Add action to forward to OFPP_ALL
888 Set port to no-flood
889 Send the packet to ingress dataplane port
890 Verify the packet is received at all other ports except
891 the ingress port and the no_flood port
892 """
893 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700894 of_ports = pa_port_map.keys()
895 of_ports.sort()
896 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
897
898 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700899 match = packet_to_flow_match(self, pkt)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700900 match.wildcards &= ~ofp.OFPFW_IN_PORT
901 self.assertTrue(match is not None,
902 "Could not generate flow match from pkt")
903 act = action.action_output()
904
905 for idx in range(len(of_ports)):
906 rv = delete_all_flows(self.controller, pa_logger)
907 self.assertEqual(rv, 0, "Failed to delete all flows")
908
909 ingress_port = of_ports[idx]
910 no_flood_idx = (idx + 1) % len(of_ports)
911 no_flood_port = of_ports[no_flood_idx]
912 rv = port_config_set(self.controller, no_flood_port,
913 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
914 pa_logger)
915 self.assertEqual(rv, 0, "Failed to set port config")
916
917 match.in_port = ingress_port
918
919 request = message.flow_mod()
920 request.match = match
921 request.buffer_id = 0xffffffff
922 act.port = ofp.OFPP_FLOOD
923 self.assertTrue(request.actions.add(act),
924 "Could not add flood port action")
925 pa_logger.info(request.show())
926
927 pa_logger.info("Inserting flow")
928 rv = self.controller.message_send(request)
929 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700930 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700931
932 pa_logger.info("Sending packet to dp port " + str(ingress_port))
933 pa_logger.info("No flood port is " + str(no_flood_port))
934 self.dataplane.send(ingress_port, str(pkt))
935 no_ports = set([ingress_port, no_flood_port])
936 yes_ports = set(of_ports).difference(no_ports)
937 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700938 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700939
940 # Turn no flood off again
941 rv = port_config_set(self.controller, no_flood_port,
942 0, ofp.OFPPC_NO_FLOOD, pa_logger)
943 self.assertEqual(rv, 0, "Failed to reset port config")
944
945 #@todo Should check no other packets received
946
Dan Talayco21381562010-07-17 00:34:47 -0700947
948
Dan Talayco551befa2010-07-15 17:05:32 -0700949################################################################
950
951class BaseMatchCase(basic.SimpleDataPlane):
952 def setUp(self):
953 basic.SimpleDataPlane.setUp(self)
954 self.logger = pa_logger
955 def runTest(self):
956 self.logger.info("BaseMatchCase")
957
958class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700959 """
Dan Talayco551befa2010-07-15 17:05:32 -0700960 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700961
962 Generate a packet
963 Generate and install a matching flow without wildcard mask
964 Add action to forward to a port
965 Send the packet to the port
966 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700967 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700968
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700969 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700970 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700971
Dan Talayco551befa2010-07-15 17:05:32 -0700972class ExactMatchTagged(BaseMatchCase):
973 """
974 Exact match for all port pairs with tagged pkts
975 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700976
Dan Talayco551befa2010-07-15 17:05:32 -0700977 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700978 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700979 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700980
Dan Talayco551befa2010-07-15 17:05:32 -0700981class ExactMatchTaggedMany(BaseMatchCase):
982 """
983 ExactMatchTagged with many VLANS
984 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700985
Dan Talayco551befa2010-07-15 17:05:32 -0700986 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700987 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700988 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
989 for vid in range(100,4000,389):
990 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
991 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700992
Dan Talayco551befa2010-07-15 17:05:32 -0700993# Don't run by default
994test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700995
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700996
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700997class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700998 """
999 SingleWildcardMatchPriority
1000 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001001
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001002 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001003 self.pkt = simple_tcp_packet()
1004 self.flowMsgs = {}
1005
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001006 def _ClearTable(self):
1007 rc = delete_all_flows(self.controller, self.logger)
1008 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001009 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001010
1011 def runTest(self):
1012
1013 self._Init()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001014 of_ports = pa_port_map.keys()
1015 of_ports.sort()
1016
1017 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001018 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001019
1020 # Run several combinations, each at lower priority settings.
1021 # At the end of each call to runPrioFlows(), the table should
1022 # be empty. If its not, we'll catch it as the priorities decreases
1023 portA = of_ports[0]
1024 portB = of_ports[1]
1025 portC = of_ports[2]
1026
1027 # TODO -- these priority numbers should be validated somehow?
1028 self.runPrioFlows(portA, portB, portC, 1000, 999)
1029 self.runPrioFlows(portB, portC, portA, 998, 997)
1030 self.runPrioFlows(portC, portA, portB, 996, 995)
1031 self.runPrioFlows(portA, portC, portB, 994, 993)
1032
1033
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001034
1035 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
1036 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001037
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001038 if clearTable:
1039 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001040
1041 # Sanity check flow at lower priority from pA to pB
1042 self.logger.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
1043 % (portA, portB, portC, prioHigher, prioLower))
1044
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001045 # Sanity check flow at lower priority from pA to pC
1046 self.installFlow(prioLower, portA, portC)
1047 self.verifyFlow(portA, portC)
1048 self.removeFlow(prioLower)
1049
1050 # Install and verify pA->pB @ prioLower
1051 self.installFlow(prioLower, portA, portB)
1052 self.verifyFlow(portA, portB)
1053
1054 # Install and verify pA->pC @ prioHigher, should override pA->pB
1055 self.installFlow(prioHigher, portA, portC)
1056 self.verifyFlow(portA, portC)
1057 # remove pA->pC
1058 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001059 # Old flow pA -> pB @ prioLower should still be active
1060 self.verifyFlow(portA, portB)
1061 self.removeFlow(prioLower)
1062
1063 # Table should be empty at this point, leave it alone as
1064 # an assumption for future test runs
1065
1066
1067
Ed Swierk99a74de2012-08-22 06:40:54 -07001068 def installFlow(self, prio, inp, egp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001069 wildcards=ofp.OFPFW_DL_SRC):
Ed Swierk99a74de2012-08-22 06:40:54 -07001070 wildcards |= required_wildcards(self)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001071 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001072 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001073 egr_ports=egp)
1074 request.priority = prio
Ken Chiang38d7a152012-05-24 15:33:50 -07001075 self.logger.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001076 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001077 self.flowMsgs[prio] = request
1078
1079 def removeFlow(self, prio):
1080 if self.flowMsgs.has_key(prio):
1081 msg = self.flowMsgs[prio]
1082 msg.command = ofp.OFPFC_DELETE_STRICT
1083 # This *must* be set for DELETE
1084 msg.out_port = ofp.OFPP_NONE
Ken Chiang38d7a152012-05-24 15:33:50 -07001085 self.logger.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001086 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001087 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001088 else:
1089 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001090
1091
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001092 def verifyFlow(self, inp, egp, pkt=None):
1093 if pkt == None:
1094 pkt = self.pkt
1095
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001096 self.logger.info("Pkt match test: " + str(inp) +
1097 " to " + str(egp))
1098 self.logger.debug("Send packet: " + str(inp) + " to "
1099 + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001100 self.dataplane.send(inp, str(pkt))
1101 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001102
1103
1104
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001105class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1106
1107 def runTest(self):
1108
1109 self._Init()
1110
1111 of_ports = pa_port_map.keys()
1112 of_ports.sort()
1113
1114 # Install an entry from 0 -> 1 @ prio 1000
1115 self._ClearTable()
1116 self.installFlow(1000, of_ports[0], of_ports[1])
1117 self.verifyFlow(of_ports[0], of_ports[1])
1118 self.installFlow(1000, of_ports[1], of_ports[0])
1119 self.verifyFlow(of_ports[1], of_ports[0])
1120 self.installFlow(1001, of_ports[0], of_ports[1])
1121 self.verifyFlow(of_ports[0], of_ports[1])
1122 self.installFlow(1001, of_ports[1], of_ports[0])
1123 self.verifyFlow(of_ports[1], of_ports[0])
1124 self.removeFlow(1001)
1125 self.verifyFlow(of_ports[0], of_ports[1])
1126 self.removeFlow(1000)
1127
1128
1129
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001130class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001131 """
1132 1. Add wildcard flow, verify packet received.
1133 2. Add exact match flow with higher priority, verify packet received
1134 on port specified by this flow.
1135 3. Add wildcard flow with even higher priority, verify packet received
1136 on port specified by this flow.
1137 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001138
1139 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001140
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001141 self._Init()
1142
1143 of_ports = pa_port_map.keys()
1144 of_ports.sort()
1145
1146 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001147
1148 # Install a flow with wildcards
1149 self.installFlow(999, of_ports[0], of_ports[1],
1150 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001151 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001152 # Install a flow with no wildcards for our packet
1153 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001154 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001155 # Install a flow with wildcards for our packet with higher
1156 # priority
1157 self.installFlow(1001, of_ports[0], of_ports[3])
1158 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001159
1160
Ken Chiang3978f242012-06-13 14:14:09 -07001161class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001162 """
1163 1. Add exact match flow, verify packet received.
1164 2. Add wildcard flow with higher priority, verify packet received on port
1165 specified by this flow.
1166 3. Add exact match flow with even higher priority, verify packet received
1167 on port specified by this flow.
1168 4. Delete lowest priority flow, verify packet received on port specified
1169 by highest priority flow.
1170 5. Delete highest priority flow, verify packet received on port specified
1171 by remaining flow.
1172 """
1173
1174 def runTest(self):
1175
1176 self._Init()
1177
1178 of_ports = pa_port_map.keys()
1179 of_ports.sort()
1180
1181 self._ClearTable()
1182
1183 # Install an exact match flow
1184 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1185 self.verifyFlow(of_ports[0], of_ports[1])
1186 # Install a flow with wildcards of higher priority
1187 self.installFlow(1250, of_ports[0], of_ports[2],
1188 wildcards=ofp.OFPFW_DL_DST)
1189 self.verifyFlow(of_ports[0], of_ports[2])
1190 # Install an exact match flow with even higher priority
1191 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1192 self.verifyFlow(of_ports[0], of_ports[3])
1193 # Delete lowest priority flow
1194 self.removeFlow(250)
1195 self.verifyFlow(of_ports[0], of_ports[3])
1196 # Delete highest priority flow
1197 self.removeFlow(2001)
1198 self.verifyFlow(of_ports[0], of_ports[2])
1199
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001200
Dan Talayco551befa2010-07-15 17:05:32 -07001201class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001202 """
1203 Exercise wildcard matching for all ports
1204
1205 Generate a packet
1206 Generate and install a matching flow with wildcard mask
1207 Add action to forward to a port
1208 Send the packet to the port
1209 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001210 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001211 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001212 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001213 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001214 for wc in WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001215 wc |= required_wildcards(self)
Dan Talayco4431d542012-03-21 16:42:16 -07001216 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001217 # Set nonzero VLAN id to avoid sending priority-tagged packet
1218 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001219 else:
1220 dl_vlan = -1
1221 flow_match_test(self, pa_port_map, wildcards=wc,
1222 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001223
Dan Talayco551befa2010-07-15 17:05:32 -07001224class SingleWildcardMatchTagged(BaseMatchCase):
1225 """
1226 SingleWildcardMatch with tagged packets
1227 """
1228 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001229 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001230 for wc in WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001231 wc |= required_wildcards(self)
Dan Talayco21381562010-07-17 00:34:47 -07001232 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001233 max_test=10)
1234
1235class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001236 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001237 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001238
1239 Generate a packet
1240 Generate and install a matching flow with wildcard all except one filed
1241 Add action to forward to a port
1242 Send the packet to the port
1243 Verify the packet is received at all other ports (one port at a time)
1244 Verify flow_expiration message is correct when command option is set
1245 """
1246 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001247 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001248 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001249 all_exp_one_wildcard |= required_wildcards(self)
Dan Talayco4431d542012-03-21 16:42:16 -07001250 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001251 # Set nonzero VLAN id to avoid sending priority-tagged packet
1252 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001253 else:
1254 dl_vlan = -1
1255 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1256 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001257
Dan Talayco551befa2010-07-15 17:05:32 -07001258class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1259 """
1260 Match one field with tagged packets
1261 """
1262 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001263 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001264 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001265 all_exp_one_wildcard |= required_wildcards(self)
Dan Talayco21381562010-07-17 00:34:47 -07001266 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1267 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001268
1269class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001270 """
1271 Create Wildcard-all flow and exercise for all ports
1272
1273 Generate a packet
1274 Generate and install a matching flow with wildcard-all
1275 Add action to forward to a port
1276 Send the packet to the port
1277 Verify the packet is received at all other ports (one port at a time)
1278 Verify flow_expiration message is correct when command option is set
1279 """
1280 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -07001281 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001282
Dan Talayco551befa2010-07-15 17:05:32 -07001283class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001284 """
Dan Talayco551befa2010-07-15 17:05:32 -07001285 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001286 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001287 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001288 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -07001289 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
1290 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001291
Dan Talaycoba3745c2010-07-21 21:51:08 -07001292
Dan Talayco551befa2010-07-15 17:05:32 -07001293class AddVLANTag(BaseMatchCase):
1294 """
1295 Add a VLAN tag to an untagged packet
1296 """
1297 def runTest(self):
1298 new_vid = 2
Ed Swierkc7193a22012-08-22 06:51:02 -07001299 sup_acts = self.supported_actions
Dan Talayco551befa2010-07-15 17:05:32 -07001300 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001301 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001302 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001303
Dan Talayco551befa2010-07-15 17:05:32 -07001304 len = 100
1305 len_w_vid = 104
1306 pkt = simple_tcp_packet(pktlen=len)
1307 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1308 dl_vlan=new_vid)
1309 vid_act = action.action_set_vlan_vid()
1310 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001311
Dan Talayco551befa2010-07-15 17:05:32 -07001312 flow_match_test(self, pa_port_map, pkt=pkt,
1313 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001314
Dan Talayco551befa2010-07-15 17:05:32 -07001315class PacketOnly(basic.DataPlaneOnly):
1316 """
1317 Just send a packet thru the switch
1318 """
1319 def runTest(self):
1320 pkt = simple_tcp_packet()
1321 of_ports = pa_port_map.keys()
1322 of_ports.sort()
1323 ing_port = of_ports[0]
1324 pa_logger.info("Sending packet to " + str(ing_port))
1325 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1326 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001327
Dan Talayco551befa2010-07-15 17:05:32 -07001328class PacketOnlyTagged(basic.DataPlaneOnly):
1329 """
1330 Just send a packet thru the switch
1331 """
1332 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001333 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001334 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
1335 of_ports = pa_port_map.keys()
1336 of_ports.sort()
1337 ing_port = of_ports[0]
1338 pa_logger.info("Sending packet to " + str(ing_port))
1339 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1340 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001341
Dan Talayco551befa2010-07-15 17:05:32 -07001342test_prio["PacketOnly"] = -1
1343test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001344
Dan Talayco551befa2010-07-15 17:05:32 -07001345class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001346 """
1347 Modify the VLAN ID in the VLAN tag of a tagged packet
1348 """
Dan Talayco551befa2010-07-15 17:05:32 -07001349 def runTest(self):
1350 old_vid = 2
1351 new_vid = 3
Ed Swierkc7193a22012-08-22 06:51:02 -07001352 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001353 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001354 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001355 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001356
Dan Talayco551befa2010-07-15 17:05:32 -07001357 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1358 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1359 vid_act = action.action_set_vlan_vid()
1360 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001361
Dan Talayco551befa2010-07-15 17:05:32 -07001362 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1363 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001364
Ken Chiange9a211d2012-04-20 14:52:11 -07001365class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1366 """
1367 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1368 The same flow should match on both untagged and tagged packets.
1369 """
1370 def runTest(self):
1371 old_vid = 2
1372 new_vid = 3
Ed Swierkc7193a22012-08-22 06:51:02 -07001373 sup_acts = self.supported_actions
Ken Chiange9a211d2012-04-20 14:52:11 -07001374 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1375 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1376 return
1377
1378 of_ports = pa_port_map.keys()
1379 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1380 ing_port = of_ports[0]
1381 egr_ports = of_ports[1]
1382
1383 rv = delete_all_flows(self.controller, pa_logger)
1384 self.assertEqual(rv, 0, "Failed to delete all flows")
1385
1386 len_untagged = 100
1387 len_w_vid = 104
1388 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1389 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1390 dl_vlan_enable=True, dl_vlan=old_vid)
1391 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1392 dl_vlan=new_vid)
Ed Swierk99a74de2012-08-22 06:40:54 -07001393 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_VLAN |
1394 ofp.OFPFW_DL_VLAN_PCP)
Ken Chiange9a211d2012-04-20 14:52:11 -07001395 vid_act = action.action_set_vlan_vid()
1396 vid_act.vlan_vid = new_vid
1397 request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
1398 wildcards=wildcards, egr_ports=egr_ports,
1399 action_list=[vid_act])
1400 flow_msg_install(self, request)
1401
1402 pa_logger.debug("Send untagged packet: " + str(ing_port) + " to " +
1403 str(egr_ports))
1404 self.dataplane.send(ing_port, str(untagged_pkt))
1405 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1406
1407 pa_logger.debug("Send tagged packet: " + str(ing_port) + " to " +
1408 str(egr_ports))
1409 self.dataplane.send(ing_port, str(tagged_pkt))
1410 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1411
Howard Pershc1199d52012-04-11 14:21:32 -07001412class ModifyVlanPcp(BaseMatchCase):
1413 """
1414 Modify the priority field of the VLAN tag of a tagged packet
1415 """
1416 def runTest(self):
1417 vid = 123
1418 old_vlan_pcp = 2
1419 new_vlan_pcp = 3
Ed Swierkc7193a22012-08-22 06:51:02 -07001420 sup_acts = self.supported_actions
Ed Swierk8c3af7f2012-04-24 14:19:17 -07001421 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_PCP):
1422 skip_message_emit(self, "Modify VLAN priority test")
Howard Pershc1199d52012-04-11 14:21:32 -07001423 return
1424
1425 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=old_vlan_pcp)
1426 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=new_vlan_pcp)
1427 vid_act = action.action_set_vlan_pcp()
1428 vid_act.vlan_pcp = new_vlan_pcp
1429
1430 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1431 action_list=[vid_act])
1432
Dan Talayco551befa2010-07-15 17:05:32 -07001433class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001434 """
1435 Strip the VLAN tag from a tagged packet
1436 """
Dan Talayco551befa2010-07-15 17:05:32 -07001437 def runTest(self):
1438 old_vid = 2
Ed Swierkc7193a22012-08-22 06:51:02 -07001439 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001440 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001441 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001442 return
Dan Talaycof36f1082010-07-13 13:57:17 -07001443
Dan Talayco551befa2010-07-15 17:05:32 -07001444 len_w_vid = 104
1445 len = 100
1446 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1447 dl_vlan=old_vid)
1448 exp_pkt = simple_tcp_packet(pktlen=len)
1449 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001450
Dan Talayco551befa2010-07-15 17:05:32 -07001451 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1452 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001453
Ken Chiange9a211d2012-04-20 14:52:11 -07001454class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
1455 """
1456 Strip the VLAN tag from a tagged packet.
1457 Differs from StripVLANTag in that VID and PCP are both wildcarded.
1458 """
1459 def runTest(self):
1460 old_vid = 2
Ed Swierkc7193a22012-08-22 06:51:02 -07001461 sup_acts = self.supported_actions
Ken Chiange9a211d2012-04-20 14:52:11 -07001462 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
1463 skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
1464 return
1465
1466 len_w_vid = 104
1467 len_untagged = 100
1468 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1469 dl_vlan=old_vid)
1470 exp_pkt = simple_tcp_packet(pktlen=len_untagged)
Ed Swierk99a74de2012-08-22 06:40:54 -07001471 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_VLAN |
1472 ofp.OFPFW_DL_VLAN_PCP)
Ken Chiange9a211d2012-04-20 14:52:11 -07001473 vid_act = action.action_strip_vlan()
1474
1475 flow_match_test(self, pa_port_map,
Ed Swierk99a74de2012-08-22 06:40:54 -07001476 wildcards=wildcards,
Ken Chiange9a211d2012-04-20 14:52:11 -07001477 pkt=pkt, exp_pkt=exp_pkt,
1478 action_list=[vid_act])
1479
Dan Talayco4b2bee62010-07-20 14:10:05 -07001480def init_pkt_args():
1481 """
1482 Pass back a dictionary with default packet arguments
1483 """
1484 args = {}
1485 args["dl_src"] = '00:23:45:67:89:AB'
1486
1487 dl_vlan_enable=False
1488 dl_vlan=-1
1489 if pa_config["test-params"]["vid"]:
1490 dl_vlan_enable=True
1491 dl_vlan = pa_config["test-params"]["vid"]
1492
1493# Unpack operator is ** on a dictionary
1494
1495 return args
1496
Dan Talayco551befa2010-07-15 17:05:32 -07001497class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001498 """
1499 Modify the source MAC address (TP1)
1500 """
Dan Talayco551befa2010-07-15 17:05:32 -07001501 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001502 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001503 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001504 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001505 return
1506
1507 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1508 check_test_params=True)
1509 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1510 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001511
Dan Talayco551befa2010-07-15 17:05:32 -07001512class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001513 """
1514 Modify the dest MAC address (TP1)
1515 """
Dan Talayco551befa2010-07-15 17:05:32 -07001516 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001517 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001518 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001519 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001520 return
1521
1522 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1523 check_test_params=True)
1524 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1525 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001526
Dan Talayco551befa2010-07-15 17:05:32 -07001527class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001528 """
1529 Modify the source IP address of an IP packet (TP1)
1530 """
Dan Talayco551befa2010-07-15 17:05:32 -07001531 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001532 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001533 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001534 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001535 return
1536
1537 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1538 check_test_params=True)
1539 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1540 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001541
Dan Talayco551befa2010-07-15 17:05:32 -07001542class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001543 """
1544 Modify the dest IP address of an IP packet (TP1)
1545 """
Dan Talayco551befa2010-07-15 17:05:32 -07001546 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001547 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001548 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001549 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001550 return
1551
1552 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1553 check_test_params=True)
1554 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1555 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001556
1557class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001558 """
1559 Modify the source TCP port of a TCP packet (TP1)
1560 """
Dan Talayco551befa2010-07-15 17:05:32 -07001561 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001562 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001563 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001564 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001565 return
1566
1567 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1568 check_test_params=True)
1569 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1570 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001571
1572class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001573 """
1574 Modify the dest TCP port of a TCP packet (TP1)
1575 """
Dan Talayco551befa2010-07-15 17:05:32 -07001576 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001577 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001578 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001579 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001580 return
1581
1582 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1583 check_test_params=True)
1584 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1585 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001586
1587class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001588 """
1589 Modify the IP type of service of an IP packet (TP1)
1590 """
Dan Talayco551befa2010-07-15 17:05:32 -07001591 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001592 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001593 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001594 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001595 return
Dan Talayco551befa2010-07-15 17:05:32 -07001596
Dan Talayco4b2bee62010-07-20 14:10:05 -07001597 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1598 check_test_params=True)
1599 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001600 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001601
Dan Talaycof6e76c02012-03-23 10:56:12 -07001602class ModifyL2DstMC(BaseMatchCase):
1603 """
1604 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001605 """
1606 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001607 sup_acts = self.supported_actions
Dan Talaycof6e76c02012-03-23 10:56:12 -07001608 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001609 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001610 return
1611
Dan Talaycof6e76c02012-03-23 10:56:12 -07001612 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1613 check_test_params=True)
1614 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001615 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001616
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001617class ModifyL2DstIngress(BaseMatchCase):
1618 """
1619 Modify the L2 dest and send to the ingress port
1620 """
1621 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001622 sup_acts = self.supported_actions
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001623 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001624 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001625 return
1626
1627 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1628 check_test_params=True)
1629 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1630 action_list=acts, max_test=2, egr_count=0,
1631 ing_port=True)
1632
Dan Talaycod8ae7582012-03-23 12:24:56 -07001633class ModifyL2DstIngressMC(BaseMatchCase):
1634 """
1635 Modify the L2 dest and send to the ingress port
1636 """
1637 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001638 sup_acts = self.supported_actions
Dan Talaycod8ae7582012-03-23 12:24:56 -07001639 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1640 skip_message_emit(self, "ModifyL2dstMC test")
1641 return
1642
1643 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1644 check_test_params=True)
1645 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1646 action_list=acts, max_test=2, egr_count=-1,
1647 ing_port=True)
1648
Dan Talaycof6e76c02012-03-23 10:56:12 -07001649class ModifyL2SrcMC(BaseMatchCase):
1650 """
1651 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001652 """
1653 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001654 sup_acts = self.supported_actions
Dan Talaycof6e76c02012-03-23 10:56:12 -07001655 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001656 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001657 return
1658
Dan Talaycof6e76c02012-03-23 10:56:12 -07001659 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1660 check_test_params=True)
1661 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001662 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001663
1664class ModifyL2SrcDstMC(BaseMatchCase):
1665 """
1666 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001667 """
1668 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001669 sup_acts = self.supported_actions
Dan Talaycocfa172f2012-03-23 12:03:00 -07001670 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1671 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1672 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001673 return
1674
Dan Talaycof6e76c02012-03-23 10:56:12 -07001675 mod_fields = ['dl_dst', 'dl_src']
1676 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1677 check_test_params=True)
1678 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001679 action_list=acts, max_test=2, egr_count=-1)
1680
1681class ModifyL2DstVIDMC(BaseMatchCase):
1682 """
1683 Modify the L2 dest and send to 2 ports
1684 """
1685 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001686 sup_acts = self.supported_actions
Dan Talaycocfa172f2012-03-23 12:03:00 -07001687 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1688 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1689 skip_message_emit(self, "ModifyL2DstVIDMC test")
1690 return
1691
1692 mod_fields = ['dl_dst', 'dl_vlan']
1693 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1694 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1695 check_test_params=True)
1696 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1697 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001698
Dan Talaycofa6454f2012-04-05 10:04:13 -07001699class FlowToggle(BaseMatchCase):
1700 """
1701 Add flows to the table and modify them repeatedly
Dan Talaycof7c41312012-07-23 12:53:19 -07001702
1703 This is done by using only "add" flow messages. Since the check overlap
1704 flag is not set, the switch is supposed to modify the existing flow if
1705 the match already exists.
1706
1707 Would probably be better to exercise more of the flow modify commands
1708 (add, modify, delete +/- strict).
Dan Talaycofa6454f2012-04-05 10:04:13 -07001709 """
1710 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001711 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1712 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001713
1714 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1715 (flow_count, iter_count))
1716 acts = []
1717 acts.append(action.action_output())
1718 acts.append(action.action_output())
1719
1720 of_ports = pa_port_map.keys()
1721 if len(of_ports) < 3:
1722 self.assertTrue(False, "Too few ports for test")
1723
1724 for idx in range(2):
1725 acts[idx].port = of_ports[idx]
1726
1727 flows = []
1728 flows.append([])
1729 flows.append([])
1730
Ed Swierk99a74de2012-08-22 06:40:54 -07001731 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_SRC |
1732 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()
Ed Swierk99a74de2012-08-22 06:40:54 -07001738 match = packet_to_flow_match(self, 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 Talayco9f47f4d2010-06-03 13:54:37 -07001879if __name__ == "__main__":
1880 print "Please run through oft script: ./oft --test_spec=basic"