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