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