aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Bronowski <piotrx.bronowski@intel.com>2025-02-06 09:00:47 +0000
committerFan Zhang <fanzhang.oss@gmail.com>2025-02-18 09:15:06 +0000
commit0b04d71ce78d7ab7a9b2d6f323431cf14f9ed848 (patch)
treed03f327e8034c212becc8bb121a1b77d65bc4f32 /src
parent9ab79f54da29f391019ede4436896d8c5e66d6b8 (diff)
ipsec: enable support for ipv6 udp ipsec encapsulation in policy mode
IPSec traffic may be sent encapsulated inside UDP packagaes. In case of esp packgaes decryption is required (according to defined policies), whereas IKE traffic should be bypassed (relevant policy needs to be defined). With this patch required behaviour is provided. Type: feature Change-Id: If99c7bf121db881c0bdf2b45e6fdca87c0d872a5 Signed-off-by: Piotr Bronowski <piotrx.bronowski@intel.com>
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));