blob: c4d18d15c2d12e2d14c98e7ff92c2696d0d86cfd [file] [log] [blame]
Shudong Zhoudc276ae2012-10-15 16:02:56 -07001"""
2"""
3import struct
4
5import logging
6
7from oftest import config
8import oftest.controller as controller
Rich Laned7b0ffa2013-03-08 15:53:42 -08009import ofp
Shudong Zhoudc276ae2012-10-15 16:02:56 -070010import oftest.base_tests as base_tests
11
12from oftest.testutils import *
13
Rich Lanecb816fd2013-03-26 21:53:47 -070014NX_ROLE_OTHER = 0
15NX_ROLE_MASTER = 1
16NX_ROLE_SLAVE = 2
Shudong Zhoudc276ae2012-10-15 16:02:56 -070017
Rich Lanef41eea62013-03-27 16:05:43 -070018def set_role(test, role):
19 request = ofp.message.nicira_controller_role_request(role=role)
20 response, _ = test.controller.transact(request)
21 test.assertTrue(isinstance(response, ofp.message.nicira_controller_role_reply), "Expected a role reply")
22 test.assertEquals(response.role, role)
23
Rich Lanecb816fd2013-03-26 21:53:47 -070024class AnyReply(base_tests.SimpleDataPlane):
Shudong Zhoudc276ae2012-10-15 16:02:56 -070025 """
Rich Lanecb816fd2013-03-26 21:53:47 -070026 Verify that a role request gets either a role reply or an error.
Shudong Zhoudc276ae2012-10-15 16:02:56 -070027
Rich Lanecb816fd2013-03-26 21:53:47 -070028 This test should pass on any switch, no matter whether it implements
29 the extension.
30 """
Shudong Zhoudc276ae2012-10-15 16:02:56 -070031 def runTest(self):
Rich Lane4b601452013-03-11 23:37:06 -070032 request = ofp.message.nicira_controller_role_request(role=NX_ROLE_MASTER)
Shudong Zhoudc276ae2012-10-15 16:02:56 -070033 response, pkt = self.controller.transact(request)
34 self.assertTrue(response is not None, "No reply to Nicira role request")
Rich Lanecb816fd2013-03-26 21:53:47 -070035 if isinstance(response, ofp.message.nicira_controller_role_reply):
36 logging.info("Role reply received")
37 logging.info(response.show())
38 self.assertEquals(response.role, NX_ROLE_MASTER)
39 elif isinstance(response, ofp.message.error_msg):
40 logging.info("Error message received")
41 logging.info(response.show())
42 self.assertEquals(response.err_type, ofp.OFPET_BAD_REQUEST)
43 self.assertEquals(response.code, ofp.OFPBRC_BAD_VENDOR)
44 else:
45 raise AssertionError("Unexpected reply type")
Rich Lanef41eea62013-03-27 16:05:43 -070046
47@nonstandard
48class RolePermissions(base_tests.SimpleDataPlane):
49 """
50 Verify that a slave connection cannot modify switch state, but
51 a master or equal can.
52 """
53 def runTest(self):
54 self.features_reply, _ = self.controller.transact(ofp.message.features_request())
55 delete_all_flows(self.controller)
56 self.verify_permission(True)
57
58 set_role(self, NX_ROLE_MASTER)
59 self.verify_permission(True)
60
61 set_role(self, NX_ROLE_SLAVE)
62 self.verify_permission(False)
63
64 set_role(self, NX_ROLE_OTHER)
65 self.verify_permission(True)
66
67 def verify_permission(self, perm):
68 port = self.features_reply.ports[0]
69
70 self.controller.message_send(ofp.message.port_mod(port_no=port.port_no, hw_addr=port.hw_addr))
71 self.controller.message_send(ofp.message.packet_out(buffer_id=0xffffffff))
72 self.controller.message_send(ofp.message.flow_add(buffer_id=0xffffffff))
73 do_barrier(self.controller)
74
75 err_count = 0
76 while self.controller.packets:
77 msg = self.controller.packets.pop(0)[0]
78 if isinstance(msg, ofp.message.error_msg):
79 self.assertEquals(msg.err_type, ofp.OFPET_BAD_REQUEST)
80 self.assertEquals(msg.code, ofp.OFPBRC_EPERM)
81 err_count += 1
82
83 if perm:
84 self.assertEquals(err_count, 0, "Expected no errors")
85 else:
86 self.assertEquals(err_count, 3, "Expected errors for each message")
Rich Lane13c91592013-03-27 17:03:56 -070087
88@nonstandard
89class SlaveNoPacketIn(base_tests.SimpleDataPlane):
90 """
91 Verify that slave connections do not receive OFPT_PACKET_IN messages but other roles do.
92 """
93 def runTest(self):
94 delete_all_flows(self.controller)
95
96 set_role(self, NX_ROLE_MASTER)
97 self.verify_packetin(True)
98
99 set_role(self, NX_ROLE_SLAVE)
100 self.verify_packetin(False)
101
102 set_role(self, NX_ROLE_OTHER)
103 self.verify_packetin(True)
104
105 def verify_packetin(self, enabled):
106 ingress_port = config["port_map"].keys()[0]
107 self.dataplane.send(ingress_port, str(simple_tcp_packet()))
108
109 if enabled:
110 timeout = -1
111 else:
112 timeout = 0.5
113 msg, _ = self.controller.poll(exp_msg=ofp.OFPT_PACKET_IN, timeout=timeout)
114
115 if enabled:
116 self.assertTrue(msg != None, "Expected a packet-in message")
117 else:
118 self.assertTrue(msg == None, "Did not expect a packet-in message")