blob: 73ef8c4991db9e0696c3a1b55a88c1b2459354f4 [file] [log] [blame]
Dan Talayco5eba8442010-03-10 13:58:43 -08001"""
2Test cases for testing actions taken on packets
3
4See basic.py for other info.
5
6It is recommended that these definitions be kept in their own
7namespace as different groups of tests will likely define
8similar identifiers.
9
10 The function test_set_init is called with a complete configuration
11dictionary prior to the invocation of any tests from this file.
12
13 The switch is actively attempting to contact the controller at the address
14indicated oin oft_config
15
16"""
17
Dan Talayco9f47f4d2010-06-03 13:54:37 -070018import copy
19
Dan Talayco5eba8442010-03-10 13:58:43 -080020import logging
21
22import unittest
23
24import oftest.controller as controller
25import oftest.cstruct as ofp
26import oftest.message as message
27import oftest.dataplane as dataplane
28import oftest.action as action
29import oftest.parse as parse
30import basic
Dan Talayco8a64e332012-03-28 14:53:20 -070031import time
Dan Talayco5eba8442010-03-10 13:58:43 -080032
33from testutils import *
34
35#@var port_map Local copy of the configuration map from OF port
36# numbers to OS interfaces
37pa_port_map = None
38#@var pa_logger Local logger object
39pa_logger = None
40#@var pa_config Local copy of global configuration data
41pa_config = None
42
Dan Talayco551befa2010-07-15 17:05:32 -070043# For test priority
44#@var test_prio Set test priority for local tests
45test_prio = {}
46
47WILDCARD_VALUES = [ofp.OFPFW_IN_PORT,
Dan Talayco488fbc52012-04-09 16:30:41 -070048 ofp.OFPFW_DL_VLAN | ofp.OFPFW_DL_VLAN_PCP,
Dan Talayco551befa2010-07-15 17:05:32 -070049 ofp.OFPFW_DL_SRC,
50 ofp.OFPFW_DL_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070051 (ofp.OFPFW_DL_TYPE | ofp.OFPFW_NW_SRC_ALL |
52 ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS | ofp.OFPFW_NW_PROTO |
53 ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
54 (ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
Dan Talayco551befa2010-07-15 17:05:32 -070055 ofp.OFPFW_TP_SRC,
56 ofp.OFPFW_TP_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070057 ofp.OFPFW_NW_SRC_MASK,
58 ofp.OFPFW_NW_DST_MASK,
Dan Talayco551befa2010-07-15 17:05:32 -070059 ofp.OFPFW_DL_VLAN_PCP,
60 ofp.OFPFW_NW_TOS]
61
Dan Talayco488fbc52012-04-09 16:30:41 -070062NO_WILDCARD_VALUES = [(ofp.OFPFW_ALL ^ ofp.OFPFW_IN_PORT),
63 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_VLAN),
64 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_SRC),
65 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_DST),
66 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE),
67 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO),
68 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
69 ofp.OFPFW_TP_SRC),
70 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
71 ofp.OFPFW_TP_DST),
72 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
73 ofp.OFPFW_NW_SRC_MASK),
74 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
75 ofp.OFPFW_NW_DST_MASK),
76 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_VLAN ^ ofp.OFPFW_DL_VLAN_PCP),
77 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
78 ofp.OFPFW_NW_TOS)]
79
Dan Talayco551befa2010-07-15 17:05:32 -070080MODIFY_ACTION_VALUES = [ofp.OFPAT_SET_VLAN_VID,
81 ofp.OFPAT_SET_VLAN_PCP,
82 ofp.OFPAT_STRIP_VLAN,
83 ofp.OFPAT_SET_DL_SRC,
84 ofp.OFPAT_SET_DL_DST,
85 ofp.OFPAT_SET_NW_SRC,
86 ofp.OFPAT_SET_NW_DST,
87 ofp.OFPAT_SET_NW_TOS,
88 ofp.OFPAT_SET_TP_SRC,
89 ofp.OFPAT_SET_TP_DST]
90
91# Cache supported features to avoid transaction overhead
92cached_supported_actions = None
93
Dan Talayco21381562010-07-17 00:34:47 -070094TEST_VID_DEFAULT = 2
95
Dan Talayco5eba8442010-03-10 13:58:43 -080096def test_set_init(config):
97 """
98 Set up function for packet action test classes
99
100 @param config The configuration dictionary; see oft
101 """
102
Ed Swierk89f78352012-03-29 12:32:32 -0700103 basic.test_set_init(config)
104
Dan Talayco5eba8442010-03-10 13:58:43 -0800105 global pa_port_map
106 global pa_logger
107 global pa_config
108
109 pa_logger = logging.getLogger("pkt_act")
110 pa_logger.info("Initializing test set")
111 pa_port_map = config["port_map"]
112 pa_config = config
113
114class DirectPacket(basic.SimpleDataPlane):
115 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700116 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -0800117
118 Generate a packet
119 Generate and install a matching flow
120 Add action to direct the packet to an egress port
121 Send the packet to ingress dataplane port
122 Verify the packet is received at the egress port only
123 """
124 def runTest(self):
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700125 self.handleFlow()
126
127 def handleFlow(self, pkttype='TCP'):
Dan Talayco5eba8442010-03-10 13:58:43 -0800128 of_ports = pa_port_map.keys()
129 of_ports.sort()
130 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
131
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700132 if (pkttype == 'ICMP'):
133 pkt = simple_icmp_packet()
134 else:
135 pkt = simple_tcp_packet()
Dan Talayco5eba8442010-03-10 13:58:43 -0800136 match = parse.packet_to_flow_match(pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -0700137 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -0800138 self.assertTrue(match is not None,
139 "Could not generate flow match from pkt")
140 act = action.action_output()
141
142 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700143 rv = delete_all_flows(self.controller, pa_logger)
144 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700145
Dan Talayco5eba8442010-03-10 13:58:43 -0800146 ingress_port = of_ports[idx]
147 egress_port = of_ports[(idx + 1) % len(of_ports)]
148 pa_logger.info("Ingress " + str(ingress_port) +
Dan Talayco551befa2010-07-15 17:05:32 -0700149 " to egress " + str(egress_port))
Dan Talayco5eba8442010-03-10 13:58:43 -0800150
151 match.in_port = ingress_port
152
153 request = message.flow_mod()
154 request.match = match
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700155
Dan Talayco5eba8442010-03-10 13:58:43 -0800156 request.buffer_id = 0xffffffff
157 act.port = egress_port
158 self.assertTrue(request.actions.add(act), "Could not add action")
159
160 pa_logger.info("Inserting flow")
161 rv = self.controller.message_send(request)
162 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700163 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco5eba8442010-03-10 13:58:43 -0800164
165 pa_logger.info("Sending packet to dp port " +
166 str(ingress_port))
167 self.dataplane.send(ingress_port, str(pkt))
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700168
169 exp_pkt_arg = None
170 exp_port = None
171 if pa_config["relax"]:
172 exp_pkt_arg = pkt
173 exp_port = egress_port
174
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700175 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700176 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800177 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700178 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800179 str(rcv_port))
180 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
181 self.assertEqual(str(pkt), str(rcv_pkt),
182 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700183
Howard Pershf97840f2012-04-10 16:30:42 -0700184
185class DirectPacketQueue(basic.SimpleDataPlane):
186 """
187 Send packet to single queue on single egress port
188
189 Generate a packet
190 Generate and install a matching flow
191 Add action to direct the packet to an egress port and queue
192 Send the packet to ingress dataplane port
193 Verify the packet is received at the egress port only
194 """
195 def runTest(self):
196 self.handleFlow()
197
Howard Persh670b5672012-04-13 09:08:29 -0700198 def portQueuesGet(self, queue_stats, port_num):
199 result = []
200 for qs in queue_stats.stats:
201 if qs.port_no != port_num:
202 continue
203 result.append(qs.queue_id)
204 return result
205
Howard Pershf97840f2012-04-10 16:30:42 -0700206 def handleFlow(self, pkttype='TCP'):
207 of_ports = pa_port_map.keys()
208 of_ports.sort()
209 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
210
211 if (pkttype == 'ICMP'):
212 pkt = simple_icmp_packet()
213 else:
214 pkt = simple_tcp_packet()
215 match = parse.packet_to_flow_match(pkt)
216 match.wildcards &= ~ofp.OFPFW_IN_PORT
217 self.assertTrue(match is not None,
218 "Could not generate flow match from pkt")
219
Howard Persh670b5672012-04-13 09:08:29 -0700220 # Get queue stats from switch
221
222 request = message.queue_stats_request()
223 request.port_no = ofp.OFPP_ALL
224 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700225 (queue_stats, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700226 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
227
228 act = action.action_enqueue()
Howard Pershf97840f2012-04-10 16:30:42 -0700229
230 for idx in range(len(of_ports)):
Howard Pershf97840f2012-04-10 16:30:42 -0700231 ingress_port = of_ports[idx]
232 egress_port = of_ports[(idx + 1) % len(of_ports)]
Howard Pershf97840f2012-04-10 16:30:42 -0700233
Howard Persh670b5672012-04-13 09:08:29 -0700234 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
235 pa_logger.info("Ingress " + str(ingress_port)
236 + " to egress " + str(egress_port)
237 + " queue " + str(egress_queue_id)
238 )
Howard Pershf97840f2012-04-10 16:30:42 -0700239
Howard Persh670b5672012-04-13 09:08:29 -0700240 rv = delete_all_flows(self.controller, pa_logger)
241 self.assertEqual(rv, 0, "Failed to delete all flows")
Howard Pershf97840f2012-04-10 16:30:42 -0700242
Howard Persh670b5672012-04-13 09:08:29 -0700243 match.in_port = ingress_port
244
245 request = message.flow_mod()
246 request.match = match
Howard Pershf97840f2012-04-10 16:30:42 -0700247
Howard Persh670b5672012-04-13 09:08:29 -0700248 request.buffer_id = 0xffffffff
249 act.port = egress_port
250 act.queue_id = egress_queue_id
251 self.assertTrue(request.actions.add(act), "Could not add action")
Howard Pershf97840f2012-04-10 16:30:42 -0700252
Howard Persh670b5672012-04-13 09:08:29 -0700253 pa_logger.info("Inserting flow")
254 rv = self.controller.message_send(request)
255 self.assertTrue(rv != -1, "Error installing flow mod")
256 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Howard Pershf97840f2012-04-10 16:30:42 -0700257
Howard Persh670b5672012-04-13 09:08:29 -0700258 # Get current stats for selected egress queue
Howard Pershf97840f2012-04-10 16:30:42 -0700259
Howard Persh670b5672012-04-13 09:08:29 -0700260 request = message.queue_stats_request()
261 request.port_no = egress_port
262 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700263 (qs_before, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700264 self.assertNotEqual(qs_before, None, "Queue stats request failed")
265
266 pa_logger.info("Sending packet to dp port " +
267 str(ingress_port))
268 self.dataplane.send(ingress_port, str(pkt))
269
270 exp_pkt_arg = None
271 exp_port = None
272 if pa_config["relax"]:
273 exp_pkt_arg = pkt
274 exp_port = egress_port
275
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700276 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Howard Persh670b5672012-04-13 09:08:29 -0700277 exp_pkt=exp_pkt_arg)
278 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
279 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
280 str(rcv_port))
281 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
282 self.assertEqual(str(pkt), str(rcv_pkt),
283 'Response packet does not match send packet')
284
Ed Swierkb8a86512012-04-18 18:45:58 -0700285 # FIXME: instead of sleeping, keep requesting queue stats until
286 # the expected queue counter increases or some large timeout is
287 # reached
288 time.sleep(2)
289
Howard Persh670b5672012-04-13 09:08:29 -0700290 # Get current stats for selected egress queue again
291
292 request = message.queue_stats_request()
293 request.port_no = egress_port
294 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700295 (qs_after, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700296 self.assertNotEqual(qs_after, None, "Queue stats request failed")
297
298 # Make sure that tx packet counter for selected egress queue was
299 # incremented
300
Ed Swierk22f59152012-04-17 16:36:47 -0700301 self.assertEqual(qs_after.stats[0].tx_packets, \
302 qs_before.stats[0].tx_packets + 1, \
Howard Persh670b5672012-04-13 09:08:29 -0700303 "Verification of egress queue tx packet count failed"
304 )
305
306
Ken Chiang899ff8e2012-05-23 18:26:12 -0700307class DirectPacketControllerQueue(basic.SimpleDataPlane):
308 """
309 Send a packet from each of the openflow ports
310 to each of the queues configured on the controller port.
311 If no queues have been configured, no packets are sent.
Howard Pershf97840f2012-04-10 16:30:42 -0700312
Ken Chiang899ff8e2012-05-23 18:26:12 -0700313 Generate a packet
314 Generate and install a matching flow
315 Add action to direct the packet to one of the controller port queues
316 Send the packet to ingress dataplane port
317 Verify the packet is received on the controller port queue
318 """
319 def runTest(self):
320 self.handleFlow()
321
322 def portQueuesGet(self, queue_stats, port_num):
323 result = []
324 for qs in queue_stats.stats:
325 if qs.port_no != port_num:
326 continue
327 result.append(qs.queue_id)
328 return result
329
330 def handleFlow(self, pkttype='TCP'):
331 of_ports = pa_port_map.keys()
332 of_ports.sort()
333 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
334
335 if (pkttype == 'ICMP'):
336 pkt = simple_icmp_packet()
337 else:
338 pkt = simple_tcp_packet()
339 match = parse.packet_to_flow_match(pkt)
340 match.wildcards &= ~ofp.OFPFW_IN_PORT
341 self.assertTrue(match is not None,
342 "Could not generate flow match from pkt")
343
344 # Get queue stats from switch
345
346 request = message.queue_stats_request()
347 request.port_no = ofp.OFPP_CONTROLLER
348 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700349 (queue_stats, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700350 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
351
352 act = action.action_enqueue()
353
354 for idx in range(len(of_ports)):
355 ingress_port = of_ports[idx]
356 egress_port = ofp.OFPP_CONTROLLER
357
358 pa_logger.info("Ingress port " + str(ingress_port)
359 + ", controller port queues "
360 + str(self.portQueuesGet(queue_stats, egress_port)))
361
362 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
363 pa_logger.info("Ingress " + str(ingress_port)
364 + " to egress " + str(egress_port)
365 + " queue " + str(egress_queue_id)
366 )
367
368 rv = delete_all_flows(self.controller, pa_logger)
369 self.assertEqual(rv, 0, "Failed to delete all flows")
370
371 match.in_port = ingress_port
372
373 request = message.flow_mod()
374 request.match = match
375
376 request.buffer_id = 0xffffffff
377 act.port = egress_port
378 act.queue_id = egress_queue_id
379 self.assertTrue(request.actions.add(act), "Could not add action")
380
381 pa_logger.info("Inserting flow")
382 rv = self.controller.message_send(request)
383 self.assertTrue(rv != -1, "Error installing flow mod")
384 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
385
386 # Get current stats for selected egress queue
387
388 request = message.queue_stats_request()
389 request.port_no = egress_port
390 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700391 (qs_before, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700392 self.assertNotEqual(qs_before, None, "Queue stats request failed")
393
394 pa_logger.info("Sending packet to dp port " +
395 str(ingress_port))
396 self.dataplane.send(ingress_port, str(pkt))
397
398 exp_pkt_arg = None
399 exp_port = None
400
401 while True:
402 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN, 2)
403 if not response: # Timeout
404 break
405 if dataplane.match_exp_pkt(pkt, response.data): # Got match
406 break
407 if not basic_config["relax"]: # Only one attempt to match
408 break
409 count += 1
410 if count > 10: # Too many tries
411 break
412
413 self.assertTrue(response is not None,
414 'Packet in message not received by controller')
415 if not dataplane.match_exp_pkt(pkt, response.data):
416 basic_logger.debug("Sent %s" % format_packet(pkt))
417 basic_logger.debug("Resp %s" % format_packet(response.data))
418 self.assertTrue(False,
419 'Response packet does not match send packet' +
420 ' for controller port')
421
422 # FIXME: instead of sleeping, keep requesting queue stats until
423 # the expected queue counter increases or some large timeout is
424 # reached
425 time.sleep(2)
426
427 # Get current stats for selected egress queue again
428
429 request = message.queue_stats_request()
430 request.port_no = egress_port
431 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700432 (qs_after, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700433 self.assertNotEqual(qs_after, None, "Queue stats request failed")
434
435 # Make sure that tx packet counter for selected egress queue was
436 # incremented
437
438 self.assertEqual(qs_after.stats[0].tx_packets, \
439 qs_before.stats[0].tx_packets + 1, \
440 "Verification of egress queue tx packet count failed"
441 )
442
Howard Pershf97840f2012-04-10 16:30:42 -0700443
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700444class DirectPacketICMP(DirectPacket):
445 """
446 Send ICMP packet to single egress port
447
448 Generate a ICMP packet
449 Generate and install a matching flow
450 Add action to direct the packet to an egress port
451 Send the packet to ingress dataplane port
452 Verify the packet is received at the egress port only
453 Difference from DirectPacket test is that sent packet is ICMP
454 """
455 def runTest(self):
456 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700457
458class DirectTwoPorts(basic.SimpleDataPlane):
459 """
460 Send packet to two egress ports
461
462 Generate a packet
463 Generate and install a matching flow
464 Add action to direct the packet to two egress ports
465 Send the packet to ingress dataplane port
466 Verify the packet is received at the two egress ports
467 """
468 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700469 of_ports = pa_port_map.keys()
470 of_ports.sort()
471 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
472
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700473 pkt = simple_tcp_packet()
474 match = parse.packet_to_flow_match(pkt)
475 match.wildcards &= ~ofp.OFPFW_IN_PORT
476 self.assertTrue(match is not None,
477 "Could not generate flow match from pkt")
478 act = action.action_output()
479
480 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700481 rv = delete_all_flows(self.controller, pa_logger)
482 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700483
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700484 ingress_port = of_ports[idx]
485 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
486 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
487 pa_logger.info("Ingress " + str(ingress_port) +
488 " to egress " + str(egress_port1) + " and " +
489 str(egress_port2))
490
491 match.in_port = ingress_port
492
493 request = message.flow_mod()
494 request.match = match
495 request.buffer_id = 0xffffffff
496 act.port = egress_port1
497 self.assertTrue(request.actions.add(act), "Could not add action1")
498 act.port = egress_port2
499 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700500 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700501
502 pa_logger.info("Inserting flow")
503 rv = self.controller.message_send(request)
504 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700505 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700506
507 pa_logger.info("Sending packet to dp port " +
508 str(ingress_port))
509 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700510 yes_ports = set([egress_port1, egress_port2])
511 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700512
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700513 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700514 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700515
516class DirectMCNonIngress(basic.SimpleDataPlane):
517 """
518 Multicast to all non-ingress ports
519
520 Generate a packet
521 Generate and install a matching flow
522 Add action to direct the packet to all non-ingress ports
523 Send the packet to ingress dataplane port
524 Verify the packet is received at all non-ingress ports
525
526 Does not use the flood action
527 """
528 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700529 of_ports = pa_port_map.keys()
530 of_ports.sort()
531 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
532
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700533 pkt = simple_tcp_packet()
534 match = parse.packet_to_flow_match(pkt)
535 match.wildcards &= ~ofp.OFPFW_IN_PORT
536 self.assertTrue(match is not None,
537 "Could not generate flow match from pkt")
538 act = action.action_output()
539
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700540 for ingress_port in of_ports:
541 rv = delete_all_flows(self.controller, pa_logger)
542 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700543
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700544 pa_logger.info("Ingress " + str(ingress_port) +
545 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700546 match.in_port = ingress_port
547
548 request = message.flow_mod()
549 request.match = match
550 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700551 for egress_port in of_ports:
552 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700553 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700554 act.port = egress_port
555 self.assertTrue(request.actions.add(act),
556 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700557 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700558
559 pa_logger.info("Inserting flow")
560 rv = self.controller.message_send(request)
561 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700562 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700563
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700564 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700565 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700566 yes_ports = set(of_ports).difference([ingress_port])
567 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700568 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700569
Dan Talayco32fa6542010-05-11 15:54:08 -0700570
571class DirectMC(basic.SimpleDataPlane):
572 """
573 Multicast to all ports including ingress
574
575 Generate a packet
576 Generate and install a matching flow
577 Add action to direct the packet to all non-ingress ports
578 Send the packet to ingress dataplane port
579 Verify the packet is received at all ports
580
581 Does not use the flood action
582 """
583 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700584 of_ports = pa_port_map.keys()
585 of_ports.sort()
586 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
587
Dan Talayco32fa6542010-05-11 15:54:08 -0700588 pkt = simple_tcp_packet()
589 match = parse.packet_to_flow_match(pkt)
590 match.wildcards &= ~ofp.OFPFW_IN_PORT
591 self.assertTrue(match is not None,
592 "Could not generate flow match from pkt")
593 act = action.action_output()
594
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700595 for ingress_port in of_ports:
596 rv = delete_all_flows(self.controller, pa_logger)
597 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700598
Dan Talayco32fa6542010-05-11 15:54:08 -0700599 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700600 match.in_port = ingress_port
601
602 request = message.flow_mod()
603 request.match = match
604 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700605 for egress_port in of_ports:
606 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700607 act.port = ofp.OFPP_IN_PORT
608 else:
609 act.port = egress_port
610 self.assertTrue(request.actions.add(act),
611 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700612 # pa_logger.info(request.show())
613
614 pa_logger.info("Inserting flow")
615 rv = self.controller.message_send(request)
616 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700617 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2e77a842010-05-12 15:39:46 -0700618
619 pa_logger.info("Sending packet to dp port " + str(ingress_port))
620 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700621 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700622 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700623
624class Flood(basic.SimpleDataPlane):
625 """
626 Flood to all ports except ingress
627
628 Generate a packet
629 Generate and install a matching flow
630 Add action to flood the packet
631 Send the packet to ingress dataplane port
632 Verify the packet is received at all other ports
633 """
634 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700635 of_ports = pa_port_map.keys()
636 of_ports.sort()
637 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
638
639 pkt = simple_tcp_packet()
640 match = parse.packet_to_flow_match(pkt)
641 match.wildcards &= ~ofp.OFPFW_IN_PORT
642 self.assertTrue(match is not None,
643 "Could not generate flow match from pkt")
644 act = action.action_output()
645
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700646 for ingress_port in of_ports:
647 rv = delete_all_flows(self.controller, pa_logger)
648 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700649
Dan Talayco2e77a842010-05-12 15:39:46 -0700650 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700651 match.in_port = ingress_port
652
653 request = message.flow_mod()
654 request.match = match
655 request.buffer_id = 0xffffffff
656 act.port = ofp.OFPP_FLOOD
657 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700658 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700659 pa_logger.info(request.show())
660
661 pa_logger.info("Inserting flow")
662 rv = self.controller.message_send(request)
663 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700664 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco32fa6542010-05-11 15:54:08 -0700665
666 pa_logger.info("Sending packet to dp port " + str(ingress_port))
667 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700668 yes_ports = set(of_ports).difference([ingress_port])
669 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700670 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700671
Dan Talayco3be5b062010-05-12 15:46:21 -0700672class FloodPlusIngress(basic.SimpleDataPlane):
673 """
674 Flood to all ports plus send to ingress port
675
676 Generate a packet
677 Generate and install a matching flow
678 Add action to flood the packet
679 Add action to send to ingress port
680 Send the packet to ingress dataplane port
681 Verify the packet is received at all other ports
682 """
683 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700684 of_ports = pa_port_map.keys()
685 of_ports.sort()
686 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
687
688 pkt = simple_tcp_packet()
689 match = parse.packet_to_flow_match(pkt)
690 match.wildcards &= ~ofp.OFPFW_IN_PORT
691 self.assertTrue(match is not None,
692 "Could not generate flow match from pkt")
693 act = action.action_output()
694
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700695 for ingress_port in of_ports:
696 rv = delete_all_flows(self.controller, pa_logger)
697 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700698
Dan Talayco3be5b062010-05-12 15:46:21 -0700699 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700700 match.in_port = ingress_port
701
702 request = message.flow_mod()
703 request.match = match
704 request.buffer_id = 0xffffffff
705 act.port = ofp.OFPP_FLOOD
706 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700707 "Could not add flood port action")
708 act.port = ofp.OFPP_IN_PORT
709 self.assertTrue(request.actions.add(act),
710 "Could not add ingress port for output")
711 pa_logger.info(request.show())
712
713 pa_logger.info("Inserting flow")
714 rv = self.controller.message_send(request)
715 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700716 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700717
718 pa_logger.info("Sending packet to dp port " + str(ingress_port))
719 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700720 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700721 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700722
723class All(basic.SimpleDataPlane):
724 """
725 Send to OFPP_ALL port
726
727 Generate a packet
728 Generate and install a matching flow
729 Add action to forward to OFPP_ALL
730 Send the packet to ingress dataplane port
731 Verify the packet is received at all other ports
732 """
733 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700734 of_ports = pa_port_map.keys()
735 of_ports.sort()
736 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
737
738 pkt = simple_tcp_packet()
739 match = parse.packet_to_flow_match(pkt)
740 match.wildcards &= ~ofp.OFPFW_IN_PORT
741 self.assertTrue(match is not None,
742 "Could not generate flow match from pkt")
743 act = action.action_output()
744
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700745 for ingress_port in of_ports:
746 rv = delete_all_flows(self.controller, pa_logger)
747 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700748
Dan Talayco4aa13122010-05-12 15:54:44 -0700749 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700750 match.in_port = ingress_port
751
752 request = message.flow_mod()
753 request.match = match
754 request.buffer_id = 0xffffffff
755 act.port = ofp.OFPP_ALL
756 self.assertTrue(request.actions.add(act),
757 "Could not add ALL port action")
758 pa_logger.info(request.show())
759
760 pa_logger.info("Inserting flow")
761 rv = self.controller.message_send(request)
762 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700763 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700764
765 pa_logger.info("Sending packet to dp port " + str(ingress_port))
766 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700767 yes_ports = set(of_ports).difference([ingress_port])
768 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700769 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700770
771class AllPlusIngress(basic.SimpleDataPlane):
772 """
773 Send to OFPP_ALL port and ingress port
774
775 Generate a packet
776 Generate and install a matching flow
777 Add action to forward to OFPP_ALL
778 Add action to forward to ingress port
779 Send the packet to ingress dataplane port
780 Verify the packet is received at all other ports
781 """
782 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700783 of_ports = pa_port_map.keys()
784 of_ports.sort()
785 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
786
787 pkt = simple_tcp_packet()
788 match = parse.packet_to_flow_match(pkt)
789 match.wildcards &= ~ofp.OFPFW_IN_PORT
790 self.assertTrue(match is not None,
791 "Could not generate flow match from pkt")
792 act = action.action_output()
793
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700794 for ingress_port in of_ports:
795 rv = delete_all_flows(self.controller, pa_logger)
796 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700797
Dan Talayco4aa13122010-05-12 15:54:44 -0700798 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700799 match.in_port = ingress_port
800
801 request = message.flow_mod()
802 request.match = match
803 request.buffer_id = 0xffffffff
804 act.port = ofp.OFPP_ALL
805 self.assertTrue(request.actions.add(act),
806 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700807 act.port = ofp.OFPP_IN_PORT
808 self.assertTrue(request.actions.add(act),
809 "Could not add ingress port for output")
810 pa_logger.info(request.show())
811
812 pa_logger.info("Inserting flow")
813 rv = self.controller.message_send(request)
814 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700815 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco3be5b062010-05-12 15:46:21 -0700816
817 pa_logger.info("Sending packet to dp port " + str(ingress_port))
818 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700819 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700820 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700821
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700822class FloodMinusPort(basic.SimpleDataPlane):
823 """
824 Config port with No_Flood and test Flood action
825
826 Generate a packet
827 Generate a matching flow
828 Add action to forward to OFPP_ALL
829 Set port to no-flood
830 Send the packet to ingress dataplane port
831 Verify the packet is received at all other ports except
832 the ingress port and the no_flood port
833 """
834 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700835 of_ports = pa_port_map.keys()
836 of_ports.sort()
837 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
838
839 pkt = simple_tcp_packet()
840 match = parse.packet_to_flow_match(pkt)
841 match.wildcards &= ~ofp.OFPFW_IN_PORT
842 self.assertTrue(match is not None,
843 "Could not generate flow match from pkt")
844 act = action.action_output()
845
846 for idx in range(len(of_ports)):
847 rv = delete_all_flows(self.controller, pa_logger)
848 self.assertEqual(rv, 0, "Failed to delete all flows")
849
850 ingress_port = of_ports[idx]
851 no_flood_idx = (idx + 1) % len(of_ports)
852 no_flood_port = of_ports[no_flood_idx]
853 rv = port_config_set(self.controller, no_flood_port,
854 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
855 pa_logger)
856 self.assertEqual(rv, 0, "Failed to set port config")
857
858 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_FLOOD
864 self.assertTrue(request.actions.add(act),
865 "Could not add flood port action")
866 pa_logger.info(request.show())
867
868 pa_logger.info("Inserting flow")
869 rv = self.controller.message_send(request)
870 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700871 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700872
873 pa_logger.info("Sending packet to dp port " + str(ingress_port))
874 pa_logger.info("No flood port is " + str(no_flood_port))
875 self.dataplane.send(ingress_port, str(pkt))
876 no_ports = set([ingress_port, no_flood_port])
877 yes_ports = set(of_ports).difference(no_ports)
878 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700879 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700880
881 # Turn no flood off again
882 rv = port_config_set(self.controller, no_flood_port,
883 0, ofp.OFPPC_NO_FLOOD, pa_logger)
884 self.assertEqual(rv, 0, "Failed to reset port config")
885
886 #@todo Should check no other packets received
887
Dan Talayco21381562010-07-17 00:34:47 -0700888
889
Dan Talayco551befa2010-07-15 17:05:32 -0700890################################################################
891
892class BaseMatchCase(basic.SimpleDataPlane):
893 def setUp(self):
894 basic.SimpleDataPlane.setUp(self)
895 self.logger = pa_logger
896 def runTest(self):
897 self.logger.info("BaseMatchCase")
898
899class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700900 """
Dan Talayco551befa2010-07-15 17:05:32 -0700901 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700902
903 Generate a packet
904 Generate and install a matching flow without wildcard mask
905 Add action to forward to a port
906 Send the packet to the port
907 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700908 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700909
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700910 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700911 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700912
Dan Talayco551befa2010-07-15 17:05:32 -0700913class ExactMatchTagged(BaseMatchCase):
914 """
915 Exact match for all port pairs with tagged pkts
916 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700917
Dan Talayco551befa2010-07-15 17:05:32 -0700918 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700919 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700920 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700921
Dan Talayco551befa2010-07-15 17:05:32 -0700922class ExactMatchTaggedMany(BaseMatchCase):
923 """
924 ExactMatchTagged with many VLANS
925 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700926
Dan Talayco551befa2010-07-15 17:05:32 -0700927 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700928 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700929 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
930 for vid in range(100,4000,389):
931 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
932 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700933
Dan Talayco551befa2010-07-15 17:05:32 -0700934# Don't run by default
935test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700936
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700937
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700938class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700939 """
940 SingleWildcardMatchPriority
941 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700942
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700943 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700944 self.pkt = simple_tcp_packet()
945 self.flowMsgs = {}
946
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700947 def _ClearTable(self):
948 rc = delete_all_flows(self.controller, self.logger)
949 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700950 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700951
952 def runTest(self):
953
954 self._Init()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700955 of_ports = pa_port_map.keys()
956 of_ports.sort()
957
958 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700959 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700960
961 # Run several combinations, each at lower priority settings.
962 # At the end of each call to runPrioFlows(), the table should
963 # be empty. If its not, we'll catch it as the priorities decreases
964 portA = of_ports[0]
965 portB = of_ports[1]
966 portC = of_ports[2]
967
968 # TODO -- these priority numbers should be validated somehow?
969 self.runPrioFlows(portA, portB, portC, 1000, 999)
970 self.runPrioFlows(portB, portC, portA, 998, 997)
971 self.runPrioFlows(portC, portA, portB, 996, 995)
972 self.runPrioFlows(portA, portC, portB, 994, 993)
973
974
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700975
976 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
977 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700978
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700979 if clearTable:
980 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700981
982 # Sanity check flow at lower priority from pA to pB
983 self.logger.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
984 % (portA, portB, portC, prioHigher, prioLower))
985
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700986 self.installFlow(prioHigher, portA, portC)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700987 self.installFlow(prioLower, portA, portB)
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700988
989 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700990 self.verifyFlow(portA, portB)
991 self.removeFlow(prioLower)
992 # Sanity check flow at lower priority from pA to pC
993 self.installFlow(prioLower, portA, portC)
994 self.verifyFlow(portA, portC)
995 self.removeFlow(prioLower)
996
997 # Install and verify pA->pB @ prioLower
998 self.installFlow(prioLower, portA, portB)
999 self.verifyFlow(portA, portB)
1000
1001 # Install and verify pA->pC @ prioHigher, should override pA->pB
1002 self.installFlow(prioHigher, portA, portC)
1003 self.verifyFlow(portA, portC)
1004 # remove pA->pC
1005 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001006 # Old flow pA -> pB @ prioLower should still be active
1007 self.verifyFlow(portA, portB)
1008 self.removeFlow(prioLower)
1009
1010 # Table should be empty at this point, leave it alone as
1011 # an assumption for future test runs
1012
1013
1014
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001015 def installFlow(self, prio, inp, egp,
1016 wildcards=ofp.OFPFW_DL_SRC):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001017 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001018 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001019 egr_ports=egp)
1020 request.priority = prio
Ken Chiang38d7a152012-05-24 15:33:50 -07001021 self.logger.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001022 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001023 self.flowMsgs[prio] = request
1024
1025 def removeFlow(self, prio):
1026 if self.flowMsgs.has_key(prio):
1027 msg = self.flowMsgs[prio]
1028 msg.command = ofp.OFPFC_DELETE_STRICT
1029 # This *must* be set for DELETE
1030 msg.out_port = ofp.OFPP_NONE
Ken Chiang38d7a152012-05-24 15:33:50 -07001031 self.logger.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001032 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001033 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001034 else:
1035 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001036
1037
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001038 def verifyFlow(self, inp, egp, pkt=None):
1039 if pkt == None:
1040 pkt = self.pkt
1041
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001042 self.logger.info("Pkt match test: " + str(inp) +
1043 " to " + str(egp))
1044 self.logger.debug("Send packet: " + str(inp) + " to "
1045 + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001046 self.dataplane.send(inp, str(pkt))
1047 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001048
1049
1050
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001051class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1052
1053 def runTest(self):
1054
1055 self._Init()
1056
1057 of_ports = pa_port_map.keys()
1058 of_ports.sort()
1059
1060 # Install an entry from 0 -> 1 @ prio 1000
1061 self._ClearTable()
1062 self.installFlow(1000, of_ports[0], of_ports[1])
1063 self.verifyFlow(of_ports[0], of_ports[1])
1064 self.installFlow(1000, of_ports[1], of_ports[0])
1065 self.verifyFlow(of_ports[1], of_ports[0])
1066 self.installFlow(1001, of_ports[0], of_ports[1])
1067 self.verifyFlow(of_ports[0], of_ports[1])
1068 self.installFlow(1001, of_ports[1], of_ports[0])
1069 self.verifyFlow(of_ports[1], of_ports[0])
1070 self.removeFlow(1001)
1071 self.verifyFlow(of_ports[0], of_ports[1])
1072 self.removeFlow(1000)
1073
1074
1075
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001076class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001077 """
1078 1. Add wildcard flow, verify packet received.
1079 2. Add exact match flow with higher priority, verify packet received
1080 on port specified by this flow.
1081 3. Add wildcard flow with even higher priority, verify packet received
1082 on port specified by this flow.
1083 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001084
1085 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001086
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001087 self._Init()
1088
1089 of_ports = pa_port_map.keys()
1090 of_ports.sort()
1091
1092 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001093
1094 # Install a flow with wildcards
1095 self.installFlow(999, of_ports[0], of_ports[1],
1096 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001097 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001098 # Install a flow with no wildcards for our packet
1099 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001100 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001101 # Install a flow with wildcards for our packet with higher
1102 # priority
1103 self.installFlow(1001, of_ports[0], of_ports[3])
1104 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001105
1106
Ken Chiang3978f242012-06-13 14:14:09 -07001107class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001108 """
1109 1. Add exact match flow, verify packet received.
1110 2. Add wildcard flow with higher priority, verify packet received on port
1111 specified by this flow.
1112 3. Add exact match flow with even higher priority, verify packet received
1113 on port specified by this flow.
1114 4. Delete lowest priority flow, verify packet received on port specified
1115 by highest priority flow.
1116 5. Delete highest priority flow, verify packet received on port specified
1117 by remaining flow.
1118 """
1119
1120 def runTest(self):
1121
1122 self._Init()
1123
1124 of_ports = pa_port_map.keys()
1125 of_ports.sort()
1126
1127 self._ClearTable()
1128
1129 # Install an exact match flow
1130 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1131 self.verifyFlow(of_ports[0], of_ports[1])
1132 # Install a flow with wildcards of higher priority
1133 self.installFlow(1250, of_ports[0], of_ports[2],
1134 wildcards=ofp.OFPFW_DL_DST)
1135 self.verifyFlow(of_ports[0], of_ports[2])
1136 # Install an exact match flow with even higher priority
1137 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1138 self.verifyFlow(of_ports[0], of_ports[3])
1139 # Delete lowest priority flow
1140 self.removeFlow(250)
1141 self.verifyFlow(of_ports[0], of_ports[3])
1142 # Delete highest priority flow
1143 self.removeFlow(2001)
1144 self.verifyFlow(of_ports[0], of_ports[2])
1145
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001146
Dan Talayco551befa2010-07-15 17:05:32 -07001147class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001148 """
1149 Exercise wildcard matching for all ports
1150
1151 Generate a packet
1152 Generate and install a matching flow with wildcard mask
1153 Add action to forward to a port
1154 Send the packet to the port
1155 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001156 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001157 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001158 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001159 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001160 for wc in WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001161 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001162 # Set nonzero VLAN id to avoid sending priority-tagged packet
1163 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001164 else:
1165 dl_vlan = -1
1166 flow_match_test(self, pa_port_map, wildcards=wc,
1167 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001168
Dan Talayco551befa2010-07-15 17:05:32 -07001169class SingleWildcardMatchTagged(BaseMatchCase):
1170 """
1171 SingleWildcardMatch with tagged packets
1172 """
1173 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001174 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001175 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001176 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001177 max_test=10)
1178
1179class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001180 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001181 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001182
1183 Generate a packet
1184 Generate and install a matching flow with wildcard all except one filed
1185 Add action to forward to a port
1186 Send the packet to the port
1187 Verify the packet is received at all other ports (one port at a time)
1188 Verify flow_expiration message is correct when command option is set
1189 """
1190 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -07001191 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001192 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -07001193 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001194 # Set nonzero VLAN id to avoid sending priority-tagged packet
1195 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001196 else:
1197 dl_vlan = -1
1198 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1199 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001200
Dan Talayco551befa2010-07-15 17:05:32 -07001201class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1202 """
1203 Match one field with tagged packets
1204 """
1205 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001206 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001207 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -07001208 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
1209 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001210
1211class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001212 """
1213 Create Wildcard-all flow and exercise for all ports
1214
1215 Generate a packet
1216 Generate and install a matching flow with wildcard-all
1217 Add action to forward to a port
1218 Send the packet to the port
1219 Verify the packet is received at all other ports (one port at a time)
1220 Verify flow_expiration message is correct when command option is set
1221 """
1222 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -07001223 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001224
Dan Talayco551befa2010-07-15 17:05:32 -07001225class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001226 """
Dan Talayco551befa2010-07-15 17:05:32 -07001227 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001228 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001229 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001230 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -07001231 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
1232 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001233
Dan Talaycoba3745c2010-07-21 21:51:08 -07001234
Dan Talayco551befa2010-07-15 17:05:32 -07001235class AddVLANTag(BaseMatchCase):
1236 """
1237 Add a VLAN tag to an untagged packet
1238 """
1239 def runTest(self):
1240 new_vid = 2
1241 sup_acts = supported_actions_get(self)
1242 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001243 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001244 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001245
Dan Talayco551befa2010-07-15 17:05:32 -07001246 len = 100
1247 len_w_vid = 104
1248 pkt = simple_tcp_packet(pktlen=len)
1249 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1250 dl_vlan=new_vid)
1251 vid_act = action.action_set_vlan_vid()
1252 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001253
Dan Talayco551befa2010-07-15 17:05:32 -07001254 flow_match_test(self, pa_port_map, pkt=pkt,
1255 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001256
Dan Talayco551befa2010-07-15 17:05:32 -07001257class PacketOnly(basic.DataPlaneOnly):
1258 """
1259 Just send a packet thru the switch
1260 """
1261 def runTest(self):
1262 pkt = simple_tcp_packet()
1263 of_ports = pa_port_map.keys()
1264 of_ports.sort()
1265 ing_port = of_ports[0]
1266 pa_logger.info("Sending packet to " + str(ing_port))
1267 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1268 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001269
Dan Talayco551befa2010-07-15 17:05:32 -07001270class PacketOnlyTagged(basic.DataPlaneOnly):
1271 """
1272 Just send a packet thru the switch
1273 """
1274 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001275 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001276 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
1277 of_ports = pa_port_map.keys()
1278 of_ports.sort()
1279 ing_port = of_ports[0]
1280 pa_logger.info("Sending packet to " + str(ing_port))
1281 pa_logger.debug("Data: " + str(pkt).encode('hex'))
1282 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001283
Dan Talayco551befa2010-07-15 17:05:32 -07001284test_prio["PacketOnly"] = -1
1285test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001286
Dan Talayco551befa2010-07-15 17:05:32 -07001287class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001288 """
1289 Modify the VLAN ID in the VLAN tag of a tagged packet
1290 """
Dan Talayco551befa2010-07-15 17:05:32 -07001291 def runTest(self):
1292 old_vid = 2
1293 new_vid = 3
1294 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001295 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001296 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001297 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001298
Dan Talayco551befa2010-07-15 17:05:32 -07001299 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1300 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1301 vid_act = action.action_set_vlan_vid()
1302 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001303
Dan Talayco551befa2010-07-15 17:05:32 -07001304 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1305 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001306
Ken Chiange9a211d2012-04-20 14:52:11 -07001307class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1308 """
1309 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1310 The same flow should match on both untagged and tagged packets.
1311 """
1312 def runTest(self):
1313 old_vid = 2
1314 new_vid = 3
1315 sup_acts = supported_actions_get(self)
1316 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1317 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1318 return
1319
1320 of_ports = pa_port_map.keys()
1321 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1322 ing_port = of_ports[0]
1323 egr_ports = of_ports[1]
1324
1325 rv = delete_all_flows(self.controller, pa_logger)
1326 self.assertEqual(rv, 0, "Failed to delete all flows")
1327
1328 len_untagged = 100
1329 len_w_vid = 104
1330 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1331 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1332 dl_vlan_enable=True, dl_vlan=old_vid)
1333 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1334 dl_vlan=new_vid)
1335 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP
1336 vid_act = action.action_set_vlan_vid()
1337 vid_act.vlan_vid = new_vid
1338 request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
1339 wildcards=wildcards, egr_ports=egr_ports,
1340 action_list=[vid_act])
1341 flow_msg_install(self, request)
1342
1343 pa_logger.debug("Send untagged packet: " + str(ing_port) + " to " +
1344 str(egr_ports))
1345 self.dataplane.send(ing_port, str(untagged_pkt))
1346 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1347
1348 pa_logger.debug("Send tagged packet: " + str(ing_port) + " to " +
1349 str(egr_ports))
1350 self.dataplane.send(ing_port, str(tagged_pkt))
1351 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1352
Howard Pershc1199d52012-04-11 14:21:32 -07001353class ModifyVlanPcp(BaseMatchCase):
1354 """
1355 Modify the priority field of the VLAN tag of a tagged packet
1356 """
1357 def runTest(self):
1358 vid = 123
1359 old_vlan_pcp = 2
1360 new_vlan_pcp = 3
1361 sup_acts = supported_actions_get(self)
Ed Swierk8c3af7f2012-04-24 14:19:17 -07001362 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_PCP):
1363 skip_message_emit(self, "Modify VLAN priority test")
Howard Pershc1199d52012-04-11 14:21:32 -07001364 return
1365
1366 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=old_vlan_pcp)
1367 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=new_vlan_pcp)
1368 vid_act = action.action_set_vlan_pcp()
1369 vid_act.vlan_pcp = new_vlan_pcp
1370
1371 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1372 action_list=[vid_act])
1373
Dan Talayco551befa2010-07-15 17:05:32 -07001374class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001375 """
1376 Strip the VLAN tag from a tagged packet
1377 """
Dan Talayco551befa2010-07-15 17:05:32 -07001378 def runTest(self):
1379 old_vid = 2
1380 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -07001381 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001382 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001383 return
Dan Talaycof36f1082010-07-13 13:57:17 -07001384
Dan Talayco551befa2010-07-15 17:05:32 -07001385 len_w_vid = 104
1386 len = 100
1387 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1388 dl_vlan=old_vid)
1389 exp_pkt = simple_tcp_packet(pktlen=len)
1390 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001391
Dan Talayco551befa2010-07-15 17:05:32 -07001392 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1393 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001394
Ken Chiange9a211d2012-04-20 14:52:11 -07001395class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
1396 """
1397 Strip the VLAN tag from a tagged packet.
1398 Differs from StripVLANTag in that VID and PCP are both wildcarded.
1399 """
1400 def runTest(self):
1401 old_vid = 2
1402 sup_acts = supported_actions_get(self)
1403 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
1404 skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
1405 return
1406
1407 len_w_vid = 104
1408 len_untagged = 100
1409 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1410 dl_vlan=old_vid)
1411 exp_pkt = simple_tcp_packet(pktlen=len_untagged)
1412 vid_act = action.action_strip_vlan()
1413
1414 flow_match_test(self, pa_port_map,
1415 wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP,
1416 pkt=pkt, exp_pkt=exp_pkt,
1417 action_list=[vid_act])
1418
Dan Talayco4b2bee62010-07-20 14:10:05 -07001419def init_pkt_args():
1420 """
1421 Pass back a dictionary with default packet arguments
1422 """
1423 args = {}
1424 args["dl_src"] = '00:23:45:67:89:AB'
1425
1426 dl_vlan_enable=False
1427 dl_vlan=-1
1428 if pa_config["test-params"]["vid"]:
1429 dl_vlan_enable=True
1430 dl_vlan = pa_config["test-params"]["vid"]
1431
1432# Unpack operator is ** on a dictionary
1433
1434 return args
1435
Dan Talayco551befa2010-07-15 17:05:32 -07001436class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001437 """
1438 Modify the source MAC address (TP1)
1439 """
Dan Talayco551befa2010-07-15 17:05:32 -07001440 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001441 sup_acts = supported_actions_get(self)
1442 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001443 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001444 return
1445
1446 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1447 check_test_params=True)
1448 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1449 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001450
Dan Talayco551befa2010-07-15 17:05:32 -07001451class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001452 """
1453 Modify the dest MAC address (TP1)
1454 """
Dan Talayco551befa2010-07-15 17:05:32 -07001455 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001456 sup_acts = supported_actions_get(self)
1457 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001458 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001459 return
1460
1461 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1462 check_test_params=True)
1463 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1464 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001465
Dan Talayco551befa2010-07-15 17:05:32 -07001466class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001467 """
1468 Modify the source IP address of an IP packet (TP1)
1469 """
Dan Talayco551befa2010-07-15 17:05:32 -07001470 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001471 sup_acts = supported_actions_get(self)
1472 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001473 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001474 return
1475
1476 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1477 check_test_params=True)
1478 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1479 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001480
Dan Talayco551befa2010-07-15 17:05:32 -07001481class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001482 """
1483 Modify the dest IP address of an IP packet (TP1)
1484 """
Dan Talayco551befa2010-07-15 17:05:32 -07001485 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001486 sup_acts = supported_actions_get(self)
1487 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001488 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001489 return
1490
1491 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1492 check_test_params=True)
1493 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1494 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001495
1496class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001497 """
1498 Modify the source TCP port of a TCP packet (TP1)
1499 """
Dan Talayco551befa2010-07-15 17:05:32 -07001500 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001501 sup_acts = supported_actions_get(self)
1502 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001503 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001504 return
1505
1506 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1507 check_test_params=True)
1508 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1509 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001510
1511class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001512 """
1513 Modify the dest TCP port of a TCP packet (TP1)
1514 """
Dan Talayco551befa2010-07-15 17:05:32 -07001515 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001516 sup_acts = supported_actions_get(self)
1517 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001518 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001519 return
1520
1521 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1522 check_test_params=True)
1523 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1524 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001525
1526class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001527 """
1528 Modify the IP type of service of an IP packet (TP1)
1529 """
Dan Talayco551befa2010-07-15 17:05:32 -07001530 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001531 sup_acts = supported_actions_get(self)
1532 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001533 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001534 return
Dan Talayco551befa2010-07-15 17:05:32 -07001535
Dan Talayco4b2bee62010-07-20 14:10:05 -07001536 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1537 check_test_params=True)
1538 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001539 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001540
Dan Talaycof6e76c02012-03-23 10:56:12 -07001541class ModifyL2DstMC(BaseMatchCase):
1542 """
1543 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001544 """
1545 def runTest(self):
1546 sup_acts = supported_actions_get(self)
1547 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001548 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001549 return
1550
Dan Talaycof6e76c02012-03-23 10:56:12 -07001551 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1552 check_test_params=True)
1553 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001554 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001555
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001556class ModifyL2DstIngress(BaseMatchCase):
1557 """
1558 Modify the L2 dest and send to the ingress port
1559 """
1560 def runTest(self):
1561 sup_acts = supported_actions_get(self)
1562 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001563 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001564 return
1565
1566 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1567 check_test_params=True)
1568 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1569 action_list=acts, max_test=2, egr_count=0,
1570 ing_port=True)
1571
Dan Talaycod8ae7582012-03-23 12:24:56 -07001572class ModifyL2DstIngressMC(BaseMatchCase):
1573 """
1574 Modify the L2 dest and send to the ingress port
1575 """
1576 def runTest(self):
1577 sup_acts = supported_actions_get(self)
1578 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1579 skip_message_emit(self, "ModifyL2dstMC test")
1580 return
1581
1582 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
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, egr_count=-1,
1586 ing_port=True)
1587
Dan Talaycof6e76c02012-03-23 10:56:12 -07001588class ModifyL2SrcMC(BaseMatchCase):
1589 """
1590 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001591 """
1592 def runTest(self):
1593 sup_acts = supported_actions_get(self)
1594 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001595 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001596 return
1597
Dan Talaycof6e76c02012-03-23 10:56:12 -07001598 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1599 check_test_params=True)
1600 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001601 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001602
1603class ModifyL2SrcDstMC(BaseMatchCase):
1604 """
1605 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001606 """
1607 def runTest(self):
1608 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001609 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1610 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1611 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001612 return
1613
Dan Talaycof6e76c02012-03-23 10:56:12 -07001614 mod_fields = ['dl_dst', 'dl_src']
1615 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
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)
1619
1620class ModifyL2DstVIDMC(BaseMatchCase):
1621 """
1622 Modify the L2 dest and send to 2 ports
1623 """
1624 def runTest(self):
1625 sup_acts = supported_actions_get(self)
1626 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1627 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1628 skip_message_emit(self, "ModifyL2DstVIDMC test")
1629 return
1630
1631 mod_fields = ['dl_dst', 'dl_vlan']
1632 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1633 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1634 check_test_params=True)
1635 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1636 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001637
Dan Talaycofa6454f2012-04-05 10:04:13 -07001638class FlowToggle(BaseMatchCase):
1639 """
1640 Add flows to the table and modify them repeatedly
Dan Talaycof7c41312012-07-23 12:53:19 -07001641
1642 This is done by using only "add" flow messages. Since the check overlap
1643 flag is not set, the switch is supposed to modify the existing flow if
1644 the match already exists.
1645
1646 Would probably be better to exercise more of the flow modify commands
1647 (add, modify, delete +/- strict).
Dan Talaycofa6454f2012-04-05 10:04:13 -07001648 """
1649 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001650 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1651 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001652
1653 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1654 (flow_count, iter_count))
1655 acts = []
1656 acts.append(action.action_output())
1657 acts.append(action.action_output())
1658
1659 of_ports = pa_port_map.keys()
1660 if len(of_ports) < 3:
1661 self.assertTrue(False, "Too few ports for test")
1662
1663 for idx in range(2):
1664 acts[idx].port = of_ports[idx]
1665
1666 flows = []
1667 flows.append([])
1668 flows.append([])
1669
Dan Talayco50be7672012-04-05 11:38:08 -07001670 wildcards = ofp.OFPFW_DL_SRC | ofp.OFPFW_DL_DST
Dan Talaycofa6454f2012-04-05 10:04:13 -07001671 # Create up the flows in an array
1672 for toggle in range(2):
1673 for f_idx in range(flow_count):
1674 pkt = simple_tcp_packet(tcp_sport=f_idx)
1675 msg = message.flow_mod()
1676 match = parse.packet_to_flow_match(pkt)
Shudong Zhou031373c2012-07-19 17:37:42 -07001677 match.in_port = of_ports[2]
Dan Talayco50be7672012-04-05 11:38:08 -07001678 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001679 msg.match = match
1680 msg.buffer_id = 0xffffffff
Dan Talaycof7c41312012-07-23 12:53:19 -07001681 msg.command = ofp.OFPFC_ADD
Dan Talaycofa6454f2012-04-05 10:04:13 -07001682 msg.actions.add(acts[toggle])
1683 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001684
1685 # Show two sample flows
1686 pa_logger.debug(flows[0][0].show())
1687 pa_logger.debug(flows[1][0].show())
1688
Dan Talaycofa6454f2012-04-05 10:04:13 -07001689 # Install the first set of flows
1690 for f_idx in range(flow_count):
1691 rv = self.controller.message_send(flows[0][f_idx])
1692 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001693 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001694
1695 pa_logger.info("Installed %d flows" % flow_count)
1696
1697 # Repeatedly modify all the flows back and forth
1698 updates = 0
1699 # Report status about 5 times
1700 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001701 start = time.time()
1702 for iter_idx in range(iter_count):
1703 if not iter_idx % mod_val:
1704 pa_logger.info("Flow Toggle: iter %d of %d. " %
1705 (iter_idx, iter_count) +
1706 "%d updates in %d secs" %
1707 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001708 for toggle in range(2):
1709 t_idx = 1 - toggle
1710 for f_idx in range(flow_count):
1711 rv = self.controller.message_send(flows[t_idx][f_idx])
1712 updates += 1
1713 self.assertTrue(rv != -1, "Error modifying flow %d" %
1714 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001715 self.assertEqual(do_barrier(self.controller), 0,
1716 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001717
1718 end = time.time()
1719 divisor = end - start or (end - start + 1)
1720 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1721 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1722 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001723
1724
Dan Talayco8a64e332012-03-28 14:53:20 -07001725# You can pick and choose these by commenting tests in or out
1726iter_classes = [
1727 basic.PacketIn,
1728 basic.PacketOut,
1729 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001730 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001731 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001732 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001733 AllWildcardMatch,
1734 AllWildcardMatchTagged,
1735 SingleWildcardMatch,
1736 SingleWildcardMatchTagged,
1737 ExactMatch,
1738 ExactMatchTagged,
1739 SingleWildcardMatch,
1740 ModifyL2Src,
1741 ModifyL2Dst,
1742 ModifyL2SrcMC,
1743 ModifyL2DstMC,
1744 ModifyL2SrcDstMC
1745 ]
1746
1747class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001748 """
1749 Iterate over a bunch of test cases
1750
1751 The cases come from the list above
1752 """
1753
Dan Talayco8a64e332012-03-28 14:53:20 -07001754 def runTest(self):
1755 count = test_param_get(self.config, 'iter_count', default=10)
1756 tests_done = 0
1757 pa_logger.info("Running iteration test " + str(count) + " times")
1758 start = time.time()
1759 last = start
1760 for idx in range(count):
1761 pa_logger.info("Iteration " + str(idx + 1))
1762 for cls in iter_classes:
1763 test = cls()
1764 test.inheritSetup(self)
1765 test.runTest()
1766 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001767 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001768 if time.time() - last > 60:
1769 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001770 pa_logger.info(
1771 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1772 (idx, count, tests_done, last - start) +
1773 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001774 stats = all_stats_get(self)
1775 last = time.time()
1776 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1777 (tests_done, last - start))
1778 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1779 (stats["flows"], stats["packets"], stats["bytes"]))
1780 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1781 (stats["active"], stats["lookups"], stats["matched"]))
1782
1783# Don't run by default
1784test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001785
Dan Talayco4b2bee62010-07-20 14:10:05 -07001786#@todo Need to implement tagged versions of the above tests
1787#
1788#@todo Implement a test case that strips tag 2, adds tag 3
1789# and modifies tag 4 to tag 5. Then verify (in addition) that
1790# tag 6 does not get modified.
1791
1792class MixedVLAN(BaseMatchCase):
1793 """
1794 Test mixture of VLAN tag actions
1795
1796 Strip tag 2 on port 1, send to port 2
1797 Add tag 3 on port 1, send to port 2
1798 Modify tag 4 to 5 on port 1, send to port 2
1799 All other traffic from port 1, send to port 3
1800 All traffic from port 2 sent to port 4
1801 Use exact matches with different packets for all mods
1802 Verify the following: (port, vid)
1803 (port 1, vid 2) => VLAN tag stripped, out port 2
1804 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1805 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1806 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1807 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1808 (port 2, no tag) => untagged packet out port 4
1809 (port 2, vid 2-6) => unmodified packet out port 4
1810
1811 Variation: Might try sending VID 5 to port 3 and check.
1812 If only VID 5 distinguishes pkt, this will fail on some platforms
1813 """
1814
1815test_prio["MixedVLAN"] = -1
1816
Dan Talayco551befa2010-07-15 17:05:32 -07001817def supported_actions_get(parent, use_cache=True):
1818 """
1819 Get the bitmap of supported actions from the switch
1820 If use_cache is false, the cached value will be updated
1821 """
1822 global cached_supported_actions
1823 if cached_supported_actions is None or not use_cache:
1824 request = message.features_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -07001825 (reply, pkt) = parent.controller.transact(request)
Dan Talayco551befa2010-07-15 17:05:32 -07001826 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1827 cached_supported_actions = reply.actions
1828 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1829
1830 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001831
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001832if __name__ == "__main__":
1833 print "Please run through oft script: ./oft --test_spec=basic"