builtinurl: mark api as deprecated
[vpp.git] / test / test_acl_plugin_macip.py
1 #!/usr/bin/env python3
2 from __future__ import print_function
3
4 """ACL plugin - MACIP tests
5 """
6 import random
7 from socket import inet_ntop, inet_pton, AF_INET, AF_INET6
8 from struct import pack, unpack
9 import re
10 import unittest
11 from ipaddress import ip_network, IPv4Network, IPv6Network
12 from config import config
13
14 import scapy.compat
15 from scapy.packet import Raw
16 from scapy.layers.l2 import Ether
17 from scapy.layers.inet import IP, UDP
18 from scapy.layers.inet6 import IPv6
19
20 from framework import VppTestCase
21 from asfframework import VppTestRunner
22 from vpp_lo_interface import VppLoInterface
23 from vpp_l2 import L2_PORT_TYPE
24 from vpp_sub_interface import (
25     L2_VTR_OP,
26     VppSubInterface,
27     VppDot1QSubint,
28     VppDot1ADSubint,
29 )
30 from vpp_acl import (
31     AclRule,
32     VppAcl,
33     VppAclInterface,
34     VppMacipAclInterface,
35     VppMacipAcl,
36     MacipRule,
37 )
38 from vpp_papi import MACAddress
39
40
41 @unittest.skipIf("acl" in config.excluded_plugins, "Exclude ACL plugin tests")
42 class MethodHolder(VppTestCase):
43     DEBUG = False
44
45     BRIDGED = True
46     ROUTED = False
47
48     IS_IP4 = False
49     IS_IP6 = True
50
51     DOT1AD = "dot1ad"
52     DOT1Q = "dot1q"
53     PERMIT_TAGS = True
54     DENY_TAGS = False
55
56     # rule types
57     DENY = 0
58     PERMIT = 1
59
60     # ACL types
61     EXACT_IP = 1
62     SUBNET_IP = 2
63     WILD_IP = 3
64
65     EXACT_MAC = 1
66     WILD_MAC = 2
67     OUI_MAC = 3
68
69     ACLS = []
70
71     @classmethod
72     def setUpClass(cls):
73         """
74         Perform standard class setup (defined by class method setUpClass in
75         class VppTestCase) before running the test case, set test case related
76         variables and configure VPP.
77         """
78         super(MethodHolder, cls).setUpClass()
79
80         cls.pg_if_packet_sizes = [64, 512, 1518, 9018]  # packet sizes
81         cls.bd_id = 111
82         cls.remote_hosts_count = 200
83
84         try:
85             # create 4 pg interfaces, 1 loopback interface
86             cls.create_pg_interfaces(range(4))
87             cls.create_loopback_interfaces(1)
88
89             # create 2 subinterfaces
90             cls.subifs = [
91                 VppDot1QSubint(cls, cls.pg1, 10),
92                 VppDot1ADSubint(cls, cls.pg2, 20, 300, 400),
93                 VppDot1QSubint(cls, cls.pg3, 30),
94                 VppDot1ADSubint(cls, cls.pg3, 40, 600, 700),
95             ]
96
97             cls.subifs[0].set_vtr(L2_VTR_OP.L2_POP_1, inner=10, push1q=1)
98             cls.subifs[1].set_vtr(L2_VTR_OP.L2_POP_2, outer=300, inner=400, push1q=1)
99             cls.subifs[2].set_vtr(L2_VTR_OP.L2_POP_1, inner=30, push1q=1)
100             cls.subifs[3].set_vtr(L2_VTR_OP.L2_POP_2, outer=600, inner=700, push1q=1)
101
102             cls.interfaces = list(cls.pg_interfaces)
103             cls.interfaces.extend(cls.lo_interfaces)
104             cls.interfaces.extend(cls.subifs)
105
106             for i in cls.interfaces:
107                 i.admin_up()
108
109             # Create BD with MAC learning enabled and put interfaces to this BD
110             cls.vapi.sw_interface_set_l2_bridge(
111                 rx_sw_if_index=cls.loop0.sw_if_index,
112                 bd_id=cls.bd_id,
113                 port_type=L2_PORT_TYPE.BVI,
114             )
115             cls.vapi.sw_interface_set_l2_bridge(
116                 rx_sw_if_index=cls.pg0.sw_if_index, bd_id=cls.bd_id
117             )
118             cls.vapi.sw_interface_set_l2_bridge(
119                 rx_sw_if_index=cls.pg1.sw_if_index, bd_id=cls.bd_id
120             )
121             cls.vapi.sw_interface_set_l2_bridge(
122                 rx_sw_if_index=cls.subifs[0].sw_if_index, bd_id=cls.bd_id
123             )
124             cls.vapi.sw_interface_set_l2_bridge(
125                 rx_sw_if_index=cls.subifs[1].sw_if_index, bd_id=cls.bd_id
126             )
127
128             # Configure IPv4/6 addresses on loop interface and routed interface
129             cls.loop0.config_ip4()
130             cls.loop0.config_ip6()
131             cls.pg2.config_ip4()
132             cls.pg2.config_ip6()
133             cls.pg3.config_ip4()
134             cls.pg3.config_ip6()
135
136             # Configure MAC address binding to IPv4 neighbors on loop0
137             cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
138             # Modify host mac addresses to have different OUI parts
139             for i in range(2, cls.remote_hosts_count + 2):
140                 mac = cls.loop0.remote_hosts[i - 2]._mac.split(":")
141                 mac[2] = format(int(mac[2], 16) + i, "02x")
142                 cls.loop0.remote_hosts[i - 2]._mac = ":".join(mac)
143
144             cls.loop0.configure_ipv4_neighbors()
145             cls.loop0.configure_ipv6_neighbors()
146
147             # configure MAC address on pg3
148             cls.pg3.resolve_arp()
149             cls.pg3.resolve_ndp()
150
151             # configure MAC address on subifs
152             for i in cls.subifs:
153                 i.config_ip4()
154                 i.resolve_arp()
155                 i.config_ip6()
156
157             # configure MAC address on pg2
158             cls.pg2.resolve_arp()
159             cls.pg2.resolve_ndp()
160
161             # Loopback BVI interface has remote hosts
162             # one half of hosts are behind pg0 second behind pg1,pg2,pg3 subifs
163             cls.pg0.remote_hosts = cls.loop0.remote_hosts[:100]
164             cls.subifs[0].remote_hosts = cls.loop0.remote_hosts[100:125]
165             cls.subifs[1].remote_hosts = cls.loop0.remote_hosts[125:150]
166             cls.subifs[2].remote_hosts = cls.loop0.remote_hosts[150:175]
167             cls.subifs[3].remote_hosts = cls.loop0.remote_hosts[175:]
168
169         except Exception:
170             super(MethodHolder, cls).tearDownClass()
171             raise
172
173     @classmethod
174     def tearDownClass(cls):
175         super(MethodHolder, cls).tearDownClass()
176
177     def setUp(self):
178         super(MethodHolder, self).setUp()
179         self.reset_packet_infos()
180
181     def show_commands_at_teardown(self):
182         self.logger.info(self.vapi.ppcli("show interface address"))
183         self.logger.info(self.vapi.ppcli("show hardware"))
184         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl"))
185         self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface"))
186         self.logger.info(self.vapi.ppcli("sh classify tables verbose"))
187         self.logger.info(self.vapi.ppcli("sh acl-plugin acl"))
188         self.logger.info(self.vapi.ppcli("sh acl-plugin interface"))
189         self.logger.info(self.vapi.ppcli("sh acl-plugin tables"))
190         # print(self.vapi.ppcli("show interface address"))
191         # print(self.vapi.ppcli("show hardware"))
192         # print(self.vapi.ppcli("sh acl-plugin macip interface"))
193         # print(self.vapi.ppcli("sh acl-plugin macip acl"))
194
195     def macip_acl_dump_debug(self):
196         acls = self.vapi.macip_acl_dump()
197         if self.DEBUG:
198             for acl in acls:
199                 # print("ACL #"+str(acl.acl_index))
200                 for r in acl.r:
201                     rule = "ACTION"
202                     if r.is_permit == 1:
203                         rule = "PERMIT"
204                     elif r.is_permit == 0:
205                         rule = "DENY  "
206                     """
207                     print("    IP6" if r.is_ipv6 else "    IP4",
208                           rule,
209                           binascii.hexlify(r.src_mac),
210                           binascii.hexlify(r.src_mac_mask),
211                           unpack('<16B', r.src_ip_addr),
212                           r.src_ip_prefix_len)
213                     """
214         return acls
215
216     def create_rules(
217         self, mac_type=EXACT_MAC, ip_type=EXACT_IP, acl_count=1, rules_count=None
218     ):
219         acls = []
220         if rules_count is None:
221             rules_count = [1]
222         src_mac = int("220000dead00", 16)
223         for acl in range(2, (acl_count + 1) * 2):
224             rules = []
225             host = random.choice(self.loop0.remote_hosts)
226             is_ip6 = acl % 2
227             ip4 = host.ip4.split(".")
228             ip6 = list(unpack("<16B", inet_pton(AF_INET6, host.ip6)))
229
230             if ip_type == self.EXACT_IP:
231                 prefix_len4 = 32
232                 prefix_len6 = 128
233             elif ip_type == self.WILD_IP:
234                 ip4 = [0, 0, 0, 0]
235                 ip6 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
236                 prefix_len4 = 0
237                 prefix_len6 = 0
238                 rules_count[int((acl / 2) - 1)] = 1
239             else:
240                 prefix_len4 = 24
241                 prefix_len6 = 64
242
243             if mac_type == self.EXACT_MAC:
244                 mask = "ff:ff:ff:ff:ff:ff"
245             elif mac_type == self.WILD_MAC:
246                 mask = "00:00:00:00:00:00"
247             elif mac_type == self.OUI_MAC:
248                 mask = "ff:ff:ff:00:00:00"
249             else:
250                 mask = "ff:ff:ff:ff:ff:00"
251
252             ip = ip6 if is_ip6 else ip4
253             ip_len = prefix_len6 if is_ip6 else prefix_len4
254
255             for i in range(0, (rules_count[int((acl / 2) - 1)])):
256                 src_mac += 16777217
257                 if mac_type == self.WILD_MAC:
258                     mac = "00:00:00:00:00:00"
259                 elif mac_type == self.OUI_MAC:
260                     mac = (
261                         ":".join(re.findall("..", "{:02x}".format(src_mac))[:3])
262                         + ":00:00:00"
263                     )
264                 else:
265                     mac = ":".join(re.findall("..", "{:02x}".format(src_mac)))
266
267                 if ip_type == self.EXACT_IP:
268                     ip4[3] = random.randint(100, 200)
269                     ip6[15] = random.randint(100, 200)
270                 elif ip_type == self.SUBNET_IP:
271                     ip4[2] = random.randint(100, 200)
272                     ip4[3] = 0
273                     ip6[7] = random.randint(100, 200)
274                     ip6[15] = 0
275                 ip_pack = b""
276                 for j in range(0, len(ip)):
277                     ip_pack += pack("<B", int(ip[j]))
278
279                 rule = MacipRule(
280                     is_permit=self.PERMIT,
281                     src_prefix=ip_network((ip_pack, ip_len)),
282                     src_mac=MACAddress(mac).packed,
283                     src_mac_mask=MACAddress(mask).packed,
284                 )
285                 rules.append(rule)
286                 if ip_type == self.WILD_IP:
287                     break
288
289             acls.append(rules)
290             src_mac += 1099511627776
291         return acls
292
293     def apply_macip_rules(self, acls):
294         macip_acls = []
295         for acl in acls:
296             macip_acl = VppMacipAcl(self, rules=acl)
297             macip_acl.add_vpp_config()
298             macip_acls.append(macip_acl)
299         return macip_acls
300
301     def verify_macip_acls(self, acl_count, rules_count, expected_count=2):
302         reply = self.macip_acl_dump_debug()
303         for acl in range(2, (acl_count + 1) * 2):
304             self.assertEqual(reply[acl - 2].count, rules_count[acl // 2 - 1])
305
306         self.vapi.macip_acl_interface_get()
307
308         self.vapi.macip_acl_interface_add_del(sw_if_index=0, acl_index=0)
309         self.vapi.macip_acl_interface_add_del(sw_if_index=1, acl_index=1)
310
311         reply = self.vapi.macip_acl_interface_get()
312         self.assertEqual(reply.count, expected_count)
313
314     def create_stream(
315         self,
316         mac_type,
317         ip_type,
318         packet_count,
319         src_if,
320         dst_if,
321         traffic,
322         is_ip6,
323         tags=PERMIT_TAGS,
324     ):
325         # exact MAC and exact IP
326         # exact MAC and subnet of IPs
327         # exact MAC and wildcard IP
328         # wildcard MAC and exact IP
329         # wildcard MAC and subnet of IPs
330         # wildcard MAC and wildcard IP
331         # OUI restricted MAC and exact IP
332         # OUI restricted MAC and subnet of IPs
333         # OUI restricted MAC and wildcard IP
334
335         packets = []
336         macip_rules = []
337         acl_rules = []
338         ip_permit = ""
339         mac_permit = ""
340         dst_mac = ""
341         mac_rule = "00:00:00:00:00:00"
342         mac_mask = "00:00:00:00:00:00"
343         for p in range(0, packet_count):
344             remote_dst_index = p % len(dst_if.remote_hosts)
345             remote_dst_host = dst_if.remote_hosts[remote_dst_index]
346
347             dst_port = 1234 + p
348             src_port = 4321 + p
349             is_permit = self.PERMIT if p % 3 == 0 else self.DENY
350             denyMAC = True if not is_permit and p % 3 == 1 else False
351             denyIP = True if not is_permit and p % 3 == 2 else False
352             if not is_permit and ip_type == self.WILD_IP:
353                 denyMAC = True
354             if not is_permit and mac_type == self.WILD_MAC:
355                 denyIP = True
356
357             if traffic == self.BRIDGED:
358                 if is_permit:
359                     src_mac = remote_dst_host._mac
360                     dst_mac = "de:ad:00:00:00:00"
361                     src_ip4 = remote_dst_host.ip4
362                     dst_ip4 = src_if.remote_ip4
363                     src_ip6 = remote_dst_host.ip6
364                     dst_ip6 = src_if.remote_ip6
365                     ip_permit = src_ip6 if is_ip6 else src_ip4
366                     mac_permit = src_mac
367                 if denyMAC:
368                     mac = src_mac.split(":")
369                     mac[0] = format(int(mac[0], 16) + 1, "02x")
370                     src_mac = ":".join(mac)
371                     if is_ip6:
372                         src_ip6 = ip_permit
373                     else:
374                         src_ip4 = ip_permit
375                 if denyIP:
376                     if ip_type != self.WILD_IP:
377                         src_mac = mac_permit
378                     src_ip4 = remote_dst_host.ip4
379                     dst_ip4 = src_if.remote_ip4
380                     src_ip6 = remote_dst_host.ip6
381                     dst_ip6 = src_if.remote_ip6
382             else:
383                 if is_permit:
384                     src_mac = remote_dst_host._mac
385                     dst_mac = src_if.local_mac
386                     src_ip4 = src_if.remote_ip4
387                     dst_ip4 = remote_dst_host.ip4
388                     src_ip6 = src_if.remote_ip6
389                     dst_ip6 = remote_dst_host.ip6
390                     ip_permit = src_ip6 if is_ip6 else src_ip4
391                     mac_permit = src_mac
392                 if denyMAC:
393                     mac = src_mac.split(":")
394                     mac[0] = format(int(mac[0], 16) + 1, "02x")
395                     src_mac = ":".join(mac)
396                     if is_ip6:
397                         src_ip6 = ip_permit
398                     else:
399                         src_ip4 = ip_permit
400                 if denyIP:
401                     src_mac = remote_dst_host._mac
402                     if ip_type != self.WILD_IP:
403                         src_mac = mac_permit
404                     src_ip4 = remote_dst_host.ip4
405                     dst_ip4 = src_if.remote_ip4
406                     src_ip6 = remote_dst_host.ip6
407                     dst_ip6 = src_if.remote_ip6
408
409             if is_permit:
410                 info = self.create_packet_info(src_if, dst_if)
411                 payload = self.info_to_payload(info)
412             else:
413                 payload = "to be blocked"
414
415             if mac_type == self.WILD_MAC:
416                 mac = src_mac.split(":")
417                 for i in range(1, 5):
418                     mac[i] = format(random.randint(0, 255), "02x")
419                 src_mac = ":".join(mac)
420
421             # create packet
422             packet = Ether(src=src_mac, dst=dst_mac)
423             ip_rule = src_ip6 if is_ip6 else src_ip4
424             if is_ip6:
425                 if ip_type != self.EXACT_IP:
426                     sub_ip = list(unpack("<16B", inet_pton(AF_INET6, ip_rule)))
427                     if ip_type == self.WILD_IP:
428                         sub_ip[0] = random.randint(240, 254)
429                         sub_ip[1] = random.randint(230, 239)
430                         sub_ip[14] = random.randint(100, 199)
431                         sub_ip[15] = random.randint(200, 255)
432                     elif ip_type == self.SUBNET_IP:
433                         if denyIP:
434                             sub_ip[2] = int(sub_ip[2]) + 1
435                         sub_ip[14] = random.randint(100, 199)
436                         sub_ip[15] = random.randint(200, 255)
437                     packed_src_ip6 = b"".join([scapy.compat.chb(x) for x in sub_ip])
438                     src_ip6 = inet_ntop(AF_INET6, packed_src_ip6)
439                 packet /= IPv6(src=src_ip6, dst=dst_ip6)
440             else:
441                 if ip_type != self.EXACT_IP:
442                     sub_ip = ip_rule.split(".")
443                     if ip_type == self.WILD_IP:
444                         sub_ip[0] = random.randint(1, 49)
445                         sub_ip[1] = random.randint(50, 99)
446                         sub_ip[2] = random.randint(100, 199)
447                         sub_ip[3] = random.randint(200, 255)
448                     elif ip_type == self.SUBNET_IP:
449                         if denyIP:
450                             sub_ip[1] = int(sub_ip[1]) + 1
451                         sub_ip[2] = random.randint(100, 199)
452                         sub_ip[3] = random.randint(200, 255)
453                     src_ip4 = ".".join(["{!s}".format(x) for x in sub_ip])
454                 packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0)
455
456             packet /= UDP(sport=src_port, dport=dst_port) / Raw(payload)
457
458             packet[Raw].load += b" mac:%s" % src_mac.encode("utf-8")
459
460             size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)]
461             if isinstance(src_if, VppSubInterface):
462                 size = size + 4
463             if isinstance(src_if, VppDot1QSubint):
464                 if src_if is self.subifs[0]:
465                     if tags == self.PERMIT_TAGS:
466                         packet = src_if.add_dot1q_layer(packet, 10)
467                     else:
468                         packet = src_if.add_dot1q_layer(packet, 11)
469                 else:
470                     if tags == self.PERMIT_TAGS:
471                         packet = src_if.add_dot1q_layer(packet, 30)
472                     else:
473                         packet = src_if.add_dot1q_layer(packet, 33)
474             elif isinstance(src_if, VppDot1ADSubint):
475                 if src_if is self.subifs[1]:
476                     if tags == self.PERMIT_TAGS:
477                         packet = src_if.add_dot1ad_layer(packet, 300, 400)
478                     else:
479                         packet = src_if.add_dot1ad_layer(packet, 333, 444)
480                 else:
481                     if tags == self.PERMIT_TAGS:
482                         packet = src_if.add_dot1ad_layer(packet, 600, 700)
483                     else:
484                         packet = src_if.add_dot1ad_layer(packet, 666, 777)
485             self.extend_packet(packet, size)
486             packets.append(packet)
487
488             # create suitable MACIP rule
489             if mac_type == self.EXACT_MAC:
490                 mac_rule = src_mac
491                 mac_mask = "ff:ff:ff:ff:ff:ff"
492             elif mac_type == self.WILD_MAC:
493                 mac_rule = "00:00:00:00:00:00"
494                 mac_mask = "00:00:00:00:00:00"
495             elif mac_type == self.OUI_MAC:
496                 mac = src_mac.split(":")
497                 mac[3] = mac[4] = mac[5] = "00"
498                 mac_rule = ":".join(mac)
499                 mac_mask = "ff:ff:ff:00:00:00"
500
501             if is_ip6:
502                 if ip_type == self.WILD_IP:
503                     ip = "0::0"
504                 else:
505                     ip = src_ip6
506                     if ip_type == self.SUBNET_IP:
507                         sub_ip = list(unpack("<16B", inet_pton(AF_INET6, ip)))
508                         for i in range(8, 16):
509                             sub_ip[i] = 0
510                         packed_ip = b"".join([scapy.compat.chb(x) for x in sub_ip])
511                         ip = inet_ntop(AF_INET6, packed_ip)
512             else:
513                 if ip_type == self.WILD_IP:
514                     ip = "0.0.0.0"
515                 else:
516                     ip = src_ip4
517                     if ip_type == self.SUBNET_IP:
518                         sub_ip = ip.split(".")
519                         sub_ip[2] = sub_ip[3] = "0"
520                         ip = ".".join(sub_ip)
521
522             prefix_len = 128 if is_ip6 else 32
523             if ip_type == self.WILD_IP:
524                 prefix_len = 0
525             elif ip_type == self.SUBNET_IP:
526                 prefix_len = 64 if is_ip6 else 16
527             ip_rule = inet_pton(AF_INET6 if is_ip6 else AF_INET, ip)
528
529             # create suitable ACL rule
530             if is_permit:
531                 rule_l4_sport = packet[UDP].sport
532                 rule_l4_dport = packet[UDP].dport
533                 rule_family = AF_INET6 if packet.haslayer(IPv6) else AF_INET
534                 rule_prefix_len = 128 if packet.haslayer(IPv6) else 32
535                 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP
536                 if packet.haslayer(IPv6):
537                     rule_l4_proto = packet[UDP].overload_fields[IPv6]["nh"]
538                 else:
539                     rule_l4_proto = packet[IP].proto
540
541                 src_network = ip_network((packet[rule_l3_layer].src, rule_prefix_len))
542                 dst_network = ip_network((packet[rule_l3_layer].dst, rule_prefix_len))
543                 acl_rule = AclRule(
544                     is_permit=is_permit,
545                     proto=rule_l4_proto,
546                     src_prefix=src_network,
547                     dst_prefix=dst_network,
548                     sport_from=rule_l4_sport,
549                     sport_to=rule_l4_sport,
550                     dport_from=rule_l4_dport,
551                     dport_to=rule_l4_dport,
552                 )
553                 acl_rules.append(acl_rule)
554
555             if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0:
556                 continue
557
558             if is_permit:
559                 macip_rule = MacipRule(
560                     is_permit=is_permit,
561                     src_prefix=ip_network((ip_rule, prefix_len)),
562                     src_mac=MACAddress(mac_rule).packed,
563                     src_mac_mask=MACAddress(mac_mask).packed,
564                 )
565                 macip_rules.append(macip_rule)
566
567         # deny all other packets
568         if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP):
569             network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0))
570             macip_rule = MacipRule(
571                 is_permit=0,
572                 src_prefix=network,
573                 src_mac=MACAddress("00:00:00:00:00:00").packed,
574                 src_mac_mask=MACAddress("00:00:00:00:00:00").packed,
575             )
576             macip_rules.append(macip_rule)
577
578         network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0))
579         acl_rule = AclRule(
580             is_permit=0,
581             src_prefix=network,
582             dst_prefix=network,
583             sport_from=0,
584             sport_to=0,
585             dport_from=0,
586             dport_to=0,
587         )
588         acl_rules.append(acl_rule)
589         return {"stream": packets, "macip_rules": macip_rules, "acl_rules": acl_rules}
590
591     def verify_capture(self, stream, capture, is_ip6):
592         """
593         :param stream:
594         :param capture:
595         :param is_ip6:
596         :return:
597         """
598         # p_l3 = IPv6 if is_ip6 else IP
599         # if self.DEBUG:
600         #     for p in stream:
601         #         print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst)
602         #
603         # acls = self.macip_acl_dump_debug()
604
605         # TODO : verify
606         # for acl in acls:
607         #     for r in acl.r:
608         #         print(binascii.hexlify(r.src_mac), \
609         #               binascii.hexlify(r.src_mac_mask),\
610         #               unpack('<16B', r.src_ip_addr), \
611         #               r.src_ip_prefix_len)
612         #
613         # for p in capture:
614         #     print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst
615         #     data = p[Raw].load.split(':',1)[1])
616         #     print(p[p_l3].src, data)
617
618     def run_traffic(
619         self,
620         mac_type,
621         ip_type,
622         traffic,
623         is_ip6,
624         packets,
625         do_not_expected_capture=False,
626         tags=None,
627         apply_rules=True,
628         isMACIP=True,
629         permit_tags=PERMIT_TAGS,
630         try_replace=False,
631     ):
632         self.reset_packet_infos()
633
634         if tags is None:
635             tx_if = self.pg0 if traffic == self.BRIDGED else self.pg3
636             rx_if = self.pg3 if traffic == self.BRIDGED else self.pg0
637             src_if = self.pg3
638             dst_if = self.loop0
639         else:
640             if tags == self.DOT1Q:
641                 if traffic == self.BRIDGED:
642                     tx_if = self.subifs[0]
643                     rx_if = self.pg0
644                     src_if = self.subifs[0]
645                     dst_if = self.loop0
646                 else:
647                     tx_if = self.subifs[2]
648                     rx_if = self.pg0
649                     src_if = self.subifs[2]
650                     dst_if = self.loop0
651             elif tags == self.DOT1AD:
652                 if traffic == self.BRIDGED:
653                     tx_if = self.subifs[1]
654                     rx_if = self.pg0
655                     src_if = self.subifs[1]
656                     dst_if = self.loop0
657                 else:
658                     tx_if = self.subifs[3]
659                     rx_if = self.pg0
660                     src_if = self.subifs[3]
661                     dst_if = self.loop0
662             else:
663                 return
664
665         test_dict = self.create_stream(
666             mac_type,
667             ip_type,
668             packets,
669             src_if,
670             dst_if,
671             traffic,
672             is_ip6,
673             tags=permit_tags,
674         )
675
676         if apply_rules:
677             if isMACIP:
678                 self.acl = VppMacipAcl(self, rules=test_dict["macip_rules"])
679             else:
680                 self.acl = VppAcl(self, rules=test_dict["acl_rules"])
681             self.acl.add_vpp_config()
682
683             if isMACIP:
684                 self.acl_if = VppMacipAclInterface(
685                     self, sw_if_index=tx_if.sw_if_index, acls=[self.acl]
686                 )
687                 self.acl_if.add_vpp_config()
688
689                 dump = self.acl_if.dump()
690                 self.assertTrue(dump)
691                 self.assertEqual(dump[0].acls[0], self.acl.acl_index)
692             else:
693                 self.acl_if = VppAclInterface(
694                     self, sw_if_index=tx_if.sw_if_index, n_input=1, acls=[self.acl]
695                 )
696                 self.acl_if.add_vpp_config()
697         else:
698             if hasattr(self, "acl_if"):
699                 self.acl_if.remove_vpp_config()
700         if try_replace and hasattr(self, "acl"):
701             if isMACIP:
702                 self.acl.modify_vpp_config(test_dict["macip_rules"])
703             else:
704                 self.acl.modify_vpp_config(test_dict["acl_rules"])
705
706         if not isinstance(src_if, VppSubInterface):
707             tx_if.add_stream(test_dict["stream"])
708         else:
709             tx_if.parent.add_stream(test_dict["stream"])
710         self.pg_enable_capture(self.pg_interfaces)
711         self.pg_start()
712
713         if do_not_expected_capture:
714             rx_if.get_capture(0)
715         else:
716             if (
717                 traffic == self.BRIDGED
718                 and mac_type == self.WILD_MAC
719                 and ip_type == self.WILD_IP
720             ):
721                 capture = rx_if.get_capture(packets)
722             else:
723                 capture = rx_if.get_capture(
724                     self.get_packet_count_for_if_idx(dst_if.sw_if_index)
725                 )
726             self.verify_capture(test_dict["stream"], capture, is_ip6)
727         if not isMACIP:
728             if hasattr(self, "acl_if"):
729                 self.acl_if.remove_vpp_config()
730             if hasattr(self, "acl"):
731                 self.acl.remove_vpp_config()
732
733     def run_test_acls(
734         self, mac_type, ip_type, acl_count, rules_count, traffic=None, ip=None
735     ):
736         self.apply_macip_rules(
737             self.create_rules(mac_type, ip_type, acl_count, rules_count)
738         )
739         self.verify_macip_acls(acl_count, rules_count)
740
741         if traffic is not None:
742             self.run_traffic(self.EXACT_MAC, self.EXACT_IP, traffic, ip, 9)
743
744
745 class TestMACIP_IP4(MethodHolder):
746     """MACIP with IP4 traffic"""
747
748     @classmethod
749     def setUpClass(cls):
750         super(TestMACIP_IP4, cls).setUpClass()
751
752     @classmethod
753     def tearDownClass(cls):
754         super(TestMACIP_IP4, cls).tearDownClass()
755
756     def test_acl_bridged_ip4_exactMAC_exactIP(self):
757         """IP4 MACIP exactMAC|exactIP ACL bridged traffic"""
758         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9)
759
760     def test_acl_bridged_ip4_exactMAC_subnetIP(self):
761         """IP4 MACIP exactMAC|subnetIP ACL bridged traffic"""
762
763         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9)
764
765     def test_acl_bridged_ip4_exactMAC_wildIP(self):
766         """IP4 MACIP exactMAC|wildIP ACL bridged traffic"""
767
768         self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9)
769
770     def test_acl_bridged_ip4_ouiMAC_exactIP(self):
771         """IP4 MACIP ouiMAC|exactIP ACL bridged traffic"""
772
773         self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 3)
774
775     def test_acl_bridged_ip4_ouiMAC_subnetIP(self):
776         """IP4 MACIP ouiMAC|subnetIP ACL bridged traffic"""
777
778         self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9)
779
780     def test_acl_bridged_ip4_ouiMAC_wildIP(self):
781         """IP4 MACIP ouiMAC|wildIP ACL bridged traffic"""
782
783         self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9)
784
785     def test_ac_bridgedl_ip4_wildMAC_exactIP(self):
786         """IP4 MACIP wildcardMAC|exactIP ACL bridged traffic"""
787
788         self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9)
789
790     def test_acl_bridged_ip4_wildMAC_subnetIP(self):
791         """IP4 MACIP wildcardMAC|subnetIP ACL bridged traffic"""
792
793         self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9)
794
795     def test_acl_bridged_ip4_wildMAC_wildIP(self):
796         """IP4 MACIP wildcardMAC|wildIP ACL bridged traffic"""
797
798         self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9)
799
800     def test_acl_routed_ip4_exactMAC_exactIP(self):
801         """IP4 MACIP exactMAC|exactIP ACL routed traffic"""
802         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9)
803
804     def test_acl_routed_ip4_exactMAC_subnetIP(self):
805         """IP4 MACIP exactMAC|subnetIP ACL routed traffic"""
806         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9)
807
808     def test_acl_routed_ip4_exactMAC_wildIP(self):
809         """IP4 MACIP exactMAC|wildIP ACL routed traffic"""
810         self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9)
811
812     def test_acl_routed_ip4_ouiMAC_exactIP(self):
813         """IP4 MACIP ouiMAC|exactIP ACL routed traffic"""
814
815         self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9)
816
817     def test_acl_routed_ip4_ouiMAC_subnetIP(self):
818         """IP4 MACIP ouiMAC|subnetIP ACL routed traffic"""
819
820         self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9)
821
822     def test_acl_routed_ip4_ouiMAC_wildIP(self):
823         """IP4 MACIP ouiMAC|wildIP ACL routed traffic"""
824
825         self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9)
826
827     def test_acl_routed_ip4_wildMAC_exactIP(self):
828         """IP4 MACIP wildcardMAC|exactIP ACL routed traffic"""
829
830         self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9)
831
832     def test_acl_routed_ip4_wildMAC_subnetIP(self):
833         """IP4 MACIP wildcardMAC|subnetIP ACL routed traffic"""
834
835         self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9)
836
837     def test_acl_routed_ip4_wildMAC_wildIP(self):
838         """IP4 MACIP wildcardMAC|wildIP ACL"""
839
840         self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9)
841
842     def test_acl_replace_traffic_ip4(self):
843         """MACIP replace ACL with IP4 traffic"""
844         self.run_traffic(
845             self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9, try_replace=True
846         )
847         self.run_traffic(
848             self.EXACT_MAC,
849             self.EXACT_IP,
850             self.BRIDGED,
851             self.IS_IP4,
852             9,
853             try_replace=True,
854         )
855
856
857 class TestMACIP_IP6(MethodHolder):
858     """MACIP with IP6 traffic"""
859
860     @classmethod
861     def setUpClass(cls):
862         super(TestMACIP_IP6, cls).setUpClass()
863
864     @classmethod
865     def tearDownClass(cls):
866         super(TestMACIP_IP6, cls).tearDownClass()
867
868     def test_acl_bridged_ip6_exactMAC_exactIP(self):
869         """IP6 MACIP exactMAC|exactIP ACL bridged traffic"""
870
871         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9)
872
873     def test_acl_bridged_ip6_exactMAC_subnetIP(self):
874         """IP6 MACIP exactMAC|subnetIP ACL bridged traffic"""
875
876         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9)
877
878     def test_acl_bridged_ip6_exactMAC_wildIP(self):
879         """IP6 MACIP exactMAC|wildIP ACL bridged traffic"""
880
881         self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9)
882
883     def test_acl_bridged_ip6_ouiMAC_exactIP(self):
884         """IP6 MACIP oui_MAC|exactIP ACL bridged traffic"""
885
886         self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9)
887
888     def test_acl_bridged_ip6_ouiMAC_subnetIP(self):
889         """IP6 MACIP ouiMAC|subnetIP ACL bridged traffic"""
890
891         self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9)
892
893     def test_acl_bridged_ip6_ouiMAC_wildIP(self):
894         """IP6 MACIP ouiMAC|wildIP ACL bridged traffic"""
895
896         self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9)
897
898     def test_acl_bridged_ip6_wildMAC_exactIP(self):
899         """IP6 MACIP wildcardMAC|exactIP ACL bridged traffic"""
900
901         self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9)
902
903     def test_acl_bridged_ip6_wildMAC_subnetIP(self):
904         """IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic"""
905
906         self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9)
907
908     def test_acl_bridged_ip6_wildMAC_wildIP(self):
909         """IP6 MACIP wildcardMAC|wildIP ACL bridged traffic"""
910
911         self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9)
912
913     def test_acl_routed_ip6_exactMAC_exactIP(self):
914         """IP6 MACIP exactMAC|exactIP ACL routed traffic"""
915
916         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9)
917
918     def test_acl_routed_ip6_exactMAC_subnetIP(self):
919         """IP6 MACIP exactMAC|subnetIP ACL routed traffic"""
920
921         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9)
922
923     def test_acl_routed_ip6_exactMAC_wildIP(self):
924         """IP6 MACIP exactMAC|wildIP ACL routed traffic"""
925
926         self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9)
927
928     def test_acl_routed_ip6_ouiMAC_exactIP(self):
929         """IP6 MACIP ouiMAC|exactIP ACL routed traffic"""
930
931         self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9)
932
933     def test_acl_routed_ip6_ouiMAC_subnetIP(self):
934         """IP6 MACIP ouiMAC|subnetIP ACL routed traffic"""
935
936         self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9)
937
938     def test_acl_routed_ip6_ouiMAC_wildIP(self):
939         """IP6 MACIP ouiMAC|wildIP ACL routed traffic"""
940
941         self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9)
942
943     def test_acl_routed_ip6_wildMAC_exactIP(self):
944         """IP6 MACIP wildcardMAC|exactIP ACL routed traffic"""
945
946         self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9)
947
948     def test_acl_routed_ip6_wildMAC_subnetIP(self):
949         """IP6 MACIP wildcardMAC|subnetIP ACL routed traffic"""
950
951         self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9)
952
953     def test_acl_routed_ip6_wildMAC_wildIP(self):
954         """IP6 MACIP wildcardMAC|wildIP ACL"""
955
956         self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9)
957
958     def test_acl_replace_traffic_ip6(self):
959         """MACIP replace ACL with IP6 traffic"""
960         self.run_traffic(
961             self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9, try_replace=True
962         )
963         self.run_traffic(
964             self.EXACT_MAC,
965             self.EXACT_IP,
966             self.BRIDGED,
967             self.IS_IP6,
968             9,
969             try_replace=True,
970         )
971
972
973 class TestMACIP(MethodHolder):
974     """MACIP Tests"""
975
976     @classmethod
977     def setUpClass(cls):
978         super(TestMACIP, cls).setUpClass()
979
980     @classmethod
981     def tearDownClass(cls):
982         super(TestMACIP, cls).tearDownClass()
983
984     def test_acl_1_2(self):
985         """MACIP ACL with 2 entries"""
986
987         self.run_test_acls(self.EXACT_MAC, self.WILD_IP, 1, [2])
988
989     def test_acl_1_5(self):
990         """MACIP ACL with 5 entries"""
991
992         self.run_test_acls(self.EXACT_MAC, self.SUBNET_IP, 1, [5])
993
994     def test_acl_1_10(self):
995         """MACIP ACL with 10 entries"""
996
997         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 1, [10])
998
999     def test_acl_1_20(self):
1000         """MACIP ACL with 20 entries"""
1001
1002         self.run_test_acls(self.OUI_MAC, self.WILD_IP, 1, [20])
1003
1004     def test_acl_1_50(self):
1005         """MACIP ACL with 50 entries"""
1006
1007         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 1, [50])
1008
1009     def test_acl_1_100(self):
1010         """MACIP ACL with 100 entries"""
1011
1012         self.run_test_acls(self.OUI_MAC, self.EXACT_IP, 1, [100])
1013
1014     def test_acl_2_X(self):
1015         """MACIP 2 ACLs each with 100+ entries"""
1016
1017         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 2, [100, 200])
1018
1019     def test_acl_10_X(self):
1020         """MACIP 10 ACLs each with 100+ entries"""
1021
1022         self.run_test_acls(
1023             self.EXACT_MAC,
1024             self.EXACT_IP,
1025             10,
1026             [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
1027         )
1028
1029     def test_acl_10_X_traffic_ip4(self):
1030         """MACIP 10 ACLs each with 100+ entries with IP4 traffic"""
1031
1032         self.run_test_acls(
1033             self.EXACT_MAC,
1034             self.EXACT_IP,
1035             10,
1036             [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
1037             self.BRIDGED,
1038             self.IS_IP4,
1039         )
1040
1041     def test_acl_10_X_traffic_ip6(self):
1042         """MACIP 10 ACLs each with 100+ entries with IP6 traffic"""
1043
1044         self.run_test_acls(
1045             self.EXACT_MAC,
1046             self.EXACT_IP,
1047             10,
1048             [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
1049             self.BRIDGED,
1050             self.IS_IP6,
1051         )
1052
1053     def test_acl_replace(self):
1054         """MACIP replace ACL"""
1055
1056         r1 = self.create_rules(acl_count=3, rules_count=[2, 2, 2])
1057         r2 = self.create_rules(mac_type=self.OUI_MAC, ip_type=self.SUBNET_IP)
1058         macip_acls = self.apply_macip_rules(r1)
1059
1060         acls_before = self.macip_acl_dump_debug()
1061
1062         # replace acls #2, #3 with new
1063         macip_acls[2].modify_vpp_config(r2[0])
1064         macip_acls[3].modify_vpp_config(r2[1])
1065
1066         acls_after = self.macip_acl_dump_debug()
1067
1068         # verify changes
1069         self.assertEqual(len(acls_before), len(acls_after))
1070         for acl1, acl2 in zip(
1071             acls_before[:2] + acls_before[4:], acls_after[:2] + acls_after[4:]
1072         ):
1073             self.assertEqual(len(acl1), len(acl2))
1074
1075             self.assertEqual(len(acl1.r), len(acl2.r))
1076             for r1, r2 in zip(acl1.r, acl2.r):
1077                 self.assertEqual(len(acl1.r), len(acl2.r))
1078                 self.assertEqual(acl1.r, acl2.r)
1079         for acl1, acl2 in zip(acls_before[2:4], acls_after[2:4]):
1080             self.assertEqual(len(acl1), len(acl2))
1081
1082             self.assertNotEqual(len(acl1.r), len(acl2.r))
1083             for r1, r2 in zip(acl1.r, acl2.r):
1084                 self.assertNotEqual(len(acl1.r), len(acl2.r))
1085                 self.assertNotEqual(acl1.r, acl2.r)
1086
1087     def test_delete_intf(self):
1088         """MACIP ACL delete intf with acl"""
1089
1090         intf_count = len(self.interfaces) + 1
1091         intf = []
1092         macip_alcs = self.apply_macip_rules(
1093             self.create_rules(acl_count=3, rules_count=[3, 5, 4])
1094         )
1095
1096         intf.append(VppLoInterface(self))
1097         intf.append(VppLoInterface(self))
1098
1099         sw_if_index0 = intf[0].sw_if_index
1100         macip_acl_if0 = VppMacipAclInterface(
1101             self, sw_if_index=sw_if_index0, acls=[macip_alcs[1]]
1102         )
1103         macip_acl_if0.add_vpp_config()
1104
1105         reply = self.vapi.macip_acl_interface_get()
1106         self.assertEqual(reply.count, intf_count + 1)
1107         self.assertEqual(reply.acls[sw_if_index0], 1)
1108
1109         sw_if_index1 = intf[1].sw_if_index
1110         macip_acl_if1 = VppMacipAclInterface(
1111             self, sw_if_index=sw_if_index1, acls=[macip_alcs[0]]
1112         )
1113         macip_acl_if1.add_vpp_config()
1114
1115         reply = self.vapi.macip_acl_interface_get()
1116         self.assertEqual(reply.count, intf_count + 2)
1117         self.assertEqual(reply.acls[sw_if_index1], 0)
1118
1119         intf[0].remove_vpp_config()
1120         reply = self.vapi.macip_acl_interface_get()
1121         self.assertEqual(reply.count, intf_count + 2)
1122         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
1123         self.assertEqual(reply.acls[sw_if_index1], 0)
1124
1125         intf.append(VppLoInterface(self))
1126         intf.append(VppLoInterface(self))
1127         sw_if_index2 = intf[2].sw_if_index
1128         sw_if_index3 = intf[3].sw_if_index
1129         macip_acl_if2 = VppMacipAclInterface(
1130             self, sw_if_index=sw_if_index2, acls=[macip_alcs[1]]
1131         )
1132         macip_acl_if2.add_vpp_config()
1133         macip_acl_if3 = VppMacipAclInterface(
1134             self, sw_if_index=sw_if_index3, acls=[macip_alcs[1]]
1135         )
1136         macip_acl_if3.add_vpp_config()
1137
1138         reply = self.vapi.macip_acl_interface_get()
1139         self.assertEqual(reply.count, intf_count + 3)
1140         self.assertEqual(reply.acls[sw_if_index1], 0)
1141         self.assertEqual(reply.acls[sw_if_index2], 1)
1142         self.assertEqual(reply.acls[sw_if_index3], 1)
1143         self.logger.info("MACIP ACL on multiple interfaces:")
1144         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl"))
1145         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 1234"))
1146         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 1"))
1147         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 0"))
1148         self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface"))
1149
1150         intf[2].remove_vpp_config()
1151         intf[1].remove_vpp_config()
1152
1153         reply = self.vapi.macip_acl_interface_get()
1154         self.assertEqual(reply.count, intf_count + 3)
1155         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
1156         self.assertEqual(reply.acls[sw_if_index1], 4294967295)
1157         self.assertEqual(reply.acls[sw_if_index2], 4294967295)
1158         self.assertEqual(reply.acls[sw_if_index3], 1)
1159
1160         intf[3].remove_vpp_config()
1161         reply = self.vapi.macip_acl_interface_get()
1162
1163         self.assertEqual(len([x for x in reply.acls if x != 4294967295]), 0)
1164
1165
1166 class TestACL_dot1q_bridged(MethodHolder):
1167     """ACL on dot1q bridged subinterfaces Tests"""
1168
1169     @classmethod
1170     def setUpClass(cls):
1171         super(TestACL_dot1q_bridged, cls).setUpClass()
1172
1173     @classmethod
1174     def tearDownClass(cls):
1175         super(TestACL_dot1q_bridged, cls).tearDownClass()
1176
1177     def test_acl_bridged_ip4_subif_dot1q(self):
1178         """IP4 ACL SubIf Dot1Q bridged traffic"""
1179         self.run_traffic(
1180             self.EXACT_MAC,
1181             self.EXACT_IP,
1182             self.BRIDGED,
1183             self.IS_IP4,
1184             9,
1185             tags=self.DOT1Q,
1186             isMACIP=False,
1187         )
1188
1189     def test_acl_bridged_ip6_subif_dot1q(self):
1190         """IP6 ACL SubIf Dot1Q bridged traffic"""
1191         self.run_traffic(
1192             self.EXACT_MAC,
1193             self.EXACT_IP,
1194             self.BRIDGED,
1195             self.IS_IP6,
1196             9,
1197             tags=self.DOT1Q,
1198             isMACIP=False,
1199         )
1200
1201
1202 class TestACL_dot1ad_bridged(MethodHolder):
1203     """ACL on dot1ad bridged subinterfaces Tests"""
1204
1205     @classmethod
1206     def setUpClass(cls):
1207         super(TestACL_dot1ad_bridged, cls).setUpClass()
1208
1209     @classmethod
1210     def tearDownClass(cls):
1211         super(TestACL_dot1ad_bridged, cls).tearDownClass()
1212
1213     def test_acl_bridged_ip4_subif_dot1ad(self):
1214         """IP4 ACL SubIf Dot1AD bridged traffic"""
1215         self.run_traffic(
1216             self.EXACT_MAC,
1217             self.EXACT_IP,
1218             self.BRIDGED,
1219             self.IS_IP4,
1220             9,
1221             tags=self.DOT1AD,
1222             isMACIP=False,
1223         )
1224
1225     def test_acl_bridged_ip6_subif_dot1ad(self):
1226         """IP6 ACL SubIf Dot1AD bridged traffic"""
1227         self.run_traffic(
1228             self.EXACT_MAC,
1229             self.EXACT_IP,
1230             self.BRIDGED,
1231             self.IS_IP6,
1232             9,
1233             tags=self.DOT1AD,
1234             isMACIP=False,
1235         )
1236
1237
1238 class TestACL_dot1q_routed(MethodHolder):
1239     """ACL on dot1q routed subinterfaces Tests"""
1240
1241     @classmethod
1242     def setUpClass(cls):
1243         super(TestACL_dot1q_routed, cls).setUpClass()
1244
1245     @classmethod
1246     def tearDownClass(cls):
1247         super(TestACL_dot1q_routed, cls).tearDownClass()
1248
1249     def test_acl_routed_ip4_subif_dot1q(self):
1250         """IP4 ACL SubIf Dot1Q routed traffic"""
1251         self.run_traffic(
1252             self.EXACT_MAC,
1253             self.EXACT_IP,
1254             self.ROUTED,
1255             self.IS_IP4,
1256             9,
1257             tags=self.DOT1Q,
1258             isMACIP=False,
1259         )
1260
1261     def test_acl_routed_ip6_subif_dot1q(self):
1262         """IP6 ACL SubIf Dot1Q routed traffic"""
1263         self.run_traffic(
1264             self.EXACT_MAC,
1265             self.EXACT_IP,
1266             self.ROUTED,
1267             self.IS_IP6,
1268             9,
1269             tags=self.DOT1Q,
1270             isMACIP=False,
1271         )
1272
1273     def test_acl_routed_ip4_subif_dot1q_deny_by_tags(self):
1274         """IP4 ACL SubIf wrong tags Dot1Q routed traffic"""
1275         self.run_traffic(
1276             self.EXACT_MAC,
1277             self.EXACT_IP,
1278             self.ROUTED,
1279             self.IS_IP4,
1280             9,
1281             True,
1282             tags=self.DOT1Q,
1283             isMACIP=False,
1284             permit_tags=self.DENY_TAGS,
1285         )
1286
1287     def test_acl_routed_ip6_subif_dot1q_deny_by_tags(self):
1288         """IP6 ACL SubIf wrong tags Dot1Q routed traffic"""
1289         self.run_traffic(
1290             self.EXACT_MAC,
1291             self.EXACT_IP,
1292             self.ROUTED,
1293             self.IS_IP6,
1294             9,
1295             True,
1296             tags=self.DOT1Q,
1297             isMACIP=False,
1298             permit_tags=self.DENY_TAGS,
1299         )
1300
1301
1302 class TestACL_dot1ad_routed(MethodHolder):
1303     """ACL on dot1ad routed subinterfaces Tests"""
1304
1305     @classmethod
1306     def setUpClass(cls):
1307         super(TestACL_dot1ad_routed, cls).setUpClass()
1308
1309     @classmethod
1310     def tearDownClass(cls):
1311         super(TestACL_dot1ad_routed, cls).tearDownClass()
1312
1313     def test_acl_routed_ip6_subif_dot1ad(self):
1314         """IP6 ACL SubIf Dot1AD routed traffic"""
1315         self.run_traffic(
1316             self.EXACT_MAC,
1317             self.EXACT_IP,
1318             self.ROUTED,
1319             self.IS_IP6,
1320             9,
1321             tags=self.DOT1AD,
1322             isMACIP=False,
1323         )
1324
1325     def test_acl_routed_ip4_subif_dot1ad(self):
1326         """IP4 ACL SubIf Dot1AD routed traffic"""
1327         self.run_traffic(
1328             self.EXACT_MAC,
1329             self.EXACT_IP,
1330             self.ROUTED,
1331             self.IS_IP4,
1332             9,
1333             tags=self.DOT1AD,
1334             isMACIP=False,
1335         )
1336
1337     def test_acl_routed_ip6_subif_dot1ad_deny_by_tags(self):
1338         """IP6 ACL SubIf wrong tags Dot1AD routed traffic"""
1339         self.run_traffic(
1340             self.EXACT_MAC,
1341             self.EXACT_IP,
1342             self.ROUTED,
1343             self.IS_IP6,
1344             9,
1345             True,
1346             tags=self.DOT1AD,
1347             isMACIP=False,
1348             permit_tags=self.DENY_TAGS,
1349         )
1350
1351     def test_acl_routed_ip4_subif_dot1ad_deny_by_tags(self):
1352         """IP4 ACL SubIf wrong tags Dot1AD routed traffic"""
1353         self.run_traffic(
1354             self.EXACT_MAC,
1355             self.EXACT_IP,
1356             self.ROUTED,
1357             self.IS_IP4,
1358             9,
1359             True,
1360             tags=self.DOT1AD,
1361             isMACIP=False,
1362             permit_tags=self.DENY_TAGS,
1363         )
1364
1365
1366 if __name__ == "__main__":
1367     unittest.main(testRunner=VppTestRunner)