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