tests: Use errno value rather than a specific int
[vpp.git] / test / test_acl_plugin_macip.py
index 8bcef25..20da6dc 100644 (file)
@@ -1,23 +1,44 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
+from __future__ import print_function
+
 """ACL plugin - MACIP tests
 """
 import random
 """ACL plugin - MACIP tests
 """
 import random
+from socket import inet_ntop, inet_pton, AF_INET, AF_INET6
+from struct import pack, unpack
 import re
 import unittest
 import re
 import unittest
+from ipaddress import ip_network, IPv4Network, IPv6Network
+from config import config
 
 
-from socket import inet_ntop, inet_pton, AF_INET, AF_INET6
-from struct import *
+import scapy.compat
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether
 from scapy.layers.inet import IP, UDP
 from scapy.layers.inet6 import IPv6
 
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether
 from scapy.layers.inet import IP, UDP
 from scapy.layers.inet6 import IPv6
 
-from framework import VppTestCase, VppTestRunner, running_extended_tests
+from framework import VppTestCase
+from asfframework import VppTestRunner
 from vpp_lo_interface import VppLoInterface
 from vpp_lo_interface import VppLoInterface
-from vpp_papi_provider import L2_VTR_OP
-from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
-
-
+from vpp_l2 import L2_PORT_TYPE
+from vpp_sub_interface import (
+    L2_VTR_OP,
+    VppSubInterface,
+    VppDot1QSubint,
+    VppDot1ADSubint,
+)
+from vpp_acl import (
+    AclRule,
+    VppAcl,
+    VppAclInterface,
+    VppMacipAclInterface,
+    VppMacipAcl,
+    MacipRule,
+)
+from vpp_papi import MACAddress
+
+
+@unittest.skipIf("acl" in config.excluded_plugins, "Exclude ACL plugin tests")
 class MethodHolder(VppTestCase):
     DEBUG = False
 
 class MethodHolder(VppTestCase):
     DEBUG = False
 
@@ -67,19 +88,16 @@ class MethodHolder(VppTestCase):
 
             # create 2 subinterfaces
             cls.subifs = [
 
             # create 2 subinterfaces
             cls.subifs = [
-                 VppDot1QSubint(cls, cls.pg1, 10),
-                 VppDot1ADSubint(cls, cls.pg2, 20, 300, 400),
-                 VppDot1QSubint(cls, cls.pg3, 30),
-                 VppDot1ADSubint(cls, cls.pg3, 40, 600, 700)]
-
-            cls.subifs[0].set_vtr(L2_VTR_OP.L2_POP_1,
-                                  inner=10, push1q=1)
-            cls.subifs[1].set_vtr(L2_VTR_OP.L2_POP_2,
-                                  outer=300, inner=400, push1q=1)
-            cls.subifs[2].set_vtr(L2_VTR_OP.L2_POP_1,
-                                  inner=30, push1q=1)
-            cls.subifs[3].set_vtr(L2_VTR_OP.L2_POP_2,
-                                  outer=600, inner=700, push1q=1)
+                VppDot1QSubint(cls, cls.pg1, 10),
+                VppDot1ADSubint(cls, cls.pg2, 20, 300, 400),
+                VppDot1QSubint(cls, cls.pg3, 30),
+                VppDot1ADSubint(cls, cls.pg3, 40, 600, 700),
+            ]
+
+            cls.subifs[0].set_vtr(L2_VTR_OP.L2_POP_1, inner=10, push1q=1)
+            cls.subifs[1].set_vtr(L2_VTR_OP.L2_POP_2, outer=300, inner=400, push1q=1)
+            cls.subifs[2].set_vtr(L2_VTR_OP.L2_POP_1, inner=30, push1q=1)
+            cls.subifs[3].set_vtr(L2_VTR_OP.L2_POP_2, outer=600, inner=700, push1q=1)
 
             cls.interfaces = list(cls.pg_interfaces)
             cls.interfaces.extend(cls.lo_interfaces)
 
             cls.interfaces = list(cls.pg_interfaces)
             cls.interfaces.extend(cls.lo_interfaces)
@@ -90,15 +108,22 @@ class MethodHolder(VppTestCase):
 
             # Create BD with MAC learning enabled and put interfaces to this BD
             cls.vapi.sw_interface_set_l2_bridge(
 
             # Create BD with MAC learning enabled and put interfaces to this BD
             cls.vapi.sw_interface_set_l2_bridge(
-                cls.loop0.sw_if_index, bd_id=cls.bd_id, bvi=1)
+                rx_sw_if_index=cls.loop0.sw_if_index,
+                bd_id=cls.bd_id,
+                port_type=L2_PORT_TYPE.BVI,
+            )
             cls.vapi.sw_interface_set_l2_bridge(
             cls.vapi.sw_interface_set_l2_bridge(
-                cls.pg0.sw_if_index, bd_id=cls.bd_id)
+                rx_sw_if_index=cls.pg0.sw_if_index, bd_id=cls.bd_id
+            )
             cls.vapi.sw_interface_set_l2_bridge(
             cls.vapi.sw_interface_set_l2_bridge(
-                cls.pg1.sw_if_index, bd_id=cls.bd_id)
+                rx_sw_if_index=cls.pg1.sw_if_index, bd_id=cls.bd_id
+            )
             cls.vapi.sw_interface_set_l2_bridge(
             cls.vapi.sw_interface_set_l2_bridge(
-                cls.subifs[0].sw_if_index, bd_id=cls.bd_id)
+                rx_sw_if_index=cls.subifs[0].sw_if_index, bd_id=cls.bd_id
+            )
             cls.vapi.sw_interface_set_l2_bridge(
             cls.vapi.sw_interface_set_l2_bridge(
-                cls.subifs[1].sw_if_index, bd_id=cls.bd_id)
+                rx_sw_if_index=cls.subifs[1].sw_if_index, bd_id=cls.bd_id
+            )
 
             # Configure IPv4/6 addresses on loop interface and routed interface
             cls.loop0.config_ip4()
 
             # Configure IPv4/6 addresses on loop interface and routed interface
             cls.loop0.config_ip4()
@@ -112,7 +137,7 @@ class MethodHolder(VppTestCase):
             cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
             # Modify host mac addresses to have different OUI parts
             for i in range(2, cls.remote_hosts_count + 2):
             cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
             # Modify host mac addresses to have different OUI parts
             for i in range(2, cls.remote_hosts_count + 2):
-                mac = cls.loop0.remote_hosts[i-2]._mac.split(':')
+                mac = cls.loop0.remote_hosts[i - 2]._mac.split(":")
                 mac[2] = format(int(mac[2], 16) + i, "02x")
                 cls.loop0.remote_hosts[i - 2]._mac = ":".join(mac)
 
                 mac[2] = format(int(mac[2], 16) + i, "02x")
                 cls.loop0.remote_hosts[i - 2]._mac = ":".join(mac)
 
@@ -142,63 +167,65 @@ class MethodHolder(VppTestCase):
             cls.subifs[3].remote_hosts = cls.loop0.remote_hosts[175:]
 
         except Exception:
             cls.subifs[3].remote_hosts = cls.loop0.remote_hosts[175:]
 
         except Exception:
-            super(TestMACIP, cls).tearDownClass()
+            super(MethodHolder, cls).tearDownClass()
             raise
 
             raise
 
+    @classmethod
+    def tearDownClass(cls):
+        super(MethodHolder, cls).tearDownClass()
+
     def setUp(self):
         super(MethodHolder, self).setUp()
         self.reset_packet_infos()
     def setUp(self):
         super(MethodHolder, self).setUp()
         self.reset_packet_infos()
-        del self.ACLS[:]
 
 
-    def tearDown(self):
-        """
-        Show various debug prints after each test.
-        """
-        super(MethodHolder, self).tearDown()
-        if not self.vpp_dead:
-            self.logger.info(self.vapi.ppcli("show interface address"))
-            self.logger.info(self.vapi.ppcli("show hardware"))
-            self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl"))
-            self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface"))
-            self.logger.info(self.vapi.ppcli("sh classify tables verbose"))
-            self.logger.info(self.vapi.ppcli("sh acl-plugin acl"))
-            self.logger.info(self.vapi.ppcli("sh acl-plugin interface"))
-            self.logger.info(self.vapi.ppcli("sh acl-plugin tables"))
-            # print self.vapi.ppcli("show interface address")
-            # print self.vapi.ppcli("show hardware")
-            # print self.vapi.ppcli("sh acl-plugin macip interface")
-            # print self.vapi.ppcli("sh acl-plugin macip acl")
-        self.delete_acls()
+    def show_commands_at_teardown(self):
+        self.logger.info(self.vapi.ppcli("show interface address"))
+        self.logger.info(self.vapi.ppcli("show hardware"))
+        self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl"))
+        self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface"))
+        self.logger.info(self.vapi.ppcli("sh classify tables verbose"))
+        self.logger.info(self.vapi.ppcli("sh acl-plugin acl"))
+        self.logger.info(self.vapi.ppcli("sh acl-plugin interface"))
+        self.logger.info(self.vapi.ppcli("sh acl-plugin tables"))
+        # print(self.vapi.ppcli("show interface address"))
+        # print(self.vapi.ppcli("show hardware"))
+        # print(self.vapi.ppcli("sh acl-plugin macip interface"))
+        # print(self.vapi.ppcli("sh acl-plugin macip acl"))
 
     def macip_acl_dump_debug(self):
         acls = self.vapi.macip_acl_dump()
         if self.DEBUG:
             for acl in acls:
 
     def macip_acl_dump_debug(self):
         acls = self.vapi.macip_acl_dump()
         if self.DEBUG:
             for acl in acls:
-                print "ACL #"+str(acl.acl_index)
+                # print("ACL #"+str(acl.acl_index))
                 for r in acl.r:
                     rule = "ACTION"
                     if r.is_permit == 1:
                         rule = "PERMIT"
                     elif r.is_permit == 0:
                         rule = "DENY  "
                 for r in acl.r:
                     rule = "ACTION"
                     if r.is_permit == 1:
                         rule = "PERMIT"
                     elif r.is_permit == 0:
                         rule = "DENY  "
-                    print "    IP6" if r.is_ipv6 else "    IP4", \
-                          rule, \
-                          r.src_mac.encode('hex'), \
-                          r.src_mac_mask.encode('hex'),\
-                          unpack('<16B', r.src_ip_addr), \
-                          r.src_ip_prefix_len
+                    """
+                    print("    IP6" if r.is_ipv6 else "    IP4",
+                          rule,
+                          binascii.hexlify(r.src_mac),
+                          binascii.hexlify(r.src_mac_mask),
+                          unpack('<16B', r.src_ip_addr),
+                          r.src_ip_prefix_len)
+                    """
         return acls
 
         return acls
 
-    def create_rules(self, mac_type=EXACT_MAC, ip_type=EXACT_IP,
-                     acl_count=1, rules_count=[1]):
+    def create_rules(
+        self, mac_type=EXACT_MAC, ip_type=EXACT_IP, acl_count=1, rules_count=None
+    ):
         acls = []
         acls = []
+        if rules_count is None:
+            rules_count = [1]
         src_mac = int("220000dead00", 16)
         src_mac = int("220000dead00", 16)
-        for acl in range(2, (acl_count+1) * 2):
+        for acl in range(2, (acl_count + 1) * 2):
             rules = []
             host = random.choice(self.loop0.remote_hosts)
             is_ip6 = acl % 2
             rules = []
             host = random.choice(self.loop0.remote_hosts)
             is_ip6 = acl % 2
-            ip4 = host.ip4.split('.')
-            ip6 = list(unpack('<16B', inet_pton(AF_INET6, host.ip6)))
+            ip4 = host.ip4.split(".")
+            ip6 = list(unpack("<16B", inet_pton(AF_INET6, host.ip6)))
 
             if ip_type == self.EXACT_IP:
                 prefix_len4 = 32
 
             if ip_type == self.EXACT_IP:
                 prefix_len4 = 32
@@ -208,7 +235,7 @@ class MethodHolder(VppTestCase):
                 ip6 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
                 prefix_len4 = 0
                 prefix_len6 = 0
                 ip6 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
                 prefix_len4 = 0
                 prefix_len6 = 0
-                rules_count[(acl / 2) - 1] = 1
+                rules_count[int((acl / 2) - 1)] = 1
             else:
                 prefix_len4 = 24
                 prefix_len6 = 64
             else:
                 prefix_len4 = 24
                 prefix_len6 = 64
@@ -225,15 +252,17 @@ class MethodHolder(VppTestCase):
             ip = ip6 if is_ip6 else ip4
             ip_len = prefix_len6 if is_ip6 else prefix_len4
 
             ip = ip6 if is_ip6 else ip4
             ip_len = prefix_len6 if is_ip6 else prefix_len4
 
-            for i in range(0, rules_count[(acl / 2) - 1]):
+            for i in range(0, (rules_count[int((acl / 2) - 1)])):
                 src_mac += 16777217
                 if mac_type == self.WILD_MAC:
                     mac = "00:00:00:00:00:00"
                 elif mac_type == self.OUI_MAC:
                 src_mac += 16777217
                 if mac_type == self.WILD_MAC:
                     mac = "00:00:00:00:00:00"
                 elif mac_type == self.OUI_MAC:
-                    mac = ':'.join(re.findall('..', '{:02x}'.format(
-                        src_mac))[:3])+":00:00:00"
+                    mac = (
+                        ":".join(re.findall("..", "{:02x}".format(src_mac))[:3])
+                        + ":00:00:00"
+                    )
                 else:
                 else:
-                    mac = ':'.join(re.findall('..', '{:02x}'.format(src_mac)))
+                    mac = ":".join(re.findall("..", "{:02x}".format(src_mac)))
 
                 if ip_type == self.EXACT_IP:
                     ip4[3] = random.randint(100, 200)
 
                 if ip_type == self.EXACT_IP:
                     ip4[3] = random.randint(100, 200)
@@ -241,18 +270,18 @@ class MethodHolder(VppTestCase):
                 elif ip_type == self.SUBNET_IP:
                     ip4[2] = random.randint(100, 200)
                     ip4[3] = 0
                 elif ip_type == self.SUBNET_IP:
                     ip4[2] = random.randint(100, 200)
                     ip4[3] = 0
-                    ip6[8] = random.randint(100, 200)
+                    ip6[7] = random.randint(100, 200)
                     ip6[15] = 0
                     ip6[15] = 0
-                ip_pack = ''
+                ip_pack = b""
                 for j in range(0, len(ip)):
                 for j in range(0, len(ip)):
-                    ip_pack += pack('<B', int(ip[j]))
-
-                rule = ({'is_permit': self.PERMIT,
-                         'is_ipv6': is_ip6,
-                         'src_ip_addr': ip_pack,
-                         'src_ip_prefix_len': ip_len,
-                         'src_mac': mac.replace(':', '').decode('hex'),
-                         'src_mac_mask': mask.replace(':', '').decode('hex')})
+                    ip_pack += pack("<B", int(ip[j]))
+
+                rule = MacipRule(
+                    is_permit=self.PERMIT,
+                    src_prefix=ip_network((ip_pack, ip_len)),
+                    src_mac=MACAddress(mac).packed,
+                    src_mac_mask=MACAddress(mask).packed,
+                )
                 rules.append(rule)
                 if ip_type == self.WILD_IP:
                     break
                 rules.append(rule)
                 if ip_type == self.WILD_IP:
                     break
@@ -262,15 +291,17 @@ class MethodHolder(VppTestCase):
         return acls
 
     def apply_macip_rules(self, acls):
         return acls
 
     def apply_macip_rules(self, acls):
+        macip_acls = []
         for acl in acls:
         for acl in acls:
-            reply = self.vapi.macip_acl_add(acl)
-            self.assertEqual(reply.retval, 0)
-            self.ACLS.append(reply.acl_index)
+            macip_acl = VppMacipAcl(self, rules=acl)
+            macip_acl.add_vpp_config()
+            macip_acls.append(macip_acl)
+        return macip_acls
 
     def verify_macip_acls(self, acl_count, rules_count, expected_count=2):
         reply = self.macip_acl_dump_debug()
 
     def verify_macip_acls(self, acl_count, rules_count, expected_count=2):
         reply = self.macip_acl_dump_debug()
-        for acl in range(2, (acl_count+1) * 2):
-            self.assertEqual(reply[acl - 2].count, rules_count[acl/2-1])
+        for acl in range(2, (acl_count + 1) * 2):
+            self.assertEqual(reply[acl - 2].count, rules_count[acl // 2 - 1])
 
         self.vapi.macip_acl_interface_get()
 
 
         self.vapi.macip_acl_interface_get()
 
@@ -280,22 +311,17 @@ class MethodHolder(VppTestCase):
         reply = self.vapi.macip_acl_interface_get()
         self.assertEqual(reply.count, expected_count)
 
         reply = self.vapi.macip_acl_interface_get()
         self.assertEqual(reply.count, expected_count)
 
-    def delete_acls(self):
-        for acl in range(len(self.ACLS)-1, -1, -1):
-            self.vapi.macip_acl_del(self.ACLS[acl])
-
-        reply = self.vapi.macip_acl_dump()
-        self.assertEqual(len(reply), 0)
-
-        intf_acls = self.vapi.acl_interface_list_dump()
-        for i_a in intf_acls:
-            sw_if_index = i_a.sw_if_index
-            for acl_index in i_a.acls:
-                self.vapi.acl_interface_add_del(sw_if_index, acl_index, 0)
-                self.vapi.acl_del(acl_index)
-
-    def create_stream(self, mac_type, ip_type, packet_count,
-                      src_if, dst_if, traffic, is_ip6, tags=PERMIT_TAGS):
+    def create_stream(
+        self,
+        mac_type,
+        ip_type,
+        packet_count,
+        src_if,
+        dst_if,
+        traffic,
+        is_ip6,
+        tags=PERMIT_TAGS,
+    ):
         # exact MAC and exact IP
         # exact MAC and subnet of IPs
         # exact MAC and wildcard IP
         # exact MAC and exact IP
         # exact MAC and subnet of IPs
         # exact MAC and wildcard IP
@@ -331,7 +357,7 @@ class MethodHolder(VppTestCase):
             if traffic == self.BRIDGED:
                 if is_permit:
                     src_mac = remote_dst_host._mac
             if traffic == self.BRIDGED:
                 if is_permit:
                     src_mac = remote_dst_host._mac
-                    dst_mac = 'de:ad:00:00:00:00'
+                    dst_mac = "de:ad:00:00:00:00"
                     src_ip4 = remote_dst_host.ip4
                     dst_ip4 = src_if.remote_ip4
                     src_ip6 = remote_dst_host.ip6
                     src_ip4 = remote_dst_host.ip4
                     dst_ip4 = src_if.remote_ip4
                     src_ip6 = remote_dst_host.ip6
@@ -339,8 +365,8 @@ class MethodHolder(VppTestCase):
                     ip_permit = src_ip6 if is_ip6 else src_ip4
                     mac_permit = src_mac
                 if denyMAC:
                     ip_permit = src_ip6 if is_ip6 else src_ip4
                     mac_permit = src_mac
                 if denyMAC:
-                    mac = src_mac.split(':')
-                    mac[0] = format(int(mac[0], 16)+1, "02x")
+                    mac = src_mac.split(":")
+                    mac[0] = format(int(mac[0], 16) + 1, "02x")
                     src_mac = ":".join(mac)
                     if is_ip6:
                         src_ip6 = ip_permit
                     src_mac = ":".join(mac)
                     if is_ip6:
                         src_ip6 = ip_permit
@@ -364,7 +390,7 @@ class MethodHolder(VppTestCase):
                     ip_permit = src_ip6 if is_ip6 else src_ip4
                     mac_permit = src_mac
                 if denyMAC:
                     ip_permit = src_ip6 if is_ip6 else src_ip4
                     mac_permit = src_mac
                 if denyMAC:
-                    mac = src_mac.split(':')
+                    mac = src_mac.split(":")
                     mac[0] = format(int(mac[0], 16) + 1, "02x")
                     src_mac = ":".join(mac)
                     if is_ip6:
                     mac[0] = format(int(mac[0], 16) + 1, "02x")
                     src_mac = ":".join(mac)
                     if is_ip6:
@@ -387,7 +413,7 @@ class MethodHolder(VppTestCase):
                 payload = "to be blocked"
 
             if mac_type == self.WILD_MAC:
                 payload = "to be blocked"
 
             if mac_type == self.WILD_MAC:
-                mac = src_mac.split(':')
+                mac = src_mac.split(":")
                 for i in range(1, 5):
                     mac[i] = format(random.randint(0, 255), "02x")
                 src_mac = ":".join(mac)
                 for i in range(1, 5):
                     mac[i] = format(random.randint(0, 255), "02x")
                 src_mac = ":".join(mac)
@@ -397,7 +423,7 @@ class MethodHolder(VppTestCase):
             ip_rule = src_ip6 if is_ip6 else src_ip4
             if is_ip6:
                 if ip_type != self.EXACT_IP:
             ip_rule = src_ip6 if is_ip6 else src_ip4
             if is_ip6:
                 if ip_type != self.EXACT_IP:
-                    sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip_rule)))
+                    sub_ip = list(unpack("<16B", inet_pton(AF_INET6, ip_rule)))
                     if ip_type == self.WILD_IP:
                         sub_ip[0] = random.randint(240, 254)
                         sub_ip[1] = random.randint(230, 239)
                     if ip_type == self.WILD_IP:
                         sub_ip[0] = random.randint(240, 254)
                         sub_ip[1] = random.randint(230, 239)
@@ -405,30 +431,31 @@ class MethodHolder(VppTestCase):
                         sub_ip[15] = random.randint(200, 255)
                     elif ip_type == self.SUBNET_IP:
                         if denyIP:
                         sub_ip[15] = random.randint(200, 255)
                     elif ip_type == self.SUBNET_IP:
                         if denyIP:
-                            sub_ip[2] = str(int(sub_ip[2]) + 1)
+                            sub_ip[2] = int(sub_ip[2]) + 1
                         sub_ip[14] = random.randint(100, 199)
                         sub_ip[15] = random.randint(200, 255)
                         sub_ip[14] = random.randint(100, 199)
                         sub_ip[15] = random.randint(200, 255)
-                    src_ip6 = inet_ntop(AF_INET6, str(bytearray(sub_ip)))
+                    packed_src_ip6 = b"".join([scapy.compat.chb(x) for x in sub_ip])
+                    src_ip6 = inet_ntop(AF_INET6, packed_src_ip6)
                 packet /= IPv6(src=src_ip6, dst=dst_ip6)
             else:
                 if ip_type != self.EXACT_IP:
                 packet /= IPv6(src=src_ip6, dst=dst_ip6)
             else:
                 if ip_type != self.EXACT_IP:
-                    sub_ip = ip_rule.split('.')
+                    sub_ip = ip_rule.split(".")
                     if ip_type == self.WILD_IP:
                     if ip_type == self.WILD_IP:
-                        sub_ip[0] = str(random.randint(1, 49))
-                        sub_ip[1] = str(random.randint(50, 99))
-                        sub_ip[2] = str(random.randint(100, 199))
-                        sub_ip[3] = str(random.randint(200, 255))
+                        sub_ip[0] = random.randint(1, 49)
+                        sub_ip[1] = random.randint(50, 99)
+                        sub_ip[2] = random.randint(100, 199)
+                        sub_ip[3] = random.randint(200, 255)
                     elif ip_type == self.SUBNET_IP:
                         if denyIP:
                     elif ip_type == self.SUBNET_IP:
                         if denyIP:
-                            sub_ip[1] = str(int(sub_ip[1])+1)
-                        sub_ip[2] = str(random.randint(100, 199))
-                        sub_ip[3] = str(random.randint(200, 255))
-                    src_ip4 = ".".join(sub_ip)
+                            sub_ip[1] = int(sub_ip[1]) + 1
+                        sub_ip[2] = random.randint(100, 199)
+                        sub_ip[3] = random.randint(200, 255)
+                    src_ip4 = ".".join(["{!s}".format(x) for x in sub_ip])
                 packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0)
 
                 packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0)
 
-            packet /= UDP(sport=src_port, dport=dst_port)/Raw(payload)
+            packet /= UDP(sport=src_port, dport=dst_port) / Raw(payload)
 
 
-            packet[Raw].load += " mac:"+src_mac
+            packet[Raw].load += b" mac:%s" % src_mac.encode("utf-8")
 
             size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)]
             if isinstance(src_if, VppSubInterface):
 
             size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)]
             if isinstance(src_if, VppSubInterface):
@@ -466,8 +493,8 @@ class MethodHolder(VppTestCase):
                 mac_rule = "00:00:00:00:00:00"
                 mac_mask = "00:00:00:00:00:00"
             elif mac_type == self.OUI_MAC:
                 mac_rule = "00:00:00:00:00:00"
                 mac_mask = "00:00:00:00:00:00"
             elif mac_type == self.OUI_MAC:
-                mac = src_mac.split(':')
-                mac[3] = mac[4] = mac[5] = '00'
+                mac = src_mac.split(":")
+                mac[3] = mac[4] = mac[5] = "00"
                 mac_rule = ":".join(mac)
                 mac_mask = "ff:ff:ff:00:00:00"
 
                 mac_rule = ":".join(mac)
                 mac_mask = "ff:ff:ff:00:00:00"
 
@@ -477,18 +504,19 @@ class MethodHolder(VppTestCase):
                 else:
                     ip = src_ip6
                     if ip_type == self.SUBNET_IP:
                 else:
                     ip = src_ip6
                     if ip_type == self.SUBNET_IP:
-                        sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip)))
+                        sub_ip = list(unpack("<16B", inet_pton(AF_INET6, ip)))
                         for i in range(8, 16):
                             sub_ip[i] = 0
                         for i in range(8, 16):
                             sub_ip[i] = 0
-                        ip = inet_ntop(AF_INET6, str(bytearray(sub_ip)))
+                        packed_ip = b"".join([scapy.compat.chb(x) for x in sub_ip])
+                        ip = inet_ntop(AF_INET6, packed_ip)
             else:
                 if ip_type == self.WILD_IP:
                     ip = "0.0.0.0"
                 else:
                     ip = src_ip4
                     if ip_type == self.SUBNET_IP:
             else:
                 if ip_type == self.WILD_IP:
                     ip = "0.0.0.0"
                 else:
                     ip = src_ip4
                     if ip_type == self.SUBNET_IP:
-                        sub_ip = ip.split('.')
-                        sub_ip[2] = sub_ip[3] = '0'
+                        sub_ip = ip.split(".")
+                        sub_ip[2] = sub_ip[3] = "0"
                         ip = ".".join(sub_ip)
 
             prefix_len = 128 if is_ip6 else 32
                         ip = ".".join(sub_ip)
 
             prefix_len = 128 if is_ip6 else 32
@@ -506,55 +534,59 @@ class MethodHolder(VppTestCase):
                 rule_prefix_len = 128 if packet.haslayer(IPv6) else 32
                 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP
                 if packet.haslayer(IPv6):
                 rule_prefix_len = 128 if packet.haslayer(IPv6) else 32
                 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP
                 if packet.haslayer(IPv6):
-                    rule_l4_proto = packet[UDP].overload_fields[IPv6]['nh']
+                    rule_l4_proto = packet[UDP].overload_fields[IPv6]["nh"]
                 else:
                     rule_l4_proto = packet[IP].proto
 
                 else:
                     rule_l4_proto = packet[IP].proto
 
-                acl_rule = {
-                    'is_permit': is_permit,
-                    'is_ipv6': is_ip6,
-                    'src_ip_addr': inet_pton(rule_family,
-                                             packet[rule_l3_layer].src),
-                    'src_ip_prefix_len': rule_prefix_len,
-                    'dst_ip_addr': inet_pton(rule_family,
-                                             packet[rule_l3_layer].dst),
-                    'dst_ip_prefix_len': rule_prefix_len,
-                    'srcport_or_icmptype_first': rule_l4_sport,
-                    'srcport_or_icmptype_last': rule_l4_sport,
-                    'dstport_or_icmpcode_first': rule_l4_dport,
-                    'dstport_or_icmpcode_last': rule_l4_dport,
-                    'proto': rule_l4_proto}
+                src_network = ip_network((packet[rule_l3_layer].src, rule_prefix_len))
+                dst_network = ip_network((packet[rule_l3_layer].dst, rule_prefix_len))
+                acl_rule = AclRule(
+                    is_permit=is_permit,
+                    proto=rule_l4_proto,
+                    src_prefix=src_network,
+                    dst_prefix=dst_network,
+                    sport_from=rule_l4_sport,
+                    sport_to=rule_l4_sport,
+                    dport_from=rule_l4_dport,
+                    dport_to=rule_l4_dport,
+                )
                 acl_rules.append(acl_rule)
 
             if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0:
                 continue
 
             if is_permit:
                 acl_rules.append(acl_rule)
 
             if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0:
                 continue
 
             if is_permit:
-                macip_rule = ({
-                    'is_permit': is_permit,
-                    'is_ipv6': is_ip6,
-                    'src_ip_addr': ip_rule,
-                    'src_ip_prefix_len': prefix_len,
-                    'src_mac': mac_rule.replace(':', '').decode('hex'),
-                    'src_mac_mask': mac_mask.replace(':', '').decode('hex')})
+                macip_rule = MacipRule(
+                    is_permit=is_permit,
+                    src_prefix=ip_network((ip_rule, prefix_len)),
+                    src_mac=MACAddress(mac_rule).packed,
+                    src_mac_mask=MACAddress(mac_mask).packed,
+                )
                 macip_rules.append(macip_rule)
 
         # deny all other packets
         if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP):
                 macip_rules.append(macip_rule)
 
         # deny all other packets
         if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP):
-            macip_rule = ({'is_permit': 0,
-                           'is_ipv6': is_ip6,
-                           'src_ip_addr': "",
-                           'src_ip_prefix_len': 0,
-                           'src_mac': "",
-                           'src_mac_mask': ""})
+            network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0))
+            macip_rule = MacipRule(
+                is_permit=0,
+                src_prefix=network,
+                src_mac=MACAddress("00:00:00:00:00:00").packed,
+                src_mac_mask=MACAddress("00:00:00:00:00:00").packed,
+            )
             macip_rules.append(macip_rule)
 
             macip_rules.append(macip_rule)
 
-        acl_rule = {'is_permit': 0,
-                    'is_ipv6': is_ip6}
+        network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0))
+        acl_rule = AclRule(
+            is_permit=0,
+            src_prefix=network,
+            dst_prefix=network,
+            sport_from=0,
+            sport_to=0,
+            dport_from=0,
+            dport_to=0,
+        )
         acl_rules.append(acl_rule)
         acl_rules.append(acl_rule)
-        return {'stream': packets,
-                'macip_rules': macip_rules,
-                'acl_rules': acl_rules}
+        return {"stream": packets, "macip_rules": macip_rules, "acl_rules": acl_rules}
 
     def verify_capture(self, stream, capture, is_ip6):
         """
 
     def verify_capture(self, stream, capture, is_ip6):
         """
@@ -566,27 +598,37 @@ class MethodHolder(VppTestCase):
         # p_l3 = IPv6 if is_ip6 else IP
         # if self.DEBUG:
         #     for p in stream:
         # p_l3 = IPv6 if is_ip6 else IP
         # if self.DEBUG:
         #     for p in stream:
-        #         print p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst
+        #         print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst)
         #
         # acls = self.macip_acl_dump_debug()
 
         # TODO : verify
         # for acl in acls:
         #     for r in acl.r:
         #
         # acls = self.macip_acl_dump_debug()
 
         # TODO : verify
         # for acl in acls:
         #     for r in acl.r:
-        #         print r.src_mac.encode('hex'), \
-        #               r.src_mac_mask.encode('hex'),\
+        #         print(binascii.hexlify(r.src_mac), \
+        #               binascii.hexlify(r.src_mac_mask),\
         #               unpack('<16B', r.src_ip_addr), \
         #               unpack('<16B', r.src_ip_addr), \
-        #               r.src_ip_prefix_len
+        #               r.src_ip_prefix_len)
         #
         # for p in capture:
         #
         # for p in capture:
-        #     print p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst
-        #     data = p[Raw].load.split(':',1)[1]
-        #     print p[p_l3].src, data
-
-    def run_traffic(self, mac_type, ip_type, traffic, is_ip6, packets,
-                    do_not_expected_capture=False, tags=None,
-                    apply_rules=True, isMACIP=True, permit_tags=PERMIT_TAGS,
-                    try_replace=False):
+        #     print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst
+        #     data = p[Raw].load.split(':',1)[1])
+        #     print(p[p_l3].src, data)
+
+    def run_traffic(
+        self,
+        mac_type,
+        ip_type,
+        traffic,
+        is_ip6,
+        packets,
+        do_not_expected_capture=False,
+        tags=None,
+        apply_rules=True,
+        isMACIP=True,
+        permit_tags=PERMIT_TAGS,
+        try_replace=False,
+    ):
         self.reset_packet_infos()
 
         if tags is None:
         self.reset_packet_infos()
 
         if tags is None:
@@ -620,70 +662,80 @@ class MethodHolder(VppTestCase):
             else:
                 return
 
             else:
                 return
 
-        test_dict = self.create_stream(mac_type, ip_type, packets,
-                                       src_if, dst_if,
-                                       traffic, is_ip6,
-                                       tags=permit_tags)
+        test_dict = self.create_stream(
+            mac_type,
+            ip_type,
+            packets,
+            src_if,
+            dst_if,
+            traffic,
+            is_ip6,
+            tags=permit_tags,
+        )
 
         if apply_rules:
             if isMACIP:
 
         if apply_rules:
             if isMACIP:
-                reply = self.vapi.macip_acl_add(test_dict['macip_rules'])
+                self.acl = VppMacipAcl(self, rules=test_dict["macip_rules"])
             else:
             else:
-                reply = self.vapi.acl_add_replace(acl_index=4294967295,
-                                                  r=test_dict['acl_rules'])
-            self.assertEqual(reply.retval, 0)
-            acl_index = reply.acl_index
+                self.acl = VppAcl(self, rules=test_dict["acl_rules"])
+            self.acl.add_vpp_config()
 
             if isMACIP:
 
             if isMACIP:
-                self.vapi.macip_acl_interface_add_del(
-                                                 sw_if_index=tx_if.sw_if_index,
-                                                 acl_index=acl_index)
-                reply = self.vapi.macip_acl_interface_get()
-                self.assertEqual(reply.acls[tx_if.sw_if_index], acl_index)
-                self.ACLS.append(reply.acls[tx_if.sw_if_index])
+                self.acl_if = VppMacipAclInterface(
+                    self, sw_if_index=tx_if.sw_if_index, acls=[self.acl]
+                )
+                self.acl_if.add_vpp_config()
+
+                dump = self.acl_if.dump()
+                self.assertTrue(dump)
+                self.assertEqual(dump[0].acls[0], self.acl.acl_index)
             else:
             else:
-                self.vapi.acl_interface_add_del(
-                    sw_if_index=tx_if.sw_if_index, acl_index=acl_index)
+                self.acl_if = VppAclInterface(
+                    self, sw_if_index=tx_if.sw_if_index, n_input=1, acls=[self.acl]
+                )
+                self.acl_if.add_vpp_config()
         else:
         else:
-            self.vapi.macip_acl_interface_add_del(
-                sw_if_index=tx_if.sw_if_index,
-                acl_index=0)
-        if try_replace:
+            if hasattr(self, "acl_if"):
+                self.acl_if.remove_vpp_config()
+        if try_replace and hasattr(self, "acl"):
             if isMACIP:
             if isMACIP:
-                reply = self.vapi.macip_acl_add_replace(
-                                                   test_dict['macip_rules'],
-                                                   acl_index)
+                self.acl.modify_vpp_config(test_dict["macip_rules"])
             else:
             else:
-                reply = self.vapi.acl_add_replace(acl_index=acl_index,
-                                                  r=test_dict['acl_rules'])
-            self.assertEqual(reply.retval, 0)
+                self.acl.modify_vpp_config(test_dict["acl_rules"])
 
         if not isinstance(src_if, VppSubInterface):
 
         if not isinstance(src_if, VppSubInterface):
-            tx_if.add_stream(test_dict['stream'])
+            tx_if.add_stream(test_dict["stream"])
         else:
         else:
-            tx_if.parent.add_stream(test_dict['stream'])
+            tx_if.parent.add_stream(test_dict["stream"])
         self.pg_enable_capture(self.pg_interfaces)
         self.pg_start()
 
         if do_not_expected_capture:
             rx_if.get_capture(0)
         else:
         self.pg_enable_capture(self.pg_interfaces)
         self.pg_start()
 
         if do_not_expected_capture:
             rx_if.get_capture(0)
         else:
-            if traffic == self.BRIDGED and mac_type == self.WILD_MAC and \
-                    ip_type == self.WILD_IP:
+            if (
+                traffic == self.BRIDGED
+                and mac_type == self.WILD_MAC
+                and ip_type == self.WILD_IP
+            ):
                 capture = rx_if.get_capture(packets)
             else:
                 capture = rx_if.get_capture(
                 capture = rx_if.get_capture(packets)
             else:
                 capture = rx_if.get_capture(
-                    self.get_packet_count_for_if_idx(dst_if.sw_if_index))
-            self.verify_capture(test_dict['stream'], capture, is_ip6)
+                    self.get_packet_count_for_if_idx(dst_if.sw_if_index)
+                )
+            self.verify_capture(test_dict["stream"], capture, is_ip6)
         if not isMACIP:
         if not isMACIP:
-            self.vapi.acl_interface_add_del(sw_if_index=tx_if.sw_if_index,
-                                            acl_index=acl_index, is_add=0)
-            self.vapi.acl_del(acl_index)
-
-    def run_test_acls(self, mac_type, ip_type, acl_count,
-                      rules_count, traffic=None, ip=None):
-        self.apply_macip_rules(self.create_rules(mac_type, ip_type, acl_count,
-                                                 rules_count))
+            if hasattr(self, "acl_if"):
+                self.acl_if.remove_vpp_config()
+            if hasattr(self, "acl"):
+                self.acl.remove_vpp_config()
+
+    def run_test_acls(
+        self, mac_type, ip_type, acl_count, rules_count, traffic=None, ip=None
+    ):
+        self.apply_macip_rules(
+            self.create_rules(mac_type, ip_type, acl_count, rules_count)
+        )
         self.verify_macip_acls(acl_count, rules_count)
 
         if traffic is not None:
         self.verify_macip_acls(acl_count, rules_count)
 
         if traffic is not None:
@@ -693,377 +745,338 @@ class MethodHolder(VppTestCase):
 class TestMACIP_IP4(MethodHolder):
     """MACIP with IP4 traffic"""
 
 class TestMACIP_IP4(MethodHolder):
     """MACIP with IP4 traffic"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestMACIP_IP4, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestMACIP_IP4, cls).tearDownClass()
+
     def test_acl_bridged_ip4_exactMAC_exactIP(self):
     def test_acl_bridged_ip4_exactMAC_exactIP(self):
-        """ IP4 MACIP exactMAC|exactIP ACL bridged traffic
-        """
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        """IP4 MACIP exactMAC|exactIP ACL bridged traffic"""
+        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_bridged_ip4_exactMAC_subnetIP(self):
 
     def test_acl_bridged_ip4_exactMAC_subnetIP(self):
-        """ IP4 MACIP exactMAC|subnetIP ACL bridged traffic
-        """
+        """IP4 MACIP exactMAC|subnetIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_bridged_ip4_exactMAC_wildIP(self):
 
     def test_acl_bridged_ip4_exactMAC_wildIP(self):
-        """ IP4 MACIP exactMAC|wildIP ACL bridged traffic
-        """
+        """IP4 MACIP exactMAC|wildIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.WILD_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_bridged_ip4_ouiMAC_exactIP(self):
 
     def test_acl_bridged_ip4_ouiMAC_exactIP(self):
-        """ IP4 MACIP ouiMAC|exactIP ACL bridged traffic
-        """
+        """IP4 MACIP ouiMAC|exactIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP4, 3)
+        self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 3)
 
     def test_acl_bridged_ip4_ouiMAC_subnetIP(self):
 
     def test_acl_bridged_ip4_ouiMAC_subnetIP(self):
-        """ IP4 MACIP ouiMAC|subnetIP ACL bridged traffic
-        """
+        """IP4 MACIP ouiMAC|subnetIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_bridged_ip4_ouiMAC_wildIP(self):
 
     def test_acl_bridged_ip4_ouiMAC_wildIP(self):
-        """ IP4 MACIP ouiMAC|wildIP ACL bridged traffic
-        """
+        """IP4 MACIP ouiMAC|wildIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.WILD_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_ac_bridgedl_ip4_wildMAC_exactIP(self):
 
     def test_ac_bridgedl_ip4_wildMAC_exactIP(self):
-        """ IP4 MACIP wildcardMAC|exactIP ACL bridged traffic
-        """
+        """IP4 MACIP wildcardMAC|exactIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_bridged_ip4_wildMAC_subnetIP(self):
 
     def test_acl_bridged_ip4_wildMAC_subnetIP(self):
-        """ IP4 MACIP wildcardMAC|subnetIP ACL bridged traffic
-        """
+        """IP4 MACIP wildcardMAC|subnetIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_bridged_ip4_wildMAC_wildIP(self):
 
     def test_acl_bridged_ip4_wildMAC_wildIP(self):
-        """ IP4 MACIP wildcardMAC|wildIP ACL bridged traffic
-        """
+        """IP4 MACIP wildcardMAC|wildIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.WILD_IP,
-                         self.BRIDGED, self.IS_IP4, 9)
+        self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_exactMAC_exactIP(self):
 
     def test_acl_routed_ip4_exactMAC_exactIP(self):
-        """ IP4 MACIP exactMAC|exactIP ACL routed traffic
-        """
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        """IP4 MACIP exactMAC|exactIP ACL routed traffic"""
+        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_exactMAC_subnetIP(self):
 
     def test_acl_routed_ip4_exactMAC_subnetIP(self):
-        """ IP4 MACIP exactMAC|subnetIP ACL routed traffic
-        """
-        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        """IP4 MACIP exactMAC|subnetIP ACL routed traffic"""
+        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_exactMAC_wildIP(self):
 
     def test_acl_routed_ip4_exactMAC_wildIP(self):
-        """ IP4 MACIP exactMAC|wildIP ACL routed traffic
-        """
-        self.run_traffic(self.EXACT_MAC, self.WILD_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        """IP4 MACIP exactMAC|wildIP ACL routed traffic"""
+        self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_ouiMAC_exactIP(self):
 
     def test_acl_routed_ip4_ouiMAC_exactIP(self):
-        """ IP4 MACIP ouiMAC|exactIP ACL routed traffic
-        """
+        """IP4 MACIP ouiMAC|exactIP ACL routed traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.EXACT_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_ouiMAC_subnetIP(self):
 
     def test_acl_routed_ip4_ouiMAC_subnetIP(self):
-        """ IP4 MACIP ouiMAC|subnetIP ACL routed traffic
-        """
+        """IP4 MACIP ouiMAC|subnetIP ACL routed traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_ouiMAC_wildIP(self):
 
     def test_acl_routed_ip4_ouiMAC_wildIP(self):
-        """ IP4 MACIP ouiMAC|wildIP ACL routed traffic
-        """
+        """IP4 MACIP ouiMAC|wildIP ACL routed traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.WILD_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_wildMAC_exactIP(self):
 
     def test_acl_routed_ip4_wildMAC_exactIP(self):
-        """ IP4 MACIP wildcardMAC|exactIP ACL routed traffic
-        """
+        """IP4 MACIP wildcardMAC|exactIP ACL routed traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.EXACT_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_wildMAC_subnetIP(self):
 
     def test_acl_routed_ip4_wildMAC_subnetIP(self):
-        """ IP4 MACIP wildcardMAC|subnetIP ACL routed traffic
-        """
+        """IP4 MACIP wildcardMAC|subnetIP ACL routed traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_routed_ip4_wildMAC_wildIP(self):
 
     def test_acl_routed_ip4_wildMAC_wildIP(self):
-        """ IP4 MACIP wildcardMAC|wildIP ACL
-        """
+        """IP4 MACIP wildcardMAC|wildIP ACL"""
 
 
-        self.run_traffic(self.WILD_MAC, self.WILD_IP,
-                         self.ROUTED, self.IS_IP4, 9)
+        self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9)
 
     def test_acl_replace_traffic_ip4(self):
 
     def test_acl_replace_traffic_ip4(self):
-        """ MACIP replace ACL with IP4 traffic
-        """
-        self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP4, 9, try_replace=True)
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP4, 9, try_replace=True)
+        """MACIP replace ACL with IP4 traffic"""
+        self.run_traffic(
+            self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9, try_replace=True
+        )
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.BRIDGED,
+            self.IS_IP4,
+            9,
+            try_replace=True,
+        )
 
 
 class TestMACIP_IP6(MethodHolder):
     """MACIP with IP6 traffic"""
 
 
 
 class TestMACIP_IP6(MethodHolder):
     """MACIP with IP6 traffic"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestMACIP_IP6, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestMACIP_IP6, cls).tearDownClass()
+
     def test_acl_bridged_ip6_exactMAC_exactIP(self):
     def test_acl_bridged_ip6_exactMAC_exactIP(self):
-        """ IP6 MACIP exactMAC|exactIP ACL bridged traffic
-        """
+        """IP6 MACIP exactMAC|exactIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_exactMAC_subnetIP(self):
 
     def test_acl_bridged_ip6_exactMAC_subnetIP(self):
-        """ IP6 MACIP exactMAC|subnetIP ACL bridged traffic
-        """
+        """IP6 MACIP exactMAC|subnetIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_exactMAC_wildIP(self):
 
     def test_acl_bridged_ip6_exactMAC_wildIP(self):
-        """ IP6 MACIP exactMAC|wildIP ACL bridged traffic
-        """
+        """IP6 MACIP exactMAC|wildIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.WILD_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_ouiMAC_exactIP(self):
 
     def test_acl_bridged_ip6_ouiMAC_exactIP(self):
-        """ IP6 MACIP oui_MAC|exactIP ACL bridged traffic
-        """
+        """IP6 MACIP oui_MAC|exactIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_ouiMAC_subnetIP(self):
 
     def test_acl_bridged_ip6_ouiMAC_subnetIP(self):
-        """ IP6 MACIP ouiMAC|subnetIP ACL bridged traffic
-        """
+        """IP6 MACIP ouiMAC|subnetIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_ouiMAC_wildIP(self):
 
     def test_acl_bridged_ip6_ouiMAC_wildIP(self):
-        """ IP6 MACIP ouiMAC|wildIP ACL bridged traffic
-        """
+        """IP6 MACIP ouiMAC|wildIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.WILD_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_wildMAC_exactIP(self):
 
     def test_acl_bridged_ip6_wildMAC_exactIP(self):
-        """ IP6 MACIP wildcardMAC|exactIP ACL bridged traffic
-        """
+        """IP6 MACIP wildcardMAC|exactIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_wildMAC_subnetIP(self):
 
     def test_acl_bridged_ip6_wildMAC_subnetIP(self):
-        """ IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic
-        """
+        """IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_bridged_ip6_wildMAC_wildIP(self):
 
     def test_acl_bridged_ip6_wildMAC_wildIP(self):
-        """ IP6 MACIP wildcardMAC|wildIP ACL bridged traffic
-        """
+        """IP6 MACIP wildcardMAC|wildIP ACL bridged traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.WILD_IP,
-                         self.BRIDGED, self.IS_IP6, 9)
+        self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_exactMAC_exactIP(self):
 
     def test_acl_routed_ip6_exactMAC_exactIP(self):
-        """ IP6 MACIP exactMAC|exactIP ACL routed traffic
-        """
+        """IP6 MACIP exactMAC|exactIP ACL routed traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_exactMAC_subnetIP(self):
 
     def test_acl_routed_ip6_exactMAC_subnetIP(self):
-        """ IP6 MACIP exactMAC|subnetIP ACL routed traffic
-        """
+        """IP6 MACIP exactMAC|subnetIP ACL routed traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_exactMAC_wildIP(self):
 
     def test_acl_routed_ip6_exactMAC_wildIP(self):
-        """ IP6 MACIP exactMAC|wildIP ACL routed traffic
-        """
+        """IP6 MACIP exactMAC|wildIP ACL routed traffic"""
 
 
-        self.run_traffic(self.EXACT_MAC, self.WILD_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_ouiMAC_exactIP(self):
 
     def test_acl_routed_ip6_ouiMAC_exactIP(self):
-        """ IP6 MACIP ouiMAC|exactIP ACL routed traffic
-        """
+        """IP6 MACIP ouiMAC|exactIP ACL routed traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.EXACT_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_ouiMAC_subnetIP(self):
 
     def test_acl_routed_ip6_ouiMAC_subnetIP(self):
-        """ IP6 MACIP ouiMAC|subnetIP ACL routed traffic
-        """
+        """IP6 MACIP ouiMAC|subnetIP ACL routed traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_ouiMAC_wildIP(self):
 
     def test_acl_routed_ip6_ouiMAC_wildIP(self):
-        """ IP6 MACIP ouiMAC|wildIP ACL routed traffic
-        """
+        """IP6 MACIP ouiMAC|wildIP ACL routed traffic"""
 
 
-        self.run_traffic(self.OUI_MAC, self.WILD_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_wildMAC_exactIP(self):
 
     def test_acl_routed_ip6_wildMAC_exactIP(self):
-        """ IP6 MACIP wildcardMAC|exactIP ACL routed traffic
-        """
+        """IP6 MACIP wildcardMAC|exactIP ACL routed traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.EXACT_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_wildMAC_subnetIP(self):
 
     def test_acl_routed_ip6_wildMAC_subnetIP(self):
-        """ IP6 MACIP wildcardMAC|subnetIP ACL routed traffic
-        """
+        """IP6 MACIP wildcardMAC|subnetIP ACL routed traffic"""
 
 
-        self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_routed_ip6_wildMAC_wildIP(self):
 
     def test_acl_routed_ip6_wildMAC_wildIP(self):
-        """ IP6 MACIP wildcardMAC|wildIP ACL
-        """
+        """IP6 MACIP wildcardMAC|wildIP ACL"""
 
 
-        self.run_traffic(self.WILD_MAC, self.WILD_IP,
-                         self.ROUTED, self.IS_IP6, 9)
+        self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9)
 
     def test_acl_replace_traffic_ip6(self):
 
     def test_acl_replace_traffic_ip6(self):
-        """ MACIP replace ACL with IP6 traffic
-        """
-        self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
-                         self.BRIDGED, self.IS_IP6, 9, try_replace=True)
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
-                         self.BRIDGED, self.IS_IP6, 9, try_replace=True)
+        """MACIP replace ACL with IP6 traffic"""
+        self.run_traffic(
+            self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9, try_replace=True
+        )
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.BRIDGED,
+            self.IS_IP6,
+            9,
+            try_replace=True,
+        )
 
 
 class TestMACIP(MethodHolder):
     """MACIP Tests"""
 
 
 
 class TestMACIP(MethodHolder):
     """MACIP Tests"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestMACIP, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestMACIP, cls).tearDownClass()
+
     def test_acl_1_2(self):
     def test_acl_1_2(self):
-        """ MACIP ACL with 2 entries
-        """
+        """MACIP ACL with 2 entries"""
 
         self.run_test_acls(self.EXACT_MAC, self.WILD_IP, 1, [2])
 
     def test_acl_1_5(self):
 
         self.run_test_acls(self.EXACT_MAC, self.WILD_IP, 1, [2])
 
     def test_acl_1_5(self):
-        """ MACIP ACL with 5 entries
-        """
+        """MACIP ACL with 5 entries"""
 
         self.run_test_acls(self.EXACT_MAC, self.SUBNET_IP, 1, [5])
 
     def test_acl_1_10(self):
 
         self.run_test_acls(self.EXACT_MAC, self.SUBNET_IP, 1, [5])
 
     def test_acl_1_10(self):
-        """ MACIP ACL with 10 entries
-        """
+        """MACIP ACL with 10 entries"""
 
         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 1, [10])
 
     def test_acl_1_20(self):
 
         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 1, [10])
 
     def test_acl_1_20(self):
-        """ MACIP ACL with 20 entries
-        """
+        """MACIP ACL with 20 entries"""
 
         self.run_test_acls(self.OUI_MAC, self.WILD_IP, 1, [20])
 
     def test_acl_1_50(self):
 
         self.run_test_acls(self.OUI_MAC, self.WILD_IP, 1, [20])
 
     def test_acl_1_50(self):
-        """ MACIP ACL with 50 entries
-        """
+        """MACIP ACL with 50 entries"""
 
         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 1, [50])
 
     def test_acl_1_100(self):
 
         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 1, [50])
 
     def test_acl_1_100(self):
-        """ MACIP ACL with 100 entries
-        """
+        """MACIP ACL with 100 entries"""
 
         self.run_test_acls(self.OUI_MAC, self.EXACT_IP, 1, [100])
 
     def test_acl_2_X(self):
 
         self.run_test_acls(self.OUI_MAC, self.EXACT_IP, 1, [100])
 
     def test_acl_2_X(self):
-        """ MACIP 2 ACLs each with 100+ entries
-        """
+        """MACIP 2 ACLs each with 100+ entries"""
 
         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 2, [100, 200])
 
     def test_acl_10_X(self):
 
         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 2, [100, 200])
 
     def test_acl_10_X(self):
-        """ MACIP 10 ACLs each with 100+ entries
-        """
+        """MACIP 10 ACLs each with 100+ entries"""
 
 
-        self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 10,
-                           [100, 120, 140, 160, 180, 200, 210, 220, 230, 240])
+        self.run_test_acls(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            10,
+            [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
+        )
 
     def test_acl_10_X_traffic_ip4(self):
 
     def test_acl_10_X_traffic_ip4(self):
-        """ MACIP 10 ACLs each with 100+ entries with IP4 traffic
-        """
+        """MACIP 10 ACLs each with 100+ entries with IP4 traffic"""
 
 
-        self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 10,
-                           [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
-                           self.BRIDGED, self.IS_IP4)
+        self.run_test_acls(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            10,
+            [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
+            self.BRIDGED,
+            self.IS_IP4,
+        )
 
     def test_acl_10_X_traffic_ip6(self):
 
     def test_acl_10_X_traffic_ip6(self):
-        """ MACIP 10 ACLs each with 100+ entries with IP6 traffic
-        """
+        """MACIP 10 ACLs each with 100+ entries with IP6 traffic"""
 
 
-        self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 10,
-                           [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
-                           self.BRIDGED, self.IS_IP6)
+        self.run_test_acls(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            10,
+            [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
+            self.BRIDGED,
+            self.IS_IP6,
+        )
 
     def test_acl_replace(self):
 
     def test_acl_replace(self):
-        """ MACIP replace ACL
-        """
+        """MACIP replace ACL"""
 
         r1 = self.create_rules(acl_count=3, rules_count=[2, 2, 2])
         r2 = self.create_rules(mac_type=self.OUI_MAC, ip_type=self.SUBNET_IP)
 
         r1 = self.create_rules(acl_count=3, rules_count=[2, 2, 2])
         r2 = self.create_rules(mac_type=self.OUI_MAC, ip_type=self.SUBNET_IP)
-        self.apply_macip_rules(r1)
+        macip_acls = self.apply_macip_rules(r1)
 
         acls_before = self.macip_acl_dump_debug()
 
         # replace acls #2, #3 with new
 
         acls_before = self.macip_acl_dump_debug()
 
         # replace acls #2, #3 with new
-        reply = self.vapi.macip_acl_add_replace(r2[0], 2)
-        self.assertEqual(reply.retval, 0)
-        self.assertEqual(reply.acl_index, 2)
-        reply = self.vapi.macip_acl_add_replace(r2[1], 3)
-        self.assertEqual(reply.retval, 0)
-        self.assertEqual(reply.acl_index, 3)
+        macip_acls[2].modify_vpp_config(r2[0])
+        macip_acls[3].modify_vpp_config(r2[1])
 
         acls_after = self.macip_acl_dump_debug()
 
         # verify changes
         self.assertEqual(len(acls_before), len(acls_after))
         for acl1, acl2 in zip(
 
         acls_after = self.macip_acl_dump_debug()
 
         # verify changes
         self.assertEqual(len(acls_before), len(acls_after))
         for acl1, acl2 in zip(
-                acls_before[:2]+acls_before[4:],
-                acls_after[:2]+acls_after[4:]):
+            acls_before[:2] + acls_before[4:], acls_after[:2] + acls_after[4:]
+        ):
             self.assertEqual(len(acl1), len(acl2))
 
             self.assertEqual(len(acl1.r), len(acl2.r))
             for r1, r2 in zip(acl1.r, acl2.r):
                 self.assertEqual(len(acl1.r), len(acl2.r))
                 self.assertEqual(acl1.r, acl2.r)
             self.assertEqual(len(acl1), len(acl2))
 
             self.assertEqual(len(acl1.r), len(acl2.r))
             for r1, r2 in zip(acl1.r, acl2.r):
                 self.assertEqual(len(acl1.r), len(acl2.r))
                 self.assertEqual(acl1.r, acl2.r)
-        for acl1, acl2 in zip(
-                acls_before[2:4],
-                acls_after[2:4]):
+        for acl1, acl2 in zip(acls_before[2:4], acls_after[2:4]):
             self.assertEqual(len(acl1), len(acl2))
 
             self.assertNotEqual(len(acl1.r), len(acl2.r))
             self.assertEqual(len(acl1), len(acl2))
 
             self.assertNotEqual(len(acl1.r), len(acl2.r))
@@ -1072,46 +1085,58 @@ class TestMACIP(MethodHolder):
                 self.assertNotEqual(acl1.r, acl2.r)
 
     def test_delete_intf(self):
                 self.assertNotEqual(acl1.r, acl2.r)
 
     def test_delete_intf(self):
-        """ MACIP ACL delete intf with acl
-        """
+        """MACIP ACL delete intf with acl"""
 
 
-        intf_count = len(self.interfaces)+1
+        intf_count = len(self.interfaces) + 1
         intf = []
         intf = []
-        self.apply_macip_rules(self.create_rules(acl_count=3,
-                                                 rules_count=[3, 5, 4]))
+        macip_alcs = self.apply_macip_rules(
+            self.create_rules(acl_count=3, rules_count=[3, 5, 4])
+        )
 
 
-        intf.append(VppLoInterface(self, 0))
-        intf.append(VppLoInterface(self, 1))
+        intf.append(VppLoInterface(self))
+        intf.append(VppLoInterface(self))
 
         sw_if_index0 = intf[0].sw_if_index
 
         sw_if_index0 = intf[0].sw_if_index
-        self.vapi.macip_acl_interface_add_del(sw_if_index0, 1)
+        macip_acl_if0 = VppMacipAclInterface(
+            self, sw_if_index=sw_if_index0, acls=[macip_alcs[1]]
+        )
+        macip_acl_if0.add_vpp_config()
 
         reply = self.vapi.macip_acl_interface_get()
 
         reply = self.vapi.macip_acl_interface_get()
-        self.assertEqual(reply.count, intf_count+1)
+        self.assertEqual(reply.count, intf_count + 1)
         self.assertEqual(reply.acls[sw_if_index0], 1)
 
         sw_if_index1 = intf[1].sw_if_index
         self.assertEqual(reply.acls[sw_if_index0], 1)
 
         sw_if_index1 = intf[1].sw_if_index
-        self.vapi.macip_acl_interface_add_del(sw_if_index1, 0)
+        macip_acl_if1 = VppMacipAclInterface(
+            self, sw_if_index=sw_if_index1, acls=[macip_alcs[0]]
+        )
+        macip_acl_if1.add_vpp_config()
 
         reply = self.vapi.macip_acl_interface_get()
 
         reply = self.vapi.macip_acl_interface_get()
-        self.assertEqual(reply.count, intf_count+2)
+        self.assertEqual(reply.count, intf_count + 2)
         self.assertEqual(reply.acls[sw_if_index1], 0)
 
         intf[0].remove_vpp_config()
         reply = self.vapi.macip_acl_interface_get()
         self.assertEqual(reply.acls[sw_if_index1], 0)
 
         intf[0].remove_vpp_config()
         reply = self.vapi.macip_acl_interface_get()
-        self.assertEqual(reply.count, intf_count+2)
+        self.assertEqual(reply.count, intf_count + 2)
         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
         self.assertEqual(reply.acls[sw_if_index1], 0)
 
         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
         self.assertEqual(reply.acls[sw_if_index1], 0)
 
-        intf.append(VppLoInterface(self, 2))
-        intf.append(VppLoInterface(self, 3))
+        intf.append(VppLoInterface(self))
+        intf.append(VppLoInterface(self))
         sw_if_index2 = intf[2].sw_if_index
         sw_if_index3 = intf[3].sw_if_index
         sw_if_index2 = intf[2].sw_if_index
         sw_if_index3 = intf[3].sw_if_index
-        self.vapi.macip_acl_interface_add_del(sw_if_index2, 1)
-        self.vapi.macip_acl_interface_add_del(sw_if_index3, 1)
+        macip_acl_if2 = VppMacipAclInterface(
+            self, sw_if_index=sw_if_index2, acls=[macip_alcs[1]]
+        )
+        macip_acl_if2.add_vpp_config()
+        macip_acl_if3 = VppMacipAclInterface(
+            self, sw_if_index=sw_if_index3, acls=[macip_alcs[1]]
+        )
+        macip_acl_if3.add_vpp_config()
 
         reply = self.vapi.macip_acl_interface_get()
 
         reply = self.vapi.macip_acl_interface_get()
-        self.assertEqual(reply.count, intf_count+3)
+        self.assertEqual(reply.count, intf_count + 3)
         self.assertEqual(reply.acls[sw_if_index1], 0)
         self.assertEqual(reply.acls[sw_if_index2], 1)
         self.assertEqual(reply.acls[sw_if_index3], 1)
         self.assertEqual(reply.acls[sw_if_index1], 0)
         self.assertEqual(reply.acls[sw_if_index2], 1)
         self.assertEqual(reply.acls[sw_if_index3], 1)
@@ -1126,7 +1151,7 @@ class TestMACIP(MethodHolder):
         intf[1].remove_vpp_config()
 
         reply = self.vapi.macip_acl_interface_get()
         intf[1].remove_vpp_config()
 
         reply = self.vapi.macip_acl_interface_get()
-        self.assertEqual(reply.count, intf_count+3)
+        self.assertEqual(reply.count, intf_count + 3)
         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
         self.assertEqual(reply.acls[sw_if_index1], 4294967295)
         self.assertEqual(reply.acls[sw_if_index2], 4294967295)
         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
         self.assertEqual(reply.acls[sw_if_index1], 4294967295)
         self.assertEqual(reply.acls[sw_if_index2], 4294967295)
@@ -1141,82 +1166,202 @@ class TestMACIP(MethodHolder):
 class TestACL_dot1q_bridged(MethodHolder):
     """ACL on dot1q bridged subinterfaces Tests"""
 
 class TestACL_dot1q_bridged(MethodHolder):
     """ACL on dot1q bridged subinterfaces Tests"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestACL_dot1q_bridged, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestACL_dot1q_bridged, cls).tearDownClass()
+
     def test_acl_bridged_ip4_subif_dot1q(self):
     def test_acl_bridged_ip4_subif_dot1q(self):
-        """ IP4 ACL SubIf Dot1Q bridged traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
-                         self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False)
+        """IP4 ACL SubIf Dot1Q bridged traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.BRIDGED,
+            self.IS_IP4,
+            9,
+            tags=self.DOT1Q,
+            isMACIP=False,
+        )
 
     def test_acl_bridged_ip6_subif_dot1q(self):
 
     def test_acl_bridged_ip6_subif_dot1q(self):
-        """ IP6 ACL SubIf Dot1Q bridged traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
-                         self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False)
+        """IP6 ACL SubIf Dot1Q bridged traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.BRIDGED,
+            self.IS_IP6,
+            9,
+            tags=self.DOT1Q,
+            isMACIP=False,
+        )
 
 
 class TestACL_dot1ad_bridged(MethodHolder):
     """ACL on dot1ad bridged subinterfaces Tests"""
 
 
 
 class TestACL_dot1ad_bridged(MethodHolder):
     """ACL on dot1ad bridged subinterfaces Tests"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestACL_dot1ad_bridged, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestACL_dot1ad_bridged, cls).tearDownClass()
+
     def test_acl_bridged_ip4_subif_dot1ad(self):
     def test_acl_bridged_ip4_subif_dot1ad(self):
-        """ IP4 ACL SubIf Dot1AD bridged traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
-                         self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False)
+        """IP4 ACL SubIf Dot1AD bridged traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.BRIDGED,
+            self.IS_IP4,
+            9,
+            tags=self.DOT1AD,
+            isMACIP=False,
+        )
 
     def test_acl_bridged_ip6_subif_dot1ad(self):
 
     def test_acl_bridged_ip6_subif_dot1ad(self):
-        """ IP6 ACL SubIf Dot1AD bridged traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
-                         self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False)
+        """IP6 ACL SubIf Dot1AD bridged traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.BRIDGED,
+            self.IS_IP6,
+            9,
+            tags=self.DOT1AD,
+            isMACIP=False,
+        )
 
 
 class TestACL_dot1q_routed(MethodHolder):
     """ACL on dot1q routed subinterfaces Tests"""
 
 
 
 class TestACL_dot1q_routed(MethodHolder):
     """ACL on dot1q routed subinterfaces Tests"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestACL_dot1q_routed, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestACL_dot1q_routed, cls).tearDownClass()
+
     def test_acl_routed_ip4_subif_dot1q(self):
     def test_acl_routed_ip4_subif_dot1q(self):
-        """ IP4 ACL SubIf Dot1Q routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False)
+        """IP4 ACL SubIf Dot1Q routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP4,
+            9,
+            tags=self.DOT1Q,
+            isMACIP=False,
+        )
 
     def test_acl_routed_ip6_subif_dot1q(self):
 
     def test_acl_routed_ip6_subif_dot1q(self):
-        """ IP6 ACL SubIf Dot1Q routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False)
+        """IP6 ACL SubIf Dot1Q routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP6,
+            9,
+            tags=self.DOT1Q,
+            isMACIP=False,
+        )
 
     def test_acl_routed_ip4_subif_dot1q_deny_by_tags(self):
 
     def test_acl_routed_ip4_subif_dot1q_deny_by_tags(self):
-        """ IP4 ACL SubIf wrong tags Dot1Q routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP4, 9, True, tags=self.DOT1Q, isMACIP=False,
-                         permit_tags=self.DENY_TAGS)
+        """IP4 ACL SubIf wrong tags Dot1Q routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP4,
+            9,
+            True,
+            tags=self.DOT1Q,
+            isMACIP=False,
+            permit_tags=self.DENY_TAGS,
+        )
 
     def test_acl_routed_ip6_subif_dot1q_deny_by_tags(self):
 
     def test_acl_routed_ip6_subif_dot1q_deny_by_tags(self):
-        """ IP6 ACL SubIf wrong tags Dot1Q routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP6, 9, True, tags=self.DOT1Q, isMACIP=False,
-                         permit_tags=self.DENY_TAGS)
+        """IP6 ACL SubIf wrong tags Dot1Q routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP6,
+            9,
+            True,
+            tags=self.DOT1Q,
+            isMACIP=False,
+            permit_tags=self.DENY_TAGS,
+        )
 
 
 class TestACL_dot1ad_routed(MethodHolder):
     """ACL on dot1ad routed subinterfaces Tests"""
 
 
 
 class TestACL_dot1ad_routed(MethodHolder):
     """ACL on dot1ad routed subinterfaces Tests"""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestACL_dot1ad_routed, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestACL_dot1ad_routed, cls).tearDownClass()
+
     def test_acl_routed_ip6_subif_dot1ad(self):
     def test_acl_routed_ip6_subif_dot1ad(self):
-        """ IP6 ACL SubIf Dot1AD routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False)
+        """IP6 ACL SubIf Dot1AD routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP6,
+            9,
+            tags=self.DOT1AD,
+            isMACIP=False,
+        )
 
     def test_acl_routed_ip4_subif_dot1ad(self):
 
     def test_acl_routed_ip4_subif_dot1ad(self):
-        """ IP4 ACL SubIf Dot1AD routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False)
+        """IP4 ACL SubIf Dot1AD routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP4,
+            9,
+            tags=self.DOT1AD,
+            isMACIP=False,
+        )
 
     def test_acl_routed_ip6_subif_dot1ad_deny_by_tags(self):
 
     def test_acl_routed_ip6_subif_dot1ad_deny_by_tags(self):
-        """ IP6 ACL SubIf wrong tags Dot1AD routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP6, 9, True, tags=self.DOT1AD, isMACIP=False,
-                         permit_tags=self.DENY_TAGS)
+        """IP6 ACL SubIf wrong tags Dot1AD routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP6,
+            9,
+            True,
+            tags=self.DOT1AD,
+            isMACIP=False,
+            permit_tags=self.DENY_TAGS,
+        )
 
     def test_acl_routed_ip4_subif_dot1ad_deny_by_tags(self):
 
     def test_acl_routed_ip4_subif_dot1ad_deny_by_tags(self):
-        """ IP4 ACL SubIf wrong tags Dot1AD routed traffic"""
-        self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
-                         self.IS_IP4, 9, True, tags=self.DOT1AD, isMACIP=False,
-                         permit_tags=self.DENY_TAGS)
-
-
-if __name__ == '__main__':
+        """IP4 ACL SubIf wrong tags Dot1AD routed traffic"""
+        self.run_traffic(
+            self.EXACT_MAC,
+            self.EXACT_IP,
+            self.ROUTED,
+            self.IS_IP4,
+            9,
+            True,
+            tags=self.DOT1AD,
+            isMACIP=False,
+            permit_tags=self.DENY_TAGS,
+        )
+
+
+if __name__ == "__main__":
     unittest.main(testRunner=VppTestRunner)
     unittest.main(testRunner=VppTestRunner)