blob: 89d9a96cc39ec68fc38e67cf88a4e18537676191 [file] [log] [blame]
Dan Talayco5eba8442010-03-10 13:58:43 -08001"""
2Test cases for testing actions taken on packets
3
4See basic.py for other info.
5
6It is recommended that these definitions be kept in their own
7namespace as different groups of tests will likely define
8similar identifiers.
9
10 The function test_set_init is called with a complete configuration
11dictionary prior to the invocation of any tests from this file.
12
13 The switch is actively attempting to contact the controller at the address
14indicated oin oft_config
15
16"""
17
18import logging
19
20import unittest
21
22import oftest.controller as controller
23import oftest.cstruct as ofp
24import oftest.message as message
25import oftest.dataplane as dataplane
26import oftest.action as action
27import oftest.parse as parse
28import basic
29
30from testutils import *
31
32#@var port_map Local copy of the configuration map from OF port
33# numbers to OS interfaces
34pa_port_map = None
35#@var pa_logger Local logger object
36pa_logger = None
37#@var pa_config Local copy of global configuration data
38pa_config = None
39
40def test_set_init(config):
41 """
42 Set up function for packet action test classes
43
44 @param config The configuration dictionary; see oft
45 """
46
47 global pa_port_map
48 global pa_logger
49 global pa_config
50
51 pa_logger = logging.getLogger("pkt_act")
52 pa_logger.info("Initializing test set")
53 pa_port_map = config["port_map"]
54 pa_config = config
55
56class DirectPacket(basic.SimpleDataPlane):
57 """
Dan Talayco2d0d49a2010-05-11 15:29:08 -070058 Send packet to single egress port
Dan Talayco5eba8442010-03-10 13:58:43 -080059
60 Generate a packet
61 Generate and install a matching flow
62 Add action to direct the packet to an egress port
63 Send the packet to ingress dataplane port
64 Verify the packet is received at the egress port only
65 """
66 def runTest(self):
67 global pa_port_map
68 of_ports = pa_port_map.keys()
69 of_ports.sort()
70 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
71
72 rc = delete_all_flows(self.controller, pa_logger)
73 self.assertEqual(rc, 0, "Failed to delete all flows")
74
75 pkt = simple_tcp_packet()
76 match = parse.packet_to_flow_match(pkt)
Dan Talayco7dd6cd62010-03-16 15:02:35 -070077 match.wildcards &= ~ofp.OFPFW_IN_PORT
Dan Talayco5eba8442010-03-10 13:58:43 -080078 self.assertTrue(match is not None,
79 "Could not generate flow match from pkt")
80 act = action.action_output()
81
82 for idx in range(len(of_ports)):
83 ingress_port = of_ports[idx]
84 egress_port = of_ports[(idx + 1) % len(of_ports)]
85 pa_logger.info("Ingress " + str(ingress_port) +
86 " to egress " + str(egress_port))
87
88 match.in_port = ingress_port
89
90 request = message.flow_mod()
91 request.match = match
92 request.buffer_id = 0xffffffff
93 act.port = egress_port
94 self.assertTrue(request.actions.add(act), "Could not add action")
95
96 pa_logger.info("Inserting flow")
97 rv = self.controller.message_send(request)
98 self.assertTrue(rv != -1, "Error installing flow mod")
99 do_barrier(self.controller)
100
101 pa_logger.info("Sending packet to dp port " +
102 str(ingress_port))
103 self.dataplane.send(ingress_port, str(pkt))
104 (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1)
105 self.assertTrue(rcv_pkt is not None, "Did not receive packet")
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700106 pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
Dan Talayco5eba8442010-03-10 13:58:43 -0800107 str(rcv_port))
108 self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
109 self.assertEqual(str(pkt), str(rcv_pkt),
110 'Response packet does not match send packet')
111
112
Dan Talayco2d0d49a2010-05-11 15:29:08 -0700113
114class DirectTwoPorts(basic.SimpleDataPlane):
115 """
116 Send packet to two egress ports
117
118 Generate a packet
119 Generate and install a matching flow
120 Add action to direct the packet to two egress ports
121 Send the packet to ingress dataplane port
122 Verify the packet is received at the two egress ports
123 """
124 def runTest(self):
125 global pa_port_map
126 of_ports = pa_port_map.keys()
127 of_ports.sort()
128 self.assertTrue(len(of_ports) > 2, "Not enough ports for test")
129
130 rc = delete_all_flows(self.controller, pa_logger)
131 self.assertEqual(rc, 0, "Failed to delete all flows")
132
133 pkt = simple_tcp_packet()
134 match = parse.packet_to_flow_match(pkt)
135 match.wildcards &= ~ofp.OFPFW_IN_PORT
136 self.assertTrue(match is not None,
137 "Could not generate flow match from pkt")
138 act = action.action_output()
139
140 for idx in range(len(of_ports)):
141 ingress_port = of_ports[idx]
142 egress_port1 = of_ports[(idx + 1) % len(of_ports)]
143 egress_port2 = of_ports[(idx + 2) % len(of_ports)]
144 pa_logger.info("Ingress " + str(ingress_port) +
145 " to egress " + str(egress_port1) + " and " +
146 str(egress_port2))
147
148 match.in_port = ingress_port
149
150 request = message.flow_mod()
151 request.match = match
152 request.buffer_id = 0xffffffff
153 act.port = egress_port1
154 self.assertTrue(request.actions.add(act), "Could not add action1")
155 act.port = egress_port2
156 self.assertTrue(request.actions.add(act), "Could not add action2")
157 pa_logger.info(request.show())
158
159 pa_logger.info("Inserting flow")
160 rv = self.controller.message_send(request)
161 self.assertTrue(rv != -1, "Error installing flow mod")
162 do_barrier(self.controller)
163
164 pa_logger.info("Sending packet to dp port " +
165 str(ingress_port))
166 self.dataplane.send(ingress_port, str(pkt))
167 (rcv_port1, rcv_pkt1, pkt_time1) = self.dataplane.poll(timeout=1)
168 (rcv_port2, rcv_pkt2, pkt_time2) = self.dataplane.poll(timeout=1)
169 self.assertTrue(rcv_pkt1 is not None, "Did not receive packet 1")
170 self.assertTrue(rcv_pkt2 is not None, "Did not receive packet 2")
171 pa_logger.debug("Packet len " + str(len(rcv_pkt1)) + " in on " +
172 str(rcv_port1))
173 pa_logger.debug("Packet len " + str(len(rcv_pkt2)) + " in on " +
174 str(rcv_port2))
175
176 # Check if ports swapped
177 if (rcv_port1 == egress_port2 and rcv_port2 == egress_port1):
178 (rcv_port2, rcv_port1) = (rcv_port1, rcv_port2)
179 (rcv_pkt2, rcv_pkt1) = (rcv_pkt1, rcv_pkt2)
180 self.assertEqual(rcv_port1, egress_port1,
181 "Unexpected receive port 1")
182 self.assertEqual(rcv_port2, egress_port2,
183 "Unexpected receive port 2")
184 self.assertEqual(str(pkt), str(rcv_pkt1),
185 'Response packet does not match send packet 1')
186 self.assertEqual(str(pkt), str(rcv_pkt2),
187 'Response packet does not match send packet 2')
188
189