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