aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ipsec/ipsec_input.c')
-rw-r--r--src/vnet/ipsec/ipsec_input.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c
index 0c572c83e96..62723d4ffa8 100644
--- a/src/vnet/ipsec/ipsec_input.c
+++ b/src/vnet/ipsec/ipsec_input.c
@@ -52,6 +52,7 @@ typedef struct
ip_protocol_t proto;
u32 spd;
u32 policy_index;
+ u32 policy_type;
u32 sa_id;
u32 spi;
u32 seq;
@@ -65,9 +66,10 @@ format_ipsec_input_trace (u8 * s, va_list * args)
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
ipsec_input_trace_t *t = va_arg (*args, ipsec_input_trace_t *);
- s = format (s, "%U: sa_id %u spd %u policy %d spi %u (0x%08x) seq %u",
- format_ip_protocol, t->proto, t->sa_id,
- t->spd, t->policy_index, t->spi, t->spi, t->seq);
+ s =
+ format (s, "%U: sa_id %u type: %u spd %u policy %d spi %u (0x%08x) seq %u",
+ format_ip_protocol, t->proto, t->sa_id, t->policy_type, t->spd,
+ t->policy_index, t->spi, t->spi, t->seq);
return s;
}
@@ -162,6 +164,19 @@ ipsec_fp_in_5tuple_from_ip4_range (ipsec_fp_5tuple_t *tuple, u32 la, u32 ra,
tuple->is_ipv6 = 0;
}
+always_inline void
+ipsec_fp_in_5tuple_from_ip6_range (ipsec_fp_5tuple_t *tuple, ip6_address_t *la,
+ ip6_address_t *ra, u32 spi, u8 action)
+
+{
+ clib_memcpy (&tuple->ip6_laddr, la, sizeof (ip6_address_t));
+ clib_memcpy (&tuple->ip6_raddr, ra, sizeof (ip6_address_t));
+
+ tuple->spi = spi;
+ tuple->action = action;
+ tuple->is_ipv6 = 1;
+}
+
always_inline ipsec_policy_t *
ipsec_input_policy_match (ipsec_spd_t *spd, u32 sa, u32 da,
ipsec_spd_policy_type_t policy_type)
@@ -732,6 +747,9 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
ipsec_main_t *im = &ipsec_main;
u32 ipsec_unprocessed = 0;
u32 ipsec_matched = 0;
+ ipsec_policy_t *policies[1];
+ ipsec_fp_5tuple_t tuples[1];
+ bool ip_v6 = true;
from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
@@ -747,7 +765,7 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
while (n_left_from > 0 && n_left_to_next > 0)
{
- u32 bi0, next0, pi0;
+ u32 bi0, next0, pi0 = ~0;
vlib_buffer_t *b0;
ip6_header_t *ip0;
esp_header_t *esp0;
@@ -784,11 +802,22 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
clib_net_to_host_u16 (ip0->payload_length) + header_size,
spd0->id);
#endif
- p0 = ipsec6_input_protect_policy_match (spd0,
- &ip0->src_address,
- &ip0->dst_address,
- clib_net_to_host_u32
- (esp0->spi));
+ if (im->fp_spd_ipv6_in_is_enabled &&
+ PREDICT_TRUE (INDEX_INVALID !=
+ spd0->fp_spd.ip6_in_lookup_hash_idx))
+ {
+ ipsec_fp_in_5tuple_from_ip6_range (
+ &tuples[0], &ip0->src_address, &ip0->dst_address,
+ clib_net_to_host_u32 (esp0->spi),
+ IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT);
+ ipsec_fp_in_policy_match_n (&spd0->fp_spd, ip_v6, tuples,
+ policies, 1);
+ p0 = policies[0];
+ }
+ else
+ p0 = ipsec6_input_protect_policy_match (
+ spd0, &ip0->src_address, &ip0->dst_address,
+ clib_net_to_host_u32 (esp0->spi));
if (PREDICT_TRUE (p0 != 0))
{
@@ -804,6 +833,8 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
next0 = im->esp6_decrypt_next_index;
vlib_buffer_advance (b0, header_size);
+ /* TODO Add policy matching for bypass and discard policy
+ * type */
goto trace0;
}
else
@@ -855,11 +886,16 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
vlib_add_trace (vm, node, b0, sizeof (*tr));
if (p0)
- tr->sa_id = p0->sa_id;
+ {
+ tr->sa_id = p0->sa_id;
+ tr->policy_type = p0->type;
+ }
+
tr->proto = ip0->protocol;
tr->spi = clib_net_to_host_u32 (esp0->spi);
tr->seq = clib_net_to_host_u32 (esp0->seq);
tr->spd = spd0->id;
+ tr->policy_index = pi0;
}
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,