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                 acl_rule.sport_from = rule_l4_sport
523                 acl_rule.sport_to = rule_l4_sport
524                 acl_rule.dport_from = rule_l4_dport
525                 acl_rule.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         acl_rule.sport_from = 0
553         acl_rule.sport_to = 0
554         acl_rule.dport_from = 0
555         acl_rule.dport_to = 0
556         acl_rules.append(acl_rule)
557         return {'stream': packets,
558                 'macip_rules': macip_rules,
559                 'acl_rules': acl_rules}
560
561     def verify_capture(self, stream, capture, is_ip6):
562         """
563         :param stream:
564         :param capture:
565         :param is_ip6:
566         :return:
567         """
568         # p_l3 = IPv6 if is_ip6 else IP
569         # if self.DEBUG:
570         #     for p in stream:
571         #         print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst)
572         #
573         # acls = self.macip_acl_dump_debug()
574
575         # TODO : verify
576         # for acl in acls:
577         #     for r in acl.r:
578         #         print(binascii.hexlify(r.src_mac), \
579         #               binascii.hexlify(r.src_mac_mask),\
580         #               unpack('<16B', r.src_ip_addr), \
581         #               r.src_ip_prefix_len)
582         #
583         # for p in capture:
584         #     print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst
585         #     data = p[Raw].load.split(':',1)[1])
586         #     print(p[p_l3].src, data)
587
588     def run_traffic(self, mac_type, ip_type, traffic, is_ip6, packets,
589                     do_not_expected_capture=False, tags=None,
590                     apply_rules=True, isMACIP=True, permit_tags=PERMIT_TAGS,
591                     try_replace=False):
592         self.reset_packet_infos()
593
594         if tags is None:
595             tx_if = self.pg0 if traffic == self.BRIDGED else self.pg3
596             rx_if = self.pg3 if traffic == self.BRIDGED else self.pg0
597             src_if = self.pg3
598             dst_if = self.loop0
599         else:
600             if tags == self.DOT1Q:
601                 if traffic == self.BRIDGED:
602                     tx_if = self.subifs[0]
603                     rx_if = self.pg0
604                     src_if = self.subifs[0]
605                     dst_if = self.loop0
606                 else:
607                     tx_if = self.subifs[2]
608                     rx_if = self.pg0
609                     src_if = self.subifs[2]
610                     dst_if = self.loop0
611             elif tags == self.DOT1AD:
612                 if traffic == self.BRIDGED:
613                     tx_if = self.subifs[1]
614                     rx_if = self.pg0
615                     src_if = self.subifs[1]
616                     dst_if = self.loop0
617                 else:
618                     tx_if = self.subifs[3]
619                     rx_if = self.pg0
620                     src_if = self.subifs[3]
621                     dst_if = self.loop0
622             else:
623                 return
624
625         test_dict = self.create_stream(mac_type, ip_type, packets,
626                                        src_if, dst_if,
627                                        traffic, is_ip6,
628                                        tags=permit_tags)
629
630         if apply_rules:
631             if isMACIP:
632                 self.acl = VppMacipAcl(self, rules=test_dict['macip_rules'])
633             else:
634                 self.acl = VppAcl(self, rules=test_dict['acl_rules'])
635             self.acl.add_vpp_config()
636
637             if isMACIP:
638                 self.acl_if = VppMacipAclInterface(
639                     self, sw_if_index=tx_if.sw_if_index, acls=[self.acl])
640                 self.acl_if.add_vpp_config()
641
642                 dump = self.acl_if.dump()
643                 self.assertTrue(dump)
644                 self.assertEqual(dump[0].acls[0], self.acl.acl_index)
645             else:
646                 self.acl_if = VppAclInterface(
647                     self, sw_if_index=tx_if.sw_if_index, n_input=1,
648                     acls=[self.acl])
649                 self.acl_if.add_vpp_config()
650         else:
651             if hasattr(self, "acl_if"):
652                 self.acl_if.remove_vpp_config()
653         if try_replace and hasattr(self, "acl"):
654             if isMACIP:
655                 self.acl.rules = test_dict['macip_rules']
656                 self.acl.add_vpp_config()
657             else:
658                 self.acl.rules = test_dict['acl_rules']
659                 self.acl.add_vpp_config()
660
661         if not isinstance(src_if, VppSubInterface):
662             tx_if.add_stream(test_dict['stream'])
663         else:
664             tx_if.parent.add_stream(test_dict['stream'])
665         self.pg_enable_capture(self.pg_interfaces)
666         self.pg_start()
667
668         if do_not_expected_capture:
669             rx_if.get_capture(0)
670         else:
671             if traffic == self.BRIDGED and mac_type == self.WILD_MAC and \
672                     ip_type == self.WILD_IP:
673                 capture = rx_if.get_capture(packets)
674             else:
675                 capture = rx_if.get_capture(
676                     self.get_packet_count_for_if_idx(dst_if.sw_if_index))
677             self.verify_capture(test_dict['stream'], capture, is_ip6)
678         if not isMACIP:
679             if hasattr(self, "acl_if"):
680                 self.acl_if.remove_vpp_config()
681             if hasattr(self, "acl"):
682                 self.acl.remove_vpp_config()
683
684     def run_test_acls(self, mac_type, ip_type, acl_count,
685                       rules_count, traffic=None, ip=None):
686         self.apply_macip_rules(self.create_rules(mac_type, ip_type, acl_count,
687                                                  rules_count))
688         self.verify_macip_acls(acl_count, rules_count)
689
690         if traffic is not None:
691             self.run_traffic(self.EXACT_MAC, self.EXACT_IP, traffic, ip, 9)
692
693
694 class TestMACIP_IP4(MethodHolder):
695     """MACIP with IP4 traffic"""
696
697     @classmethod
698     def setUpClass(cls):
699         super(TestMACIP_IP4, cls).setUpClass()
700
701     @classmethod
702     def tearDownClass(cls):
703         super(TestMACIP_IP4, cls).tearDownClass()
704
705     def test_acl_bridged_ip4_exactMAC_exactIP(self):
706         """ IP4 MACIP exactMAC|exactIP ACL bridged traffic
707         """
708         self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
709                          self.BRIDGED, self.IS_IP4, 9)
710
711     def test_acl_bridged_ip4_exactMAC_subnetIP(self):
712         """ IP4 MACIP exactMAC|subnetIP ACL bridged traffic
713         """
714
715         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
716                          self.BRIDGED, self.IS_IP4, 9)
717
718     def test_acl_bridged_ip4_exactMAC_wildIP(self):
719         """ IP4 MACIP exactMAC|wildIP ACL bridged traffic
720         """
721
722         self.run_traffic(self.EXACT_MAC, self.WILD_IP,
723                          self.BRIDGED, self.IS_IP4, 9)
724
725     def test_acl_bridged_ip4_ouiMAC_exactIP(self):
726         """ IP4 MACIP ouiMAC|exactIP ACL bridged traffic
727         """
728
729         self.run_traffic(self.OUI_MAC, self.EXACT_IP,
730                          self.BRIDGED, self.IS_IP4, 3)
731
732     def test_acl_bridged_ip4_ouiMAC_subnetIP(self):
733         """ IP4 MACIP ouiMAC|subnetIP ACL bridged traffic
734         """
735
736         self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
737                          self.BRIDGED, self.IS_IP4, 9)
738
739     def test_acl_bridged_ip4_ouiMAC_wildIP(self):
740         """ IP4 MACIP ouiMAC|wildIP ACL bridged traffic
741         """
742
743         self.run_traffic(self.OUI_MAC, self.WILD_IP,
744                          self.BRIDGED, self.IS_IP4, 9)
745
746     def test_ac_bridgedl_ip4_wildMAC_exactIP(self):
747         """ IP4 MACIP wildcardMAC|exactIP ACL bridged traffic
748         """
749
750         self.run_traffic(self.WILD_MAC, self.EXACT_IP,
751                          self.BRIDGED, self.IS_IP4, 9)
752
753     def test_acl_bridged_ip4_wildMAC_subnetIP(self):
754         """ IP4 MACIP wildcardMAC|subnetIP ACL bridged traffic
755         """
756
757         self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
758                          self.BRIDGED, self.IS_IP4, 9)
759
760     def test_acl_bridged_ip4_wildMAC_wildIP(self):
761         """ IP4 MACIP wildcardMAC|wildIP ACL bridged traffic
762         """
763
764         self.run_traffic(self.WILD_MAC, self.WILD_IP,
765                          self.BRIDGED, self.IS_IP4, 9)
766
767     def test_acl_routed_ip4_exactMAC_exactIP(self):
768         """ IP4 MACIP exactMAC|exactIP ACL routed traffic
769         """
770         self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
771                          self.ROUTED, self.IS_IP4, 9)
772
773     def test_acl_routed_ip4_exactMAC_subnetIP(self):
774         """ IP4 MACIP exactMAC|subnetIP ACL routed traffic
775         """
776         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
777                          self.ROUTED, self.IS_IP4, 9)
778
779     def test_acl_routed_ip4_exactMAC_wildIP(self):
780         """ IP4 MACIP exactMAC|wildIP ACL routed traffic
781         """
782         self.run_traffic(self.EXACT_MAC, self.WILD_IP,
783                          self.ROUTED, self.IS_IP4, 9)
784
785     def test_acl_routed_ip4_ouiMAC_exactIP(self):
786         """ IP4 MACIP ouiMAC|exactIP ACL routed traffic
787         """
788
789         self.run_traffic(self.OUI_MAC, self.EXACT_IP,
790                          self.ROUTED, self.IS_IP4, 9)
791
792     def test_acl_routed_ip4_ouiMAC_subnetIP(self):
793         """ IP4 MACIP ouiMAC|subnetIP ACL routed traffic
794         """
795
796         self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
797                          self.ROUTED, self.IS_IP4, 9)
798
799     def test_acl_routed_ip4_ouiMAC_wildIP(self):
800         """ IP4 MACIP ouiMAC|wildIP ACL routed traffic
801         """
802
803         self.run_traffic(self.OUI_MAC, self.WILD_IP,
804                          self.ROUTED, self.IS_IP4, 9)
805
806     def test_acl_routed_ip4_wildMAC_exactIP(self):
807         """ IP4 MACIP wildcardMAC|exactIP ACL routed traffic
808         """
809
810         self.run_traffic(self.WILD_MAC, self.EXACT_IP,
811                          self.ROUTED, self.IS_IP4, 9)
812
813     def test_acl_routed_ip4_wildMAC_subnetIP(self):
814         """ IP4 MACIP wildcardMAC|subnetIP ACL routed traffic
815         """
816
817         self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
818                          self.ROUTED, self.IS_IP4, 9)
819
820     def test_acl_routed_ip4_wildMAC_wildIP(self):
821         """ IP4 MACIP wildcardMAC|wildIP ACL
822         """
823
824         self.run_traffic(self.WILD_MAC, self.WILD_IP,
825                          self.ROUTED, self.IS_IP4, 9)
826
827     def test_acl_replace_traffic_ip4(self):
828         """ MACIP replace ACL with IP4 traffic
829         """
830         self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
831                          self.BRIDGED, self.IS_IP4, 9, try_replace=True)
832         self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
833                          self.BRIDGED, self.IS_IP4, 9, try_replace=True)
834
835
836 class TestMACIP_IP6(MethodHolder):
837     """MACIP with IP6 traffic"""
838
839     @classmethod
840     def setUpClass(cls):
841         super(TestMACIP_IP6, cls).setUpClass()
842
843     @classmethod
844     def tearDownClass(cls):
845         super(TestMACIP_IP6, cls).tearDownClass()
846
847     def test_acl_bridged_ip6_exactMAC_exactIP(self):
848         """ IP6 MACIP exactMAC|exactIP ACL bridged traffic
849         """
850
851         self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
852                          self.BRIDGED, self.IS_IP6, 9)
853
854     def test_acl_bridged_ip6_exactMAC_subnetIP(self):
855         """ IP6 MACIP exactMAC|subnetIP ACL bridged traffic
856         """
857
858         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
859                          self.BRIDGED, self.IS_IP6, 9)
860
861     def test_acl_bridged_ip6_exactMAC_wildIP(self):
862         """ IP6 MACIP exactMAC|wildIP ACL bridged traffic
863         """
864
865         self.run_traffic(self.EXACT_MAC, self.WILD_IP,
866                          self.BRIDGED, self.IS_IP6, 9)
867
868     def test_acl_bridged_ip6_ouiMAC_exactIP(self):
869         """ IP6 MACIP oui_MAC|exactIP ACL bridged traffic
870         """
871
872         self.run_traffic(self.OUI_MAC, self.EXACT_IP,
873                          self.BRIDGED, self.IS_IP6, 9)
874
875     def test_acl_bridged_ip6_ouiMAC_subnetIP(self):
876         """ IP6 MACIP ouiMAC|subnetIP ACL bridged traffic
877         """
878
879         self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
880                          self.BRIDGED, self.IS_IP6, 9)
881
882     def test_acl_bridged_ip6_ouiMAC_wildIP(self):
883         """ IP6 MACIP ouiMAC|wildIP ACL bridged traffic
884         """
885
886         self.run_traffic(self.OUI_MAC, self.WILD_IP,
887                          self.BRIDGED, self.IS_IP6, 9)
888
889     def test_acl_bridged_ip6_wildMAC_exactIP(self):
890         """ IP6 MACIP wildcardMAC|exactIP ACL bridged traffic
891         """
892
893         self.run_traffic(self.WILD_MAC, self.EXACT_IP,
894                          self.BRIDGED, self.IS_IP6, 9)
895
896     def test_acl_bridged_ip6_wildMAC_subnetIP(self):
897         """ IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic
898         """
899
900         self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
901                          self.BRIDGED, self.IS_IP6, 9)
902
903     def test_acl_bridged_ip6_wildMAC_wildIP(self):
904         """ IP6 MACIP wildcardMAC|wildIP ACL bridged traffic
905         """
906
907         self.run_traffic(self.WILD_MAC, self.WILD_IP,
908                          self.BRIDGED, self.IS_IP6, 9)
909
910     def test_acl_routed_ip6_exactMAC_exactIP(self):
911         """ IP6 MACIP exactMAC|exactIP ACL routed traffic
912         """
913
914         self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
915                          self.ROUTED, self.IS_IP6, 9)
916
917     def test_acl_routed_ip6_exactMAC_subnetIP(self):
918         """ IP6 MACIP exactMAC|subnetIP ACL routed traffic
919         """
920
921         self.run_traffic(self.EXACT_MAC, self.SUBNET_IP,
922                          self.ROUTED, self.IS_IP6, 9)
923
924     def test_acl_routed_ip6_exactMAC_wildIP(self):
925         """ IP6 MACIP exactMAC|wildIP ACL routed traffic
926         """
927
928         self.run_traffic(self.EXACT_MAC, self.WILD_IP,
929                          self.ROUTED, self.IS_IP6, 9)
930
931     def test_acl_routed_ip6_ouiMAC_exactIP(self):
932         """ IP6 MACIP ouiMAC|exactIP ACL routed traffic
933         """
934
935         self.run_traffic(self.OUI_MAC, self.EXACT_IP,
936                          self.ROUTED, self.IS_IP6, 9)
937
938     def test_acl_routed_ip6_ouiMAC_subnetIP(self):
939         """ IP6 MACIP ouiMAC|subnetIP ACL routed traffic
940         """
941
942         self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
943                          self.ROUTED, self.IS_IP6, 9)
944
945     def test_acl_routed_ip6_ouiMAC_wildIP(self):
946         """ IP6 MACIP ouiMAC|wildIP ACL routed traffic
947         """
948
949         self.run_traffic(self.OUI_MAC, self.WILD_IP,
950                          self.ROUTED, self.IS_IP6, 9)
951
952     def test_acl_routed_ip6_wildMAC_exactIP(self):
953         """ IP6 MACIP wildcardMAC|exactIP ACL routed traffic
954         """
955
956         self.run_traffic(self.WILD_MAC, self.EXACT_IP,
957                          self.ROUTED, self.IS_IP6, 9)
958
959     def test_acl_routed_ip6_wildMAC_subnetIP(self):
960         """ IP6 MACIP wildcardMAC|subnetIP ACL routed traffic
961         """
962
963         self.run_traffic(self.WILD_MAC, self.SUBNET_IP,
964                          self.ROUTED, self.IS_IP6, 9)
965
966     def test_acl_routed_ip6_wildMAC_wildIP(self):
967         """ IP6 MACIP wildcardMAC|wildIP ACL
968         """
969
970         self.run_traffic(self.WILD_MAC, self.WILD_IP,
971                          self.ROUTED, self.IS_IP6, 9)
972
973     def test_acl_replace_traffic_ip6(self):
974         """ MACIP replace ACL with IP6 traffic
975         """
976         self.run_traffic(self.OUI_MAC, self.SUBNET_IP,
977                          self.BRIDGED, self.IS_IP6, 9, try_replace=True)
978         self.run_traffic(self.EXACT_MAC, self.EXACT_IP,
979                          self.BRIDGED, self.IS_IP6, 9, try_replace=True)
980
981
982 class TestMACIP(MethodHolder):
983     """MACIP Tests"""
984
985     @classmethod
986     def setUpClass(cls):
987         super(TestMACIP, cls).setUpClass()
988
989     @classmethod
990     def tearDownClass(cls):
991         super(TestMACIP, cls).tearDownClass()
992
993     def test_acl_1_2(self):
994         """ MACIP ACL with 2 entries
995         """
996
997         self.run_test_acls(self.EXACT_MAC, self.WILD_IP, 1, [2])
998
999     def test_acl_1_5(self):
1000         """ MACIP ACL with 5 entries
1001         """
1002
1003         self.run_test_acls(self.EXACT_MAC, self.SUBNET_IP, 1, [5])
1004
1005     def test_acl_1_10(self):
1006         """ MACIP ACL with 10 entries
1007         """
1008
1009         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 1, [10])
1010
1011     def test_acl_1_20(self):
1012         """ MACIP ACL with 20 entries
1013         """
1014
1015         self.run_test_acls(self.OUI_MAC, self.WILD_IP, 1, [20])
1016
1017     def test_acl_1_50(self):
1018         """ MACIP ACL with 50 entries
1019         """
1020
1021         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 1, [50])
1022
1023     def test_acl_1_100(self):
1024         """ MACIP ACL with 100 entries
1025         """
1026
1027         self.run_test_acls(self.OUI_MAC, self.EXACT_IP, 1, [100])
1028
1029     def test_acl_2_X(self):
1030         """ MACIP 2 ACLs each with 100+ entries
1031         """
1032
1033         self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 2, [100, 200])
1034
1035     def test_acl_10_X(self):
1036         """ MACIP 10 ACLs each with 100+ entries
1037         """
1038
1039         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 10,
1040                            [100, 120, 140, 160, 180, 200, 210, 220, 230, 240])
1041
1042     def test_acl_10_X_traffic_ip4(self):
1043         """ MACIP 10 ACLs each with 100+ entries with IP4 traffic
1044         """
1045
1046         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 10,
1047                            [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
1048                            self.BRIDGED, self.IS_IP4)
1049
1050     def test_acl_10_X_traffic_ip6(self):
1051         """ MACIP 10 ACLs each with 100+ entries with IP6 traffic
1052         """
1053
1054         self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 10,
1055                            [100, 120, 140, 160, 180, 200, 210, 220, 230, 240],
1056                            self.BRIDGED, self.IS_IP6)
1057
1058     def test_acl_replace(self):
1059         """ MACIP replace ACL
1060         """
1061
1062         r1 = self.create_rules(acl_count=3, rules_count=[2, 2, 2])
1063         r2 = self.create_rules(mac_type=self.OUI_MAC, ip_type=self.SUBNET_IP)
1064         macip_acls = self.apply_macip_rules(r1)
1065
1066         acls_before = self.macip_acl_dump_debug()
1067
1068         # replace acls #2, #3 with new
1069         macip_acls[2].rules = r2[0]
1070         macip_acls[2].add_vpp_config()
1071         macip_acls[3].rules = r2[1]
1072         macip_acls[3].add_vpp_config()
1073
1074         acls_after = self.macip_acl_dump_debug()
1075
1076         # verify changes
1077         self.assertEqual(len(acls_before), len(acls_after))
1078         for acl1, acl2 in zip(
1079                 acls_before[:2]+acls_before[4:],
1080                 acls_after[:2]+acls_after[4:]):
1081             self.assertEqual(len(acl1), len(acl2))
1082
1083             self.assertEqual(len(acl1.r), len(acl2.r))
1084             for r1, r2 in zip(acl1.r, acl2.r):
1085                 self.assertEqual(len(acl1.r), len(acl2.r))
1086                 self.assertEqual(acl1.r, acl2.r)
1087         for acl1, acl2 in zip(
1088                 acls_before[2:4],
1089                 acls_after[2:4]):
1090             self.assertEqual(len(acl1), len(acl2))
1091
1092             self.assertNotEqual(len(acl1.r), len(acl2.r))
1093             for r1, r2 in zip(acl1.r, acl2.r):
1094                 self.assertNotEqual(len(acl1.r), len(acl2.r))
1095                 self.assertNotEqual(acl1.r, acl2.r)
1096
1097     def test_delete_intf(self):
1098         """ MACIP ACL delete intf with acl
1099         """
1100
1101         intf_count = len(self.interfaces)+1
1102         intf = []
1103         macip_alcs = self.apply_macip_rules(
1104             self.create_rules(acl_count=3, rules_count=[3, 5, 4]))
1105
1106         intf.append(VppLoInterface(self))
1107         intf.append(VppLoInterface(self))
1108
1109         sw_if_index0 = intf[0].sw_if_index
1110         macip_acl_if0 = VppMacipAclInterface(
1111             self, sw_if_index=sw_if_index0, acls=[macip_alcs[1]])
1112         macip_acl_if0.add_vpp_config()
1113
1114         reply = self.vapi.macip_acl_interface_get()
1115         self.assertEqual(reply.count, intf_count+1)
1116         self.assertEqual(reply.acls[sw_if_index0], 1)
1117
1118         sw_if_index1 = intf[1].sw_if_index
1119         macip_acl_if1 = VppMacipAclInterface(
1120             self, sw_if_index=sw_if_index1, acls=[macip_alcs[0]])
1121         macip_acl_if1.add_vpp_config()
1122
1123         reply = self.vapi.macip_acl_interface_get()
1124         self.assertEqual(reply.count, intf_count+2)
1125         self.assertEqual(reply.acls[sw_if_index1], 0)
1126
1127         intf[0].remove_vpp_config()
1128         reply = self.vapi.macip_acl_interface_get()
1129         self.assertEqual(reply.count, intf_count+2)
1130         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
1131         self.assertEqual(reply.acls[sw_if_index1], 0)
1132
1133         intf.append(VppLoInterface(self))
1134         intf.append(VppLoInterface(self))
1135         sw_if_index2 = intf[2].sw_if_index
1136         sw_if_index3 = intf[3].sw_if_index
1137         macip_acl_if2 = VppMacipAclInterface(
1138             self, sw_if_index=sw_if_index2, acls=[macip_alcs[1]])
1139         macip_acl_if2.add_vpp_config()
1140         macip_acl_if3 = VppMacipAclInterface(
1141             self, sw_if_index=sw_if_index3, acls=[macip_alcs[1]])
1142         macip_acl_if3.add_vpp_config()
1143
1144         reply = self.vapi.macip_acl_interface_get()
1145         self.assertEqual(reply.count, intf_count+3)
1146         self.assertEqual(reply.acls[sw_if_index1], 0)
1147         self.assertEqual(reply.acls[sw_if_index2], 1)
1148         self.assertEqual(reply.acls[sw_if_index3], 1)
1149         self.logger.info("MACIP ACL on multiple interfaces:")
1150         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl"))
1151         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 1234"))
1152         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 1"))
1153         self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 0"))
1154         self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface"))
1155
1156         intf[2].remove_vpp_config()
1157         intf[1].remove_vpp_config()
1158
1159         reply = self.vapi.macip_acl_interface_get()
1160         self.assertEqual(reply.count, intf_count+3)
1161         self.assertEqual(reply.acls[sw_if_index0], 4294967295)
1162         self.assertEqual(reply.acls[sw_if_index1], 4294967295)
1163         self.assertEqual(reply.acls[sw_if_index2], 4294967295)
1164         self.assertEqual(reply.acls[sw_if_index3], 1)
1165
1166         intf[3].remove_vpp_config()
1167         reply = self.vapi.macip_acl_interface_get()
1168
1169         self.assertEqual(len([x for x in reply.acls if x != 4294967295]), 0)
1170
1171
1172 class TestACL_dot1q_bridged(MethodHolder):
1173     """ACL on dot1q bridged subinterfaces Tests"""
1174
1175     @classmethod
1176     def setUpClass(cls):
1177         super(TestACL_dot1q_bridged, cls).setUpClass()
1178
1179     @classmethod
1180     def tearDownClass(cls):
1181         super(TestACL_dot1q_bridged, cls).tearDownClass()
1182
1183     def test_acl_bridged_ip4_subif_dot1q(self):
1184         """ IP4 ACL SubIf Dot1Q bridged traffic"""
1185         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
1186                          self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False)
1187
1188     def test_acl_bridged_ip6_subif_dot1q(self):
1189         """ IP6 ACL SubIf Dot1Q bridged traffic"""
1190         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
1191                          self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False)
1192
1193
1194 class TestACL_dot1ad_bridged(MethodHolder):
1195     """ACL on dot1ad bridged subinterfaces Tests"""
1196
1197     @classmethod
1198     def setUpClass(cls):
1199         super(TestACL_dot1ad_bridged, cls).setUpClass()
1200
1201     @classmethod
1202     def tearDownClass(cls):
1203         super(TestACL_dot1ad_bridged, cls).tearDownClass()
1204
1205     def test_acl_bridged_ip4_subif_dot1ad(self):
1206         """ IP4 ACL SubIf Dot1AD bridged traffic"""
1207         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
1208                          self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False)
1209
1210     def test_acl_bridged_ip6_subif_dot1ad(self):
1211         """ IP6 ACL SubIf Dot1AD bridged traffic"""
1212         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED,
1213                          self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False)
1214
1215
1216 class TestACL_dot1q_routed(MethodHolder):
1217     """ACL on dot1q routed subinterfaces Tests"""
1218
1219     @classmethod
1220     def setUpClass(cls):
1221         super(TestACL_dot1q_routed, cls).setUpClass()
1222
1223     @classmethod
1224     def tearDownClass(cls):
1225         super(TestACL_dot1q_routed, cls).tearDownClass()
1226
1227     def test_acl_routed_ip4_subif_dot1q(self):
1228         """ IP4 ACL SubIf Dot1Q routed traffic"""
1229         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1230                          self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False)
1231
1232     def test_acl_routed_ip6_subif_dot1q(self):
1233         """ IP6 ACL SubIf Dot1Q routed traffic"""
1234         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1235                          self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False)
1236
1237     def test_acl_routed_ip4_subif_dot1q_deny_by_tags(self):
1238         """ IP4 ACL SubIf wrong tags Dot1Q routed traffic"""
1239         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1240                          self.IS_IP4, 9, True, tags=self.DOT1Q, isMACIP=False,
1241                          permit_tags=self.DENY_TAGS)
1242
1243     def test_acl_routed_ip6_subif_dot1q_deny_by_tags(self):
1244         """ IP6 ACL SubIf wrong tags Dot1Q routed traffic"""
1245         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1246                          self.IS_IP6, 9, True, tags=self.DOT1Q, isMACIP=False,
1247                          permit_tags=self.DENY_TAGS)
1248
1249
1250 class TestACL_dot1ad_routed(MethodHolder):
1251     """ACL on dot1ad routed subinterfaces Tests"""
1252
1253     @classmethod
1254     def setUpClass(cls):
1255         super(TestACL_dot1ad_routed, cls).setUpClass()
1256
1257     @classmethod
1258     def tearDownClass(cls):
1259         super(TestACL_dot1ad_routed, cls).tearDownClass()
1260
1261     def test_acl_routed_ip6_subif_dot1ad(self):
1262         """ IP6 ACL SubIf Dot1AD routed traffic"""
1263         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1264                          self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False)
1265
1266     def test_acl_routed_ip4_subif_dot1ad(self):
1267         """ IP4 ACL SubIf Dot1AD routed traffic"""
1268         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1269                          self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False)
1270
1271     def test_acl_routed_ip6_subif_dot1ad_deny_by_tags(self):
1272         """ IP6 ACL SubIf wrong tags Dot1AD routed traffic"""
1273         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1274                          self.IS_IP6, 9, True, tags=self.DOT1AD, isMACIP=False,
1275                          permit_tags=self.DENY_TAGS)
1276
1277     def test_acl_routed_ip4_subif_dot1ad_deny_by_tags(self):
1278         """ IP4 ACL SubIf wrong tags Dot1AD routed traffic"""
1279         self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED,
1280                          self.IS_IP4, 9, True, tags=self.DOT1AD, isMACIP=False,
1281                          permit_tags=self.DENY_TAGS)
1282
1283
1284 if __name__ == '__main__':
1285     unittest.main(testRunner=VppTestRunner)