blob: 7b34d12558cd862f07205e17a4a6c876343c2904 [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
175 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1,
176 port_number=exp_port,
177 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800178 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700179 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800180 str(rcv_port))
181 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
182 self.assertEqual(str(pkt), str(rcv_pkt),
183 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700184
185class DirectPacketICMP(DirectPacket):
186 """
187 Send ICMP packet to single egress port
188
189 Generate a ICMP packet
190 Generate and install a matching flow
191 Add action to direct the packet to an egress port
192 Send the packet to ingress dataplane port
193 Verify the packet is received at the egress port only
194 Difference from DirectPacket test is that sent packet is ICMP
195 """
196 def runTest(self):
197 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700198
199class DirectTwoPorts(basic.SimpleDataPlane):
200 """
201 Send packet to two egress ports
202
203 Generate a packet
204 Generate and install a matching flow
205 Add action to direct the packet to two egress ports
206 Send the packet to ingress dataplane port
207 Verify the packet is received at the two egress ports
208 """
209 def runTest(self):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700210 of_ports = pa_port_map.keys()
211 of_ports.sort()
212 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
213
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700214 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 act = action.action_output()
220
221 for idx in range(len(of_ports)):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700222 rv = delete_all_flows(self.controller, pa_logger)
223 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700224
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700225 ingress_port = of_ports[idx]
226 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
227 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
228 pa_logger.info("Ingress " + str(ingress_port) +
229 " to egress " + str(egress_port1) + " and " +
230 str(egress_port2))
231
232 match.in_port = ingress_port
233
234 request = message.flow_mod()
235 request.match = match
236 request.buffer_id = 0xffffffff
237 act.port = egress_port1
238 self.assertTrue(request.actions.add(act), "Could not add action1")
239 act.port = egress_port2
240 self.assertTrue(request.actions.add(act), "Could not add action2")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700241 # pa_logger.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700242
243 pa_logger.info("Inserting flow")
244 rv = self.controller.message_send(request)
245 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700246 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700247
248 pa_logger.info("Sending packet to dp port " +
249 str(ingress_port))
250 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700251 yes_ports = set([egress_port1, egress_port2])
252 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700253
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700254 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700255 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700256
257class DirectMCNonIngress(basic.SimpleDataPlane):
258 """
259 Multicast to all non-ingress ports
260
261 Generate a packet
262 Generate and install a matching flow
263 Add action to direct the packet to all non-ingress ports
264 Send the packet to ingress dataplane port
265 Verify the packet is received at all non-ingress ports
266
267 Does not use the flood action
268 """
269 def runTest(self):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700270 of_ports = pa_port_map.keys()
271 of_ports.sort()
272 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
273
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700274 pkt = simple_tcp_packet()
275 match = parse.packet_to_flow_match(pkt)
276 match.wildcards &= ~ofp.OFPFW_IN_PORT
277 self.assertTrue(match is not None,
278 "Could not generate flow match from pkt")
279 act = action.action_output()
280
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700281 for ingress_port in of_ports:
282 rv = delete_all_flows(self.controller, pa_logger)
283 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700284
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700285 pa_logger.info("Ingress " + str(ingress_port) +
286 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700287 match.in_port = ingress_port
288
289 request = message.flow_mod()
290 request.match = match
291 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700292 for egress_port in of_ports:
293 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700294 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700295 act.port = egress_port
296 self.assertTrue(request.actions.add(act),
297 "Could not add output to " + str(egress_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700298 pa_logger.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700299
300 pa_logger.info("Inserting flow")
301 rv = self.controller.message_send(request)
302 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700303 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700304
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700305 pa_logger.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700306 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700307 yes_ports = set(of_ports).difference([ingress_port])
308 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700309 self, pa_logger, pa_config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700310
Dan Talayco32fa6542010-05-11 15:54:08 -0700311
312class DirectMC(basic.SimpleDataPlane):
313 """
314 Multicast to all ports including ingress
315
316 Generate a packet
317 Generate and install a matching flow
318 Add action to direct the packet to all non-ingress ports
319 Send the packet to ingress dataplane port
320 Verify the packet is received at all ports
321
322 Does not use the flood action
323 """
324 def runTest(self):
Dan Talayco32fa6542010-05-11 15:54:08 -0700325 of_ports = pa_port_map.keys()
326 of_ports.sort()
327 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
328
Dan Talayco32fa6542010-05-11 15:54:08 -0700329 pkt = simple_tcp_packet()
330 match = parse.packet_to_flow_match(pkt)
331 match.wildcards &= ~ofp.OFPFW_IN_PORT
332 self.assertTrue(match is not None,
333 "Could not generate flow match from pkt")
334 act = action.action_output()
335
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700336 for ingress_port in of_ports:
337 rv = delete_all_flows(self.controller, pa_logger)
338 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700339
Dan Talayco32fa6542010-05-11 15:54:08 -0700340 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700341 match.in_port = ingress_port
342
343 request = message.flow_mod()
344 request.match = match
345 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700346 for egress_port in of_ports:
347 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700348 act.port = ofp.OFPP_IN_PORT
349 else:
350 act.port = egress_port
351 self.assertTrue(request.actions.add(act),
352 "Could not add output to " + str(egress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700353 # pa_logger.info(request.show())
354
355 pa_logger.info("Inserting flow")
356 rv = self.controller.message_send(request)
357 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700358 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2e77a842010-05-12 15:39:46 -0700359
360 pa_logger.info("Sending packet to dp port " + str(ingress_port))
361 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700362 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700363 pa_logger, pa_config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700364
365class Flood(basic.SimpleDataPlane):
366 """
367 Flood to all ports except ingress
368
369 Generate a packet
370 Generate and install a matching flow
371 Add action to flood the packet
372 Send the packet to ingress dataplane port
373 Verify the packet is received at all other ports
374 """
375 def runTest(self):
Dan Talayco2e77a842010-05-12 15:39:46 -0700376 of_ports = pa_port_map.keys()
377 of_ports.sort()
378 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
379
380 pkt = simple_tcp_packet()
381 match = parse.packet_to_flow_match(pkt)
382 match.wildcards &= ~ofp.OFPFW_IN_PORT
383 self.assertTrue(match is not None,
384 "Could not generate flow match from pkt")
385 act = action.action_output()
386
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700387 for ingress_port in of_ports:
388 rv = delete_all_flows(self.controller, pa_logger)
389 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700390
Dan Talayco2e77a842010-05-12 15:39:46 -0700391 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700392 match.in_port = ingress_port
393
394 request = message.flow_mod()
395 request.match = match
396 request.buffer_id = 0xffffffff
397 act.port = ofp.OFPP_FLOOD
398 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700399 "Could not add flood port action")
Dan Talayco32fa6542010-05-11 15:54:08 -0700400 pa_logger.info(request.show())
401
402 pa_logger.info("Inserting flow")
403 rv = self.controller.message_send(request)
404 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700405 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco32fa6542010-05-11 15:54:08 -0700406
407 pa_logger.info("Sending packet to dp port " + str(ingress_port))
408 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700409 yes_ports = set(of_ports).difference([ingress_port])
410 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700411 self, pa_logger, pa_config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700412
Dan Talayco3be5b062010-05-12 15:46:21 -0700413class FloodPlusIngress(basic.SimpleDataPlane):
414 """
415 Flood to all ports plus send to ingress port
416
417 Generate a packet
418 Generate and install a matching flow
419 Add action to flood the packet
420 Add action to send to ingress port
421 Send the packet to ingress dataplane port
422 Verify the packet is received at all other ports
423 """
424 def runTest(self):
Dan Talayco3be5b062010-05-12 15:46:21 -0700425 of_ports = pa_port_map.keys()
426 of_ports.sort()
427 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
428
429 pkt = simple_tcp_packet()
430 match = parse.packet_to_flow_match(pkt)
431 match.wildcards &= ~ofp.OFPFW_IN_PORT
432 self.assertTrue(match is not None,
433 "Could not generate flow match from pkt")
434 act = action.action_output()
435
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700436 for ingress_port in of_ports:
437 rv = delete_all_flows(self.controller, pa_logger)
438 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700439
Dan Talayco3be5b062010-05-12 15:46:21 -0700440 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700441 match.in_port = ingress_port
442
443 request = message.flow_mod()
444 request.match = match
445 request.buffer_id = 0xffffffff
446 act.port = ofp.OFPP_FLOOD
447 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700448 "Could not add flood port action")
449 act.port = ofp.OFPP_IN_PORT
450 self.assertTrue(request.actions.add(act),
451 "Could not add ingress port for output")
452 pa_logger.info(request.show())
453
454 pa_logger.info("Inserting flow")
455 rv = self.controller.message_send(request)
456 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700457 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700458
459 pa_logger.info("Sending packet to dp port " + str(ingress_port))
460 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700461 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700462 pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700463
464class All(basic.SimpleDataPlane):
465 """
466 Send to OFPP_ALL port
467
468 Generate a packet
469 Generate and install a matching flow
470 Add action to forward to OFPP_ALL
471 Send the packet to ingress dataplane port
472 Verify the packet is received at all other ports
473 """
474 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700475 of_ports = pa_port_map.keys()
476 of_ports.sort()
477 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
478
479 pkt = simple_tcp_packet()
480 match = parse.packet_to_flow_match(pkt)
481 match.wildcards &= ~ofp.OFPFW_IN_PORT
482 self.assertTrue(match is not None,
483 "Could not generate flow match from pkt")
484 act = action.action_output()
485
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700486 for ingress_port in of_ports:
487 rv = delete_all_flows(self.controller, pa_logger)
488 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700489
Dan Talayco4aa13122010-05-12 15:54:44 -0700490 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700491 match.in_port = ingress_port
492
493 request = message.flow_mod()
494 request.match = match
495 request.buffer_id = 0xffffffff
496 act.port = ofp.OFPP_ALL
497 self.assertTrue(request.actions.add(act),
498 "Could not add ALL port action")
499 pa_logger.info(request.show())
500
501 pa_logger.info("Inserting flow")
502 rv = self.controller.message_send(request)
503 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700504 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700505
506 pa_logger.info("Sending packet to dp port " + str(ingress_port))
507 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700508 yes_ports = set(of_ports).difference([ingress_port])
509 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700510 self, pa_logger, pa_config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700511
512class AllPlusIngress(basic.SimpleDataPlane):
513 """
514 Send to OFPP_ALL port and ingress port
515
516 Generate a packet
517 Generate and install a matching flow
518 Add action to forward to OFPP_ALL
519 Add action to forward to ingress port
520 Send the packet to ingress dataplane port
521 Verify the packet is received at all other ports
522 """
523 def runTest(self):
Dan Talayco4aa13122010-05-12 15:54:44 -0700524 of_ports = pa_port_map.keys()
525 of_ports.sort()
526 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
527
528 pkt = simple_tcp_packet()
529 match = parse.packet_to_flow_match(pkt)
530 match.wildcards &= ~ofp.OFPFW_IN_PORT
531 self.assertTrue(match is not None,
532 "Could not generate flow match from pkt")
533 act = action.action_output()
534
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700535 for ingress_port in of_ports:
536 rv = delete_all_flows(self.controller, pa_logger)
537 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700538
Dan Talayco4aa13122010-05-12 15:54:44 -0700539 pa_logger.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700540 match.in_port = ingress_port
541
542 request = message.flow_mod()
543 request.match = match
544 request.buffer_id = 0xffffffff
545 act.port = ofp.OFPP_ALL
546 self.assertTrue(request.actions.add(act),
547 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700548 act.port = ofp.OFPP_IN_PORT
549 self.assertTrue(request.actions.add(act),
550 "Could not add ingress port for output")
551 pa_logger.info(request.show())
552
553 pa_logger.info("Inserting flow")
554 rv = self.controller.message_send(request)
555 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700556 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco3be5b062010-05-12 15:46:21 -0700557
558 pa_logger.info("Sending packet to dp port " + str(ingress_port))
559 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700560 receive_pkt_check(self.dataplane, pkt, of_ports, [], self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700561 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700562
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700563class FloodMinusPort(basic.SimpleDataPlane):
564 """
565 Config port with No_Flood and test Flood action
566
567 Generate a packet
568 Generate a matching flow
569 Add action to forward to OFPP_ALL
570 Set port to no-flood
571 Send the packet to ingress dataplane port
572 Verify the packet is received at all other ports except
573 the ingress port and the no_flood port
574 """
575 def runTest(self):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700576 of_ports = pa_port_map.keys()
577 of_ports.sort()
578 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
579
580 pkt = simple_tcp_packet()
581 match = parse.packet_to_flow_match(pkt)
582 match.wildcards &= ~ofp.OFPFW_IN_PORT
583 self.assertTrue(match is not None,
584 "Could not generate flow match from pkt")
585 act = action.action_output()
586
587 for idx in range(len(of_ports)):
588 rv = delete_all_flows(self.controller, pa_logger)
589 self.assertEqual(rv, 0, "Failed to delete all flows")
590
591 ingress_port = of_ports[idx]
592 no_flood_idx = (idx + 1) % len(of_ports)
593 no_flood_port = of_ports[no_flood_idx]
594 rv = port_config_set(self.controller, no_flood_port,
595 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD,
596 pa_logger)
597 self.assertEqual(rv, 0, "Failed to set port config")
598
599 match.in_port = ingress_port
600
601 request = message.flow_mod()
602 request.match = match
603 request.buffer_id = 0xffffffff
604 act.port = ofp.OFPP_FLOOD
605 self.assertTrue(request.actions.add(act),
606 "Could not add flood port action")
607 pa_logger.info(request.show())
608
609 pa_logger.info("Inserting flow")
610 rv = self.controller.message_send(request)
611 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700612 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700613
614 pa_logger.info("Sending packet to dp port " + str(ingress_port))
615 pa_logger.info("No flood port is " + str(no_flood_port))
616 self.dataplane.send(ingress_port, str(pkt))
617 no_ports = set([ingress_port, no_flood_port])
618 yes_ports = set(of_ports).difference(no_ports)
619 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700620 pa_logger, pa_config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700621
622 # Turn no flood off again
623 rv = port_config_set(self.controller, no_flood_port,
624 0, ofp.OFPPC_NO_FLOOD, pa_logger)
625 self.assertEqual(rv, 0, "Failed to reset port config")
626
627 #@todo Should check no other packets received
628
Dan Talayco21381562010-07-17 00:34:47 -0700629
630
Dan Talayco551befa2010-07-15 17:05:32 -0700631################################################################
632
633class BaseMatchCase(basic.SimpleDataPlane):
634 def setUp(self):
635 basic.SimpleDataPlane.setUp(self)
636 self.logger = pa_logger
637 def runTest(self):
638 self.logger.info("BaseMatchCase")
639
640class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700641 """
Dan Talayco551befa2010-07-15 17:05:32 -0700642 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700643
644 Generate a packet
645 Generate and install a matching flow without wildcard mask
646 Add action to forward to a port
647 Send the packet to the port
648 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700649 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700650
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700651 def runTest(self):
Dan Talayco551befa2010-07-15 17:05:32 -0700652 flow_match_test(self, pa_port_map)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700653
Dan Talayco551befa2010-07-15 17:05:32 -0700654class ExactMatchTagged(BaseMatchCase):
655 """
656 Exact match for all port pairs with tagged pkts
657 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700658
Dan Talayco551befa2010-07-15 17:05:32 -0700659 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700660 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700661 flow_match_test(self, pa_port_map, dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700662
Dan Talayco551befa2010-07-15 17:05:32 -0700663class ExactMatchTaggedMany(BaseMatchCase):
664 """
665 ExactMatchTagged with many VLANS
666 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700667
Dan Talayco551befa2010-07-15 17:05:32 -0700668 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700669 for vid in range(2,100,10):
Dan Talayco551befa2010-07-15 17:05:32 -0700670 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
671 for vid in range(100,4000,389):
672 flow_match_test(self, pa_port_map, dl_vlan=vid, max_test=5)
673 flow_match_test(self, pa_port_map, dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700674
Dan Talayco551befa2010-07-15 17:05:32 -0700675# Don't run by default
676test_prio["ExactMatchTaggedMany"] = -1
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700677
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700678
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700679class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700680 """
681 SingleWildcardMatchPriority
682 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700683
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700684 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700685 self.pkt = simple_tcp_packet()
686 self.flowMsgs = {}
687
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700688 def _ClearTable(self):
689 rc = delete_all_flows(self.controller, self.logger)
690 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700691 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700692
693 def runTest(self):
694
695 self._Init()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700696 of_ports = pa_port_map.keys()
697 of_ports.sort()
698
699 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700700 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700701
702 # Run several combinations, each at lower priority settings.
703 # At the end of each call to runPrioFlows(), the table should
704 # be empty. If its not, we'll catch it as the priorities decreases
705 portA = of_ports[0]
706 portB = of_ports[1]
707 portC = of_ports[2]
708
709 # TODO -- these priority numbers should be validated somehow?
710 self.runPrioFlows(portA, portB, portC, 1000, 999)
711 self.runPrioFlows(portB, portC, portA, 998, 997)
712 self.runPrioFlows(portC, portA, portB, 996, 995)
713 self.runPrioFlows(portA, portC, portB, 994, 993)
714
715
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700716
717 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
718 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700719
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700720 if clearTable:
721 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700722
723 # Sanity check flow at lower priority from pA to pB
724 self.logger.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
725 % (portA, portB, portC, prioHigher, prioLower))
726
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700727 self.installFlow(prioHigher, portA, portC)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700728 self.installFlow(prioLower, portA, portB)
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700729
730 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700731 self.verifyFlow(portA, portB)
732 self.removeFlow(prioLower)
733 # Sanity check flow at lower priority from pA to pC
734 self.installFlow(prioLower, portA, portC)
735 self.verifyFlow(portA, portC)
736 self.removeFlow(prioLower)
737
738 # Install and verify pA->pB @ prioLower
739 self.installFlow(prioLower, portA, portB)
740 self.verifyFlow(portA, portB)
741
742 # Install and verify pA->pC @ prioHigher, should override pA->pB
743 self.installFlow(prioHigher, portA, portC)
744 self.verifyFlow(portA, portC)
745 # remove pA->pC
746 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700747 # Old flow pA -> pB @ prioLower should still be active
748 self.verifyFlow(portA, portB)
749 self.removeFlow(prioLower)
750
751 # Table should be empty at this point, leave it alone as
752 # an assumption for future test runs
753
754
755
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700756 def installFlow(self, prio, inp, egp):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700757 request = flow_msg_create(self, self.pkt, ing_port=inp,
758 wildcards=ofp.OFPFW_DL_SRC,
759 egr_ports=egp)
760 request.priority = prio
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700761 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700762 self.flowMsgs[prio] = request
763
764 def removeFlow(self, prio):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700765 return
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700766 if self.flowMsgs.has_key(prio):
767 msg = self.flowMsgs[prio]
768 msg.command = ofp.OFPFC_DELETE_STRICT
769 # This *must* be set for DELETE
770 msg.out_port = ofp.OFPP_NONE
771 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700772 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700773 else:
774 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700775
776
777 def verifyFlow(self, inp, egp):
778 self.logger.info("Pkt match test: " + str(inp) +
779 " to " + str(egp))
780 self.logger.debug("Send packet: " + str(inp) + " to "
781 + str(egp))
782 self.dataplane.send(inp, str(self.pkt))
783 receive_pkt_verify(self, egp, self.pkt, inp)
784
785
786
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700787class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
788
789 def runTest(self):
790
791 self._Init()
792
793 of_ports = pa_port_map.keys()
794 of_ports.sort()
795
796 # Install an entry from 0 -> 1 @ prio 1000
797 self._ClearTable()
798 self.installFlow(1000, of_ports[0], of_ports[1])
799 self.verifyFlow(of_ports[0], of_ports[1])
800 self.installFlow(1000, of_ports[1], of_ports[0])
801 self.verifyFlow(of_ports[1], of_ports[0])
802 self.installFlow(1001, of_ports[0], of_ports[1])
803 self.verifyFlow(of_ports[0], of_ports[1])
804 self.installFlow(1001, of_ports[1], of_ports[0])
805 self.verifyFlow(of_ports[1], of_ports[0])
806 self.removeFlow(1001)
807 self.verifyFlow(of_ports[0], of_ports[1])
808 self.removeFlow(1000)
809
810
811
812
Dan Talayco551befa2010-07-15 17:05:32 -0700813class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700814 """
815 Exercise wildcard matching for all ports
816
817 Generate a packet
818 Generate and install a matching flow with wildcard mask
819 Add action to forward to a port
820 Send the packet to the port
821 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700822 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700823 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700824 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -0700825 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700826 for wc in WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -0700827 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -0700828 # Set nonzero VLAN id to avoid sending priority-tagged packet
829 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -0700830 else:
831 dl_vlan = -1
832 flow_match_test(self, pa_port_map, wildcards=wc,
833 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700834
Dan Talayco551befa2010-07-15 17:05:32 -0700835class SingleWildcardMatchTagged(BaseMatchCase):
836 """
837 SingleWildcardMatch with tagged packets
838 """
839 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700840 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700841 for wc in WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -0700842 flow_match_test(self, pa_port_map, wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -0700843 max_test=10)
844
845class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700846 """
Dan Talayco80b54ed2010-07-13 09:48:35 -0700847 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -0700848
849 Generate a packet
850 Generate and install a matching flow with wildcard all except one filed
851 Add action to forward to a port
852 Send the packet to the port
853 Verify the packet is received at all other ports (one port at a time)
854 Verify flow_expiration message is correct when command option is set
855 """
856 def runTest(self):
Ken Chiang5be06dd2012-04-03 10:03:50 -0700857 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -0700858 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco4431d542012-03-21 16:42:16 -0700859 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -0700860 # Set nonzero VLAN id to avoid sending priority-tagged packet
861 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -0700862 else:
863 dl_vlan = -1
864 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
865 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -0700866
Dan Talayco551befa2010-07-15 17:05:32 -0700867class AllExceptOneWildcardMatchTagged(BaseMatchCase):
868 """
869 Match one field with tagged packets
870 """
871 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700872 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -0700873 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Dan Talayco21381562010-07-17 00:34:47 -0700874 flow_match_test(self, pa_port_map, wildcards=all_exp_one_wildcard,
875 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -0700876
877class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -0700878 """
879 Create Wildcard-all flow and exercise for all ports
880
881 Generate a packet
882 Generate and install a matching flow with wildcard-all
883 Add action to forward to a port
884 Send the packet to the port
885 Verify the packet is received at all other ports (one port at a time)
886 Verify flow_expiration message is correct when command option is set
887 """
888 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700889 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700890
Dan Talayco551befa2010-07-15 17:05:32 -0700891class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700892 """
Dan Talayco551befa2010-07-15 17:05:32 -0700893 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700894 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700895 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700896 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco21381562010-07-17 00:34:47 -0700897 flow_match_test(self, pa_port_map, wildcards=ofp.OFPFW_ALL,
898 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700899
Dan Talaycoba3745c2010-07-21 21:51:08 -0700900
Dan Talayco551befa2010-07-15 17:05:32 -0700901class AddVLANTag(BaseMatchCase):
902 """
903 Add a VLAN tag to an untagged packet
904 """
905 def runTest(self):
906 new_vid = 2
907 sup_acts = supported_actions_get(self)
908 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700909 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -0700910 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -0700911
Dan Talayco551befa2010-07-15 17:05:32 -0700912 len = 100
913 len_w_vid = 104
914 pkt = simple_tcp_packet(pktlen=len)
915 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
916 dl_vlan=new_vid)
917 vid_act = action.action_set_vlan_vid()
918 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700919
Dan Talayco551befa2010-07-15 17:05:32 -0700920 flow_match_test(self, pa_port_map, pkt=pkt,
921 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700922
Dan Talayco551befa2010-07-15 17:05:32 -0700923class PacketOnly(basic.DataPlaneOnly):
924 """
925 Just send a packet thru the switch
926 """
927 def runTest(self):
928 pkt = simple_tcp_packet()
929 of_ports = pa_port_map.keys()
930 of_ports.sort()
931 ing_port = of_ports[0]
932 pa_logger.info("Sending packet to " + str(ing_port))
933 pa_logger.debug("Data: " + str(pkt).encode('hex'))
934 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700935
Dan Talayco551befa2010-07-15 17:05:32 -0700936class PacketOnlyTagged(basic.DataPlaneOnly):
937 """
938 Just send a packet thru the switch
939 """
940 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700941 vid = test_param_get(self.config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -0700942 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
943 of_ports = pa_port_map.keys()
944 of_ports.sort()
945 ing_port = of_ports[0]
946 pa_logger.info("Sending packet to " + str(ing_port))
947 pa_logger.debug("Data: " + str(pkt).encode('hex'))
948 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700949
Dan Talayco551befa2010-07-15 17:05:32 -0700950test_prio["PacketOnly"] = -1
951test_prio["PacketOnlyTagged"] = -1
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700952
Dan Talayco551befa2010-07-15 17:05:32 -0700953class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700954 """
955 Modify the VLAN ID in the VLAN tag of a tagged packet
956 """
Dan Talayco551befa2010-07-15 17:05:32 -0700957 def runTest(self):
958 old_vid = 2
959 new_vid = 3
960 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -0700961 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700962 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -0700963 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700964
Dan Talayco551befa2010-07-15 17:05:32 -0700965 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
966 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
967 vid_act = action.action_set_vlan_vid()
968 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700969
Dan Talayco551befa2010-07-15 17:05:32 -0700970 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
971 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700972
Dan Talayco551befa2010-07-15 17:05:32 -0700973class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -0700974 """
975 Strip the VLAN tag from a tagged packet
976 """
Dan Talayco551befa2010-07-15 17:05:32 -0700977 def runTest(self):
978 old_vid = 2
979 sup_acts = supported_actions_get(self)
Dan Talayco4b2bee62010-07-20 14:10:05 -0700980 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -0700981 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -0700982 return
Dan Talaycof36f1082010-07-13 13:57:17 -0700983
Dan Talayco551befa2010-07-15 17:05:32 -0700984 len_w_vid = 104
985 len = 100
986 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
987 dl_vlan=old_vid)
988 exp_pkt = simple_tcp_packet(pktlen=len)
989 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700990
Dan Talayco551befa2010-07-15 17:05:32 -0700991 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
992 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -0700993
Dan Talayco4b2bee62010-07-20 14:10:05 -0700994def init_pkt_args():
995 """
996 Pass back a dictionary with default packet arguments
997 """
998 args = {}
999 args["dl_src"] = '00:23:45:67:89:AB'
1000
1001 dl_vlan_enable=False
1002 dl_vlan=-1
1003 if pa_config["test-params"]["vid"]:
1004 dl_vlan_enable=True
1005 dl_vlan = pa_config["test-params"]["vid"]
1006
1007# Unpack operator is ** on a dictionary
1008
1009 return args
1010
Dan Talayco551befa2010-07-15 17:05:32 -07001011class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001012 """
1013 Modify the source MAC address (TP1)
1014 """
Dan Talayco551befa2010-07-15 17:05:32 -07001015 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001016 sup_acts = supported_actions_get(self)
1017 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001018 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001019 return
1020
1021 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1022 check_test_params=True)
1023 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1024 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001025
Dan Talayco551befa2010-07-15 17:05:32 -07001026class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001027 """
1028 Modify the dest MAC address (TP1)
1029 """
Dan Talayco551befa2010-07-15 17:05:32 -07001030 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001031 sup_acts = supported_actions_get(self)
1032 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001033 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001034 return
1035
1036 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1037 check_test_params=True)
1038 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1039 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001040
Dan Talayco551befa2010-07-15 17:05:32 -07001041class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001042 """
1043 Modify the source IP address of an IP packet (TP1)
1044 """
Dan Talayco551befa2010-07-15 17:05:32 -07001045 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001046 sup_acts = supported_actions_get(self)
1047 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001048 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001049 return
1050
1051 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1052 check_test_params=True)
1053 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1054 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001055
Dan Talayco551befa2010-07-15 17:05:32 -07001056class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001057 """
1058 Modify the dest IP address of an IP packet (TP1)
1059 """
Dan Talayco551befa2010-07-15 17:05:32 -07001060 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001061 sup_acts = supported_actions_get(self)
1062 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001063 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001064 return
1065
1066 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1067 check_test_params=True)
1068 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1069 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001070
1071class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001072 """
1073 Modify the source TCP port of a TCP packet (TP1)
1074 """
Dan Talayco551befa2010-07-15 17:05:32 -07001075 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001076 sup_acts = supported_actions_get(self)
1077 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001078 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001079 return
1080
1081 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1082 check_test_params=True)
1083 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1084 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001085
1086class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001087 """
1088 Modify the dest TCP port of a TCP packet (TP1)
1089 """
Dan Talayco551befa2010-07-15 17:05:32 -07001090 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001091 sup_acts = supported_actions_get(self)
1092 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001093 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001094 return
1095
1096 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1097 check_test_params=True)
1098 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1099 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001100
1101class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001102 """
1103 Modify the IP type of service of an IP packet (TP1)
1104 """
Dan Talayco551befa2010-07-15 17:05:32 -07001105 def runTest(self):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001106 sup_acts = supported_actions_get(self)
1107 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001108 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001109 return
Dan Talayco551befa2010-07-15 17:05:32 -07001110
Dan Talayco4b2bee62010-07-20 14:10:05 -07001111 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1112 check_test_params=True)
1113 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001114 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001115
Dan Talaycof6e76c02012-03-23 10:56:12 -07001116class ModifyL2DstMC(BaseMatchCase):
1117 """
1118 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001119 """
1120 def runTest(self):
1121 sup_acts = supported_actions_get(self)
1122 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001123 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001124 return
1125
Dan Talaycof6e76c02012-03-23 10:56:12 -07001126 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1127 check_test_params=True)
1128 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001129 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001130
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001131class ModifyL2DstIngress(BaseMatchCase):
1132 """
1133 Modify the L2 dest and send to the ingress port
1134 """
1135 def runTest(self):
1136 sup_acts = supported_actions_get(self)
1137 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001138 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001139 return
1140
1141 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1142 check_test_params=True)
1143 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1144 action_list=acts, max_test=2, egr_count=0,
1145 ing_port=True)
1146
Dan Talaycod8ae7582012-03-23 12:24:56 -07001147class ModifyL2DstIngressMC(BaseMatchCase):
1148 """
1149 Modify the L2 dest and send to the ingress port
1150 """
1151 def runTest(self):
1152 sup_acts = supported_actions_get(self)
1153 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1154 skip_message_emit(self, "ModifyL2dstMC test")
1155 return
1156
1157 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1158 check_test_params=True)
1159 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1160 action_list=acts, max_test=2, egr_count=-1,
1161 ing_port=True)
1162
Dan Talaycof6e76c02012-03-23 10:56:12 -07001163class ModifyL2SrcMC(BaseMatchCase):
1164 """
1165 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001166 """
1167 def runTest(self):
1168 sup_acts = supported_actions_get(self)
1169 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001170 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001171 return
1172
Dan Talaycof6e76c02012-03-23 10:56:12 -07001173 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1174 check_test_params=True)
1175 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001176 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001177
1178class ModifyL2SrcDstMC(BaseMatchCase):
1179 """
1180 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001181 """
1182 def runTest(self):
1183 sup_acts = supported_actions_get(self)
Dan Talaycocfa172f2012-03-23 12:03:00 -07001184 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1185 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1186 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001187 return
1188
Dan Talaycof6e76c02012-03-23 10:56:12 -07001189 mod_fields = ['dl_dst', 'dl_src']
1190 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1191 check_test_params=True)
1192 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001193 action_list=acts, max_test=2, egr_count=-1)
1194
1195class ModifyL2DstVIDMC(BaseMatchCase):
1196 """
1197 Modify the L2 dest and send to 2 ports
1198 """
1199 def runTest(self):
1200 sup_acts = supported_actions_get(self)
1201 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1202 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1203 skip_message_emit(self, "ModifyL2DstVIDMC test")
1204 return
1205
1206 mod_fields = ['dl_dst', 'dl_vlan']
1207 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1208 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1209 check_test_params=True)
1210 flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
1211 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001212
Dan Talaycofa6454f2012-04-05 10:04:13 -07001213class FlowToggle(BaseMatchCase):
1214 """
1215 Add flows to the table and modify them repeatedly
1216 """
1217 def runTest(self):
Dan Talayco50be7672012-04-05 11:38:08 -07001218 flow_count = test_param_get(self.config, 'ft_flow_count', default=20)
1219 iter_count = test_param_get(self.config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001220
1221 pa_logger.info("Running flow toggle with %d flows, %d iterations" %
1222 (flow_count, iter_count))
1223 acts = []
1224 acts.append(action.action_output())
1225 acts.append(action.action_output())
1226
1227 of_ports = pa_port_map.keys()
1228 if len(of_ports) < 3:
1229 self.assertTrue(False, "Too few ports for test")
1230
1231 for idx in range(2):
1232 acts[idx].port = of_ports[idx]
1233
1234 flows = []
1235 flows.append([])
1236 flows.append([])
1237
Dan Talayco50be7672012-04-05 11:38:08 -07001238 wildcards = ofp.OFPFW_DL_SRC | ofp.OFPFW_DL_DST
Dan Talaycofa6454f2012-04-05 10:04:13 -07001239 # Create up the flows in an array
1240 for toggle in range(2):
1241 for f_idx in range(flow_count):
1242 pkt = simple_tcp_packet(tcp_sport=f_idx)
1243 msg = message.flow_mod()
1244 match = parse.packet_to_flow_match(pkt)
1245 match.in_port = of_ports[3]
Dan Talayco50be7672012-04-05 11:38:08 -07001246 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001247 msg.match = match
1248 msg.buffer_id = 0xffffffff
1249 msg.actions.add(acts[toggle])
1250 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001251
1252 # Show two sample flows
1253 pa_logger.debug(flows[0][0].show())
1254 pa_logger.debug(flows[1][0].show())
1255
Dan Talaycofa6454f2012-04-05 10:04:13 -07001256 # Install the first set of flows
1257 for f_idx in range(flow_count):
1258 rv = self.controller.message_send(flows[0][f_idx])
1259 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001260 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001261
1262 pa_logger.info("Installed %d flows" % flow_count)
1263
1264 # Repeatedly modify all the flows back and forth
1265 updates = 0
1266 # Report status about 5 times
1267 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001268 start = time.time()
1269 for iter_idx in range(iter_count):
1270 if not iter_idx % mod_val:
1271 pa_logger.info("Flow Toggle: iter %d of %d. " %
1272 (iter_idx, iter_count) +
1273 "%d updates in %d secs" %
1274 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001275 for toggle in range(2):
1276 t_idx = 1 - toggle
1277 for f_idx in range(flow_count):
1278 rv = self.controller.message_send(flows[t_idx][f_idx])
1279 updates += 1
1280 self.assertTrue(rv != -1, "Error modifying flow %d" %
1281 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001282 self.assertEqual(do_barrier(self.controller), 0,
1283 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001284
1285 end = time.time()
1286 divisor = end - start or (end - start + 1)
1287 pa_logger.info("Flow toggle: %d iterations" % iter_count)
1288 pa_logger.info(" %d flow mods in %d secs, %d mods/sec" %
1289 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001290
1291
Dan Talayco8a64e332012-03-28 14:53:20 -07001292# You can pick and choose these by commenting tests in or out
1293iter_classes = [
1294 basic.PacketIn,
1295 basic.PacketOut,
1296 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001297 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001298 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001299 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001300 AllWildcardMatch,
1301 AllWildcardMatchTagged,
1302 SingleWildcardMatch,
1303 SingleWildcardMatchTagged,
1304 ExactMatch,
1305 ExactMatchTagged,
1306 SingleWildcardMatch,
1307 ModifyL2Src,
1308 ModifyL2Dst,
1309 ModifyL2SrcMC,
1310 ModifyL2DstMC,
1311 ModifyL2SrcDstMC
1312 ]
1313
1314class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001315 """
1316 Iterate over a bunch of test cases
1317
1318 The cases come from the list above
1319 """
1320
Dan Talayco8a64e332012-03-28 14:53:20 -07001321 def runTest(self):
1322 count = test_param_get(self.config, 'iter_count', default=10)
1323 tests_done = 0
1324 pa_logger.info("Running iteration test " + str(count) + " times")
1325 start = time.time()
1326 last = start
1327 for idx in range(count):
1328 pa_logger.info("Iteration " + str(idx + 1))
1329 for cls in iter_classes:
1330 test = cls()
1331 test.inheritSetup(self)
1332 test.runTest()
1333 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001334 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001335 if time.time() - last > 60:
1336 last = time.time()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001337 pa_logger.info(
1338 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1339 (idx, count, tests_done, last - start) +
1340 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001341 stats = all_stats_get(self)
1342 last = time.time()
1343 pa_logger.info("\nIterCases ran %d tests in %d seconds." %
1344 (tests_done, last - start))
1345 pa_logger.info(" flows: %d. packets: %d. bytes: %d" %
1346 (stats["flows"], stats["packets"], stats["bytes"]))
1347 pa_logger.info(" active: %d. lookups: %d. matched %d." %
1348 (stats["active"], stats["lookups"], stats["matched"]))
1349
1350# Don't run by default
1351test_prio["IterCases"] = -1
Dan Talaycof6e76c02012-03-23 10:56:12 -07001352
Dan Talayco4b2bee62010-07-20 14:10:05 -07001353#@todo Need to implement tagged versions of the above tests
1354#
1355#@todo Implement a test case that strips tag 2, adds tag 3
1356# and modifies tag 4 to tag 5. Then verify (in addition) that
1357# tag 6 does not get modified.
1358
1359class MixedVLAN(BaseMatchCase):
1360 """
1361 Test mixture of VLAN tag actions
1362
1363 Strip tag 2 on port 1, send to port 2
1364 Add tag 3 on port 1, send to port 2
1365 Modify tag 4 to 5 on port 1, send to port 2
1366 All other traffic from port 1, send to port 3
1367 All traffic from port 2 sent to port 4
1368 Use exact matches with different packets for all mods
1369 Verify the following: (port, vid)
1370 (port 1, vid 2) => VLAN tag stripped, out port 2
1371 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1372 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1373 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1374 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1375 (port 2, no tag) => untagged packet out port 4
1376 (port 2, vid 2-6) => unmodified packet out port 4
1377
1378 Variation: Might try sending VID 5 to port 3 and check.
1379 If only VID 5 distinguishes pkt, this will fail on some platforms
1380 """
1381
1382test_prio["MixedVLAN"] = -1
1383
Dan Talayco551befa2010-07-15 17:05:32 -07001384def supported_actions_get(parent, use_cache=True):
1385 """
1386 Get the bitmap of supported actions from the switch
1387 If use_cache is false, the cached value will be updated
1388 """
1389 global cached_supported_actions
1390 if cached_supported_actions is None or not use_cache:
1391 request = message.features_request()
1392 (reply, pkt) = parent.controller.transact(request, timeout=2)
1393 parent.assertTrue(reply is not None, "Did not get response to ftr req")
1394 cached_supported_actions = reply.actions
1395 pa_logger.info("Supported actions: " + hex(cached_supported_actions))
1396
1397 return cached_supported_actions
Tatsuya Yabe9c31e222010-06-16 13:48:02 -07001398
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001399if __name__ == "__main__":
1400 print "Please run through oft script: ./oft --test_spec=basic"