From: Piotr Bronowski Date: Thu, 17 Oct 2024 15:16:06 +0000 (+0200) Subject: ipsec: fix spd fast path single match compare for ipv6 X-Git-Tag: v25.06-rc0~51 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F21%2F41721%2F5;p=vpp.git ipsec: fix spd fast path single match compare for ipv6 Fast path match single compare (the last step of policy matching in spd fast path) is only implemented for IPv4 addresses. This change adds support to also do a single match on IPv6 addresses. Type: fix Change-Id: I5aeb6e1e9afccfd2b2082e26502c5b7e9a8b2d4c Signed-off-by: Piotr Bronowski Signed-off-by: Vinayak Udandkar --- diff --git a/src/vnet/ipsec/ipsec_spd_fp_lookup.h b/src/vnet/ipsec/ipsec_spd_fp_lookup.h index 2bbd7c664f9..6162035fda8 100644 --- a/src/vnet/ipsec/ipsec_spd_fp_lookup.h +++ b/src/vnet/ipsec/ipsec_spd_fp_lookup.h @@ -96,9 +96,7 @@ single_rule_out_match_5tuple (ipsec_policy_t *policy, ipsec_fp_5tuple_t *match) static_always_inline int single_rule_in_match_5tuple (ipsec_policy_t *policy, ipsec_fp_5tuple_t *match) { - - u32 da = clib_net_to_host_u32 (match->laddr.as_u32); - u32 sa = clib_net_to_host_u32 (match->raddr.as_u32); + u32 da, sa; if (policy->policy == IPSEC_POLICY_ACTION_PROTECT) { @@ -109,26 +107,104 @@ single_rule_in_match_5tuple (ipsec_policy_t *policy, ipsec_fp_5tuple_t *match) if (ipsec_sa_is_set_IS_TUNNEL (s)) { - if (da != clib_net_to_host_u32 (s->tunnel.t_dst.ip.ip4.as_u32)) - return (0); + if (!policy->is_ipv6) + { + da = clib_net_to_host_u32 (match->laddr.as_u32); + sa = clib_net_to_host_u32 (match->raddr.as_u32); - if (sa != clib_net_to_host_u32 (s->tunnel.t_src.ip.ip4.as_u32)) - return (0); + if (da != clib_net_to_host_u32 (s->tunnel.t_dst.ip.ip4.as_u32)) + return (0); + + if (sa != clib_net_to_host_u32 (s->tunnel.t_src.ip.ip4.as_u32)) + return (0); + } + else + { + if (ip6_address_compare (&match->ip6_laddr, + &s->tunnel.t_dst.ip.ip6) != 0) + return (0); + + if (ip6_address_compare (&match->ip6_raddr, + &s->tunnel.t_src.ip.ip6) != 0) + return (0); + } + } + else + { + if (!policy->is_ipv6) + { + da = clib_net_to_host_u32 (match->laddr.as_u32); + sa = clib_net_to_host_u32 (match->raddr.as_u32); + + if (sa < clib_net_to_host_u32 (policy->raddr.start.ip4.as_u32)) + return (0); + + if (sa > clib_net_to_host_u32 (policy->raddr.stop.ip4.as_u32)) + return (0); + + if (da < clib_net_to_host_u32 (policy->laddr.start.ip4.as_u32)) + return (0); + + if (da > clib_net_to_host_u32 (policy->laddr.stop.ip4.as_u32)) + return (0); + } + else + { + if (ip6_address_compare (&match->ip6_laddr, + &policy->laddr.start.ip6) < 0) + return (0); + + if (ip6_address_compare (&policy->laddr.stop.ip6, + &match->ip6_laddr) < 0) + return (0); + + if (ip6_address_compare (&match->ip6_raddr, + &policy->raddr.start.ip6) < 0) + return (0); + + if (ip6_address_compare (&policy->raddr.stop.ip6, + &match->ip6_raddr) < 0) + return (0); + } } } else { - if (sa < clib_net_to_host_u32 (policy->raddr.start.ip4.as_u32)) - return (0); + if (!policy->is_ipv6) + { + da = clib_net_to_host_u32 (match->laddr.as_u32); + sa = clib_net_to_host_u32 (match->raddr.as_u32); - if (sa > clib_net_to_host_u32 (policy->raddr.stop.ip4.as_u32)) - return (0); + if (sa < clib_net_to_host_u32 (policy->raddr.start.ip4.as_u32)) + return (0); - if (da < clib_net_to_host_u32 (policy->laddr.start.ip4.as_u32)) - return (0); + if (sa > clib_net_to_host_u32 (policy->raddr.stop.ip4.as_u32)) + return (0); - if (da > clib_net_to_host_u32 (policy->laddr.stop.ip4.as_u32)) - return (0); + if (da < clib_net_to_host_u32 (policy->laddr.start.ip4.as_u32)) + return (0); + + if (da > clib_net_to_host_u32 (policy->laddr.stop.ip4.as_u32)) + return (0); + } + else + { + if (ip6_address_compare (&match->ip6_laddr, + &policy->laddr.start.ip6) < 0) + return (0); + + if (ip6_address_compare (&policy->laddr.stop.ip6, + &match->ip6_laddr) < 0) + return (0); + + if (ip6_address_compare (&match->ip6_raddr, + &policy->raddr.start.ip6) < 0) + return (0); + + if (ip6_address_compare (&policy->raddr.stop.ip6, + &match->ip6_raddr) < 0) + return (0); + } } return (1); }