aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/esp_encrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ipsec/esp_encrypt.c')
-rw-r--r--src/vnet/ipsec/esp_encrypt.c523
1 files changed, 240 insertions, 283 deletions
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index 1e0bd7facf5..080a3458926 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -122,325 +122,282 @@ esp_encrypt_inline (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * from_frame,
int is_ip6)
{
- u32 n_left_from, *from, *to_next = 0, next_index;
- from = vlib_frame_vector_args (from_frame);
- n_left_from = from_frame->n_vectors;
+ u32 *from = vlib_frame_vector_args (from_frame);
+ u32 n_left_from = from_frame->n_vectors;
ipsec_main_t *im = &ipsec_main;
ipsec_proto_main_t *em = &ipsec_proto_main;
- u32 *recycle = 0;
- u32 thread_index = vm->thread_index;
-
- ipsec_alloc_empty_buffers (vm, im);
-
- u32 *empty_buffers = im->empty_buffers[thread_index];
-
- if (PREDICT_FALSE (vec_len (empty_buffers) < n_left_from))
+ u32 new_bufs[VLIB_FRAME_SIZE];
+ vlib_buffer_t *i_bufs[VLIB_FRAME_SIZE], **ib = i_bufs;
+ vlib_buffer_t *o_bufs[VLIB_FRAME_SIZE], **ob = o_bufs;
+ u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
+ u32 n_alloc, thread_index = vm->thread_index;
+
+ n_alloc = vlib_buffer_alloc (vm, new_bufs, n_left_from);
+ if (n_alloc != n_left_from)
{
vlib_node_increment_counter (vm, node->node_index,
- ESP_ENCRYPT_ERROR_NO_BUFFER, n_left_from);
- clib_warning ("not enough empty buffers. discarding frame");
- goto free_buffers_and_exit;
+ ESP_ENCRYPT_ERROR_NO_BUFFER,
+ n_left_from - n_alloc);
+ if (n_alloc == 0)
+ goto done;
+ n_left_from = n_alloc;
}
- next_index = node->cached_next_index;
+ vlib_get_buffers (vm, from, ib, n_left_from);
+ vlib_get_buffers (vm, new_bufs, ob, n_left_from);
while (n_left_from > 0)
{
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
+ u32 sa_index0;
+ ipsec_sa_t *sa0;
+ ip4_and_esp_header_t *oh0 = 0;
+ ip6_and_esp_header_t *ih6_0, *oh6_0 = 0;
+ ip4_and_udp_and_esp_header_t *iuh0, *ouh0 = 0;
+ esp_header_t *o_esp0;
+ esp_footer_t *f0;
+ u8 ip_udp_hdr_size;
+ u8 next_hdr_type;
+ u32 ip_proto = 0;
+ u8 transport_mode = 0;
+ u32 esp_seq_err;
+
+ next[0] = ESP_ENCRYPT_NEXT_DROP;
+
+ sa_index0 = vnet_buffer (ib[0])->ipsec.sad_index;
+ sa0 = pool_elt_at_index (im->sad, sa_index0);
+
+ vlib_prefetch_combined_counter (&ipsec_sa_counters, thread_index,
+ sa_index0);
+
+ esp_seq_err = esp_seq_advance (sa0);
+
+ /* grab free buffer */
+ ob[0]->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
+ ob[0]->current_data = sizeof (ethernet_header_t);
+ iuh0 = vlib_buffer_get_current (ib[0]);
+
+ if (is_ip6)
{
- u32 i_bi0, o_bi0, next0;
- vlib_buffer_t *i_b0, *o_b0 = 0;
- u32 sa_index0;
- ipsec_sa_t *sa0;
- ip4_and_esp_header_t *oh0 = 0;
- ip6_and_esp_header_t *ih6_0, *oh6_0 = 0;
- ip4_and_udp_and_esp_header_t *iuh0, *ouh0 = 0;
- uword last_empty_buffer;
- esp_header_t *o_esp0;
- esp_footer_t *f0;
- u8 ip_udp_hdr_size;
- u8 next_hdr_type;
- u32 ip_proto = 0;
- u8 transport_mode = 0;
-
- i_bi0 = from[0];
- from += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- next0 = ESP_ENCRYPT_NEXT_DROP;
-
- i_b0 = vlib_get_buffer (vm, i_bi0);
- sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
- sa0 = pool_elt_at_index (im->sad, sa_index0);
-
- vlib_prefetch_combined_counter
- (&ipsec_sa_counters, thread_index, sa_index0);
-
- if (PREDICT_FALSE (esp_seq_advance (sa0)))
- {
- clib_warning ("sequence number counter has cycled SPI %u",
- sa0->spi);
- vlib_node_increment_counter (vm, node->node_index,
- ESP_ENCRYPT_ERROR_SEQ_CYCLED, 1);
- //TODO: rekey SA
- o_bi0 = i_bi0;
- to_next[0] = o_bi0;
- to_next += 1;
- goto trace;
- }
-
- /* grab free buffer */
- last_empty_buffer = vec_len (empty_buffers) - 1;
- o_bi0 = empty_buffers[last_empty_buffer];
- o_b0 = vlib_get_buffer (vm, o_bi0);
- o_b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
- o_b0->current_data = sizeof (ethernet_header_t);
- iuh0 = vlib_buffer_get_current (i_b0);
- vlib_prefetch_buffer_with_index (vm,
- empty_buffers[last_empty_buffer -
- 1], STORE);
- _vec_len (empty_buffers) = last_empty_buffer;
- to_next[0] = o_bi0;
- to_next += 1;
-
- /* add old buffer to the recycle list */
- vec_add1 (recycle, i_bi0);
-
- if (is_ip6)
+ ih6_0 = vlib_buffer_get_current (ib[0]);
+ next_hdr_type = IP_PROTOCOL_IPV6;
+ oh6_0 = vlib_buffer_get_current (ob[0]);
+
+ oh6_0->ip6.ip_version_traffic_class_and_flow_label =
+ ih6_0->ip6.ip_version_traffic_class_and_flow_label;
+ oh6_0->ip6.protocol = IP_PROTOCOL_IPSEC_ESP;
+ ip_udp_hdr_size = sizeof (ip6_header_t);
+ o_esp0 = vlib_buffer_get_current (ob[0]) + ip_udp_hdr_size;
+ oh6_0->ip6.hop_limit = 254;
+ oh6_0->ip6.src_address.as_u64[0] = ih6_0->ip6.src_address.as_u64[0];
+ oh6_0->ip6.src_address.as_u64[1] = ih6_0->ip6.src_address.as_u64[1];
+ oh6_0->ip6.dst_address.as_u64[0] = ih6_0->ip6.dst_address.as_u64[0];
+ oh6_0->ip6.dst_address.as_u64[1] = ih6_0->ip6.dst_address.as_u64[1];
+ o_esp0->spi = clib_net_to_host_u32 (sa0->spi);
+ o_esp0->seq = clib_net_to_host_u32 (sa0->seq);
+ ip_proto = ih6_0->ip6.protocol;
+
+ next[0] = ESP_ENCRYPT_NEXT_IP6_LOOKUP;
+ }
+ else
+ {
+ next_hdr_type = IP_PROTOCOL_IP_IN_IP;
+ oh0 = vlib_buffer_get_current (ob[0]);
+ ouh0 = vlib_buffer_get_current (ob[0]);
+
+ oh0->ip4.ip_version_and_header_length = 0x45;
+ oh0->ip4.tos = iuh0->ip4.tos;
+ oh0->ip4.fragment_id = 0;
+ oh0->ip4.flags_and_fragment_offset = 0;
+ oh0->ip4.ttl = 254;
+ if (sa0->udp_encap)
{
- ih6_0 = vlib_buffer_get_current (i_b0);
- next_hdr_type = IP_PROTOCOL_IPV6;
- oh6_0 = vlib_buffer_get_current (o_b0);
-
- oh6_0->ip6.ip_version_traffic_class_and_flow_label =
- ih6_0->ip6.ip_version_traffic_class_and_flow_label;
- oh6_0->ip6.protocol = IP_PROTOCOL_IPSEC_ESP;
- ip_udp_hdr_size = sizeof (ip6_header_t);
- o_esp0 = vlib_buffer_get_current (o_b0) + ip_udp_hdr_size;
- oh6_0->ip6.hop_limit = 254;
- oh6_0->ip6.src_address.as_u64[0] =
- ih6_0->ip6.src_address.as_u64[0];
- oh6_0->ip6.src_address.as_u64[1] =
- ih6_0->ip6.src_address.as_u64[1];
- oh6_0->ip6.dst_address.as_u64[0] =
- ih6_0->ip6.dst_address.as_u64[0];
- oh6_0->ip6.dst_address.as_u64[1] =
- ih6_0->ip6.dst_address.as_u64[1];
- o_esp0->spi = clib_net_to_host_u32 (sa0->spi);
- o_esp0->seq = clib_net_to_host_u32 (sa0->seq);
- ip_proto = ih6_0->ip6.protocol;
-
- next0 = ESP_ENCRYPT_NEXT_IP6_LOOKUP;
+ ouh0->udp.src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+ ouh0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+ ouh0->udp.checksum = 0;
+ ouh0->ip4.protocol = IP_PROTOCOL_UDP;
+ ip_udp_hdr_size = sizeof (udp_header_t) + sizeof (ip4_header_t);
}
else
{
- next_hdr_type = IP_PROTOCOL_IP_IN_IP;
- oh0 = vlib_buffer_get_current (o_b0);
- ouh0 = vlib_buffer_get_current (o_b0);
-
- oh0->ip4.ip_version_and_header_length = 0x45;
- oh0->ip4.tos = iuh0->ip4.tos;
- oh0->ip4.fragment_id = 0;
- oh0->ip4.flags_and_fragment_offset = 0;
- oh0->ip4.ttl = 254;
- if (sa0->udp_encap)
- {
- ouh0->udp.src_port =
- clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
- ouh0->udp.dst_port =
- clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
- ouh0->udp.checksum = 0;
- ouh0->ip4.protocol = IP_PROTOCOL_UDP;
- ip_udp_hdr_size =
- sizeof (udp_header_t) + sizeof (ip4_header_t);
- }
- else
- {
- oh0->ip4.protocol = IP_PROTOCOL_IPSEC_ESP;
- ip_udp_hdr_size = sizeof (ip4_header_t);
- }
- o_esp0 = vlib_buffer_get_current (o_b0) + ip_udp_hdr_size;
- oh0->ip4.src_address.as_u32 = iuh0->ip4.src_address.as_u32;
- oh0->ip4.dst_address.as_u32 = iuh0->ip4.dst_address.as_u32;
- o_esp0->spi = clib_net_to_host_u32 (sa0->spi);
- o_esp0->seq = clib_net_to_host_u32 (sa0->seq);
- ip_proto = iuh0->ip4.protocol;
-
- next0 = ESP_ENCRYPT_NEXT_IP4_LOOKUP;
+ oh0->ip4.protocol = IP_PROTOCOL_IPSEC_ESP;
+ ip_udp_hdr_size = sizeof (ip4_header_t);
}
+ o_esp0 = vlib_buffer_get_current (ob[0]) + ip_udp_hdr_size;
+ oh0->ip4.src_address.as_u32 = iuh0->ip4.src_address.as_u32;
+ oh0->ip4.dst_address.as_u32 = iuh0->ip4.dst_address.as_u32;
+ o_esp0->spi = clib_net_to_host_u32 (sa0->spi);
+ o_esp0->seq = clib_net_to_host_u32 (sa0->seq);
+ ip_proto = iuh0->ip4.protocol;
+
+ next[0] = ESP_ENCRYPT_NEXT_IP4_LOOKUP;
+ }
- if (PREDICT_TRUE (!is_ip6 && sa0->is_tunnel && !sa0->is_tunnel_ip6))
- {
- oh0->ip4.src_address.as_u32 = sa0->tunnel_src_addr.ip4.as_u32;
- oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32;
+ if (PREDICT_TRUE (!is_ip6 && sa0->is_tunnel && !sa0->is_tunnel_ip6))
+ {
+ oh0->ip4.src_address.as_u32 = sa0->tunnel_src_addr.ip4.as_u32;
+ oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32;
- next0 = sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_next_node;
- vnet_buffer (o_b0)->ip.adj_index[VLIB_TX] =
- sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_index;
- }
- else if (is_ip6 && sa0->is_tunnel && sa0->is_tunnel_ip6)
+ next[0] = sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_next_node;
+ vnet_buffer (ob[0])->ip.adj_index[VLIB_TX] =
+ sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_index;
+ }
+ else if (is_ip6 && sa0->is_tunnel && sa0->is_tunnel_ip6)
+ {
+ oh6_0->ip6.src_address.as_u64[0] =
+ sa0->tunnel_src_addr.ip6.as_u64[0];
+ oh6_0->ip6.src_address.as_u64[1] =
+ sa0->tunnel_src_addr.ip6.as_u64[1];
+ oh6_0->ip6.dst_address.as_u64[0] =
+ sa0->tunnel_dst_addr.ip6.as_u64[0];
+ oh6_0->ip6.dst_address.as_u64[1] =
+ sa0->tunnel_dst_addr.ip6.as_u64[1];
+
+ next[0] = sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_next_node;
+ vnet_buffer (ob[0])->ip.adj_index[VLIB_TX] =
+ sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_index;
+ }
+ else
+ {
+ next_hdr_type = ip_proto;
+ if (vnet_buffer (ib[0])->sw_if_index[VLIB_TX] != ~0)
{
- oh6_0->ip6.src_address.as_u64[0] =
- sa0->tunnel_src_addr.ip6.as_u64[0];
- oh6_0->ip6.src_address.as_u64[1] =
- sa0->tunnel_src_addr.ip6.as_u64[1];
- oh6_0->ip6.dst_address.as_u64[0] =
- sa0->tunnel_dst_addr.ip6.as_u64[0];
- oh6_0->ip6.dst_address.as_u64[1] =
- sa0->tunnel_dst_addr.ip6.as_u64[1];
-
- next0 = sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_next_node;
- vnet_buffer (o_b0)->ip.adj_index[VLIB_TX] =
- sa0->dpo[IPSEC_PROTOCOL_ESP].dpoi_index;
+ transport_mode = 1;
+ ethernet_header_t *ieh0, *oeh0;
+ ieh0 =
+ (ethernet_header_t *) ((u8 *)
+ vlib_buffer_get_current (ib[0]) -
+ sizeof (ethernet_header_t));
+ oeh0 = (ethernet_header_t *) ob[0]->data;
+ clib_memcpy_fast (oeh0, ieh0, sizeof (ethernet_header_t));
+ next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
+ vnet_buffer (ob[0])->sw_if_index[VLIB_TX] =
+ vnet_buffer (ib[0])->sw_if_index[VLIB_TX];
}
+
+ if (is_ip6)
+ vlib_buffer_advance (ib[0], sizeof (ip6_header_t));
else
- {
- next_hdr_type = ip_proto;
- if (vnet_buffer (i_b0)->sw_if_index[VLIB_TX] != ~0)
- {
- transport_mode = 1;
- ethernet_header_t *ieh0, *oeh0;
- ieh0 =
- (ethernet_header_t *) ((u8 *)
- vlib_buffer_get_current (i_b0) -
- sizeof (ethernet_header_t));
- oeh0 = (ethernet_header_t *) o_b0->data;
- clib_memcpy_fast (oeh0, ieh0, sizeof (ethernet_header_t));
- next0 = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
- vnet_buffer (o_b0)->sw_if_index[VLIB_TX] =
- vnet_buffer (i_b0)->sw_if_index[VLIB_TX];
- }
-
- if (is_ip6)
- {
- vlib_buffer_advance (i_b0, sizeof (ip6_header_t));
- }
- else
- {
- vlib_buffer_advance (i_b0, sizeof (ip4_header_t));
- }
- }
+ vlib_buffer_advance (ib[0], sizeof (ip4_header_t));
+ }
- ASSERT (sa0->crypto_alg < IPSEC_CRYPTO_N_ALG);
- vlib_increment_combined_counter
- (&ipsec_sa_counters, thread_index, sa_index0,
- 1, i_b0->current_length);
+ ASSERT (sa0->crypto_alg < IPSEC_CRYPTO_N_ALG);
+ vlib_increment_combined_counter
+ (&ipsec_sa_counters, thread_index, sa_index0,
+ 1, ib[0]->current_length);
- if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE))
- {
+ if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE))
+ {
- const int BLOCK_SIZE =
- em->ipsec_proto_main_crypto_algs[sa0->crypto_alg].block_size;
- const int IV_SIZE =
- em->ipsec_proto_main_crypto_algs[sa0->crypto_alg].iv_size;
- int blocks = 1 + (i_b0->current_length + 1) / BLOCK_SIZE;
-
- /* pad packet in input buffer */
- u8 pad_bytes = BLOCK_SIZE * blocks - 2 - i_b0->current_length;
- u8 i;
- u8 *padding =
- vlib_buffer_get_current (i_b0) + i_b0->current_length;
- i_b0->current_length = BLOCK_SIZE * blocks;
- for (i = 0; i < pad_bytes; ++i)
- {
- padding[i] = i + 1;
- }
- f0 = vlib_buffer_get_current (i_b0) + i_b0->current_length - 2;
- f0->pad_length = pad_bytes;
- f0->next_header = next_hdr_type;
-
- o_b0->current_length = ip_udp_hdr_size + sizeof (esp_header_t) +
- BLOCK_SIZE * blocks + IV_SIZE;
-
- vnet_buffer (o_b0)->sw_if_index[VLIB_RX] =
- vnet_buffer (i_b0)->sw_if_index[VLIB_RX];
-
- u8 iv[em->
- ipsec_proto_main_crypto_algs[sa0->crypto_alg].iv_size];
- RAND_bytes (iv, sizeof (iv));
-
- clib_memcpy_fast ((u8 *) vlib_buffer_get_current (o_b0) +
- ip_udp_hdr_size + sizeof (esp_header_t), iv,
- em->ipsec_proto_main_crypto_algs[sa0->
- crypto_alg].iv_size);
-
- esp_encrypt_cbc (vm, sa0->crypto_alg,
- (u8 *) vlib_buffer_get_current (i_b0),
- (u8 *) vlib_buffer_get_current (o_b0) +
- ip_udp_hdr_size + sizeof (esp_header_t) +
- IV_SIZE, BLOCK_SIZE * blocks,
- sa0->crypto_key.data, iv);
+ const int BLOCK_SIZE =
+ em->ipsec_proto_main_crypto_algs[sa0->crypto_alg].block_size;
+ const int IV_SIZE =
+ em->ipsec_proto_main_crypto_algs[sa0->crypto_alg].iv_size;
+ int blocks = 1 + (ib[0]->current_length + 1) / BLOCK_SIZE;
+
+ /* pad packet in input buffer */
+ u8 pad_bytes = BLOCK_SIZE * blocks - 2 - ib[0]->current_length;
+ u8 i;
+ u8 *padding =
+ vlib_buffer_get_current (ib[0]) + ib[0]->current_length;
+ ib[0]->current_length = BLOCK_SIZE * blocks;
+ for (i = 0; i < pad_bytes; ++i)
+ {
+ padding[i] = i + 1;
}
+ f0 = vlib_buffer_get_current (ib[0]) + ib[0]->current_length - 2;
+ f0->pad_length = pad_bytes;
+ f0->next_header = next_hdr_type;
+
+ ob[0]->current_length = ip_udp_hdr_size + sizeof (esp_header_t) +
+ BLOCK_SIZE * blocks + IV_SIZE;
+
+ vnet_buffer (ob[0])->sw_if_index[VLIB_RX] =
+ vnet_buffer (ib[0])->sw_if_index[VLIB_RX];
+
+ u8 iv[em->ipsec_proto_main_crypto_algs[sa0->crypto_alg].iv_size];
+ RAND_bytes (iv, sizeof (iv));
+
+ clib_memcpy_fast ((u8 *) vlib_buffer_get_current (ob[0]) +
+ ip_udp_hdr_size + sizeof (esp_header_t), iv,
+ em->ipsec_proto_main_crypto_algs[sa0->
+ crypto_alg].iv_size);
+
+ esp_encrypt_cbc (vm, sa0->crypto_alg,
+ (u8 *) vlib_buffer_get_current (ib[0]),
+ (u8 *) vlib_buffer_get_current (ob[0]) +
+ ip_udp_hdr_size + sizeof (esp_header_t) +
+ IV_SIZE, BLOCK_SIZE * blocks,
+ sa0->crypto_key.data, iv);
+ }
- o_b0->current_length +=
- hmac_calc (sa0->integ_alg, sa0->integ_key.data,
- sa0->integ_key.len, (u8 *) o_esp0,
- o_b0->current_length - ip_udp_hdr_size,
- vlib_buffer_get_current (o_b0) + o_b0->current_length,
- sa0->use_esn, sa0->seq_hi);
+ ob[0]->current_length +=
+ hmac_calc (sa0->integ_alg, sa0->integ_key.data,
+ sa0->integ_key.len, (u8 *) o_esp0,
+ ob[0]->current_length - ip_udp_hdr_size,
+ vlib_buffer_get_current (ob[0]) + ob[0]->current_length,
+ sa0->use_esn, sa0->seq_hi);
- if (is_ip6)
- {
- oh6_0->ip6.payload_length =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, o_b0) -
- sizeof (ip6_header_t));
- }
- else
+ if (is_ip6)
+ {
+ oh6_0->ip6.payload_length =
+ clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, ob[0]) -
+ sizeof (ip6_header_t));
+ }
+ else
+ {
+ oh0->ip4.length =
+ clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, ob[0]));
+ oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4);
+ if (sa0->udp_encap)
{
- oh0->ip4.length =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, o_b0));
- oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4);
- if (sa0->udp_encap)
- {
- ouh0->udp.length =
- clib_host_to_net_u16 (clib_net_to_host_u16
- (oh0->ip4.length) -
- ip4_header_bytes (&oh0->ip4));
- }
+ ouh0->udp.length =
+ clib_host_to_net_u16 (clib_net_to_host_u16
+ (oh0->ip4.length) -
+ ip4_header_bytes (&oh0->ip4));
}
+ }
- if (transport_mode)
- vlib_buffer_reset (o_b0);
+ if (transport_mode)
+ vlib_buffer_reset (ob[0]);
+
+ if (PREDICT_FALSE (esp_seq_err))
+ {
+ ob[0]->error = node->errors[ESP_ENCRYPT_ERROR_SEQ_CYCLED];
+ next[0] = ESP_ENCRYPT_NEXT_DROP;
+ }
- trace:
- if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED))
+ if (PREDICT_FALSE (ib[0]->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ if (ob[0])
{
- if (o_b0)
- {
- o_b0->flags |= VLIB_BUFFER_IS_TRACED;
- o_b0->trace_index = i_b0->trace_index;
- esp_encrypt_trace_t *tr =
- vlib_add_trace (vm, node, o_b0, sizeof (*tr));
- tr->sa_index = sa_index0;
- tr->spi = sa0->spi;
- tr->seq = sa0->seq - 1;
- tr->udp_encap = sa0->udp_encap;
- tr->crypto_alg = sa0->crypto_alg;
- tr->integ_alg = sa0->integ_alg;
- }
+ ob[0]->flags |= VLIB_BUFFER_IS_TRACED;
+ ob[0]->trace_index = ib[0]->trace_index;
+ esp_encrypt_trace_t *tr =
+ vlib_add_trace (vm, node, ob[0], sizeof (*tr));
+ tr->sa_index = sa_index0;
+ tr->spi = sa0->spi;
+ tr->seq = sa0->seq - 1;
+ tr->udp_encap = sa0->udp_encap;
+ tr->crypto_alg = sa0->crypto_alg;
+ tr->integ_alg = sa0->integ_alg;
}
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next, o_bi0,
- next0);
}
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+
+ /* next */
+ n_left_from -= 1;
+ ib += 1;
+ ob += 1;
+ next += 1;
}
+
vlib_node_increment_counter (vm, node->node_index,
- ESP_ENCRYPT_ERROR_RX_PKTS,
- from_frame->n_vectors);
-
-free_buffers_and_exit:
- if (recycle)
- vlib_buffer_free (vm, recycle, vec_len (recycle));
- vec_free (recycle);
- return from_frame->n_vectors;
+ ESP_ENCRYPT_ERROR_RX_PKTS, n_alloc);
+
+ vlib_buffer_enqueue_to_next (vm, node, new_bufs, nexts, n_alloc);
+done:
+ vlib_buffer_free (vm, from, from_frame->n_vectors);
+ return n_alloc;
}
VLIB_NODE_FN (esp4_encrypt_node) (vlib_main_t * vm,