blob: 3d5f45351cacd6db950bc31e4685d8036507d677 [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
130class VlanPCP(MatchTest):
131 """
132 Match on VLAN PCP (VID matched)
133 """
134 def runTest(self):
135 match = ofp.match([
136 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
137 ofp.oxm.vlan_pcp(3),
138 ])
139
140 matching = {
141 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
142 }
143
144 nonmatching = {
145 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
146 "no vlan tag": simple_tcp_packet(),
147 }
148
149 self.verify_match(match, matching, nonmatching)
150
151class VlanPCPAnyVID(MatchTest):
152 """
153 Match on VLAN PCP (VID present)
154 """
155 def runTest(self):
156 match = ofp.match([
157 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
158 ofp.oxm.vlan_pcp(3),
159 ])
160
161 matching = {
162 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
163 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=3),
164 }
165
166 nonmatching = {
167 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
168 "no vlan tag": simple_tcp_packet(),
169 }
170
171 self.verify_match(match, matching, nonmatching)
172
173class VlanPresent(MatchTest):
174 """
175 Match on any VLAN tag (but must be present)
176 """
177 def runTest(self):
178 match = ofp.match([
179 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
180 ])
181
182 matching = {
183 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
184 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
185 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
186 }
187
188 nonmatching = {
189 "no vlan tag": simple_tcp_packet()
190 }
191
192 self.verify_match(match, matching, nonmatching)
193
194class VlanAbsent(MatchTest):
195 """
196 Match on absent VLAN tag
197 """
198 def runTest(self):
199 match = ofp.match([
200 ofp.oxm.vlan_vid(ofp.OFPVID_NONE),
201 ])
202
203 matching = {
204 "no vlan tag": simple_tcp_packet()
205 }
206
207 nonmatching = {
208 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
209 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
210 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
211 }
212
213 self.verify_match(match, matching, nonmatching)