diff options
author | Piotr Bronowski <piotrx.bronowski@intel.com> | 2024-10-17 17:16:06 +0200 |
---|---|---|
committer | Fan Zhang <fanzhang.oss@gmail.com> | 2025-01-08 13:47:36 +0000 |
commit | 36132815da2efe0e2d9b2d7b145a3bece8d6e757 (patch) | |
tree | 440ea1f9ee11d25f8a52441a2aad8eb16a3938b0 | |
parent | 4d9df5cb3da12498ffd41ee2adddc97dfe31e626 (diff) |
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 <piotrx.bronowski@intel.com>
Signed-off-by: Vinayak Udandkar <vinayakx.udandkar@intel.com>
-rw-r--r-- | src/vnet/ipsec/ipsec_spd_fp_lookup.h | 106 |
1 files changed, 91 insertions, 15 deletions
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); } |