blob: 6abce492c15bf404951e29f25a6525e01dd6e5a9 [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 Lane074c8ec2013-07-17 19:35:11 -07001155class IPv6TCPSrc(MatchTest):
1156 """
1157 Match on ipv4 tcp source port
1158 """
1159 def runTest(self):
1160 match = ofp.match([
1161 ofp.oxm.eth_type(0x86dd),
1162 ofp.oxm.ip_proto(6),
1163 ofp.oxm.tcp_src(53),
1164 ])
1165
1166 matching = {
1167 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1168 }
1169
1170 nonmatching = {
1171 "tcp sport=52": simple_tcpv6_packet(tcp_sport=52),
1172 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1173 }
1174
1175 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001176
1177class IPv4TCPDst(MatchTest):
1178 """
1179 Match on ipv4 tcp destination port
1180 """
1181 def runTest(self):
1182 match = ofp.match([
1183 ofp.oxm.eth_type(0x0800),
1184 ofp.oxm.ip_proto(6),
1185 ofp.oxm.tcp_dst(53),
1186 ])
1187
1188 matching = {
1189 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1190 }
1191
1192 nonmatching = {
1193 "tcp dport=52": simple_tcp_packet(tcp_dport=52),
1194 "udp dport=53": simple_udp_packet(udp_dport=53),
1195 }
1196
1197 self.verify_match(match, matching, nonmatching)
1198
Rich Lane074c8ec2013-07-17 19:35:11 -07001199class IPv6TCPDst(MatchTest):
1200 """
1201 Match on ipv6 tcp destination port
1202 """
1203 def runTest(self):
1204 match = ofp.match([
1205 ofp.oxm.eth_type(0x86dd),
1206 ofp.oxm.ip_proto(6),
1207 ofp.oxm.tcp_dst(53),
1208 ])
1209
1210 matching = {
1211 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1212 }
1213
1214 nonmatching = {
1215 "tcp dport=52": simple_tcpv6_packet(tcp_dport=52),
1216 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1217 }
1218
1219 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001220
1221class IPv4UDPSrc(MatchTest):
1222 """
1223 Match on ipv4 udp source port
1224 """
1225 def runTest(self):
1226 match = ofp.match([
1227 ofp.oxm.eth_type(0x0800),
1228 ofp.oxm.ip_proto(17),
1229 ofp.oxm.udp_src(53),
1230 ])
1231
1232 matching = {
1233 "udp sport=53": simple_udp_packet(udp_sport=53),
1234 }
1235
1236 nonmatching = {
1237 "udp sport=52": simple_udp_packet(udp_sport=52),
1238 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1239 }
1240
1241 self.verify_match(match, matching, nonmatching)
1242
Rich Lane074c8ec2013-07-17 19:35:11 -07001243class IPv6UDPSrc(MatchTest):
1244 """
1245 Match on ipv4 udp source port
1246 """
1247 def runTest(self):
1248 match = ofp.match([
1249 ofp.oxm.eth_type(0x86dd),
1250 ofp.oxm.ip_proto(17),
1251 ofp.oxm.udp_src(53),
1252 ])
1253
1254 matching = {
1255 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1256 }
1257
1258 nonmatching = {
1259 "udp sport=52": simple_udpv6_packet(udp_sport=52),
1260 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1261 }
1262
1263 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001264
1265class IPv4UDPDst(MatchTest):
1266 """
1267 Match on ipv4 udp destination port
1268 """
1269 def runTest(self):
1270 match = ofp.match([
1271 ofp.oxm.eth_type(0x0800),
1272 ofp.oxm.ip_proto(17),
1273 ofp.oxm.udp_dst(53),
1274 ])
1275
1276 matching = {
1277 "udp dport=53": simple_udp_packet(udp_dport=53),
1278 }
1279
1280 nonmatching = {
1281 "udp dport=52": simple_udp_packet(udp_dport=52),
1282 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1283 }
1284
1285 self.verify_match(match, matching, nonmatching)
1286
Rich Lane074c8ec2013-07-17 19:35:11 -07001287class IPv6UDPDst(MatchTest):
1288 """
1289 Match on ipv4 udp destination port
1290 """
1291 def runTest(self):
1292 match = ofp.match([
1293 ofp.oxm.eth_type(0x86dd),
1294 ofp.oxm.ip_proto(17),
1295 ofp.oxm.udp_dst(53),
1296 ])
1297
1298 matching = {
1299 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1300 }
1301
1302 nonmatching = {
1303 "udp dport=52": simple_udpv6_packet(udp_dport=52),
1304 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1305 }
1306
1307 self.verify_match(match, matching, nonmatching)
Rich Laneee574362013-07-17 16:40:07 -07001308
1309class IPv4ICMPType(MatchTest):
1310 """
1311 Match on ipv4 icmp type
1312 """
1313 def runTest(self):
1314 match = ofp.match([
1315 ofp.oxm.eth_type(0x0800),
1316 ofp.oxm.ip_proto(1),
1317 ofp.oxm.icmpv4_type(3),
1318 ])
1319
1320 matching = {
1321 "type=3 code=1": simple_icmp_packet(icmp_type=3, icmp_code=1),
1322 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1323 }
1324
1325 nonmatching = {
1326 "type=2 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
1327 }
1328
1329 self.verify_match(match, matching, nonmatching)
1330
1331class IPv4ICMPCode(MatchTest):
1332 """
1333 Match on ipv4 icmp code
1334 """
1335 def runTest(self):
1336 match = ofp.match([
1337 ofp.oxm.eth_type(0x0800),
1338 ofp.oxm.ip_proto(1),
1339 ofp.oxm.icmpv4_code(2),
1340 ])
1341
1342 matching = {
1343 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1344 "type=5 code=2": simple_icmp_packet(icmp_type=5, icmp_code=2),
1345 }
1346
1347 nonmatching = {
Rich Lanee1175892013-07-19 18:52:55 -07001348 "type=2 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
Rich Laneee574362013-07-17 16:40:07 -07001349 }
1350
1351 self.verify_match(match, matching, nonmatching)
1352
Rich Lanea4317532013-07-17 19:27:19 -07001353class IPv6ICMPType(MatchTest):
1354 """
1355 Match on ipv6 icmp type
1356 """
1357 def runTest(self):
1358 match = ofp.match([
1359 ofp.oxm.eth_type(0x86dd),
1360 ofp.oxm.ip_proto(58),
1361 ofp.oxm.icmpv6_type(3),
1362 ])
1363
1364 matching = {
1365 "type=3 code=1": simple_icmpv6_packet(icmp_type=3, icmp_code=1),
1366 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1367 }
1368
1369 nonmatching = {
1370 "type=2 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
1371 }
1372
1373 self.verify_match(match, matching, nonmatching)
1374
1375class IPv6ICMPCode(MatchTest):
1376 """
1377 Match on ipv6 icmp code
1378 """
1379 def runTest(self):
1380 match = ofp.match([
1381 ofp.oxm.eth_type(0x86dd),
1382 ofp.oxm.ip_proto(58),
1383 ofp.oxm.icmpv6_code(2),
1384 ])
1385
1386 matching = {
1387 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1388 "type=5 code=2": simple_icmpv6_packet(icmp_type=5, icmp_code=2),
1389 }
1390
1391 nonmatching = {
Rich Lanee1175892013-07-19 18:52:55 -07001392 "type=2 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
Rich Lanea4317532013-07-17 19:27:19 -07001393 }
1394
1395 self.verify_match(match, matching, nonmatching)
Rich Lane6b770992013-07-17 17:11:24 -07001396
1397class ArpOp(MatchTest):
1398 """
1399 Match on ARP operation
1400 """
1401 def runTest(self):
1402 match = ofp.match([
1403 ofp.oxm.eth_type(0x0806),
1404 ofp.oxm.arp_op(3),
1405 ])
1406
1407 matching = {
1408 "op=3": simple_arp_packet(arp_op=3),
1409 }
1410
1411 nonmatching = {
1412 "op=4": simple_arp_packet(arp_op=4),
1413 }
1414
1415 self.verify_match(match, matching, nonmatching)
Rich Lane503a2de2013-07-17 17:20:58 -07001416
1417class ArpSPA(MatchTest):
1418 """
1419 Match on ARP sender IP
1420 """
1421 def runTest(self):
1422 match = ofp.match([
1423 ofp.oxm.eth_type(0x0806),
1424 ofp.oxm.arp_spa(0xc0a80001), # 192.168.0.1
1425 ])
1426
1427 matching = {
1428 "192.168.0.1": simple_arp_packet(ip_snd="192.168.0.1"),
1429 }
1430
1431 nonmatching = {
1432 "192.168.0.2": simple_arp_packet(ip_snd="192.168.0.2"),
1433 }
1434
1435 self.verify_match(match, matching, nonmatching)
1436
Rich Lanef7565362013-07-18 22:33:57 -07001437class ArpSPASubnetMasked(MatchTest):
1438 """
1439 Match on ARP sender IP (subnet mask)
1440 """
1441 def runTest(self):
1442 match = ofp.match([
1443 ofp.oxm.eth_type(0x0806),
1444 # 192.168.0.0/20 (255.255.240.0)
1445 ofp.oxm.arp_spa_masked(0xc0a80000, 0xfffff000),
1446 ])
1447
1448 matching = {
1449 "192.168.0.1": simple_arp_packet(ip_snd='192.168.0.1'),
1450 "192.168.0.2": simple_arp_packet(ip_snd='192.168.0.2'),
1451 "192.168.4.2": simple_arp_packet(ip_snd='192.168.4.2'),
1452 "192.168.0.0": simple_arp_packet(ip_snd='192.168.0.0'),
1453 "192.168.15.255": simple_arp_packet(ip_snd='192.168.15.255'),
1454 }
1455
1456 nonmatching = {
1457 "192.168.16.0": simple_arp_packet(ip_snd='192.168.16.0'),
1458 "192.167.255.255": simple_arp_packet(ip_snd='192.167.255.255'),
1459 "192.168.31.1": simple_arp_packet(ip_snd='192.168.31.1'),
1460 }
1461
1462 self.verify_match(match, matching, nonmatching)
1463
1464class ArpSPAMasked(MatchTest):
1465 """
1466 Match on ARP sender IP (arbitrarily masked)
1467 """
1468 def runTest(self):
1469 match = ofp.match([
1470 ofp.oxm.eth_type(0x0806),
1471 # 192.168.0.1 255.254.255.255
1472 ofp.oxm.arp_spa_masked(0xc0a80001, 0xfffeffff),
1473 ])
1474
1475 matching = {
1476 "192.168.0.1": simple_arp_packet(ip_snd='192.168.0.1'),
1477 "192.169.0.1": simple_arp_packet(ip_snd='192.169.0.1'),
1478 }
1479
1480 nonmatching = {
1481 "192.168.0.2": simple_arp_packet(ip_snd='192.168.0.2'),
1482 "192.167.0.1": simple_arp_packet(ip_snd='192.167.0.1'),
1483 }
1484
1485 self.verify_match(match, matching, nonmatching)
1486
Rich Lane503a2de2013-07-17 17:20:58 -07001487class ArpTPA(MatchTest):
1488 """
1489 Match on ARP target IP
1490 """
1491 def runTest(self):
1492 match = ofp.match([
1493 ofp.oxm.eth_type(0x0806),
1494 ofp.oxm.arp_tpa(0xc0a80001), # 192.168.0.1
1495 ])
1496
1497 matching = {
1498 "192.168.0.1": simple_arp_packet(ip_tgt="192.168.0.1"),
1499 }
1500
1501 nonmatching = {
1502 "192.168.0.2": simple_arp_packet(ip_tgt="192.168.0.2"),
1503 }
1504
1505 self.verify_match(match, matching, nonmatching)
Rich Lanef7565362013-07-18 22:33:57 -07001506
1507class ArpTPASubnetMasked(MatchTest):
1508 """
1509 Match on ARP target IP (subnet mask)
1510 """
1511 def runTest(self):
1512 match = ofp.match([
1513 ofp.oxm.eth_type(0x0806),
1514 # 192.168.0.0/20 (255.255.240.0)
1515 ofp.oxm.arp_tpa_masked(0xc0a80000, 0xfffff000),
1516 ])
1517
1518 matching = {
1519 "192.168.0.1": simple_arp_packet(ip_tgt='192.168.0.1'),
1520 "192.168.0.2": simple_arp_packet(ip_tgt='192.168.0.2'),
1521 "192.168.4.2": simple_arp_packet(ip_tgt='192.168.4.2'),
1522 "192.168.0.0": simple_arp_packet(ip_tgt='192.168.0.0'),
1523 "192.168.15.255": simple_arp_packet(ip_tgt='192.168.15.255'),
1524 }
1525
1526 nonmatching = {
1527 "192.168.16.0": simple_arp_packet(ip_tgt='192.168.16.0'),
1528 "192.167.255.255": simple_arp_packet(ip_tgt='192.167.255.255'),
1529 "192.168.31.1": simple_arp_packet(ip_tgt='192.168.31.1'),
1530 }
1531
1532 self.verify_match(match, matching, nonmatching)
1533
1534class ArpTPAMasked(MatchTest):
1535 """
1536 Match on ARP target IP (arbitrarily masked)
1537 """
1538 def runTest(self):
1539 match = ofp.match([
1540 ofp.oxm.eth_type(0x0806),
1541 # 192.168.0.1 255.254.255.255
1542 ofp.oxm.arp_tpa_masked(0xc0a80001, 0xfffeffff),
1543 ])
1544
1545 matching = {
1546 "192.168.0.1": simple_arp_packet(ip_tgt='192.168.0.1'),
1547 "192.169.0.1": simple_arp_packet(ip_tgt='192.169.0.1'),
1548 }
1549
1550 nonmatching = {
1551 "192.168.0.2": simple_arp_packet(ip_tgt='192.168.0.2'),
1552 "192.167.0.1": simple_arp_packet(ip_tgt='192.167.0.1'),
1553 }
1554
1555 self.verify_match(match, matching, nonmatching)