blob: 3fa902b4f00d161f43f4f1e47a402f6eaa1aa967 [file] [log] [blame]
Dan Talaycodba244e2010-02-15 14:08:53 -08001"""
Dan Talayco79f36082010-03-11 16:53:53 -08002Basic protocol and dataplane test cases
Dan Talaycodba244e2010-02-15 14:08:53 -08003
Dan Talayco48370102010-03-03 15:17:33 -08004It is recommended that these definitions be kept in their own
5namespace as different groups of tests will likely define
6similar identifiers.
7
Dan Talaycodba244e2010-02-15 14:08:53 -08008Current Assumptions:
9
Dan Talaycodba244e2010-02-15 14:08:53 -080010 The switch is actively attempting to contact the controller at the address
Rich Lane477f4812012-10-04 22:49:00 -070011indicated in oftest.config.
Dan Talaycodba244e2010-02-15 14:08:53 -080012
13"""
14
Dan Talaycodba244e2010-02-15 14:08:53 -080015import time
16import sys
Dan Talayco48370102010-03-03 15:17:33 -080017import logging
Dan Talaycodba244e2010-02-15 14:08:53 -080018
Dan Talayco2c0dba32010-03-06 22:47:06 -080019import unittest
Ken Chiang1bf01602012-04-04 10:48:23 -070020import random
Dan Talayco2c0dba32010-03-06 22:47:06 -080021
Rich Lane477f4812012-10-04 22:49:00 -070022from oftest import config
Dan Talayco2c0dba32010-03-06 22:47:06 -080023import oftest.controller as controller
24import oftest.cstruct as ofp
25import oftest.message as message
26import oftest.dataplane as dataplane
27import oftest.action as action
Rich Laneb90a1c42012-10-05 09:16:05 -070028import oftest.base_tests as base_tests
Dan Talayco2c0dba32010-03-06 22:47:06 -080029
Dan Talaycoe605b1b2012-09-18 06:56:20 -070030import oftest.illegal_message as illegal_message
31
Rich Laneda3b5ad2012-10-03 09:05:32 -070032from oftest.testutils import *
Dan Talayco6ce963a2010-03-07 21:58:13 -080033
Ken Chiangaeb23d62012-08-23 21:20:07 -070034TEST_VID_DEFAULT = 2
35
Rich Laneb90a1c42012-10-05 09:16:05 -070036class Echo(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080037 """
38 Test echo response with no data
39 """
40 def runTest(self):
Dan Talayco2c0dba32010-03-06 22:47:06 -080041 request = message.echo_request()
Dan Talaycoe226eb12010-02-18 23:06:30 -080042 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070043 self.assertTrue(response is not None,
44 "Did not get echo reply")
Dan Talayco2c0dba32010-03-06 22:47:06 -080045 self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080046 'response is not echo_reply')
Dan Talaycodba244e2010-02-15 14:08:53 -080047 self.assertEqual(request.header.xid, response.header.xid,
48 'response xid != request xid')
49 self.assertEqual(len(response.data), 0, 'response data non-empty')
50
Rich Laneb90a1c42012-10-05 09:16:05 -070051class EchoWithData(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080052 """
53 Test echo response with short string data
54 """
55 def runTest(self):
Rich Lanec3c2ae12013-01-04 10:13:17 -080056 request = message.echo_request(data='OpenFlow Will Rule The World')
Dan Talaycoe226eb12010-02-18 23:06:30 -080057 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070058 self.assertTrue(response is not None,
59 "Did not get echo reply (with data)")
Dan Talayco2c0dba32010-03-06 22:47:06 -080060 self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080061 'response is not echo_reply')
Dan Talaycodba244e2010-02-15 14:08:53 -080062 self.assertEqual(request.header.xid, response.header.xid,
63 'response xid != request xid')
64 self.assertEqual(request.data, response.data,
65 'response data does not match request')
66
Rich Laneb90a1c42012-10-05 09:16:05 -070067class PacketIn(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -080068 """
69 Test packet in function
Dan Talayco6ce963a2010-03-07 21:58:13 -080070
71 Send a packet to each dataplane port and verify that a packet
72 in message is received from the controller for each
Dan Talaycodba244e2010-02-15 14:08:53 -080073 """
74 def runTest(self):
75 # Construct packet to send to dataplane
Dan Talaycoe226eb12010-02-18 23:06:30 -080076 # Send packet to dataplane, once to each port
Dan Talaycodba244e2010-02-15 14:08:53 -080077 # Poll controller with expect message type packet in
Dan Talaycoe226eb12010-02-18 23:06:30 -080078
Rich Lane32bf9482013-01-03 17:26:30 -080079 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -080080 do_barrier(self.controller)
Dan Talayco6ce963a2010-03-07 21:58:13 -080081
Rich Lane2014f9b2012-10-05 15:29:40 -070082 vid = test_param_get('vid', default=TEST_VID_DEFAULT)
Ken Chiangaeb23d62012-08-23 21:20:07 -070083
Rich Lane477f4812012-10-04 22:49:00 -070084 for of_port in config["port_map"].keys():
Ed Swierk0aeff8c2012-03-23 20:27:18 -070085 for pkt, pt in [
86 (simple_tcp_packet(), "simple TCP packet"),
Ken Chiangaeb23d62012-08-23 21:20:07 -070087 (simple_tcp_packet(dl_vlan_enable=True,dl_vlan=vid,pktlen=108),
88 "simple tagged TCP packet"),
Ed Swierk0aeff8c2012-03-23 20:27:18 -070089 (simple_eth_packet(), "simple Ethernet packet"),
90 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -080091
Rich Lane9a003812012-10-04 17:17:59 -070092 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -070093 self.dataplane.send(of_port, str(pkt))
94 #@todo Check for unexpected messages?
95 count = 0
96 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -070097 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Ed Swierk0aeff8c2012-03-23 20:27:18 -070098 if not response: # Timeout
99 break
Ed Swierk506614a2012-03-29 08:16:59 -0700100 if dataplane.match_exp_pkt(pkt, response.data): # Got match
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700101 break
Rich Lane477f4812012-10-04 22:49:00 -0700102 if not config["relax"]: # Only one attempt to match
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700103 break
104 count += 1
105 if count > 10: # Too many tries
106 break
Dan Talayco48370102010-03-03 15:17:33 -0800107
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700108 self.assertTrue(response is not None,
109 'Packet in message not received on port ' +
110 str(of_port))
Ed Swierk506614a2012-03-29 08:16:59 -0700111 if not dataplane.match_exp_pkt(pkt, response.data):
Rich Lane9a003812012-10-04 17:17:59 -0700112 logging.debug("Sent %s" % format_packet(pkt))
113 logging.debug("Resp %s" % format_packet(response.data))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700114 self.assertTrue(False,
115 'Response packet does not match send packet' +
116 ' for port ' + str(of_port))
Dan Talaycodba244e2010-02-15 14:08:53 -0800117
Rich Laneb90a1c42012-10-05 09:16:05 -0700118class PacketInDefaultDrop(base_tests.SimpleDataPlane):
Ed Swierk3ae7f712012-08-22 06:45:25 -0700119 """
120 Test packet in function
121
122 Send a packet to each dataplane port and verify that a packet
123 in message is received from the controller for each
124 """
Rich Laned1d9c282012-10-04 22:07:10 -0700125
126 priority = -1
127
Ed Swierk3ae7f712012-08-22 06:45:25 -0700128 def runTest(self):
Rich Lane32bf9482013-01-03 17:26:30 -0800129 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800130 do_barrier(self.controller)
Ed Swierk3ae7f712012-08-22 06:45:25 -0700131
Rich Lane477f4812012-10-04 22:49:00 -0700132 for of_port in config["port_map"].keys():
Ed Swierk3ae7f712012-08-22 06:45:25 -0700133 pkt = simple_tcp_packet()
134 self.dataplane.send(of_port, str(pkt))
135 count = 0
136 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700137 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Ed Swierk3ae7f712012-08-22 06:45:25 -0700138 if not response: # Timeout
139 break
140 if dataplane.match_exp_pkt(pkt, response.data): # Got match
141 break
Rich Lane477f4812012-10-04 22:49:00 -0700142 if not config["relax"]: # Only one attempt to match
Ed Swierk3ae7f712012-08-22 06:45:25 -0700143 break
144 count += 1
145 if count > 10: # Too many tries
146 break
147
148 self.assertTrue(response is None,
149 'Packet in message received on port ' +
150 str(of_port))
151
Rich Laneb90a1c42012-10-05 09:16:05 -0700152class PacketInBroadcastCheck(base_tests.SimpleDataPlane):
Dan Talayco1f648cb2012-05-03 09:37:56 -0700153 """
154 Check if bcast pkts leak when no flows are present
155
156 Clear the flow table
157 Send in a broadcast pkt
158 Look for the packet on other dataplane ports.
159 """
Rich Laned1d9c282012-10-04 22:07:10 -0700160
161 priority = -1
162
Dan Talayco1f648cb2012-05-03 09:37:56 -0700163 def runTest(self):
164 # Need at least two ports
Rich Lane477f4812012-10-04 22:49:00 -0700165 self.assertTrue(len(config["port_map"]) > 1, "Too few ports for test")
Dan Talayco1f648cb2012-05-03 09:37:56 -0700166
Rich Lane32bf9482013-01-03 17:26:30 -0800167 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800168 do_barrier(self.controller)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700169
Rich Lane477f4812012-10-04 22:49:00 -0700170 of_ports = config["port_map"].keys()
Dan Talayco1f648cb2012-05-03 09:37:56 -0700171 d_port = of_ports[0]
172 pkt = simple_eth_packet(dl_dst='ff:ff:ff:ff:ff:ff')
173
Rich Lane9a003812012-10-04 17:17:59 -0700174 logging.info("BCast Leak Test, send to port %s" % d_port)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700175 self.dataplane.send(d_port, str(pkt))
176
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700177 (of_port, pkt_in, pkt_time) = self.dataplane.poll(exp_pkt=pkt)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700178 self.assertTrue(pkt_in is None,
179 'BCast packet received on port ' + str(of_port))
180
Rich Laneb90a1c42012-10-05 09:16:05 -0700181class PacketOut(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -0800182 """
183 Test packet out function
Dan Talayco6ce963a2010-03-07 21:58:13 -0800184
185 Send packet out message to controller for each dataplane port and
186 verify the packet appears on the appropriate dataplane port
Dan Talaycodba244e2010-02-15 14:08:53 -0800187 """
188 def runTest(self):
189 # Construct packet to send to dataplane
190 # Send packet to dataplane
191 # Poll controller with expect message type packet in
Dan Talayco41eae8b2010-03-10 13:57:06 -0800192
Rich Lane32bf9482013-01-03 17:26:30 -0800193 delete_all_flows(self.controller)
Dan Talaycodba244e2010-02-15 14:08:53 -0800194
195 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700196 of_ports = config["port_map"].keys()
Dan Talayco48370102010-03-03 15:17:33 -0800197 of_ports.sort()
198 for dp_port in of_ports:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700199 for outpkt, opt in [
200 (simple_tcp_packet(), "simple TCP packet"),
201 (simple_eth_packet(), "simple Ethernet packet"),
202 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -0800203
Rich Lane9a003812012-10-04 17:17:59 -0700204 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
Rich Lanec3c2ae12013-01-04 10:13:17 -0800205 msg = message.packet_out(in_port=ofp.OFPP_NONE,
Rich Lane0f0adc92013-01-04 15:13:02 -0800206 data=str(outpkt),
207 actions=[action.action_output(port=dp_port)])
Dan Talaycodba244e2010-02-15 14:08:53 -0800208
Rich Lane9a003812012-10-04 17:17:59 -0700209 logging.info("PacketOut to: " + str(dp_port))
Rich Lane5c3151c2013-01-03 17:15:41 -0800210 self.controller.message_send(msg)
Dan Talaycodba244e2010-02-15 14:08:53 -0800211
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700212 exp_pkt_arg = None
213 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -0700214 if config["relax"]:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700215 exp_pkt_arg = outpkt
216 exp_port = dp_port
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700217 (of_port, pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700218 exp_pkt=exp_pkt_arg)
219
220 self.assertTrue(pkt is not None, 'Packet not received')
Rich Lane9a003812012-10-04 17:17:59 -0700221 logging.info("PacketOut: got pkt from " + str(of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700222 if of_port is not None:
223 self.assertEqual(of_port, dp_port, "Unexpected receive port")
Ed Swierk506614a2012-03-29 08:16:59 -0700224 if not dataplane.match_exp_pkt(outpkt, pkt):
Rich Lane9a003812012-10-04 17:17:59 -0700225 logging.debug("Sent %s" % format_packet(outpkt))
226 logging.debug("Resp %s" % format_packet(
Dan Talayco2baf8b52012-03-30 09:55:42 -0700227 str(pkt)[:len(str(outpkt))]))
Dan Talaycodc6fca32012-03-30 10:05:49 -0700228 self.assertEqual(str(outpkt), str(pkt)[:len(str(outpkt))],
229 'Response packet does not match send packet')
Dan Talaycodba244e2010-02-15 14:08:53 -0800230
Rich Laneb90a1c42012-10-05 09:16:05 -0700231class PacketOutMC(base_tests.SimpleDataPlane):
Ken Chiang1bf01602012-04-04 10:48:23 -0700232 """
233 Test packet out to multiple output ports
234
235 Send packet out message to controller for 1 to N dataplane ports and
236 verify the packet appears on the appropriate ports
237 """
238 def runTest(self):
239 # Construct packet to send to dataplane
240 # Send packet to dataplane
241 # Poll controller with expect message type packet in
242
Rich Lane32bf9482013-01-03 17:26:30 -0800243 delete_all_flows(self.controller)
Ken Chiang1bf01602012-04-04 10:48:23 -0700244
245 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700246 of_ports = config["port_map"].keys()
Ken Chiang1bf01602012-04-04 10:48:23 -0700247 random.shuffle(of_ports)
248 for num_ports in range(1,len(of_ports)+1):
249 for outpkt, opt in [
250 (simple_tcp_packet(), "simple TCP packet"),
251 (simple_eth_packet(), "simple Ethernet packet"),
252 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
253
254 dp_ports = of_ports[0:num_ports]
Rich Lane9a003812012-10-04 17:17:59 -0700255 logging.info("PKT OUT test with " + opt +
Ken Chiang1bf01602012-04-04 10:48:23 -0700256 ", ports " + str(dp_ports))
Rich Lane0f0adc92013-01-04 15:13:02 -0800257 actions = [action.action_output(port=port) for port in dp_ports]
Rich Lanec3c2ae12013-01-04 10:13:17 -0800258 msg = message.packet_out(in_port=ofp.OFPP_NONE,
Rich Lane0f0adc92013-01-04 15:13:02 -0800259 data=str(outpkt),
260 actions=actions)
Ken Chiang1bf01602012-04-04 10:48:23 -0700261
Rich Lane9a003812012-10-04 17:17:59 -0700262 logging.info("PacketOut to: " + str(dp_ports))
Rich Lane5c3151c2013-01-03 17:15:41 -0800263 self.controller.message_send(msg)
Ken Chiang1bf01602012-04-04 10:48:23 -0700264
265 receive_pkt_check(self.dataplane, outpkt, dp_ports,
266 set(of_ports).difference(dp_ports),
Rich Lane2014f9b2012-10-05 15:29:40 -0700267 self)
Ken Chiang1bf01602012-04-04 10:48:23 -0700268
Rich Laneb90a1c42012-10-05 09:16:05 -0700269class FlowStatsGet(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800270 """
271 Get stats
Dan Talayco2c0dba32010-03-06 22:47:06 -0800272
Dan Talayco6ce963a2010-03-07 21:58:13 -0800273 Simply verify stats get transaction
274 """
Rich Laned1d9c282012-10-04 22:07:10 -0700275
276 priority = -1
277
Dan Talayco6ce963a2010-03-07 21:58:13 -0800278 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700279 logging.info("Running StatsGet")
280 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700281 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800282 self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800283
Rich Lane9a003812012-10-04 17:17:59 -0700284 logging.info("Sending flow request")
Rich Lanec3c2ae12013-01-04 10:13:17 -0800285 request = message.flow_stats_request(out_port=ofp.OFPP_NONE,
286 table_id=0xff)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800287 request.match.wildcards = 0 # ofp.OFPFW_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700288 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700289 self.assertTrue(response is not None,
290 "Did not get response for flow stats")
Rich Lane9a003812012-10-04 17:17:59 -0700291 logging.debug(response.show())
Dan Talayco6ce963a2010-03-07 21:58:13 -0800292
Rich Laneb90a1c42012-10-05 09:16:05 -0700293class TableStatsGet(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700294 """
295 Get table stats
296
297 Simply verify table stats get transaction
298 """
299 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700300 logging.info("Running TableStatsGet")
301 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700302 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800303 self.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700304
Rich Lane9a003812012-10-04 17:17:59 -0700305 logging.info("Sending table stats request")
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700306 request = message.table_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700307 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700308 self.assertTrue(response is not None,
309 "Did not get reply for table stats")
Rich Lane9a003812012-10-04 17:17:59 -0700310 logging.debug(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700311
Rich Laneb90a1c42012-10-05 09:16:05 -0700312class DescStatsGet(base_tests.SimpleProtocol):
Ed Swierkae74c362012-04-02 08:21:41 -0700313 """
314 Get stats
315
316 Simply verify stats get transaction
317 """
318 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700319 logging.info("Running DescStatsGet")
Ed Swierkae74c362012-04-02 08:21:41 -0700320
Rich Lane9a003812012-10-04 17:17:59 -0700321 logging.info("Sending stats request")
Ed Swierkae74c362012-04-02 08:21:41 -0700322 request = message.desc_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700323 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700324 self.assertTrue(response is not None,
325 "Did not get reply for desc stats")
Rich Lane9a003812012-10-04 17:17:59 -0700326 logging.debug(response.show())
Ed Swierkae74c362012-04-02 08:21:41 -0700327
Rich Laneb90a1c42012-10-05 09:16:05 -0700328class FlowMod(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800329 """
330 Insert a flow
331
332 Simple verification of a flow mod transaction
333 """
334
335 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700336 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700337 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800338 self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800339
Rich Laneb90a1c42012-10-05 09:16:05 -0700340class PortConfigMod(base_tests.SimpleProtocol):
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700341 """
342 Modify a bit in port config and verify changed
343
344 Get the switch configuration, modify the port configuration
345 and write it back; get the config again and verify changed.
346 Then set it back to the way it was.
347 """
348
349 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700350 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700351 for of_port, ifname in config["port_map"].items(): # Grab first port
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700352 break
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700353
Rich Lane477f4812012-10-04 22:49:00 -0700354 (hw_addr, port_config, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700355 port_config_get(self.controller, of_port)
Rich Lane477f4812012-10-04 22:49:00 -0700356 self.assertTrue(port_config is not None, "Did not get port config")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700357
Rich Lane9a003812012-10-04 17:17:59 -0700358 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700359 str(port_config & ofp.OFPPC_NO_FLOOD))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700360
361 rv = port_config_set(self.controller, of_port,
Rich Lane477f4812012-10-04 22:49:00 -0700362 port_config ^ ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700363 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lane3a261d52013-01-03 17:45:08 -0800364 do_barrier(self.controller)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700365
366 # Verify change took place with same feature request
Rich Lane477f4812012-10-04 22:49:00 -0700367 (hw_addr, port_config2, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700368 port_config_get(self.controller, of_port)
369 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700370 str(port_config2 & ofp.OFPPC_NO_FLOOD))
371 self.assertTrue(port_config2 is not None, "Did not get port config2")
372 self.assertTrue(port_config2 & ofp.OFPPC_NO_FLOOD !=
373 port_config & ofp.OFPPC_NO_FLOOD,
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700374 "Bit change did not take")
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700375 # Set it back
Rich Lane477f4812012-10-04 22:49:00 -0700376 rv = port_config_set(self.controller, of_port, port_config,
Rich Lane9a003812012-10-04 17:17:59 -0700377 ofp.OFPPC_NO_FLOOD)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700378 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lane3a261d52013-01-03 17:45:08 -0800379 do_barrier(self.controller)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700380
Rich Laneb90a1c42012-10-05 09:16:05 -0700381class PortConfigModErr(base_tests.SimpleProtocol):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700382 """
383 Modify a bit in port config on an invalid port and verify
384 error message is received.
385 """
386
387 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700388 logging.info("Running " + str(self))
Ken Chiangaeb23d62012-08-23 21:20:07 -0700389
390 # pick a random bad port number
391 bad_port = random.randint(1, ofp.OFPP_MAX)
392 count = 0
Rich Lane477f4812012-10-04 22:49:00 -0700393 while (count < 50) and (bad_port in config["port_map"].keys()):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700394 bad_port = random.randint(1, ofp.OFPP_MAX)
395 count = count + 1
396 self.assertTrue(count < 50, "Error selecting bad port")
Rich Lane9a003812012-10-04 17:17:59 -0700397 logging.info("Select " + str(bad_port) + " as invalid port")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700398
399 rv = port_config_set(self.controller, bad_port,
Rich Lane9a003812012-10-04 17:17:59 -0700400 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700401 self.assertTrue(rv != -1, "Error sending port mod")
402
403 # poll for error message
404 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700405 (response, raw) = self.controller.poll(ofp.OFPT_ERROR)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700406 if not response: # Timeout
407 break
408 if response.code == ofp.OFPPMFC_BAD_PORT:
Rich Lane9a003812012-10-04 17:17:59 -0700409 logging.info("Received error message with OFPPMFC_BAD_PORT code")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700410 break
Rich Lane477f4812012-10-04 22:49:00 -0700411 if not config["relax"]: # Only one attempt to match
Ken Chiangaeb23d62012-08-23 21:20:07 -0700412 break
413 count += 1
414 if count > 10: # Too many tries
415 break
416
417 self.assertTrue(response is not None, 'Did not receive error message')
418
Rich Laneb90a1c42012-10-05 09:16:05 -0700419class BadMessage(base_tests.SimpleProtocol):
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700420 """
421 Send a message with a bad type and verify an error is returned
422 """
423
424 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700425 logging.info("Running " + str(self))
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700426 request = illegal_message.illegal_message_type()
427
Dan Talaycoc689a792012-09-28 14:22:53 -0700428 reply, pkt = self.controller.transact(request)
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700429 self.assertTrue(reply is not None, "Did not get response to bad req")
430 self.assertTrue(reply.header.type == ofp.OFPT_ERROR,
431 "reply not an error message")
432 self.assertTrue(reply.type == ofp.OFPET_BAD_REQUEST,
433 "reply error type is not bad request")
434 self.assertTrue(reply.code == ofp.OFPBRC_BAD_TYPE,
435 "reply error code is not bad type")
436
Dan Talaycodba244e2010-02-15 14:08:53 -0800437if __name__ == "__main__":
Dan Talayco2c0dba32010-03-06 22:47:06 -0800438 print "Please run through oft script: ./oft --test_spec=basic"