X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fplugins%2Fdpdk%2Fipsec%2Fesp_encrypt.c;h=af0e4b6211b93eb4424a596f96e7df479bfccde8;hb=8f818cc35972f447acd3cf68229d5f9e634926f3;hp=cdeeb4022f6cb04927a63629d90face4e246008d;hpb=0a9dd3cab74c148fff20abd7e869016ff7dee8b3;p=vpp.git diff --git a/src/plugins/dpdk/ipsec/esp_encrypt.c b/src/plugins/dpdk/ipsec/esp_encrypt.c index cdeeb4022f6..af0e4b6211b 100644 --- a/src/plugins/dpdk/ipsec/esp_encrypt.c +++ b/src/plugins/dpdk/ipsec/esp_encrypt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -109,10 +110,12 @@ format_esp_encrypt_trace (u8 * s, va_list * args) always_inline uword dpdk_esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * from_frame, int is_ip6) + vlib_frame_t * from_frame, int is_ip6, int is_tun) { - u32 n_left_from, *from, *to_next, next_index; + u32 n_left_from, *from, *to_next, next_index, thread_index; ipsec_main_t *im = &ipsec_main; + vnet_main_t *vnm = im->vnet_main; + vnet_interface_main_t *vim = &vnm->interface_main; u32 thread_idx = vlib_get_thread_index (); dpdk_crypto_main_t *dcm = &dpdk_crypto_main; crypto_resource_t *res = 0; @@ -128,6 +131,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; + thread_index = vm->thread_index; ret = crypto_alloc_ops (numa, ops, n_left_from); if (ret) @@ -153,8 +157,8 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next > 0) { clib_error_t *error; - u32 bi0; - vlib_buffer_t *b0 = 0; + u32 bi0, bi1; + vlib_buffer_t *b0, *b1; u32 sa_index0; ip4_and_esp_header_t *ih0, *oh0 = 0; ip6_and_esp_header_t *ih6_0, *oh6_0 = 0; @@ -167,7 +171,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, u8 trunc_size; u16 rewrite_len; u16 udp_encap_adv = 0; - struct rte_mbuf *mb0 = 0; + struct rte_mbuf *mb0; struct rte_crypto_op *op; u16 res_idx; @@ -186,17 +190,39 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, /* mb0 */ CLIB_PREFETCH (mb0, CLIB_CACHE_LINE_BYTES, STORE); + if (n_left_from > 1) + { + bi1 = from[1]; + b1 = vlib_get_buffer (vm, bi1); + + CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, LOAD); + CLIB_PREFETCH (b1->data - CLIB_CACHE_LINE_BYTES, + CLIB_CACHE_LINE_BYTES, STORE); + } + op = ops[0]; ops += 1; ASSERT (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED); dpdk_op_priv_t *priv = crypto_op_get_priv (op); + /* store bi in op private */ + priv->bi = bi0; + priv->encrypt = 1; u16 op_len = sizeof (op[0]) + sizeof (op[0].sym[0]) + sizeof (priv[0]); CLIB_PREFETCH (op, op_len, STORE); - sa_index0 = vnet_buffer (b0)->ipsec.sad_index; + if (is_tun) + { + u32 tmp; + /* we are on a ipsec tunnel's feature arc */ + sa_index0 = *(u32 *) vnet_feature_next_with_data (&tmp, b0, + sizeof + (sa_index0)); + } + else + sa_index0 = vnet_buffer (b0)->ipsec.sad_index; if (sa_index0 != last_sa_index) { @@ -257,8 +283,9 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, if (PREDICT_FALSE (esp_seq_advance (sa0))) { - clib_warning ("sequence number counter has cycled SPI %u", - sa0->spi); + clib_warning + ("sequence number counter has cycled SPI %u (0x%08x)", + sa0->spi, sa0->spi); if (is_ip6) vlib_node_increment_counter (vm, dpdk_esp6_encrypt_node.index, @@ -277,7 +304,16 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, orig_sz = b0->current_length; /* TODO multi-seg support - total_length_not_including_first_buffer */ - sa0->total_data_size += b0->current_length; + vlib_increment_combined_counter + (&ipsec_sa_counters, thread_index, sa_index0, + 1, b0->current_length); + + /* Update tunnel interface tx counters */ + if (is_tun) + vlib_increment_combined_counter + (vim->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, + thread_index, vnet_buffer (b0)->sw_if_index[VLIB_TX], + 1, b0->current_length); res->ops[res->n_ops] = op; res->bi[res->n_ops] = bi0; @@ -291,13 +327,13 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, trunc_size = auth_alg->trunc_size; /* if UDP encapsulation is used adjust the address of the IP header */ - if (sa0->udp_encap && !is_ip6) + if (ipsec_sa_is_set_UDP_ENCAP (sa0) && !is_ip6) udp_encap_adv = sizeof (udp_header_t); - if (sa0->is_tunnel) + if (ipsec_sa_is_set_IS_TUNNEL (sa0)) { rewrite_len = 0; - if (!is_ip6 && !sa0->is_tunnel_ip6) /* ip4inip4 */ + if (!is_ip6 && !ipsec_sa_is_set_IS_TUNNEL_V6 (sa0)) /* ip4inip4 */ { /* in tunnel mode send it back to FIB */ priv->next = DPDK_CRYPTO_INPUT_NEXT_IP4_LOOKUP; @@ -327,7 +363,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32; - if (sa0->udp_encap) + if (ipsec_sa_is_set_UDP_ENCAP (sa0)) { oh0->ip4.protocol = IP_PROTOCOL_UDP; esp0 = &ouh0->esp; @@ -337,8 +373,9 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, esp0->spi = clib_host_to_net_u32 (sa0->spi); esp0->seq = clib_host_to_net_u32 (sa0->seq); } - else if (is_ip6 && sa0->is_tunnel_ip6) /* ip6inip6 */ + else if (is_ip6 && ipsec_sa_is_set_IS_TUNNEL_V6 (sa0)) { + /* ip6inip6 */ /* in tunnel mode send it back to FIB */ priv->next = DPDK_CRYPTO_INPUT_NEXT_IP6_LOOKUP; @@ -412,7 +449,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, memmove (dst, src, rewrite_len + ip_size); oh0->ip4.protocol = IP_PROTOCOL_IPSEC_ESP; esp0 = (esp_header_t *) (((u8 *) oh0) + ip_size); - if (sa0->udp_encap) + if (ipsec_sa_is_set_UDP_ENCAP (sa0)) { oh0->ip4.protocol = IP_PROTOCOL_UDP; esp0 = (esp_header_t *) @@ -428,7 +465,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, esp0->seq = clib_host_to_net_u32 (sa0->seq); } - if (sa0->udp_encap && ouh0) + if (ipsec_sa_is_set_UDP_ENCAP (sa0) && ouh0) { 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); @@ -461,7 +498,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, oh0->ip4.length = clib_host_to_net_u16 (b0->current_length - rewrite_len); oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4); - if (sa0->udp_encap && ouh0) + if (ipsec_sa_is_set_UDP_ENCAP (sa0) && ouh0) { ouh0->udp.length = clib_host_to_net_u16 (clib_net_to_host_u16 @@ -506,7 +543,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, aad[1] = clib_host_to_net_u32 (sa0->seq); /* aad[3] should always be 0 */ - if (PREDICT_FALSE (sa0->use_esn)) + if (PREDICT_FALSE (ipsec_sa_is_set_USE_ESN (sa0))) aad[2] = clib_host_to_net_u32 (sa0->seq_hi); else aad[2] = 0; @@ -515,7 +552,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, { auth_len = vlib_buffer_get_tail (b0) - ((u8 *) esp0) - trunc_size; - if (sa0->use_esn) + if (ipsec_sa_is_set_USE_ESN (sa0)) { u32 *_digest = (u32 *) digest; _digest[0] = clib_host_to_net_u32 (sa0->seq_hi); @@ -534,7 +571,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, tr->crypto_alg = sa0->crypto_alg; tr->integ_alg = sa0->integ_alg; u8 *p = vlib_buffer_get_current (b0); - if (!sa0->is_tunnel) + if (!ipsec_sa_is_set_IS_TUNNEL (sa0)) p += vnet_buffer (b0)->ip.save_rewrite_length; clib_memcpy_fast (tr->packet_data, p, sizeof (tr->packet_data)); } @@ -547,8 +584,8 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, ESP_ENCRYPT_ERROR_RX_PKTS, from_frame->n_vectors); - crypto_enqueue_ops (vm, cwm, 1, dpdk_esp6_encrypt_node.index, - ESP_ENCRYPT_ERROR_ENQ_FAIL, numa); + crypto_enqueue_ops (vm, cwm, dpdk_esp6_encrypt_node.index, + ESP_ENCRYPT_ERROR_ENQ_FAIL, numa, 1 /* encrypt */ ); } else { @@ -556,8 +593,8 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, ESP_ENCRYPT_ERROR_RX_PKTS, from_frame->n_vectors); - crypto_enqueue_ops (vm, cwm, 1, dpdk_esp4_encrypt_node.index, - ESP_ENCRYPT_ERROR_ENQ_FAIL, numa); + crypto_enqueue_ops (vm, cwm, dpdk_esp4_encrypt_node.index, + ESP_ENCRYPT_ERROR_ENQ_FAIL, numa, 1 /* encrypt */ ); } crypto_free_ops (numa, ops, cwm->ops + from_frame->n_vectors - ops); @@ -569,7 +606,7 @@ VLIB_NODE_FN (dpdk_esp4_encrypt_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { - return dpdk_esp_encrypt_inline (vm, node, from_frame, 0 /*is_ip6 */ ); + return dpdk_esp_encrypt_inline (vm, node, from_frame, 0 /*is_ip6 */ , 0); } /* *INDENT-OFF* */ @@ -592,7 +629,7 @@ VLIB_NODE_FN (dpdk_esp6_encrypt_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { - return dpdk_esp_encrypt_inline (vm, node, from_frame, 1 /*is_ip6 */ ); + return dpdk_esp_encrypt_inline (vm, node, from_frame, 1 /*is_ip6 */ , 0); } /* *INDENT-OFF* */ @@ -611,6 +648,66 @@ VLIB_REGISTER_NODE (dpdk_esp6_encrypt_node) = { }; /* *INDENT-ON* */ +VLIB_NODE_FN (dpdk_esp4_encrypt_tun_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) +{ + return dpdk_esp_encrypt_inline (vm, node, from_frame, 0 /*is_ip6 */ , 1); +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (dpdk_esp4_encrypt_tun_node) = { + .name = "dpdk-esp4-encrypt-tun", + .flags = VLIB_NODE_FLAG_IS_OUTPUT, + .vector_size = sizeof (u32), + .format_trace = format_esp_encrypt_trace, + .n_errors = ARRAY_LEN (esp_encrypt_error_strings), + .error_strings = esp_encrypt_error_strings, + .n_next_nodes = 1, + .next_nodes = + { + [ESP_ENCRYPT_NEXT_DROP] = "error-drop", + } +}; + +VNET_FEATURE_INIT (dpdk_esp4_encrypt_tun_feat_node, static) = +{ + .arc_name = "ip4-output", + .node_name = "dpdk-esp4-encrypt-tun", + .runs_before = VNET_FEATURES ("adj-midchain-tx"), +}; +/* *INDENT-ON* */ + +VLIB_NODE_FN (dpdk_esp6_encrypt_tun_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) +{ + return dpdk_esp_encrypt_inline (vm, node, from_frame, 1 /*is_ip6 */ , 1); +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (dpdk_esp6_encrypt_tun_node) = { + .name = "dpdk-esp6-encrypt-tun", + .flags = VLIB_NODE_FLAG_IS_OUTPUT, + .vector_size = sizeof (u32), + .format_trace = format_esp_encrypt_trace, + .n_errors = ARRAY_LEN (esp_encrypt_error_strings), + .error_strings = esp_encrypt_error_strings, + .n_next_nodes = 1, + .next_nodes = + { + [ESP_ENCRYPT_NEXT_DROP] = "error-drop", + } +}; + +VNET_FEATURE_INIT (dpdk_esp6_encrypt_tun_feat_node, static) = +{ + .arc_name = "ip6-output", + .node_name = "dpdk-esp6-encrypt-tun", + .runs_before = VNET_FEATURES ("adj-midchain-tx"), +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON *