blob: c56fdcba287699fe7567e3d1731b88f5d089c368 [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Rich Lanea8d74912013-07-16 10:10:39 -070017# Distributed under the OpenFlow Software License (see LICENSE)
18# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
19# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
20"""
21Flow match test cases
22
23These tests check the behavior of each match field. The only action used is a
24single output.
25"""
26
27import logging
28
29from oftest import config
30import oftest.base_tests as base_tests
31import ofp
Rich Lanea68176f2013-08-09 17:41:05 -070032import oftest.packet as scapy
Rich Lanea8d74912013-07-16 10:10:39 -070033
34from oftest.testutils import *
Rich Lanea4f3b732013-07-17 20:32:58 -070035from oftest.parse import parse_ipv6
Rich Lanea8d74912013-07-16 10:10:39 -070036
37class MatchTest(base_tests.SimpleDataPlane):
38 """
39 Base class for match tests
40 """
41
42 def verify_match(self, match, matching, nonmatching):
43 """
44 Verify matching behavior
45
46 Checks that all the packets in 'matching' match 'match', and that
47 the packets in 'nonmatching' do not.
48
49 'match' is a LOXI match object. 'matching' and 'nonmatching' are
50 dicts mapping from string names (used in log messages) to string
51 packet data.
52 """
Rich Lane045db072013-08-06 13:16:30 -070053 in_port, out_port = openflow_ports(2)
Wilson Ng6f539642013-10-28 18:17:44 -070054 table_id = test_param_get("table", 0)
Rich Lanea8d74912013-07-16 10:10:39 -070055
56 logging.info("Running match test for %s", match.show())
57
58 delete_all_flows(self.controller)
59
60 logging.info("Inserting flow sending matching packets to port %d", out_port)
61 request = ofp.message.flow_add(
Wilson Ng42df57a2013-10-28 17:54:57 -070062 table_id=table_id,
Rich Lanea8d74912013-07-16 10:10:39 -070063 match=match,
64 instructions=[
65 ofp.instruction.apply_actions(
66 actions=[
67 ofp.action.output(
68 port=out_port,
69 max_len=ofp.OFPCML_NO_BUFFER)])],
70 buffer_id=ofp.OFP_NO_BUFFER,
71 priority=1000)
72 self.controller.message_send(request)
73
74 logging.info("Inserting match-all flow sending packets to controller")
75 request = ofp.message.flow_add(
Wilson Ng42df57a2013-10-28 17:54:57 -070076 table_id=table_id,
Rich Lanea8d74912013-07-16 10:10:39 -070077 instructions=[
78 ofp.instruction.apply_actions(
79 actions=[
80 ofp.action.output(
81 port=ofp.OFPP_CONTROLLER,
82 max_len=ofp.OFPCML_NO_BUFFER)])],
83 buffer_id=ofp.OFP_NO_BUFFER,
84 priority=1)
85 self.controller.message_send(request)
86
87 do_barrier(self.controller)
88
89 for name, pkt in matching.items():
90 logging.info("Sending matching packet %s, expecting output to port %d", repr(name), out_port)
91 pktstr = str(pkt)
92 self.dataplane.send(in_port, pktstr)
Rich Lanee4b384d2013-09-13 14:33:40 -070093 verify_packets(self, pktstr, [out_port])
Rich Lanea8d74912013-07-16 10:10:39 -070094
95 for name, pkt in nonmatching.items():
96 logging.info("Sending non-matching packet %s, expecting packet-in", repr(name))
97 pktstr = str(pkt)
98 self.dataplane.send(in_port, pktstr)
99 verify_packet_in(self, pktstr, in_port, ofp.OFPR_ACTION)
100
Rich Laneb9d1f4b2013-07-17 18:02:23 -0700101# Does not use MatchTest because the ingress port is not a packet field
102class InPort(base_tests.SimpleDataPlane):
103 """
104 Match on ingress port
105 """
106 def runTest(self):
Rich Lane045db072013-08-06 13:16:30 -0700107 in_port, out_port, bad_port = openflow_ports(3)
Wilson Ng6f539642013-10-28 18:17:44 -0700108 table_id = test_param_get("table", 0)
Rich Laneb9d1f4b2013-07-17 18:02:23 -0700109
110 match = ofp.match([
111 ofp.oxm.in_port(in_port)
112 ])
113
114 pkt = simple_tcp_packet()
115
116 logging.info("Running match test for %s", match.show())
117
118 delete_all_flows(self.controller)
119
120 logging.info("Inserting flow sending matching packets to port %d", out_port)
121 request = ofp.message.flow_add(
Wilson Ng42df57a2013-10-28 17:54:57 -0700122 table_id=table_id,
Rich Laneb9d1f4b2013-07-17 18:02:23 -0700123 match=match,
124 instructions=[
125 ofp.instruction.apply_actions(
126 actions=[
127 ofp.action.output(
128 port=out_port,
129 max_len=ofp.OFPCML_NO_BUFFER)])],
130 buffer_id=ofp.OFP_NO_BUFFER,
131 priority=1000)
132 self.controller.message_send(request)
133
134 logging.info("Inserting match-all flow sending packets to controller")
135 request = ofp.message.flow_add(
Wilson Ng42df57a2013-10-28 17:54:57 -0700136 table_id=table_id,
Rich Laneb9d1f4b2013-07-17 18:02:23 -0700137 instructions=[
138 ofp.instruction.apply_actions(
139 actions=[
140 ofp.action.output(
141 port=ofp.OFPP_CONTROLLER,
142 max_len=ofp.OFPCML_NO_BUFFER)])],
143 buffer_id=ofp.OFP_NO_BUFFER,
144 priority=1)
145 self.controller.message_send(request)
146
147 do_barrier(self.controller)
148
149 pktstr = str(pkt)
150
151 logging.info("Sending packet on matching ingress port, expecting output to port %d", out_port)
152 self.dataplane.send(in_port, pktstr)
Rich Lanee4b384d2013-09-13 14:33:40 -0700153 verify_packets(self, pktstr, [out_port])
Rich Laneb9d1f4b2013-07-17 18:02:23 -0700154
155 logging.info("Sending packet on non-matching ingress port, expecting packet-in")
156 self.dataplane.send(bad_port, pktstr)
157 verify_packet_in(self, pktstr, bad_port, ofp.OFPR_ACTION)
158
Rich Lane059f0122013-07-17 11:54:13 -0700159class EthDst(MatchTest):
160 """
161 Match on ethernet destination
162 """
163 def runTest(self):
164 match = ofp.match([
165 ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
166 ])
167
168 matching = {
169 "correct": simple_tcp_packet(eth_dst='00:01:02:03:04:05'),
170 }
171
172 nonmatching = {
173 "incorrect": simple_tcp_packet(eth_dst='00:01:02:03:04:06'),
174 "multicast": simple_tcp_packet(eth_dst='01:01:02:03:04:05'),
175 "local": simple_tcp_packet(eth_dst='02:01:02:03:04:05'),
176 }
177
178 self.verify_match(match, matching, nonmatching)
179
180class EthDstBroadcast(MatchTest):
181 """
182 Match on ethernet destination (broadcast)
183 """
184 def runTest(self):
185 match = ofp.match([
186 ofp.oxm.eth_dst([0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
187 ])
188
189 matching = {
190 "ff:ff:ff:ff:ff:ff": simple_tcp_packet(eth_dst='ff:ff:ff:ff:ff:ff'),
191 }
192
193 nonmatching = {
194 "fd:ff:ff:ff:ff:ff": simple_tcp_packet(eth_dst='fd:ff:ff:ff:ff:ff'),
195 "fe:ff:ff:ff:ff:ff": simple_tcp_packet(eth_dst='fe:ff:ff:ff:ff:ff'),
196 "ff:fe:ff:ff:ff:ff": simple_tcp_packet(eth_dst='ff:fe:ff:ff:ff:ff'),
197 }
198
199 self.verify_match(match, matching, nonmatching)
200
201class EthDstMulticast(MatchTest):
202 """
203 Match on ethernet destination (IPv4 multicast)
204 """
205 def runTest(self):
206 match = ofp.match([
207 ofp.oxm.eth_dst([0x01, 0x00, 0x5e, 0xed, 0x99, 0x02])
208 ])
209
210 matching = {
211 "correct": simple_tcp_packet(eth_dst='01:00:5e:ed:99:02'),
212 }
213
214 nonmatching = {
215 "incorrect": simple_tcp_packet(eth_dst='01:00:5e:ed:99:03'),
216 "unicast": simple_tcp_packet(eth_dst='00:00:5e:ed:99:02'),
Rich Lane0a2d0d22013-07-19 19:05:18 -0700217 "broadcast": simple_tcp_packet(eth_dst='ff:ff:ff:ff:ff:ff'),
Rich Lane059f0122013-07-17 11:54:13 -0700218 "local": simple_tcp_packet(eth_dst='03:00:5e:ed:99:02'),
219 }
220
221 self.verify_match(match, matching, nonmatching)
222
223class EthDstMasked(MatchTest):
224 """
225 Match on ethernet destination (masked)
226 """
227 def runTest(self):
228 match = ofp.match([
229 ofp.oxm.eth_dst_masked([0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
230 [0x00, 0xff, 0xff, 0x0f, 0xff, 0xff])
231 ])
232
233 matching = {
234 "00:01:02:03:04:05": simple_tcp_packet(eth_dst='00:01:02:03:04:05'),
235 "ff:01:02:f3:04:05": simple_tcp_packet(eth_dst='ff:01:02:f3:04:05'),
236 }
237
238 nonmatching = {
239 "00:02:02:03:04:05": simple_tcp_packet(eth_dst='00:02:02:03:04:05'),
240 "00:01:02:07:04:05": simple_tcp_packet(eth_dst='00:01:02:07:04:05'),
241 }
242
243 self.verify_match(match, matching, nonmatching)
244
245class EthSrc(MatchTest):
246 """
247 Match on ethernet source
248 """
249 def runTest(self):
250 match = ofp.match([
251 ofp.oxm.eth_src([0,1,2,3,4,5])
252 ])
253
254 matching = {
255 "correct": simple_tcp_packet(eth_src='00:01:02:03:04:05'),
256 }
257
258 nonmatching = {
259 "incorrect": simple_tcp_packet(eth_src='00:01:02:03:04:06'),
260 "multicast": simple_tcp_packet(eth_src='01:01:02:03:04:05'),
261 "local": simple_tcp_packet(eth_src='02:01:02:03:04:05'),
262 }
263
264 self.verify_match(match, matching, nonmatching)
265
Rich Lane0a2d0d22013-07-19 19:05:18 -0700266class EthSrcBroadcast(MatchTest):
267 """
268 Match on ethernet source (broadcast)
269 """
270 def runTest(self):
271 match = ofp.match([
272 ofp.oxm.eth_src([0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
273 ])
274
275 matching = {
276 "ff:ff:ff:ff:ff:ff": simple_tcp_packet(eth_src='ff:ff:ff:ff:ff:ff'),
277 }
278
279 nonmatching = {
280 "fd:ff:ff:ff:ff:ff": simple_tcp_packet(eth_src='fd:ff:ff:ff:ff:ff'),
281 "fe:ff:ff:ff:ff:ff": simple_tcp_packet(eth_src='fe:ff:ff:ff:ff:ff'),
282 "ff:fe:ff:ff:ff:ff": simple_tcp_packet(eth_src='ff:fe:ff:ff:ff:ff'),
283 }
284
285 self.verify_match(match, matching, nonmatching)
286
287class EthSrcMulticast(MatchTest):
288 """
289 Match on ethernet source (IPv4 multicast)
290 """
291 def runTest(self):
292 match = ofp.match([
293 ofp.oxm.eth_src([0x01, 0x00, 0x5e, 0xed, 0x99, 0x02])
294 ])
295
296 matching = {
297 "correct": simple_tcp_packet(eth_src='01:00:5e:ed:99:02'),
298 }
299
300 nonmatching = {
301 "incorrect": simple_tcp_packet(eth_src='01:00:5e:ed:99:03'),
302 "unicast": simple_tcp_packet(eth_src='00:00:5e:ed:99:02'),
303 "broadcast": simple_tcp_packet(eth_src='ff:ff:ff:ff:ff:ff'),
304 "local": simple_tcp_packet(eth_src='03:00:5e:ed:99:02'),
305 }
306
307 self.verify_match(match, matching, nonmatching)
308
Rich Lane059f0122013-07-17 11:54:13 -0700309class EthSrcMasked(MatchTest):
310 """
311 Match on ethernet source (masked)
312 """
313 def runTest(self):
314 match = ofp.match([
315 ofp.oxm.eth_src_masked([0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
316 [0x00, 0xff, 0xff, 0x0f, 0xff, 0xff])
317 ])
318
319 matching = {
320 "00:01:02:03:04:05": simple_tcp_packet(eth_src='00:01:02:03:04:05'),
321 "ff:01:02:f3:04:05": simple_tcp_packet(eth_src='ff:01:02:f3:04:05'),
322 }
323
324 nonmatching = {
325 "00:02:02:03:04:05": simple_tcp_packet(eth_src='00:02:02:03:04:05'),
326 "00:01:02:07:04:05": simple_tcp_packet(eth_src='00:01:02:07:04:05'),
327 }
328
329 self.verify_match(match, matching, nonmatching)
330
Rich Lane14f10e22013-07-17 14:24:35 -0700331class EthTypeIPv4(MatchTest):
332 """
333 Match on ethertype (IPv4)
334 """
335 def runTest(self):
336 match = ofp.match([
337 ofp.oxm.eth_type(0x0800)
338 ])
339
340 snap_pkt = \
341 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=48)/ \
342 scapy.LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03)/ \
343 scapy.SNAP(OUI=0x000000, code=0x0800)/ \
344 scapy.IP(src='192.168.0.1', dst='192.168.0.2', proto=6)/ \
345 scapy.TCP(sport=1234, dport=80)
346
347 llc_pkt = \
348 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=17)/ \
349 scapy.LLC(dsap=0xaa, ssap=0xab, ctrl=0x03)
350
351 matching = {
352 "ipv4/tcp": simple_tcp_packet(),
353 "ipv4/udp": simple_udp_packet(),
354 "ipv4/icmp": simple_icmp_packet(),
355 "vlan tagged": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
356 "llc/snap": snap_pkt,
357 }
358
359 nonmatching = {
360 "arp": simple_arp_packet(),
361 "llc": llc_pkt,
Rich Lane86aceb02013-07-17 18:45:38 -0700362 "ipv6/tcp": simple_tcpv6_packet(),
363 }
364
365 self.verify_match(match, matching, nonmatching)
366
367class EthTypeIPv6(MatchTest):
368 """
369 Match on ethertype (IPv6)
370 """
371 def runTest(self):
372 match = ofp.match([
373 ofp.oxm.eth_type(0x86dd)
374 ])
375
376 matching = {
377 "ipv6/tcp": simple_tcpv6_packet(),
378 "ipv6/udp": simple_udpv6_packet(),
379 "ipv6/icmp": simple_icmpv6_packet(),
380 "vlan tagged": simple_tcpv6_packet(vlan_vid=2, vlan_pcp=3),
381 }
382
383 nonmatching = {
384 "ipv4/tcp": simple_tcp_packet(),
385 "arp": simple_arp_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700386 }
387
388 self.verify_match(match, matching, nonmatching)
389
390class EthTypeARP(MatchTest):
391 """
392 Match on ethertype (ARP)
393 """
394 def runTest(self):
395 match = ofp.match([
396 ofp.oxm.eth_type(0x0806)
397 ])
398
399 matching = {
400 "arp": simple_arp_packet(),
401 # TODO vlan tagged
402 }
403
404 nonmatching = {
405 "ipv4/tcp": simple_tcp_packet(),
Rich Lane86aceb02013-07-17 18:45:38 -0700406 "ipv6/tcp": simple_tcpv6_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700407 }
408
409 self.verify_match(match, matching, nonmatching)
410
411class EthTypeNone(MatchTest):
412 """
413 Match on no ethertype (IEEE 802.3 without SNAP header)
414 """
415 def runTest(self):
416 match = ofp.match([
417 ofp.oxm.eth_type(0x05ff)
418 ])
419
420 snap_pkt = \
421 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=48)/ \
422 scapy.LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03)/ \
423 scapy.SNAP(OUI=0x000000, code=0x0800)/ \
424 scapy.IP(src='192.168.0.1', dst='192.168.0.2', proto=6)/ \
425 scapy.TCP(sport=1234, dport=80)
426
427 llc_pkt = \
428 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=17)/ \
429 scapy.LLC(dsap=0xaa, ssap=0xab, ctrl=0x03)
430
431 matching = {
432 "llc": llc_pkt,
433 }
434
435 nonmatching = {
436 "ipv4/tcp": simple_tcp_packet(),
Rich Lane86aceb02013-07-17 18:45:38 -0700437 "ipv6/tcp": simple_tcpv6_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700438 "llc/snap": snap_pkt,
439 }
440
441 self.verify_match(match, matching, nonmatching)
442
Rich Lanea8d74912013-07-16 10:10:39 -0700443class VlanExact(MatchTest):
444 """
445 Match on VLAN VID and PCP
446 """
447 def runTest(self):
448 match = ofp.match([
449 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
450 ofp.oxm.vlan_pcp(3),
451 ])
452
453 matching = {
454 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
455 }
456
457 nonmatching = {
458 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
Rich Lanee1175892013-07-19 18:52:55 -0700459 "vid=4 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=3),
460 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
461 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=3),
462 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
Rich Lanea8d74912013-07-16 10:10:39 -0700463 "no vlan tag": simple_tcp_packet(),
464 }
465
466 self.verify_match(match, matching, nonmatching)
467
468class VlanVID(MatchTest):
469 """
470 Match on VLAN VID
471 """
472 def runTest(self):
473 match = ofp.match([
474 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
475 ])
476
477 matching = {
478 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
479 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
480 }
481
482 nonmatching = {
483 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
484 "no vlan tag": simple_tcp_packet(),
485 }
486
487 self.verify_match(match, matching, nonmatching)
488
Rich Laned51b94f2013-07-16 13:29:55 -0700489class VlanVIDMasked(MatchTest):
490 """
491 Match on VLAN VID (masked)
492 """
493 def runTest(self):
494 match = ofp.match([
495 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT|3, ofp.OFPVID_PRESENT|3),
496 ])
497
498 matching = {
499 "vid=3 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=3, vlan_pcp=2),
500 "vid=7 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=7, vlan_pcp=2),
501 "vid=11 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=11, vlan_pcp=2),
502 }
503
504 nonmatching = {
505 "vid=0 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=2),
506 "vid=1 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=1, vlan_pcp=2),
507 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
508 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
509 "no vlan tag": simple_tcp_packet(),
510 }
511
512 self.verify_match(match, matching, nonmatching)
513
Rich Lanea8d74912013-07-16 10:10:39 -0700514class VlanPCP(MatchTest):
515 """
516 Match on VLAN PCP (VID matched)
517 """
518 def runTest(self):
519 match = ofp.match([
520 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
521 ofp.oxm.vlan_pcp(3),
522 ])
523
524 matching = {
525 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
526 }
527
528 nonmatching = {
529 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
530 "no vlan tag": simple_tcp_packet(),
531 }
532
533 self.verify_match(match, matching, nonmatching)
534
Rich Laned51b94f2013-07-16 13:29:55 -0700535@nonstandard
536class VlanPCPMasked(MatchTest):
537 """
538 Match on VLAN PCP (masked, VID matched)
539 """
540 def runTest(self):
541 match = ofp.match([
542 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
543 ofp.oxm.vlan_pcp_masked(3, 3),
544 ])
545
546 matching = {
547 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
548 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
549 }
550
551 nonmatching = {
552 "vid=2 pcp=1": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=1),
553 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
554 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
555 "vid=2 pcp=5": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=5),
556 "vid=2 pcp=6": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=6),
557 "no vlan tag": simple_tcp_packet(),
558 }
559
560 self.verify_match(match, matching, nonmatching)
561
Rich Lanea8d74912013-07-16 10:10:39 -0700562class VlanPCPAnyVID(MatchTest):
563 """
564 Match on VLAN PCP (VID present)
565 """
566 def runTest(self):
567 match = ofp.match([
568 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
569 ofp.oxm.vlan_pcp(3),
570 ])
571
572 matching = {
573 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
574 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=3),
575 }
576
577 nonmatching = {
578 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
579 "no vlan tag": simple_tcp_packet(),
580 }
581
582 self.verify_match(match, matching, nonmatching)
583
584class VlanPresent(MatchTest):
585 """
586 Match on any VLAN tag (but must be present)
587 """
588 def runTest(self):
589 match = ofp.match([
590 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
591 ])
592
593 matching = {
594 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
595 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
596 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
597 }
598
599 nonmatching = {
600 "no vlan tag": simple_tcp_packet()
601 }
602
603 self.verify_match(match, matching, nonmatching)
604
605class VlanAbsent(MatchTest):
606 """
607 Match on absent VLAN tag
608 """
609 def runTest(self):
610 match = ofp.match([
611 ofp.oxm.vlan_vid(ofp.OFPVID_NONE),
612 ])
613
614 matching = {
615 "no vlan tag": simple_tcp_packet()
616 }
617
618 nonmatching = {
619 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
620 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
621 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
622 }
623
624 self.verify_match(match, matching, nonmatching)
Rich Lane11f6d772013-07-17 15:27:46 -0700625
626class IPv4Dscp(MatchTest):
627 """
628 Match on ipv4 dscp
629 """
630 def runTest(self):
631 match = ofp.match([
632 ofp.oxm.eth_type(0x0800),
633 ofp.oxm.ip_dscp(4),
634 ])
635
636 matching = {
637 "dscp=4 ecn=0": simple_tcp_packet(ip_tos=0x10),
638 "dscp=4 ecn=3": simple_tcp_packet(ip_tos=0x13),
639 }
640
641 nonmatching = {
642 "dscp=5 ecn=0": simple_tcp_packet(ip_tos=0x14),
643 }
644
645 self.verify_match(match, matching, nonmatching)
646
Rich Lane93bbc542013-07-17 19:06:24 -0700647class IPv6Dscp(MatchTest):
648 """
649 Match on ipv6 dscp
650 """
651 def runTest(self):
652 match = ofp.match([
653 ofp.oxm.eth_type(0x86dd),
654 ofp.oxm.ip_dscp(4),
655 ])
656
657 matching = {
658 "dscp=4 ecn=0": simple_tcpv6_packet(ipv6_tc=0x10),
659 "dscp=4 ecn=3": simple_tcpv6_packet(ipv6_tc=0x13),
660 }
661
662 nonmatching = {
663 "dscp=5 ecn=0": simple_tcpv6_packet(ipv6_tc=0x14),
664 }
665
666 self.verify_match(match, matching, nonmatching)
Rich Lane11f6d772013-07-17 15:27:46 -0700667
668class IPv4Ecn(MatchTest):
669 """
670 Match on ipv4 ecn
671 """
672 def runTest(self):
673 match = ofp.match([
674 ofp.oxm.eth_type(0x0800),
675 ofp.oxm.ip_ecn(2),
676 ])
677
678 matching = {
679 "dscp=4 ecn=2": simple_tcp_packet(ip_tos=0x12),
680 "dscp=6 ecn=2": simple_tcp_packet(ip_tos=0x1a),
681 }
682
683 nonmatching = {
684 "dscp=4 ecn=0": simple_tcp_packet(ip_tos=0x10),
685 "dscp=4 ecn=3": simple_tcp_packet(ip_tos=0x13),
686 }
687
688 self.verify_match(match, matching, nonmatching)
689
Rich Lane93bbc542013-07-17 19:06:24 -0700690class IPv6Ecn(MatchTest):
691 """
692 Match on ipv6 ecn
693 """
694 def runTest(self):
695 match = ofp.match([
696 ofp.oxm.eth_type(0x86dd),
697 ofp.oxm.ip_ecn(2),
698 ])
699
700 matching = {
701 "dscp=4 ecn=2": simple_tcpv6_packet(ipv6_tc=0x12),
702 "dscp=6 ecn=2": simple_tcpv6_packet(ipv6_tc=0x1a),
703 }
704
705 nonmatching = {
706 "dscp=4 ecn=0": simple_tcpv6_packet(ipv6_tc=0x10),
707 "dscp=4 ecn=3": simple_tcpv6_packet(ipv6_tc=0x13),
708 }
709
710 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700711
712class IPv4ProtoTCP(MatchTest):
713 """
714 Match on ipv4 protocol field (TCP)
715 """
716 def runTest(self):
717 match = ofp.match([
718 ofp.oxm.eth_type(0x0800),
719 ofp.oxm.ip_proto(6),
720 ])
721
722 matching = {
723 "tcp": simple_tcp_packet(),
724 }
725
726 nonmatching = {
727 "udp": simple_udp_packet(),
728 "icmp": simple_icmp_packet(),
729 }
730
731 self.verify_match(match, matching, nonmatching)
732
Rich Lane745e8b22013-07-17 19:16:16 -0700733class IPv6ProtoTCP(MatchTest):
734 """
735 Match on ipv6 protocol field (TCP)
736 """
737 def runTest(self):
738 match = ofp.match([
739 ofp.oxm.eth_type(0x86dd),
740 ofp.oxm.ip_proto(6),
741 ])
742
743 matching = {
744 "tcp": simple_tcpv6_packet(),
745 }
746
747 nonmatching = {
748 "udp": simple_udpv6_packet(),
749 "icmp": simple_icmpv6_packet(),
750 }
751
752 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700753
754class IPv4ProtoUDP(MatchTest):
755 """
756 Match on ipv4 protocol field (UDP)
757 """
758 def runTest(self):
759 match = ofp.match([
760 ofp.oxm.eth_type(0x0800),
761 ofp.oxm.ip_proto(17),
762 ])
763
764 matching = {
765 "udp": simple_udp_packet(),
766 }
767
768 nonmatching = {
769 "tcp": simple_tcp_packet(),
770 "icmp": simple_icmp_packet(),
771 }
772
773 self.verify_match(match, matching, nonmatching)
774
Rich Lane745e8b22013-07-17 19:16:16 -0700775class IPv6ProtoUDP(MatchTest):
776 """
777 Match on ipv6 protocol field (UDP)
778 """
779 def runTest(self):
780 match = ofp.match([
781 ofp.oxm.eth_type(0x86dd),
782 ofp.oxm.ip_proto(17),
783 ])
784
785 matching = {
786 "udp": simple_udpv6_packet(),
787 }
788
789 nonmatching = {
790 "tcp": simple_tcpv6_packet(),
791 "icmp": simple_icmpv6_packet(),
792 }
793
794 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700795
796class IPv4ProtoICMP(MatchTest):
797 """
798 Match on ipv4 protocol field (ICMP)
799 """
800 def runTest(self):
801 match = ofp.match([
802 ofp.oxm.eth_type(0x0800),
803 ofp.oxm.ip_proto(1),
804 ])
805
806 matching = {
807 "icmp": simple_icmp_packet(),
808 }
809
810 nonmatching = {
811 "tcp": simple_tcp_packet(),
812 "udp": simple_udp_packet(),
813 }
814
815 self.verify_match(match, matching, nonmatching)
816
Rich Lane745e8b22013-07-17 19:16:16 -0700817class IPv6ProtoICMP(MatchTest):
818 """
819 Match on ipv6 protocol field (ICMP)
820 """
821 def runTest(self):
822 match = ofp.match([
823 ofp.oxm.eth_type(0x86dd),
824 ofp.oxm.ip_proto(58),
825 ])
826
827 matching = {
828 "icmp": simple_icmpv6_packet(),
829 }
830
831 nonmatching = {
832 "tcp": simple_tcpv6_packet(),
833 "udp": simple_udpv6_packet(),
834 }
835
836 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -0700837
Rich Lane3030a4f2013-07-17 16:21:45 -0700838class IPv4Src(MatchTest):
839 """
840 Match on ipv4 source address
841 """
842 def runTest(self):
843 match = ofp.match([
844 ofp.oxm.eth_type(0x0800),
845 ofp.oxm.ipv4_src(0xc0a80001), # 192.168.0.1
846 ])
847
848 matching = {
849 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
850 }
851
852 nonmatching = {
853 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
854 "255.255.255.255": simple_tcp_packet(ip_src='255.255.255.255'),
855 }
856
857 self.verify_match(match, matching, nonmatching)
858
859class IPv4SrcSubnetMasked(MatchTest):
860 """
861 Match on ipv4 source address (subnet masked)
862 """
863 def runTest(self):
864 match = ofp.match([
865 ofp.oxm.eth_type(0x0800),
866 # 192.168.0.0/20 (255.255.240.0)
867 ofp.oxm.ipv4_src_masked(0xc0a80000, 0xfffff000),
868 ])
869
870 matching = {
871 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
872 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
873 "192.168.4.2": simple_tcp_packet(ip_src='192.168.4.2'),
874 "192.168.0.0": simple_tcp_packet(ip_src='192.168.0.0'),
875 "192.168.15.255": simple_tcp_packet(ip_src='192.168.15.255'),
876 }
877
878 nonmatching = {
879 "192.168.16.0": simple_tcp_packet(ip_src='192.168.16.0'),
880 "192.167.255.255": simple_tcp_packet(ip_src='192.167.255.255'),
881 "192.168.31.1": simple_tcp_packet(ip_src='192.168.31.1'),
882 }
883
884 self.verify_match(match, matching, nonmatching)
885
886class IPv4SrcMasked(MatchTest):
887 """
888 Match on ipv4 source address (arbitrarily masked)
889 """
890 def runTest(self):
891 match = ofp.match([
892 ofp.oxm.eth_type(0x0800),
893 # 192.168.0.1 255.254.255.255
894 ofp.oxm.ipv4_src_masked(0xc0a80001, 0xfffeffff),
895 ])
896
897 matching = {
898 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
899 "192.169.0.1": simple_tcp_packet(ip_src='192.169.0.1'),
900 }
901
902 nonmatching = {
903 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
904 "192.167.0.1": simple_tcp_packet(ip_src='192.167.0.1'),
905 }
906
907 self.verify_match(match, matching, nonmatching)
908
909class IPv4Dst(MatchTest):
910 """
Rich Lanee1175892013-07-19 18:52:55 -0700911 Match on ipv4 destination address
Rich Lane3030a4f2013-07-17 16:21:45 -0700912 """
913 def runTest(self):
914 match = ofp.match([
915 ofp.oxm.eth_type(0x0800),
916 ofp.oxm.ipv4_dst(0xc0a80001), # 192.168.0.1
917 ])
918
919 matching = {
920 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
921 }
922
923 nonmatching = {
924 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
925 "255.255.255.255": simple_tcp_packet(ip_dst='255.255.255.255'),
926 }
927
928 self.verify_match(match, matching, nonmatching)
929
930class IPv4DstSubnetMasked(MatchTest):
931 """
Rich Lanee1175892013-07-19 18:52:55 -0700932 Match on ipv4 destination address (subnet masked)
Rich Lane3030a4f2013-07-17 16:21:45 -0700933 """
934 def runTest(self):
935 match = ofp.match([
936 ofp.oxm.eth_type(0x0800),
937 # 192.168.0.0/20 (255.255.240.0)
938 ofp.oxm.ipv4_dst_masked(0xc0a80000, 0xfffff000),
939 ])
940
941 matching = {
942 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
943 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
944 "192.168.4.2": simple_tcp_packet(ip_dst='192.168.4.2'),
945 "192.168.0.0": simple_tcp_packet(ip_dst='192.168.0.0'),
946 "192.168.15.255": simple_tcp_packet(ip_dst='192.168.15.255'),
947 }
948
949 nonmatching = {
950 "192.168.16.0": simple_tcp_packet(ip_dst='192.168.16.0'),
951 "192.167.255.255": simple_tcp_packet(ip_dst='192.167.255.255'),
952 "192.168.31.1": simple_tcp_packet(ip_dst='192.168.31.1'),
953 }
954
955 self.verify_match(match, matching, nonmatching)
956
957class IPv4DstMasked(MatchTest):
958 """
Rich Lanee1175892013-07-19 18:52:55 -0700959 Match on ipv4 destination address (arbitrarily masked)
Rich Lane3030a4f2013-07-17 16:21:45 -0700960 """
961 def runTest(self):
962 match = ofp.match([
963 ofp.oxm.eth_type(0x0800),
964 # 192.168.0.1 255.254.255.255
965 ofp.oxm.ipv4_dst_masked(0xc0a80001, 0xfffeffff),
966 ])
967
968 matching = {
969 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
970 "192.169.0.1": simple_tcp_packet(ip_dst='192.169.0.1'),
971 }
972
973 nonmatching = {
974 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
975 "192.167.0.1": simple_tcp_packet(ip_dst='192.167.0.1'),
976 }
977
978 self.verify_match(match, matching, nonmatching)
979
Rich Lanea4f3b732013-07-17 20:32:58 -0700980class IPv6Src(MatchTest):
981 """
982 Match on ipv6 source address
983 """
984 def runTest(self):
985 correct = "2001:db8:85a3::8a2e:370:7334"
986 incorrect = "2001:db8:85a3::8a2e:370:7324"
987 unspecified = "::"
988
989 match = ofp.match([
990 ofp.oxm.eth_type(0x86dd),
991 ofp.oxm.ipv6_src(parse_ipv6(correct)),
992 ])
993
994 matching = {
995 "correct": simple_tcpv6_packet(ipv6_src=correct),
996 }
997
998 nonmatching = {
999 "incorrect": simple_tcpv6_packet(ipv6_src=incorrect),
1000 "unspecified": simple_tcpv6_packet(ipv6_src=unspecified),
1001 }
1002
1003 self.verify_match(match, matching, nonmatching)
1004
1005class IPv6SrcSubnetMasked(MatchTest):
1006 """
1007 Match on ipv6 source address (subnet masked)
1008 """
1009 def runTest(self):
1010 flow = "2001:0db8:85a3::"
1011 mask = "ffff:ffff:ffff::"
1012 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
1013 correct2 = "2001:0db8:85a3::ffff:ffff:ffff"
1014 incorrect1 = "2001:0db8:85a2::"
1015
1016 match = ofp.match([
1017 ofp.oxm.eth_type(0x86dd),
1018 ofp.oxm.ipv6_src_masked(parse_ipv6(flow), parse_ipv6(mask)),
1019 ])
1020
1021 matching = {
1022 "flow": simple_tcpv6_packet(ipv6_src=flow),
1023 "correct1": simple_tcpv6_packet(ipv6_src=correct1),
1024 "correct2": simple_tcpv6_packet(ipv6_src=correct2),
1025 }
1026
1027 nonmatching = {
1028 "incorrect1": simple_tcpv6_packet(ipv6_src=incorrect1),
1029 }
1030
1031 self.verify_match(match, matching, nonmatching)
1032
1033class IPv6SrcMasked(MatchTest):
1034 """
1035 Match on ipv6 source address (arbitrarily masked)
1036 """
1037 def runTest(self):
1038 flow = "2001:0db8:85a3::0001"
1039 mask = "ffff:ffff:ffff::000f"
1040 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
1041 correct2 = "2001:0db8:85a3::ffff:ffff:fff1"
1042 incorrect1 = "2001:0db8:85a2::0001"
1043 incorrect2 = "2001:0db8:85a3::0000"
1044
1045 match = ofp.match([
1046 ofp.oxm.eth_type(0x86dd),
1047 ofp.oxm.ipv6_src_masked(parse_ipv6(flow), parse_ipv6(mask)),
1048 ])
1049
1050 matching = {
1051 "flow": simple_tcpv6_packet(ipv6_src=flow),
1052 "correct1": simple_tcpv6_packet(ipv6_src=correct1),
1053 "correct2": simple_tcpv6_packet(ipv6_src=correct2),
1054 }
1055
1056 nonmatching = {
1057 "incorrect1": simple_tcpv6_packet(ipv6_src=incorrect1),
1058 "incorrect2": simple_tcpv6_packet(ipv6_src=incorrect2),
1059 }
1060
1061 self.verify_match(match, matching, nonmatching)
1062
1063class IPv6Dst(MatchTest):
1064 """
1065 Match on ipv6 destination address
1066 """
1067 def runTest(self):
1068 correct = "2001:db8:85a3::8a2e:370:7334"
1069 incorrect = "2001:db8:85a3::8a2e:370:7324"
1070 unspecified = "::"
1071
1072 match = ofp.match([
1073 ofp.oxm.eth_type(0x86dd),
1074 ofp.oxm.ipv6_dst(parse_ipv6(correct)),
1075 ])
1076
1077 matching = {
1078 "correct": simple_tcpv6_packet(ipv6_dst=correct),
1079 }
1080
1081 nonmatching = {
1082 "incorrect": simple_tcpv6_packet(ipv6_dst=incorrect),
1083 "unspecified": simple_tcpv6_packet(ipv6_dst=unspecified),
1084 }
1085
1086 self.verify_match(match, matching, nonmatching)
1087
1088class IPv6DstSubnetMasked(MatchTest):
1089 """
1090 Match on ipv6 destination address (subnet masked)
1091 """
1092 def runTest(self):
1093 flow = "2001:0db8:85a3::"
1094 mask = "ffff:ffff:ffff::"
1095 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
1096 correct2 = "2001:0db8:85a3::ffff:ffff:ffff"
1097 incorrect1 = "2001:0db8:85a2::"
1098
1099 match = ofp.match([
1100 ofp.oxm.eth_type(0x86dd),
1101 ofp.oxm.ipv6_dst_masked(parse_ipv6(flow), parse_ipv6(mask)),
1102 ])
1103
1104 matching = {
1105 "flow": simple_tcpv6_packet(ipv6_dst=flow),
1106 "correct1": simple_tcpv6_packet(ipv6_dst=correct1),
1107 "correct2": simple_tcpv6_packet(ipv6_dst=correct2),
1108 }
1109
1110 nonmatching = {
1111 "incorrect1": simple_tcpv6_packet(ipv6_dst=incorrect1),
1112 }
1113
1114 self.verify_match(match, matching, nonmatching)
1115
1116class IPv6DstMasked(MatchTest):
1117 """
1118 Match on ipv6 destination address (arbitrarily masked)
1119 """
1120 def runTest(self):
1121 flow = "2001:0db8:85a3::0001"
1122 mask = "ffff:ffff:ffff::000f"
1123 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
1124 correct2 = "2001:0db8:85a3::ffff:ffff:fff1"
1125 incorrect1 = "2001:0db8:85a2::0001"
1126 incorrect2 = "2001:0db8:85a3::0000"
1127
1128 match = ofp.match([
1129 ofp.oxm.eth_type(0x86dd),
1130 ofp.oxm.ipv6_dst_masked(parse_ipv6(flow), parse_ipv6(mask)),
1131 ])
1132
1133 matching = {
1134 "flow": simple_tcpv6_packet(ipv6_dst=flow),
1135 "correct1": simple_tcpv6_packet(ipv6_dst=correct1),
1136 "correct2": simple_tcpv6_packet(ipv6_dst=correct2),
1137 }
1138
1139 nonmatching = {
1140 "incorrect1": simple_tcpv6_packet(ipv6_dst=incorrect1),
1141 "incorrect2": simple_tcpv6_packet(ipv6_dst=incorrect2),
1142 }
1143
1144 self.verify_match(match, matching, nonmatching)
Rich Lane3030a4f2013-07-17 16:21:45 -07001145
Rich Lane05e756b2013-07-17 15:48:16 -07001146class IPv4TCPSrc(MatchTest):
1147 """
1148 Match on ipv4 tcp source port
1149 """
1150 def runTest(self):
1151 match = ofp.match([
1152 ofp.oxm.eth_type(0x0800),
1153 ofp.oxm.ip_proto(6),
1154 ofp.oxm.tcp_src(53),
1155 ])
1156
1157 matching = {
1158 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1159 }
1160
1161 nonmatching = {
1162 "tcp sport=52": simple_tcp_packet(tcp_sport=52),
1163 "udp sport=53": simple_udp_packet(udp_sport=53),
1164 }
1165
1166 self.verify_match(match, matching, nonmatching)
1167
Rich Lane2e6dc512013-07-19 19:05:39 -07001168@nonstandard
1169class IPv4TCPSrcMasked(MatchTest):
1170 """
1171 Match on ipv4 tcp source port (masked)
1172 """
1173 def runTest(self):
1174 match = ofp.match([
1175 ofp.oxm.eth_type(0x0800),
1176 ofp.oxm.ip_proto(6),
1177 ofp.oxm.tcp_src_masked(52, 0xFE),
1178 ])
1179
1180 matching = {
1181 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1182 "tcp sport=52": simple_tcp_packet(tcp_sport=52),
1183 }
1184
1185 nonmatching = {
1186 "tcp sport=54": simple_tcp_packet(tcp_sport=54),
1187 "tcp sport=51": simple_tcp_packet(tcp_sport=51),
1188 }
1189
1190 self.verify_match(match, matching, nonmatching)
1191
Rich Lane074c8ec2013-07-17 19:35:11 -07001192class IPv6TCPSrc(MatchTest):
1193 """
1194 Match on ipv4 tcp source port
1195 """
1196 def runTest(self):
1197 match = ofp.match([
1198 ofp.oxm.eth_type(0x86dd),
1199 ofp.oxm.ip_proto(6),
1200 ofp.oxm.tcp_src(53),
1201 ])
1202
1203 matching = {
1204 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1205 }
1206
1207 nonmatching = {
1208 "tcp sport=52": simple_tcpv6_packet(tcp_sport=52),
1209 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1210 }
1211
1212 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001213
1214class IPv4TCPDst(MatchTest):
1215 """
1216 Match on ipv4 tcp destination port
1217 """
1218 def runTest(self):
1219 match = ofp.match([
1220 ofp.oxm.eth_type(0x0800),
1221 ofp.oxm.ip_proto(6),
1222 ofp.oxm.tcp_dst(53),
1223 ])
1224
1225 matching = {
1226 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1227 }
1228
1229 nonmatching = {
1230 "tcp dport=52": simple_tcp_packet(tcp_dport=52),
1231 "udp dport=53": simple_udp_packet(udp_dport=53),
1232 }
1233
1234 self.verify_match(match, matching, nonmatching)
1235
Rich Lane2e6dc512013-07-19 19:05:39 -07001236@nonstandard
1237class IPv4TCPDstMasked(MatchTest):
1238 """
1239 Match on ipv4 tcp destination port (masked)
1240 """
1241 def runTest(self):
1242 match = ofp.match([
1243 ofp.oxm.eth_type(0x0800),
1244 ofp.oxm.ip_proto(6),
1245 ofp.oxm.tcp_dst_masked(52, 0xFE),
1246 ])
1247
1248 matching = {
1249 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1250 "tcp dport=52": simple_tcp_packet(tcp_dport=52),
1251 }
1252
1253 nonmatching = {
1254 "tcp dport=54": simple_tcp_packet(tcp_dport=54),
1255 "tcp dport=51": simple_tcp_packet(tcp_dport=51),
1256 }
1257
1258 self.verify_match(match, matching, nonmatching)
1259
Rich Lane074c8ec2013-07-17 19:35:11 -07001260class IPv6TCPDst(MatchTest):
1261 """
1262 Match on ipv6 tcp destination port
1263 """
1264 def runTest(self):
1265 match = ofp.match([
1266 ofp.oxm.eth_type(0x86dd),
1267 ofp.oxm.ip_proto(6),
1268 ofp.oxm.tcp_dst(53),
1269 ])
1270
1271 matching = {
1272 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1273 }
1274
1275 nonmatching = {
1276 "tcp dport=52": simple_tcpv6_packet(tcp_dport=52),
1277 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1278 }
1279
1280 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001281
1282class IPv4UDPSrc(MatchTest):
1283 """
1284 Match on ipv4 udp source port
1285 """
1286 def runTest(self):
1287 match = ofp.match([
1288 ofp.oxm.eth_type(0x0800),
1289 ofp.oxm.ip_proto(17),
1290 ofp.oxm.udp_src(53),
1291 ])
1292
1293 matching = {
1294 "udp sport=53": simple_udp_packet(udp_sport=53),
1295 }
1296
1297 nonmatching = {
1298 "udp sport=52": simple_udp_packet(udp_sport=52),
1299 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1300 }
1301
1302 self.verify_match(match, matching, nonmatching)
1303
Rich Lane2e6dc512013-07-19 19:05:39 -07001304@nonstandard
1305class IPv4UDPSrcMasked(MatchTest):
1306 """
1307 Match on ipv4 udp source port (masked)
1308 """
1309 def runTest(self):
1310 match = ofp.match([
1311 ofp.oxm.eth_type(0x0800),
1312 ofp.oxm.ip_proto(17),
1313 ofp.oxm.udp_src_masked(52, 0xFE),
1314 ])
1315
1316 matching = {
1317 "udp sport=53": simple_udp_packet(udp_sport=53),
1318 "udp sport=52": simple_udp_packet(udp_sport=52),
1319 }
1320
1321 nonmatching = {
1322 "udp sport=54": simple_udp_packet(udp_sport=54),
1323 "udp sport=51": simple_udp_packet(udp_sport=51),
1324 }
1325
1326 self.verify_match(match, matching, nonmatching)
1327
Rich Lane074c8ec2013-07-17 19:35:11 -07001328class IPv6UDPSrc(MatchTest):
1329 """
1330 Match on ipv4 udp source port
1331 """
1332 def runTest(self):
1333 match = ofp.match([
1334 ofp.oxm.eth_type(0x86dd),
1335 ofp.oxm.ip_proto(17),
1336 ofp.oxm.udp_src(53),
1337 ])
1338
1339 matching = {
1340 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1341 }
1342
1343 nonmatching = {
1344 "udp sport=52": simple_udpv6_packet(udp_sport=52),
1345 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1346 }
1347
1348 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001349
1350class IPv4UDPDst(MatchTest):
1351 """
1352 Match on ipv4 udp destination port
1353 """
1354 def runTest(self):
1355 match = ofp.match([
1356 ofp.oxm.eth_type(0x0800),
1357 ofp.oxm.ip_proto(17),
1358 ofp.oxm.udp_dst(53),
1359 ])
1360
1361 matching = {
1362 "udp dport=53": simple_udp_packet(udp_dport=53),
1363 }
1364
1365 nonmatching = {
1366 "udp dport=52": simple_udp_packet(udp_dport=52),
1367 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1368 }
1369
1370 self.verify_match(match, matching, nonmatching)
1371
Rich Lane2e6dc512013-07-19 19:05:39 -07001372@nonstandard
1373class IPv4UDPDstMasked(MatchTest):
1374 """
1375 Match on ipv4 udp destination port (masked)
1376 """
1377 def runTest(self):
1378 match = ofp.match([
1379 ofp.oxm.eth_type(0x0800),
1380 ofp.oxm.ip_proto(17),
1381 ofp.oxm.udp_dst_masked(52, 0xFE),
1382 ])
1383
1384 matching = {
1385 "udp dport=53": simple_udp_packet(udp_dport=53),
1386 "udp dport=52": simple_udp_packet(udp_dport=52),
1387 }
1388
1389 nonmatching = {
1390 "udp dport=54": simple_udp_packet(udp_dport=54),
1391 "udp dport=51": simple_udp_packet(udp_dport=51),
1392 }
1393
1394 self.verify_match(match, matching, nonmatching)
1395
Rich Lane074c8ec2013-07-17 19:35:11 -07001396class IPv6UDPDst(MatchTest):
1397 """
1398 Match on ipv4 udp destination port
1399 """
1400 def runTest(self):
1401 match = ofp.match([
1402 ofp.oxm.eth_type(0x86dd),
1403 ofp.oxm.ip_proto(17),
1404 ofp.oxm.udp_dst(53),
1405 ])
1406
1407 matching = {
1408 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1409 }
1410
1411 nonmatching = {
1412 "udp dport=52": simple_udpv6_packet(udp_dport=52),
1413 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1414 }
1415
1416 self.verify_match(match, matching, nonmatching)
Rich Laneee574362013-07-17 16:40:07 -07001417
1418class IPv4ICMPType(MatchTest):
1419 """
1420 Match on ipv4 icmp type
1421 """
1422 def runTest(self):
1423 match = ofp.match([
1424 ofp.oxm.eth_type(0x0800),
1425 ofp.oxm.ip_proto(1),
1426 ofp.oxm.icmpv4_type(3),
1427 ])
1428
1429 matching = {
1430 "type=3 code=1": simple_icmp_packet(icmp_type=3, icmp_code=1),
1431 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1432 }
1433
1434 nonmatching = {
1435 "type=2 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
1436 }
1437
1438 self.verify_match(match, matching, nonmatching)
1439
1440class IPv4ICMPCode(MatchTest):
1441 """
1442 Match on ipv4 icmp code
1443 """
1444 def runTest(self):
1445 match = ofp.match([
1446 ofp.oxm.eth_type(0x0800),
1447 ofp.oxm.ip_proto(1),
1448 ofp.oxm.icmpv4_code(2),
1449 ])
1450
1451 matching = {
1452 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1453 "type=5 code=2": simple_icmp_packet(icmp_type=5, icmp_code=2),
1454 }
1455
1456 nonmatching = {
Rich Lanee1175892013-07-19 18:52:55 -07001457 "type=2 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
Rich Laneee574362013-07-17 16:40:07 -07001458 }
1459
1460 self.verify_match(match, matching, nonmatching)
1461
Rich Lanea4317532013-07-17 19:27:19 -07001462class IPv6ICMPType(MatchTest):
1463 """
1464 Match on ipv6 icmp type
1465 """
1466 def runTest(self):
1467 match = ofp.match([
1468 ofp.oxm.eth_type(0x86dd),
1469 ofp.oxm.ip_proto(58),
1470 ofp.oxm.icmpv6_type(3),
1471 ])
1472
1473 matching = {
1474 "type=3 code=1": simple_icmpv6_packet(icmp_type=3, icmp_code=1),
1475 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1476 }
1477
1478 nonmatching = {
1479 "type=2 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
1480 }
1481
1482 self.verify_match(match, matching, nonmatching)
1483
1484class IPv6ICMPCode(MatchTest):
1485 """
1486 Match on ipv6 icmp code
1487 """
1488 def runTest(self):
1489 match = ofp.match([
1490 ofp.oxm.eth_type(0x86dd),
1491 ofp.oxm.ip_proto(58),
1492 ofp.oxm.icmpv6_code(2),
1493 ])
1494
1495 matching = {
1496 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1497 "type=5 code=2": simple_icmpv6_packet(icmp_type=5, icmp_code=2),
1498 }
1499
1500 nonmatching = {
Rich Lanee1175892013-07-19 18:52:55 -07001501 "type=2 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
Rich Lanea4317532013-07-17 19:27:19 -07001502 }
1503
1504 self.verify_match(match, matching, nonmatching)
Rich Lane6b770992013-07-17 17:11:24 -07001505
1506class ArpOp(MatchTest):
1507 """
1508 Match on ARP operation
1509 """
1510 def runTest(self):
1511 match = ofp.match([
1512 ofp.oxm.eth_type(0x0806),
1513 ofp.oxm.arp_op(3),
1514 ])
1515
1516 matching = {
1517 "op=3": simple_arp_packet(arp_op=3),
1518 }
1519
1520 nonmatching = {
1521 "op=4": simple_arp_packet(arp_op=4),
1522 }
1523
1524 self.verify_match(match, matching, nonmatching)
Rich Lane503a2de2013-07-17 17:20:58 -07001525
1526class ArpSPA(MatchTest):
1527 """
1528 Match on ARP sender IP
1529 """
1530 def runTest(self):
1531 match = ofp.match([
1532 ofp.oxm.eth_type(0x0806),
1533 ofp.oxm.arp_spa(0xc0a80001), # 192.168.0.1
1534 ])
1535
1536 matching = {
1537 "192.168.0.1": simple_arp_packet(ip_snd="192.168.0.1"),
1538 }
1539
1540 nonmatching = {
1541 "192.168.0.2": simple_arp_packet(ip_snd="192.168.0.2"),
1542 }
1543
1544 self.verify_match(match, matching, nonmatching)
1545
Rich Lanef7565362013-07-18 22:33:57 -07001546class ArpSPASubnetMasked(MatchTest):
1547 """
1548 Match on ARP sender IP (subnet mask)
1549 """
1550 def runTest(self):
1551 match = ofp.match([
1552 ofp.oxm.eth_type(0x0806),
1553 # 192.168.0.0/20 (255.255.240.0)
1554 ofp.oxm.arp_spa_masked(0xc0a80000, 0xfffff000),
1555 ])
1556
1557 matching = {
1558 "192.168.0.1": simple_arp_packet(ip_snd='192.168.0.1'),
1559 "192.168.0.2": simple_arp_packet(ip_snd='192.168.0.2'),
1560 "192.168.4.2": simple_arp_packet(ip_snd='192.168.4.2'),
1561 "192.168.0.0": simple_arp_packet(ip_snd='192.168.0.0'),
1562 "192.168.15.255": simple_arp_packet(ip_snd='192.168.15.255'),
1563 }
1564
1565 nonmatching = {
1566 "192.168.16.0": simple_arp_packet(ip_snd='192.168.16.0'),
1567 "192.167.255.255": simple_arp_packet(ip_snd='192.167.255.255'),
1568 "192.168.31.1": simple_arp_packet(ip_snd='192.168.31.1'),
1569 }
1570
1571 self.verify_match(match, matching, nonmatching)
1572
1573class ArpSPAMasked(MatchTest):
1574 """
1575 Match on ARP sender IP (arbitrarily masked)
1576 """
1577 def runTest(self):
1578 match = ofp.match([
1579 ofp.oxm.eth_type(0x0806),
1580 # 192.168.0.1 255.254.255.255
1581 ofp.oxm.arp_spa_masked(0xc0a80001, 0xfffeffff),
1582 ])
1583
1584 matching = {
1585 "192.168.0.1": simple_arp_packet(ip_snd='192.168.0.1'),
1586 "192.169.0.1": simple_arp_packet(ip_snd='192.169.0.1'),
1587 }
1588
1589 nonmatching = {
1590 "192.168.0.2": simple_arp_packet(ip_snd='192.168.0.2'),
1591 "192.167.0.1": simple_arp_packet(ip_snd='192.167.0.1'),
1592 }
1593
1594 self.verify_match(match, matching, nonmatching)
1595
Rich Lane503a2de2013-07-17 17:20:58 -07001596class ArpTPA(MatchTest):
1597 """
1598 Match on ARP target IP
1599 """
1600 def runTest(self):
1601 match = ofp.match([
1602 ofp.oxm.eth_type(0x0806),
1603 ofp.oxm.arp_tpa(0xc0a80001), # 192.168.0.1
1604 ])
1605
1606 matching = {
1607 "192.168.0.1": simple_arp_packet(ip_tgt="192.168.0.1"),
1608 }
1609
1610 nonmatching = {
1611 "192.168.0.2": simple_arp_packet(ip_tgt="192.168.0.2"),
1612 }
1613
1614 self.verify_match(match, matching, nonmatching)
Rich Lanef7565362013-07-18 22:33:57 -07001615
1616class ArpTPASubnetMasked(MatchTest):
1617 """
1618 Match on ARP target IP (subnet mask)
1619 """
1620 def runTest(self):
1621 match = ofp.match([
1622 ofp.oxm.eth_type(0x0806),
1623 # 192.168.0.0/20 (255.255.240.0)
1624 ofp.oxm.arp_tpa_masked(0xc0a80000, 0xfffff000),
1625 ])
1626
1627 matching = {
1628 "192.168.0.1": simple_arp_packet(ip_tgt='192.168.0.1'),
1629 "192.168.0.2": simple_arp_packet(ip_tgt='192.168.0.2'),
1630 "192.168.4.2": simple_arp_packet(ip_tgt='192.168.4.2'),
1631 "192.168.0.0": simple_arp_packet(ip_tgt='192.168.0.0'),
1632 "192.168.15.255": simple_arp_packet(ip_tgt='192.168.15.255'),
1633 }
1634
1635 nonmatching = {
1636 "192.168.16.0": simple_arp_packet(ip_tgt='192.168.16.0'),
1637 "192.167.255.255": simple_arp_packet(ip_tgt='192.167.255.255'),
1638 "192.168.31.1": simple_arp_packet(ip_tgt='192.168.31.1'),
1639 }
1640
1641 self.verify_match(match, matching, nonmatching)
1642
1643class ArpTPAMasked(MatchTest):
1644 """
1645 Match on ARP target IP (arbitrarily masked)
1646 """
1647 def runTest(self):
1648 match = ofp.match([
1649 ofp.oxm.eth_type(0x0806),
1650 # 192.168.0.1 255.254.255.255
1651 ofp.oxm.arp_tpa_masked(0xc0a80001, 0xfffeffff),
1652 ])
1653
1654 matching = {
1655 "192.168.0.1": simple_arp_packet(ip_tgt='192.168.0.1'),
1656 "192.169.0.1": simple_arp_packet(ip_tgt='192.169.0.1'),
1657 }
1658
1659 nonmatching = {
1660 "192.168.0.2": simple_arp_packet(ip_tgt='192.168.0.2'),
1661 "192.167.0.1": simple_arp_packet(ip_tgt='192.167.0.1'),
1662 }
1663
1664 self.verify_match(match, matching, nonmatching)