blob: a551d58234e44a2d896923ca2b5ff87455e23a51 [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
31
32from testutils import *
33
34#@var port_map Local copy of the configuration map from OF port
35# numbers to OS interfaces
36pa_port_map = None
37#@var pa_logger Local logger object
38pa_logger = None
39#@var pa_config Local copy of global configuration data
40pa_config = None
41
Dan Talayco551befa2010-07-15 17:05:32 -070042# For test priority
43#@var test_prio Set test priority for local tests
44test_prio = {}
45
46WILDCARD_VALUES = [ofp.OFPFW_IN_PORT,
47 ofp.OFPFW_DL_VLAN,
48 ofp.OFPFW_DL_SRC,
49 ofp.OFPFW_DL_DST,
50 ofp.OFPFW_DL_TYPE,
51 ofp.OFPFW_NW_PROTO,
52 ofp.OFPFW_TP_SRC,
53 ofp.OFPFW_TP_DST,
54 0x3F << ofp.OFPFW_NW_SRC_SHIFT,
55 0x3F << ofp.OFPFW_NW_DST_SHIFT,
56 ofp.OFPFW_DL_VLAN_PCP,
57 ofp.OFPFW_NW_TOS]
58
59MODIFY_ACTION_VALUES = [ofp.OFPAT_SET_VLAN_VID,
60 ofp.OFPAT_SET_VLAN_PCP,
61 ofp.OFPAT_STRIP_VLAN,
62 ofp.OFPAT_SET_DL_SRC,
63 ofp.OFPAT_SET_DL_DST,
64 ofp.OFPAT_SET_NW_SRC,
65 ofp.OFPAT_SET_NW_DST,
66 ofp.OFPAT_SET_NW_TOS,
67 ofp.OFPAT_SET_TP_SRC,
68 ofp.OFPAT_SET_TP_DST]
69
70# Cache supported features to avoid transaction overhead
71cached_supported_actions = None
72
Dan Talayco21381562010-07-17 00:34:47 -070073TEST_VID_DEFAULT = 2
74
Dan Talayco5eba8442010-03-10 13:58:43 -080075def test_set_init(config):
76 """
77 Set up function for packet action test classes
78
79 @param config The configuration dictionary; see oft
80 """
81
82 global pa_port_map
83 global pa_logger
84 global pa_config
85
86 pa_logger = logging.getLogger("pkt_act")
87 pa_logger.info("Initializing test set")
88 pa_port_map = config["port_map"]
89 pa_config = config
90
91class DirectPacket(basic.SimpleDataPlane):
92 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -070093 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -080094
95 Generate a packet
96 Generate and install a matching flow
97 Add action to direct the packet to an egress port
98 Send the packet to ingress dataplane port
99 Verify the packet is received at the egress port only
100 """
101 def runTest(self):
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700102 self.handleFlow()
103
104 def handleFlow(self, pkttype='TCP'):
Dan Talayco5eba8442010-03-10 13:58:43 -0800105 of_ports = pa_port_map.keys()
106 of_ports.sort()
107 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
108
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700109 if (pkttype == 'ICMP'):
110 pkt = simple_icmp_packet()
111 else:
112 pkt = simple_tcp_packet()
Dan Talayco5eba8442010-03-10 13:58:43 -0800113 match = parse.packet_to_flow_match(pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -0700114 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -0800115 self.assertTrue(match is not None,
116 "Could not generate flow match from pkt")
117 act = action.action_output()
118
119 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700120 rv = delete_all_flows(self.controller, pa_logger)
121 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700122
Dan Talayco5eba8442010-03-10 13:58:43 -0800123 ingress_port = of_ports[idx]
124 egress_port = of_ports[(idx + 1) % len(of_ports)]
125 pa_logger.info("Ingress " + str(ingress_port) +
Dan Talayco551befa2010-07-15 17:05:32 -0700126 " to egress " + str(egress_port))
Dan Talayco5eba8442010-03-10 13:58:43 -0800127
128 match.in_port = ingress_port
129
130 request = message.flow_mod()
131 request.match = match
132 request.buffer_id = 0xffffffff
133 act.port = egress_port
134 self.assertTrue(request.actions.add(act), "Could not add action")
135
136 pa_logger.info("Inserting flow")
137 rv = self.controller.message_send(request)
138 self.assertTrue(rv != -1, "Error installing flow mod")
139 do_barrier(self.controller)
140
141 pa_logger.info("Sending packet to dp port " +
142 str(ingress_port))
143 self.dataplane.send(ingress_port, str(pkt))
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700144
145 exp_pkt_arg = None
146 exp_port = None
147 if pa_config["relax"]:
148 exp_pkt_arg = pkt
149 exp_port = egress_port
150
151 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1,
152 port_number=exp_port,
153 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800154 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700155 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800156 str(rcv_port))
157 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
158 self.assertEqual(str(pkt), str(rcv_pkt),
159 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700160
161class DirectPacketICMP(DirectPacket):
162 """
163 Send ICMP packet to single egress port
164
165 Generate a ICMP packet
166 Generate and install a matching flow
167 Add action to direct the packet to an egress port
168 Send the packet to ingress dataplane port
169 Verify the packet is received at the egress port only
170 Difference from DirectPacket test is that sent packet is ICMP
171 """
172 def runTest(self):
173 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700174
175class DirectTwoPorts(basic.SimpleDataPlane):
176 """
177 Send packet to two egress ports
178
179 Generate a packet
180 Generate and install a matching flow
181 Add action to direct the packet to two egress ports
182 Send the packet to ingress dataplane port
183 Verify the packet is received at the two egress ports
184 """
185 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700186 of_ports = pa_port_map.keys()
187 of_ports.sort()
188 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
189
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700190 pkt = simple_tcp_packet()
191 match = parse.packet_to_flow_match(pkt)
192 match.wildcards &= ~ofp.OFPFW_IN_PORT
193 self.assertTrue(match is not None,
194 "Could not generate flow match from pkt")
195 act = action.action_output()
196
197 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700198 rv = delete_all_flows(self.controller, pa_logger)
199 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700200
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700201 ingress_port = of_ports[idx]
202 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
203 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
204 pa_logger.info("Ingress " + str(ingress_port) +
205 " to egress " + str(egress_port1) + " and " +
206 str(egress_port2))
207
208 match.in_port = ingress_port
209
210 request = message.flow_mod()
211 request.match = match
212 request.buffer_id = 0xffffffff
213 act.port = egress_port1
214 self.assertTrue(request.actions.add(act), "Could not add action1")
215 act.port = egress_port2
216 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700217 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700218
219 pa_logger.info("Inserting flow")
220 rv = self.controller.message_send(request)
221 self.assertTrue(rv != -1, "Error installing flow mod")
222 do_barrier(self.controller)
223
224 pa_logger.info("Sending packet to dp port " +
225 str(ingress_port))
226 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700227 yes_ports = set([egress_port1, egress_port2])
228 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700229
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700230 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700231 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700232
233class DirectMCNonIngress(basic.SimpleDataPlane):
234 """
235 Multicast to all non-ingress ports
236
237 Generate a packet
238 Generate and install a matching flow
239 Add action to direct the packet to all non-ingress ports
240 Send the packet to ingress dataplane port
241 Verify the packet is received at all non-ingress ports
242
243 Does not use the flood action
244 """
245 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700246 of_ports = pa_port_map.keys()
247 of_ports.sort()
248 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
249
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700250 pkt = simple_tcp_packet()
251 match = parse.packet_to_flow_match(pkt)
252 match.wildcards &= ~ofp.OFPFW_IN_PORT
253 self.assertTrue(match is not None,
254 "Could not generate flow match from pkt")
255 act = action.action_output()
256
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700257 for ingress_port in of_ports:
258 rv = delete_all_flows(self.controller, pa_logger)
259 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700260
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700261 pa_logger.info("Ingress " + str(ingress_port) +
262 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700263 match.in_port = ingress_port
264
265 request = message.flow_mod()
266 request.match = match
267 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700268 for egress_port in of_ports:
269 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700270 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700271 act.port = egress_port
272 self.assertTrue(request.actions.add(act),
273 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700274 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700275
276 pa_logger.info("Inserting flow")
277 rv = self.controller.message_send(request)
278 self.assertTrue(rv != -1, "Error installing flow mod")
279 do_barrier(self.controller)
280
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700281 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700282 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700283 yes_ports = set(of_ports).difference([ingress_port])
284 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700285 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700286
Dan Talayco32fa6542010-05-11 15:54:08 -0700287
288class DirectMC(basic.SimpleDataPlane):
289 """
290 Multicast to all ports including ingress
291
292 Generate a packet
293 Generate and install a matching flow
294 Add action to direct the packet to all non-ingress ports
295 Send the packet to ingress dataplane port
296 Verify the packet is received at all ports
297
298 Does not use the flood action
299 """
300 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700301 of_ports = pa_port_map.keys()
302 of_ports.sort()
303 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
304
Dan Talayco32fa6542010-05-11 15:54:08 -0700305 pkt = simple_tcp_packet()
306 match = parse.packet_to_flow_match(pkt)
307 match.wildcards &= ~ofp.OFPFW_IN_PORT
308 self.assertTrue(match is not None,
309 "Could not generate flow match from pkt")
310 act = action.action_output()
311
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700312 for ingress_port in of_ports:
313 rv = delete_all_flows(self.controller, pa_logger)
314 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700315
Dan Talayco32fa6542010-05-11 15:54:08 -0700316 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700317 match.in_port = ingress_port
318
319 request = message.flow_mod()
320 request.match = match
321 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700322 for egress_port in of_ports:
323 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700324 act.port = ofp.OFPP_IN_PORT
325 else:
326 act.port = egress_port
327 self.assertTrue(request.actions.add(act),
328 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700329 # pa_logger.info(request.show())
330
331 pa_logger.info("Inserting flow")
332 rv = self.controller.message_send(request)
333 self.assertTrue(rv != -1, "Error installing flow mod")
334 do_barrier(self.controller)
335
336 pa_logger.info("Sending packet to dp port " + str(ingress_port))
337 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700338 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700339 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700340
341class Flood(basic.SimpleDataPlane):
342 """
343 Flood to all ports except ingress
344
345 Generate a packet
346 Generate and install a matching flow
347 Add action to flood the packet
348 Send the packet to ingress dataplane port
349 Verify the packet is received at all other ports
350 """
351 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700352 of_ports = pa_port_map.keys()
353 of_ports.sort()
354 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
355
356 pkt = simple_tcp_packet()
357 match = parse.packet_to_flow_match(pkt)
358 match.wildcards &= ~ofp.OFPFW_IN_PORT
359 self.assertTrue(match is not None,
360 "Could not generate flow match from pkt")
361 act = action.action_output()
362
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700363 for ingress_port in of_ports:
364 rv = delete_all_flows(self.controller, pa_logger)
365 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700366
Dan Talayco2e77a842010-05-12 15:39:46 -0700367 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700368 match.in_port = ingress_port
369
370 request = message.flow_mod()
371 request.match = match
372 request.buffer_id = 0xffffffff
373 act.port = ofp.OFPP_FLOOD
374 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700375 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700376 pa_logger.info(request.show())
377
378 pa_logger.info("Inserting flow")
379 rv = self.controller.message_send(request)
380 self.assertTrue(rv != -1, "Error installing flow mod")
381 do_barrier(self.controller)
382
383 pa_logger.info("Sending packet to dp port " + str(ingress_port))
384 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700385 yes_ports = set(of_ports).difference([ingress_port])
386 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700387 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700388
Dan Talayco3be5b062010-05-12 15:46:21 -0700389class FloodPlusIngress(basic.SimpleDataPlane):
390 """
391 Flood to all ports plus send to ingress port
392
393 Generate a packet
394 Generate and install a matching flow
395 Add action to flood the packet
396 Add action to send to ingress port
397 Send the packet to ingress dataplane port
398 Verify the packet is received at all other ports
399 """
400 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700401 of_ports = pa_port_map.keys()
402 of_ports.sort()
403 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
404
405 pkt = simple_tcp_packet()
406 match = parse.packet_to_flow_match(pkt)
407 match.wildcards &= ~ofp.OFPFW_IN_PORT
408 self.assertTrue(match is not None,
409 "Could not generate flow match from pkt")
410 act = action.action_output()
411
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700412 for ingress_port in of_ports:
413 rv = delete_all_flows(self.controller, pa_logger)
414 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700415
Dan Talayco3be5b062010-05-12 15:46:21 -0700416 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700417 match.in_port = ingress_port
418
419 request = message.flow_mod()
420 request.match = match
421 request.buffer_id = 0xffffffff
422 act.port = ofp.OFPP_FLOOD
423 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700424 "Could not add flood port action")
425 act.port = ofp.OFPP_IN_PORT
426 self.assertTrue(request.actions.add(act),
427 "Could not add ingress port for output")
428 pa_logger.info(request.show())
429
430 pa_logger.info("Inserting flow")
431 rv = self.controller.message_send(request)
432 self.assertTrue(rv != -1, "Error installing flow mod")
433 do_barrier(self.controller)
434
435 pa_logger.info("Sending packet to dp port " + str(ingress_port))
436 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700437 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700438 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700439
440class All(basic.SimpleDataPlane):
441 """
442 Send to OFPP_ALL port
443
444 Generate a packet
445 Generate and install a matching flow
446 Add action to forward to OFPP_ALL
447 Send the packet to ingress dataplane port
448 Verify the packet is received at all other ports
449 """
450 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700451 of_ports = pa_port_map.keys()
452 of_ports.sort()
453 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
454
455 pkt = simple_tcp_packet()
456 match = parse.packet_to_flow_match(pkt)
457 match.wildcards &= ~ofp.OFPFW_IN_PORT
458 self.assertTrue(match is not None,
459 "Could not generate flow match from pkt")
460 act = action.action_output()
461
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700462 for ingress_port in of_ports:
463 rv = delete_all_flows(self.controller, pa_logger)
464 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700465
Dan Talayco4aa13122010-05-12 15:54:44 -0700466 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700467 match.in_port = ingress_port
468
469 request = message.flow_mod()
470 request.match = match
471 request.buffer_id = 0xffffffff
472 act.port = ofp.OFPP_ALL
473 self.assertTrue(request.actions.add(act),
474 "Could not add ALL port action")
475 pa_logger.info(request.show())
476
477 pa_logger.info("Inserting flow")
478 rv = self.controller.message_send(request)
479 self.assertTrue(rv != -1, "Error installing flow mod")
480 do_barrier(self.controller)
481
482 pa_logger.info("Sending packet to dp port " + str(ingress_port))
483 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700484 yes_ports = set(of_ports).difference([ingress_port])
485 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700486 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700487
488class AllPlusIngress(basic.SimpleDataPlane):
489 """
490 Send to OFPP_ALL port and ingress port
491
492 Generate a packet
493 Generate and install a matching flow
494 Add action to forward to OFPP_ALL
495 Add action to forward to ingress port
496 Send the packet to ingress dataplane port
497 Verify the packet is received at all other ports
498 """
499 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700500 of_ports = pa_port_map.keys()
501 of_ports.sort()
502 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
503
504 pkt = simple_tcp_packet()
505 match = parse.packet_to_flow_match(pkt)
506 match.wildcards &= ~ofp.OFPFW_IN_PORT
507 self.assertTrue(match is not None,
508 "Could not generate flow match from pkt")
509 act = action.action_output()
510
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700511 for ingress_port in of_ports:
512 rv = delete_all_flows(self.controller, pa_logger)
513 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700514
Dan Talayco4aa13122010-05-12 15:54:44 -0700515 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700516 match.in_port = ingress_port
517
518 request = message.flow_mod()
519 request.match = match
520 request.buffer_id = 0xffffffff
521 act.port = ofp.OFPP_ALL
522 self.assertTrue(request.actions.add(act),
523 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700524 act.port = ofp.OFPP_IN_PORT
525 self.assertTrue(request.actions.add(act),
526 "Could not add ingress port for output")
527 pa_logger.info(request.show())
528
529 pa_logger.info("Inserting flow")
530 rv = self.controller.message_send(request)
531 self.assertTrue(rv != -1, "Error installing flow mod")
532 do_barrier(self.controller)
533
534 pa_logger.info("Sending packet to dp port " + str(ingress_port))
535 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700536 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700537 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700538
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700539class FloodMinusPort(basic.SimpleDataPlane):
540 """
541 Config port with No_Flood and test Flood action
542
543 Generate a packet
544 Generate a matching flow
545 Add action to forward to OFPP_ALL
546 Set port to no-flood
547 Send the packet to ingress dataplane port
548 Verify the packet is received at all other ports except
549 the ingress port and the no_flood port
550 """
551 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700552 of_ports = pa_port_map.keys()
553 of_ports.sort()
554 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
555
556 pkt = simple_tcp_packet()
557 match = parse.packet_to_flow_match(pkt)
558 match.wildcards &= ~ofp.OFPFW_IN_PORT
559 self.assertTrue(match is not None,
560 "Could not generate flow match from pkt")
561 act = action.action_output()
562
563 for idx in range(len(of_ports)):
564 rv = delete_all_flows(self.controller, pa_logger)
565 self.assertEqual(rv, 0, "Failed to delete all flows")
566
567 ingress_port = of_ports[idx]
568 no_flood_idx = (idx + 1) % len(of_ports)
569 no_flood_port = of_ports[no_flood_idx]
570 rv = port_config_set(self.controller, no_flood_port,
571 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
572 pa_logger)
573 self.assertEqual(rv, 0, "Failed to set port config")
574
575 match.in_port = ingress_port
576
577 request = message.flow_mod()
578 request.match = match
579 request.buffer_id = 0xffffffff
580 act.port = ofp.OFPP_FLOOD
581 self.assertTrue(request.actions.add(act),
582 "Could not add flood port action")
583 pa_logger.info(request.show())
584
585 pa_logger.info("Inserting flow")
586 rv = self.controller.message_send(request)
587 self.assertTrue(rv != -1, "Error installing flow mod")
588 do_barrier(self.controller)
589
590 pa_logger.info("Sending packet to dp port " + str(ingress_port))
591 pa_logger.info("No flood port is " + str(no_flood_port))
592 self.dataplane.send(ingress_port, str(pkt))
593 no_ports = set([ingress_port, no_flood_port])
594 yes_ports = set(of_ports).difference(no_ports)
595 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700596 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700597
598 # Turn no flood off again
599 rv = port_config_set(self.controller, no_flood_port,
600 0, ofp.OFPPC_NO_FLOOD, pa_logger)
601 self.assertEqual(rv, 0, "Failed to reset port config")
602
603 #@todo Should check no other packets received
604
Dan Talayco21381562010-07-17 00:34:47 -0700605
606
Dan Talayco551befa2010-07-15 17:05:32 -0700607################################################################
608
609class BaseMatchCase(basic.SimpleDataPlane):
610 def setUp(self):
611 basic.SimpleDataPlane.setUp(self)
612 self.logger = pa_logger
613 def runTest(self):
614 self.logger.info("BaseMatchCase")
615
616class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700617 """
Dan Talayco551befa2010-07-15 17:05:32 -0700618 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700619
620 Generate a packet
621 Generate and install a matching flow without wildcard mask
622 Add action to forward to a port
623 Send the packet to the port
624 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700625 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700626
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700627 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700628 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700629
Dan Talayco551befa2010-07-15 17:05:32 -0700630class ExactMatchTagged(BaseMatchCase):
631 """
632 Exact match for all port pairs with tagged pkts
633 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700634
Dan Talayco551befa2010-07-15 17:05:32 -0700635 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700636 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700637 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700638
Dan Talayco551befa2010-07-15 17:05:32 -0700639class ExactMatchTaggedMany(BaseMatchCase):
640 """
641 ExactMatchTagged with many VLANS
642 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700643
Dan Talayco551befa2010-07-15 17:05:32 -0700644 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700645 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700646 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
647 for vid in range(100,4000,389):
648 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
649 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700650
Dan Talayco551befa2010-07-15 17:05:32 -0700651# Don't run by default
652test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700653
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700654
Dan Talayco551befa2010-07-15 17:05:32 -0700655class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700656 """
657 Exercise wildcard matching for all ports
658
659 Generate a packet
660 Generate and install a matching flow with wildcard mask
661 Add action to forward to a port
662 Send the packet to the port
663 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700664 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700665 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700666 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700667 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -0700668 flow_match_test(self, pa_port_map, wildcards=wc, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700669
Dan Talayco551befa2010-07-15 17:05:32 -0700670class SingleWildcardMatchTagged(BaseMatchCase):
671 """
672 SingleWildcardMatch with tagged packets
673 """
674 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700675 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700676 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -0700677 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -0700678 max_test=10)
679
680class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700681 """
Dan Talayco80b54ed2010-07-13 09:48:35 -0700682 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700683
684 Generate a packet
685 Generate and install a matching flow with wildcard all except one filed
686 Add action to forward to a port
687 Send the packet to the port
688 Verify the packet is received at all other ports (one port at a time)
689 Verify flow_expiration message is correct when command option is set
690 """
691 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700692 for wc in WILDCARD_VALUES:
693 all_exp_one_wildcard = ofp.OFPFW_ALL ^ wc
Dan Talayco21381562010-07-17 00:34:47 -0700694 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -0700695
Dan Talayco551befa2010-07-15 17:05:32 -0700696class AllExceptOneWildcardMatchTagged(BaseMatchCase):
697 """
698 Match one field with tagged packets
699 """
700 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700701 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700702 for wc in WILDCARD_VALUES:
703 all_exp_one_wildcard = ofp.OFPFW_ALL ^ wc
Dan Talayco21381562010-07-17 00:34:47 -0700704 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
705 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -0700706
707class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -0700708 """
709 Create Wildcard-all flow and exercise for all ports
710
711 Generate a packet
712 Generate and install a matching flow with wildcard-all
713 Add action to forward to a port
714 Send the packet to the port
715 Verify the packet is received at all other ports (one port at a time)
716 Verify flow_expiration message is correct when command option is set
717 """
718 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700719 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700720
Dan Talayco551befa2010-07-15 17:05:32 -0700721class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700722 """
Dan Talayco551befa2010-07-15 17:05:32 -0700723 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700724 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700725 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700726 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700727 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
728 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700729
Dan Talaycoba3745c2010-07-21 21:51:08 -0700730
Dan Talayco551befa2010-07-15 17:05:32 -0700731class AddVLANTag(BaseMatchCase):
732 """
733 Add a VLAN tag to an untagged packet
734 """
735 def runTest(self):
736 new_vid = 2
737 sup_acts = supported_actions_get(self)
738 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700739 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -0700740 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -0700741
Dan Talayco551befa2010-07-15 17:05:32 -0700742 len = 100
743 len_w_vid = 104
744 pkt = simple_tcp_packet(pktlen=len)
745 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
746 dl_vlan=new_vid)
747 vid_act = action.action_set_vlan_vid()
748 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700749
Dan Talayco551befa2010-07-15 17:05:32 -0700750 flow_match_test(self, pa_port_map, pkt=pkt,
751 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700752
Dan Talayco551befa2010-07-15 17:05:32 -0700753class PacketOnly(basic.DataPlaneOnly):
754 """
755 Just send a packet thru the switch
756 """
757 def runTest(self):
758 pkt = simple_tcp_packet()
759 of_ports = pa_port_map.keys()
760 of_ports.sort()
761 ing_port = of_ports[0]
762 pa_logger.info("Sending packet to " + str(ing_port))
763 pa_logger.debug("Data: " + str(pkt).encode('hex'))
764 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700765
Dan Talayco551befa2010-07-15 17:05:32 -0700766class PacketOnlyTagged(basic.DataPlaneOnly):
767 """
768 Just send a packet thru the switch
769 """
770 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700771 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700772 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
773 of_ports = pa_port_map.keys()
774 of_ports.sort()
775 ing_port = of_ports[0]
776 pa_logger.info("Sending packet to " + str(ing_port))
777 pa_logger.debug("Data: " + str(pkt).encode('hex'))
778 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700779
Dan Talayco551befa2010-07-15 17:05:32 -0700780test_prio["PacketOnly"] = -1
781test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700782
Dan Talayco551befa2010-07-15 17:05:32 -0700783class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700784 """
785 Modify the VLAN ID in the VLAN tag of a tagged packet
786 """
Dan Talayco551befa2010-07-15 17:05:32 -0700787 def runTest(self):
788 old_vid = 2
789 new_vid = 3
790 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -0700791 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700792 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -0700793 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700794
Dan Talayco551befa2010-07-15 17:05:32 -0700795 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
796 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
797 vid_act = action.action_set_vlan_vid()
798 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700799
Dan Talayco551befa2010-07-15 17:05:32 -0700800 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
801 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700802
Dan Talayco551befa2010-07-15 17:05:32 -0700803class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700804 """
805 Strip the VLAN tag from a tagged packet
806 """
Dan Talayco551befa2010-07-15 17:05:32 -0700807 def runTest(self):
808 old_vid = 2
809 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -0700810 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700811 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -0700812 return
Dan Talaycof36f1082010-07-13 13:57:17 -0700813
Dan Talayco551befa2010-07-15 17:05:32 -0700814 len_w_vid = 104
815 len = 100
816 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
817 dl_vlan=old_vid)
818 exp_pkt = simple_tcp_packet(pktlen=len)
819 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700820
Dan Talayco551befa2010-07-15 17:05:32 -0700821 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
822 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700823
Dan Talayco4b2bee62010-07-20 14:10:05 -0700824def init_pkt_args():
825 """
826 Pass back a dictionary with default packet arguments
827 """
828 args = {}
829 args["dl_src"] = '00:23:45:67:89:AB'
830
831 dl_vlan_enable=False
832 dl_vlan=-1
833 if pa_config["test-params"]["vid"]:
834 dl_vlan_enable=True
835 dl_vlan = pa_config["test-params"]["vid"]
836
837# Unpack operator is ** on a dictionary
838
839 return args
840
Dan Talayco551befa2010-07-15 17:05:32 -0700841class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700842 """
843 Modify the source MAC address (TP1)
844 """
Dan Talayco551befa2010-07-15 17:05:32 -0700845 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700846 sup_acts = supported_actions_get(self)
847 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700848 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700849 return
850
851 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
852 check_test_params=True)
853 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
854 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700855
Dan Talayco551befa2010-07-15 17:05:32 -0700856class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700857 """
858 Modify the dest MAC address (TP1)
859 """
Dan Talayco551befa2010-07-15 17:05:32 -0700860 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700861 sup_acts = supported_actions_get(self)
862 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700863 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700864 return
865
866 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
867 check_test_params=True)
868 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
869 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700870
Dan Talayco551befa2010-07-15 17:05:32 -0700871class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700872 """
873 Modify the source IP address of an IP packet (TP1)
874 """
Dan Talayco551befa2010-07-15 17:05:32 -0700875 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700876 sup_acts = supported_actions_get(self)
877 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700878 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700879 return
880
881 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
882 check_test_params=True)
883 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
884 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700885
Dan Talayco551befa2010-07-15 17:05:32 -0700886class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700887 """
888 Modify the dest IP address of an IP packet (TP1)
889 """
Dan Talayco551befa2010-07-15 17:05:32 -0700890 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700891 sup_acts = supported_actions_get(self)
892 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700893 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700894 return
895
896 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
897 check_test_params=True)
898 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
899 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -0700900
901class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700902 """
903 Modify the source TCP port of a TCP packet (TP1)
904 """
Dan Talayco551befa2010-07-15 17:05:32 -0700905 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700906 sup_acts = supported_actions_get(self)
907 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700908 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700909 return
910
911 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
912 check_test_params=True)
913 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
914 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -0700915
916class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700917 """
918 Modify the dest TCP port of a TCP packet (TP1)
919 """
Dan Talayco551befa2010-07-15 17:05:32 -0700920 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700921 sup_acts = supported_actions_get(self)
922 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700923 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700924 return
925
926 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
927 check_test_params=True)
928 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
929 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -0700930
931class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700932 """
933 Modify the IP type of service of an IP packet (TP1)
934 """
Dan Talayco551befa2010-07-15 17:05:32 -0700935 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700936 sup_acts = supported_actions_get(self)
937 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700938 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -0700939 return
Dan Talayco551befa2010-07-15 17:05:32 -0700940
Dan Talayco4b2bee62010-07-20 14:10:05 -0700941 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
942 check_test_params=True)
943 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
944 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -0700945
Dan Talayco4b2bee62010-07-20 14:10:05 -0700946#@todo Need to implement tagged versions of the above tests
947#
948#@todo Implement a test case that strips tag 2, adds tag 3
949# and modifies tag 4 to tag 5. Then verify (in addition) that
950# tag 6 does not get modified.
951
952class MixedVLAN(BaseMatchCase):
953 """
954 Test mixture of VLAN tag actions
955
956 Strip tag 2 on port 1, send to port 2
957 Add tag 3 on port 1, send to port 2
958 Modify tag 4 to 5 on port 1, send to port 2
959 All other traffic from port 1, send to port 3
960 All traffic from port 2 sent to port 4
961 Use exact matches with different packets for all mods
962 Verify the following: (port, vid)
963 (port 1, vid 2) => VLAN tag stripped, out port 2
964 (port 1, no tag) => tagged packet w/ vid 2 out port 2
965 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
966 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
967 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
968 (port 2, no tag) => untagged packet out port 4
969 (port 2, vid 2-6) => unmodified packet out port 4
970
971 Variation: Might try sending VID 5 to port 3 and check.
972 If only VID 5 distinguishes pkt, this will fail on some platforms
973 """
974
975test_prio["MixedVLAN"] = -1
976
Dan Talayco551befa2010-07-15 17:05:32 -0700977def supported_actions_get(parent, use_cache=True):
978 """
979 Get the bitmap of supported actions from the switch
980 If use_cache is false, the cached value will be updated
981 """
982 global cached_supported_actions
983 if cached_supported_actions is None or not use_cache:
984 request = message.features_request()
985 (reply, pkt) = parent.controller.transact(request, timeout=2)
986 parent.assertTrue(reply is not None, "Did not get response to ftr req")
987 cached_supported_actions = reply.actions
988 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
989
990 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -0700991
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700992if __name__ == "__main__":
993 print "Please run through oft script: ./oft --test_spec=basic"