#include <vnet/ipsec/ipsec_io.h>
#include <vnet/ipsec/ipsec_tun.h>
-#include <vnet/gre/gre.h>
+#include <vnet/gre/packet.h>
-#define foreach_esp_decrypt_next \
-_(DROP, "error-drop") \
-_(IP4_INPUT, "ip4-input-no-checksum") \
-_(IP6_INPUT, "ip6-input") \
-_(L2_INPUT, "l2-input") \
-_(HANDOFF, "handoff")
+#define foreach_esp_decrypt_next \
+ _ (DROP, "error-drop") \
+ _ (IP4_INPUT, "ip4-input-no-checksum") \
+ _ (IP6_INPUT, "ip6-input") \
+ _ (L2_INPUT, "l2-input") \
+ _ (MPLS_INPUT, "mpls-input") \
+ _ (HANDOFF, "handoff")
#define _(v, s) ESP_DECRYPT_NEXT_##v,
typedef enum
ESP_DECRYPT_N_NEXT,
} esp_decrypt_next_t;
-#define foreach_esp_decrypt_post_next \
-_(DROP, "error-drop") \
-_(IP4_INPUT, "ip4-input-no-checksum") \
-_(IP6_INPUT, "ip6-input") \
-_(L2_INPUT, "l2-input")
+#define foreach_esp_decrypt_post_next \
+ _ (DROP, "error-drop") \
+ _ (IP4_INPUT, "ip4-input-no-checksum") \
+ _ (IP6_INPUT, "ip6-input") \
+ _ (MPLS_INPUT, "mpls-input") \
+ _ (L2_INPUT, "l2-input")
#define _(v, s) ESP_DECRYPT_POST_NEXT_##v,
typedef enum
return pointer to it */
static_always_inline u8 *
esp_move_icv (vlib_main_t * vm, vlib_buffer_t * first,
+ esp_decrypt_packet_data_t * pd,
esp_decrypt_packet_data2_t * pd2, u16 icv_sz, u16 * dif)
{
vlib_buffer_t *before_last, *bp;
clib_memcpy_fast (lb_curr, vlib_buffer_get_tail (before_last) - first_sz,
first_sz);
before_last->current_length -= first_sz;
+ if (before_last == first)
+ pd->current_length -= first_sz;
clib_memset (vlib_buffer_get_tail (before_last), 0, first_sz);
if (dif)
dif[0] = first_sz;
static_always_inline u8 *
esp_move_icv_esn (vlib_main_t * vm, vlib_buffer_t * first,
+ esp_decrypt_packet_data_t * pd,
esp_decrypt_packet_data2_t * pd2, u16 icv_sz,
ipsec_sa_t * sa, u8 * extra_esn, u32 * len)
{
u16 dif = 0;
- u8 *digest = esp_move_icv (vm, first, pd2, icv_sz, &dif);
+ u8 *digest = esp_move_icv (vm, first, pd, pd2, icv_sz, &dif);
if (dif)
*len -= dif;
static_always_inline u32
esp_decrypt_chain_crypto (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
+ esp_decrypt_packet_data_t * pd,
esp_decrypt_packet_data2_t * pd2,
ipsec_sa_t * sa0, vlib_buffer_t * b, u8 icv_sz,
u8 * start, u32 start_len, u8 ** tag, u16 * n_ch)
if (pd2->lb->current_length < icv_sz)
{
u16 dif = 0;
- *tag = esp_move_icv (vm, b, pd2, icv_sz, &dif);
+ *tag = esp_move_icv (vm, b, pd, pd2, icv_sz, &dif);
/* this chunk does not contain crypto data */
n_chunks -= 1;
{
u8 extra_esn = 0;
op->digest =
- esp_move_icv_esn (vm, b, pd2, icv_sz, sa0,
+ esp_move_icv_esn (vm, b, pd, pd2, icv_sz, sa0,
&extra_esn, &op->len);
if (extra_esn)
/* buffer is chained */
op->flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
op->chunk_index = vec_len (ptd->chunks);
- esp_decrypt_chain_crypto (vm, ptd, pd2, sa0, b, icv_sz,
+ esp_decrypt_chain_crypto (vm, ptd, pd, pd2, sa0, b, icv_sz,
payload, len - pd->iv_sz + pd->icv_sz,
&op->tag, &op->n_chunks);
}
if (pd2->lb->current_length < icv_sz)
{
u8 extra_esn = 0;
- tag = esp_move_icv_esn (vm, b, pd2, icv_sz, sa0,
+ tag = esp_move_icv_esn (vm, b, pd, pd2, icv_sz, sa0,
&extra_esn, &integ_len);
if (extra_esn)
/* buffer is chained */
flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
- crypto_len = esp_decrypt_chain_crypto (vm, ptd, pd2, sa0, b, icv_sz,
+ crypto_len = esp_decrypt_chain_crypto (vm, ptd, pd, pd2, sa0, b, icv_sz,
payload,
len - pd->iv_sz + pd->icv_sz,
&tag, 0);
b->current_length = pd->current_length - adv;
esp_remove_tail (vm, b, lb, tail);
}
+ else if (next_header == IP_PROTOCOL_MPLS_IN_IP)
+ {
+ next[0] = ESP_DECRYPT_NEXT_MPLS_INPUT;
+ b->current_data = pd->current_data + adv;
+ b->current_length = pd->current_length - adv;
+ esp_remove_tail (vm, b, lb, tail);
+ }
else
{
if (is_tun && next_header == IP_PROTOCOL_GRE)
ipsec_sa_assign_thread (thread_index));
}
- if (PREDICT_TRUE (thread_index != sa0->decrypt_thread_index))
+ if (PREDICT_FALSE (thread_index != sa0->decrypt_thread_index))
{
esp_set_next_index (is_async, from, nexts, from[b - bufs],
&n_async_drop, ESP_DECRYPT_NEXT_HANDOFF, next);
[ESP_DECRYPT_NEXT_DROP] = "ip4-drop",
[ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
[ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
+ [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-drop",
[ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
[ESP_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-handoff",
},
[ESP_DECRYPT_NEXT_DROP] = "ip6-drop",
[ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
[ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
+ [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-drop",
[ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
[ESP_DECRYPT_NEXT_HANDOFF]= "esp6-decrypt-handoff",
},
[ESP_DECRYPT_NEXT_DROP] = "ip4-drop",
[ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
[ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
+ [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-input",
[ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
[ESP_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-tun-handoff",
},
[ESP_DECRYPT_NEXT_DROP] = "ip6-drop",
[ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
[ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
+ [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-input",
[ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
[ESP_DECRYPT_NEXT_HANDOFF]= "esp6-decrypt-tun-handoff",
},