blob: d9557ee7ef2213572e584a4ac76f73f3b18e192c [file] [log] [blame]
Andrew Yourtchenko08118f02018-02-08 21:45:08 +01001#!/usr/bin/env python
2""" Classifier-based L2 ACL Test Case HLD:
3"""
4
5import unittest
6import random
7import binascii
8import socket
9
10
11from scapy.packet import Raw
Jan Gelety059d1d02018-07-03 13:58:24 +020012from scapy.data import ETH_P_IP
Andrew Yourtchenko08118f02018-02-08 21:45:08 +010013from scapy.layers.l2 import Ether
14from scapy.layers.inet import IP, TCP, UDP, ICMP
15from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
16from scapy.layers.inet6 import IPv6ExtHdrFragment
17from framework import VppTestCase, VppTestRunner
18from util import Host, ppp
19
20
21class TestClassifyAcl(VppTestCase):
22 """ Classifier-based L2 input and output ACL Test Case """
23
24 # traffic types
25 IP = 0
26 ICMP = 1
27
28 # IP version
29 IPRANDOM = -1
30 IPV4 = 0
31 IPV6 = 1
32
33 # rule types
34 DENY = 0
35 PERMIT = 1
36
37 # supported protocols
38 proto = [[6, 17], [1, 58]]
39 proto_map = {1: 'ICMP', 58: 'ICMPv6EchoRequest', 6: 'TCP', 17: 'UDP'}
40 ICMPv4 = 0
41 ICMPv6 = 1
42 TCP = 0
43 UDP = 1
44 PROTO_ALL = 0
45
46 # port ranges
47 PORTS_ALL = -1
48 PORTS_RANGE = 0
49 PORTS_RANGE_2 = 1
50 udp_sport_from = 10
51 udp_sport_to = udp_sport_from + 5
52 udp_dport_from = 20000
53 udp_dport_to = udp_dport_from + 5000
54 tcp_sport_from = 30
55 tcp_sport_to = tcp_sport_from + 5
56 tcp_dport_from = 40000
57 tcp_dport_to = tcp_dport_from + 5000
58
59 udp_sport_from_2 = 90
60 udp_sport_to_2 = udp_sport_from_2 + 5
61 udp_dport_from_2 = 30000
62 udp_dport_to_2 = udp_dport_from_2 + 5000
63 tcp_sport_from_2 = 130
64 tcp_sport_to_2 = tcp_sport_from_2 + 5
65 tcp_dport_from_2 = 20000
66 tcp_dport_to_2 = tcp_dport_from_2 + 5000
67
68 icmp4_type = 8 # echo request
69 icmp4_code = 3
70 icmp6_type = 128 # echo request
71 icmp6_code = 3
72
73 icmp4_type_2 = 8
74 icmp4_code_from_2 = 5
75 icmp4_code_to_2 = 20
76 icmp6_type_2 = 128
77 icmp6_code_from_2 = 8
78 icmp6_code_to_2 = 42
79
80 # Test variables
81 bd_id = 1
82
83 @classmethod
84 def setUpClass(cls):
85 """
86 Perform standard class setup (defined by class method setUpClass in
87 class VppTestCase) before running the test case, set test case related
88 variables and configure VPP.
89 """
90 super(TestClassifyAcl, cls).setUpClass()
91
92 try:
93 # Create 2 pg interfaces
94 cls.create_pg_interfaces(range(2))
95
96 # Packet flows mapping pg0 -> pg1, pg2 etc.
97 cls.flows = dict()
98 cls.flows[cls.pg0] = [cls.pg1]
99
100 # Packet sizes
101 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
102
103 # Create BD with MAC learning and unknown unicast flooding disabled
104 # and put interfaces to this BD
105 cls.vapi.bridge_domain_add_del(bd_id=cls.bd_id, uu_flood=1,
106 learn=1)
107 for pg_if in cls.pg_interfaces:
108 cls.vapi.sw_interface_set_l2_bridge(pg_if.sw_if_index,
109 bd_id=cls.bd_id)
110
111 # Set up all interfaces
112 for i in cls.pg_interfaces:
113 i.admin_up()
114
115 # Mapping between packet-generator index and lists of test hosts
116 cls.hosts_by_pg_idx = dict()
117 for pg_if in cls.pg_interfaces:
118 cls.hosts_by_pg_idx[pg_if.sw_if_index] = []
119
120 # Create list of deleted hosts
121 cls.deleted_hosts_by_pg_idx = dict()
122 for pg_if in cls.pg_interfaces:
123 cls.deleted_hosts_by_pg_idx[pg_if.sw_if_index] = []
124
125 # warm-up the mac address tables
126 # self.warmup_test()
127
Jan Gelety059d1d02018-07-03 13:58:24 +0200128 # Holder of the active classify table key
129 cls.acl_active_table = ''
130
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100131 except Exception:
132 super(TestClassifyAcl, cls).tearDownClass()
133 raise
134
135 def setUp(self):
136 super(TestClassifyAcl, self).setUp()
137
138 self.acl_tbl_idx = {}
139 self.reset_packet_infos()
140
141 def tearDown(self):
142 """
143 Show various debug prints after each test.
144 """
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100145 if not self.vpp_dead:
146 self.logger.info(self.vapi.ppcli("show inacl type l2"))
147 self.logger.info(self.vapi.ppcli("show outacl type l2"))
148 self.logger.info(self.vapi.ppcli("show classify tables verbose"))
149 self.logger.info(self.vapi.ppcli("show bridge-domain %s detail"
150 % self.bd_id))
Jan Gelety059d1d02018-07-03 13:58:24 +0200151 if self.acl_active_table == 'mac_inout':
152 self.output_acl_set_interface(
153 self.pg1, self.acl_tbl_idx.get(self.acl_active_table), 0)
154 self.input_acl_set_interface(
155 self.pg0, self.acl_tbl_idx.get(self.acl_active_table), 0)
156 self.acl_active_table = ''
157 elif self.acl_active_table == 'mac_out':
158 self.output_acl_set_interface(
159 self.pg1, self.acl_tbl_idx.get(self.acl_active_table), 0)
160 self.acl_active_table = ''
161 elif self.acl_active_table == 'mac_in':
162 self.input_acl_set_interface(
163 self.pg0, self.acl_tbl_idx.get(self.acl_active_table), 0)
164 self.acl_active_table = ''
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100165
Jan Gelety059d1d02018-07-03 13:58:24 +0200166 super(TestClassifyAcl, self).tearDown()
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100167
168 @staticmethod
169 def build_mac_mask(dst_mac='', src_mac='', ether_type=''):
170 """Build MAC ACL mask data with hexstring format
171
172 :param str dst_mac: source MAC address <0-ffffffffffff>
173 :param str src_mac: destination MAC address <0-ffffffffffff>
174 :param str ether_type: ethernet type <0-ffff>
175 """
176
177 return ('{:0>12}{:0>12}{:0>4}'.format(dst_mac, src_mac,
178 ether_type)).rstrip('0')
179
180 @staticmethod
181 def build_mac_match(dst_mac='', src_mac='', ether_type=''):
182 """Build MAC ACL match data with hexstring format
183
184 :param str dst_mac: source MAC address <x:x:x:x:x:x>
185 :param str src_mac: destination MAC address <x:x:x:x:x:x>
186 :param str ether_type: ethernet type <0-ffff>
187 """
188 if dst_mac:
189 dst_mac = dst_mac.replace(':', '')
190 if src_mac:
191 src_mac = src_mac.replace(':', '')
192
193 return ('{:0>12}{:0>12}{:0>4}'.format(dst_mac, src_mac,
194 ether_type)).rstrip('0')
195
196 def create_classify_table(self, key, mask, data_offset=0, is_add=1):
197 """Create Classify Table
198
199 :param str key: key for classify table (ex, ACL name).
200 :param str mask: mask value for interested traffic.
201 :param int match_n_vectors:
202 :param int is_add: option to configure classify table.
203 - create(1) or delete(0)
204 """
205 r = self.vapi.classify_add_del_table(
206 is_add,
207 binascii.unhexlify(mask),
208 match_n_vectors=(len(mask) - 1) // 32 + 1,
209 miss_next_index=0,
210 current_data_flag=1,
211 current_data_offset=data_offset)
212 self.assertIsNotNone(r, msg='No response msg for add_del_table')
213 self.acl_tbl_idx[key] = r.new_table_index
214
215 def create_classify_session(self, intf, table_index, match,
216 hit_next_index=0xffffffff, is_add=1):
217 """Create Classify Session
218
219 :param VppInterface intf: Interface to apply classify session.
220 :param int table_index: table index to identify classify table.
221 :param str match: matched value for interested traffic.
222 :param int pbr_action: enable/disable PBR feature.
223 :param int vrfid: VRF id.
224 :param int is_add: option to configure classify session.
225 - create(1) or delete(0)
226 """
227 r = self.vapi.classify_add_del_session(
228 is_add,
229 table_index,
230 binascii.unhexlify(match),
231 hit_next_index=hit_next_index)
232 self.assertIsNotNone(r, msg='No response msg for add_del_session')
233
234 def input_acl_set_interface(self, intf, table_index, is_add=1):
235 """Configure Input ACL interface
236
237 :param VppInterface intf: Interface to apply Input ACL feature.
238 :param int table_index: table index to identify classify table.
239 :param int is_add: option to configure classify session.
240 - enable(1) or disable(0)
241 """
242 r = self.vapi.input_acl_set_interface(
243 is_add,
244 intf.sw_if_index,
245 l2_table_index=table_index)
246 self.assertIsNotNone(r, msg='No response msg for acl_set_interface')
247
248 def output_acl_set_interface(self, intf, table_index, is_add=1):
249 """Configure Output ACL interface
250
251 :param VppInterface intf: Interface to apply Output ACL feature.
252 :param int table_index: table index to identify classify table.
253 :param int is_add: option to configure classify session.
254 - enable(1) or disable(0)
255 """
256 r = self.vapi.output_acl_set_interface(
257 is_add,
258 intf.sw_if_index,
259 l2_table_index=table_index)
260 self.assertIsNotNone(r, msg='No response msg for acl_set_interface')
261
262 def create_hosts(self, count, start=0):
263 """
264 Create required number of host MAC addresses and distribute them among
265 interfaces. Create host IPv4 address for every host MAC address.
266
267 :param int count: Number of hosts to create MAC/IPv4 addresses for.
268 :param int start: Number to start numbering from.
269 """
270 n_int = len(self.pg_interfaces)
271 macs_per_if = count / n_int
272 i = -1
273 for pg_if in self.pg_interfaces:
274 i += 1
275 start_nr = macs_per_if * i + start
276 end_nr = count + start if i == (n_int - 1) \
277 else macs_per_if * (i + 1) + start
278 hosts = self.hosts_by_pg_idx[pg_if.sw_if_index]
279 for j in range(start_nr, end_nr):
280 host = Host(
281 "00:00:00:ff:%02x:%02x" % (pg_if.sw_if_index, j),
282 "172.17.1%02x.%u" % (pg_if.sw_if_index, j),
283 "2017:dead:%02x::%u" % (pg_if.sw_if_index, j))
284 hosts.append(host)
285
286 def create_upper_layer(self, packet_index, proto, ports=0):
287 p = self.proto_map[proto]
288 if p == 'UDP':
289 if ports == 0:
290 return UDP(sport=random.randint(self.udp_sport_from,
291 self.udp_sport_to),
292 dport=random.randint(self.udp_dport_from,
293 self.udp_dport_to))
294 else:
295 return UDP(sport=ports, dport=ports)
296 elif p == 'TCP':
297 if ports == 0:
298 return TCP(sport=random.randint(self.tcp_sport_from,
299 self.tcp_sport_to),
300 dport=random.randint(self.tcp_dport_from,
301 self.tcp_dport_to))
302 else:
303 return TCP(sport=ports, dport=ports)
304 return ''
305
306 def create_stream(self, src_if, packet_sizes, traffic_type=0, ipv6=0,
307 proto=-1, ports=0, fragments=False,
308 pkt_raw=True, etype=-1):
309 """
310 Create input packet stream for defined interface using hosts or
311 deleted_hosts list.
312
313 :param object src_if: Interface to create packet stream for.
314 :param list packet_sizes: List of required packet sizes.
315 :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise.
316 :return: Stream of packets.
317 """
318 pkts = []
319 if self.flows.__contains__(src_if):
320 src_hosts = self.hosts_by_pg_idx[src_if.sw_if_index]
321 for dst_if in self.flows[src_if]:
322 dst_hosts = self.hosts_by_pg_idx[dst_if.sw_if_index]
323 n_int = len(dst_hosts) * len(src_hosts)
324 for i in range(0, n_int):
325 dst_host = dst_hosts[i / len(src_hosts)]
326 src_host = src_hosts[i % len(src_hosts)]
327 pkt_info = self.create_packet_info(src_if, dst_if)
328 if ipv6 == 1:
329 pkt_info.ip = 1
330 elif ipv6 == 0:
331 pkt_info.ip = 0
332 else:
333 pkt_info.ip = random.choice([0, 1])
334 if proto == -1:
335 pkt_info.proto = random.choice(self.proto[self.IP])
336 else:
337 pkt_info.proto = proto
338 payload = self.info_to_payload(pkt_info)
339 p = Ether(dst=dst_host.mac, src=src_host.mac)
340 if etype > 0:
341 p = Ether(dst=dst_host.mac,
342 src=src_host.mac,
343 type=etype)
344 if pkt_info.ip:
345 p /= IPv6(dst=dst_host.ip6, src=src_host.ip6)
346 if fragments:
347 p /= IPv6ExtHdrFragment(offset=64, m=1)
348 else:
349 if fragments:
350 p /= IP(src=src_host.ip4, dst=dst_host.ip4,
351 flags=1, frag=64)
352 else:
353 p /= IP(src=src_host.ip4, dst=dst_host.ip4)
354 if traffic_type == self.ICMP:
355 if pkt_info.ip:
356 p /= ICMPv6EchoRequest(type=self.icmp6_type,
357 code=self.icmp6_code)
358 else:
359 p /= ICMP(type=self.icmp4_type,
360 code=self.icmp4_code)
361 else:
362 p /= self.create_upper_layer(i, pkt_info.proto, ports)
363 if pkt_raw:
364 p /= Raw(payload)
365 pkt_info.data = p.copy()
366 if pkt_raw:
367 size = random.choice(packet_sizes)
368 self.extend_packet(p, size)
369 pkts.append(p)
370 return pkts
371
372 def verify_capture(self, pg_if, capture,
373 traffic_type=0, ip_type=0, etype=-1):
374 """
375 Verify captured input packet stream for defined interface.
376
377 :param object pg_if: Interface to verify captured packet stream for.
378 :param list capture: Captured packet stream.
379 :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise.
380 """
381 last_info = dict()
382 for i in self.pg_interfaces:
383 last_info[i.sw_if_index] = None
384 dst_sw_if_index = pg_if.sw_if_index
385 for packet in capture:
386 if etype > 0:
387 if packet[Ether].type != etype:
388 self.logger.error(ppp("Unexpected ethertype in packet:",
389 packet))
390 else:
391 continue
392 try:
393 # Raw data for ICMPv6 are stored in ICMPv6EchoRequest.data
394 if traffic_type == self.ICMP and ip_type == self.IPV6:
395 payload_info = self.payload_to_info(
396 packet[ICMPv6EchoRequest].data)
397 payload = packet[ICMPv6EchoRequest]
398 else:
399 payload_info = self.payload_to_info(str(packet[Raw]))
400 payload = packet[self.proto_map[payload_info.proto]]
401 except:
402 self.logger.error(ppp("Unexpected or invalid packet "
403 "(outside network):", packet))
404 raise
405
406 if ip_type != 0:
407 self.assertEqual(payload_info.ip, ip_type)
408 if traffic_type == self.ICMP:
409 try:
410 if payload_info.ip == 0:
411 self.assertEqual(payload.type, self.icmp4_type)
412 self.assertEqual(payload.code, self.icmp4_code)
413 else:
414 self.assertEqual(payload.type, self.icmp6_type)
415 self.assertEqual(payload.code, self.icmp6_code)
416 except:
417 self.logger.error(ppp("Unexpected or invalid packet "
418 "(outside network):", packet))
419 raise
420 else:
421 try:
422 ip_version = IPv6 if payload_info.ip == 1 else IP
423
424 ip = packet[ip_version]
425 packet_index = payload_info.index
426
427 self.assertEqual(payload_info.dst, dst_sw_if_index)
428 self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
429 (pg_if.name, payload_info.src,
430 packet_index))
431 next_info = self.get_next_packet_info_for_interface2(
432 payload_info.src, dst_sw_if_index,
433 last_info[payload_info.src])
434 last_info[payload_info.src] = next_info
435 self.assertTrue(next_info is not None)
436 self.assertEqual(packet_index, next_info.index)
437 saved_packet = next_info.data
438 # Check standard fields
439 self.assertEqual(ip.src, saved_packet[ip_version].src)
440 self.assertEqual(ip.dst, saved_packet[ip_version].dst)
441 p = self.proto_map[payload_info.proto]
442 if p == 'TCP':
443 tcp = packet[TCP]
444 self.assertEqual(tcp.sport, saved_packet[
445 TCP].sport)
446 self.assertEqual(tcp.dport, saved_packet[
447 TCP].dport)
448 elif p == 'UDP':
449 udp = packet[UDP]
450 self.assertEqual(udp.sport, saved_packet[
451 UDP].sport)
452 self.assertEqual(udp.dport, saved_packet[
453 UDP].dport)
454 except:
455 self.logger.error(ppp("Unexpected or invalid packet:",
456 packet))
457 raise
458 for i in self.pg_interfaces:
459 remaining_packet = self.get_next_packet_info_for_interface2(
460 i, dst_sw_if_index, last_info[i.sw_if_index])
461 self.assertTrue(
462 remaining_packet is None,
463 "Port %u: Packet expected from source %u didn't arrive" %
464 (dst_sw_if_index, i.sw_if_index))
465
466 def run_traffic_no_check(self):
467 # Test
468 # Create incoming packet streams for packet-generator interfaces
469 for i in self.pg_interfaces:
470 if self.flows.__contains__(i):
471 pkts = self.create_stream(i, self.pg_if_packet_sizes)
472 if len(pkts) > 0:
473 i.add_stream(pkts)
474
475 # Enable packet capture and start packet sending
476 self.pg_enable_capture(self.pg_interfaces)
477 self.pg_start()
478
479 def run_verify_test(self, traffic_type=0, ip_type=0, proto=-1, ports=0,
480 frags=False, pkt_raw=True, etype=-1):
481 # Test
482 # Create incoming packet streams for packet-generator interfaces
483 pkts_cnt = 0
484 for i in self.pg_interfaces:
485 if self.flows.__contains__(i):
486 pkts = self.create_stream(i, self.pg_if_packet_sizes,
487 traffic_type, ip_type, proto, ports,
488 frags, pkt_raw, etype)
489 if len(pkts) > 0:
490 i.add_stream(pkts)
491 pkts_cnt += len(pkts)
492
493 # Enable packet capture and start packet sendingself.IPV
494 self.pg_enable_capture(self.pg_interfaces)
495 self.pg_start()
496
497 # Verify
498 # Verify outgoing packet streams per packet-generator interface
499 for src_if in self.pg_interfaces:
500 if self.flows.__contains__(src_if):
501 for dst_if in self.flows[src_if]:
502 capture = dst_if.get_capture(pkts_cnt)
503 self.logger.info("Verifying capture on interface %s" %
504 dst_if.name)
505 self.verify_capture(dst_if, capture,
506 traffic_type, ip_type, etype)
507
508 def run_verify_negat_test(self, traffic_type=0, ip_type=0, proto=-1,
509 ports=0, frags=False, etype=-1):
510 # Test
511 self.reset_packet_infos()
512 for i in self.pg_interfaces:
513 if self.flows.__contains__(i):
514 pkts = self.create_stream(i, self.pg_if_packet_sizes,
515 traffic_type, ip_type, proto, ports,
516 frags, True, etype)
517 if len(pkts) > 0:
518 i.add_stream(pkts)
519
520 # Enable packet capture and start packet sending
521 self.pg_enable_capture(self.pg_interfaces)
522 self.pg_start()
523
524 # Verify
525 # Verify outgoing packet streams per packet-generator interface
526 for src_if in self.pg_interfaces:
527 if self.flows.__contains__(src_if):
528 for dst_if in self.flows[src_if]:
529 self.logger.info("Verifying capture on interface %s" %
530 dst_if.name)
531 capture = dst_if.get_capture(0)
532 self.assertEqual(len(capture), 0)
533
Jan Gelety059d1d02018-07-03 13:58:24 +0200534 def build_classify_table(self, src_mac='', dst_mac='', ether_type='',
535 etype='', key='mac', hit_next_index=0xffffffff):
536 # Basic ACL testing
537 a_mask = self.build_mac_mask(src_mac=src_mac, dst_mac=dst_mac,
538 ether_type=ether_type)
539 self.create_classify_table(key, a_mask)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100540 for host in self.hosts_by_pg_idx[self.pg0.sw_if_index]:
Jan Gelety059d1d02018-07-03 13:58:24 +0200541 s_mac = host.mac if src_mac else ''
542 if dst_mac:
543 for dst_if in self.flows[self.pg0]:
544 for dst_host in self.hosts_by_pg_idx[dst_if.sw_if_index]:
545 self.create_classify_session(
546 self.pg0, self.acl_tbl_idx.get(key),
547 self.build_mac_match(src_mac=s_mac,
548 dst_mac=dst_host.mac,
549 ether_type=etype),
550 hit_next_index=hit_next_index)
551 else:
552 self.create_classify_session(
553 self.pg0, self.acl_tbl_idx.get(key),
554 self.build_mac_match(src_mac=s_mac, dst_mac='',
555 ether_type=etype),
556 hit_next_index=hit_next_index)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100557
558 def test_0000_warmup_test(self):
559 """ Learn the MAC addresses
560 """
561 self.create_hosts(2)
562 self.run_traffic_no_check()
563
Jan Gelety059d1d02018-07-03 13:58:24 +0200564 def test_0010_inacl_permit_src_mac(self):
565 """ Input L2 ACL test - permit source MAC
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100566
567 Test scenario for basic IP ACL with source IP
568 - Create IPv4 stream for pg0 -> pg1 interface.
569 - Create ACL with source MAC address.
570 - Send and verify received packets on pg1 interface.
571 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200572 key = 'mac_in'
573 self.build_classify_table(src_mac='ffffffffffff', key=key)
574 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
575 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100576 self.run_verify_test(self.IP, self.IPV4, -1)
Jan Gelety059d1d02018-07-03 13:58:24 +0200577
578 def test_0011_inacl_permit_dst_mac(self):
579 """ Input L2 ACL test - permit destination MAC
580
581 Test scenario for basic IP ACL with source IP
582 - Create IPv4 stream for pg0 -> pg1 interface.
583 - Create ACL with destination MAC address.
584 - Send and verify received packets on pg1 interface.
585 """
586 key = 'mac_in'
587 self.build_classify_table(dst_mac='ffffffffffff', key=key)
588 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
589 self.acl_active_table = key
590 self.run_verify_test(self.IP, self.IPV4, -1)
591
592 def test_0012_inacl_permit_src_dst_mac(self):
593 """ Input L2 ACL test - permit source and destination MAC
594
595 Test scenario for basic IP ACL with source IP
596 - Create IPv4 stream for pg0 -> pg1 interface.
597 - Create ACL with source and destination MAC addresses.
598 - Send and verify received packets on pg1 interface.
599 """
600 key = 'mac_in'
601 self.build_classify_table(
602 src_mac='ffffffffffff', dst_mac='ffffffffffff', key=key)
603 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
604 self.acl_active_table = key
605 self.run_verify_test(self.IP, self.IPV4, -1)
606
607 def test_0013_inacl_permit_ether_type(self):
608 """ Input L2 ACL test - permit ether_type
609
610 Test scenario for basic IP ACL with source IP
611 - Create IPv4 stream for pg0 -> pg1 interface.
612 - Create ACL with destination MAC address.
613 - Send and verify received packets on pg1 interface.
614 """
615 key = 'mac_in'
616 self.build_classify_table(
617 ether_type='ffff', etype=hex(ETH_P_IP)[2:], key=key)
618 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
619 self.acl_active_table = key
620 self.run_verify_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100621
622 def test_0015_inacl_deny(self):
623 """ Input L2 ACL test - deny
624
625 Test scenario for basic IP ACL with source IP
626 - Create IPv4 stream for pg0 -> pg1 interface.
Jan Gelety059d1d02018-07-03 13:58:24 +0200627
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100628 - Create ACL with source MAC address.
629 - Send and verify no received packets on pg1 interface.
630 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200631 key = 'mac_in'
632 self.build_classify_table(
633 src_mac='ffffffffffff', hit_next_index=0, key=key)
634 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
635 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100636 self.run_verify_negat_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100637
638 def test_0020_outacl_permit(self):
639 """ Output L2 ACL test - permit
640
641 Test scenario for basic IP ACL with source IP
642 - Create IPv4 stream for pg0 -> pg1 interface.
643 - Create ACL with source MAC address.
644 - Send and verify received packets on pg1 interface.
645 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200646 key = 'mac_out'
647 self.build_classify_table(src_mac='ffffffffffff', key=key)
648 self.output_acl_set_interface(self.pg1, self.acl_tbl_idx.get(key))
649 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100650 self.run_verify_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100651
652 def test_0025_outacl_deny(self):
653 """ Output L2 ACL test - deny
654
655 Test scenario for basic IP ACL with source IP
656 - Create IPv4 stream for pg0 -> pg1 interface.
657 - Create ACL with source MAC address.
658 - Send and verify no received packets on pg1 interface.
659 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200660 key = 'mac_out'
661 self.build_classify_table(
662 src_mac='ffffffffffff', hit_next_index=0, key=key)
663 self.output_acl_set_interface(self.pg1, self.acl_tbl_idx.get(key))
664 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100665 self.run_verify_negat_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100666
667 def test_0030_inoutacl_permit(self):
668 """ Input+Output L2 ACL test - permit
669
670 Test scenario for basic IP ACL with source IP
671 - Create IPv4 stream for pg0 -> pg1 interface.
672 - Create ACLs with source MAC address.
673 - Send and verify received packets on pg1 interface.
674 """
Jan Gelety059d1d02018-07-03 13:58:24 +0200675 key = 'mac_inout'
676 self.build_classify_table(src_mac='ffffffffffff', key=key)
677 self.output_acl_set_interface(self.pg1, self.acl_tbl_idx.get(key))
678 self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
679 self.acl_active_table = key
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100680 self.run_verify_test(self.IP, self.IPV4, -1)
Andrew Yourtchenko08118f02018-02-08 21:45:08 +0100681
682if __name__ == '__main__':
683 unittest.main(testRunner=VppTestRunner)