From 993b6bee63d4f455db0a6021c9659aad4545acf2 Mon Sep 17 00:00:00 2001 From: Piotr Bronowski Date: Wed, 31 Aug 2022 13:48:14 +0000 Subject: ipsec: introduce fast path ipv4 inbound matching This patch introduces fast path matching for inbound traffic ipv4. Fast path uses bihash tables in order to find matching policy. Adding and removing policies in fast path is much faster than in current implementation. It is still new feature and further work needs and can be done in order to improve perfromance. Type: feature Signed-off-by: Piotr Bronowski Change-Id: Ifbd5bfecc21b76ddf8363f5dc089d77595196675 --- src/vnet/ipsec/ipsec_input.c | 54 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'src/vnet/ipsec/ipsec_input.c') diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c index 09166bccf5b..0c572c83e96 100644 --- a/src/vnet/ipsec/ipsec_input.c +++ b/src/vnet/ipsec/ipsec_input.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -149,6 +150,18 @@ ipsec4_input_spd_find_flow_cache_entry (ipsec_main_t *im, u32 sa, u32 da, return p; } +always_inline void +ipsec_fp_in_5tuple_from_ip4_range (ipsec_fp_5tuple_t *tuple, u32 la, u32 ra, + u32 spi, u8 action) +{ + clib_memset (tuple->l3_zero_pad, 0, sizeof (tuple->l3_zero_pad)); + tuple->laddr.as_u32 = la; + tuple->raddr.as_u32 = ra; + tuple->spi = spi; + tuple->action = action; + tuple->is_ipv6 = 0; +} + always_inline ipsec_policy_t * ipsec_input_policy_match (ipsec_spd_t *spd, u32 sa, u32 da, ipsec_spd_policy_type_t policy_type) @@ -317,6 +330,9 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm, ipsec_policy_t *p0 = NULL; u8 has_space0; bool search_flow_cache = false; + ipsec_policy_t *policies[1]; + ipsec_fp_5tuple_t tuples[1]; + bool ip_v6 = true; if (n_left_from > 2) { @@ -351,7 +367,19 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm, search_flow_cache = im->input_flow_cache_flag; esp_or_udp: - if (search_flow_cache) // attempt to match policy in flow cache + if (im->fp_spd_ipv4_in_is_enabled && + PREDICT_TRUE (INDEX_INVALID != + spd0->fp_spd.ip4_in_lookup_hash_idx)) + { + ipsec_fp_in_5tuple_from_ip4_range ( + &tuples[0], ip0->src_address.as_u32, ip0->dst_address.as_u32, + clib_net_to_host_u32 (esp0->spi), + IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT); + ipsec_fp_in_policy_match_n (&spd0->fp_spd, !ip_v6, tuples, + policies, 1); + p0 = policies[0]; + } + else if (search_flow_cache) // attempt to match policy in flow cache { p0 = ipsec4_input_spd_find_flow_cache_entry ( im, ip0->src_address.as_u32, ip0->dst_address.as_u32, @@ -392,7 +420,16 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm, pi0 = ~0; }; - if (search_flow_cache) + if (im->fp_spd_ipv4_in_is_enabled && + PREDICT_TRUE (INDEX_INVALID != + spd0->fp_spd.ip4_in_lookup_hash_idx)) + { + tuples->action = IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS; + ipsec_fp_in_policy_match_n (&spd0->fp_spd, !ip_v6, tuples, + policies, 1); + p0 = policies[0]; + } + else if (search_flow_cache) { p0 = ipsec4_input_spd_find_flow_cache_entry ( im, ip0->src_address.as_u32, ip0->dst_address.as_u32, @@ -424,7 +461,18 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm, pi0 = ~0; }; - if (search_flow_cache) + if (im->fp_spd_ipv4_in_is_enabled && + PREDICT_TRUE (INDEX_INVALID != + spd0->fp_spd.ip4_in_lookup_hash_idx)) + { + tuples->action = IPSEC_SPD_POLICY_IP4_INBOUND_DISCARD; + ipsec_fp_in_policy_match_n (&spd0->fp_spd, !ip_v6, tuples, + policies, 1); + p0 = policies[0]; + } + else + + if (search_flow_cache) { p0 = ipsec4_input_spd_find_flow_cache_entry ( im, ip0->src_address.as_u32, ip0->dst_address.as_u32, -- cgit 1.2.3-korg