summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorvinay tripathi <vinayx.tripathi@intel.com>2023-06-06 12:57:55 +0530
committervinay Tripathi <vinayx.tripathi@intel.com>2023-10-31 11:41:54 +0000
commit2d7988d719d1f3cab9ac4a0762786c4b07443671 (patch)
tree8b149e722029f810d6ae860662b765519186b82c /src
parentbc5f5305997e3b8f624b64bcc2d68687f31d515a (diff)
ipsec: separate UDP and UDP-encapsulated ESP packet processing
This fix differentiates UDP and UDP-encapsulated ESP packets processing. While UDP-encapsulated ESP traffic is processed as IPsec traffic, UDP as other plain-text protocols is NOT dispatched against SPD policies. Key logic is taken from RFC 3948, and is based on the fact that the checksum of UDP packet encapsulating ESP packet must be zero. Type: fix Signed-off-by: vinay tripathi <vinayx.tripathi@intel.com> Change-Id: Ib1b4d240eea8e89f2daf17ec833905f26cdb31bd
Diffstat (limited to 'src')
-rw-r--r--src/vnet/ipsec/ipsec_input.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c
index 0e92ae9f1a7..8f9eb204c55 100644
--- a/src/vnet/ipsec/ipsec_input.c
+++ b/src/vnet/ipsec/ipsec_input.c
@@ -299,6 +299,15 @@ ipsec_esp_packet_process (vlib_main_t *vm, ipsec_main_t *im, ip4_header_t *ip0,
search_flow_cache = im->input_flow_cache_flag;
udp_or_esp:
+ /* SPI ID field in the ESP header MUST NOT be a zero value */
+ if (esp0->spi == 0)
+ {
+ /* Drop the packet if SPI ID is zero */
+ *ipsec_unprocessed += 1;
+ next[0] = IPSEC_INPUT_NEXT_DROP;
+ return;
+ }
+
if (im->fp_spd_ipv4_in_is_enabled &&
PREDICT_TRUE (INDEX_INVALID != spd0->fp_spd.ip4_in_lookup_hash_idx))
{
@@ -538,20 +547,36 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
ip0 = vlib_buffer_get_current (b[0]);
- if (PREDICT_TRUE
- (ip0->protocol == IP_PROTOCOL_IPSEC_ESP
- || ip0->protocol == IP_PROTOCOL_UDP))
+ if (ip0->protocol == IP_PROTOCOL_UDP)
{
+ udp_header_t *udp0 = NULL;
+ udp0 = (udp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
- esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
- if (PREDICT_FALSE (ip0->protocol == IP_PROTOCOL_UDP))
+ /* As per rfc3948 in UDP Encapsulated Header, UDP checksum must be
+ * Zero, and receivers must not depen upon UPD checksum.
+ * inside ESP header , SPI ID value MUST NOT be a zero value
+ * */
+
+ if (udp0->checksum == 0)
{
- /* FIXME Skip, if not a UDP encapsulated packet */
- esp0 = (esp_header_t *) ((u8 *) esp0 + sizeof (udp_header_t));
+ esp0 = (esp_header_t *) ((u8 *) udp0 + sizeof (udp_header_t));
+
+ ipsec_esp_packet_process (vm, im, ip0, esp0, thread_index, spd0,
+ b, node, &ipsec_bypassed,
+ &ipsec_dropped, &ipsec_matched,
+ &ipsec_unprocessed, next);
+ if (ipsec_bypassed > 0)
+ goto ipsec_bypassed;
}
+ }
+ else if (PREDICT_TRUE (ip0->protocol == IP_PROTOCOL_IPSEC_ESP))
+ {
+ esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
ipsec_esp_packet_process (vm, im, ip0, esp0, thread_index, spd0, b,
node, &ipsec_bypassed, &ipsec_dropped,
&ipsec_matched, &ipsec_unprocessed, next);
+ if (ipsec_bypassed > 0)
+ goto ipsec_bypassed;
}
else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH)
{
@@ -694,6 +719,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
}
else
{
+ ipsec_bypassed:
ipsec_unprocessed += 1;
}
n_left_from -= 1;
@@ -725,7 +751,6 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ipsec4_input_node) = {
.name = "ipsec4-input-feature",