blob: 73dd473c67f354117fd5fae0d737a63358daa96e [file] [log] [blame]
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +01001#!/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
26import unittest
27from socket import inet_pton, AF_INET, AF_INET6
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +010028from random import choice, shuffle
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010029from pprint import pprint
30
31from scapy.packet import Raw
32from scapy.layers.l2 import Ether
33from scapy.layers.inet import IP, UDP, ICMP, TCP
34from scapy.layers.inet6 import IPv6, ICMPv6Unknown, ICMPv6EchoRequest
35from scapy.layers.inet6 import ICMPv6EchoReply, IPv6ExtHdrRouting
Andrew Yourtchenkod1b05642017-04-04 14:10:40 +000036from scapy.layers.inet6 import IPv6ExtHdrFragment
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010037
38from framework import VppTestCase, VppTestRunner
Neale Rannsb4743802018-09-05 09:13:57 -070039from vpp_papi_provider import L2_PORT_TYPE
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010040import time
41
42
juraj.linkes8e26f6d2018-09-19 14:59:43 +020043class TestACLpluginL2L3(VppTestCase):
44 """TestACLpluginL2L3 Test Case"""
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010045
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 """
juraj.linkes8e26f6d2018-09-19 14:59:43 +020056 super(TestACLpluginL2L3, cls).setUpClass()
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010057
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))
Klement Sekerab9ef2732018-06-24 22:49:33 +020064 cls.create_loopback_interfaces(1)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010065
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(
Neale Rannsb4743802018-09-05 09:13:57 -070074 cls.loop0.sw_if_index, bd_id=cls.bd_id,
75 port_type=L2_PORT_TYPE.BVI)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010076 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
Andrew Yourtchenkofae83372018-09-26 21:03:06 +020097 cls.STATELESS_ICMP = False
98 cls.STATEFUL_ICMP = True
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +010099
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 """
juraj.linkes8e26f6d2018-09-19 14:59:43 +0200111 super(TestACLpluginL2L3, self).tearDown()
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100112 if not self.vpp_dead:
113 self.logger.info(self.vapi.cli("show l2patch"))
114 self.logger.info(self.vapi.cli("show classify tables"))
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100115 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"))
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200120 cmd = "show acl-plugin sessions verbose 1"
121 self.logger.info(self.vapi.cli(cmd))
Andrew Yourtchenko7f4d5772017-05-24 13:20:47 +0200122 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"))
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100125
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100126 def create_stream(self, src_ip_if, dst_ip_if, reverse, packet_sizes,
127 is_ip6, expect_blocked, expect_established,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200128 add_extension_header, icmp_stateful=False):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100129 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
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200136 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
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100145 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
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200180 if is_reflected_icmp:
181 icmp_type_delta = 1
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100182
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
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200188 if is_udp_packet:
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100189 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() /
Andrew Yourtchenkod1b05642017-04-04 14:10:40 +0000194 IPv6ExtHdrFragment(offset=0, m=1) / ulp_l4)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100195 # 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)
Andrew Yourtchenkod1b05642017-04-04 14:10:40 +0000205 # IPv4 does not allow extension headers,
206 # but we rather make it a first fragment
207 flags = 1 if add_extension_header else 0
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100208 ulp = ulp_l4
209 p = (Ether(dst=dst_mac, src=src_mac) /
Andrew Yourtchenkod1b05642017-04-04 14:10:40 +0000210 IP(src=src_ip4, dst=dst_ip4, frag=0, flags=flags) /
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100211 ulp /
212 Raw(payload))
213 elif modulo == 1:
214 if is_ip6:
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200215 ulp_l4 = ICMPv6Unknown(type=128 + icmp_type_delta,
216 code=icmp_code)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100217 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:
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200223 ulp_l4 = ICMP(type=8 - 8*icmp_type_delta, code=icmp_code)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100224 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
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200280
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100281 permit_and_reflect_rules.append(new_rule_permit_and_reflect)
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200282 self.logger.info("create_stream pkt#%d: %s" % (i, payload))
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100283
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
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100351 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:
Klement Sekera9690e902018-04-09 12:01:32 +0200366 all_rules.append(dict(rule._asdict()))
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100367
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],
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800372 tag=b"shuffle 1. acl")
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100373 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],
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800377 tag=b"shuffle 2. acl")
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100378 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],
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800382 tag=b"shuffle 3. acl")
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100383 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)],
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800407 tag=b"shuffle 1. acl")
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100408 shuffle(all_rules)
409 reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_2,
410 r=all_rules[::1+(i % 3)],
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800411 tag=b"shuffle 2. acl")
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100412 shuffle(all_rules)
413 reply = self.vapi.acl_add_replace(acl_index=shuffle_acl_2,
414 r=all_rules[::1+(i % 5)],
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800415 tag=b"shuffle 3. acl")
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100416
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
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100425 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
Andrew Yourtchenko51d26512017-09-14 18:26:36 +0200431 reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_action,
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800432 tag=b"act. acl")
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100433 action_acl_index = reply.acl_index
Andrew Yourtchenko51d26512017-09-14 18:26:36 +0200434 reply = self.vapi.acl_add_replace(acl_index=4294967295, r=r_permit,
Paul Vinciguerra4a4cea02019-03-06 19:06:19 -0800435 tag=b"perm. acl")
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100436 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
Andrew Yourtchenko51d26512017-09-14 18:26:36 +0200456 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']])
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100465 self.applied_acl_shuffle(self.pg0.sw_if_index)
466 self.applied_acl_shuffle(self.pg2.sw_if_index)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100467
468 def apply_acl_ip46_both_directions_reflect(self,
469 primary_is_bridged_to_routed,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200470 reflect_on_l2, is_ip6, add_eh,
471 stateful_icmp):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100472 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,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200477 False, False, add_eh,
478 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100479 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,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200485 True, True, add_eh, stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100486 # 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
Andrew Yourtchenko51d26512017-09-14 18:26:36 +0200510 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])
Andrew Yourtchenko0e89dfc2018-03-23 09:34:29 +0100522 self.applied_acl_shuffle(self.pg0.sw_if_index)
523 self.applied_acl_shuffle(self.pg2.sw_if_index)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100524
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,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200537 is_reflect, is_established, add_eh,
538 stateful_icmp=False):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100539 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,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200544 add_eh, stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100545 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,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200558 is_reflect, is_established, add_eh,
559 stateful_icmp=False):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100560 self.run_traffic_ip46_x_to_y(False, test_l2_deny, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200561 is_reflect, is_established, add_eh,
562 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100563
564 def run_traffic_ip46_bridged_to_routed(self, test_l2_deny, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200565 is_reflect, is_established, add_eh,
566 stateful_icmp=False):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100567 self.run_traffic_ip46_x_to_y(True, test_l2_deny, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200568 is_reflect, is_established, add_eh,
569 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100570
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,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200586 is_ip6, add_eh,
587 stateful_icmp=False):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100588 self.apply_acl_ip46_both_directions_reflect(False, test_l2_action,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200589 is_ip6, add_eh,
590 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100591 self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200592 True, False, add_eh,
593 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100594 self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200595 False, True, add_eh,
596 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100597
598 def run_test_ip46_bridged_to_routed_and_back(self, test_l2_action,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200599 is_ip6, add_eh,
600 stateful_icmp=False):
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100601 self.apply_acl_ip46_both_directions_reflect(True, test_l2_action,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200602 is_ip6, add_eh,
603 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100604 self.run_traffic_ip46_bridged_to_routed(test_l2_action, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200605 True, False, add_eh,
606 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100607 self.run_traffic_ip46_routed_to_bridged(test_l2_action, is_ip6,
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200608 False, True, add_eh,
609 stateful_icmp)
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100610
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
Andrew Yourtchenkod1b05642017-04-04 14:10:40 +0000753 # 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)
Andrew Yourtchenkofae83372018-09-26 21:03:06 +0200794 # 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
Andrew Yourtchenkod1b05642017-04-04 14:10:40 +0000844
Andrew Yourtchenkod2a59be2017-03-21 10:31:55 +0100845if __name__ == '__main__':
846 unittest.main(testRunner=VppTestRunner)