blob: 2da8ca9c77481f8c24dbf1da049e44cf9aeff81c [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 *
19
20class MatchTest(base_tests.SimpleDataPlane):
21 """
22 Base class for match tests
23 """
24
25 def verify_match(self, match, matching, nonmatching):
26 """
27 Verify matching behavior
28
29 Checks that all the packets in 'matching' match 'match', and that
30 the packets in 'nonmatching' do not.
31
32 'match' is a LOXI match object. 'matching' and 'nonmatching' are
33 dicts mapping from string names (used in log messages) to string
34 packet data.
35 """
36 ports = sorted(config["port_map"].keys())
37 in_port = ports[0]
38 out_port = ports[1]
39
40 logging.info("Running match test for %s", match.show())
41
42 delete_all_flows(self.controller)
43
44 logging.info("Inserting flow sending matching packets to port %d", out_port)
45 request = ofp.message.flow_add(
46 table_id=0,
47 match=match,
48 instructions=[
49 ofp.instruction.apply_actions(
50 actions=[
51 ofp.action.output(
52 port=out_port,
53 max_len=ofp.OFPCML_NO_BUFFER)])],
54 buffer_id=ofp.OFP_NO_BUFFER,
55 priority=1000)
56 self.controller.message_send(request)
57
58 logging.info("Inserting match-all flow sending packets to controller")
59 request = ofp.message.flow_add(
60 table_id=0,
61 instructions=[
62 ofp.instruction.apply_actions(
63 actions=[
64 ofp.action.output(
65 port=ofp.OFPP_CONTROLLER,
66 max_len=ofp.OFPCML_NO_BUFFER)])],
67 buffer_id=ofp.OFP_NO_BUFFER,
68 priority=1)
69 self.controller.message_send(request)
70
71 do_barrier(self.controller)
72
73 for name, pkt in matching.items():
74 logging.info("Sending matching packet %s, expecting output to port %d", repr(name), out_port)
75 pktstr = str(pkt)
76 self.dataplane.send(in_port, pktstr)
77 receive_pkt_verify(self, [out_port], pktstr, in_port)
78
79 for name, pkt in nonmatching.items():
80 logging.info("Sending non-matching packet %s, expecting packet-in", repr(name))
81 pktstr = str(pkt)
82 self.dataplane.send(in_port, pktstr)
83 verify_packet_in(self, pktstr, in_port, ofp.OFPR_ACTION)
84
Rich Laneb9d1f4b2013-07-17 18:02:23 -070085# Does not use MatchTest because the ingress port is not a packet field
86class InPort(base_tests.SimpleDataPlane):
87 """
88 Match on ingress port
89 """
90 def runTest(self):
91 ports = sorted(config["port_map"].keys())
92 in_port = ports[0]
93 out_port = ports[1]
94 bad_port = ports[2]
95
96 match = ofp.match([
97 ofp.oxm.in_port(in_port)
98 ])
99
100 pkt = simple_tcp_packet()
101
102 logging.info("Running match test for %s", match.show())
103
104 delete_all_flows(self.controller)
105
106 logging.info("Inserting flow sending matching packets to port %d", out_port)
107 request = ofp.message.flow_add(
108 table_id=0,
109 match=match,
110 instructions=[
111 ofp.instruction.apply_actions(
112 actions=[
113 ofp.action.output(
114 port=out_port,
115 max_len=ofp.OFPCML_NO_BUFFER)])],
116 buffer_id=ofp.OFP_NO_BUFFER,
117 priority=1000)
118 self.controller.message_send(request)
119
120 logging.info("Inserting match-all flow sending packets to controller")
121 request = ofp.message.flow_add(
122 table_id=0,
123 instructions=[
124 ofp.instruction.apply_actions(
125 actions=[
126 ofp.action.output(
127 port=ofp.OFPP_CONTROLLER,
128 max_len=ofp.OFPCML_NO_BUFFER)])],
129 buffer_id=ofp.OFP_NO_BUFFER,
130 priority=1)
131 self.controller.message_send(request)
132
133 do_barrier(self.controller)
134
135 pktstr = str(pkt)
136
137 logging.info("Sending packet on matching ingress port, expecting output to port %d", out_port)
138 self.dataplane.send(in_port, pktstr)
139 receive_pkt_verify(self, [out_port], pktstr, in_port)
140
141 logging.info("Sending packet on non-matching ingress port, expecting packet-in")
142 self.dataplane.send(bad_port, pktstr)
143 verify_packet_in(self, pktstr, bad_port, ofp.OFPR_ACTION)
144
Rich Lane059f0122013-07-17 11:54:13 -0700145class EthDst(MatchTest):
146 """
147 Match on ethernet destination
148 """
149 def runTest(self):
150 match = ofp.match([
151 ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
152 ])
153
154 matching = {
155 "correct": simple_tcp_packet(eth_dst='00:01:02:03:04:05'),
156 }
157
158 nonmatching = {
159 "incorrect": simple_tcp_packet(eth_dst='00:01:02:03:04:06'),
160 "multicast": simple_tcp_packet(eth_dst='01:01:02:03:04:05'),
161 "local": simple_tcp_packet(eth_dst='02:01:02:03:04:05'),
162 }
163
164 self.verify_match(match, matching, nonmatching)
165
166class EthDstBroadcast(MatchTest):
167 """
168 Match on ethernet destination (broadcast)
169 """
170 def runTest(self):
171 match = ofp.match([
172 ofp.oxm.eth_dst([0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
173 ])
174
175 matching = {
176 "ff:ff:ff:ff:ff:ff": simple_tcp_packet(eth_dst='ff:ff:ff:ff:ff:ff'),
177 }
178
179 nonmatching = {
180 "fd:ff:ff:ff:ff:ff": simple_tcp_packet(eth_dst='fd:ff:ff:ff:ff:ff'),
181 "fe:ff:ff:ff:ff:ff": simple_tcp_packet(eth_dst='fe:ff:ff:ff:ff:ff'),
182 "ff:fe:ff:ff:ff:ff": simple_tcp_packet(eth_dst='ff:fe:ff:ff:ff:ff'),
183 }
184
185 self.verify_match(match, matching, nonmatching)
186
187class EthDstMulticast(MatchTest):
188 """
189 Match on ethernet destination (IPv4 multicast)
190 """
191 def runTest(self):
192 match = ofp.match([
193 ofp.oxm.eth_dst([0x01, 0x00, 0x5e, 0xed, 0x99, 0x02])
194 ])
195
196 matching = {
197 "correct": simple_tcp_packet(eth_dst='01:00:5e:ed:99:02'),
198 }
199
200 nonmatching = {
201 "incorrect": simple_tcp_packet(eth_dst='01:00:5e:ed:99:03'),
202 "unicast": simple_tcp_packet(eth_dst='00:00:5e:ed:99:02'),
203 "local": simple_tcp_packet(eth_dst='03:00:5e:ed:99:02'),
204 }
205
206 self.verify_match(match, matching, nonmatching)
207
208class EthDstMasked(MatchTest):
209 """
210 Match on ethernet destination (masked)
211 """
212 def runTest(self):
213 match = ofp.match([
214 ofp.oxm.eth_dst_masked([0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
215 [0x00, 0xff, 0xff, 0x0f, 0xff, 0xff])
216 ])
217
218 matching = {
219 "00:01:02:03:04:05": simple_tcp_packet(eth_dst='00:01:02:03:04:05'),
220 "ff:01:02:f3:04:05": simple_tcp_packet(eth_dst='ff:01:02:f3:04:05'),
221 }
222
223 nonmatching = {
224 "00:02:02:03:04:05": simple_tcp_packet(eth_dst='00:02:02:03:04:05'),
225 "00:01:02:07:04:05": simple_tcp_packet(eth_dst='00:01:02:07:04:05'),
226 }
227
228 self.verify_match(match, matching, nonmatching)
229
230class EthSrc(MatchTest):
231 """
232 Match on ethernet source
233 """
234 def runTest(self):
235 match = ofp.match([
236 ofp.oxm.eth_src([0,1,2,3,4,5])
237 ])
238
239 matching = {
240 "correct": simple_tcp_packet(eth_src='00:01:02:03:04:05'),
241 }
242
243 nonmatching = {
244 "incorrect": simple_tcp_packet(eth_src='00:01:02:03:04:06'),
245 "multicast": simple_tcp_packet(eth_src='01:01:02:03:04:05'),
246 "local": simple_tcp_packet(eth_src='02:01:02:03:04:05'),
247 }
248
249 self.verify_match(match, matching, nonmatching)
250
251class EthSrcMasked(MatchTest):
252 """
253 Match on ethernet source (masked)
254 """
255 def runTest(self):
256 match = ofp.match([
257 ofp.oxm.eth_src_masked([0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
258 [0x00, 0xff, 0xff, 0x0f, 0xff, 0xff])
259 ])
260
261 matching = {
262 "00:01:02:03:04:05": simple_tcp_packet(eth_src='00:01:02:03:04:05'),
263 "ff:01:02:f3:04:05": simple_tcp_packet(eth_src='ff:01:02:f3:04:05'),
264 }
265
266 nonmatching = {
267 "00:02:02:03:04:05": simple_tcp_packet(eth_src='00:02:02:03:04:05'),
268 "00:01:02:07:04:05": simple_tcp_packet(eth_src='00:01:02:07:04:05'),
269 }
270
271 self.verify_match(match, matching, nonmatching)
272
Rich Lane14f10e22013-07-17 14:24:35 -0700273class EthTypeIPv4(MatchTest):
274 """
275 Match on ethertype (IPv4)
276 """
277 def runTest(self):
278 match = ofp.match([
279 ofp.oxm.eth_type(0x0800)
280 ])
281
282 snap_pkt = \
283 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=48)/ \
284 scapy.LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03)/ \
285 scapy.SNAP(OUI=0x000000, code=0x0800)/ \
286 scapy.IP(src='192.168.0.1', dst='192.168.0.2', proto=6)/ \
287 scapy.TCP(sport=1234, dport=80)
288
289 llc_pkt = \
290 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=17)/ \
291 scapy.LLC(dsap=0xaa, ssap=0xab, ctrl=0x03)
292
293 matching = {
294 "ipv4/tcp": simple_tcp_packet(),
295 "ipv4/udp": simple_udp_packet(),
296 "ipv4/icmp": simple_icmp_packet(),
297 "vlan tagged": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
298 "llc/snap": snap_pkt,
299 }
300
301 nonmatching = {
302 "arp": simple_arp_packet(),
303 "llc": llc_pkt,
Rich Lane86aceb02013-07-17 18:45:38 -0700304 "ipv6/tcp": simple_tcpv6_packet(),
305 }
306
307 self.verify_match(match, matching, nonmatching)
308
309class EthTypeIPv6(MatchTest):
310 """
311 Match on ethertype (IPv6)
312 """
313 def runTest(self):
314 match = ofp.match([
315 ofp.oxm.eth_type(0x86dd)
316 ])
317
318 matching = {
319 "ipv6/tcp": simple_tcpv6_packet(),
320 "ipv6/udp": simple_udpv6_packet(),
321 "ipv6/icmp": simple_icmpv6_packet(),
322 "vlan tagged": simple_tcpv6_packet(vlan_vid=2, vlan_pcp=3),
323 }
324
325 nonmatching = {
326 "ipv4/tcp": simple_tcp_packet(),
327 "arp": simple_arp_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700328 }
329
330 self.verify_match(match, matching, nonmatching)
331
332class EthTypeARP(MatchTest):
333 """
334 Match on ethertype (ARP)
335 """
336 def runTest(self):
337 match = ofp.match([
338 ofp.oxm.eth_type(0x0806)
339 ])
340
341 matching = {
342 "arp": simple_arp_packet(),
343 # TODO vlan tagged
344 }
345
346 nonmatching = {
347 "ipv4/tcp": simple_tcp_packet(),
Rich Lane86aceb02013-07-17 18:45:38 -0700348 "ipv6/tcp": simple_tcpv6_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700349 }
350
351 self.verify_match(match, matching, nonmatching)
352
353class EthTypeNone(MatchTest):
354 """
355 Match on no ethertype (IEEE 802.3 without SNAP header)
356 """
357 def runTest(self):
358 match = ofp.match([
359 ofp.oxm.eth_type(0x05ff)
360 ])
361
362 snap_pkt = \
363 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=48)/ \
364 scapy.LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03)/ \
365 scapy.SNAP(OUI=0x000000, code=0x0800)/ \
366 scapy.IP(src='192.168.0.1', dst='192.168.0.2', proto=6)/ \
367 scapy.TCP(sport=1234, dport=80)
368
369 llc_pkt = \
370 scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=17)/ \
371 scapy.LLC(dsap=0xaa, ssap=0xab, ctrl=0x03)
372
373 matching = {
374 "llc": llc_pkt,
375 }
376
377 nonmatching = {
378 "ipv4/tcp": simple_tcp_packet(),
Rich Lane86aceb02013-07-17 18:45:38 -0700379 "ipv6/tcp": simple_tcpv6_packet(),
Rich Lane14f10e22013-07-17 14:24:35 -0700380 "llc/snap": snap_pkt,
381 }
382
383 self.verify_match(match, matching, nonmatching)
384
Rich Lanea8d74912013-07-16 10:10:39 -0700385class VlanExact(MatchTest):
386 """
387 Match on VLAN VID and PCP
388 """
389 def runTest(self):
390 match = ofp.match([
391 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
392 ofp.oxm.vlan_pcp(3),
393 ])
394
395 matching = {
396 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
397 }
398
399 nonmatching = {
400 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
401 "vid=4 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
402 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
403 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
404 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
405 "no vlan tag": simple_tcp_packet(),
406 }
407
408 self.verify_match(match, matching, nonmatching)
409
410class VlanVID(MatchTest):
411 """
412 Match on VLAN VID
413 """
414 def runTest(self):
415 match = ofp.match([
416 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
417 ])
418
419 matching = {
420 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
421 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
422 }
423
424 nonmatching = {
425 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
426 "no vlan tag": simple_tcp_packet(),
427 }
428
429 self.verify_match(match, matching, nonmatching)
430
Rich Laned51b94f2013-07-16 13:29:55 -0700431class VlanVIDMasked(MatchTest):
432 """
433 Match on VLAN VID (masked)
434 """
435 def runTest(self):
436 match = ofp.match([
437 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT|3, ofp.OFPVID_PRESENT|3),
438 ])
439
440 matching = {
441 "vid=3 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=3, vlan_pcp=2),
442 "vid=7 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=7, vlan_pcp=2),
443 "vid=11 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=11, vlan_pcp=2),
444 }
445
446 nonmatching = {
447 "vid=0 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=2),
448 "vid=1 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=1, vlan_pcp=2),
449 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
450 "vid=4 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=4, vlan_pcp=2),
451 "no vlan tag": simple_tcp_packet(),
452 }
453
454 self.verify_match(match, matching, nonmatching)
455
Rich Lanea8d74912013-07-16 10:10:39 -0700456class VlanPCP(MatchTest):
457 """
458 Match on VLAN PCP (VID matched)
459 """
460 def runTest(self):
461 match = ofp.match([
462 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
463 ofp.oxm.vlan_pcp(3),
464 ])
465
466 matching = {
467 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
468 }
469
470 nonmatching = {
471 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
472 "no vlan tag": simple_tcp_packet(),
473 }
474
475 self.verify_match(match, matching, nonmatching)
476
Rich Laned51b94f2013-07-16 13:29:55 -0700477@nonstandard
478class VlanPCPMasked(MatchTest):
479 """
480 Match on VLAN PCP (masked, VID matched)
481 """
482 def runTest(self):
483 match = ofp.match([
484 ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2),
485 ofp.oxm.vlan_pcp_masked(3, 3),
486 ])
487
488 matching = {
489 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
490 "vid=2 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=7),
491 }
492
493 nonmatching = {
494 "vid=2 pcp=1": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=1),
495 "vid=2 pcp=2": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=2),
496 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
497 "vid=2 pcp=5": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=5),
498 "vid=2 pcp=6": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=6),
499 "no vlan tag": simple_tcp_packet(),
500 }
501
502 self.verify_match(match, matching, nonmatching)
503
Rich Lanea8d74912013-07-16 10:10:39 -0700504class VlanPCPAnyVID(MatchTest):
505 """
506 Match on VLAN PCP (VID present)
507 """
508 def runTest(self):
509 match = ofp.match([
510 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
511 ofp.oxm.vlan_pcp(3),
512 ])
513
514 matching = {
515 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
516 "vid=0 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=3),
517 }
518
519 nonmatching = {
520 "vid=2 pcp=4": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=4),
521 "no vlan tag": simple_tcp_packet(),
522 }
523
524 self.verify_match(match, matching, nonmatching)
525
526class VlanPresent(MatchTest):
527 """
528 Match on any VLAN tag (but must be present)
529 """
530 def runTest(self):
531 match = ofp.match([
532 ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT),
533 ])
534
535 matching = {
536 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
537 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
538 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
539 }
540
541 nonmatching = {
542 "no vlan tag": simple_tcp_packet()
543 }
544
545 self.verify_match(match, matching, nonmatching)
546
547class VlanAbsent(MatchTest):
548 """
549 Match on absent VLAN tag
550 """
551 def runTest(self):
552 match = ofp.match([
553 ofp.oxm.vlan_vid(ofp.OFPVID_NONE),
554 ])
555
556 matching = {
557 "no vlan tag": simple_tcp_packet()
558 }
559
560 nonmatching = {
561 "vid=2 pcp=3": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=3),
562 "vid=0 pcp=7": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=7),
563 "vid=2 pcp=0": simple_tcp_packet(dl_vlan_enable=True, vlan_vid=2, vlan_pcp=0),
564 }
565
566 self.verify_match(match, matching, nonmatching)
Rich Lane11f6d772013-07-17 15:27:46 -0700567
568class IPv4Dscp(MatchTest):
569 """
570 Match on ipv4 dscp
571 """
572 def runTest(self):
573 match = ofp.match([
574 ofp.oxm.eth_type(0x0800),
575 ofp.oxm.ip_dscp(4),
576 ])
577
578 matching = {
579 "dscp=4 ecn=0": simple_tcp_packet(ip_tos=0x10),
580 "dscp=4 ecn=3": simple_tcp_packet(ip_tos=0x13),
581 }
582
583 nonmatching = {
584 "dscp=5 ecn=0": simple_tcp_packet(ip_tos=0x14),
585 }
586
587 self.verify_match(match, matching, nonmatching)
588
Rich Lane93bbc542013-07-17 19:06:24 -0700589class IPv6Dscp(MatchTest):
590 """
591 Match on ipv6 dscp
592 """
593 def runTest(self):
594 match = ofp.match([
595 ofp.oxm.eth_type(0x86dd),
596 ofp.oxm.ip_dscp(4),
597 ])
598
599 matching = {
600 "dscp=4 ecn=0": simple_tcpv6_packet(ipv6_tc=0x10),
601 "dscp=4 ecn=3": simple_tcpv6_packet(ipv6_tc=0x13),
602 }
603
604 nonmatching = {
605 "dscp=5 ecn=0": simple_tcpv6_packet(ipv6_tc=0x14),
606 }
607
608 self.verify_match(match, matching, nonmatching)
Rich Lane11f6d772013-07-17 15:27:46 -0700609
610class IPv4Ecn(MatchTest):
611 """
612 Match on ipv4 ecn
613 """
614 def runTest(self):
615 match = ofp.match([
616 ofp.oxm.eth_type(0x0800),
617 ofp.oxm.ip_ecn(2),
618 ])
619
620 matching = {
621 "dscp=4 ecn=2": simple_tcp_packet(ip_tos=0x12),
622 "dscp=6 ecn=2": simple_tcp_packet(ip_tos=0x1a),
623 }
624
625 nonmatching = {
626 "dscp=4 ecn=0": simple_tcp_packet(ip_tos=0x10),
627 "dscp=4 ecn=3": simple_tcp_packet(ip_tos=0x13),
628 }
629
630 self.verify_match(match, matching, nonmatching)
631
Rich Lane93bbc542013-07-17 19:06:24 -0700632class IPv6Ecn(MatchTest):
633 """
634 Match on ipv6 ecn
635 """
636 def runTest(self):
637 match = ofp.match([
638 ofp.oxm.eth_type(0x86dd),
639 ofp.oxm.ip_ecn(2),
640 ])
641
642 matching = {
643 "dscp=4 ecn=2": simple_tcpv6_packet(ipv6_tc=0x12),
644 "dscp=6 ecn=2": simple_tcpv6_packet(ipv6_tc=0x1a),
645 }
646
647 nonmatching = {
648 "dscp=4 ecn=0": simple_tcpv6_packet(ipv6_tc=0x10),
649 "dscp=4 ecn=3": simple_tcpv6_packet(ipv6_tc=0x13),
650 }
651
652 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700653
654class IPv4ProtoTCP(MatchTest):
655 """
656 Match on ipv4 protocol field (TCP)
657 """
658 def runTest(self):
659 match = ofp.match([
660 ofp.oxm.eth_type(0x0800),
661 ofp.oxm.ip_proto(6),
662 ])
663
664 matching = {
665 "tcp": simple_tcp_packet(),
666 }
667
668 nonmatching = {
669 "udp": simple_udp_packet(),
670 "icmp": simple_icmp_packet(),
671 }
672
673 self.verify_match(match, matching, nonmatching)
674
Rich Lane745e8b22013-07-17 19:16:16 -0700675class IPv6ProtoTCP(MatchTest):
676 """
677 Match on ipv6 protocol field (TCP)
678 """
679 def runTest(self):
680 match = ofp.match([
681 ofp.oxm.eth_type(0x86dd),
682 ofp.oxm.ip_proto(6),
683 ])
684
685 matching = {
686 "tcp": simple_tcpv6_packet(),
687 }
688
689 nonmatching = {
690 "udp": simple_udpv6_packet(),
691 "icmp": simple_icmpv6_packet(),
692 }
693
694 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700695
696class IPv4ProtoUDP(MatchTest):
697 """
698 Match on ipv4 protocol field (UDP)
699 """
700 def runTest(self):
701 match = ofp.match([
702 ofp.oxm.eth_type(0x0800),
703 ofp.oxm.ip_proto(17),
704 ])
705
706 matching = {
707 "udp": simple_udp_packet(),
708 }
709
710 nonmatching = {
711 "tcp": simple_tcp_packet(),
712 "icmp": simple_icmp_packet(),
713 }
714
715 self.verify_match(match, matching, nonmatching)
716
Rich Lane745e8b22013-07-17 19:16:16 -0700717class IPv6ProtoUDP(MatchTest):
718 """
719 Match on ipv6 protocol field (UDP)
720 """
721 def runTest(self):
722 match = ofp.match([
723 ofp.oxm.eth_type(0x86dd),
724 ofp.oxm.ip_proto(17),
725 ])
726
727 matching = {
728 "udp": simple_udpv6_packet(),
729 }
730
731 nonmatching = {
732 "tcp": simple_tcpv6_packet(),
733 "icmp": simple_icmpv6_packet(),
734 }
735
736 self.verify_match(match, matching, nonmatching)
Rich Lane6b848af2013-07-17 15:35:36 -0700737
738class IPv4ProtoICMP(MatchTest):
739 """
740 Match on ipv4 protocol field (ICMP)
741 """
742 def runTest(self):
743 match = ofp.match([
744 ofp.oxm.eth_type(0x0800),
745 ofp.oxm.ip_proto(1),
746 ])
747
748 matching = {
749 "icmp": simple_icmp_packet(),
750 }
751
752 nonmatching = {
753 "tcp": simple_tcp_packet(),
754 "udp": simple_udp_packet(),
755 }
756
757 self.verify_match(match, matching, nonmatching)
758
Rich Lane745e8b22013-07-17 19:16:16 -0700759class IPv6ProtoICMP(MatchTest):
760 """
761 Match on ipv6 protocol field (ICMP)
762 """
763 def runTest(self):
764 match = ofp.match([
765 ofp.oxm.eth_type(0x86dd),
766 ofp.oxm.ip_proto(58),
767 ])
768
769 matching = {
770 "icmp": simple_icmpv6_packet(),
771 }
772
773 nonmatching = {
774 "tcp": simple_tcpv6_packet(),
775 "udp": simple_udpv6_packet(),
776 }
777
778 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -0700779
Rich Lane3030a4f2013-07-17 16:21:45 -0700780class IPv4Src(MatchTest):
781 """
782 Match on ipv4 source address
783 """
784 def runTest(self):
785 match = ofp.match([
786 ofp.oxm.eth_type(0x0800),
787 ofp.oxm.ipv4_src(0xc0a80001), # 192.168.0.1
788 ])
789
790 matching = {
791 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
792 }
793
794 nonmatching = {
795 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
796 "255.255.255.255": simple_tcp_packet(ip_src='255.255.255.255'),
797 }
798
799 self.verify_match(match, matching, nonmatching)
800
801class IPv4SrcSubnetMasked(MatchTest):
802 """
803 Match on ipv4 source address (subnet masked)
804 """
805 def runTest(self):
806 match = ofp.match([
807 ofp.oxm.eth_type(0x0800),
808 # 192.168.0.0/20 (255.255.240.0)
809 ofp.oxm.ipv4_src_masked(0xc0a80000, 0xfffff000),
810 ])
811
812 matching = {
813 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
814 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
815 "192.168.4.2": simple_tcp_packet(ip_src='192.168.4.2'),
816 "192.168.0.0": simple_tcp_packet(ip_src='192.168.0.0'),
817 "192.168.15.255": simple_tcp_packet(ip_src='192.168.15.255'),
818 }
819
820 nonmatching = {
821 "192.168.16.0": simple_tcp_packet(ip_src='192.168.16.0'),
822 "192.167.255.255": simple_tcp_packet(ip_src='192.167.255.255'),
823 "192.168.31.1": simple_tcp_packet(ip_src='192.168.31.1'),
824 }
825
826 self.verify_match(match, matching, nonmatching)
827
828class IPv4SrcMasked(MatchTest):
829 """
830 Match on ipv4 source address (arbitrarily masked)
831 """
832 def runTest(self):
833 match = ofp.match([
834 ofp.oxm.eth_type(0x0800),
835 # 192.168.0.1 255.254.255.255
836 ofp.oxm.ipv4_src_masked(0xc0a80001, 0xfffeffff),
837 ])
838
839 matching = {
840 "192.168.0.1": simple_tcp_packet(ip_src='192.168.0.1'),
841 "192.169.0.1": simple_tcp_packet(ip_src='192.169.0.1'),
842 }
843
844 nonmatching = {
845 "192.168.0.2": simple_tcp_packet(ip_src='192.168.0.2'),
846 "192.167.0.1": simple_tcp_packet(ip_src='192.167.0.1'),
847 }
848
849 self.verify_match(match, matching, nonmatching)
850
851class IPv4Dst(MatchTest):
852 """
853 Match on ipv4 source address
854 """
855 def runTest(self):
856 match = ofp.match([
857 ofp.oxm.eth_type(0x0800),
858 ofp.oxm.ipv4_dst(0xc0a80001), # 192.168.0.1
859 ])
860
861 matching = {
862 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
863 }
864
865 nonmatching = {
866 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
867 "255.255.255.255": simple_tcp_packet(ip_dst='255.255.255.255'),
868 }
869
870 self.verify_match(match, matching, nonmatching)
871
872class IPv4DstSubnetMasked(MatchTest):
873 """
874 Match on ipv4 source address (subnet masked)
875 """
876 def runTest(self):
877 match = ofp.match([
878 ofp.oxm.eth_type(0x0800),
879 # 192.168.0.0/20 (255.255.240.0)
880 ofp.oxm.ipv4_dst_masked(0xc0a80000, 0xfffff000),
881 ])
882
883 matching = {
884 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
885 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
886 "192.168.4.2": simple_tcp_packet(ip_dst='192.168.4.2'),
887 "192.168.0.0": simple_tcp_packet(ip_dst='192.168.0.0'),
888 "192.168.15.255": simple_tcp_packet(ip_dst='192.168.15.255'),
889 }
890
891 nonmatching = {
892 "192.168.16.0": simple_tcp_packet(ip_dst='192.168.16.0'),
893 "192.167.255.255": simple_tcp_packet(ip_dst='192.167.255.255'),
894 "192.168.31.1": simple_tcp_packet(ip_dst='192.168.31.1'),
895 }
896
897 self.verify_match(match, matching, nonmatching)
898
899class IPv4DstMasked(MatchTest):
900 """
901 Match on ipv4 source address (arbitrarily masked)
902 """
903 def runTest(self):
904 match = ofp.match([
905 ofp.oxm.eth_type(0x0800),
906 # 192.168.0.1 255.254.255.255
907 ofp.oxm.ipv4_dst_masked(0xc0a80001, 0xfffeffff),
908 ])
909
910 matching = {
911 "192.168.0.1": simple_tcp_packet(ip_dst='192.168.0.1'),
912 "192.169.0.1": simple_tcp_packet(ip_dst='192.169.0.1'),
913 }
914
915 nonmatching = {
916 "192.168.0.2": simple_tcp_packet(ip_dst='192.168.0.2'),
917 "192.167.0.1": simple_tcp_packet(ip_dst='192.167.0.1'),
918 }
919
920 self.verify_match(match, matching, nonmatching)
921
922# TODO IPv6 source address
923# TODO IPv6 destination address
924
Rich Lane05e756b2013-07-17 15:48:16 -0700925class IPv4TCPSrc(MatchTest):
926 """
927 Match on ipv4 tcp source port
928 """
929 def runTest(self):
930 match = ofp.match([
931 ofp.oxm.eth_type(0x0800),
932 ofp.oxm.ip_proto(6),
933 ofp.oxm.tcp_src(53),
934 ])
935
936 matching = {
937 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
938 }
939
940 nonmatching = {
941 "tcp sport=52": simple_tcp_packet(tcp_sport=52),
942 "udp sport=53": simple_udp_packet(udp_sport=53),
943 }
944
945 self.verify_match(match, matching, nonmatching)
946
Rich Lane074c8ec2013-07-17 19:35:11 -0700947class IPv6TCPSrc(MatchTest):
948 """
949 Match on ipv4 tcp source port
950 """
951 def runTest(self):
952 match = ofp.match([
953 ofp.oxm.eth_type(0x86dd),
954 ofp.oxm.ip_proto(6),
955 ofp.oxm.tcp_src(53),
956 ])
957
958 matching = {
959 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
960 }
961
962 nonmatching = {
963 "tcp sport=52": simple_tcpv6_packet(tcp_sport=52),
964 "udp sport=53": simple_udpv6_packet(udp_sport=53),
965 }
966
967 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -0700968
969class IPv4TCPDst(MatchTest):
970 """
971 Match on ipv4 tcp destination port
972 """
973 def runTest(self):
974 match = ofp.match([
975 ofp.oxm.eth_type(0x0800),
976 ofp.oxm.ip_proto(6),
977 ofp.oxm.tcp_dst(53),
978 ])
979
980 matching = {
981 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
982 }
983
984 nonmatching = {
985 "tcp dport=52": simple_tcp_packet(tcp_dport=52),
986 "udp dport=53": simple_udp_packet(udp_dport=53),
987 }
988
989 self.verify_match(match, matching, nonmatching)
990
Rich Lane074c8ec2013-07-17 19:35:11 -0700991class IPv6TCPDst(MatchTest):
992 """
993 Match on ipv6 tcp destination port
994 """
995 def runTest(self):
996 match = ofp.match([
997 ofp.oxm.eth_type(0x86dd),
998 ofp.oxm.ip_proto(6),
999 ofp.oxm.tcp_dst(53),
1000 ])
1001
1002 matching = {
1003 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1004 }
1005
1006 nonmatching = {
1007 "tcp dport=52": simple_tcpv6_packet(tcp_dport=52),
1008 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1009 }
1010
1011 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001012
1013class IPv4UDPSrc(MatchTest):
1014 """
1015 Match on ipv4 udp source port
1016 """
1017 def runTest(self):
1018 match = ofp.match([
1019 ofp.oxm.eth_type(0x0800),
1020 ofp.oxm.ip_proto(17),
1021 ofp.oxm.udp_src(53),
1022 ])
1023
1024 matching = {
1025 "udp sport=53": simple_udp_packet(udp_sport=53),
1026 }
1027
1028 nonmatching = {
1029 "udp sport=52": simple_udp_packet(udp_sport=52),
1030 "tcp sport=53": simple_tcp_packet(tcp_sport=53),
1031 }
1032
1033 self.verify_match(match, matching, nonmatching)
1034
Rich Lane074c8ec2013-07-17 19:35:11 -07001035class IPv6UDPSrc(MatchTest):
1036 """
1037 Match on ipv4 udp source port
1038 """
1039 def runTest(self):
1040 match = ofp.match([
1041 ofp.oxm.eth_type(0x86dd),
1042 ofp.oxm.ip_proto(17),
1043 ofp.oxm.udp_src(53),
1044 ])
1045
1046 matching = {
1047 "udp sport=53": simple_udpv6_packet(udp_sport=53),
1048 }
1049
1050 nonmatching = {
1051 "udp sport=52": simple_udpv6_packet(udp_sport=52),
1052 "tcp sport=53": simple_tcpv6_packet(tcp_sport=53),
1053 }
1054
1055 self.verify_match(match, matching, nonmatching)
Rich Lane05e756b2013-07-17 15:48:16 -07001056
1057class IPv4UDPDst(MatchTest):
1058 """
1059 Match on ipv4 udp destination port
1060 """
1061 def runTest(self):
1062 match = ofp.match([
1063 ofp.oxm.eth_type(0x0800),
1064 ofp.oxm.ip_proto(17),
1065 ofp.oxm.udp_dst(53),
1066 ])
1067
1068 matching = {
1069 "udp dport=53": simple_udp_packet(udp_dport=53),
1070 }
1071
1072 nonmatching = {
1073 "udp dport=52": simple_udp_packet(udp_dport=52),
1074 "tcp dport=53": simple_tcp_packet(tcp_dport=53),
1075 }
1076
1077 self.verify_match(match, matching, nonmatching)
1078
Rich Lane074c8ec2013-07-17 19:35:11 -07001079class IPv6UDPDst(MatchTest):
1080 """
1081 Match on ipv4 udp destination port
1082 """
1083 def runTest(self):
1084 match = ofp.match([
1085 ofp.oxm.eth_type(0x86dd),
1086 ofp.oxm.ip_proto(17),
1087 ofp.oxm.udp_dst(53),
1088 ])
1089
1090 matching = {
1091 "udp dport=53": simple_udpv6_packet(udp_dport=53),
1092 }
1093
1094 nonmatching = {
1095 "udp dport=52": simple_udpv6_packet(udp_dport=52),
1096 "tcp dport=53": simple_tcpv6_packet(tcp_dport=53),
1097 }
1098
1099 self.verify_match(match, matching, nonmatching)
Rich Laneee574362013-07-17 16:40:07 -07001100
1101class IPv4ICMPType(MatchTest):
1102 """
1103 Match on ipv4 icmp type
1104 """
1105 def runTest(self):
1106 match = ofp.match([
1107 ofp.oxm.eth_type(0x0800),
1108 ofp.oxm.ip_proto(1),
1109 ofp.oxm.icmpv4_type(3),
1110 ])
1111
1112 matching = {
1113 "type=3 code=1": simple_icmp_packet(icmp_type=3, icmp_code=1),
1114 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1115 }
1116
1117 nonmatching = {
1118 "type=2 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
1119 }
1120
1121 self.verify_match(match, matching, nonmatching)
1122
1123class IPv4ICMPCode(MatchTest):
1124 """
1125 Match on ipv4 icmp code
1126 """
1127 def runTest(self):
1128 match = ofp.match([
1129 ofp.oxm.eth_type(0x0800),
1130 ofp.oxm.ip_proto(1),
1131 ofp.oxm.icmpv4_code(2),
1132 ])
1133
1134 matching = {
1135 "type=3 code=2": simple_icmp_packet(icmp_type=3, icmp_code=2),
1136 "type=5 code=2": simple_icmp_packet(icmp_type=5, icmp_code=2),
1137 }
1138
1139 nonmatching = {
1140 "type=3 code=1": simple_icmp_packet(icmp_type=2, icmp_code=1),
1141 }
1142
1143 self.verify_match(match, matching, nonmatching)
1144
Rich Lanea4317532013-07-17 19:27:19 -07001145class IPv6ICMPType(MatchTest):
1146 """
1147 Match on ipv6 icmp type
1148 """
1149 def runTest(self):
1150 match = ofp.match([
1151 ofp.oxm.eth_type(0x86dd),
1152 ofp.oxm.ip_proto(58),
1153 ofp.oxm.icmpv6_type(3),
1154 ])
1155
1156 matching = {
1157 "type=3 code=1": simple_icmpv6_packet(icmp_type=3, icmp_code=1),
1158 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1159 }
1160
1161 nonmatching = {
1162 "type=2 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
1163 }
1164
1165 self.verify_match(match, matching, nonmatching)
1166
1167class IPv6ICMPCode(MatchTest):
1168 """
1169 Match on ipv6 icmp code
1170 """
1171 def runTest(self):
1172 match = ofp.match([
1173 ofp.oxm.eth_type(0x86dd),
1174 ofp.oxm.ip_proto(58),
1175 ofp.oxm.icmpv6_code(2),
1176 ])
1177
1178 matching = {
1179 "type=3 code=2": simple_icmpv6_packet(icmp_type=3, icmp_code=2),
1180 "type=5 code=2": simple_icmpv6_packet(icmp_type=5, icmp_code=2),
1181 }
1182
1183 nonmatching = {
1184 "type=3 code=1": simple_icmpv6_packet(icmp_type=2, icmp_code=1),
1185 }
1186
1187 self.verify_match(match, matching, nonmatching)
Rich Lane6b770992013-07-17 17:11:24 -07001188
1189class ArpOp(MatchTest):
1190 """
1191 Match on ARP operation
1192 """
1193 def runTest(self):
1194 match = ofp.match([
1195 ofp.oxm.eth_type(0x0806),
1196 ofp.oxm.arp_op(3),
1197 ])
1198
1199 matching = {
1200 "op=3": simple_arp_packet(arp_op=3),
1201 }
1202
1203 nonmatching = {
1204 "op=4": simple_arp_packet(arp_op=4),
1205 }
1206
1207 self.verify_match(match, matching, nonmatching)
Rich Lane503a2de2013-07-17 17:20:58 -07001208
1209class ArpSPA(MatchTest):
1210 """
1211 Match on ARP sender IP
1212 """
1213 def runTest(self):
1214 match = ofp.match([
1215 ofp.oxm.eth_type(0x0806),
1216 ofp.oxm.arp_spa(0xc0a80001), # 192.168.0.1
1217 ])
1218
1219 matching = {
1220 "192.168.0.1": simple_arp_packet(ip_snd="192.168.0.1"),
1221 }
1222
1223 nonmatching = {
1224 "192.168.0.2": simple_arp_packet(ip_snd="192.168.0.2"),
1225 }
1226
1227 self.verify_match(match, matching, nonmatching)
1228
1229class ArpTPA(MatchTest):
1230 """
1231 Match on ARP target IP
1232 """
1233 def runTest(self):
1234 match = ofp.match([
1235 ofp.oxm.eth_type(0x0806),
1236 ofp.oxm.arp_tpa(0xc0a80001), # 192.168.0.1
1237 ])
1238
1239 matching = {
1240 "192.168.0.1": simple_arp_packet(ip_tgt="192.168.0.1"),
1241 }
1242
1243 nonmatching = {
1244 "192.168.0.2": simple_arp_packet(ip_tgt="192.168.0.2"),
1245 }
1246
1247 self.verify_match(match, matching, nonmatching)