04f91cfca5a25119b705389b1fffbbae4472b24e
[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
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 import time
40
41
42 class TestIpIrb(VppTestCase):
43     """IRB Test Case"""
44
45     @classmethod
46     def setUpClass(cls):
47         """
48         #. Create BD with MAC learning enabled and put interfaces to this BD.
49         #. Configure IPv4 addresses on loopback interface and routed interface.
50         #. Configure MAC address binding to IPv4 neighbors on loop0.
51         #. Configure MAC address on pg2.
52         #. Loopback BVI interface has remote hosts, one half of hosts are
53            behind pg0 second behind pg1.
54         """
55         super(TestIpIrb, cls).setUpClass()
56
57         cls.pg_if_packet_sizes = [64, 512, 1518, 9018]  # packet sizes
58         cls.bd_id = 10
59         cls.remote_hosts_count = 250
60
61         # create 3 pg interfaces, 1 loopback interface
62         cls.create_pg_interfaces(range(3))
63         cls.create_loopback_interfaces(range(1))
64
65         cls.interfaces = list(cls.pg_interfaces)
66         cls.interfaces.extend(cls.lo_interfaces)
67
68         for i in cls.interfaces:
69             i.admin_up()
70
71         # Create BD with MAC learning enabled and put interfaces to this BD
72         cls.vapi.sw_interface_set_l2_bridge(
73             cls.loop0.sw_if_index, bd_id=cls.bd_id, bvi=1)
74         cls.vapi.sw_interface_set_l2_bridge(
75             cls.pg0.sw_if_index, bd_id=cls.bd_id)
76         cls.vapi.sw_interface_set_l2_bridge(
77             cls.pg1.sw_if_index, bd_id=cls.bd_id)
78
79         # Configure IPv4 addresses on loopback interface and routed interface
80         cls.loop0.config_ip4()
81         cls.loop0.config_ip6()
82         cls.pg2.config_ip4()
83         cls.pg2.config_ip6()
84
85         # Configure MAC address binding to IPv4 neighbors on loop0
86         cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
87         cls.loop0.configure_ipv4_neighbors()
88         cls.loop0.configure_ipv6_neighbors()
89         # configure MAC address on pg2
90         cls.pg2.resolve_arp()
91         cls.pg2.resolve_ndp()
92
93         cls.WITHOUT_EH = False
94         cls.WITH_EH = True
95
96         # Loopback BVI interface has remote hosts, one half of hosts are behind
97         # pg0 second behind pg1
98         half = cls.remote_hosts_count // 2
99         cls.pg0.remote_hosts = cls.loop0.remote_hosts[:half]
100         cls.pg1.remote_hosts = cls.loop0.remote_hosts[half:]
101
102     def tearDown(self):
103         """Run standard test teardown and log ``show l2patch``,
104         ``show l2fib verbose``,``show bridge-domain <bd_id> detail``,
105         ``show ip arp``.
106         """
107         super(TestIpIrb, self).tearDown()
108         if not self.vpp_dead:
109             self.logger.info(self.vapi.cli("show l2patch"))
110             self.logger.info(self.vapi.cli("show classify tables"))
111             self.logger.info(self.vapi.cli("show vlib graph"))
112             self.logger.info(self.vapi.cli("show l2fib verbose"))
113             self.logger.info(self.vapi.cli("show bridge-domain %s detail" %
114                                            self.bd_id))
115             self.logger.info(self.vapi.cli("show ip arp"))
116             self.logger.info(self.vapi.cli("show ip6 neighbors"))
117             self.logger.info(self.vapi.cli("show acl-plugin sessions"))
118             self.logger.info(self.vapi.cli("show acl-plugin acl"))
119             self.logger.info(self.vapi.cli("show acl-plugin interface"))
120             self.logger.info(self.vapi.cli("show acl-plugin tables"))
121
122     def create_stream(self, src_ip_if, dst_ip_if, reverse, packet_sizes,
123                       is_ip6, expect_blocked, expect_established,
124                       add_extension_header):
125         pkts = []
126         rules = []
127         permit_rules = []
128         permit_and_reflect_rules = []
129         total_packet_count = 8
130         for i in range(0, total_packet_count):
131             modulo = (i//2) % 2
132             can_reflect_this_packet = (modulo == 0)
133             is_permit = i % 2
134             remote_dst_index = i % len(dst_ip_if.remote_hosts)
135             remote_dst_host = dst_ip_if.remote_hosts[remote_dst_index]
136             if is_permit == 1:
137                 info = self.create_packet_info(src_ip_if, dst_ip_if)
138                 payload = self.info_to_payload(info)
139             else:
140                 to_be_blocked = False
141                 if (expect_blocked and not expect_established):
142                     to_be_blocked = True
143                 if (not can_reflect_this_packet):
144                     to_be_blocked = True
145                 if to_be_blocked:
146                     payload = "to be blocked"
147                 else:
148                     info = self.create_packet_info(src_ip_if, dst_ip_if)
149                     payload = self.info_to_payload(info)
150             if reverse:
151                 dst_mac = 'de:ad:00:00:00:00'
152                 src_mac = remote_dst_host._mac
153                 dst_ip6 = src_ip_if.remote_ip6
154                 src_ip6 = remote_dst_host.ip6
155                 dst_ip4 = src_ip_if.remote_ip4
156                 src_ip4 = remote_dst_host.ip4
157                 dst_l4 = 1234 + i
158                 src_l4 = 4321 + i
159             else:
160                 dst_mac = src_ip_if.local_mac
161                 src_mac = src_ip_if.remote_mac
162                 src_ip6 = src_ip_if.remote_ip6
163                 dst_ip6 = remote_dst_host.ip6
164                 src_ip4 = src_ip_if.remote_ip4
165                 dst_ip4 = remote_dst_host.ip4
166                 src_l4 = 1234 + i
167                 dst_l4 = 4321 + i
168
169             # default ULP should be something we do not use in tests
170             ulp_l4 = TCP(sport=src_l4, dport=dst_l4)
171             # potentially a chain of protocols leading to ULP
172             ulp = ulp_l4
173
174             if can_reflect_this_packet:
175                 if is_ip6:
176                     ulp_l4 = UDP(sport=src_l4, dport=dst_l4)
177                     if add_extension_header:
178                         # prepend some extension headers
179                         ulp = (IPv6ExtHdrRouting() / IPv6ExtHdrRouting() /
180                                IPv6ExtHdrFragment(offset=0, m=1) / ulp_l4)
181                         # uncomment below to test invalid ones
182                         # ulp = IPv6ExtHdrRouting(len = 200) / ulp_l4
183                     else:
184                         ulp = ulp_l4
185                     p = (Ether(dst=dst_mac, src=src_mac) /
186                          IPv6(src=src_ip6, dst=dst_ip6) /
187                          ulp /
188                          Raw(payload))
189                 else:
190                     ulp_l4 = UDP(sport=src_l4, dport=dst_l4)
191                     # IPv4 does not allow extension headers,
192                     # but we rather make it a first fragment
193                     flags = 1 if add_extension_header else 0
194                     ulp = ulp_l4
195                     p = (Ether(dst=dst_mac, src=src_mac) /
196                          IP(src=src_ip4, dst=dst_ip4, frag=0, flags=flags) /
197                          ulp /
198                          Raw(payload))
199             elif modulo == 1:
200                 if is_ip6:
201                     ulp_l4 = ICMPv6Unknown(type=128 + (i % 2), code=i % 2)
202                     ulp = ulp_l4
203                     p = (Ether(dst=dst_mac, src=src_mac) /
204                          IPv6(src=src_ip6, dst=dst_ip6) /
205                          ulp /
206                          Raw(payload))
207                 else:
208                     ulp_l4 = ICMP(type=8 + (i % 2), code=i % 2)
209                     ulp = ulp_l4
210                     p = (Ether(dst=dst_mac, src=src_mac) /
211                          IP(src=src_ip4, dst=dst_ip4) /
212                          ulp /
213                          Raw(payload))
214
215             if i % 2 == 1:
216                 info.data = p.copy()
217             size = packet_sizes[(i // 2) % len(packet_sizes)]
218             self.extend_packet(p, size)
219             pkts.append(p)
220
221             rule_family = AF_INET6 if p.haslayer(IPv6) else AF_INET
222             rule_prefix_len = 128 if p.haslayer(IPv6) else 32
223             rule_l3_layer = IPv6 if p.haslayer(IPv6) else IP
224
225             if p.haslayer(UDP):
226                 rule_l4_sport = p[UDP].sport
227                 rule_l4_dport = p[UDP].dport
228             else:
229                 if p.haslayer(ICMP):
230                     rule_l4_sport = p[ICMP].type
231                     rule_l4_dport = p[ICMP].code
232                 else:
233                     rule_l4_sport = p[ICMPv6Unknown].type
234                     rule_l4_dport = p[ICMPv6Unknown].code
235             if p.haslayer(IPv6):
236                 rule_l4_proto = ulp_l4.overload_fields[IPv6]['nh']
237             else:
238                 rule_l4_proto = p[IP].proto
239
240             new_rule = {
241                         'is_permit': is_permit,
242                         'is_ipv6': p.haslayer(IPv6),
243                         'src_ip_addr': inet_pton(rule_family,
244                                                  p[rule_l3_layer].src),
245                         'src_ip_prefix_len': rule_prefix_len,
246                         'dst_ip_addr': inet_pton(rule_family,
247                                                  p[rule_l3_layer].dst),
248                         'dst_ip_prefix_len': rule_prefix_len,
249                         'srcport_or_icmptype_first': rule_l4_sport,
250                         'srcport_or_icmptype_last': rule_l4_sport,
251                         'dstport_or_icmpcode_first': rule_l4_dport,
252                         'dstport_or_icmpcode_last': rule_l4_dport,
253                         'proto': rule_l4_proto,
254                        }
255             rules.append(new_rule)
256             new_rule_permit = new_rule.copy()
257             new_rule_permit['is_permit'] = 1
258             permit_rules.append(new_rule_permit)
259
260             new_rule_permit_and_reflect = new_rule.copy()
261             if can_reflect_this_packet:
262                 new_rule_permit_and_reflect['is_permit'] = 2
263             else:
264                 new_rule_permit_and_reflect['is_permit'] = is_permit
265             permit_and_reflect_rules.append(new_rule_permit_and_reflect)
266
267         return {'stream': pkts,
268                 'rules': rules,
269                 'permit_rules': permit_rules,
270                 'permit_and_reflect_rules': permit_and_reflect_rules}
271
272     def verify_capture(self, dst_ip_if, src_ip_if, capture, reverse):
273         last_info = dict()
274         for i in self.interfaces:
275             last_info[i.sw_if_index] = None
276
277         dst_ip_sw_if_index = dst_ip_if.sw_if_index
278         return
279
280         for packet in capture:
281             l3 = IP if packet.haslayer(IP) else IPv6
282             ip = packet[l3]
283             if packet.haslayer(UDP):
284                 l4 = UDP
285             else:
286                 if packet.haslayer(ICMP):
287                     l4 = ICMP
288                 else:
289                     l4 = ICMPv6Unknown
290
291             # Scapy IPv6 stuff is too smart for its own good.
292             # So we do this and coerce the ICMP into unknown type
293             if packet.haslayer(UDP):
294                 data = str(packet[UDP][Raw])
295             else:
296                 if l3 == IP:
297                     data = str(ICMP(str(packet[l3].payload))[Raw])
298                 else:
299                     data = str(ICMPv6Unknown(str(packet[l3].payload)).msgbody)
300             udp_or_icmp = packet[l3].payload
301             payload_info = self.payload_to_info(data)
302             packet_index = payload_info.index
303
304             self.assertEqual(payload_info.dst, dst_ip_sw_if_index)
305
306             next_info = self.get_next_packet_info_for_interface2(
307                 payload_info.src, dst_ip_sw_if_index,
308                 last_info[payload_info.src])
309             last_info[payload_info.src] = next_info
310             self.assertTrue(next_info is not None)
311             self.assertEqual(packet_index, next_info.index)
312             saved_packet = next_info.data
313             self.assertTrue(next_info is not None)
314
315             # MAC: src, dst
316             if not reverse:
317                 self.assertEqual(packet.src, dst_ip_if.local_mac)
318                 host = dst_ip_if.host_by_mac(packet.dst)
319
320             # IP: src, dst
321             # self.assertEqual(ip.src, src_ip_if.remote_ip4)
322             if saved_packet is not None:
323                 self.assertEqual(ip.src, saved_packet[l3].src)
324                 self.assertEqual(ip.dst, saved_packet[l3].dst)
325                 if l4 == UDP:
326                     self.assertEqual(udp_or_icmp.sport, saved_packet[l4].sport)
327                     self.assertEqual(udp_or_icmp.dport, saved_packet[l4].dport)
328             else:
329                 print("Saved packet is none")
330             # self.assertEqual(ip.dst, host.ip4)
331
332             # UDP:
333
334     def create_acls_for_a_stream(self, stream_dict,
335                                  test_l2_action, is_reflect):
336         r = stream_dict['rules']
337         r_permit = stream_dict['permit_rules']
338         r_permit_reflect = stream_dict['permit_and_reflect_rules']
339         r_action = r_permit_reflect if is_reflect else r
340         reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_action,
341                                           tag="act. acl")
342         action_acl_index = reply.acl_index
343         reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_permit,
344                                           tag="perm. acl")
345         permit_acl_index = reply.acl_index
346         return {'L2': action_acl_index if test_l2_action else permit_acl_index,
347                 'L3': permit_acl_index if test_l2_action else action_acl_index,
348                 'permit': permit_acl_index, 'action': action_acl_index}
349
350     def apply_acl_ip46_x_to_y(self, bridged_to_routed, test_l2_deny,
351                               is_ip6, is_reflect, add_eh):
352         """ Apply the ACLs
353         """
354         self.reset_packet_infos()
355         stream_dict = self.create_stream(
356                                          self.pg2, self.loop0,
357                                          bridged_to_routed,
358                                          self.pg_if_packet_sizes, is_ip6,
359                                          not is_reflect, False, add_eh)
360         stream = stream_dict['stream']
361         acl_idx = self.create_acls_for_a_stream(stream_dict, test_l2_deny,
362                                                 is_reflect)
363         n_input_l3 = 0 if bridged_to_routed else 1
364         n_input_l2 = 1 if bridged_to_routed else 0
365         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg2.sw_if_index,
366                                              n_input=n_input_l3,
367                                              acls=[acl_idx['L3']])
368         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg0.sw_if_index,
369                                              n_input=n_input_l2,
370                                              acls=[acl_idx['L2']])
371         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
372                                              n_input=n_input_l2,
373                                              acls=[acl_idx['L2']])
374
375     def apply_acl_ip46_both_directions_reflect(self,
376                                                primary_is_bridged_to_routed,
377                                                reflect_on_l2, is_ip6, add_eh):
378         primary_is_routed_to_bridged = not primary_is_bridged_to_routed
379         self.reset_packet_infos()
380         stream_dict_fwd = self.create_stream(self.pg2, self.loop0,
381                                              primary_is_bridged_to_routed,
382                                              self.pg_if_packet_sizes, is_ip6,
383                                              False, False, add_eh)
384         acl_idx_fwd = self.create_acls_for_a_stream(stream_dict_fwd,
385                                                     reflect_on_l2, True)
386
387         stream_dict_rev = self.create_stream(self.pg2, self.loop0,
388                                              not primary_is_bridged_to_routed,
389                                              self.pg_if_packet_sizes, is_ip6,
390                                              True, True, add_eh)
391         # We want the primary action to be "deny" rather than reflect
392         acl_idx_rev = self.create_acls_for_a_stream(stream_dict_rev,
393                                                     reflect_on_l2, False)
394
395         if primary_is_bridged_to_routed:
396             inbound_l2_acl = acl_idx_fwd['L2']
397         else:
398             inbound_l2_acl = acl_idx_rev['L2']
399
400         if primary_is_routed_to_bridged:
401             outbound_l2_acl = acl_idx_fwd['L2']
402         else:
403             outbound_l2_acl = acl_idx_rev['L2']
404
405         if primary_is_routed_to_bridged:
406             inbound_l3_acl = acl_idx_fwd['L3']
407         else:
408             inbound_l3_acl = acl_idx_rev['L3']
409
410         if primary_is_bridged_to_routed:
411             outbound_l3_acl = acl_idx_fwd['L3']
412         else:
413             outbound_l3_acl = acl_idx_rev['L3']
414
415         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg2.sw_if_index,
416                                              n_input=1,
417                                              acls=[inbound_l3_acl,
418                                                    outbound_l3_acl])
419         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg0.sw_if_index,
420                                              n_input=1,
421                                              acls=[inbound_l2_acl,
422                                                    outbound_l2_acl])
423         self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
424                                              n_input=1,
425                                              acls=[inbound_l2_acl,
426                                                    outbound_l2_acl])
427
428     def apply_acl_ip46_routed_to_bridged(self, test_l2_deny, is_ip6,
429                                          is_reflect, add_eh):
430         self.apply_acl_ip46_x_to_y(False, test_l2_deny, is_ip6,
431                                    is_reflect, add_eh)
432
433     def apply_acl_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
434                                          is_reflect, add_eh):
435         self.apply_acl_ip46_x_to_y(True, test_l2_deny, is_ip6,
436                                    is_reflect, add_eh)
437
438     def run_traffic_ip46_x_to_y(self, bridged_to_routed,
439                                 test_l2_deny, is_ip6,
440                                 is_reflect, is_established, add_eh):
441         self.reset_packet_infos()
442         stream_dict = self.create_stream(self.pg2, self.loop0,
443                                          bridged_to_routed,
444                                          self.pg_if_packet_sizes, is_ip6,
445                                          not is_reflect, is_established,
446                                          add_eh)
447         stream = stream_dict['stream']
448
449         tx_if = self.pg0 if bridged_to_routed else self.pg2
450         rx_if = self.pg2 if bridged_to_routed else self.pg0
451
452         tx_if.add_stream(stream)
453         self.pg_enable_capture(self.pg_interfaces)
454         self.pg_start()
455         packet_count = self.get_packet_count_for_if_idx(self.loop0.sw_if_index)
456         rcvd1 = rx_if.get_capture(packet_count)
457         self.verify_capture(self.loop0, self.pg2, rcvd1, bridged_to_routed)
458
459     def run_traffic_ip46_routed_to_bridged(self, test_l2_deny, is_ip6,
460                                            is_reflect, is_established, add_eh):
461         self.run_traffic_ip46_x_to_y(False, test_l2_deny, is_ip6,
462                                      is_reflect, is_established, add_eh)
463
464     def run_traffic_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
465                                            is_reflect, is_established, add_eh):
466         self.run_traffic_ip46_x_to_y(True, test_l2_deny, is_ip6,
467                                      is_reflect, is_established, add_eh)
468
469     def run_test_ip46_routed_to_bridged(self, test_l2_deny,
470                                         is_ip6, is_reflect, add_eh):
471         self.apply_acl_ip46_routed_to_bridged(test_l2_deny,
472                                               is_ip6, is_reflect, add_eh)
473         self.run_traffic_ip46_routed_to_bridged(test_l2_deny, is_ip6,
474                                                 is_reflect, False, add_eh)
475
476     def run_test_ip46_bridged_to_routed(self, test_l2_deny,
477                                         is_ip6, is_reflect, add_eh):
478         self.apply_acl_ip46_bridged_to_routed(test_l2_deny,
479                                               is_ip6, is_reflect, add_eh)
480         self.run_traffic_ip46_bridged_to_routed(test_l2_deny, is_ip6,
481                                                 is_reflect, False, add_eh)
482
483     def run_test_ip46_routed_to_bridged_and_back(self, test_l2_action,
484                                                  is_ip6, add_eh):
485         self.apply_acl_ip46_both_directions_reflect(False, test_l2_action,
486                                                     is_ip6, add_eh)
487         self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
488                                                 True, False, add_eh)
489         self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
490                                                 False, True, add_eh)
491
492     def run_test_ip46_bridged_to_routed_and_back(self, test_l2_action,
493                                                  is_ip6, add_eh):
494         self.apply_acl_ip46_both_directions_reflect(True, test_l2_action,
495                                                     is_ip6, add_eh)
496         self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
497                                                 True, False, add_eh)
498         self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
499                                                 False, True, add_eh)
500
501     def test_0000_ip6_irb_1(self):
502         """ ACL plugin prepare"""
503         if not self.vpp_dead:
504             cmd = "set acl-plugin session timeout udp idle 2000"
505             self.logger.info(self.vapi.ppcli(cmd))
506             # uncomment to not skip past the routing header
507             # and watch the EH tests fail
508             # self.logger.info(self.vapi.ppcli(
509             #    "set acl-plugin skip-ipv6-extension-header 43 0"))
510             # uncomment to test the session limit (stateful tests will fail)
511             # self.logger.info(self.vapi.ppcli(
512             #    "set acl-plugin session table max-entries 1"))
513             # new datapath is the default, but just in case
514             # self.logger.info(self.vapi.ppcli(
515             #    "set acl-plugin l2-datapath new"))
516             # If you want to see some tests fail, uncomment the next line
517             # self.logger.info(self.vapi.ppcli(
518             #    "set acl-plugin l2-datapath old"))
519
520     def test_0001_ip6_irb_1(self):
521         """ ACL IPv6 routed -> bridged, L2 ACL deny"""
522         self.run_test_ip46_routed_to_bridged(True, True, False,
523                                              self.WITHOUT_EH)
524
525     def test_0002_ip6_irb_1(self):
526         """ ACL IPv6 routed -> bridged, L3 ACL deny"""
527         self.run_test_ip46_routed_to_bridged(False, True, False,
528                                              self.WITHOUT_EH)
529
530     def test_0003_ip4_irb_1(self):
531         """ ACL IPv4 routed -> bridged, L2 ACL deny"""
532         self.run_test_ip46_routed_to_bridged(True, False, False,
533                                              self.WITHOUT_EH)
534
535     def test_0004_ip4_irb_1(self):
536         """ ACL IPv4 routed -> bridged, L3 ACL deny"""
537         self.run_test_ip46_routed_to_bridged(False, False, False,
538                                              self.WITHOUT_EH)
539
540     def test_0005_ip6_irb_1(self):
541         """ ACL IPv6 bridged -> routed, L2 ACL deny """
542         self.run_test_ip46_bridged_to_routed(True, True, False,
543                                              self.WITHOUT_EH)
544
545     def test_0006_ip6_irb_1(self):
546         """ ACL IPv6 bridged -> routed, L3 ACL deny """
547         self.run_test_ip46_bridged_to_routed(False, True, False,
548                                              self.WITHOUT_EH)
549
550     def test_0007_ip6_irb_1(self):
551         """ ACL IPv4 bridged -> routed, L2 ACL deny """
552         self.run_test_ip46_bridged_to_routed(True, False, False,
553                                              self.WITHOUT_EH)
554
555     def test_0008_ip6_irb_1(self):
556         """ ACL IPv4 bridged -> routed, L3 ACL deny """
557         self.run_test_ip46_bridged_to_routed(False, False, False,
558                                              self.WITHOUT_EH)
559
560     # Stateful ACL tests
561     def test_0101_ip6_irb_1(self):
562         """ ACL IPv6 routed -> bridged, L2 ACL permit+reflect"""
563         self.run_test_ip46_routed_to_bridged_and_back(True, True,
564                                                       self.WITHOUT_EH)
565
566     def test_0102_ip6_irb_1(self):
567         """ ACL IPv6 bridged -> routed, L2 ACL permit+reflect"""
568         self.run_test_ip46_bridged_to_routed_and_back(True, True,
569                                                       self.WITHOUT_EH)
570
571     def test_0103_ip6_irb_1(self):
572         """ ACL IPv4 routed -> bridged, L2 ACL permit+reflect"""
573         self.run_test_ip46_routed_to_bridged_and_back(True, False,
574                                                       self.WITHOUT_EH)
575
576     def test_0104_ip6_irb_1(self):
577         """ ACL IPv4 bridged -> routed, L2 ACL permit+reflect"""
578         self.run_test_ip46_bridged_to_routed_and_back(True, False,
579                                                       self.WITHOUT_EH)
580
581     def test_0111_ip6_irb_1(self):
582         """ ACL IPv6 routed -> bridged, L3 ACL permit+reflect"""
583         self.run_test_ip46_routed_to_bridged_and_back(False, True,
584                                                       self.WITHOUT_EH)
585
586     def test_0112_ip6_irb_1(self):
587         """ ACL IPv6 bridged -> routed, L3 ACL permit+reflect"""
588         self.run_test_ip46_bridged_to_routed_and_back(False, True,
589                                                       self.WITHOUT_EH)
590
591     def test_0113_ip6_irb_1(self):
592         """ ACL IPv4 routed -> bridged, L3 ACL permit+reflect"""
593         self.run_test_ip46_routed_to_bridged_and_back(False, False,
594                                                       self.WITHOUT_EH)
595
596     def test_0114_ip6_irb_1(self):
597         """ ACL IPv4 bridged -> routed, L3 ACL permit+reflect"""
598         self.run_test_ip46_bridged_to_routed_and_back(False, False,
599                                                       self.WITHOUT_EH)
600
601     # A block of tests with extension headers
602
603     def test_1001_ip6_irb_1(self):
604         """ ACL IPv6+EH routed -> bridged, L2 ACL deny"""
605         self.run_test_ip46_routed_to_bridged(True, True, False,
606                                              self.WITH_EH)
607
608     def test_1002_ip6_irb_1(self):
609         """ ACL IPv6+EH routed -> bridged, L3 ACL deny"""
610         self.run_test_ip46_routed_to_bridged(False, True, False,
611                                              self.WITH_EH)
612
613     def test_1005_ip6_irb_1(self):
614         """ ACL IPv6+EH bridged -> routed, L2 ACL deny """
615         self.run_test_ip46_bridged_to_routed(True, True, False,
616                                              self.WITH_EH)
617
618     def test_1006_ip6_irb_1(self):
619         """ ACL IPv6+EH bridged -> routed, L3 ACL deny """
620         self.run_test_ip46_bridged_to_routed(False, True, False,
621                                              self.WITH_EH)
622
623     def test_1101_ip6_irb_1(self):
624         """ ACL IPv6+EH routed -> bridged, L2 ACL permit+reflect"""
625         self.run_test_ip46_routed_to_bridged_and_back(True, True,
626                                                       self.WITH_EH)
627
628     def test_1102_ip6_irb_1(self):
629         """ ACL IPv6+EH bridged -> routed, L2 ACL permit+reflect"""
630         self.run_test_ip46_bridged_to_routed_and_back(True, True,
631                                                       self.WITH_EH)
632
633     def test_1111_ip6_irb_1(self):
634         """ ACL IPv6+EH routed -> bridged, L3 ACL permit+reflect"""
635         self.run_test_ip46_routed_to_bridged_and_back(False, True,
636                                                       self.WITH_EH)
637
638     def test_1112_ip6_irb_1(self):
639         """ ACL IPv6+EH bridged -> routed, L3 ACL permit+reflect"""
640         self.run_test_ip46_bridged_to_routed_and_back(False, True,
641                                                       self.WITH_EH)
642
643     # IPv4 with "MF" bit set
644
645     def test_1201_ip6_irb_1(self):
646         """ ACL IPv4+MF routed -> bridged, L2 ACL deny"""
647         self.run_test_ip46_routed_to_bridged(True, False, False,
648                                              self.WITH_EH)
649
650     def test_1202_ip6_irb_1(self):
651         """ ACL IPv4+MF routed -> bridged, L3 ACL deny"""
652         self.run_test_ip46_routed_to_bridged(False, False, False,
653                                              self.WITH_EH)
654
655     def test_1205_ip6_irb_1(self):
656         """ ACL IPv4+MF bridged -> routed, L2 ACL deny """
657         self.run_test_ip46_bridged_to_routed(True, False, False,
658                                              self.WITH_EH)
659
660     def test_1206_ip6_irb_1(self):
661         """ ACL IPv4+MF bridged -> routed, L3 ACL deny """
662         self.run_test_ip46_bridged_to_routed(False, False, False,
663                                              self.WITH_EH)
664
665     def test_1301_ip6_irb_1(self):
666         """ ACL IPv4+MF routed -> bridged, L2 ACL permit+reflect"""
667         self.run_test_ip46_routed_to_bridged_and_back(True, False,
668                                                       self.WITH_EH)
669
670     def test_1302_ip6_irb_1(self):
671         """ ACL IPv4+MF bridged -> routed, L2 ACL permit+reflect"""
672         self.run_test_ip46_bridged_to_routed_and_back(True, False,
673                                                       self.WITH_EH)
674
675     def test_1311_ip6_irb_1(self):
676         """ ACL IPv4+MF routed -> bridged, L3 ACL permit+reflect"""
677         self.run_test_ip46_routed_to_bridged_and_back(False, False,
678                                                       self.WITH_EH)
679
680     def test_1312_ip6_irb_1(self):
681         """ ACL IPv4+MF bridged -> routed, L3 ACL permit+reflect"""
682         self.run_test_ip46_bridged_to_routed_and_back(False, False,
683                                                       self.WITH_EH)
684
685 if __name__ == '__main__':
686     unittest.main(testRunner=VppTestRunner)