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