summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Bronowski <piotrx.bronowski@intel.com>2024-10-17 17:16:06 +0200
committerFan Zhang <fanzhang.oss@gmail.com>2025-01-08 13:47:36 +0000
commit36132815da2efe0e2d9b2d7b145a3bece8d6e757 (patch)
tree440ea1f9ee11d25f8a52441a2aad8eb16a3938b0
parent4d9df5cb3da12498ffd41ee2adddc97dfe31e626 (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.h106
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);
}