blob: 76dea36862a52db2ba991dbef2b56d56085ba230 [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
Rich Lane477f4812012-10-04 22:49:00 -070010The switch is actively attempting to contact the controller at the address
11indicated in config.
Dan Talayco5eba8442010-03-10 13:58:43 -080012
13"""
14
Dan Talayco9f47f4d2010-06-03 13:54:37 -070015import copy
Dan Talayco5eba8442010-03-10 13:58:43 -080016import logging
Rich Laneb90a1c42012-10-05 09:16:05 -070017import time
Dan Talayco5eba8442010-03-10 13:58:43 -080018import unittest
19
Rich Lane477f4812012-10-04 22:49:00 -070020from oftest import config
Dan Talayco5eba8442010-03-10 13:58:43 -080021import oftest.controller as controller
22import oftest.cstruct as ofp
23import oftest.message as message
24import oftest.dataplane as dataplane
25import oftest.action as action
26import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070027import oftest.base_tests as base_tests
28import basic # for IterCases
Dan Talayco5eba8442010-03-10 13:58:43 -080029
Rich Laneda3b5ad2012-10-03 09:05:32 -070030from oftest.testutils import *
Dan Talayco5eba8442010-03-10 13:58:43 -080031
Dan Talayco551befa2010-07-15 17:05:32 -070032WILDCARD_VALUES = [ofp.OFPFW_IN_PORT,
Dan Talayco488fbc52012-04-09 16:30:41 -070033 ofp.OFPFW_DL_VLAN | ofp.OFPFW_DL_VLAN_PCP,
Dan Talayco551befa2010-07-15 17:05:32 -070034 ofp.OFPFW_DL_SRC,
35 ofp.OFPFW_DL_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070036 (ofp.OFPFW_DL_TYPE | ofp.OFPFW_NW_SRC_ALL |
37 ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS | ofp.OFPFW_NW_PROTO |
38 ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
39 (ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
Dan Talayco551befa2010-07-15 17:05:32 -070040 ofp.OFPFW_TP_SRC,
41 ofp.OFPFW_TP_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070042 ofp.OFPFW_NW_SRC_MASK,
43 ofp.OFPFW_NW_DST_MASK,
Dan Talayco551befa2010-07-15 17:05:32 -070044 ofp.OFPFW_DL_VLAN_PCP,
45 ofp.OFPFW_NW_TOS]
46
Dan Talayco488fbc52012-04-09 16:30:41 -070047NO_WILDCARD_VALUES = [(ofp.OFPFW_ALL ^ ofp.OFPFW_IN_PORT),
48 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_VLAN),
49 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_SRC),
50 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_DST),
51 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE),
52 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO),
53 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
54 ofp.OFPFW_TP_SRC),
55 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
56 ofp.OFPFW_TP_DST),
57 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
58 ofp.OFPFW_NW_SRC_MASK),
59 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
60 ofp.OFPFW_NW_DST_MASK),
61 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_VLAN ^ ofp.OFPFW_DL_VLAN_PCP),
62 (ofp.OFPFW_ALL ^ ofp.OFPFW_DL_TYPE ^ ofp.OFPFW_NW_PROTO ^
63 ofp.OFPFW_NW_TOS)]
64
Dan Talayco551befa2010-07-15 17:05:32 -070065MODIFY_ACTION_VALUES = [ofp.OFPAT_SET_VLAN_VID,
66 ofp.OFPAT_SET_VLAN_PCP,
67 ofp.OFPAT_STRIP_VLAN,
68 ofp.OFPAT_SET_DL_SRC,
69 ofp.OFPAT_SET_DL_DST,
70 ofp.OFPAT_SET_NW_SRC,
71 ofp.OFPAT_SET_NW_DST,
72 ofp.OFPAT_SET_NW_TOS,
73 ofp.OFPAT_SET_TP_SRC,
74 ofp.OFPAT_SET_TP_DST]
75
Dan Talayco21381562010-07-17 00:34:47 -070076TEST_VID_DEFAULT = 2
77
Rich Laneb90a1c42012-10-05 09:16:05 -070078class DirectPacket(base_tests.SimpleDataPlane):
Dan Talayco5eba8442010-03-10 13:58:43 -080079 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -070080 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -080081
82 Generate a packet
83 Generate and install a matching flow
84 Add action to direct the packet to an egress port
85 Send the packet to ingress dataplane port
86 Verify the packet is received at the egress port only
87 """
88 def runTest(self):
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -070089 self.handleFlow()
90
91 def handleFlow(self, pkttype='TCP'):
Rich Lane477f4812012-10-04 22:49:00 -070092 of_ports = config["port_map"].keys()
Dan Talayco5eba8442010-03-10 13:58:43 -080093 of_ports.sort()
94 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
95
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -070096 if (pkttype == 'ICMP'):
97 pkt = simple_icmp_packet()
98 else:
99 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700100 match = packet_to_flow_match(self, pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -0700101 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -0800102 self.assertTrue(match is not None,
103 "Could not generate flow match from pkt")
104 act = action.action_output()
105
106 for idx in range(len(of_ports)):
Rich Lane9a003812012-10-04 17:17:59 -0700107 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700108 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700109
Dan Talayco5eba8442010-03-10 13:58:43 -0800110 ingress_port = of_ports[idx]
111 egress_port = of_ports[(idx + 1) % len(of_ports)]
Rich Lane9a003812012-10-04 17:17:59 -0700112 logging.info("Ingress " + str(ingress_port) +
Dan Talayco551befa2010-07-15 17:05:32 -0700113 " to egress " + str(egress_port))
Dan Talayco5eba8442010-03-10 13:58:43 -0800114
115 match.in_port = ingress_port
116
117 request = message.flow_mod()
118 request.match = match
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700119
Dan Talayco5eba8442010-03-10 13:58:43 -0800120 request.buffer_id = 0xffffffff
121 act.port = egress_port
122 self.assertTrue(request.actions.add(act), "Could not add action")
123
Rich Lane9a003812012-10-04 17:17:59 -0700124 logging.info("Inserting flow")
Dan Talayco5eba8442010-03-10 13:58:43 -0800125 rv = self.controller.message_send(request)
126 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700127 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco5eba8442010-03-10 13:58:43 -0800128
Rich Lane9a003812012-10-04 17:17:59 -0700129 logging.info("Sending packet to dp port " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800130 str(ingress_port))
131 self.dataplane.send(ingress_port, str(pkt))
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700132
133 exp_pkt_arg = None
134 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -0700135 if config["relax"]:
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700136 exp_pkt_arg = pkt
137 exp_port = egress_port
138
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700139 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Dan Talaycocf26b7a2011-08-05 10:15:35 -0700140 exp_pkt=exp_pkt_arg)
Dan Talayco5eba8442010-03-10 13:58:43 -0800141 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Rich Lane9a003812012-10-04 17:17:59 -0700142 logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800143 str(rcv_port))
144 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
145 self.assertEqual(str(pkt), str(rcv_pkt),
146 'Response packet does not match send packet')
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700147
Rich Laneb90a1c42012-10-05 09:16:05 -0700148class DirectPacketController(base_tests.SimpleDataPlane):
Rich Lane51c23b32012-07-27 16:37:25 -0700149 """
150 Send packet to the controller port
151
152 Generate a packet
153 Generate and install a matching flow
154 Add action to direct the packet to the controller port
155 Send the packet to ingress dataplane port
156 Verify the packet is received at the controller port
157 """
158 def runTest(self):
159 self.handleFlow()
160
161 def handleFlow(self, pkttype='TCP'):
Rich Lane477f4812012-10-04 22:49:00 -0700162 of_ports = config["port_map"].keys()
Rich Lane51c23b32012-07-27 16:37:25 -0700163 of_ports.sort()
164 self.assertTrue(len(of_ports) > 0, "Not enough ports for test")
165
166 if (pkttype == 'ICMP'):
167 pkt = simple_icmp_packet()
168 else:
169 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700170 match = packet_to_flow_match(self, pkt)
Rich Lane51c23b32012-07-27 16:37:25 -0700171 match.wildcards &= ~ofp.OFPFW_IN_PORT
172 self.assertTrue(match is not None,
173 "Could not generate flow match from pkt")
174 act = action.action_output()
175
Rich Lane9a003812012-10-04 17:17:59 -0700176 rv = delete_all_flows(self.controller)
Rich Lane51c23b32012-07-27 16:37:25 -0700177 self.assertEqual(rv, 0, "Failed to delete all flows")
178
179 ingress_port = of_ports[0]
180 match.in_port = ingress_port
181
182 request = message.flow_mod()
183 request.match = match
184
185 request.buffer_id = 0xffffffff
186 act.port = ofp.OFPP_CONTROLLER
187 act.max_len = 65535
188 self.assertTrue(request.actions.add(act), "Could not add action")
189
Rich Lane9a003812012-10-04 17:17:59 -0700190 logging.info("Inserting flow")
Rich Lane51c23b32012-07-27 16:37:25 -0700191 rv = self.controller.message_send(request)
192 self.assertTrue(rv != -1, "Error installing flow mod")
193 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
194
Rich Lane9a003812012-10-04 17:17:59 -0700195 logging.info("Sending packet to dp port " +
Rich Lane51c23b32012-07-27 16:37:25 -0700196 str(ingress_port))
197 self.dataplane.send(ingress_port, str(pkt))
198
199 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
200
201 self.assertTrue(response is not None,
202 'Packet in message not received by controller')
203 if not dataplane.match_exp_pkt(pkt, response.data):
Rich Lane9a003812012-10-04 17:17:59 -0700204 logging.debug("Sent %s" % format_packet(pkt))
205 logging.debug("Resp %s" % format_packet(response.data))
Rich Lane51c23b32012-07-27 16:37:25 -0700206 self.assertTrue(False,
207 'Response packet does not match send packet' +
208 ' for controller port')
209
Howard Pershf97840f2012-04-10 16:30:42 -0700210
Rich Laneb90a1c42012-10-05 09:16:05 -0700211class DirectPacketQueue(base_tests.SimpleDataPlane):
Howard Pershf97840f2012-04-10 16:30:42 -0700212 """
213 Send packet to single queue on single egress port
214
215 Generate a packet
216 Generate and install a matching flow
217 Add action to direct the packet to an egress port and queue
218 Send the packet to ingress dataplane port
219 Verify the packet is received at the egress port only
220 """
221 def runTest(self):
222 self.handleFlow()
223
Howard Persh670b5672012-04-13 09:08:29 -0700224 def portQueuesGet(self, queue_stats, port_num):
225 result = []
226 for qs in queue_stats.stats:
227 if qs.port_no != port_num:
228 continue
229 result.append(qs.queue_id)
230 return result
231
Howard Pershf97840f2012-04-10 16:30:42 -0700232 def handleFlow(self, pkttype='TCP'):
Rich Lane477f4812012-10-04 22:49:00 -0700233 of_ports = config["port_map"].keys()
Howard Pershf97840f2012-04-10 16:30:42 -0700234 of_ports.sort()
235 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
236
237 if (pkttype == 'ICMP'):
238 pkt = simple_icmp_packet()
239 else:
240 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700241 match = packet_to_flow_match(self, pkt)
Howard Pershf97840f2012-04-10 16:30:42 -0700242 match.wildcards &= ~ofp.OFPFW_IN_PORT
243 self.assertTrue(match is not None,
244 "Could not generate flow match from pkt")
245
Howard Persh670b5672012-04-13 09:08:29 -0700246 # Get queue stats from switch
247
248 request = message.queue_stats_request()
249 request.port_no = ofp.OFPP_ALL
250 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700251 (queue_stats, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700252 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
253
254 act = action.action_enqueue()
Howard Pershf97840f2012-04-10 16:30:42 -0700255
256 for idx in range(len(of_ports)):
Howard Pershf97840f2012-04-10 16:30:42 -0700257 ingress_port = of_ports[idx]
258 egress_port = of_ports[(idx + 1) % len(of_ports)]
Howard Pershf97840f2012-04-10 16:30:42 -0700259
Howard Persh670b5672012-04-13 09:08:29 -0700260 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
Rich Lane9a003812012-10-04 17:17:59 -0700261 logging.info("Ingress " + str(ingress_port)
Howard Persh670b5672012-04-13 09:08:29 -0700262 + " to egress " + str(egress_port)
263 + " queue " + str(egress_queue_id)
264 )
Howard Pershf97840f2012-04-10 16:30:42 -0700265
Rich Lane9a003812012-10-04 17:17:59 -0700266 rv = delete_all_flows(self.controller)
Howard Persh670b5672012-04-13 09:08:29 -0700267 self.assertEqual(rv, 0, "Failed to delete all flows")
Howard Pershf97840f2012-04-10 16:30:42 -0700268
Howard Persh670b5672012-04-13 09:08:29 -0700269 match.in_port = ingress_port
270
271 request = message.flow_mod()
272 request.match = match
Howard Pershf97840f2012-04-10 16:30:42 -0700273
Howard Persh670b5672012-04-13 09:08:29 -0700274 request.buffer_id = 0xffffffff
275 act.port = egress_port
276 act.queue_id = egress_queue_id
277 self.assertTrue(request.actions.add(act), "Could not add action")
Howard Pershf97840f2012-04-10 16:30:42 -0700278
Rich Lane9a003812012-10-04 17:17:59 -0700279 logging.info("Inserting flow")
Howard Persh670b5672012-04-13 09:08:29 -0700280 rv = self.controller.message_send(request)
281 self.assertTrue(rv != -1, "Error installing flow mod")
282 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Howard Pershf97840f2012-04-10 16:30:42 -0700283
Howard Persh670b5672012-04-13 09:08:29 -0700284 # Get current stats for selected egress queue
Howard Pershf97840f2012-04-10 16:30:42 -0700285
Howard Persh670b5672012-04-13 09:08:29 -0700286 request = message.queue_stats_request()
287 request.port_no = egress_port
288 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700289 (qs_before, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700290 self.assertNotEqual(qs_before, None, "Queue stats request failed")
291
Rich Lane9a003812012-10-04 17:17:59 -0700292 logging.info("Sending packet to dp port " +
Howard Persh670b5672012-04-13 09:08:29 -0700293 str(ingress_port))
294 self.dataplane.send(ingress_port, str(pkt))
295
296 exp_pkt_arg = None
297 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -0700298 if config["relax"]:
Howard Persh670b5672012-04-13 09:08:29 -0700299 exp_pkt_arg = pkt
300 exp_port = egress_port
301
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700302 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Howard Persh670b5672012-04-13 09:08:29 -0700303 exp_pkt=exp_pkt_arg)
304 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Rich Lane9a003812012-10-04 17:17:59 -0700305 logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Howard Persh670b5672012-04-13 09:08:29 -0700306 str(rcv_port))
307 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
308 self.assertEqual(str(pkt), str(rcv_pkt),
309 'Response packet does not match send packet')
310
Ed Swierkb8a86512012-04-18 18:45:58 -0700311 # FIXME: instead of sleeping, keep requesting queue stats until
312 # the expected queue counter increases or some large timeout is
313 # reached
314 time.sleep(2)
315
Howard Persh670b5672012-04-13 09:08:29 -0700316 # Get current stats for selected egress queue again
317
318 request = message.queue_stats_request()
319 request.port_no = egress_port
320 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700321 (qs_after, p) = self.controller.transact(request)
Howard Persh670b5672012-04-13 09:08:29 -0700322 self.assertNotEqual(qs_after, None, "Queue stats request failed")
323
324 # Make sure that tx packet counter for selected egress queue was
325 # incremented
326
Ed Swierk22f59152012-04-17 16:36:47 -0700327 self.assertEqual(qs_after.stats[0].tx_packets, \
328 qs_before.stats[0].tx_packets + 1, \
Howard Persh670b5672012-04-13 09:08:29 -0700329 "Verification of egress queue tx packet count failed"
330 )
331
332
Rich Laneb90a1c42012-10-05 09:16:05 -0700333class DirectPacketControllerQueue(base_tests.SimpleDataPlane):
Ken Chiang899ff8e2012-05-23 18:26:12 -0700334 """
335 Send a packet from each of the openflow ports
336 to each of the queues configured on the controller port.
337 If no queues have been configured, no packets are sent.
Howard Pershf97840f2012-04-10 16:30:42 -0700338
Ken Chiang899ff8e2012-05-23 18:26:12 -0700339 Generate a packet
340 Generate and install a matching flow
341 Add action to direct the packet to one of the controller port queues
342 Send the packet to ingress dataplane port
343 Verify the packet is received on the controller port queue
344 """
345 def runTest(self):
346 self.handleFlow()
347
348 def portQueuesGet(self, queue_stats, port_num):
349 result = []
350 for qs in queue_stats.stats:
351 if qs.port_no != port_num:
352 continue
353 result.append(qs.queue_id)
354 return result
355
356 def handleFlow(self, pkttype='TCP'):
Rich Lane477f4812012-10-04 22:49:00 -0700357 of_ports = config["port_map"].keys()
Ken Chiang899ff8e2012-05-23 18:26:12 -0700358 of_ports.sort()
359 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
360
361 if (pkttype == 'ICMP'):
362 pkt = simple_icmp_packet()
363 else:
364 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700365 match = packet_to_flow_match(self, pkt)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700366 match.wildcards &= ~ofp.OFPFW_IN_PORT
367 self.assertTrue(match is not None,
368 "Could not generate flow match from pkt")
369
370 # Get queue stats from switch
371
372 request = message.queue_stats_request()
373 request.port_no = ofp.OFPP_CONTROLLER
374 request.queue_id = ofp.OFPQ_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700375 (queue_stats, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700376 self.assertNotEqual(queue_stats, None, "Queue stats request failed")
377
378 act = action.action_enqueue()
379
380 for idx in range(len(of_ports)):
381 ingress_port = of_ports[idx]
382 egress_port = ofp.OFPP_CONTROLLER
383
Rich Lane9a003812012-10-04 17:17:59 -0700384 logging.info("Ingress port " + str(ingress_port)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700385 + ", controller port queues "
386 + str(self.portQueuesGet(queue_stats, egress_port)))
387
388 for egress_queue_id in self.portQueuesGet(queue_stats, egress_port):
Rich Lane9a003812012-10-04 17:17:59 -0700389 logging.info("Ingress " + str(ingress_port)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700390 + " to egress " + str(egress_port)
391 + " queue " + str(egress_queue_id)
392 )
393
Rich Lane9a003812012-10-04 17:17:59 -0700394 rv = delete_all_flows(self.controller)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700395 self.assertEqual(rv, 0, "Failed to delete all flows")
396
397 match.in_port = ingress_port
398
399 request = message.flow_mod()
400 request.match = match
401
402 request.buffer_id = 0xffffffff
403 act.port = egress_port
404 act.queue_id = egress_queue_id
405 self.assertTrue(request.actions.add(act), "Could not add action")
406
Rich Lane9a003812012-10-04 17:17:59 -0700407 logging.info("Inserting flow")
Ken Chiang899ff8e2012-05-23 18:26:12 -0700408 rv = self.controller.message_send(request)
409 self.assertTrue(rv != -1, "Error installing flow mod")
410 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
411
412 # Get current stats for selected egress queue
413
414 request = message.queue_stats_request()
415 request.port_no = egress_port
416 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700417 (qs_before, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700418 self.assertNotEqual(qs_before, None, "Queue stats request failed")
419
Rich Lane9a003812012-10-04 17:17:59 -0700420 logging.info("Sending packet to dp port " +
Ken Chiang899ff8e2012-05-23 18:26:12 -0700421 str(ingress_port))
422 self.dataplane.send(ingress_port, str(pkt))
423
424 exp_pkt_arg = None
425 exp_port = None
426
427 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700428 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700429 if not response: # Timeout
430 break
431 if dataplane.match_exp_pkt(pkt, response.data): # Got match
432 break
Rich Lane477f4812012-10-04 22:49:00 -0700433 if not config["relax"]: # Only one attempt to match
Ken Chiang899ff8e2012-05-23 18:26:12 -0700434 break
435 count += 1
436 if count > 10: # Too many tries
437 break
438
439 self.assertTrue(response is not None,
440 'Packet in message not received by controller')
441 if not dataplane.match_exp_pkt(pkt, response.data):
Rich Lane9a003812012-10-04 17:17:59 -0700442 logging.debug("Sent %s" % format_packet(pkt))
443 logging.debug("Resp %s" % format_packet(response.data))
Ken Chiang899ff8e2012-05-23 18:26:12 -0700444 self.assertTrue(False,
445 'Response packet does not match send packet' +
446 ' for controller port')
447
448 # FIXME: instead of sleeping, keep requesting queue stats until
449 # the expected queue counter increases or some large timeout is
450 # reached
451 time.sleep(2)
452
453 # Get current stats for selected egress queue again
454
455 request = message.queue_stats_request()
456 request.port_no = egress_port
457 request.queue_id = egress_queue_id
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700458 (qs_after, p) = self.controller.transact(request)
Ken Chiang899ff8e2012-05-23 18:26:12 -0700459 self.assertNotEqual(qs_after, None, "Queue stats request failed")
460
461 # Make sure that tx packet counter for selected egress queue was
462 # incremented
463
464 self.assertEqual(qs_after.stats[0].tx_packets, \
465 qs_before.stats[0].tx_packets + 1, \
466 "Verification of egress queue tx packet count failed"
467 )
468
Howard Pershf97840f2012-04-10 16:30:42 -0700469
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -0700470class DirectPacketICMP(DirectPacket):
471 """
472 Send ICMP packet to single egress port
473
474 Generate a ICMP packet
475 Generate and install a matching flow
476 Add action to direct the packet to an egress port
477 Send the packet to ingress dataplane port
478 Verify the packet is received at the egress port only
479 Difference from DirectPacket test is that sent packet is ICMP
480 """
481 def runTest(self):
482 self.handleFlow(pkttype='ICMP')
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700483
Rich Laneb90a1c42012-10-05 09:16:05 -0700484class DirectTwoPorts(base_tests.SimpleDataPlane):
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700485 """
486 Send packet to two egress ports
487
488 Generate a packet
489 Generate and install a matching flow
490 Add action to direct the packet to two egress ports
491 Send the packet to ingress dataplane port
492 Verify the packet is received at the two egress ports
493 """
494 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700495 of_ports = config["port_map"].keys()
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700496 of_ports.sort()
497 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
498
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700499 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700500 match = packet_to_flow_match(self, pkt)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700501 match.wildcards &= ~ofp.OFPFW_IN_PORT
502 self.assertTrue(match is not None,
503 "Could not generate flow match from pkt")
504 act = action.action_output()
505
506 for idx in range(len(of_ports)):
Rich Lane9a003812012-10-04 17:17:59 -0700507 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700508 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700509
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700510 ingress_port = of_ports[idx]
511 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
512 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
Rich Lane9a003812012-10-04 17:17:59 -0700513 logging.info("Ingress " + str(ingress_port) +
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700514 " to egress " + str(egress_port1) + " and " +
515 str(egress_port2))
516
517 match.in_port = ingress_port
518
519 request = message.flow_mod()
520 request.match = match
521 request.buffer_id = 0xffffffff
522 act.port = egress_port1
523 self.assertTrue(request.actions.add(act), "Could not add action1")
524 act.port = egress_port2
525 self.assertTrue(request.actions.add(act), "Could not add action2")
Rich Lane9a003812012-10-04 17:17:59 -0700526 # logging.info(request.show())
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700527
Rich Lane9a003812012-10-04 17:17:59 -0700528 logging.info("Inserting flow")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700529 rv = self.controller.message_send(request)
530 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700531 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700532
Rich Lane9a003812012-10-04 17:17:59 -0700533 logging.info("Sending packet to dp port " +
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700534 str(ingress_port))
535 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700536 yes_ports = set([egress_port1, egress_port2])
537 no_ports = set(of_ports).difference(yes_ports)
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700538
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700539 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
Rich Lane477f4812012-10-04 22:49:00 -0700540 self, config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700541
Rich Laneb90a1c42012-10-05 09:16:05 -0700542class DirectMCNonIngress(base_tests.SimpleDataPlane):
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700543 """
544 Multicast to all non-ingress ports
545
546 Generate a packet
547 Generate and install a matching flow
548 Add action to direct the packet to all non-ingress ports
549 Send the packet to ingress dataplane port
550 Verify the packet is received at all non-ingress ports
551
552 Does not use the flood action
553 """
554 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700555 of_ports = config["port_map"].keys()
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700556 of_ports.sort()
557 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
558
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700559 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700560 match = packet_to_flow_match(self, pkt)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700561 match.wildcards &= ~ofp.OFPFW_IN_PORT
562 self.assertTrue(match is not None,
563 "Could not generate flow match from pkt")
564 act = action.action_output()
565
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700566 for ingress_port in of_ports:
Rich Lane9a003812012-10-04 17:17:59 -0700567 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700568 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700569
Rich Lane9a003812012-10-04 17:17:59 -0700570 logging.info("Ingress " + str(ingress_port) +
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700571 " all non-ingress ports")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700572 match.in_port = ingress_port
573
574 request = message.flow_mod()
575 request.match = match
576 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700577 for egress_port in of_ports:
578 if egress_port == ingress_port:
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700579 continue
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700580 act.port = egress_port
581 self.assertTrue(request.actions.add(act),
582 "Could not add output to " + str(egress_port))
Rich Lane9a003812012-10-04 17:17:59 -0700583 logging.debug(request.show())
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700584
Rich Lane9a003812012-10-04 17:17:59 -0700585 logging.info("Inserting flow")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700586 rv = self.controller.message_send(request)
587 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700588 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700589
Rich Lane9a003812012-10-04 17:17:59 -0700590 logging.info("Sending packet to dp port " + str(ingress_port))
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700591 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700592 yes_ports = set(of_ports).difference([ingress_port])
593 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Rich Lane477f4812012-10-04 22:49:00 -0700594 self, config)
Dan Talaycob0b0fdb2010-05-11 15:44:56 -0700595
Dan Talayco32fa6542010-05-11 15:54:08 -0700596
Rich Laneb90a1c42012-10-05 09:16:05 -0700597class DirectMC(base_tests.SimpleDataPlane):
Dan Talayco32fa6542010-05-11 15:54:08 -0700598 """
599 Multicast to all ports including ingress
600
601 Generate a packet
602 Generate and install a matching flow
603 Add action to direct the packet to all non-ingress ports
604 Send the packet to ingress dataplane port
605 Verify the packet is received at all ports
606
607 Does not use the flood action
608 """
609 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700610 of_ports = config["port_map"].keys()
Dan Talayco32fa6542010-05-11 15:54:08 -0700611 of_ports.sort()
612 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
613
Dan Talayco32fa6542010-05-11 15:54:08 -0700614 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700615 match = packet_to_flow_match(self, pkt)
Dan Talayco32fa6542010-05-11 15:54:08 -0700616 match.wildcards &= ~ofp.OFPFW_IN_PORT
617 self.assertTrue(match is not None,
618 "Could not generate flow match from pkt")
619 act = action.action_output()
620
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700621 for ingress_port in of_ports:
Rich Lane9a003812012-10-04 17:17:59 -0700622 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700623 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700624
Rich Lane9a003812012-10-04 17:17:59 -0700625 logging.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco32fa6542010-05-11 15:54:08 -0700626 match.in_port = ingress_port
627
628 request = message.flow_mod()
629 request.match = match
630 request.buffer_id = 0xffffffff
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700631 for egress_port in of_ports:
632 if egress_port == ingress_port:
Dan Talayco32fa6542010-05-11 15:54:08 -0700633 act.port = ofp.OFPP_IN_PORT
634 else:
635 act.port = egress_port
636 self.assertTrue(request.actions.add(act),
637 "Could not add output to " + str(egress_port))
Rich Lane9a003812012-10-04 17:17:59 -0700638 # logging.info(request.show())
Dan Talayco2e77a842010-05-12 15:39:46 -0700639
Rich Lane9a003812012-10-04 17:17:59 -0700640 logging.info("Inserting flow")
Dan Talayco2e77a842010-05-12 15:39:46 -0700641 rv = self.controller.message_send(request)
642 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700643 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco2e77a842010-05-12 15:39:46 -0700644
Rich Lane9a003812012-10-04 17:17:59 -0700645 logging.info("Sending packet to dp port " + str(ingress_port))
Dan Talayco2e77a842010-05-12 15:39:46 -0700646 self.dataplane.send(ingress_port, str(pkt))
Rich Lane477f4812012-10-04 22:49:00 -0700647 receive_pkt_check(self.dataplane, pkt, of_ports, [], self, config)
Dan Talayco2e77a842010-05-12 15:39:46 -0700648
Rich Laneb90a1c42012-10-05 09:16:05 -0700649class Flood(base_tests.SimpleDataPlane):
Dan Talayco2e77a842010-05-12 15:39:46 -0700650 """
651 Flood to all ports except ingress
652
653 Generate a packet
654 Generate and install a matching flow
655 Add action to flood the packet
656 Send the packet to ingress dataplane port
657 Verify the packet is received at all other ports
658 """
659 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700660 of_ports = config["port_map"].keys()
Dan Talayco2e77a842010-05-12 15:39:46 -0700661 of_ports.sort()
662 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
663
664 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700665 match = packet_to_flow_match(self, pkt)
Dan Talayco2e77a842010-05-12 15:39:46 -0700666 match.wildcards &= ~ofp.OFPFW_IN_PORT
667 self.assertTrue(match is not None,
668 "Could not generate flow match from pkt")
669 act = action.action_output()
670
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700671 for ingress_port in of_ports:
Rich Lane9a003812012-10-04 17:17:59 -0700672 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700673 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco2e77a842010-05-12 15:39:46 -0700674
Rich Lane9a003812012-10-04 17:17:59 -0700675 logging.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco2e77a842010-05-12 15:39:46 -0700676 match.in_port = ingress_port
677
678 request = message.flow_mod()
679 request.match = match
680 request.buffer_id = 0xffffffff
681 act.port = ofp.OFPP_FLOOD
682 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700683 "Could not add flood port action")
Rich Lane9a003812012-10-04 17:17:59 -0700684 logging.info(request.show())
Dan Talayco32fa6542010-05-11 15:54:08 -0700685
Rich Lane9a003812012-10-04 17:17:59 -0700686 logging.info("Inserting flow")
Dan Talayco32fa6542010-05-11 15:54:08 -0700687 rv = self.controller.message_send(request)
688 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700689 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco32fa6542010-05-11 15:54:08 -0700690
Rich Lane9a003812012-10-04 17:17:59 -0700691 logging.info("Sending packet to dp port " + str(ingress_port))
Dan Talayco32fa6542010-05-11 15:54:08 -0700692 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700693 yes_ports = set(of_ports).difference([ingress_port])
694 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Rich Lane477f4812012-10-04 22:49:00 -0700695 self, config)
Dan Talayco3be5b062010-05-12 15:46:21 -0700696
Rich Laneb90a1c42012-10-05 09:16:05 -0700697class FloodPlusIngress(base_tests.SimpleDataPlane):
Dan Talayco3be5b062010-05-12 15:46:21 -0700698 """
699 Flood to all ports plus send to ingress port
700
701 Generate a packet
702 Generate and install a matching flow
703 Add action to flood the packet
704 Add action to send to ingress port
705 Send the packet to ingress dataplane port
706 Verify the packet is received at all other ports
707 """
708 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700709 of_ports = config["port_map"].keys()
Dan Talayco3be5b062010-05-12 15:46:21 -0700710 of_ports.sort()
711 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
712
713 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700714 match = packet_to_flow_match(self, pkt)
Dan Talayco3be5b062010-05-12 15:46:21 -0700715 match.wildcards &= ~ofp.OFPFW_IN_PORT
716 self.assertTrue(match is not None,
717 "Could not generate flow match from pkt")
718 act = action.action_output()
719
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700720 for ingress_port in of_ports:
Rich Lane9a003812012-10-04 17:17:59 -0700721 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700722 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco3be5b062010-05-12 15:46:21 -0700723
Rich Lane9a003812012-10-04 17:17:59 -0700724 logging.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco3be5b062010-05-12 15:46:21 -0700725 match.in_port = ingress_port
726
727 request = message.flow_mod()
728 request.match = match
729 request.buffer_id = 0xffffffff
730 act.port = ofp.OFPP_FLOOD
731 self.assertTrue(request.actions.add(act),
Dan Talayco4aa13122010-05-12 15:54:44 -0700732 "Could not add flood port action")
733 act.port = ofp.OFPP_IN_PORT
734 self.assertTrue(request.actions.add(act),
735 "Could not add ingress port for output")
Rich Lane9a003812012-10-04 17:17:59 -0700736 logging.info(request.show())
Dan Talayco4aa13122010-05-12 15:54:44 -0700737
Rich Lane9a003812012-10-04 17:17:59 -0700738 logging.info("Inserting flow")
Dan Talayco4aa13122010-05-12 15:54:44 -0700739 rv = self.controller.message_send(request)
740 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700741 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700742
Rich Lane9a003812012-10-04 17:17:59 -0700743 logging.info("Sending packet to dp port " + str(ingress_port))
Dan Talayco4aa13122010-05-12 15:54:44 -0700744 self.dataplane.send(ingress_port, str(pkt))
Rich Lane477f4812012-10-04 22:49:00 -0700745 receive_pkt_check(self.dataplane, pkt, of_ports, [], self, config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700746
Rich Laneb90a1c42012-10-05 09:16:05 -0700747class All(base_tests.SimpleDataPlane):
Dan Talayco4aa13122010-05-12 15:54:44 -0700748 """
749 Send to OFPP_ALL port
750
751 Generate a packet
752 Generate and install a matching flow
753 Add action to forward to OFPP_ALL
754 Send the packet to ingress dataplane port
755 Verify the packet is received at all other ports
756 """
757 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700758 of_ports = config["port_map"].keys()
Dan Talayco4aa13122010-05-12 15:54:44 -0700759 of_ports.sort()
760 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
761
762 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700763 match = packet_to_flow_match(self, pkt)
Dan Talayco4aa13122010-05-12 15:54:44 -0700764 match.wildcards &= ~ofp.OFPFW_IN_PORT
765 self.assertTrue(match is not None,
766 "Could not generate flow match from pkt")
767 act = action.action_output()
768
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700769 for ingress_port in of_ports:
Rich Lane9a003812012-10-04 17:17:59 -0700770 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700771 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700772
Rich Lane9a003812012-10-04 17:17:59 -0700773 logging.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700774 match.in_port = ingress_port
775
776 request = message.flow_mod()
777 request.match = match
778 request.buffer_id = 0xffffffff
779 act.port = ofp.OFPP_ALL
780 self.assertTrue(request.actions.add(act),
781 "Could not add ALL port action")
Rich Lane9a003812012-10-04 17:17:59 -0700782 logging.info(request.show())
Dan Talayco4aa13122010-05-12 15:54:44 -0700783
Rich Lane9a003812012-10-04 17:17:59 -0700784 logging.info("Inserting flow")
Dan Talayco4aa13122010-05-12 15:54:44 -0700785 rv = self.controller.message_send(request)
786 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700787 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco4aa13122010-05-12 15:54:44 -0700788
Rich Lane9a003812012-10-04 17:17:59 -0700789 logging.info("Sending packet to dp port " + str(ingress_port))
Dan Talayco4aa13122010-05-12 15:54:44 -0700790 self.dataplane.send(ingress_port, str(pkt))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700791 yes_ports = set(of_ports).difference([ingress_port])
792 receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
Rich Lane477f4812012-10-04 22:49:00 -0700793 self, config)
Dan Talayco4aa13122010-05-12 15:54:44 -0700794
Rich Laneb90a1c42012-10-05 09:16:05 -0700795class AllPlusIngress(base_tests.SimpleDataPlane):
Dan Talayco4aa13122010-05-12 15:54:44 -0700796 """
797 Send to OFPP_ALL port and ingress port
798
799 Generate a packet
800 Generate and install a matching flow
801 Add action to forward to OFPP_ALL
802 Add action to forward to ingress port
803 Send the packet to ingress dataplane port
804 Verify the packet is received at all other ports
805 """
806 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700807 of_ports = config["port_map"].keys()
Dan Talayco4aa13122010-05-12 15:54:44 -0700808 of_ports.sort()
809 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
810
811 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700812 match = packet_to_flow_match(self, pkt)
Dan Talayco4aa13122010-05-12 15:54:44 -0700813 match.wildcards &= ~ofp.OFPFW_IN_PORT
814 self.assertTrue(match is not None,
815 "Could not generate flow match from pkt")
816 act = action.action_output()
817
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700818 for ingress_port in of_ports:
Rich Lane9a003812012-10-04 17:17:59 -0700819 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700820 self.assertEqual(rv, 0, "Failed to delete all flows")
Dan Talayco4aa13122010-05-12 15:54:44 -0700821
Rich Lane9a003812012-10-04 17:17:59 -0700822 logging.info("Ingress " + str(ingress_port) + " to all ports")
Dan Talayco4aa13122010-05-12 15:54:44 -0700823 match.in_port = ingress_port
824
825 request = message.flow_mod()
826 request.match = match
827 request.buffer_id = 0xffffffff
828 act.port = ofp.OFPP_ALL
829 self.assertTrue(request.actions.add(act),
830 "Could not add ALL port action")
Dan Talayco3be5b062010-05-12 15:46:21 -0700831 act.port = ofp.OFPP_IN_PORT
832 self.assertTrue(request.actions.add(act),
833 "Could not add ingress port for output")
Rich Lane9a003812012-10-04 17:17:59 -0700834 logging.info(request.show())
Dan Talayco3be5b062010-05-12 15:46:21 -0700835
Rich Lane9a003812012-10-04 17:17:59 -0700836 logging.info("Inserting flow")
Dan Talayco3be5b062010-05-12 15:46:21 -0700837 rv = self.controller.message_send(request)
838 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700839 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco3be5b062010-05-12 15:46:21 -0700840
Rich Lane9a003812012-10-04 17:17:59 -0700841 logging.info("Sending packet to dp port " + str(ingress_port))
Dan Talayco3be5b062010-05-12 15:46:21 -0700842 self.dataplane.send(ingress_port, str(pkt))
Rich Lane477f4812012-10-04 22:49:00 -0700843 receive_pkt_check(self.dataplane, pkt, of_ports, [], self, config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700844
Rich Laneb90a1c42012-10-05 09:16:05 -0700845class FloodMinusPort(base_tests.SimpleDataPlane):
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700846 """
847 Config port with No_Flood and test Flood action
848
849 Generate a packet
850 Generate a matching flow
851 Add action to forward to OFPP_ALL
852 Set port to no-flood
853 Send the packet to ingress dataplane port
854 Verify the packet is received at all other ports except
855 the ingress port and the no_flood port
856 """
857 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700858 of_ports = config["port_map"].keys()
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700859 of_ports.sort()
860 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
861
862 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -0700863 match = packet_to_flow_match(self, pkt)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700864 match.wildcards &= ~ofp.OFPFW_IN_PORT
865 self.assertTrue(match is not None,
866 "Could not generate flow match from pkt")
867 act = action.action_output()
868
869 for idx in range(len(of_ports)):
Rich Lane9a003812012-10-04 17:17:59 -0700870 rv = delete_all_flows(self.controller)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700871 self.assertEqual(rv, 0, "Failed to delete all flows")
872
873 ingress_port = of_ports[idx]
874 no_flood_idx = (idx + 1) % len(of_ports)
875 no_flood_port = of_ports[no_flood_idx]
876 rv = port_config_set(self.controller, no_flood_port,
Rich Lane9a003812012-10-04 17:17:59 -0700877 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700878 self.assertEqual(rv, 0, "Failed to set port config")
879
880 match.in_port = ingress_port
881
882 request = message.flow_mod()
883 request.match = match
884 request.buffer_id = 0xffffffff
885 act.port = ofp.OFPP_FLOOD
886 self.assertTrue(request.actions.add(act),
887 "Could not add flood port action")
Rich Lane9a003812012-10-04 17:17:59 -0700888 logging.info(request.show())
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700889
Rich Lane9a003812012-10-04 17:17:59 -0700890 logging.info("Inserting flow")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700891 rv = self.controller.message_send(request)
892 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700893 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700894
Rich Lane9a003812012-10-04 17:17:59 -0700895 logging.info("Sending packet to dp port " + str(ingress_port))
896 logging.info("No flood port is " + str(no_flood_port))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700897 self.dataplane.send(ingress_port, str(pkt))
898 no_ports = set([ingress_port, no_flood_port])
899 yes_ports = set(of_ports).difference(no_ports)
Rich Lane477f4812012-10-04 22:49:00 -0700900 receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports, self, config)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700901
902 # Turn no flood off again
903 rv = port_config_set(self.controller, no_flood_port,
Rich Lane9a003812012-10-04 17:17:59 -0700904 0, ofp.OFPPC_NO_FLOOD)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700905 self.assertEqual(rv, 0, "Failed to reset port config")
906
907 #@todo Should check no other packets received
908
Dan Talayco21381562010-07-17 00:34:47 -0700909
910
Dan Talayco551befa2010-07-15 17:05:32 -0700911################################################################
912
Rich Laneb90a1c42012-10-05 09:16:05 -0700913class BaseMatchCase(base_tests.SimpleDataPlane):
Dan Talayco551befa2010-07-15 17:05:32 -0700914 def setUp(self):
Rich Laneb90a1c42012-10-05 09:16:05 -0700915 base_tests.SimpleDataPlane.setUp(self)
Dan Talayco551befa2010-07-15 17:05:32 -0700916 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700917 logging.info("BaseMatchCase")
Dan Talayco551befa2010-07-15 17:05:32 -0700918
919class ExactMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700920 """
Dan Talayco551befa2010-07-15 17:05:32 -0700921 Exercise exact matching for all port pairs
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700922
923 Generate a packet
924 Generate and install a matching flow without wildcard mask
925 Add action to forward to a port
926 Send the packet to the port
927 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700928 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -0700929
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700930 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700931 flow_match_test(self, config["port_map"])
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700932
Dan Talayco551befa2010-07-15 17:05:32 -0700933class ExactMatchTagged(BaseMatchCase):
934 """
935 Exact match for all port pairs with tagged pkts
936 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700937
Dan Talayco551befa2010-07-15 17:05:32 -0700938 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -0700939 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
940 flow_match_test(self, config["port_map"], dl_vlan=vid)
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700941
Dan Talayco551befa2010-07-15 17:05:32 -0700942class ExactMatchTaggedMany(BaseMatchCase):
943 """
944 ExactMatchTagged with many VLANS
945 """
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -0700946
Rich Laned1d9c282012-10-04 22:07:10 -0700947 priority = -1
948
Dan Talayco551befa2010-07-15 17:05:32 -0700949 def runTest(self):
Dan Talayco21381562010-07-17 00:34:47 -0700950 for vid in range(2,100,10):
Rich Lane477f4812012-10-04 22:49:00 -0700951 flow_match_test(self, config["port_map"], dl_vlan=vid, max_test=5)
Dan Talayco551befa2010-07-15 17:05:32 -0700952 for vid in range(100,4000,389):
Rich Lane477f4812012-10-04 22:49:00 -0700953 flow_match_test(self, config["port_map"], dl_vlan=vid, max_test=5)
954 flow_match_test(self, config["port_map"], dl_vlan=4094, max_test=5)
Tatsuya Yabecdf575e2010-05-25 16:56:38 -0700955
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700956class SingleWildcardMatchPriority(BaseMatchCase):
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700957 """
958 SingleWildcardMatchPriority
959 """
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700960
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700961 def _Init(self):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700962 self.pkt = simple_tcp_packet()
963 self.flowMsgs = {}
964
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700965 def _ClearTable(self):
Rich Lane9a003812012-10-04 17:17:59 -0700966 rc = delete_all_flows(self.controller)
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700967 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700968 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700969
970 def runTest(self):
971
972 self._Init()
Rich Lane477f4812012-10-04 22:49:00 -0700973 of_ports = config["port_map"].keys()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700974 of_ports.sort()
975
976 # Delete the initial flow table
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700977 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700978
979 # Run several combinations, each at lower priority settings.
980 # At the end of each call to runPrioFlows(), the table should
981 # be empty. If its not, we'll catch it as the priorities decreases
982 portA = of_ports[0]
983 portB = of_ports[1]
984 portC = of_ports[2]
985
986 # TODO -- these priority numbers should be validated somehow?
987 self.runPrioFlows(portA, portB, portC, 1000, 999)
988 self.runPrioFlows(portB, portC, portA, 998, 997)
989 self.runPrioFlows(portC, portA, portB, 996, 995)
990 self.runPrioFlows(portA, portC, portB, 994, 993)
991
992
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700993
994 def runPrioFlows(self, portA, portB, portC, prioHigher, prioLower,
995 clearTable=False):
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700996
Jeffrey Townsend50c82462012-03-28 18:26:14 -0700997 if clearTable:
998 self._ClearTable()
Jeffrey Townsend2a300e42012-03-28 17:24:02 -0700999
1000 # Sanity check flow at lower priority from pA to pB
Rich Lane9a003812012-10-04 17:17:59 -07001001 logging.info("runPrioFlows(pA=%d,pB=%d,pC=%d,ph=%d,pl=%d"
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001002 % (portA, portB, portC, prioHigher, prioLower))
1003
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001004 # Sanity check flow at lower priority from pA to pC
1005 self.installFlow(prioLower, portA, portC)
1006 self.verifyFlow(portA, portC)
1007 self.removeFlow(prioLower)
1008
1009 # Install and verify pA->pB @ prioLower
1010 self.installFlow(prioLower, portA, portB)
1011 self.verifyFlow(portA, portB)
1012
1013 # Install and verify pA->pC @ prioHigher, should override pA->pB
1014 self.installFlow(prioHigher, portA, portC)
1015 self.verifyFlow(portA, portC)
1016 # remove pA->pC
1017 self.removeFlow(prioHigher)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001018 # Old flow pA -> pB @ prioLower should still be active
1019 self.verifyFlow(portA, portB)
1020 self.removeFlow(prioLower)
1021
1022 # Table should be empty at this point, leave it alone as
1023 # an assumption for future test runs
1024
1025
1026
Ed Swierk99a74de2012-08-22 06:40:54 -07001027 def installFlow(self, prio, inp, egp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001028 wildcards=ofp.OFPFW_DL_SRC):
Ed Swierk99a74de2012-08-22 06:40:54 -07001029 wildcards |= required_wildcards(self)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001030 request = flow_msg_create(self, self.pkt, ing_port=inp,
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001031 wildcards=wildcards,
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001032 egr_ports=egp)
1033 request.priority = prio
Rich Lane9a003812012-10-04 17:17:59 -07001034 logging.debug("Install flow with priority " + str(prio))
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001035 flow_msg_install(self, request, clear_table_override=False)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001036 self.flowMsgs[prio] = request
1037
1038 def removeFlow(self, prio):
1039 if self.flowMsgs.has_key(prio):
1040 msg = self.flowMsgs[prio]
1041 msg.command = ofp.OFPFC_DELETE_STRICT
1042 # This *must* be set for DELETE
1043 msg.out_port = ofp.OFPP_NONE
Rich Lane9a003812012-10-04 17:17:59 -07001044 logging.debug("Remove flow with priority " + str(prio))
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001045 self.controller.message_send(msg)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001046 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001047 else:
1048 raise Exception("Not initialized")
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001049
1050
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001051 def verifyFlow(self, inp, egp, pkt=None):
1052 if pkt == None:
1053 pkt = self.pkt
1054
Rich Lane9a003812012-10-04 17:17:59 -07001055 logging.info("Pkt match test: " + str(inp) + " to " + str(egp))
1056 logging.debug("Send packet: " + str(inp) + " to " + str(egp))
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001057 self.dataplane.send(inp, str(pkt))
1058 receive_pkt_verify(self, egp, pkt, inp)
Jeffrey Townsend2a300e42012-03-28 17:24:02 -07001059
1060
1061
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001062class SingleWildcardMatchPriorityInsertModifyDelete(SingleWildcardMatchPriority):
1063
1064 def runTest(self):
1065
1066 self._Init()
1067
Rich Lane477f4812012-10-04 22:49:00 -07001068 of_ports = config["port_map"].keys()
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001069 of_ports.sort()
1070
1071 # Install an entry from 0 -> 1 @ prio 1000
1072 self._ClearTable()
1073 self.installFlow(1000, of_ports[0], of_ports[1])
1074 self.verifyFlow(of_ports[0], of_ports[1])
1075 self.installFlow(1000, of_ports[1], of_ports[0])
1076 self.verifyFlow(of_ports[1], of_ports[0])
1077 self.installFlow(1001, of_ports[0], of_ports[1])
1078 self.verifyFlow(of_ports[0], of_ports[1])
1079 self.installFlow(1001, of_ports[1], of_ports[0])
1080 self.verifyFlow(of_ports[1], of_ports[0])
1081 self.removeFlow(1001)
1082 self.verifyFlow(of_ports[0], of_ports[1])
1083 self.removeFlow(1000)
1084
1085
1086
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001087class WildcardPriority(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001088 """
1089 1. Add wildcard flow, verify packet received.
1090 2. Add exact match flow with higher priority, verify packet received
1091 on port specified by this flow.
1092 3. Add wildcard flow with even higher priority, verify packet received
1093 on port specified by this flow.
1094 """
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001095
1096 def runTest(self):
Jeffrey Townsend50c82462012-03-28 18:26:14 -07001097
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001098 self._Init()
1099
Rich Lane477f4812012-10-04 22:49:00 -07001100 of_ports = config["port_map"].keys()
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001101 of_ports.sort()
1102
1103 self._ClearTable()
Ken Chiang38d7a152012-05-24 15:33:50 -07001104
1105 # Install a flow with wildcards
1106 self.installFlow(999, of_ports[0], of_ports[1],
1107 wildcards=ofp.OFPFW_DL_DST)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001108 self.verifyFlow(of_ports[0], of_ports[1])
Ken Chiang38d7a152012-05-24 15:33:50 -07001109 # Install a flow with no wildcards for our packet
1110 self.installFlow(1000, of_ports[0], of_ports[2], wildcards=0)
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001111 self.verifyFlow(of_ports[0], of_ports[2])
Ken Chiang38d7a152012-05-24 15:33:50 -07001112 # Install a flow with wildcards for our packet with higher
1113 # priority
1114 self.installFlow(1001, of_ports[0], of_ports[3])
1115 self.verifyFlow(of_ports[0], of_ports[3])
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001116
1117
Ken Chiang3978f242012-06-13 14:14:09 -07001118class WildcardPriorityWithDelete(SingleWildcardMatchPriority):
Ken Chiang38d7a152012-05-24 15:33:50 -07001119 """
1120 1. Add exact match flow, verify packet received.
1121 2. Add wildcard flow with higher priority, verify packet received on port
1122 specified by this flow.
1123 3. Add exact match flow with even higher priority, verify packet received
1124 on port specified by this flow.
1125 4. Delete lowest priority flow, verify packet received on port specified
1126 by highest priority flow.
1127 5. Delete highest priority flow, verify packet received on port specified
1128 by remaining flow.
1129 """
1130
1131 def runTest(self):
1132
1133 self._Init()
1134
Rich Lane477f4812012-10-04 22:49:00 -07001135 of_ports = config["port_map"].keys()
Ken Chiang38d7a152012-05-24 15:33:50 -07001136 of_ports.sort()
1137
1138 self._ClearTable()
1139
1140 # Install an exact match flow
1141 self.installFlow(250, of_ports[0], of_ports[1], wildcards=0)
1142 self.verifyFlow(of_ports[0], of_ports[1])
1143 # Install a flow with wildcards of higher priority
1144 self.installFlow(1250, of_ports[0], of_ports[2],
1145 wildcards=ofp.OFPFW_DL_DST)
1146 self.verifyFlow(of_ports[0], of_ports[2])
1147 # Install an exact match flow with even higher priority
1148 self.installFlow(2001, of_ports[0], of_ports[3], wildcards=0)
1149 self.verifyFlow(of_ports[0], of_ports[3])
1150 # Delete lowest priority flow
1151 self.removeFlow(250)
1152 self.verifyFlow(of_ports[0], of_ports[3])
1153 # Delete highest priority flow
1154 self.removeFlow(2001)
1155 self.verifyFlow(of_ports[0], of_ports[2])
1156
Jeffrey Townsend8364b162012-04-12 13:45:40 -07001157
Dan Talayco551befa2010-07-15 17:05:32 -07001158class SingleWildcardMatch(BaseMatchCase):
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001159 """
1160 Exercise wildcard matching for all ports
1161
1162 Generate a packet
1163 Generate and install a matching flow with wildcard mask
1164 Add action to forward to a port
1165 Send the packet to the port
1166 Verify the packet is received at all other ports (one port at a time)
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001167 Verify flow_expiration message is correct when command option is set
Tatsuya Yabe6a6f38a2010-05-22 23:48:04 -07001168 """
Tatsuya Yabe0718ad32010-05-24 15:22:10 -07001169 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001170 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001171 for wc in WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001172 wc |= required_wildcards(self)
Dan Talayco4431d542012-03-21 16:42:16 -07001173 if wc & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001174 # Set nonzero VLAN id to avoid sending priority-tagged packet
1175 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001176 else:
1177 dl_vlan = -1
Rich Lane477f4812012-10-04 22:49:00 -07001178 flow_match_test(self, config["port_map"], wildcards=wc,
Dan Talayco4431d542012-03-21 16:42:16 -07001179 dl_vlan=dl_vlan, max_test=10)
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001180
Dan Talayco551befa2010-07-15 17:05:32 -07001181class SingleWildcardMatchTagged(BaseMatchCase):
1182 """
1183 SingleWildcardMatch with tagged packets
1184 """
1185 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001186 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001187 for wc in WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001188 wc |= required_wildcards(self)
Rich Lane477f4812012-10-04 22:49:00 -07001189 flow_match_test(self, config["port_map"], wildcards=wc, dl_vlan=vid,
Dan Talayco551befa2010-07-15 17:05:32 -07001190 max_test=10)
1191
1192class AllExceptOneWildcardMatch(BaseMatchCase):
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001193 """
Dan Talayco80b54ed2010-07-13 09:48:35 -07001194 Match exactly one field
Tatsuya Yabe4fad7e32010-05-24 15:24:50 -07001195
1196 Generate a packet
1197 Generate and install a matching flow with wildcard all except one filed
1198 Add action to forward to a port
1199 Send the packet to the port
1200 Verify the packet is received at all other ports (one port at a time)
1201 Verify flow_expiration message is correct when command option is set
1202 """
1203 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001204 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001205 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001206 all_exp_one_wildcard |= required_wildcards(self)
Dan Talayco4431d542012-03-21 16:42:16 -07001207 if all_exp_one_wildcard & ofp.OFPFW_DL_VLAN:
Ken Chiang5be06dd2012-04-03 10:03:50 -07001208 # Set nonzero VLAN id to avoid sending priority-tagged packet
1209 dl_vlan = vid
Dan Talayco4431d542012-03-21 16:42:16 -07001210 else:
1211 dl_vlan = -1
Rich Lane477f4812012-10-04 22:49:00 -07001212 flow_match_test(self, config["port_map"], wildcards=all_exp_one_wildcard,
Dan Talayco4431d542012-03-21 16:42:16 -07001213 dl_vlan=dl_vlan)
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001214
Dan Talayco551befa2010-07-15 17:05:32 -07001215class AllExceptOneWildcardMatchTagged(BaseMatchCase):
1216 """
1217 Match one field with tagged packets
1218 """
1219 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001220 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco488fbc52012-04-09 16:30:41 -07001221 for all_exp_one_wildcard in NO_WILDCARD_VALUES:
Ed Swierk99a74de2012-08-22 06:40:54 -07001222 all_exp_one_wildcard |= required_wildcards(self)
Rich Lane477f4812012-10-04 22:49:00 -07001223 flow_match_test(self, config["port_map"], wildcards=all_exp_one_wildcard,
Dan Talayco21381562010-07-17 00:34:47 -07001224 dl_vlan=vid)
Dan Talayco551befa2010-07-15 17:05:32 -07001225
1226class AllWildcardMatch(BaseMatchCase):
Tatsuya Yabee30ebe22010-05-25 09:30:49 -07001227 """
1228 Create Wildcard-all flow and exercise for all ports
1229
1230 Generate a packet
1231 Generate and install a matching flow with wildcard-all
1232 Add action to forward to a port
1233 Send the packet to the port
1234 Verify the packet is received at all other ports (one port at a time)
1235 Verify flow_expiration message is correct when command option is set
1236 """
1237 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001238 flow_match_test(self, config["port_map"], wildcards=ofp.OFPFW_ALL)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001239
Dan Talayco551befa2010-07-15 17:05:32 -07001240class AllWildcardMatchTagged(BaseMatchCase):
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001241 """
Dan Talayco551befa2010-07-15 17:05:32 -07001242 AllWildcardMatch with tagged packets
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001243 """
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001244 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001245 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
1246 flow_match_test(self, config["port_map"], wildcards=ofp.OFPFW_ALL,
Dan Talayco21381562010-07-17 00:34:47 -07001247 dl_vlan=vid)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001248
Dan Talaycoba3745c2010-07-21 21:51:08 -07001249
Dan Talayco551befa2010-07-15 17:05:32 -07001250class AddVLANTag(BaseMatchCase):
1251 """
1252 Add a VLAN tag to an untagged packet
1253 """
1254 def runTest(self):
1255 new_vid = 2
Ed Swierkc7193a22012-08-22 06:51:02 -07001256 sup_acts = self.supported_actions
Dan Talayco551befa2010-07-15 17:05:32 -07001257 if not(sup_acts & 1<<ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001258 skip_message_emit(self, "Add VLAN tag test")
Dan Talaycof36f1082010-07-13 13:57:17 -07001259 return
Tatsuya Yabef5ffb972010-05-26 15:36:33 -07001260
Dan Talayco551befa2010-07-15 17:05:32 -07001261 len = 100
1262 len_w_vid = 104
1263 pkt = simple_tcp_packet(pktlen=len)
1264 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1265 dl_vlan=new_vid)
1266 vid_act = action.action_set_vlan_vid()
1267 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001268
Rich Lane477f4812012-10-04 22:49:00 -07001269 flow_match_test(self, config["port_map"], pkt=pkt,
Dan Talayco551befa2010-07-15 17:05:32 -07001270 exp_pkt=exp_pkt, action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001271
Rich Laneb90a1c42012-10-05 09:16:05 -07001272class PacketOnly(base_tests.DataPlaneOnly):
Dan Talayco551befa2010-07-15 17:05:32 -07001273 """
1274 Just send a packet thru the switch
1275 """
Rich Laned1d9c282012-10-04 22:07:10 -07001276
1277 priority = -1
1278
Dan Talayco551befa2010-07-15 17:05:32 -07001279 def runTest(self):
1280 pkt = simple_tcp_packet()
Rich Lane477f4812012-10-04 22:49:00 -07001281 of_ports = config["port_map"].keys()
Dan Talayco551befa2010-07-15 17:05:32 -07001282 of_ports.sort()
1283 ing_port = of_ports[0]
Rich Lane9a003812012-10-04 17:17:59 -07001284 logging.info("Sending packet to " + str(ing_port))
1285 logging.debug("Data: " + str(pkt).encode('hex'))
Dan Talayco551befa2010-07-15 17:05:32 -07001286 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001287
Rich Laneb90a1c42012-10-05 09:16:05 -07001288class PacketOnlyTagged(base_tests.DataPlaneOnly):
Dan Talayco551befa2010-07-15 17:05:32 -07001289 """
1290 Just send a packet thru the switch
1291 """
Rich Laned1d9c282012-10-04 22:07:10 -07001292
1293 priority = -1
1294
Dan Talayco551befa2010-07-15 17:05:32 -07001295 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001296 vid = test_param_get(config, 'vid', default=TEST_VID_DEFAULT)
Dan Talayco551befa2010-07-15 17:05:32 -07001297 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid)
Rich Lane477f4812012-10-04 22:49:00 -07001298 of_ports = config["port_map"].keys()
Dan Talayco551befa2010-07-15 17:05:32 -07001299 of_ports.sort()
1300 ing_port = of_ports[0]
Rich Lane9a003812012-10-04 17:17:59 -07001301 logging.info("Sending packet to " + str(ing_port))
1302 logging.debug("Data: " + str(pkt).encode('hex'))
Dan Talayco551befa2010-07-15 17:05:32 -07001303 self.dataplane.send(ing_port, str(pkt))
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001304
Dan Talayco551befa2010-07-15 17:05:32 -07001305class ModifyVID(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001306 """
1307 Modify the VLAN ID in the VLAN tag of a tagged packet
1308 """
Dan Talaycoaf669322012-09-12 22:51:22 -07001309 def setUp(self):
1310 BaseMatchCase.setUp(self)
1311 self.ing_port=False
1312
Dan Talayco551befa2010-07-15 17:05:32 -07001313 def runTest(self):
1314 old_vid = 2
1315 new_vid = 3
Ed Swierkc7193a22012-08-22 06:51:02 -07001316 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001317 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001318 skip_message_emit(self, "Modify VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001319 return
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001320
Dan Talayco551befa2010-07-15 17:05:32 -07001321 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=old_vid)
1322 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=new_vid)
1323 vid_act = action.action_set_vlan_vid()
1324 vid_act.vlan_vid = new_vid
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001325
Rich Lane477f4812012-10-04 22:49:00 -07001326 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycoaf669322012-09-12 22:51:22 -07001327 action_list=[vid_act], ing_port=self.ing_port)
1328
1329class ModifyVIDToIngress(ModifyVID):
1330 """
1331 Modify the VLAN ID in the VLAN tag of a tagged packet and send to
1332 ingress port
1333 """
1334 def setUp(self):
1335 BaseMatchCase.setUp(self)
1336 self.ing_port=True
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001337
Ken Chiange9a211d2012-04-20 14:52:11 -07001338class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
1339 """
1340 With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
1341 The same flow should match on both untagged and tagged packets.
1342 """
1343 def runTest(self):
1344 old_vid = 2
1345 new_vid = 3
Ed Swierkc7193a22012-08-22 06:51:02 -07001346 sup_acts = self.supported_actions
Ken Chiange9a211d2012-04-20 14:52:11 -07001347 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
1348 skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
1349 return
1350
Rich Lane477f4812012-10-04 22:49:00 -07001351 of_ports = config["port_map"].keys()
Ken Chiange9a211d2012-04-20 14:52:11 -07001352 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1353 ing_port = of_ports[0]
1354 egr_ports = of_ports[1]
1355
Rich Lane9a003812012-10-04 17:17:59 -07001356 rv = delete_all_flows(self.controller)
Ken Chiange9a211d2012-04-20 14:52:11 -07001357 self.assertEqual(rv, 0, "Failed to delete all flows")
1358
1359 len_untagged = 100
1360 len_w_vid = 104
1361 untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
1362 tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
1363 dl_vlan_enable=True, dl_vlan=old_vid)
1364 exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1365 dl_vlan=new_vid)
Ed Swierk99a74de2012-08-22 06:40:54 -07001366 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_VLAN |
1367 ofp.OFPFW_DL_VLAN_PCP)
Ken Chiange9a211d2012-04-20 14:52:11 -07001368 vid_act = action.action_set_vlan_vid()
1369 vid_act.vlan_vid = new_vid
1370 request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
1371 wildcards=wildcards, egr_ports=egr_ports,
1372 action_list=[vid_act])
1373 flow_msg_install(self, request)
1374
Rich Lane9a003812012-10-04 17:17:59 -07001375 logging.debug("Send untagged packet: " + str(ing_port) + " to " +
Ken Chiange9a211d2012-04-20 14:52:11 -07001376 str(egr_ports))
1377 self.dataplane.send(ing_port, str(untagged_pkt))
1378 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1379
Rich Lane9a003812012-10-04 17:17:59 -07001380 logging.debug("Send tagged packet: " + str(ing_port) + " to " +
Ken Chiange9a211d2012-04-20 14:52:11 -07001381 str(egr_ports))
1382 self.dataplane.send(ing_port, str(tagged_pkt))
1383 receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
1384
Howard Pershc1199d52012-04-11 14:21:32 -07001385class ModifyVlanPcp(BaseMatchCase):
1386 """
1387 Modify the priority field of the VLAN tag of a tagged packet
1388 """
1389 def runTest(self):
1390 vid = 123
1391 old_vlan_pcp = 2
1392 new_vlan_pcp = 3
Ed Swierkc7193a22012-08-22 06:51:02 -07001393 sup_acts = self.supported_actions
Ed Swierk8c3af7f2012-04-24 14:19:17 -07001394 if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_PCP):
1395 skip_message_emit(self, "Modify VLAN priority test")
Howard Pershc1199d52012-04-11 14:21:32 -07001396 return
1397
1398 pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=old_vlan_pcp)
1399 exp_pkt = simple_tcp_packet(dl_vlan_enable=True, dl_vlan=vid, dl_vlan_pcp=new_vlan_pcp)
1400 vid_act = action.action_set_vlan_pcp()
1401 vid_act.vlan_pcp = new_vlan_pcp
1402
Rich Lane477f4812012-10-04 22:49:00 -07001403 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Howard Pershc1199d52012-04-11 14:21:32 -07001404 action_list=[vid_act])
1405
Dan Talayco551befa2010-07-15 17:05:32 -07001406class StripVLANTag(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001407 """
1408 Strip the VLAN tag from a tagged packet
1409 """
Dan Talayco551befa2010-07-15 17:05:32 -07001410 def runTest(self):
1411 old_vid = 2
Ed Swierkc7193a22012-08-22 06:51:02 -07001412 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001413 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001414 skip_message_emit(self, "Strip VLAN tag test")
Dan Talayco551befa2010-07-15 17:05:32 -07001415 return
Dan Talaycof36f1082010-07-13 13:57:17 -07001416
Dan Talayco551befa2010-07-15 17:05:32 -07001417 len_w_vid = 104
1418 len = 100
1419 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1420 dl_vlan=old_vid)
1421 exp_pkt = simple_tcp_packet(pktlen=len)
1422 vid_act = action.action_strip_vlan()
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001423
Rich Lane477f4812012-10-04 22:49:00 -07001424 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco551befa2010-07-15 17:05:32 -07001425 action_list=[vid_act])
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001426
Ken Chiange9a211d2012-04-20 14:52:11 -07001427class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
1428 """
1429 Strip the VLAN tag from a tagged packet.
1430 Differs from StripVLANTag in that VID and PCP are both wildcarded.
1431 """
1432 def runTest(self):
1433 old_vid = 2
Ed Swierkc7193a22012-08-22 06:51:02 -07001434 sup_acts = self.supported_actions
Ken Chiange9a211d2012-04-20 14:52:11 -07001435 if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
1436 skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
1437 return
1438
1439 len_w_vid = 104
1440 len_untagged = 100
1441 pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
1442 dl_vlan=old_vid)
1443 exp_pkt = simple_tcp_packet(pktlen=len_untagged)
Ed Swierk99a74de2012-08-22 06:40:54 -07001444 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_VLAN |
1445 ofp.OFPFW_DL_VLAN_PCP)
Ken Chiange9a211d2012-04-20 14:52:11 -07001446 vid_act = action.action_strip_vlan()
1447
Rich Lane477f4812012-10-04 22:49:00 -07001448 flow_match_test(self, config["port_map"],
Ed Swierk99a74de2012-08-22 06:40:54 -07001449 wildcards=wildcards,
Ken Chiange9a211d2012-04-20 14:52:11 -07001450 pkt=pkt, exp_pkt=exp_pkt,
1451 action_list=[vid_act])
1452
Dan Talayco4b2bee62010-07-20 14:10:05 -07001453def init_pkt_args():
1454 """
1455 Pass back a dictionary with default packet arguments
1456 """
1457 args = {}
1458 args["dl_src"] = '00:23:45:67:89:AB'
1459
1460 dl_vlan_enable=False
1461 dl_vlan=-1
Rich Lane477f4812012-10-04 22:49:00 -07001462 if config["test-params"]["vid"]:
Dan Talayco4b2bee62010-07-20 14:10:05 -07001463 dl_vlan_enable=True
Rich Lane477f4812012-10-04 22:49:00 -07001464 dl_vlan = config["test-params"]["vid"]
Dan Talayco4b2bee62010-07-20 14:10:05 -07001465
1466# Unpack operator is ** on a dictionary
1467
1468 return args
1469
Dan Talayco551befa2010-07-15 17:05:32 -07001470class ModifyL2Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001471 """
1472 Modify the source MAC address (TP1)
1473 """
Dan Talayco551befa2010-07-15 17:05:32 -07001474 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001475 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001476 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001477 skip_message_emit(self, "ModifyL2Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001478 return
1479
1480 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1481 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001482 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco4b2bee62010-07-20 14:10:05 -07001483 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001484
Dan Talayco551befa2010-07-15 17:05:32 -07001485class ModifyL2Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001486 """
1487 Modify the dest MAC address (TP1)
1488 """
Dan Talayco551befa2010-07-15 17:05:32 -07001489 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001490 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001491 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001492 skip_message_emit(self, "ModifyL2dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001493 return
1494
1495 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1496 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001497 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco4b2bee62010-07-20 14:10:05 -07001498 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001499
Dan Talayco551befa2010-07-15 17:05:32 -07001500class ModifyL3Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001501 """
1502 Modify the source IP address of an IP packet (TP1)
1503 """
Dan Talayco551befa2010-07-15 17:05:32 -07001504 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001505 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001506 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001507 skip_message_emit(self, "ModifyL3Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001508 return
1509
1510 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_src'],
1511 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001512 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco4b2bee62010-07-20 14:10:05 -07001513 action_list=acts, max_test=2)
Tatsuya Yabee6cae8b2010-05-25 18:20:04 -07001514
Dan Talayco551befa2010-07-15 17:05:32 -07001515class ModifyL3Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001516 """
1517 Modify the dest IP address of an IP packet (TP1)
1518 """
Dan Talayco551befa2010-07-15 17:05:32 -07001519 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001520 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001521 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001522 skip_message_emit(self, "ModifyL3Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001523 return
1524
1525 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_dst'],
1526 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001527 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco4b2bee62010-07-20 14:10:05 -07001528 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001529
1530class ModifyL4Src(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001531 """
1532 Modify the source TCP port of a TCP packet (TP1)
1533 """
Dan Talayco551befa2010-07-15 17:05:32 -07001534 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001535 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001536 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_SRC):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001537 skip_message_emit(self, "ModifyL4Src test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001538 return
1539
1540 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_sport'],
1541 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001542 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco4b2bee62010-07-20 14:10:05 -07001543 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001544
1545class ModifyL4Dst(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001546 """
1547 Modify the dest TCP port of a TCP packet (TP1)
1548 """
Dan Talayco551befa2010-07-15 17:05:32 -07001549 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001550 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001551 if not (sup_acts & 1 << ofp.OFPAT_SET_TP_DST):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001552 skip_message_emit(self, "ModifyL4Dst test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001553 return
1554
1555 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['tcp_dport'],
1556 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001557 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talayco4b2bee62010-07-20 14:10:05 -07001558 action_list=acts, max_test=2)
Dan Talayco551befa2010-07-15 17:05:32 -07001559
1560class ModifyTOS(BaseMatchCase):
Dan Talayco4b2bee62010-07-20 14:10:05 -07001561 """
1562 Modify the IP type of service of an IP packet (TP1)
1563 """
Dan Talayco551befa2010-07-15 17:05:32 -07001564 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001565 sup_acts = self.supported_actions
Dan Talayco4b2bee62010-07-20 14:10:05 -07001566 if not (sup_acts & 1 << ofp.OFPAT_SET_NW_TOS):
Dan Talaycoba3745c2010-07-21 21:51:08 -07001567 skip_message_emit(self, "ModifyTOS test")
Dan Talayco4b2bee62010-07-20 14:10:05 -07001568 return
Dan Talayco551befa2010-07-15 17:05:32 -07001569
Dan Talayco4b2bee62010-07-20 14:10:05 -07001570 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['ip_tos'],
1571 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001572 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001573 action_list=acts, max_test=2, egr_count=-1)
Dan Talayco551befa2010-07-15 17:05:32 -07001574
Dan Talaycof6e76c02012-03-23 10:56:12 -07001575class ModifyL2DstMC(BaseMatchCase):
1576 """
1577 Modify the L2 dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001578 """
1579 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001580 sup_acts = self.supported_actions
Dan Talaycof6e76c02012-03-23 10:56:12 -07001581 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001582 skip_message_emit(self, "ModifyL2dstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001583 return
1584
Dan Talaycof6e76c02012-03-23 10:56:12 -07001585 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1586 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001587 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001588 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001589
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001590class ModifyL2DstIngress(BaseMatchCase):
1591 """
1592 Modify the L2 dest and send to the ingress port
1593 """
1594 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001595 sup_acts = self.supported_actions
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001596 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001597 skip_message_emit(self, "ModifyL2dstIngress test")
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001598 return
1599
1600 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1601 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001602 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycoc948d0b2012-03-23 12:17:54 -07001603 action_list=acts, max_test=2, egr_count=0,
1604 ing_port=True)
1605
Dan Talaycod8ae7582012-03-23 12:24:56 -07001606class ModifyL2DstIngressMC(BaseMatchCase):
1607 """
1608 Modify the L2 dest and send to the ingress port
1609 """
1610 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001611 sup_acts = self.supported_actions
Dan Talaycod8ae7582012-03-23 12:24:56 -07001612 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST):
1613 skip_message_emit(self, "ModifyL2dstMC test")
1614 return
1615
1616 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_dst'],
1617 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001618 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycod8ae7582012-03-23 12:24:56 -07001619 action_list=acts, max_test=2, egr_count=-1,
1620 ing_port=True)
1621
Dan Talaycof6e76c02012-03-23 10:56:12 -07001622class ModifyL2SrcMC(BaseMatchCase):
1623 """
1624 Modify the source MAC address (TP1) and send to multiple
Dan Talaycof6e76c02012-03-23 10:56:12 -07001625 """
1626 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001627 sup_acts = self.supported_actions
Dan Talaycof6e76c02012-03-23 10:56:12 -07001628 if not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC):
Dan Talaycocfa172f2012-03-23 12:03:00 -07001629 skip_message_emit(self, "ModifyL2SrcMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001630 return
1631
Dan Talaycof6e76c02012-03-23 10:56:12 -07001632 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=['dl_src'],
1633 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001634 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001635 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001636
1637class ModifyL2SrcDstMC(BaseMatchCase):
1638 """
1639 Modify the L2 source and dest and send to 2 ports
Dan Talaycof6e76c02012-03-23 10:56:12 -07001640 """
1641 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001642 sup_acts = self.supported_actions
Dan Talaycocfa172f2012-03-23 12:03:00 -07001643 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1644 not (sup_acts & 1 << ofp.OFPAT_SET_DL_SRC)):
1645 skip_message_emit(self, "ModifyL2SrcDstMC test")
Dan Talaycof6e76c02012-03-23 10:56:12 -07001646 return
1647
Dan Talaycof6e76c02012-03-23 10:56:12 -07001648 mod_fields = ['dl_dst', 'dl_src']
1649 (pkt, exp_pkt, acts) = pkt_action_setup(self, mod_fields=mod_fields,
1650 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001651 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001652 action_list=acts, max_test=2, egr_count=-1)
1653
1654class ModifyL2DstVIDMC(BaseMatchCase):
1655 """
1656 Modify the L2 dest and send to 2 ports
1657 """
1658 def runTest(self):
Ed Swierkc7193a22012-08-22 06:51:02 -07001659 sup_acts = self.supported_actions
Dan Talaycocfa172f2012-03-23 12:03:00 -07001660 if (not (sup_acts & 1 << ofp.OFPAT_SET_DL_DST) or
1661 not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID)):
1662 skip_message_emit(self, "ModifyL2DstVIDMC test")
1663 return
1664
1665 mod_fields = ['dl_dst', 'dl_vlan']
1666 (pkt, exp_pkt, acts) = pkt_action_setup(self,
1667 start_field_vals={'dl_vlan_enable':True}, mod_fields=mod_fields,
1668 check_test_params=True)
Rich Lane477f4812012-10-04 22:49:00 -07001669 flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
Dan Talaycocfa172f2012-03-23 12:03:00 -07001670 action_list=acts, max_test=2, egr_count=-1)
Dan Talaycof6e76c02012-03-23 10:56:12 -07001671
Dan Talaycofa6454f2012-04-05 10:04:13 -07001672class FlowToggle(BaseMatchCase):
1673 """
1674 Add flows to the table and modify them repeatedly
Dan Talaycof7c41312012-07-23 12:53:19 -07001675
1676 This is done by using only "add" flow messages. Since the check overlap
1677 flag is not set, the switch is supposed to modify the existing flow if
1678 the match already exists.
1679
1680 Would probably be better to exercise more of the flow modify commands
1681 (add, modify, delete +/- strict).
Dan Talaycofa6454f2012-04-05 10:04:13 -07001682 """
1683 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001684 flow_count = test_param_get(config, 'ft_flow_count', default=20)
1685 iter_count = test_param_get(config, 'ft_iter_count', default=10)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001686
Rich Lane9a003812012-10-04 17:17:59 -07001687 logging.info("Running flow toggle with %d flows, %d iterations" %
Dan Talaycofa6454f2012-04-05 10:04:13 -07001688 (flow_count, iter_count))
1689 acts = []
1690 acts.append(action.action_output())
1691 acts.append(action.action_output())
1692
Rich Lane477f4812012-10-04 22:49:00 -07001693 of_ports = config["port_map"].keys()
Dan Talaycofa6454f2012-04-05 10:04:13 -07001694 if len(of_ports) < 3:
1695 self.assertTrue(False, "Too few ports for test")
1696
1697 for idx in range(2):
1698 acts[idx].port = of_ports[idx]
1699
1700 flows = []
1701 flows.append([])
1702 flows.append([])
1703
Ed Swierk99a74de2012-08-22 06:40:54 -07001704 wildcards = (required_wildcards(self) | ofp.OFPFW_DL_SRC |
1705 ofp.OFPFW_DL_DST)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001706 # Create up the flows in an array
1707 for toggle in range(2):
1708 for f_idx in range(flow_count):
1709 pkt = simple_tcp_packet(tcp_sport=f_idx)
1710 msg = message.flow_mod()
Ed Swierk99a74de2012-08-22 06:40:54 -07001711 match = packet_to_flow_match(self, pkt)
Shudong Zhou031373c2012-07-19 17:37:42 -07001712 match.in_port = of_ports[2]
Dan Talayco50be7672012-04-05 11:38:08 -07001713 match.wildcards = wildcards
Dan Talaycofa6454f2012-04-05 10:04:13 -07001714 msg.match = match
1715 msg.buffer_id = 0xffffffff
Dan Talaycof7c41312012-07-23 12:53:19 -07001716 msg.command = ofp.OFPFC_ADD
Dan Talaycofa6454f2012-04-05 10:04:13 -07001717 msg.actions.add(acts[toggle])
1718 flows[toggle].append(msg)
Dan Talayco50be7672012-04-05 11:38:08 -07001719
1720 # Show two sample flows
Rich Lane9a003812012-10-04 17:17:59 -07001721 logging.debug(flows[0][0].show())
1722 logging.debug(flows[1][0].show())
Dan Talayco50be7672012-04-05 11:38:08 -07001723
Dan Talaycofa6454f2012-04-05 10:04:13 -07001724 # Install the first set of flows
1725 for f_idx in range(flow_count):
1726 rv = self.controller.message_send(flows[0][f_idx])
1727 self.assertTrue(rv != -1, "Error installing flow %d" % f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001728 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycofa6454f2012-04-05 10:04:13 -07001729
Rich Lane9a003812012-10-04 17:17:59 -07001730 logging.info("Installed %d flows" % flow_count)
Dan Talaycofa6454f2012-04-05 10:04:13 -07001731
1732 # Repeatedly modify all the flows back and forth
1733 updates = 0
1734 # Report status about 5 times
1735 mod_val = (iter_count / 4) + 1
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001736 start = time.time()
1737 for iter_idx in range(iter_count):
1738 if not iter_idx % mod_val:
Rich Lane9a003812012-10-04 17:17:59 -07001739 logging.info("Flow Toggle: iter %d of %d. " %
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001740 (iter_idx, iter_count) +
1741 "%d updates in %d secs" %
1742 (updates, time.time() - start))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001743 for toggle in range(2):
1744 t_idx = 1 - toggle
1745 for f_idx in range(flow_count):
1746 rv = self.controller.message_send(flows[t_idx][f_idx])
1747 updates += 1
1748 self.assertTrue(rv != -1, "Error modifying flow %d" %
1749 f_idx)
Dan Talayco0fc08bd2012-04-09 16:56:18 -07001750 self.assertEqual(do_barrier(self.controller), 0,
1751 "Barrier failed")
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001752
1753 end = time.time()
1754 divisor = end - start or (end - start + 1)
Rich Lane9a003812012-10-04 17:17:59 -07001755 logging.info("Flow toggle: %d iterations" % iter_count)
1756 logging.info(" %d flow mods in %d secs, %d mods/sec" %
Dan Talaycoabbfdbb2012-04-05 10:29:26 -07001757 (updates, end - start, updates/divisor))
Dan Talaycofa6454f2012-04-05 10:04:13 -07001758
1759
Dan Talayco8a64e332012-03-28 14:53:20 -07001760# You can pick and choose these by commenting tests in or out
1761iter_classes = [
1762 basic.PacketIn,
1763 basic.PacketOut,
1764 DirectPacket,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001765 FlowToggle,
Dan Talayco8a64e332012-03-28 14:53:20 -07001766 DirectTwoPorts,
Dan Talaycofa6454f2012-04-05 10:04:13 -07001767 DirectMCNonIngress,
Dan Talayco8a64e332012-03-28 14:53:20 -07001768 AllWildcardMatch,
1769 AllWildcardMatchTagged,
1770 SingleWildcardMatch,
1771 SingleWildcardMatchTagged,
1772 ExactMatch,
1773 ExactMatchTagged,
1774 SingleWildcardMatch,
1775 ModifyL2Src,
1776 ModifyL2Dst,
1777 ModifyL2SrcMC,
1778 ModifyL2DstMC,
1779 ModifyL2SrcDstMC
1780 ]
1781
1782class IterCases(BaseMatchCase):
Dan Talaycofa6454f2012-04-05 10:04:13 -07001783 """
1784 Iterate over a bunch of test cases
1785
1786 The cases come from the list above
1787 """
1788
Rich Laned1d9c282012-10-04 22:07:10 -07001789 priority = -1
1790
Dan Talayco8a64e332012-03-28 14:53:20 -07001791 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001792 count = test_param_get(config, 'iter_count', default=10)
Dan Talayco8a64e332012-03-28 14:53:20 -07001793 tests_done = 0
Rich Lane9a003812012-10-04 17:17:59 -07001794 logging.info("Running iteration test " + str(count) + " times")
Dan Talayco8a64e332012-03-28 14:53:20 -07001795 start = time.time()
1796 last = start
1797 for idx in range(count):
Rich Lane9a003812012-10-04 17:17:59 -07001798 logging.info("Iteration " + str(idx + 1))
Dan Talayco8a64e332012-03-28 14:53:20 -07001799 for cls in iter_classes:
1800 test = cls()
1801 test.inheritSetup(self)
1802 test.runTest()
1803 tests_done += 1
Dan Talaycofa6454f2012-04-05 10:04:13 -07001804 # Report update about every minute, between tests
Dan Talayco8a64e332012-03-28 14:53:20 -07001805 if time.time() - last > 60:
1806 last = time.time()
Rich Lane9a003812012-10-04 17:17:59 -07001807 logging.info(
Dan Talaycofa6454f2012-04-05 10:04:13 -07001808 "IterCases: Iter %d of %d; Ran %d tests in %d " %
1809 (idx, count, tests_done, last - start) +
1810 "seconds so far")
Dan Talayco8a64e332012-03-28 14:53:20 -07001811 stats = all_stats_get(self)
1812 last = time.time()
Rich Lane9a003812012-10-04 17:17:59 -07001813 logging.info("\nIterCases ran %d tests in %d seconds." %
Dan Talayco8a64e332012-03-28 14:53:20 -07001814 (tests_done, last - start))
Rich Lane9a003812012-10-04 17:17:59 -07001815 logging.info(" flows: %d. packets: %d. bytes: %d" %
Dan Talayco8a64e332012-03-28 14:53:20 -07001816 (stats["flows"], stats["packets"], stats["bytes"]))
Rich Lane9a003812012-10-04 17:17:59 -07001817 logging.info(" active: %d. lookups: %d. matched %d." %
Dan Talayco8a64e332012-03-28 14:53:20 -07001818 (stats["active"], stats["lookups"], stats["matched"]))
1819
Dan Talayco4b2bee62010-07-20 14:10:05 -07001820#@todo Need to implement tagged versions of the above tests
1821#
1822#@todo Implement a test case that strips tag 2, adds tag 3
1823# and modifies tag 4 to tag 5. Then verify (in addition) that
1824# tag 6 does not get modified.
1825
1826class MixedVLAN(BaseMatchCase):
1827 """
1828 Test mixture of VLAN tag actions
1829
1830 Strip tag 2 on port 1, send to port 2
1831 Add tag 3 on port 1, send to port 2
1832 Modify tag 4 to 5 on port 1, send to port 2
1833 All other traffic from port 1, send to port 3
1834 All traffic from port 2 sent to port 4
1835 Use exact matches with different packets for all mods
1836 Verify the following: (port, vid)
1837 (port 1, vid 2) => VLAN tag stripped, out port 2
1838 (port 1, no tag) => tagged packet w/ vid 2 out port 2
1839 (port 1, vid 4) => tagged packet w/ vid 5 out port 2
1840 (port 1, vid 5) => tagged packet w/ vid 5 out port 2
1841 (port 1, vid 6) => tagged packet w/ vid 6 out port 2
1842 (port 2, no tag) => untagged packet out port 4
1843 (port 2, vid 2-6) => unmodified packet out port 4
1844
1845 Variation: Might try sending VID 5 to port 3 and check.
1846 If only VID 5 distinguishes pkt, this will fail on some platforms
1847 """
1848
Rich Laned1d9c282012-10-04 22:07:10 -07001849 priority = -1
Rich Lane8d6ab272012-09-23 18:06:20 -07001850
Rich Laneb90a1c42012-10-05 09:16:05 -07001851class MatchEach(base_tests.SimpleDataPlane):
Rich Lane8d6ab272012-09-23 18:06:20 -07001852 """
1853 Check that each match field is actually matched on.
1854 Installs two flows that differ in one field. The flow that should not
1855 match has a higher priority, so if that field is ignored during matching
1856 the packet will be sent out the wrong port.
1857
1858 TODO test UDP, ARP, ICMP, etc.
1859 """
1860 def runTest(self):
Rich Lane477f4812012-10-04 22:49:00 -07001861 of_ports = config["port_map"].keys()
Rich Lane8d6ab272012-09-23 18:06:20 -07001862 of_ports.sort()
1863 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
1864
Rich Lane9a003812012-10-04 17:17:59 -07001865 delete_all_flows(self.controller)
Rich Lane8d6ab272012-09-23 18:06:20 -07001866
1867 pkt = simple_tcp_packet()
1868 ingress_port = of_ports[0]
1869 egress_port = of_ports[1]
1870
1871 def testField(field, mask):
Rich Lane9a003812012-10-04 17:17:59 -07001872 logging.info("Testing field %s" % field)
Rich Lane8d6ab272012-09-23 18:06:20 -07001873
1874 def addFlow(matching, priority, output_port):
1875 match = packet_to_flow_match(self, pkt)
1876 self.assertTrue(match is not None, "Could not generate flow match from pkt")
1877 match.wildcards &= ~ofp.OFPFW_IN_PORT
1878 match.in_port = ingress_port
1879 if not matching:
1880 # Make sure flow doesn't match
1881 orig = getattr(match, field)
1882 if isinstance(orig, list):
1883 new = map(lambda a: ~a[0] & a[1], zip(orig, mask))
1884 else:
1885 new = ~orig & mask
1886 setattr(match, field, new)
1887 request = message.flow_mod()
1888 request.match = match
1889 request.buffer_id = 0xffffffff
1890 request.priority = priority
1891 act = action.action_output()
1892 act.port = output_port
1893 self.assertTrue(request.actions.add(act), "Could not add action")
Rich Lane9a003812012-10-04 17:17:59 -07001894 logging.info("Inserting flow")
Rich Lane8d6ab272012-09-23 18:06:20 -07001895 self.controller.message_send(request)
1896
1897 # This flow should match.
1898 addFlow(matching=True, priority=0, output_port=egress_port)
1899 # This flow should not match, but it has a higher priority.
1900 addFlow(matching=False, priority=1, output_port=ofp.OFPP_IN_PORT)
1901
1902 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
1903
Rich Lane9a003812012-10-04 17:17:59 -07001904 logging.info("Sending packet to dp port " + str(ingress_port))
Rich Lane8d6ab272012-09-23 18:06:20 -07001905 self.dataplane.send(ingress_port, str(pkt))
1906
1907 exp_pkt_arg = None
1908 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -07001909 if config["relax"]:
Rich Lane8d6ab272012-09-23 18:06:20 -07001910 exp_pkt_arg = pkt
1911 exp_port = egress_port
1912
1913 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
1914 exp_pkt=exp_pkt_arg)
1915 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Rich Lane9a003812012-10-04 17:17:59 -07001916 logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " + str(rcv_port))
Rich Lane8d6ab272012-09-23 18:06:20 -07001917 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
1918 self.assertEqual(str(pkt), str(rcv_pkt), 'Response packet does not match send packet')
1919
1920 # TODO in_port
1921 testField("dl_src", [0xff]*6)
1922 testField("dl_dst", [0xff]*6)
1923 testField("dl_type", 0xffff)
1924 testField("dl_vlan", 0xfff)
1925 # TODO dl_vlan_pcp
1926 testField("nw_src", 0xffffffff)
1927 testField("nw_dst", 0xffffffff)
1928 testField("nw_tos", 0x3f)
1929 testField("nw_proto", 0xff)
1930 testField("tp_src", 0xffff)
1931 testField("tp_dst", 0xffff)
1932
Dan Talayco9f47f4d2010-06-03 13:54:37 -07001933if __name__ == "__main__":
1934 print "Please run through oft script: ./oft --test_spec=basic"