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