blob: 14a8d45e9e11f2af291f65ae0c74a7ee09cee50b [file] [log] [blame]
Rich Lanea8d74912013-07-16 10:10:39 -07001# Distributed under the OpenFlow Software License (see LICENSE)
2# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
3# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
4"""
5Flow match test cases
6
7These tests check the behavior of each match field. The only action used is a
8single output.
9"""
10
11import logging
12
13from oftest import config
14import oftest.base_tests as base_tests
15import ofp
16
17from oftest.testutils import *
18
19class MatchTest(base_tests.SimpleDataPlane):
20 """
21 Base class for match tests
22 """
23
24 def verify_match(self, match, matching, nonmatching):
25 """
26 Verify matching behavior
27
28 Checks that all the packets in 'matching' match 'match', and that
29 the packets in 'nonmatching' do not.
30
31 'match' is a LOXI match object. 'matching' and 'nonmatching' are
32 dicts mapping from string names (used in log messages) to string
33 packet data.
34 """
35 ports = sorted(config["port_map"].keys())
36 in_port = ports[0]
37 out_port = ports[1]
38
39 logging.info("Running match test for %s", match.show())
40
41 delete_all_flows(self.controller)
42
43 logging.info("Inserting flow sending matching packets to port %d", out_port)
44 request = ofp.message.flow_add(
45 table_id=0,
46 match=match,
47 instructions=[
48 ofp.instruction.apply_actions(
49 actions=[
50 ofp.action.output(
51 port=out_port,
52 max_len=ofp.OFPCML_NO_BUFFER)])],
53 buffer_id=ofp.OFP_NO_BUFFER,
54 priority=1000)
55 self.controller.message_send(request)
56
57 logging.info("Inserting match-all flow sending packets to controller")
58 request = ofp.message.flow_add(
59 table_id=0,
60 instructions=[
61 ofp.instruction.apply_actions(
62 actions=[
63 ofp.action.output(
64 port=ofp.OFPP_CONTROLLER,
65 max_len=ofp.OFPCML_NO_BUFFER)])],
66 buffer_id=ofp.OFP_NO_BUFFER,
67 priority=1)
68 self.controller.message_send(request)
69
70 do_barrier(self.controller)
71
72 for name, pkt in matching.items():
73 logging.info("Sending matching packet %s, expecting output to port %d", repr(name), out_port)
74 pktstr = str(pkt)
75 self.dataplane.send(in_port, pktstr)
76 receive_pkt_verify(self, [out_port], pktstr, in_port)
77
78 for name, pkt in nonmatching.items():
79 logging.info("Sending non-matching packet %s, expecting packet-in", repr(name))
80 pktstr = str(pkt)
81 self.dataplane.send(in_port, pktstr)
82 verify_packet_in(self, pktstr, in_port, ofp.OFPR_ACTION)
83
84class VlanExact(MatchTest):
85 """
86 Match on VLAN VID and PCP
87 """
88 def runTest(self):
89 match = ofp.match([
90 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
91 ofp.oxm.vlan_pcp(3),
92 ])
93
94 matching = {
95 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
96 }
97
98 nonmatching = {
99 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
100 "vid=4 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
101 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
102 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
103 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
104 "no vlan tag": simple_tcp_packet(),
105 }
106
107 self.verify_match(match, matching, nonmatching)
108
109class VlanVID(MatchTest):
110 """
111 Match on VLAN VID
112 """
113 def runTest(self):
114 match = ofp.match([
115 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
116 ])
117
118 matching = {
119 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
120 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
121 }
122
123 nonmatching = {
124 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
125 "no vlan tag": simple_tcp_packet(),
126 }
127
128 self.verify_match(match, matching, nonmatching)
129
Rich Laned51b94f2013-07-16 13:29:55 -0700130class VlanVIDMasked(MatchTest):
131 """
132 Match on VLAN VID (masked)
133 """
134 def runTest(self):
135 match = ofp.match([
136 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT|3, ofp.OFPVID_PRESENT|3),
137 ])
138
139 matching = {
140 "vid=3 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=3, vlan_pcp=2),
141 "vid=7 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=7, vlan_pcp=2),
142 "vid=11 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=11, vlan_pcp=2),
143 }
144
145 nonmatching = {
146 "vid=0 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=2),
147 "vid=1 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=1, vlan_pcp=2),
148 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
149 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
150 "no vlan tag": simple_tcp_packet(),
151 }
152
153 self.verify_match(match, matching, nonmatching)
154
Rich Lanea8d74912013-07-16 10:10:39 -0700155class VlanPCP(MatchTest):
156 """
157 Match on VLAN PCP (VID matched)
158 """
159 def runTest(self):
160 match = ofp.match([
161 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
162 ofp.oxm.vlan_pcp(3),
163 ])
164
165 matching = {
166 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
167 }
168
169 nonmatching = {
170 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
171 "no vlan tag": simple_tcp_packet(),
172 }
173
174 self.verify_match(match, matching, nonmatching)
175
Rich Laned51b94f2013-07-16 13:29:55 -0700176@nonstandard
177class VlanPCPMasked(MatchTest):
178 """
179 Match on VLAN PCP (masked, VID matched)
180 """
181 def runTest(self):
182 match = ofp.match([
183 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
184 ofp.oxm.vlan_pcp_masked(3, 3),
185 ])
186
187 matching = {
188 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
189 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
190 }
191
192 nonmatching = {
193 "vid=2 pcp=1": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=1),
194 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
195 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
196 "vid=2 pcp=5": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=5),
197 "vid=2 pcp=6": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=6),
198 "no vlan tag": simple_tcp_packet(),
199 }
200
201 self.verify_match(match, matching, nonmatching)
202
Rich Lanea8d74912013-07-16 10:10:39 -0700203class VlanPCPAnyVID(MatchTest):
204 """
205 Match on VLAN PCP (VID present)
206 """
207 def runTest(self):
208 match = ofp.match([
209 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
210 ofp.oxm.vlan_pcp(3),
211 ])
212
213 matching = {
214 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
215 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=3),
216 }
217
218 nonmatching = {
219 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
220 "no vlan tag": simple_tcp_packet(),
221 }
222
223 self.verify_match(match, matching, nonmatching)
224
225class VlanPresent(MatchTest):
226 """
227 Match on any VLAN tag (but must be present)
228 """
229 def runTest(self):
230 match = ofp.match([
231 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
232 ])
233
234 matching = {
235 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
236 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
237 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
238 }
239
240 nonmatching = {
241 "no vlan tag": simple_tcp_packet()
242 }
243
244 self.verify_match(match, matching, nonmatching)
245
246class VlanAbsent(MatchTest):
247 """
248 Match on absent VLAN tag
249 """
250 def runTest(self):
251 match = ofp.match([
252 ofp.oxm.vlan_vid(ofp.OFPVID_NONE),
253 ])
254
255 matching = {
256 "no vlan tag": simple_tcp_packet()
257 }
258
259 nonmatching = {
260 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
261 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
262 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
263 }
264
265 self.verify_match(match, matching, nonmatching)