diff options
author | vinay tripathi <vinayx.tripathi@intel.com> | 2023-06-06 12:57:55 +0530 |
---|---|---|
committer | vinay Tripathi <vinayx.tripathi@intel.com> | 2023-10-31 11:41:54 +0000 |
commit | 2d7988d719d1f3cab9ac4a0762786c4b07443671 (patch) | |
tree | 8b149e722029f810d6ae860662b765519186b82c /src/vnet | |
parent | bc5f5305997e3b8f624b64bcc2d68687f31d515a (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/vnet')
-rw-r--r-- | src/vnet/ipsec/ipsec_input.c | 41 |
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", |