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