aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vnet/ipsec/ipsec_input.c81
1 files changed, 49 insertions, 32 deletions
diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c
index a1ee83d0d74..a20c8317144 100644
--- a/src/vnet/ipsec/ipsec_input.c
+++ b/src/vnet/ipsec/ipsec_input.c
@@ -854,39 +854,43 @@ ipsec6_esp_packet_process (vlib_main_t *vm, ipsec_main_t *im,
&tuples[0], &ip0->src_address, &ip0->dst_address,
clib_net_to_host_u32 (esp0->spi), IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT);
- if (im->fp_spd_ipv6_in_is_enabled &&
- PREDICT_TRUE (INDEX_INVALID != spd0->fp_spd.ip6_in_lookup_hash_idx))
- {
- ipsec_fp_in_policy_match_n (&spd0->fp_spd, ip_v6, tuples, policies, 1);
- p0 = policies[0];
- }
- else /* linear search if fast path is not enabled */
+ if (esp0->spi != 0)
{
- p0 = ipsec6_input_protect_policy_match (
- spd0, &ip0->src_address, &ip0->dst_address,
- clib_net_to_host_u32 (esp0->spi));
- }
- has_space0 = vlib_buffer_has_space (b[0], (clib_address_t) (esp0 + 1) -
- (clib_address_t) ip0);
+ if (im->fp_spd_ipv6_in_is_enabled &&
+ PREDICT_TRUE (INDEX_INVALID != spd0->fp_spd.ip6_in_lookup_hash_idx))
+ {
+ ipsec_fp_in_policy_match_n (&spd0->fp_spd, ip_v6, tuples, policies,
+ 1);
+ p0 = policies[0];
+ }
+ else /* linear search if fast path is not enabled */
+ {
+ p0 = ipsec6_input_protect_policy_match (
+ spd0, &ip0->src_address, &ip0->dst_address,
+ clib_net_to_host_u32 (esp0->spi));
+ }
+ has_space0 = vlib_buffer_has_space (b[0], (clib_address_t) (esp0 + 1) -
+ (clib_address_t) ip0);
- if (PREDICT_TRUE ((p0 != NULL) && (has_space0)))
- {
- *ipsec_matched += 1;
+ if (PREDICT_TRUE ((p0 != NULL) && (has_space0)))
+ {
+ *ipsec_matched += 1;
- pi0 = p0 - im->policies;
- vlib_increment_combined_counter (
- &ipsec_spd_policy_counters, thread_index, pi0, 1,
- clib_net_to_host_u16 (ip0->payload_length));
+ pi0 = p0 - im->policies;
+ vlib_increment_combined_counter (
+ &ipsec_spd_policy_counters, thread_index, pi0, 1,
+ clib_net_to_host_u16 (ip0->payload_length));
- vnet_buffer (b[0])->ipsec.sad_index = p0->sa_index;
- next[0] = im->esp6_decrypt_next_index;
- vlib_buffer_advance (b[0], ((u8 *) esp0 - (u8 *) ip0));
- goto trace0;
- }
- else
- {
- p0 = NULL;
- pi0 = ~0;
+ vnet_buffer (b[0])->ipsec.sad_index = p0->sa_index;
+ next[0] = im->esp6_decrypt_next_index;
+ vlib_buffer_advance (b[0], ((u8 *) esp0 - (u8 *) ip0));
+ goto trace0;
+ }
+ else
+ {
+ p0 = NULL;
+ pi0 = ~0;
+ }
}
if (im->fp_spd_ipv6_in_is_enabled &&
@@ -999,7 +1003,6 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
ip4_ipsec_config_t *c0;
ipsec_spd_t *spd0;
ipsec_policy_t *p0 = 0;
- ah_header_t *ah0;
u32 header_size = sizeof (ip0[0]);
u64 ipsec_unprocessed = 0, ipsec_matched = 0;
u64 ipsec_dropped = 0, ipsec_bypassed = 0;
@@ -1018,9 +1021,21 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
spd0 = pool_elt_at_index (im->spds, c0->spd_index);
ip0 = vlib_buffer_get_current (b0);
- ah0 = (ah_header_t *) ((u8 *) ip0 + header_size);
- if (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)
+ if (ip0->protocol == IP_PROTOCOL_UDP)
+ {
+ udp_header_t *udp0 = (udp_header_t *) ((u8 *) ip0 + header_size);
+
+ /* RFC5996 Section 2.23: "Port 4500 is reserved for
+ * UDP-encapsulated ESP and IKE."
+ * RFC5996 Section 3.1: "IKE messages use UDP ports 500 and/or
+ 4500"
+ */
+ if ((clib_host_to_net_u16 (500) == udp0->dst_port) ||
+ (clib_host_to_net_u16 (4500) == udp0->dst_port))
+ esp0 = (esp_header_t *) ((u8 *) udp0 + sizeof (udp_header_t));
+ }
+ else if (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)
esp0 = (esp_header_t *) ((u8 *) ip0 + header_size);
if (esp0 != NULL)
@@ -1032,6 +1047,8 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
}
else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH)
{
+ ah_header_t *ah0 = (ah_header_t *) ((u8 *) ip0 + header_size);
+
p0 = ipsec6_input_protect_policy_match (
spd0, &ip0->src_address, &ip0->dst_address,
clib_net_to_host_u32 (ah0->spi));