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