X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fipsec%2Fah_encrypt.c;h=e2d17d48ccff53390efce04f448a74f8f50ad938;hb=ad95b06181c354291f4433c5e550cb89c5122252;hp=b4e9af3480284420b344c178080b11aa58b5bb3a;hpb=f3a6622c7363501b9d4db1f605daa87b4f803cb1;p=vpp.git diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c index b4e9af34802..e2d17d48ccf 100644 --- a/src/vnet/ipsec/ah_encrypt.c +++ b/src/vnet/ipsec/ah_encrypt.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define foreach_ah_encrypt_next \ _ (DROP, "error-drop") \ @@ -37,26 +39,6 @@ typedef enum AH_ENCRYPT_N_NEXT, } ah_encrypt_next_t; -#define foreach_ah_encrypt_error \ - _(RX_PKTS, "AH pkts received") \ - _(CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)") \ - _(SEQ_CYCLED, "sequence number cycled") - - -typedef enum -{ -#define _(sym,str) AH_ENCRYPT_ERROR_##sym, - foreach_ah_encrypt_error -#undef _ - AH_ENCRYPT_N_ERROR, -} ah_encrypt_error_t; - -static char *ah_encrypt_error_strings[] = { -#define _(sym,string) string, - foreach_ah_encrypt_error -#undef _ -}; - typedef struct { u32 sa_index; @@ -99,8 +81,10 @@ ah_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node, if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED) { u32 bi = op->user_data; - b[bi]->error = node->errors[AH_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR]; - nexts[bi] = AH_ENCRYPT_NEXT_DROP; + ah_encrypt_set_next_index (b[bi], node, vm->thread_index, + AH_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR, bi, + nexts, AH_ENCRYPT_NEXT_DROP, + vnet_buffer (b[bi])->ipsec.sad_index); n_fail--; } op++; @@ -111,20 +95,21 @@ typedef struct { union { + /* Variable fields in the IP header not covered by the AH + * integrity check */ struct { - u8 hop_limit; u32 ip_version_traffic_class_and_flow_label; + u8 hop_limit; }; - struct { u8 ttl; u8 tos; }; }; - i16 current_data; u8 skip; + i16 current_data; u32 sa_index; } ah_encrypt_packet_data_t; @@ -170,36 +155,40 @@ ah_encrypt_inline (vlib_main_t * vm, { if (current_sa_index != ~0) vlib_increment_combined_counter (&ipsec_sa_counters, thread_index, - current_sa_index, - current_sa_pkts, + current_sa_index, current_sa_pkts, current_sa_bytes); current_sa_index = vnet_buffer (b[0])->ipsec.sad_index; - sa0 = pool_elt_at_index (im->sad, current_sa_index); + sa0 = ipsec_sa_get (current_sa_index); current_sa_bytes = current_sa_pkts = 0; + vlib_prefetch_combined_counter (&ipsec_sa_counters, thread_index, + current_sa_index); } pd->sa_index = current_sa_index; next[0] = AH_ENCRYPT_NEXT_DROP; - if (PREDICT_FALSE (~0 == sa0->encrypt_thread_index)) + if (PREDICT_FALSE (~0 == sa0->thread_index)) { /* this is the first packet to use this SA, claim the SA * for this thread. this could happen simultaneously on * another thread */ - clib_atomic_cmp_and_swap (&sa0->encrypt_thread_index, ~0, + clib_atomic_cmp_and_swap (&sa0->thread_index, ~0, ipsec_sa_assign_thread (thread_index)); } - if (PREDICT_TRUE (thread_index != sa0->encrypt_thread_index)) + if (PREDICT_TRUE (thread_index != sa0->thread_index)) { + vnet_buffer (b[0])->ipsec.thread_index = sa0->thread_index; next[0] = AH_ENCRYPT_NEXT_HANDOFF; goto next; } if (PREDICT_FALSE (esp_seq_advance (sa0))) { - b[0]->error = node->errors[AH_ENCRYPT_ERROR_SEQ_CYCLED]; + ah_encrypt_set_next_index (b[0], node, vm->thread_index, + AH_ENCRYPT_ERROR_SEQ_CYCLED, 0, next, + AH_ENCRYPT_NEXT_DROP, current_sa_index); pd->skip = 1; goto next; } @@ -209,8 +198,6 @@ ah_encrypt_inline (vlib_main_t * vm, ssize_t adv; ih0 = vlib_buffer_get_current (b[0]); - pd->ttl = ih0->ip4.ttl; - pd->tos = ih0->ip4.tos; if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0))) { @@ -246,10 +233,20 @@ ah_encrypt_inline (vlib_main_t * vm, ip_hdr_size = sizeof (ip6_header_t); oh6_0 = vlib_buffer_get_current (b[0]); pd->current_data = b[0]->current_data; - pd->hop_limit = ih6_0->ip6.hop_limit; - pd->ip_version_traffic_class_and_flow_label = + + oh6_0->ip6.ip_version_traffic_class_and_flow_label = ih6_0->ip6.ip_version_traffic_class_and_flow_label; + + if (PREDICT_FALSE (ipsec_sa_is_set_IS_TUNNEL (sa0))) + { + ip6_set_dscp_network_order (&oh6_0->ip6, sa0->tunnel.t_dscp); + tunnel_encap_fixup_6o6 (sa0->tunnel_flags, &ih6_0->ip6, + &oh6_0->ip6); + } + pd->ip_version_traffic_class_and_flow_label = + oh6_0->ip6.ip_version_traffic_class_and_flow_label; + if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0))) { next_hdr_type = IP_PROTOCOL_IPV6; @@ -275,8 +272,31 @@ ah_encrypt_inline (vlib_main_t * vm, { ip_hdr_size = sizeof (ip4_header_t); oh0 = vlib_buffer_get_current (b[0]); - clib_memset (oh0, 0, sizeof (ip4_and_ah_header_t)); + pd->ttl = ih0->ip4.ttl; + + if (PREDICT_FALSE (ipsec_sa_is_set_IS_TUNNEL (sa0))) + { + if (sa0->tunnel.t_dscp) + pd->tos = sa0->tunnel.t_dscp << 2; + else + { + pd->tos = ih0->ip4.tos; + + if (!(sa0->tunnel_flags & + TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)) + pd->tos &= 0x3; + if (!(sa0->tunnel_flags & + TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)) + pd->tos &= 0xfc; + } + } + else + { + pd->tos = ih0->ip4.tos; + } + pd->current_data = b[0]->current_data; + clib_memset (oh0, 0, sizeof (ip4_and_ah_header_t)); if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0))) { @@ -351,6 +371,18 @@ ah_encrypt_inline (vlib_main_t * vm, } next: + if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED)) + { + sa0 = ipsec_sa_get (pd->sa_index); + ah_encrypt_trace_t *tr = + vlib_add_trace (vm, node, b[0], sizeof (*tr)); + tr->spi = sa0->spi; + tr->seq_lo = sa0->seq; + tr->seq_hi = sa0->seq_hi; + tr->integ_alg = sa0->integ_alg; + tr->sa_index = pd->sa_index; + } + n_left -= 1; next += 1; pd += 1; @@ -373,7 +405,7 @@ ah_encrypt_inline (vlib_main_t * vm, while (n_left) { if (pd->skip) - goto trace; + goto next_pkt; if (is_ip6) { @@ -390,19 +422,7 @@ ah_encrypt_inline (vlib_main_t * vm, oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4); } - trace: - if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED)) - { - sa0 = vec_elt_at_index (im->sad, pd->sa_index); - ah_encrypt_trace_t *tr = - vlib_add_trace (vm, node, b[0], sizeof (*tr)); - tr->spi = sa0->spi; - tr->seq_lo = sa0->seq; - tr->seq_hi = sa0->seq_hi; - tr->integ_alg = sa0->integ_alg; - tr->sa_index = pd->sa_index; - } - + next_pkt: n_left -= 1; next += 1; pd += 1; @@ -429,8 +449,8 @@ VLIB_REGISTER_NODE (ah4_encrypt_node) = { .format_trace = format_ah_encrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = ARRAY_LEN(ah_encrypt_error_strings), - .error_strings = ah_encrypt_error_strings, + .n_errors = AH_ENCRYPT_N_ERROR, + .error_counters = ah_encrypt_error_counters, .n_next_nodes = AH_ENCRYPT_N_NEXT, .next_nodes = { @@ -455,8 +475,8 @@ VLIB_REGISTER_NODE (ah6_encrypt_node) = { .format_trace = format_ah_encrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = ARRAY_LEN(ah_encrypt_error_strings), - .error_strings = ah_encrypt_error_strings, + .n_errors = AH_ENCRYPT_N_ERROR, + .error_counters = ah_encrypt_error_counters, .n_next_nodes = AH_ENCRYPT_N_NEXT, .next_nodes = { @@ -467,6 +487,25 @@ VLIB_REGISTER_NODE (ah6_encrypt_node) = { }; /* *INDENT-ON* */ +#ifndef CLIB_MARCH_VARIANT + +static clib_error_t * +ah_encrypt_init (vlib_main_t *vm) +{ + ipsec_main_t *im = &ipsec_main; + + im->ah4_enc_fq_index = + vlib_frame_queue_main_init (ah4_encrypt_node.index, 0); + im->ah6_enc_fq_index = + vlib_frame_queue_main_init (ah6_encrypt_node.index, 0); + + return 0; +} + +VLIB_INIT_FUNCTION (ah_encrypt_init); + +#endif + /* * fd.io coding-style-patch-verification: ON *