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