0c846e7329c3bf23700e060381a1aeb420b5f8c0
[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_l2 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             rx_sw_if_index=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(rx_sw_if_index=cls.pg0.sw_if_index,
78                                             bd_id=cls.bd_id)
79         cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=cls.pg1.sw_if_index,
80                                             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
297         for packet in capture:
298             l3 = IP if packet.haslayer(IP) else IPv6
299             ip = packet[l3]
300             if packet.haslayer(UDP):
301                 l4 = UDP
302             else:
303                 if packet.haslayer(ICMP):
304                     l4 = ICMP
305                 else:
306                     l4 = ICMPv6Unknown
307
308             # Scapy IPv6 stuff is too smart for its own good.
309             # So we do this and coerce the ICMP into unknown type
310             if packet.haslayer(UDP):
311                 data = scapy.compat.raw(packet[UDP][Raw])
312             else:
313                 if l3 == IP:
314                     data = scapy.compat.raw(ICMP(
315                         scapy.compat.raw(packet[l3].payload))[Raw])
316                 else:
317                     data = scapy.compat.raw(ICMPv6Unknown(
318                         scapy.compat.raw(packet[l3].payload)).msgbody)
319             udp_or_icmp = packet[l3].payload
320             data_obj = Raw(data)
321             # FIXME: make framework believe we are on object
322             payload_info = self.payload_to_info(data_obj)
323             packet_index = payload_info.index
324
325             self.assertEqual(payload_info.dst, dst_ip_sw_if_index)
326
327             next_info = self.get_next_packet_info_for_interface2(
328                 payload_info.src, dst_ip_sw_if_index,
329                 last_info[payload_info.src])
330             last_info[payload_info.src] = next_info
331             self.assertTrue(next_info is not None)
332             self.assertEqual(packet_index, next_info.index)
333             saved_packet = next_info.data
334             self.assertTrue(next_info is not None)
335
336             # MAC: src, dst
337             if not reverse:
338                 self.assertEqual(packet.src, dst_ip_if.local_mac)
339                 host = dst_ip_if.host_by_mac(packet.dst)
340
341             # IP: src, dst
342             # self.assertEqual(ip.src, src_ip_if.remote_ip4)
343             if saved_packet is not None:
344                 self.assertEqual(ip.src, saved_packet[l3].src)
345                 self.assertEqual(ip.dst, saved_packet[l3].dst)
346                 if l4 == UDP:
347                     self.assertEqual(udp_or_icmp.sport, saved_packet[l4].sport)
348                     self.assertEqual(udp_or_icmp.dport, saved_packet[l4].dport)
349             # self.assertEqual(ip.dst, host.ip4)
350
351             # UDP:
352
353     def applied_acl_shuffle(self, sw_if_index):
354         # first collect what ACLs are applied and what they look like
355         r = self.vapi.acl_interface_list_dump(sw_if_index=sw_if_index)
356         orig_applied_acls = r[0]
357
358         # we will collect these just to save and generate additional rulesets
359         orig_acls = []
360         for acl_num in orig_applied_acls.acls:
361             rr = self.vapi.acl_dump(acl_num)
362             orig_acls.append(rr[0])
363
364         # now create a list of all the rules in all ACLs
365         all_rules = []
366         for old_acl in orig_acls:
367             for rule in old_acl.r:
368                 all_rules.append(dict(rule._asdict()))
369
370         # Add a few ACLs made from shuffled rules
371         shuffle(all_rules)
372         reply = self.vapi.acl_add_replace(acl_index=4294967295,
373                                           r=all_rules[::2],
374                                           tag=b"shuffle 1. acl")
375         shuffle_acl_1 = reply.acl_index
376         shuffle(all_rules)
377         reply = self.vapi.acl_add_replace(acl_index=4294967295,
378                                           r=all_rules[::3],
379                                           tag=b"shuffle 2. acl")
380         shuffle_acl_2 = reply.acl_index
381         shuffle(all_rules)
382         reply = self.vapi.acl_add_replace(acl_index=4294967295,
383                                           r=all_rules[::2],
384                                           tag=b"shuffle 3. acl")
385         shuffle_acl_3 = reply.acl_index
386
387         # apply the shuffle ACLs in front
388         input_acls = [shuffle_acl_1, shuffle_acl_2]
389         output_acls = [shuffle_acl_1, shuffle_acl_2]
390
391         # add the currently applied ACLs
392         n_input = orig_applied_acls.n_input
393         input_acls.extend(orig_applied_acls.acls[:n_input])
394         output_acls.extend(orig_applied_acls.acls[n_input:])
395
396         # and the trailing shuffle ACL(s)
397         input_acls.extend([shuffle_acl_3])
398         output_acls.extend([shuffle_acl_3])
399
400         # set the interface ACL list to the result
401         self.vapi.acl_interface_set_acl_list(sw_if_index=sw_if_index,
402                                              n_input=len(input_acls),
403                                              acls=input_acls + output_acls)
404         # change the ACLs a few times
405         for i in range(1, 10):
406             shuffle(all_rules)
407             reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_1,
408                                               r=all_rules[::1+(i % 2)],
409                                               tag=b"shuffle 1. acl")
410             shuffle(all_rules)
411             reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_2,
412                                               r=all_rules[::1+(i % 3)],
413                                               tag=b"shuffle 2. acl")
414             shuffle(all_rules)
415             reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_2,
416                                               r=all_rules[::1+(i % 5)],
417                                               tag=b"shuffle 3. acl")
418
419         # restore to how it was before and clean up
420         self.vapi.acl_interface_set_acl_list(sw_if_index=sw_if_index,
421                                              n_input=orig_applied_acls.n_input,
422                                              acls=orig_applied_acls.acls)
423         reply = self.vapi.acl_del(acl_index=shuffle_acl_1)
424         reply = self.vapi.acl_del(acl_index=shuffle_acl_2)
425         reply = self.vapi.acl_del(acl_index=shuffle_acl_3)
426
427     def create_acls_for_a_stream(self, stream_dict,
428                                  test_l2_action, is_reflect):
429         r = stream_dict['rules']
430         r_permit = stream_dict['permit_rules']
431         r_permit_reflect = stream_dict['permit_and_reflect_rules']
432         r_action = r_permit_reflect if is_reflect else r
433         reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_action,
434                                           tag=b"act. acl")
435         action_acl_index = reply.acl_index
436         reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_permit,
437                                           tag=b"perm. acl")
438         permit_acl_index = reply.acl_index
439         return {'L2': action_acl_index if test_l2_action else permit_acl_index,
440                 'L3': permit_acl_index if test_l2_action else action_acl_index,
441                 'permit': permit_acl_index, 'action': action_acl_index}
442
443     def apply_acl_ip46_x_to_y(self, bridged_to_routed, test_l2_deny,
444                               is_ip6, is_reflect, add_eh):
445         """ Apply the ACLs
446         """
447         self.reset_packet_infos()
448         stream_dict = self.create_stream(
449                                          self.pg2, self.loop0,
450                                          bridged_to_routed,
451                                          self.pg_if_packet_sizes, is_ip6,
452                                          not is_reflect, False, add_eh)
453         stream = stream_dict['stream']
454         acl_idx = self.create_acls_for_a_stream(stream_dict, test_l2_deny,
455                                                 is_reflect)
456         n_input_l3 = 0 if bridged_to_routed else 1
457         n_input_l2 = 1 if bridged_to_routed else 0
458         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg2.sw_if_index,
459                                              n_input=n_input_l3,
460                                              acls=[acl_idx['L3']])
461         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg0.sw_if_index,
462                                              n_input=n_input_l2,
463                                              acls=[acl_idx['L2']])
464         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
465                                              n_input=n_input_l2,
466                                              acls=[acl_idx['L2']])
467         self.applied_acl_shuffle(self.pg0.sw_if_index)
468         self.applied_acl_shuffle(self.pg2.sw_if_index)
469
470     def apply_acl_ip46_both_directions_reflect(self,
471                                                primary_is_bridged_to_routed,
472                                                reflect_on_l2, is_ip6, add_eh,
473                                                stateful_icmp):
474         primary_is_routed_to_bridged = not primary_is_bridged_to_routed
475         self.reset_packet_infos()
476         stream_dict_fwd = self.create_stream(self.pg2, self.loop0,
477                                              primary_is_bridged_to_routed,
478                                              self.pg_if_packet_sizes, is_ip6,
479                                              False, False, add_eh,
480                                              stateful_icmp)
481         acl_idx_fwd = self.create_acls_for_a_stream(stream_dict_fwd,
482                                                     reflect_on_l2, True)
483
484         stream_dict_rev = self.create_stream(self.pg2, self.loop0,
485                                              not primary_is_bridged_to_routed,
486                                              self.pg_if_packet_sizes, is_ip6,
487                                              True, True, add_eh, stateful_icmp)
488         # We want the primary action to be "deny" rather than reflect
489         acl_idx_rev = self.create_acls_for_a_stream(stream_dict_rev,
490                                                     reflect_on_l2, False)
491
492         if primary_is_bridged_to_routed:
493             inbound_l2_acl = acl_idx_fwd['L2']
494         else:
495             inbound_l2_acl = acl_idx_rev['L2']
496
497         if primary_is_routed_to_bridged:
498             outbound_l2_acl = acl_idx_fwd['L2']
499         else:
500             outbound_l2_acl = acl_idx_rev['L2']
501
502         if primary_is_routed_to_bridged:
503             inbound_l3_acl = acl_idx_fwd['L3']
504         else:
505             inbound_l3_acl = acl_idx_rev['L3']
506
507         if primary_is_bridged_to_routed:
508             outbound_l3_acl = acl_idx_fwd['L3']
509         else:
510             outbound_l3_acl = acl_idx_rev['L3']
511
512         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg2.sw_if_index,
513                                              n_input=1,
514                                              acls=[inbound_l3_acl,
515                                                    outbound_l3_acl])
516         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg0.sw_if_index,
517                                              n_input=1,
518                                              acls=[inbound_l2_acl,
519                                                    outbound_l2_acl])
520         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
521                                              n_input=1,
522                                              acls=[inbound_l2_acl,
523                                                    outbound_l2_acl])
524         self.applied_acl_shuffle(self.pg0.sw_if_index)
525         self.applied_acl_shuffle(self.pg2.sw_if_index)
526
527     def apply_acl_ip46_routed_to_bridged(self, test_l2_deny, is_ip6,
528                                          is_reflect, add_eh):
529         self.apply_acl_ip46_x_to_y(False, test_l2_deny, is_ip6,
530                                    is_reflect, add_eh)
531
532     def apply_acl_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
533                                          is_reflect, add_eh):
534         self.apply_acl_ip46_x_to_y(True, test_l2_deny, is_ip6,
535                                    is_reflect, add_eh)
536
537     def run_traffic_ip46_x_to_y(self, bridged_to_routed,
538                                 test_l2_deny, is_ip6,
539                                 is_reflect, is_established, add_eh,
540                                 stateful_icmp=False):
541         self.reset_packet_infos()
542         stream_dict = self.create_stream(self.pg2, self.loop0,
543                                          bridged_to_routed,
544                                          self.pg_if_packet_sizes, is_ip6,
545                                          not is_reflect, is_established,
546                                          add_eh, stateful_icmp)
547         stream = stream_dict['stream']
548
549         tx_if = self.pg0 if bridged_to_routed else self.pg2
550         rx_if = self.pg2 if bridged_to_routed else self.pg0
551
552         tx_if.add_stream(stream)
553         self.pg_enable_capture(self.pg_interfaces)
554         self.pg_start()
555         packet_count = self.get_packet_count_for_if_idx(self.loop0.sw_if_index)
556         rcvd1 = rx_if.get_capture(packet_count)
557         self.verify_capture(self.loop0, self.pg2, rcvd1, bridged_to_routed)
558
559     def run_traffic_ip46_routed_to_bridged(self, test_l2_deny, is_ip6,
560                                            is_reflect, is_established, add_eh,
561                                            stateful_icmp=False):
562         self.run_traffic_ip46_x_to_y(False, test_l2_deny, is_ip6,
563                                      is_reflect, is_established, add_eh,
564                                      stateful_icmp)
565
566     def run_traffic_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
567                                            is_reflect, is_established, add_eh,
568                                            stateful_icmp=False):
569         self.run_traffic_ip46_x_to_y(True, test_l2_deny, is_ip6,
570                                      is_reflect, is_established, add_eh,
571                                      stateful_icmp)
572
573     def run_test_ip46_routed_to_bridged(self, test_l2_deny,
574                                         is_ip6, is_reflect, add_eh):
575         self.apply_acl_ip46_routed_to_bridged(test_l2_deny,
576                                               is_ip6, is_reflect, add_eh)
577         self.run_traffic_ip46_routed_to_bridged(test_l2_deny, is_ip6,
578                                                 is_reflect, False, add_eh)
579
580     def run_test_ip46_bridged_to_routed(self, test_l2_deny,
581                                         is_ip6, is_reflect, add_eh):
582         self.apply_acl_ip46_bridged_to_routed(test_l2_deny,
583                                               is_ip6, is_reflect, add_eh)
584         self.run_traffic_ip46_bridged_to_routed(test_l2_deny, is_ip6,
585                                                 is_reflect, False, add_eh)
586
587     def run_test_ip46_routed_to_bridged_and_back(self, test_l2_action,
588                                                  is_ip6, add_eh,
589                                                  stateful_icmp=False):
590         self.apply_acl_ip46_both_directions_reflect(False, test_l2_action,
591                                                     is_ip6, add_eh,
592                                                     stateful_icmp)
593         self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
594                                                 True, False, add_eh,
595                                                 stateful_icmp)
596         self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
597                                                 False, True, add_eh,
598                                                 stateful_icmp)
599
600     def run_test_ip46_bridged_to_routed_and_back(self, test_l2_action,
601                                                  is_ip6, add_eh,
602                                                  stateful_icmp=False):
603         self.apply_acl_ip46_both_directions_reflect(True, test_l2_action,
604                                                     is_ip6, add_eh,
605                                                     stateful_icmp)
606         self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
607                                                 True, False, add_eh,
608                                                 stateful_icmp)
609         self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
610                                                 False, True, add_eh,
611                                                 stateful_icmp)
612
613     def test_0000_ip6_irb_1(self):
614         """ ACL plugin prepare"""
615         if not self.vpp_dead:
616             cmd = "set acl-plugin session timeout udp idle 2000"
617             self.logger.info(self.vapi.ppcli(cmd))
618             # uncomment to not skip past the routing header
619             # and watch the EH tests fail
620             # self.logger.info(self.vapi.ppcli(
621             #    "set acl-plugin skip-ipv6-extension-header 43 0"))
622             # uncomment to test the session limit (stateful tests will fail)
623             # self.logger.info(self.vapi.ppcli(
624             #    "set acl-plugin session table max-entries 1"))
625             # new datapath is the default, but just in case
626             # self.logger.info(self.vapi.ppcli(
627             #    "set acl-plugin l2-datapath new"))
628             # If you want to see some tests fail, uncomment the next line
629             # self.logger.info(self.vapi.ppcli(
630             #    "set acl-plugin l2-datapath old"))
631
632     def test_0001_ip6_irb_1(self):
633         """ ACL IPv6 routed -> bridged, L2 ACL deny"""
634         self.run_test_ip46_routed_to_bridged(True, True, False,
635                                              self.WITHOUT_EH)
636
637     def test_0002_ip6_irb_1(self):
638         """ ACL IPv6 routed -> bridged, L3 ACL deny"""
639         self.run_test_ip46_routed_to_bridged(False, True, False,
640                                              self.WITHOUT_EH)
641
642     def test_0003_ip4_irb_1(self):
643         """ ACL IPv4 routed -> bridged, L2 ACL deny"""
644         self.run_test_ip46_routed_to_bridged(True, False, False,
645                                              self.WITHOUT_EH)
646
647     def test_0004_ip4_irb_1(self):
648         """ ACL IPv4 routed -> bridged, L3 ACL deny"""
649         self.run_test_ip46_routed_to_bridged(False, False, False,
650                                              self.WITHOUT_EH)
651
652     def test_0005_ip6_irb_1(self):
653         """ ACL IPv6 bridged -> routed, L2 ACL deny """
654         self.run_test_ip46_bridged_to_routed(True, True, False,
655                                              self.WITHOUT_EH)
656
657     def test_0006_ip6_irb_1(self):
658         """ ACL IPv6 bridged -> routed, L3 ACL deny """
659         self.run_test_ip46_bridged_to_routed(False, True, False,
660                                              self.WITHOUT_EH)
661
662     def test_0007_ip6_irb_1(self):
663         """ ACL IPv4 bridged -> routed, L2 ACL deny """
664         self.run_test_ip46_bridged_to_routed(True, False, False,
665                                              self.WITHOUT_EH)
666
667     def test_0008_ip6_irb_1(self):
668         """ ACL IPv4 bridged -> routed, L3 ACL deny """
669         self.run_test_ip46_bridged_to_routed(False, False, False,
670                                              self.WITHOUT_EH)
671
672     # Stateful ACL tests
673     def test_0101_ip6_irb_1(self):
674         """ ACL IPv6 routed -> bridged, L2 ACL permit+reflect"""
675         self.run_test_ip46_routed_to_bridged_and_back(True, True,
676                                                       self.WITHOUT_EH)
677
678     def test_0102_ip6_irb_1(self):
679         """ ACL IPv6 bridged -> routed, L2 ACL permit+reflect"""
680         self.run_test_ip46_bridged_to_routed_and_back(True, True,
681                                                       self.WITHOUT_EH)
682
683     def test_0103_ip6_irb_1(self):
684         """ ACL IPv4 routed -> bridged, L2 ACL permit+reflect"""
685         self.run_test_ip46_routed_to_bridged_and_back(True, False,
686                                                       self.WITHOUT_EH)
687
688     def test_0104_ip6_irb_1(self):
689         """ ACL IPv4 bridged -> routed, L2 ACL permit+reflect"""
690         self.run_test_ip46_bridged_to_routed_and_back(True, False,
691                                                       self.WITHOUT_EH)
692
693     def test_0111_ip6_irb_1(self):
694         """ ACL IPv6 routed -> bridged, L3 ACL permit+reflect"""
695         self.run_test_ip46_routed_to_bridged_and_back(False, True,
696                                                       self.WITHOUT_EH)
697
698     def test_0112_ip6_irb_1(self):
699         """ ACL IPv6 bridged -> routed, L3 ACL permit+reflect"""
700         self.run_test_ip46_bridged_to_routed_and_back(False, True,
701                                                       self.WITHOUT_EH)
702
703     def test_0113_ip6_irb_1(self):
704         """ ACL IPv4 routed -> bridged, L3 ACL permit+reflect"""
705         self.run_test_ip46_routed_to_bridged_and_back(False, False,
706                                                       self.WITHOUT_EH)
707
708     def test_0114_ip6_irb_1(self):
709         """ ACL IPv4 bridged -> routed, L3 ACL permit+reflect"""
710         self.run_test_ip46_bridged_to_routed_and_back(False, False,
711                                                       self.WITHOUT_EH)
712
713     # A block of tests with extension headers
714
715     def test_1001_ip6_irb_1(self):
716         """ ACL IPv6+EH routed -> bridged, L2 ACL deny"""
717         self.run_test_ip46_routed_to_bridged(True, True, False,
718                                              self.WITH_EH)
719
720     def test_1002_ip6_irb_1(self):
721         """ ACL IPv6+EH routed -> bridged, L3 ACL deny"""
722         self.run_test_ip46_routed_to_bridged(False, True, False,
723                                              self.WITH_EH)
724
725     def test_1005_ip6_irb_1(self):
726         """ ACL IPv6+EH bridged -> routed, L2 ACL deny """
727         self.run_test_ip46_bridged_to_routed(True, True, False,
728                                              self.WITH_EH)
729
730     def test_1006_ip6_irb_1(self):
731         """ ACL IPv6+EH bridged -> routed, L3 ACL deny """
732         self.run_test_ip46_bridged_to_routed(False, True, False,
733                                              self.WITH_EH)
734
735     def test_1101_ip6_irb_1(self):
736         """ ACL IPv6+EH routed -> bridged, L2 ACL permit+reflect"""
737         self.run_test_ip46_routed_to_bridged_and_back(True, True,
738                                                       self.WITH_EH)
739
740     def test_1102_ip6_irb_1(self):
741         """ ACL IPv6+EH bridged -> routed, L2 ACL permit+reflect"""
742         self.run_test_ip46_bridged_to_routed_and_back(True, True,
743                                                       self.WITH_EH)
744
745     def test_1111_ip6_irb_1(self):
746         """ ACL IPv6+EH routed -> bridged, L3 ACL permit+reflect"""
747         self.run_test_ip46_routed_to_bridged_and_back(False, True,
748                                                       self.WITH_EH)
749
750     def test_1112_ip6_irb_1(self):
751         """ ACL IPv6+EH bridged -> routed, L3 ACL permit+reflect"""
752         self.run_test_ip46_bridged_to_routed_and_back(False, True,
753                                                       self.WITH_EH)
754
755     # IPv4 with "MF" bit set
756
757     def test_1201_ip6_irb_1(self):
758         """ ACL IPv4+MF routed -> bridged, L2 ACL deny"""
759         self.run_test_ip46_routed_to_bridged(True, False, False,
760                                              self.WITH_EH)
761
762     def test_1202_ip6_irb_1(self):
763         """ ACL IPv4+MF routed -> bridged, L3 ACL deny"""
764         self.run_test_ip46_routed_to_bridged(False, False, False,
765                                              self.WITH_EH)
766
767     def test_1205_ip6_irb_1(self):
768         """ ACL IPv4+MF bridged -> routed, L2 ACL deny """
769         self.run_test_ip46_bridged_to_routed(True, False, False,
770                                              self.WITH_EH)
771
772     def test_1206_ip6_irb_1(self):
773         """ ACL IPv4+MF bridged -> routed, L3 ACL deny """
774         self.run_test_ip46_bridged_to_routed(False, False, False,
775                                              self.WITH_EH)
776
777     def test_1301_ip6_irb_1(self):
778         """ ACL IPv4+MF routed -> bridged, L2 ACL permit+reflect"""
779         self.run_test_ip46_routed_to_bridged_and_back(True, False,
780                                                       self.WITH_EH)
781
782     def test_1302_ip6_irb_1(self):
783         """ ACL IPv4+MF bridged -> routed, L2 ACL permit+reflect"""
784         self.run_test_ip46_bridged_to_routed_and_back(True, False,
785                                                       self.WITH_EH)
786
787     def test_1311_ip6_irb_1(self):
788         """ ACL IPv4+MF routed -> bridged, L3 ACL permit+reflect"""
789         self.run_test_ip46_routed_to_bridged_and_back(False, False,
790                                                       self.WITH_EH)
791
792     def test_1312_ip6_irb_1(self):
793         """ ACL IPv4+MF bridged -> routed, L3 ACL permit+reflect"""
794         self.run_test_ip46_bridged_to_routed_and_back(False, False,
795                                                       self.WITH_EH)
796     # Stateful ACL tests with stateful ICMP
797
798     def test_1401_ip6_irb_1(self):
799         """ IPv6 routed -> bridged, L2 ACL permit+reflect, ICMP reflect"""
800         self.run_test_ip46_routed_to_bridged_and_back(True, True,
801                                                       self.WITHOUT_EH,
802                                                       self.STATEFUL_ICMP)
803
804     def test_1402_ip6_irb_1(self):
805         """ IPv6 bridged -> routed, L2 ACL permit+reflect, ICMP reflect"""
806         self.run_test_ip46_bridged_to_routed_and_back(True, True,
807                                                       self.WITHOUT_EH,
808                                                       self.STATEFUL_ICMP)
809
810     def test_1403_ip4_irb_1(self):
811         """ IPv4 routed -> bridged, L2 ACL permit+reflect, ICMP reflect"""
812         self.run_test_ip46_routed_to_bridged_and_back(True, False,
813                                                       self.WITHOUT_EH,
814                                                       self.STATEFUL_ICMP)
815
816     def test_1404_ip4_irb_1(self):
817         """ IPv4 bridged -> routed, L2 ACL permit+reflect, ICMP reflect"""
818         self.run_test_ip46_bridged_to_routed_and_back(True, False,
819                                                       self.WITHOUT_EH,
820                                                       self.STATEFUL_ICMP)
821
822     def test_1411_ip6_irb_1(self):
823         """ IPv6 routed -> bridged, L3 ACL permit+reflect, ICMP reflect"""
824         self.run_test_ip46_routed_to_bridged_and_back(False, True,
825                                                       self.WITHOUT_EH,
826                                                       self.STATEFUL_ICMP)
827
828     def test_1412_ip6_irb_1(self):
829         """ IPv6 bridged -> routed, L3 ACL permit+reflect, ICMP reflect"""
830         self.run_test_ip46_bridged_to_routed_and_back(False, True,
831                                                       self.WITHOUT_EH,
832                                                       self.STATEFUL_ICMP)
833
834     def test_1413_ip4_irb_1(self):
835         """ IPv4 routed -> bridged, L3 ACL permit+reflect, ICMP reflect"""
836         self.run_test_ip46_routed_to_bridged_and_back(False, False,
837                                                       self.WITHOUT_EH,
838                                                       self.STATEFUL_ICMP)
839
840     def test_1414_ip4_irb_1(self):
841         """ IPv4 bridged -> routed, L3 ACL permit+reflect, ICMP reflect"""
842         self.run_test_ip46_bridged_to_routed_and_back(False, False,
843                                                       self.WITHOUT_EH,
844                                                       self.STATEFUL_ICMP)
845
846
847 if __name__ == '__main__':
848     unittest.main(testRunner=VppTestRunner)