blob: ac986224fea9eaddae5516889f44ce96c8a35856 [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'),
204 "local": simple_tcp_packet(eth_dst='03:00:5e:ed:99:02'),
205 }
206
207 self.verify_match(match, matching, nonmatching)
208
209class EthDstMasked(MatchTest):
210 """
211 Match on ethernet destination (masked)
212 """
213 def runTest(self):
214 match = ofp.match([
215 ofp.oxm.eth_dst_masked([0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
216 [0x00, 0xff, 0xff, 0x0f, 0xff, 0xff])
217 ])
218
219 matching = {
220 "00:01:02:03:04:05": simple_tcp_packet(eth_dst='00:01:02:03:04:05'),
221 "ff:01:02:f3:04:05": simple_tcp_packet(eth_dst='ff:01:02:f3:04:05'),
222 }
223
224 nonmatching = {
225 "00:02:02:03:04:05": simple_tcp_packet(eth_dst='00:02:02:03:04:05'),
226 "00:01:02:07:04:05": simple_tcp_packet(eth_dst='00:01:02:07:04:05'),
227 }
228
229 self.verify_match(match, matching, nonmatching)
230
231class EthSrc(MatchTest):
232 """
233 Match on ethernet source
234 """
235 def runTest(self):
236 match = ofp.match([
237 ofp.oxm.eth_src([0,1,2,3,4,5])
238 ])
239
240 matching = {
241 "correct": simple_tcp_packet(eth_src='00:01:02:03:04:05'),
242 }
243
244 nonmatching = {
245 "incorrect": simple_tcp_packet(eth_src='00:01:02:03:04:06'),
246 "multicast": simple_tcp_packet(eth_src='01:01:02:03:04:05'),
247 "local": simple_tcp_packet(eth_src='02:01:02:03:04:05'),
248 }
249
250 self.verify_match(match, matching, nonmatching)
251
252class EthSrcMasked(MatchTest):
253 """
254 Match on ethernet source (masked)
255 """
256 def runTest(self):
257 match = ofp.match([
258 ofp.oxm.eth_src_masked([0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
259 [0x00, 0xff, 0xff, 0x0f, 0xff, 0xff])
260 ])
261
262 matching = {
263 "00:01:02:03:04:05": simple_tcp_packet(eth_src='00:01:02:03:04:05'),
264 "ff:01:02:f3:04:05": simple_tcp_packet(eth_src='ff:01:02:f3:04:05'),
265 }
266
267 nonmatching = {
268 "00:02:02:03:04:05": simple_tcp_packet(eth_src='00:02:02:03:04:05'),
269 "00:01:02:07:04:05": simple_tcp_packet(eth_src='00:01:02:07:04:05'),
270 }
271
272 self.verify_match(match, matching, nonmatching)
273
Rich Lane14f10e22013-07-17 14:24:35 -0700274class EthTypeIPv4(MatchTest):
275 """
276 Match on ethertype (IPv4)
277 """
278 def runTest(self):
279 match = ofp.match([
280 ofp.oxm.eth_type(0x0800)
281 ])
282
283 snap_pkt = \
284 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=48)/ \
285 scapy.LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03)/ \
286 scapy.SNAP(OUI=0x000000, code=0x0800)/ \
287 scapy.IP(src='192.168.0.1', dst='192.168.0.2', proto=6)/ \
288 scapy.TCP(sport=1234, dport=80)
289
290 llc_pkt = \
291 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=17)/ \
292 scapy.LLC(dsap=0xaa, ssap=0xab, ctrl=0x03)
293
294 matching = {
295 "ipv4/tcp": simple_tcp_packet(),
296 "ipv4/udp": simple_udp_packet(),
297 "ipv4/icmp": simple_icmp_packet(),
298 "vlan tagged": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
299 "llc/snap": snap_pkt,
300 }
301
302 nonmatching = {
303 "arp": simple_arp_packet(),
304 "llc": llc_pkt,
Rich Lane86aceb02013-07-17 18:45:38 -0700305 "ipv6/tcp": simple_tcpv6_packet(),
306 }
307
308 self.verify_match(match, matching, nonmatching)
309
310class EthTypeIPv6(MatchTest):
311 """
312 Match on ethertype (IPv6)
313 """
314 def runTest(self):
315 match = ofp.match([
316 ofp.oxm.eth_type(0x86dd)
317 ])
318
319 matching = {
320 "ipv6/tcp": simple_tcpv6_packet(),
321 "ipv6/udp": simple_udpv6_packet(),
322 "ipv6/icmp": simple_icmpv6_packet(),
323 "vlan tagged": simple_tcpv6_packet(vlan_vid=2, vlan_pcp=3),
324 }
325
326 nonmatching = {
327 "ipv4/tcp": simple_tcp_packet(),
328 "arp": simple_arp_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700329 }
330
331 self.verify_match(match, matching, nonmatching)
332
333class EthTypeARP(MatchTest):
334 """
335 Match on ethertype (ARP)
336 """
337 def runTest(self):
338 match = ofp.match([
339 ofp.oxm.eth_type(0x0806)
340 ])
341
342 matching = {
343 "arp": simple_arp_packet(),
344 # TODO vlan tagged
345 }
346
347 nonmatching = {
348 "ipv4/tcp": simple_tcp_packet(),
Rich Lane86aceb02013-07-17 18:45:38 -0700349 "ipv6/tcp": simple_tcpv6_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700350 }
351
352 self.verify_match(match, matching, nonmatching)
353
354class EthTypeNone(MatchTest):
355 """
356 Match on no ethertype (IEEE 802.3 without SNAP header)
357 """
358 def runTest(self):
359 match = ofp.match([
360 ofp.oxm.eth_type(0x05ff)
361 ])
362
363 snap_pkt = \
364 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=48)/ \
365 scapy.LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03)/ \
366 scapy.SNAP(OUI=0x000000, code=0x0800)/ \
367 scapy.IP(src='192.168.0.1', dst='192.168.0.2', proto=6)/ \
368 scapy.TCP(sport=1234, dport=80)
369
370 llc_pkt = \
371 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=17)/ \
372 scapy.LLC(dsap=0xaa, ssap=0xab, ctrl=0x03)
373
374 matching = {
375 "llc": llc_pkt,
376 }
377
378 nonmatching = {
379 "ipv4/tcp": simple_tcp_packet(),
Rich Lane86aceb02013-07-17 18:45:38 -0700380 "ipv6/tcp": simple_tcpv6_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700381 "llc/snap": snap_pkt,
382 }
383
384 self.verify_match(match, matching, nonmatching)
385
Rich Lanea8d74912013-07-16 10:10:39 -0700386class VlanExact(MatchTest):
387 """
388 Match on VLAN VID and PCP
389 """
390 def runTest(self):
391 match = ofp.match([
392 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
393 ofp.oxm.vlan_pcp(3),
394 ])
395
396 matching = {
397 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
398 }
399
400 nonmatching = {
401 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
402 "vid=4 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
403 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
404 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
405 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
406 "no vlan tag": simple_tcp_packet(),
407 }
408
409 self.verify_match(match, matching, nonmatching)
410
411class VlanVID(MatchTest):
412 """
413 Match on VLAN VID
414 """
415 def runTest(self):
416 match = ofp.match([
417 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
418 ])
419
420 matching = {
421 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
422 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
423 }
424
425 nonmatching = {
426 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
427 "no vlan tag": simple_tcp_packet(),
428 }
429
430 self.verify_match(match, matching, nonmatching)
431
Rich Laned51b94f2013-07-16 13:29:55 -0700432class VlanVIDMasked(MatchTest):
433 """
434 Match on VLAN VID (masked)
435 """
436 def runTest(self):
437 match = ofp.match([
438 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT|3, ofp.OFPVID_PRESENT|3),
439 ])
440
441 matching = {
442 "vid=3 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=3, vlan_pcp=2),
443 "vid=7 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=7, vlan_pcp=2),
444 "vid=11 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=11, vlan_pcp=2),
445 }
446
447 nonmatching = {
448 "vid=0 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=2),
449 "vid=1 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=1, vlan_pcp=2),
450 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
451 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
452 "no vlan tag": simple_tcp_packet(),
453 }
454
455 self.verify_match(match, matching, nonmatching)
456
Rich Lanea8d74912013-07-16 10:10:39 -0700457class VlanPCP(MatchTest):
458 """
459 Match on VLAN PCP (VID matched)
460 """
461 def runTest(self):
462 match = ofp.match([
463 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
464 ofp.oxm.vlan_pcp(3),
465 ])
466
467 matching = {
468 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
469 }
470
471 nonmatching = {
472 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
473 "no vlan tag": simple_tcp_packet(),
474 }
475
476 self.verify_match(match, matching, nonmatching)
477
Rich Laned51b94f2013-07-16 13:29:55 -0700478@nonstandard
479class VlanPCPMasked(MatchTest):
480 """
481 Match on VLAN PCP (masked, VID matched)
482 """
483 def runTest(self):
484 match = ofp.match([
485 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
486 ofp.oxm.vlan_pcp_masked(3, 3),
487 ])
488
489 matching = {
490 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
491 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
492 }
493
494 nonmatching = {
495 "vid=2 pcp=1": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=1),
496 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
497 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
498 "vid=2 pcp=5": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=5),
499 "vid=2 pcp=6": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=6),
500 "no vlan tag": simple_tcp_packet(),
501 }
502
503 self.verify_match(match, matching, nonmatching)
504
Rich Lanea8d74912013-07-16 10:10:39 -0700505class VlanPCPAnyVID(MatchTest):
506 """
507 Match on VLAN PCP (VID present)
508 """
509 def runTest(self):
510 match = ofp.match([
511 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
512 ofp.oxm.vlan_pcp(3),
513 ])
514
515 matching = {
516 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
517 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=3),
518 }
519
520 nonmatching = {
521 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
522 "no vlan tag": simple_tcp_packet(),
523 }
524
525 self.verify_match(match, matching, nonmatching)
526
527class VlanPresent(MatchTest):
528 """
529 Match on any VLAN tag (but must be present)
530 """
531 def runTest(self):
532 match = ofp.match([
533 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
534 ])
535
536 matching = {
537 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
538 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
539 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
540 }
541
542 nonmatching = {
543 "no vlan tag": simple_tcp_packet()
544 }
545
546 self.verify_match(match, matching, nonmatching)
547
548class VlanAbsent(MatchTest):
549 """
550 Match on absent VLAN tag
551 """
552 def runTest(self):
553 match = ofp.match([
554 ofp.oxm.vlan_vid(ofp.OFPVID_NONE),
555 ])
556
557 matching = {
558 "no vlan tag": simple_tcp_packet()
559 }
560
561 nonmatching = {
562 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
563 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
564 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
565 }
566
567 self.verify_match(match, matching, nonmatching)
Rich Lane11f6d772013-07-17 15:27:46 -0700568
569class IPv4Dscp(MatchTest):
570 """
571 Match on ipv4 dscp
572 """
573 def runTest(self):
574 match = ofp.match([
575 ofp.oxm.eth_type(0x0800),
576 ofp.oxm.ip_dscp(4),
577 ])
578
579 matching = {
580 "dscp=4 ecn=0": simple_tcp_packet(ip_tos=0x10),
581 "dscp=4 ecn=3": simple_tcp_packet(ip_tos=0x13),
582 }
583
584 nonmatching = {
585 "dscp=5 ecn=0": simple_tcp_packet(ip_tos=0x14),
586 }
587
588 self.verify_match(match, matching, nonmatching)
589
Rich Lane93bbc542013-07-17 19:06:24 -0700590class IPv6Dscp(MatchTest):
591 """
592 Match on ipv6 dscp
593 """
594 def runTest(self):
595 match = ofp.match([
596 ofp.oxm.eth_type(0x86dd),
597 ofp.oxm.ip_dscp(4),
598 ])
599
600 matching = {
601 "dscp=4 ecn=0": simple_tcpv6_packet(ipv6_tc=0x10),
602 "dscp=4 ecn=3": simple_tcpv6_packet(ipv6_tc=0x13),
603 }
604
605 nonmatching = {
606 "dscp=5 ecn=0": simple_tcpv6_packet(ipv6_tc=0x14),
607 }
608
609 self.verify_match(match, matching, nonmatching)
Rich Lane11f6d772013-07-17 15:27:46 -0700610
611class IPv4Ecn(MatchTest):
612 """
613 Match on ipv4 ecn
614 """
615 def runTest(self):
616 match = ofp.match([
617 ofp.oxm.eth_type(0x0800),
618 ofp.oxm.ip_ecn(2),
619 ])
620
621 matching = {
622 "dscp=4 ecn=2": simple_tcp_packet(ip_tos=0x12),
623 "dscp=6 ecn=2": simple_tcp_packet(ip_tos=0x1a),
624 }
625
626 nonmatching = {
627 "dscp=4 ecn=0": simple_tcp_packet(ip_tos=0x10),
628 "dscp=4 ecn=3": simple_tcp_packet(ip_tos=0x13),
629 }
630
631 self.verify_match(match, matching, nonmatching)
632
Rich Lane93bbc542013-07-17 19:06:24 -0700633class IPv6Ecn(MatchTest):
634 """
635 Match on ipv6 ecn
636 """
637 def runTest(self):
638 match = ofp.match([
639 ofp.oxm.eth_type(0x86dd),
640 ofp.oxm.ip_ecn(2),
641 ])
642
643 matching = {
644 "dscp=4 ecn=2": simple_tcpv6_packet(ipv6_tc=0x12),
645 "dscp=6 ecn=2": simple_tcpv6_packet(ipv6_tc=0x1a),
646 }
647
648 nonmatching = {
649 "dscp=4 ecn=0": simple_tcpv6_packet(ipv6_tc=0x10),
650 "dscp=4 ecn=3": simple_tcpv6_packet(ipv6_tc=0x13),
651 }
652
653 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700654
655class IPv4ProtoTCP(MatchTest):
656 """
657 Match on ipv4 protocol field (TCP)
658 """
659 def runTest(self):
660 match = ofp.match([
661 ofp.oxm.eth_type(0x0800),
662 ofp.oxm.ip_proto(6),
663 ])
664
665 matching = {
666 "tcp": simple_tcp_packet(),
667 }
668
669 nonmatching = {
670 "udp": simple_udp_packet(),
671 "icmp": simple_icmp_packet(),
672 }
673
674 self.verify_match(match, matching, nonmatching)
675
Rich Lane745e8b22013-07-17 19:16:16 -0700676class IPv6ProtoTCP(MatchTest):
677 """
678 Match on ipv6 protocol field (TCP)
679 """
680 def runTest(self):
681 match = ofp.match([
682 ofp.oxm.eth_type(0x86dd),
683 ofp.oxm.ip_proto(6),
684 ])
685
686 matching = {
687 "tcp": simple_tcpv6_packet(),
688 }
689
690 nonmatching = {
691 "udp": simple_udpv6_packet(),
692 "icmp": simple_icmpv6_packet(),
693 }
694
695 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700696
697class IPv4ProtoUDP(MatchTest):
698 """
699 Match on ipv4 protocol field (UDP)
700 """
701 def runTest(self):
702 match = ofp.match([
703 ofp.oxm.eth_type(0x0800),
704 ofp.oxm.ip_proto(17),
705 ])
706
707 matching = {
708 "udp": simple_udp_packet(),
709 }
710
711 nonmatching = {
712 "tcp": simple_tcp_packet(),
713 "icmp": simple_icmp_packet(),
714 }
715
716 self.verify_match(match, matching, nonmatching)
717
Rich Lane745e8b22013-07-17 19:16:16 -0700718class IPv6ProtoUDP(MatchTest):
719 """
720 Match on ipv6 protocol field (UDP)
721 """
722 def runTest(self):
723 match = ofp.match([
724 ofp.oxm.eth_type(0x86dd),
725 ofp.oxm.ip_proto(17),
726 ])
727
728 matching = {
729 "udp": simple_udpv6_packet(),
730 }
731
732 nonmatching = {
733 "tcp": simple_tcpv6_packet(),
734 "icmp": simple_icmpv6_packet(),
735 }
736
737 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700738
739class IPv4ProtoICMP(MatchTest):
740 """
741 Match on ipv4 protocol field (ICMP)
742 """
743 def runTest(self):
744 match = ofp.match([
745 ofp.oxm.eth_type(0x0800),
746 ofp.oxm.ip_proto(1),
747 ])
748
749 matching = {
750 "icmp": simple_icmp_packet(),
751 }
752
753 nonmatching = {
754 "tcp": simple_tcp_packet(),
755 "udp": simple_udp_packet(),
756 }
757
758 self.verify_match(match, matching, nonmatching)
759
Rich Lane745e8b22013-07-17 19:16:16 -0700760class IPv6ProtoICMP(MatchTest):
761 """
762 Match on ipv6 protocol field (ICMP)
763 """
764 def runTest(self):
765 match = ofp.match([
766 ofp.oxm.eth_type(0x86dd),
767 ofp.oxm.ip_proto(58),
768 ])
769
770 matching = {
771 "icmp": simple_icmpv6_packet(),
772 }
773
774 nonmatching = {
775 "tcp": simple_tcpv6_packet(),
776 "udp": simple_udpv6_packet(),
777 }
778
779 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -0700780
Rich Lane3030a4f2013-07-17 16:21:45 -0700781class IPv4Src(MatchTest):
782 """
783 Match on ipv4 source address
784 """
785 def runTest(self):
786 match = ofp.match([
787 ofp.oxm.eth_type(0x0800),
788 ofp.oxm.ipv4_src(0xc0a80001), # 192.168.0.1
789 ])
790
791 matching = {
792 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
793 }
794
795 nonmatching = {
796 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
797 "255.255.255.255": simple_tcp_packet(ip_src='255.255.255.255'),
798 }
799
800 self.verify_match(match, matching, nonmatching)
801
802class IPv4SrcSubnetMasked(MatchTest):
803 """
804 Match on ipv4 source address (subnet masked)
805 """
806 def runTest(self):
807 match = ofp.match([
808 ofp.oxm.eth_type(0x0800),
809 # 192.168.0.0/20 (255.255.240.0)
810 ofp.oxm.ipv4_src_masked(0xc0a80000, 0xfffff000),
811 ])
812
813 matching = {
814 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
815 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
816 "192.168.4.2": simple_tcp_packet(ip_src='192.168.4.2'),
817 "192.168.0.0": simple_tcp_packet(ip_src='192.168.0.0'),
818 "192.168.15.255": simple_tcp_packet(ip_src='192.168.15.255'),
819 }
820
821 nonmatching = {
822 "192.168.16.0": simple_tcp_packet(ip_src='192.168.16.0'),
823 "192.167.255.255": simple_tcp_packet(ip_src='192.167.255.255'),
824 "192.168.31.1": simple_tcp_packet(ip_src='192.168.31.1'),
825 }
826
827 self.verify_match(match, matching, nonmatching)
828
829class IPv4SrcMasked(MatchTest):
830 """
831 Match on ipv4 source address (arbitrarily masked)
832 """
833 def runTest(self):
834 match = ofp.match([
835 ofp.oxm.eth_type(0x0800),
836 # 192.168.0.1 255.254.255.255
837 ofp.oxm.ipv4_src_masked(0xc0a80001, 0xfffeffff),
838 ])
839
840 matching = {
841 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
842 "192.169.0.1": simple_tcp_packet(ip_src='192.169.0.1'),
843 }
844
845 nonmatching = {
846 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
847 "192.167.0.1": simple_tcp_packet(ip_src='192.167.0.1'),
848 }
849
850 self.verify_match(match, matching, nonmatching)
851
852class IPv4Dst(MatchTest):
853 """
854 Match on ipv4 source address
855 """
856 def runTest(self):
857 match = ofp.match([
858 ofp.oxm.eth_type(0x0800),
859 ofp.oxm.ipv4_dst(0xc0a80001), # 192.168.0.1
860 ])
861
862 matching = {
863 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
864 }
865
866 nonmatching = {
867 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
868 "255.255.255.255": simple_tcp_packet(ip_dst='255.255.255.255'),
869 }
870
871 self.verify_match(match, matching, nonmatching)
872
873class IPv4DstSubnetMasked(MatchTest):
874 """
875 Match on ipv4 source address (subnet masked)
876 """
877 def runTest(self):
878 match = ofp.match([
879 ofp.oxm.eth_type(0x0800),
880 # 192.168.0.0/20 (255.255.240.0)
881 ofp.oxm.ipv4_dst_masked(0xc0a80000, 0xfffff000),
882 ])
883
884 matching = {
885 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
886 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
887 "192.168.4.2": simple_tcp_packet(ip_dst='192.168.4.2'),
888 "192.168.0.0": simple_tcp_packet(ip_dst='192.168.0.0'),
889 "192.168.15.255": simple_tcp_packet(ip_dst='192.168.15.255'),
890 }
891
892 nonmatching = {
893 "192.168.16.0": simple_tcp_packet(ip_dst='192.168.16.0'),
894 "192.167.255.255": simple_tcp_packet(ip_dst='192.167.255.255'),
895 "192.168.31.1": simple_tcp_packet(ip_dst='192.168.31.1'),
896 }
897
898 self.verify_match(match, matching, nonmatching)
899
900class IPv4DstMasked(MatchTest):
901 """
902 Match on ipv4 source address (arbitrarily masked)
903 """
904 def runTest(self):
905 match = ofp.match([
906 ofp.oxm.eth_type(0x0800),
907 # 192.168.0.1 255.254.255.255
908 ofp.oxm.ipv4_dst_masked(0xc0a80001, 0xfffeffff),
909 ])
910
911 matching = {
912 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
913 "192.169.0.1": simple_tcp_packet(ip_dst='192.169.0.1'),
914 }
915
916 nonmatching = {
917 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
918 "192.167.0.1": simple_tcp_packet(ip_dst='192.167.0.1'),
919 }
920
921 self.verify_match(match, matching, nonmatching)
922
Rich Lanea4f3b732013-07-17 20:32:58 -0700923class IPv6Src(MatchTest):
924 """
925 Match on ipv6 source address
926 """
927 def runTest(self):
928 correct = "2001:db8:85a3::8a2e:370:7334"
929 incorrect = "2001:db8:85a3::8a2e:370:7324"
930 unspecified = "::"
931
932 match = ofp.match([
933 ofp.oxm.eth_type(0x86dd),
934 ofp.oxm.ipv6_src(parse_ipv6(correct)),
935 ])
936
937 matching = {
938 "correct": simple_tcpv6_packet(ipv6_src=correct),
939 }
940
941 nonmatching = {
942 "incorrect": simple_tcpv6_packet(ipv6_src=incorrect),
943 "unspecified": simple_tcpv6_packet(ipv6_src=unspecified),
944 }
945
946 self.verify_match(match, matching, nonmatching)
947
948class IPv6SrcSubnetMasked(MatchTest):
949 """
950 Match on ipv6 source address (subnet masked)
951 """
952 def runTest(self):
953 flow = "2001:0db8:85a3::"
954 mask = "ffff:ffff:ffff::"
955 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
956 correct2 = "2001:0db8:85a3::ffff:ffff:ffff"
957 incorrect1 = "2001:0db8:85a2::"
958
959 match = ofp.match([
960 ofp.oxm.eth_type(0x86dd),
961 ofp.oxm.ipv6_src_masked(parse_ipv6(flow), parse_ipv6(mask)),
962 ])
963
964 matching = {
965 "flow": simple_tcpv6_packet(ipv6_src=flow),
966 "correct1": simple_tcpv6_packet(ipv6_src=correct1),
967 "correct2": simple_tcpv6_packet(ipv6_src=correct2),
968 }
969
970 nonmatching = {
971 "incorrect1": simple_tcpv6_packet(ipv6_src=incorrect1),
972 }
973
974 self.verify_match(match, matching, nonmatching)
975
976class IPv6SrcMasked(MatchTest):
977 """
978 Match on ipv6 source address (arbitrarily masked)
979 """
980 def runTest(self):
981 flow = "2001:0db8:85a3::0001"
982 mask = "ffff:ffff:ffff::000f"
983 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
984 correct2 = "2001:0db8:85a3::ffff:ffff:fff1"
985 incorrect1 = "2001:0db8:85a2::0001"
986 incorrect2 = "2001:0db8:85a3::0000"
987
988 match = ofp.match([
989 ofp.oxm.eth_type(0x86dd),
990 ofp.oxm.ipv6_src_masked(parse_ipv6(flow), parse_ipv6(mask)),
991 ])
992
993 matching = {
994 "flow": simple_tcpv6_packet(ipv6_src=flow),
995 "correct1": simple_tcpv6_packet(ipv6_src=correct1),
996 "correct2": simple_tcpv6_packet(ipv6_src=correct2),
997 }
998
999 nonmatching = {
1000 "incorrect1": simple_tcpv6_packet(ipv6_src=incorrect1),
1001 "incorrect2": simple_tcpv6_packet(ipv6_src=incorrect2),
1002 }
1003
1004 self.verify_match(match, matching, nonmatching)
1005
1006class IPv6Dst(MatchTest):
1007 """
1008 Match on ipv6 destination address
1009 """
1010 def runTest(self):
1011 correct = "2001:db8:85a3::8a2e:370:7334"
1012 incorrect = "2001:db8:85a3::8a2e:370:7324"
1013 unspecified = "::"
1014
1015 match = ofp.match([
1016 ofp.oxm.eth_type(0x86dd),
1017 ofp.oxm.ipv6_dst(parse_ipv6(correct)),
1018 ])
1019
1020 matching = {
1021 "correct": simple_tcpv6_packet(ipv6_dst=correct),
1022 }
1023
1024 nonmatching = {
1025 "incorrect": simple_tcpv6_packet(ipv6_dst=incorrect),
1026 "unspecified": simple_tcpv6_packet(ipv6_dst=unspecified),
1027 }
1028
1029 self.verify_match(match, matching, nonmatching)
1030
1031class IPv6DstSubnetMasked(MatchTest):
1032 """
1033 Match on ipv6 destination address (subnet masked)
1034 """
1035 def runTest(self):
1036 flow = "2001:0db8:85a3::"
1037 mask = "ffff:ffff:ffff::"
1038 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
1039 correct2 = "2001:0db8:85a3::ffff:ffff:ffff"
1040 incorrect1 = "2001:0db8:85a2::"
1041
1042 match = ofp.match([
1043 ofp.oxm.eth_type(0x86dd),
1044 ofp.oxm.ipv6_dst_masked(parse_ipv6(flow), parse_ipv6(mask)),
1045 ])
1046
1047 matching = {
1048 "flow": simple_tcpv6_packet(ipv6_dst=flow),
1049 "correct1": simple_tcpv6_packet(ipv6_dst=correct1),
1050 "correct2": simple_tcpv6_packet(ipv6_dst=correct2),
1051 }
1052
1053 nonmatching = {
1054 "incorrect1": simple_tcpv6_packet(ipv6_dst=incorrect1),
1055 }
1056
1057 self.verify_match(match, matching, nonmatching)
1058
1059class IPv6DstMasked(MatchTest):
1060 """
1061 Match on ipv6 destination address (arbitrarily masked)
1062 """
1063 def runTest(self):
1064 flow = "2001:0db8:85a3::0001"
1065 mask = "ffff:ffff:ffff::000f"
1066 correct1 = "2001:0db8:85a3::8a2e:0370:7331"
1067 correct2 = "2001:0db8:85a3::ffff:ffff:fff1"
1068 incorrect1 = "2001:0db8:85a2::0001"
1069 incorrect2 = "2001:0db8:85a3::0000"
1070
1071 match = ofp.match([
1072 ofp.oxm.eth_type(0x86dd),
1073 ofp.oxm.ipv6_dst_masked(parse_ipv6(flow), parse_ipv6(mask)),
1074 ])
1075
1076 matching = {
1077 "flow": simple_tcpv6_packet(ipv6_dst=flow),
1078 "correct1": simple_tcpv6_packet(ipv6_dst=correct1),
1079 "correct2": simple_tcpv6_packet(ipv6_dst=correct2),
1080 }
1081
1082 nonmatching = {
1083 "incorrect1": simple_tcpv6_packet(ipv6_dst=incorrect1),
1084 "incorrect2": simple_tcpv6_packet(ipv6_dst=incorrect2),
1085 }
1086
1087 self.verify_match(match, matching, nonmatching)
Rich Lane3030a4f2013-07-17 16:21:45 -07001088
Rich Lane05e756b2013-07-17 15:48:16 -07001089class IPv4TCPSrc(MatchTest):
1090 """
1091 Match on ipv4 tcp source port
1092 """
1093 def runTest(self):
1094 match = ofp.match([
1095 ofp.oxm.eth_type(0x0800),
1096 ofp.oxm.ip_proto(6),
1097 ofp.oxm.tcp_src(53),
1098 ])
1099
1100 matching = {
1101 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1102 }
1103
1104 nonmatching = {
1105 "tcp sport=52": simple_tcp_packet(tcp_sport=52),
1106 "udp sport=53": simple_udp_packet(udp_sport=53),
1107 }
1108
1109 self.verify_match(match, matching, nonmatching)
1110
Rich Lane074c8ec2013-07-17 19:35:11 -07001111class IPv6TCPSrc(MatchTest):
1112 """
1113 Match on ipv4 tcp source port
1114 """
1115 def runTest(self):
1116 match = ofp.match([
1117 ofp.oxm.eth_type(0x86dd),
1118 ofp.oxm.ip_proto(6),
1119 ofp.oxm.tcp_src(53),
1120 ])
1121
1122 matching = {
1123 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1124 }
1125
1126 nonmatching = {
1127 "tcp sport=52": simple_tcpv6_packet(tcp_sport=52),
1128 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1129 }
1130
1131 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001132
1133class IPv4TCPDst(MatchTest):
1134 """
1135 Match on ipv4 tcp destination 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_dst(53),
1142 ])
1143
1144 matching = {
1145 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1146 }
1147
1148 nonmatching = {
1149 "tcp dport=52": simple_tcp_packet(tcp_dport=52),
1150 "udp dport=53": simple_udp_packet(udp_dport=53),
1151 }
1152
1153 self.verify_match(match, matching, nonmatching)
1154
Rich Lane074c8ec2013-07-17 19:35:11 -07001155class IPv6TCPDst(MatchTest):
1156 """
1157 Match on ipv6 tcp destination 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_dst(53),
1164 ])
1165
1166 matching = {
1167 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1168 }
1169
1170 nonmatching = {
1171 "tcp dport=52": simple_tcpv6_packet(tcp_dport=52),
1172 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1173 }
1174
1175 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001176
1177class IPv4UDPSrc(MatchTest):
1178 """
1179 Match on ipv4 udp source port
1180 """
1181 def runTest(self):
1182 match = ofp.match([
1183 ofp.oxm.eth_type(0x0800),
1184 ofp.oxm.ip_proto(17),
1185 ofp.oxm.udp_src(53),
1186 ])
1187
1188 matching = {
1189 "udp sport=53": simple_udp_packet(udp_sport=53),
1190 }
1191
1192 nonmatching = {
1193 "udp sport=52": simple_udp_packet(udp_sport=52),
1194 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1195 }
1196
1197 self.verify_match(match, matching, nonmatching)
1198
Rich Lane074c8ec2013-07-17 19:35:11 -07001199class IPv6UDPSrc(MatchTest):
1200 """
1201 Match on ipv4 udp source port
1202 """
1203 def runTest(self):
1204 match = ofp.match([
1205 ofp.oxm.eth_type(0x86dd),
1206 ofp.oxm.ip_proto(17),
1207 ofp.oxm.udp_src(53),
1208 ])
1209
1210 matching = {
1211 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1212 }
1213
1214 nonmatching = {
1215 "udp sport=52": simple_udpv6_packet(udp_sport=52),
1216 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1217 }
1218
1219 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001220
1221class IPv4UDPDst(MatchTest):
1222 """
1223 Match on ipv4 udp destination 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_dst(53),
1230 ])
1231
1232 matching = {
1233 "udp dport=53": simple_udp_packet(udp_dport=53),
1234 }
1235
1236 nonmatching = {
1237 "udp dport=52": simple_udp_packet(udp_dport=52),
1238 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1239 }
1240
1241 self.verify_match(match, matching, nonmatching)
1242
Rich Lane074c8ec2013-07-17 19:35:11 -07001243class IPv6UDPDst(MatchTest):
1244 """
1245 Match on ipv4 udp destination 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_dst(53),
1252 ])
1253
1254 matching = {
1255 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1256 }
1257
1258 nonmatching = {
1259 "udp dport=52": simple_udpv6_packet(udp_dport=52),
1260 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1261 }
1262
1263 self.verify_match(match, matching, nonmatching)
Rich Laneee574362013-07-17 16:40:07 -07001264
1265class IPv4ICMPType(MatchTest):
1266 """
1267 Match on ipv4 icmp type
1268 """
1269 def runTest(self):
1270 match = ofp.match([
1271 ofp.oxm.eth_type(0x0800),
1272 ofp.oxm.ip_proto(1),
1273 ofp.oxm.icmpv4_type(3),
1274 ])
1275
1276 matching = {
1277 "type=3 code=1": simple_icmp_packet(icmp_type=3, icmp_code=1),
1278 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1279 }
1280
1281 nonmatching = {
1282 "type=2 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
1283 }
1284
1285 self.verify_match(match, matching, nonmatching)
1286
1287class IPv4ICMPCode(MatchTest):
1288 """
1289 Match on ipv4 icmp code
1290 """
1291 def runTest(self):
1292 match = ofp.match([
1293 ofp.oxm.eth_type(0x0800),
1294 ofp.oxm.ip_proto(1),
1295 ofp.oxm.icmpv4_code(2),
1296 ])
1297
1298 matching = {
1299 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1300 "type=5 code=2": simple_icmp_packet(icmp_type=5, icmp_code=2),
1301 }
1302
1303 nonmatching = {
1304 "type=3 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
1305 }
1306
1307 self.verify_match(match, matching, nonmatching)
1308
Rich Lanea4317532013-07-17 19:27:19 -07001309class IPv6ICMPType(MatchTest):
1310 """
1311 Match on ipv6 icmp type
1312 """
1313 def runTest(self):
1314 match = ofp.match([
1315 ofp.oxm.eth_type(0x86dd),
1316 ofp.oxm.ip_proto(58),
1317 ofp.oxm.icmpv6_type(3),
1318 ])
1319
1320 matching = {
1321 "type=3 code=1": simple_icmpv6_packet(icmp_type=3, icmp_code=1),
1322 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1323 }
1324
1325 nonmatching = {
1326 "type=2 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
1327 }
1328
1329 self.verify_match(match, matching, nonmatching)
1330
1331class IPv6ICMPCode(MatchTest):
1332 """
1333 Match on ipv6 icmp code
1334 """
1335 def runTest(self):
1336 match = ofp.match([
1337 ofp.oxm.eth_type(0x86dd),
1338 ofp.oxm.ip_proto(58),
1339 ofp.oxm.icmpv6_code(2),
1340 ])
1341
1342 matching = {
1343 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1344 "type=5 code=2": simple_icmpv6_packet(icmp_type=5, icmp_code=2),
1345 }
1346
1347 nonmatching = {
1348 "type=3 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
1349 }
1350
1351 self.verify_match(match, matching, nonmatching)
Rich Lane6b770992013-07-17 17:11:24 -07001352
1353class ArpOp(MatchTest):
1354 """
1355 Match on ARP operation
1356 """
1357 def runTest(self):
1358 match = ofp.match([
1359 ofp.oxm.eth_type(0x0806),
1360 ofp.oxm.arp_op(3),
1361 ])
1362
1363 matching = {
1364 "op=3": simple_arp_packet(arp_op=3),
1365 }
1366
1367 nonmatching = {
1368 "op=4": simple_arp_packet(arp_op=4),
1369 }
1370
1371 self.verify_match(match, matching, nonmatching)
Rich Lane503a2de2013-07-17 17:20:58 -07001372
1373class ArpSPA(MatchTest):
1374 """
1375 Match on ARP sender IP
1376 """
1377 def runTest(self):
1378 match = ofp.match([
1379 ofp.oxm.eth_type(0x0806),
1380 ofp.oxm.arp_spa(0xc0a80001), # 192.168.0.1
1381 ])
1382
1383 matching = {
1384 "192.168.0.1": simple_arp_packet(ip_snd="192.168.0.1"),
1385 }
1386
1387 nonmatching = {
1388 "192.168.0.2": simple_arp_packet(ip_snd="192.168.0.2"),
1389 }
1390
1391 self.verify_match(match, matching, nonmatching)
1392
1393class ArpTPA(MatchTest):
1394 """
1395 Match on ARP target IP
1396 """
1397 def runTest(self):
1398 match = ofp.match([
1399 ofp.oxm.eth_type(0x0806),
1400 ofp.oxm.arp_tpa(0xc0a80001), # 192.168.0.1
1401 ])
1402
1403 matching = {
1404 "192.168.0.1": simple_arp_packet(ip_tgt="192.168.0.1"),
1405 }
1406
1407 nonmatching = {
1408 "192.168.0.2": simple_arp_packet(ip_tgt="192.168.0.2"),
1409 }
1410
1411 self.verify_match(match, matching, nonmatching)