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))
{
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)
{
}
else
{
+ ipsec_bypassed:
ipsec_unprocessed += 1;
}
n_left_from -= 1;
return frame->n_vectors;
}
-
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ipsec4_input_node) = {
.name = "ipsec4-input-feature",