From: Josh Dorsey Date: Wed, 4 Jan 2023 21:28:07 +0000 (+0000) Subject: abf: exclude networks with deny rules X-Git-Tag: v23.06-rc0~27 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=6903da232304bc47fc82178bb6956e3613a9921c;p=vpp.git abf: exclude networks with deny rules Type: improvement Signed-off-by: Josh Dorsey Change-Id: Iee43ca9278922fc7396764b88cff1a87bcb28349 --- diff --git a/src/plugins/abf/FEATURE.yaml b/src/plugins/abf/FEATURE.yaml index b9f3285daa3..7902dbe7800 100644 --- a/src/plugins/abf/FEATURE.yaml +++ b/src/plugins/abf/FEATURE.yaml @@ -1,9 +1,12 @@ --- name: ACL Based Forwarding -maintainer: Neale Ranns +maintainer: Neale Ranns features: - 'Policy Based Routing' - - ACLs match traffic to be forwarded + - ACLs identify how traffic should be forwarded. Packets matching a permit + rule are forwarded using ABF policy. Packets matching a deny rule are + excluded from ABF handling and continue traversing the input feature arc on + the L3 path. - Each rule in the ACL has an associated 'path' which determines how the traffic will be forwarded. This path is described as a FIB path, so anything possible with basic L3 forwarding is possible with ABF (with the exception diff --git a/src/plugins/abf/abf_itf_attach.c b/src/plugins/abf/abf_itf_attach.c index 6f85ff69ae6..a14717e1999 100644 --- a/src/plugins/abf/abf_itf_attach.c +++ b/src/plugins/abf/abf_itf_attach.c @@ -567,10 +567,11 @@ abf_input_inline (vlib_main_t * vm, (FIB_PROTOCOL_IP6 == fproto), 1, 0, &fa_5tuple0); - if (acl_plugin_match_5tuple_inline - (acl_plugin.p_acl_main, lc_index, &fa_5tuple0, - (FIB_PROTOCOL_IP6 == fproto), &action, &match_acl_pos, - &match_acl_index, &match_rule_index, &trace_bitmap)) + if (acl_plugin_match_5tuple_inline ( + acl_plugin.p_acl_main, lc_index, &fa_5tuple0, + (FIB_PROTOCOL_IP6 == fproto), &action, &match_acl_pos, + &match_acl_index, &match_rule_index, &trace_bitmap) && + action > 0) { /* * match: diff --git a/test/test_abf.py b/test/test_abf.py index 856d02a8185..87e6842dc5f 100644 --- a/test/test_abf.py +++ b/test/test_abf.py @@ -343,6 +343,132 @@ class TestAbf(VppTestCase): # self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1) + def test_abf4_deny(self): + """IPv4 ACL Deny Rule""" + import ipaddress + + # + # Rules 1/2 + # + pg0_subnet = ipaddress.ip_network(self.pg0.local_ip4_prefix, strict=False) + pg2_subnet = ipaddress.ip_network(self.pg2.local_ip4_prefix, strict=False) + pg3_subnet = ipaddress.ip_network(self.pg3.local_ip4_prefix, strict=False) + rule_deny = AclRule( + is_permit=0, + proto=17, + ports=1234, + src_prefix=IPv4Network(pg0_subnet), + dst_prefix=IPv4Network(pg3_subnet), + ) + rule_permit = AclRule( + is_permit=1, + proto=17, + ports=1234, + src_prefix=IPv4Network(pg0_subnet), + dst_prefix=IPv4Network(pg2_subnet), + ) + acl_1 = VppAcl(self, rules=[rule_deny, rule_permit]) + acl_1.add_vpp_config() + + # + # ABF policy for ACL 1 - path via interface 1 + # + abf_1 = VppAbfPolicy( + self, 10, acl_1, [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)] + ) + abf_1.add_vpp_config() + + # + # Attach the policy to input interface Pg0 + # + attach_1 = VppAbfAttach(self, 10, self.pg0.sw_if_index, 50) + attach_1.add_vpp_config() + + # + # a packet matching the deny rule + # + p_deny = ( + Ether(src=self.pg0.remote_mac, dst=self.pg3.remote_mac) + / IP(src=self.pg0.remote_ip4, dst=self.pg3.remote_ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect(self.pg0, p_deny * NUM_PKTS, self.pg3) + + # + # a packet matching the permit rule + # + p_permit = ( + Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) + / IP(src=self.pg0.remote_ip4, dst=self.pg2.remote_ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect(self.pg0, p_permit * NUM_PKTS, self.pg1) + + def test_abf6_deny(self): + """IPv6 ACL Deny Rule""" + import ipaddress + + # + # Rules 1/2 + # + pg0_subnet = ipaddress.ip_network(self.pg0.local_ip6_prefix, strict=False) + pg2_subnet = ipaddress.ip_network(self.pg2.local_ip6_prefix, strict=False) + pg3_subnet = ipaddress.ip_network(self.pg3.local_ip6_prefix, strict=False) + rule_deny = AclRule( + is_permit=0, + proto=17, + ports=1234, + src_prefix=IPv6Network(pg0_subnet), + dst_prefix=IPv6Network(pg3_subnet), + ) + rule_permit = AclRule( + is_permit=1, + proto=17, + ports=1234, + src_prefix=IPv6Network(pg0_subnet), + dst_prefix=IPv6Network(pg2_subnet), + ) + acl_1 = VppAcl(self, rules=[rule_deny, rule_permit]) + acl_1.add_vpp_config() + + # + # ABF policy for ACL 1 - path via interface 1 + # + abf_1 = VppAbfPolicy( + self, 10, acl_1, [VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index)] + ) + abf_1.add_vpp_config() + + # + # Attach the policy to input interface Pg0 + # + attach_1 = VppAbfAttach(self, 10, self.pg0.sw_if_index, 50, is_ipv6=1) + attach_1.add_vpp_config() + + # + # a packet matching the deny rule + # + p_deny = ( + Ether(src=self.pg0.remote_mac, dst=self.pg3.remote_mac) + / IPv6(src=self.pg0.remote_ip6, dst=self.pg3.remote_ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect(self.pg0, p_deny * NUM_PKTS, self.pg3) + + # + # a packet matching the permit rule + # + p_permit = ( + Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) + / IPv6(src=self.pg0.remote_ip6, dst=self.pg2.remote_ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect(self.pg0, p_permit * NUM_PKTS, self.pg1) + if __name__ == "__main__": unittest.main(testRunner=VppTestRunner)