2a99e86119bad0a07b52b9df82e91126321495e8
[vpp.git] / test / test_acl_plugin_l2l3.py
1 #!/usr/bin/env python
2 """ACL IRB Test Case HLD:
3
4 **config**
5     - L2 MAC learning enabled in l2bd
6     - 2 routed interfaces untagged, bvi (Bridge Virtual Interface)
7     - 2 bridged interfaces in l2bd with bvi
8
9 **test**
10     - sending ip4 eth pkts between routed interfaces
11         - 2 routed interfaces
12         - 2 bridged interfaces
13
14     - 64B, 512B, 1518B, 9200B (ether_size)
15
16     - burst of pkts per interface
17         - 257pkts per burst
18         - routed pkts hitting different FIB entries
19         - bridged pkts hitting different MAC entries
20
21 **verify**
22     - all packets received correctly
23
24 """
25
26 import unittest
27 from socket import inet_pton, AF_INET, AF_INET6
28 from random import choice, shuffle
29 from pprint import pprint
30
31 import scapy.compat
32 from scapy.packet import Raw
33 from scapy.layers.l2 import Ether
34 from scapy.layers.inet import IP, UDP, ICMP, TCP
35 from scapy.layers.inet6 import IPv6, ICMPv6Unknown, ICMPv6EchoRequest
36 from scapy.layers.inet6 import ICMPv6EchoReply, IPv6ExtHdrRouting
37 from scapy.layers.inet6 import IPv6ExtHdrFragment
38
39 from framework import VppTestCase, VppTestRunner
40 from vpp_papi_provider import L2_PORT_TYPE
41 import time
42
43
44 class TestACLpluginL2L3(VppTestCase):
45     """TestACLpluginL2L3 Test Case"""
46
47     @classmethod
48     def setUpClass(cls):
49         """
50         #. Create BD with MAC learning enabled and put interfaces to this BD.
51         #. Configure IPv4 addresses on loopback interface and routed interface.
52         #. Configure MAC address binding to IPv4 neighbors on loop0.
53         #. Configure MAC address on pg2.
54         #. Loopback BVI interface has remote hosts, one half of hosts are
55            behind pg0 second behind pg1.
56         """
57         super(TestACLpluginL2L3, cls).setUpClass()
58
59         cls.pg_if_packet_sizes = [64, 512, 1518, 9018]  # packet sizes
60         cls.bd_id = 10
61         cls.remote_hosts_count = 250
62
63         # create 3 pg interfaces, 1 loopback interface
64         cls.create_pg_interfaces(range(3))
65         cls.create_loopback_interfaces(1)
66
67         cls.interfaces = list(cls.pg_interfaces)
68         cls.interfaces.extend(cls.lo_interfaces)
69
70         for i in cls.interfaces:
71             i.admin_up()
72
73         # Create BD with MAC learning enabled and put interfaces to this BD
74         cls.vapi.sw_interface_set_l2_bridge(
75             cls.loop0.sw_if_index, bd_id=cls.bd_id,
76             port_type=L2_PORT_TYPE.BVI)
77         cls.vapi.sw_interface_set_l2_bridge(
78             cls.pg0.sw_if_index, bd_id=cls.bd_id)
79         cls.vapi.sw_interface_set_l2_bridge(
80             cls.pg1.sw_if_index, bd_id=cls.bd_id)
81
82         # Configure IPv4 addresses on loopback interface and routed interface
83         cls.loop0.config_ip4()
84         cls.loop0.config_ip6()
85         cls.pg2.config_ip4()
86         cls.pg2.config_ip6()
87
88         # Configure MAC address binding to IPv4 neighbors on loop0
89         cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
90         cls.loop0.configure_ipv4_neighbors()
91         cls.loop0.configure_ipv6_neighbors()
92         # configure MAC address on pg2
93         cls.pg2.resolve_arp()
94         cls.pg2.resolve_ndp()
95
96         cls.WITHOUT_EH = False
97         cls.WITH_EH = True
98         cls.STATELESS_ICMP = False
99         cls.STATEFUL_ICMP = True
100
101         # Loopback BVI interface has remote hosts, one half of hosts are behind
102         # pg0 second behind pg1
103         half = cls.remote_hosts_count // 2
104         cls.pg0.remote_hosts = cls.loop0.remote_hosts[:half]
105         cls.pg1.remote_hosts = cls.loop0.remote_hosts[half:]
106
107     def tearDown(self):
108         """Run standard test teardown and log ``show l2patch``,
109         ``show l2fib verbose``,``show bridge-domain <bd_id> detail``,
110         ``show ip arp``.
111         """
112         super(TestACLpluginL2L3, self).tearDown()
113         if not self.vpp_dead:
114             self.logger.info(self.vapi.cli("show l2patch"))
115             self.logger.info(self.vapi.cli("show classify tables"))
116             self.logger.info(self.vapi.cli("show l2fib verbose"))
117             self.logger.info(self.vapi.cli("show bridge-domain %s detail" %
118                                            self.bd_id))
119             self.logger.info(self.vapi.cli("show ip arp"))
120             self.logger.info(self.vapi.cli("show ip6 neighbors"))
121             cmd = "show acl-plugin sessions verbose 1"
122             self.logger.info(self.vapi.cli(cmd))
123             self.logger.info(self.vapi.cli("show acl-plugin acl"))
124             self.logger.info(self.vapi.cli("show acl-plugin interface"))
125             self.logger.info(self.vapi.cli("show acl-plugin tables"))
126
127     def create_stream(self, src_ip_if, dst_ip_if, reverse, packet_sizes,
128                       is_ip6, expect_blocked, expect_established,
129                       add_extension_header, icmp_stateful=False):
130         pkts = []
131         rules = []
132         permit_rules = []
133         permit_and_reflect_rules = []
134         total_packet_count = 8
135         for i in range(0, total_packet_count):
136             modulo = (i//2) % 2
137             icmp_type_delta = i % 2
138             icmp_code = i
139             is_udp_packet = (modulo == 0)
140             if is_udp_packet and icmp_stateful:
141                 continue
142             is_reflectable_icmp = (icmp_stateful and icmp_type_delta == 0 and
143                                    not is_udp_packet)
144             is_reflected_icmp = is_reflectable_icmp and expect_established
145             can_reflect_this_packet = is_udp_packet or is_reflectable_icmp
146             is_permit = i % 2
147             remote_dst_index = i % len(dst_ip_if.remote_hosts)
148             remote_dst_host = dst_ip_if.remote_hosts[remote_dst_index]
149             if is_permit == 1:
150                 info = self.create_packet_info(src_ip_if, dst_ip_if)
151                 payload = self.info_to_payload(info)
152             else:
153                 to_be_blocked = False
154                 if (expect_blocked and not expect_established):
155                     to_be_blocked = True
156                 if (not can_reflect_this_packet):
157                     to_be_blocked = True
158                 if to_be_blocked:
159                     payload = "to be blocked"
160                 else:
161                     info = self.create_packet_info(src_ip_if, dst_ip_if)
162                     payload = self.info_to_payload(info)
163             if reverse:
164                 dst_mac = 'de:ad:00:00:00:00'
165                 src_mac = remote_dst_host._mac
166                 dst_ip6 = src_ip_if.remote_ip6
167                 src_ip6 = remote_dst_host.ip6
168                 dst_ip4 = src_ip_if.remote_ip4
169                 src_ip4 = remote_dst_host.ip4
170                 dst_l4 = 1234 + i
171                 src_l4 = 4321 + i
172             else:
173                 dst_mac = src_ip_if.local_mac
174                 src_mac = src_ip_if.remote_mac
175                 src_ip6 = src_ip_if.remote_ip6
176                 dst_ip6 = remote_dst_host.ip6
177                 src_ip4 = src_ip_if.remote_ip4
178                 dst_ip4 = remote_dst_host.ip4
179                 src_l4 = 1234 + i
180                 dst_l4 = 4321 + i
181             if is_reflected_icmp:
182                 icmp_type_delta = 1
183
184             # default ULP should be something we do not use in tests
185             ulp_l4 = TCP(sport=src_l4, dport=dst_l4)
186             # potentially a chain of protocols leading to ULP
187             ulp = ulp_l4
188
189             if is_udp_packet:
190                 if is_ip6:
191                     ulp_l4 = UDP(sport=src_l4, dport=dst_l4)
192                     if add_extension_header:
193                         # prepend some extension headers
194                         ulp = (IPv6ExtHdrRouting() / IPv6ExtHdrRouting() /
195                                IPv6ExtHdrFragment(offset=0, m=1) / ulp_l4)
196                         # uncomment below to test invalid ones
197                         # ulp = IPv6ExtHdrRouting(len = 200) / ulp_l4
198                     else:
199                         ulp = ulp_l4
200                     p = (Ether(dst=dst_mac, src=src_mac) /
201                          IPv6(src=src_ip6, dst=dst_ip6) /
202                          ulp /
203                          Raw(payload))
204                 else:
205                     ulp_l4 = UDP(sport=src_l4, dport=dst_l4)
206                     # IPv4 does not allow extension headers,
207                     # but we rather make it a first fragment
208                     flags = 1 if add_extension_header else 0
209                     ulp = ulp_l4
210                     p = (Ether(dst=dst_mac, src=src_mac) /
211                          IP(src=src_ip4, dst=dst_ip4, frag=0, flags=flags) /
212                          ulp /
213                          Raw(payload))
214             elif modulo == 1:
215                 if is_ip6:
216                     ulp_l4 = ICMPv6Unknown(type=128 + icmp_type_delta,
217                                            code=icmp_code)
218                     ulp = ulp_l4
219                     p = (Ether(dst=dst_mac, src=src_mac) /
220                          IPv6(src=src_ip6, dst=dst_ip6) /
221                          ulp /
222                          Raw(payload))
223                 else:
224                     ulp_l4 = ICMP(type=8 - 8*icmp_type_delta, code=icmp_code)
225                     ulp = ulp_l4
226                     p = (Ether(dst=dst_mac, src=src_mac) /
227                          IP(src=src_ip4, dst=dst_ip4) /
228                          ulp /
229                          Raw(payload))
230
231             if i % 2 == 1:
232                 info.data = p.copy()
233             size = packet_sizes[(i // 2) % len(packet_sizes)]
234             self.extend_packet(p, size)
235             pkts.append(p)
236
237             rule_family = AF_INET6 if p.haslayer(IPv6) else AF_INET
238             rule_prefix_len = 128 if p.haslayer(IPv6) else 32
239             rule_l3_layer = IPv6 if p.haslayer(IPv6) else IP
240
241             if p.haslayer(UDP):
242                 rule_l4_sport = p[UDP].sport
243                 rule_l4_dport = p[UDP].dport
244             else:
245                 if p.haslayer(ICMP):
246                     rule_l4_sport = p[ICMP].type
247                     rule_l4_dport = p[ICMP].code
248                 else:
249                     rule_l4_sport = p[ICMPv6Unknown].type
250                     rule_l4_dport = p[ICMPv6Unknown].code
251             if p.haslayer(IPv6):
252                 rule_l4_proto = ulp_l4.overload_fields[IPv6]['nh']
253             else:
254                 rule_l4_proto = p[IP].proto
255
256             new_rule = {
257                         'is_permit': is_permit,
258                         'is_ipv6': p.haslayer(IPv6),
259                         'src_ip_addr': inet_pton(rule_family,
260                                                  p[rule_l3_layer].src),
261                         'src_ip_prefix_len': rule_prefix_len,
262                         'dst_ip_addr': inet_pton(rule_family,
263                                                  p[rule_l3_layer].dst),
264                         'dst_ip_prefix_len': rule_prefix_len,
265                         'srcport_or_icmptype_first': rule_l4_sport,
266                         'srcport_or_icmptype_last': rule_l4_sport,
267                         'dstport_or_icmpcode_first': rule_l4_dport,
268                         'dstport_or_icmpcode_last': rule_l4_dport,
269                         'proto': rule_l4_proto,
270                        }
271             rules.append(new_rule)
272             new_rule_permit = new_rule.copy()
273             new_rule_permit['is_permit'] = 1
274             permit_rules.append(new_rule_permit)
275
276             new_rule_permit_and_reflect = new_rule.copy()
277             if can_reflect_this_packet:
278                 new_rule_permit_and_reflect['is_permit'] = 2
279             else:
280                 new_rule_permit_and_reflect['is_permit'] = is_permit
281
282             permit_and_reflect_rules.append(new_rule_permit_and_reflect)
283             self.logger.info("create_stream pkt#%d: %s" % (i, payload))
284
285         return {'stream': pkts,
286                 'rules': rules,
287                 'permit_rules': permit_rules,
288                 'permit_and_reflect_rules': permit_and_reflect_rules}
289
290     def verify_capture(self, dst_ip_if, src_ip_if, capture, reverse):
291         last_info = dict()
292         for i in self.interfaces:
293             last_info[i.sw_if_index] = None
294
295         dst_ip_sw_if_index = dst_ip_if.sw_if_index
296         return
297
298         for packet in capture:
299             l3 = IP if packet.haslayer(IP) else IPv6
300             ip = packet[l3]
301             if packet.haslayer(UDP):
302                 l4 = UDP
303             else:
304                 if packet.haslayer(ICMP):
305                     l4 = ICMP
306                 else:
307                     l4 = ICMPv6Unknown
308
309             # Scapy IPv6 stuff is too smart for its own good.
310             # So we do this and coerce the ICMP into unknown type
311             if packet.haslayer(UDP):
312                 data = scapy.compat.raw(packet[UDP][Raw])
313             else:
314                 if l3 == IP:
315                     data = scapy.compat.raw(ICMP(
316                         scapy.compat.raw(packet[l3].payload))[Raw])
317                 else:
318                     data = scapy.compat.raw(ICMPv6Unknown(
319                         scapy.compat.raw(packet[l3].payload)).msgbody)
320             udp_or_icmp = packet[l3].payload
321             payload_info = self.payload_to_info(data)
322             packet_index = payload_info.index
323
324             self.assertEqual(payload_info.dst, dst_ip_sw_if_index)
325
326             next_info = self.get_next_packet_info_for_interface2(
327                 payload_info.src, dst_ip_sw_if_index,
328                 last_info[payload_info.src])
329             last_info[payload_info.src] = next_info
330             self.assertTrue(next_info is not None)
331             self.assertEqual(packet_index, next_info.index)
332             saved_packet = next_info.data
333             self.assertTrue(next_info is not None)
334
335             # MAC: src, dst
336             if not reverse:
337                 self.assertEqual(packet.src, dst_ip_if.local_mac)
338                 host = dst_ip_if.host_by_mac(packet.dst)
339
340             # IP: src, dst
341             # self.assertEqual(ip.src, src_ip_if.remote_ip4)
342             if saved_packet is not None:
343                 self.assertEqual(ip.src, saved_packet[l3].src)
344                 self.assertEqual(ip.dst, saved_packet[l3].dst)
345                 if l4 == UDP:
346                     self.assertEqual(udp_or_icmp.sport, saved_packet[l4].sport)
347                     self.assertEqual(udp_or_icmp.dport, saved_packet[l4].dport)
348             else:
349                 print("Saved packet is none")
350             # self.assertEqual(ip.dst, host.ip4)
351
352             # UDP:
353
354     def applied_acl_shuffle(self, sw_if_index):
355         # first collect what ACLs are applied and what they look like
356         r = self.vapi.acl_interface_list_dump(sw_if_index=sw_if_index)
357         orig_applied_acls = r[0]
358
359         # we will collect these just to save and generate additional rulesets
360         orig_acls = []
361         for acl_num in orig_applied_acls.acls:
362             rr = self.vapi.acl_dump(acl_num)
363             orig_acls.append(rr[0])
364
365         # now create a list of all the rules in all ACLs
366         all_rules = []
367         for old_acl in orig_acls:
368             for rule in old_acl.r:
369                 all_rules.append(dict(rule._asdict()))
370
371         # Add a few ACLs made from shuffled rules
372         shuffle(all_rules)
373         reply = self.vapi.acl_add_replace(acl_index=4294967295,
374                                           r=all_rules[::2],
375                                           tag=b"shuffle 1. acl")
376         shuffle_acl_1 = reply.acl_index
377         shuffle(all_rules)
378         reply = self.vapi.acl_add_replace(acl_index=4294967295,
379                                           r=all_rules[::3],
380                                           tag=b"shuffle 2. acl")
381         shuffle_acl_2 = reply.acl_index
382         shuffle(all_rules)
383         reply = self.vapi.acl_add_replace(acl_index=4294967295,
384                                           r=all_rules[::2],
385                                           tag=b"shuffle 3. acl")
386         shuffle_acl_3 = reply.acl_index
387
388         # apply the shuffle ACLs in front
389         input_acls = [shuffle_acl_1, shuffle_acl_2]
390         output_acls = [shuffle_acl_1, shuffle_acl_2]
391
392         # add the currently applied ACLs
393         n_input = orig_applied_acls.n_input
394         input_acls.extend(orig_applied_acls.acls[:n_input])
395         output_acls.extend(orig_applied_acls.acls[n_input:])
396
397         # and the trailing shuffle ACL(s)
398         input_acls.extend([shuffle_acl_3])
399         output_acls.extend([shuffle_acl_3])
400
401         # set the interface ACL list to the result
402         self.vapi.acl_interface_set_acl_list(sw_if_index=sw_if_index,
403                                              n_input=len(input_acls),
404                                              acls=input_acls + output_acls)
405         # change the ACLs a few times
406         for i in range(1, 10):
407             shuffle(all_rules)
408             reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_1,
409                                               r=all_rules[::1+(i % 2)],
410                                               tag=b"shuffle 1. acl")
411             shuffle(all_rules)
412             reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_2,
413                                               r=all_rules[::1+(i % 3)],
414                                               tag=b"shuffle 2. acl")
415             shuffle(all_rules)
416             reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_2,
417                                               r=all_rules[::1+(i % 5)],
418                                               tag=b"shuffle 3. acl")
419
420         # restore to how it was before and clean up
421         self.vapi.acl_interface_set_acl_list(sw_if_index=sw_if_index,
422                                              n_input=orig_applied_acls.n_input,
423                                              acls=orig_applied_acls.acls)
424         reply = self.vapi.acl_del(acl_index=shuffle_acl_1)
425         reply = self.vapi.acl_del(acl_index=shuffle_acl_2)
426         reply = self.vapi.acl_del(acl_index=shuffle_acl_3)
427
428     def create_acls_for_a_stream(self, stream_dict,
429                                  test_l2_action, is_reflect):
430         r = stream_dict['rules']
431         r_permit = stream_dict['permit_rules']
432         r_permit_reflect = stream_dict['permit_and_reflect_rules']
433         r_action = r_permit_reflect if is_reflect else r
434         reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_action,
435                                           tag=b"act. acl")
436         action_acl_index = reply.acl_index
437         reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_permit,
438                                           tag=b"perm. acl")
439         permit_acl_index = reply.acl_index
440         return {'L2': action_acl_index if test_l2_action else permit_acl_index,
441                 'L3': permit_acl_index if test_l2_action else action_acl_index,
442                 'permit': permit_acl_index, 'action': action_acl_index}
443
444     def apply_acl_ip46_x_to_y(self, bridged_to_routed, test_l2_deny,
445                               is_ip6, is_reflect, add_eh):
446         """ Apply the ACLs
447         """
448         self.reset_packet_infos()
449         stream_dict = self.create_stream(
450                                          self.pg2, self.loop0,
451                                          bridged_to_routed,
452                                          self.pg_if_packet_sizes, is_ip6,
453                                          not is_reflect, False, add_eh)
454         stream = stream_dict['stream']
455         acl_idx = self.create_acls_for_a_stream(stream_dict, test_l2_deny,
456                                                 is_reflect)
457         n_input_l3 = 0 if bridged_to_routed else 1
458         n_input_l2 = 1 if bridged_to_routed else 0
459         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg2.sw_if_index,
460                                              n_input=n_input_l3,
461                                              acls=[acl_idx['L3']])
462         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg0.sw_if_index,
463                                              n_input=n_input_l2,
464                                              acls=[acl_idx['L2']])
465         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
466                                              n_input=n_input_l2,
467                                              acls=[acl_idx['L2']])
468         self.applied_acl_shuffle(self.pg0.sw_if_index)
469         self.applied_acl_shuffle(self.pg2.sw_if_index)
470
471     def apply_acl_ip46_both_directions_reflect(self,
472                                                primary_is_bridged_to_routed,
473                                                reflect_on_l2, is_ip6, add_eh,
474                                                stateful_icmp):
475         primary_is_routed_to_bridged = not primary_is_bridged_to_routed
476         self.reset_packet_infos()
477         stream_dict_fwd = self.create_stream(self.pg2, self.loop0,
478                                              primary_is_bridged_to_routed,
479                                              self.pg_if_packet_sizes, is_ip6,
480                                              False, False, add_eh,
481                                              stateful_icmp)
482         acl_idx_fwd = self.create_acls_for_a_stream(stream_dict_fwd,
483                                                     reflect_on_l2, True)
484
485         stream_dict_rev = self.create_stream(self.pg2, self.loop0,
486                                              not primary_is_bridged_to_routed,
487                                              self.pg_if_packet_sizes, is_ip6,
488                                              True, True, add_eh, stateful_icmp)
489         # We want the primary action to be "deny" rather than reflect
490         acl_idx_rev = self.create_acls_for_a_stream(stream_dict_rev,
491                                                     reflect_on_l2, False)
492
493         if primary_is_bridged_to_routed:
494             inbound_l2_acl = acl_idx_fwd['L2']
495         else:
496             inbound_l2_acl = acl_idx_rev['L2']
497
498         if primary_is_routed_to_bridged:
499             outbound_l2_acl = acl_idx_fwd['L2']
500         else:
501             outbound_l2_acl = acl_idx_rev['L2']
502
503         if primary_is_routed_to_bridged:
504             inbound_l3_acl = acl_idx_fwd['L3']
505         else:
506             inbound_l3_acl = acl_idx_rev['L3']
507
508         if primary_is_bridged_to_routed:
509             outbound_l3_acl = acl_idx_fwd['L3']
510         else:
511             outbound_l3_acl = acl_idx_rev['L3']
512
513         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg2.sw_if_index,
514                                              n_input=1,
515                                              acls=[inbound_l3_acl,
516                                                    outbound_l3_acl])
517         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg0.sw_if_index,
518                                              n_input=1,
519                                              acls=[inbound_l2_acl,
520                                                    outbound_l2_acl])
521         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
522                                              n_input=1,
523                                              acls=[inbound_l2_acl,
524                                                    outbound_l2_acl])
525         self.applied_acl_shuffle(self.pg0.sw_if_index)
526         self.applied_acl_shuffle(self.pg2.sw_if_index)
527
528     def apply_acl_ip46_routed_to_bridged(self, test_l2_deny, is_ip6,
529                                          is_reflect, add_eh):
530         self.apply_acl_ip46_x_to_y(False, test_l2_deny, is_ip6,
531                                    is_reflect, add_eh)
532
533     def apply_acl_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
534                                          is_reflect, add_eh):
535         self.apply_acl_ip46_x_to_y(True, test_l2_deny, is_ip6,
536                                    is_reflect, add_eh)
537
538     def run_traffic_ip46_x_to_y(self, bridged_to_routed,
539                                 test_l2_deny, is_ip6,
540                                 is_reflect, is_established, add_eh,
541                                 stateful_icmp=False):
542         self.reset_packet_infos()
543         stream_dict = self.create_stream(self.pg2, self.loop0,
544                                          bridged_to_routed,
545                                          self.pg_if_packet_sizes, is_ip6,
546                                          not is_reflect, is_established,
547                                          add_eh, stateful_icmp)
548         stream = stream_dict['stream']
549
550         tx_if = self.pg0 if bridged_to_routed else self.pg2
551         rx_if = self.pg2 if bridged_to_routed else self.pg0
552
553         tx_if.add_stream(stream)
554         self.pg_enable_capture(self.pg_interfaces)
555         self.pg_start()
556         packet_count = self.get_packet_count_for_if_idx(self.loop0.sw_if_index)
557         rcvd1 = rx_if.get_capture(packet_count)
558         self.verify_capture(self.loop0, self.pg2, rcvd1, bridged_to_routed)
559
560     def run_traffic_ip46_routed_to_bridged(self, test_l2_deny, is_ip6,
561                                            is_reflect, is_established, add_eh,
562                                            stateful_icmp=False):
563         self.run_traffic_ip46_x_to_y(False, test_l2_deny, is_ip6,
564                                      is_reflect, is_established, add_eh,
565                                      stateful_icmp)
566
567     def run_traffic_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
568                                            is_reflect, is_established, add_eh,
569                                            stateful_icmp=False):
570         self.run_traffic_ip46_x_to_y(True, test_l2_deny, is_ip6,
571                                      is_reflect, is_established, add_eh,
572                                      stateful_icmp)
573
574     def run_test_ip46_routed_to_bridged(self, test_l2_deny,
575                                         is_ip6, is_reflect, add_eh):
576         self.apply_acl_ip46_routed_to_bridged(test_l2_deny,
577                                               is_ip6, is_reflect, add_eh)
578         self.run_traffic_ip46_routed_to_bridged(test_l2_deny, is_ip6,
579                                                 is_reflect, False, add_eh)
580
581     def run_test_ip46_bridged_to_routed(self, test_l2_deny,
582                                         is_ip6, is_reflect, add_eh):
583         self.apply_acl_ip46_bridged_to_routed(test_l2_deny,
584                                               is_ip6, is_reflect, add_eh)
585         self.run_traffic_ip46_bridged_to_routed(test_l2_deny, is_ip6,
586                                                 is_reflect, False, add_eh)
587
588     def run_test_ip46_routed_to_bridged_and_back(self, test_l2_action,
589                                                  is_ip6, add_eh,
590                                                  stateful_icmp=False):
591         self.apply_acl_ip46_both_directions_reflect(False, test_l2_action,
592                                                     is_ip6, add_eh,
593                                                     stateful_icmp)
594         self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
595                                                 True, False, add_eh,
596                                                 stateful_icmp)
597         self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
598                                                 False, True, add_eh,
599                                                 stateful_icmp)
600
601     def run_test_ip46_bridged_to_routed_and_back(self, test_l2_action,
602                                                  is_ip6, add_eh,
603                                                  stateful_icmp=False):
604         self.apply_acl_ip46_both_directions_reflect(True, test_l2_action,
605                                                     is_ip6, add_eh,
606                                                     stateful_icmp)
607         self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
608                                                 True, False, add_eh,
609                                                 stateful_icmp)
610         self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
611                                                 False, True, add_eh,
612                                                 stateful_icmp)
613
614     def test_0000_ip6_irb_1(self):
615         """ ACL plugin prepare"""
616         if not self.vpp_dead:
617             cmd = "set acl-plugin session timeout udp idle 2000"
618             self.logger.info(self.vapi.ppcli(cmd))
619             # uncomment to not skip past the routing header
620             # and watch the EH tests fail
621             # self.logger.info(self.vapi.ppcli(
622             #    "set acl-plugin skip-ipv6-extension-header 43 0"))
623             # uncomment to test the session limit (stateful tests will fail)
624             # self.logger.info(self.vapi.ppcli(
625             #    "set acl-plugin session table max-entries 1"))
626             # new datapath is the default, but just in case
627             # self.logger.info(self.vapi.ppcli(
628             #    "set acl-plugin l2-datapath new"))
629             # If you want to see some tests fail, uncomment the next line
630             # self.logger.info(self.vapi.ppcli(
631             #    "set acl-plugin l2-datapath old"))
632
633     def test_0001_ip6_irb_1(self):
634         """ ACL IPv6 routed -> bridged, L2 ACL deny"""
635         self.run_test_ip46_routed_to_bridged(True, True, False,
636                                              self.WITHOUT_EH)
637
638     def test_0002_ip6_irb_1(self):
639         """ ACL IPv6 routed -> bridged, L3 ACL deny"""
640         self.run_test_ip46_routed_to_bridged(False, True, False,
641                                              self.WITHOUT_EH)
642
643     def test_0003_ip4_irb_1(self):
644         """ ACL IPv4 routed -> bridged, L2 ACL deny"""
645         self.run_test_ip46_routed_to_bridged(True, False, False,
646                                              self.WITHOUT_EH)
647
648     def test_0004_ip4_irb_1(self):
649         """ ACL IPv4 routed -> bridged, L3 ACL deny"""
650         self.run_test_ip46_routed_to_bridged(False, False, False,
651                                              self.WITHOUT_EH)
652
653     def test_0005_ip6_irb_1(self):
654         """ ACL IPv6 bridged -> routed, L2 ACL deny """
655         self.run_test_ip46_bridged_to_routed(True, True, False,
656                                              self.WITHOUT_EH)
657
658     def test_0006_ip6_irb_1(self):
659         """ ACL IPv6 bridged -> routed, L3 ACL deny """
660         self.run_test_ip46_bridged_to_routed(False, True, False,
661                                              self.WITHOUT_EH)
662
663     def test_0007_ip6_irb_1(self):
664         """ ACL IPv4 bridged -> routed, L2 ACL deny """
665         self.run_test_ip46_bridged_to_routed(True, False, False,
666                                              self.WITHOUT_EH)
667
668     def test_0008_ip6_irb_1(self):
669         """ ACL IPv4 bridged -> routed, L3 ACL deny """
670         self.run_test_ip46_bridged_to_routed(False, False, False,
671                                              self.WITHOUT_EH)
672
673     # Stateful ACL tests
674     def test_0101_ip6_irb_1(self):
675         """ ACL IPv6 routed -> bridged, L2 ACL permit+reflect"""
676         self.run_test_ip46_routed_to_bridged_and_back(True, True,
677                                                       self.WITHOUT_EH)
678
679     def test_0102_ip6_irb_1(self):
680         """ ACL IPv6 bridged -> routed, L2 ACL permit+reflect"""
681         self.run_test_ip46_bridged_to_routed_and_back(True, True,
682                                                       self.WITHOUT_EH)
683
684     def test_0103_ip6_irb_1(self):
685         """ ACL IPv4 routed -> bridged, L2 ACL permit+reflect"""
686         self.run_test_ip46_routed_to_bridged_and_back(True, False,
687                                                       self.WITHOUT_EH)
688
689     def test_0104_ip6_irb_1(self):
690         """ ACL IPv4 bridged -> routed, L2 ACL permit+reflect"""
691         self.run_test_ip46_bridged_to_routed_and_back(True, False,
692                                                       self.WITHOUT_EH)
693
694     def test_0111_ip6_irb_1(self):
695         """ ACL IPv6 routed -> bridged, L3 ACL permit+reflect"""
696         self.run_test_ip46_routed_to_bridged_and_back(False, True,
697                                                       self.WITHOUT_EH)
698
699     def test_0112_ip6_irb_1(self):
700         """ ACL IPv6 bridged -> routed, L3 ACL permit+reflect"""
701         self.run_test_ip46_bridged_to_routed_and_back(False, True,
702                                                       self.WITHOUT_EH)
703
704     def test_0113_ip6_irb_1(self):
705         """ ACL IPv4 routed -> bridged, L3 ACL permit+reflect"""
706         self.run_test_ip46_routed_to_bridged_and_back(False, False,
707                                                       self.WITHOUT_EH)
708
709     def test_0114_ip6_irb_1(self):
710         """ ACL IPv4 bridged -> routed, L3 ACL permit+reflect"""
711         self.run_test_ip46_bridged_to_routed_and_back(False, False,
712                                                       self.WITHOUT_EH)
713
714     # A block of tests with extension headers
715
716     def test_1001_ip6_irb_1(self):
717         """ ACL IPv6+EH routed -> bridged, L2 ACL deny"""
718         self.run_test_ip46_routed_to_bridged(True, True, False,
719                                              self.WITH_EH)
720
721     def test_1002_ip6_irb_1(self):
722         """ ACL IPv6+EH routed -> bridged, L3 ACL deny"""
723         self.run_test_ip46_routed_to_bridged(False, True, False,
724                                              self.WITH_EH)
725
726     def test_1005_ip6_irb_1(self):
727         """ ACL IPv6+EH bridged -> routed, L2 ACL deny """
728         self.run_test_ip46_bridged_to_routed(True, True, False,
729                                              self.WITH_EH)
730
731     def test_1006_ip6_irb_1(self):
732         """ ACL IPv6+EH bridged -> routed, L3 ACL deny """
733         self.run_test_ip46_bridged_to_routed(False, True, False,
734                                              self.WITH_EH)
735
736     def test_1101_ip6_irb_1(self):
737         """ ACL IPv6+EH routed -> bridged, L2 ACL permit+reflect"""
738         self.run_test_ip46_routed_to_bridged_and_back(True, True,
739                                                       self.WITH_EH)
740
741     def test_1102_ip6_irb_1(self):
742         """ ACL IPv6+EH bridged -> routed, L2 ACL permit+reflect"""
743         self.run_test_ip46_bridged_to_routed_and_back(True, True,
744                                                       self.WITH_EH)
745
746     def test_1111_ip6_irb_1(self):
747         """ ACL IPv6+EH routed -> bridged, L3 ACL permit+reflect"""
748         self.run_test_ip46_routed_to_bridged_and_back(False, True,
749                                                       self.WITH_EH)
750
751     def test_1112_ip6_irb_1(self):
752         """ ACL IPv6+EH bridged -> routed, L3 ACL permit+reflect"""
753         self.run_test_ip46_bridged_to_routed_and_back(False, True,
754                                                       self.WITH_EH)
755
756     # IPv4 with "MF" bit set
757
758     def test_1201_ip6_irb_1(self):
759         """ ACL IPv4+MF routed -> bridged, L2 ACL deny"""
760         self.run_test_ip46_routed_to_bridged(True, False, False,
761                                              self.WITH_EH)
762
763     def test_1202_ip6_irb_1(self):
764         """ ACL IPv4+MF routed -> bridged, L3 ACL deny"""
765         self.run_test_ip46_routed_to_bridged(False, False, False,
766                                              self.WITH_EH)
767
768     def test_1205_ip6_irb_1(self):
769         """ ACL IPv4+MF bridged -> routed, L2 ACL deny """
770         self.run_test_ip46_bridged_to_routed(True, False, False,
771                                              self.WITH_EH)
772
773     def test_1206_ip6_irb_1(self):
774         """ ACL IPv4+MF bridged -> routed, L3 ACL deny """
775         self.run_test_ip46_bridged_to_routed(False, False, False,
776                                              self.WITH_EH)
777
778     def test_1301_ip6_irb_1(self):
779         """ ACL IPv4+MF routed -> bridged, L2 ACL permit+reflect"""
780         self.run_test_ip46_routed_to_bridged_and_back(True, False,
781                                                       self.WITH_EH)
782
783     def test_1302_ip6_irb_1(self):
784         """ ACL IPv4+MF bridged -> routed, L2 ACL permit+reflect"""
785         self.run_test_ip46_bridged_to_routed_and_back(True, False,
786                                                       self.WITH_EH)
787
788     def test_1311_ip6_irb_1(self):
789         """ ACL IPv4+MF routed -> bridged, L3 ACL permit+reflect"""
790         self.run_test_ip46_routed_to_bridged_and_back(False, False,
791                                                       self.WITH_EH)
792
793     def test_1312_ip6_irb_1(self):
794         """ ACL IPv4+MF bridged -> routed, L3 ACL permit+reflect"""
795         self.run_test_ip46_bridged_to_routed_and_back(False, False,
796                                                       self.WITH_EH)
797     # Stateful ACL tests with stateful ICMP
798
799     def test_1401_ip6_irb_1(self):
800         """ IPv6 routed -> bridged, L2 ACL permit+reflect, ICMP reflect"""
801         self.run_test_ip46_routed_to_bridged_and_back(True, True,
802                                                       self.WITHOUT_EH,
803                                                       self.STATEFUL_ICMP)
804
805     def test_1402_ip6_irb_1(self):
806         """ IPv6 bridged -> routed, L2 ACL permit+reflect, ICMP reflect"""
807         self.run_test_ip46_bridged_to_routed_and_back(True, True,
808                                                       self.WITHOUT_EH,
809                                                       self.STATEFUL_ICMP)
810
811     def test_1403_ip4_irb_1(self):
812         """ IPv4 routed -> bridged, L2 ACL permit+reflect, ICMP reflect"""
813         self.run_test_ip46_routed_to_bridged_and_back(True, False,
814                                                       self.WITHOUT_EH,
815                                                       self.STATEFUL_ICMP)
816
817     def test_1404_ip4_irb_1(self):
818         """ IPv4 bridged -> routed, L2 ACL permit+reflect, ICMP reflect"""
819         self.run_test_ip46_bridged_to_routed_and_back(True, False,
820                                                       self.WITHOUT_EH,
821                                                       self.STATEFUL_ICMP)
822
823     def test_1411_ip6_irb_1(self):
824         """ IPv6 routed -> bridged, L3 ACL permit+reflect, ICMP reflect"""
825         self.run_test_ip46_routed_to_bridged_and_back(False, True,
826                                                       self.WITHOUT_EH,
827                                                       self.STATEFUL_ICMP)
828
829     def test_1412_ip6_irb_1(self):
830         """ IPv6 bridged -> routed, L3 ACL permit+reflect, ICMP reflect"""
831         self.run_test_ip46_bridged_to_routed_and_back(False, True,
832                                                       self.WITHOUT_EH,
833                                                       self.STATEFUL_ICMP)
834
835     def test_1413_ip4_irb_1(self):
836         """ IPv4 routed -> bridged, L3 ACL permit+reflect, ICMP reflect"""
837         self.run_test_ip46_routed_to_bridged_and_back(False, False,
838                                                       self.WITHOUT_EH,
839                                                       self.STATEFUL_ICMP)
840
841     def test_1414_ip4_irb_1(self):
842         """ IPv4 bridged -> routed, L3 ACL permit+reflect, ICMP reflect"""
843         self.run_test_ip46_bridged_to_routed_and_back(False, False,
844                                                       self.WITHOUT_EH,
845                                                       self.STATEFUL_ICMP)
846
847
848 if __name__ == '__main__':
849     unittest.main(testRunner=VppTestRunner)