diff options
author | Szymon Sliwa <szs@semihalf.com> | 2018-01-24 14:05:06 +0100 |
---|---|---|
committer | Szymon Sliwa <szs@semihalf.com> | 2018-02-19 17:47:48 +0100 |
commit | 84cc712ed30960bd4b4598ce387fc9ed6a610987 (patch) | |
tree | f4e3a9bed98f9c54b65e7069a00883f73d577c65 | |
parent | 97495b8966f4b25959719e3e1570b3f5942b1d64 (diff) |
plugins: odp: Add support for IPsec inline operation
To use inline mode put inline flag in the odp section
of the startup.conf file, like this:
odp {
enable-odp-ipsec
inline
}
Falls back to lookaside mode.
Change-Id: I1292a7254b25a15b25285773a43bae112394827d
Signed-off-by: Szymon Sliwa <szs@semihalf.com>
-rw-r--r-- | src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c | 93 | ||||
-rw-r--r-- | src/plugins/odp/ipsec/ipsec.c | 30 | ||||
-rwxr-xr-x | src/plugins/odp/node.c | 7 | ||||
-rwxr-xr-x | src/plugins/odp/odp_packet.c | 11 | ||||
-rwxr-xr-x | src/plugins/odp/odp_packet.h | 1 | ||||
-rw-r--r-- | src/vpp/conf/startup.conf | 3 |
6 files changed, 109 insertions, 36 deletions
diff --git a/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c b/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c index 4753ff80..4feaa103 100644 --- a/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c +++ b/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c @@ -108,6 +108,10 @@ esp_encrypt_node_fn (vlib_main_t * vm, odp_crypto_main_t *ocm = &odp_crypto_main; u32 thread_index = vlib_get_thread_index (); + vnet_main_t *vnm = vnet_get_main (); + odp_packet_main_t *om = odp_packet_main; + vnet_interface_main_t *vint_main = &vnm->interface_main; + ipsec_alloc_empty_buffers (vm, im); u32 *empty_buffers = im->empty_buffers[thread_index]; @@ -135,10 +139,12 @@ esp_encrypt_node_fn (vlib_main_t * vm, { u32 bi0, next0; vlib_buffer_t *i_b0, *o_b0; + vnet_sw_interface_t *sw; + vnet_hw_interface_t *hw; u32 sa_index0; ipsec_sa_t *sa0; ip6_header_t *h6 = 0; - //u8 transport_mode = 0; + odp_packet_if_t *oif; sa_data_t *sa_sess_data; u32 flow_label; @@ -201,6 +207,7 @@ esp_encrypt_node_fn (vlib_main_t * vm, { odp_packet_t pkt = odp_packet_from_vlib_buffer (i_b0); odp_packet_t out_pkt; + odp_ipsec_out_inline_param_t ipsec_inline_params; odp_ipsec_out_param_t oiopt; oiopt.num_sa = 1; @@ -218,7 +225,29 @@ esp_encrypt_node_fn (vlib_main_t * vm, int ret; - if (is_async) + if (is_inline && next0 == ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT) + { + sw = + vnet_get_sw_interface (vnm, + vnet_buffer (i_b0)->sw_if_index + [VLIB_TX]); + hw = vnet_get_hw_interface (vnm, sw->hw_if_index); + oif = pool_elt_at_index (om->interfaces, hw->dev_instance); + ipsec_inline_params.pktio = oif->pktio; + ipsec_inline_params.outer_hdr.ptr = + (u8 *) & vnet_buffer (i_b0)->post_crypto.dst_mac; + ipsec_inline_params.outer_hdr.len = + sizeof (ethernet_header_t); + ret = + odp_ipsec_out_inline (&pkt, 1, &oiopt, + &ipsec_inline_params); + vlib_increment_combined_counter + (vint_main->combined_sw_if_counters + + VNET_INTERFACE_COUNTER_TX, thread_index, + vnet_buffer (i_b0)->sw_if_index[VLIB_TX], 1, + i_b0->current_length); + } + else if (is_async) ret = odp_ipsec_out_enq (&pkt, 1, &oiopt); else ret = odp_ipsec_out (&pkt, 1, &out_pkt, &processed, &oiopt); @@ -230,7 +259,9 @@ esp_encrypt_node_fn (vlib_main_t * vm, } - if (!is_async) + if (!is_async + && !(is_inline + && next0 == ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT)) { o_b0 = vlib_buffer_from_odp_packet (out_pkt); @@ -240,37 +271,38 @@ esp_encrypt_node_fn (vlib_main_t * vm, (intptr_t) o_b0->data + (intptr_t) odp_packet_l3_offset (out_pkt)); o_b0->current_length = odp_packet_len (out_pkt); - } - - } - if (!is_async) - { - if (!sa0->is_tunnel) - { - if (vnet_buffer (o_b0)->sw_if_index[VLIB_TX] != ~0) + if (!sa0->is_tunnel) { - ethernet_header_t *ieh0, *oeh0; - ieh0 = - (ethernet_header_t *) & vnet_buffer (i_b0)->post_crypto.dst_mac; - oeh0 = - (ethernet_header_t *) ((uintptr_t) - vlib_buffer_get_current (o_b0) - - sizeof (ethernet_header_t)); - clib_memcpy (oeh0, ieh0, sizeof (ethernet_header_t)); + if (vnet_buffer (o_b0)->sw_if_index[VLIB_TX] != ~0) + { + ethernet_header_t *ieh0, *oeh0; + ieh0 = + (ethernet_header_t *) & + vnet_buffer (i_b0)->post_crypto.dst_mac; + oeh0 = + (ethernet_header_t *) ((uintptr_t) + vlib_buffer_get_current + (o_b0) - + sizeof + (ethernet_header_t)); + clib_memcpy (oeh0, ieh0, + sizeof (ethernet_header_t)); + } + + o_b0->current_data -= sizeof (ethernet_header_t); + o_b0->current_length += sizeof (ethernet_header_t); } - o_b0->current_data -= sizeof (ethernet_header_t); - o_b0->current_length += sizeof (ethernet_header_t); - } - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, bi0, - next0); - } - else - { - to_next -= 1; - n_left_to_next += 1; + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, + to_next, n_left_to_next, + bi0, next0); + } + else + { + to_next -= 1; + n_left_to_next += 1; + } } trace: if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED)) @@ -314,7 +346,6 @@ VLIB_REGISTER_NODE (odp_ipsec_esp_encrypt_node) = { }; VLIB_NODE_FUNCTION_MULTIARCH (odp_ipsec_esp_encrypt_node, esp_encrypt_node_fn) - static uword esp_encrypt_post_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, diff --git a/src/plugins/odp/ipsec/ipsec.c b/src/plugins/odp/ipsec/ipsec.c index 62a074f8..f21f3fe1 100644 --- a/src/plugins/odp/ipsec/ipsec.c +++ b/src/plugins/odp/ipsec/ipsec.c @@ -132,6 +132,13 @@ create_odp_sa (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int flow_label, } } + if (sa_params.dir == ODP_IPSEC_DIR_INBOUND && is_inline) + { + sa_params.inbound.lookup_mode = ODP_IPSEC_LOOKUP_SPI; + sa_params.inbound.lookup_param.ip_version = + (sa->is_tunnel_ip6 ? ODP_IPSEC_IPV6 : ODP_IPSEC_IPV4); + } + sa_params.crypto.cipher_alg = ODP_CIPHER_ALG_AES_CBC; sa_params.crypto.cipher_key.data = sa->crypto_key; sa_params.crypto.cipher_key.length = sa->crypto_key_len; @@ -380,6 +387,29 @@ ipsec_init (vlib_main_t * vm, u8 ipsec_api) ocm->workers[0].post_decrypt = ocm->workers[1].post_decrypt; } + if (ipsec_api) + { + odp_ipsec_config_t ipsec_config; + odp_ipsec_config_init (&ipsec_config); + + if (is_inline) + { + ipsec_config.inbound_mode = ODP_IPSEC_OP_MODE_INLINE; + ipsec_config.outbound_mode = ODP_IPSEC_OP_MODE_INLINE; + } + else if (is_async) + { + ipsec_config.inbound_mode = ODP_IPSEC_OP_MODE_ASYNC; + ipsec_config.outbound_mode = ODP_IPSEC_OP_MODE_ASYNC; + } + else + { + ipsec_config.inbound_mode = ODP_IPSEC_OP_MODE_SYNC; + ipsec_config.outbound_mode = ODP_IPSEC_OP_MODE_SYNC; + } + odp_ipsec_config (&ipsec_config); + } + return 0; } diff --git a/src/plugins/odp/node.c b/src/plugins/odp/node.c index e0b468a2..322aeb7d 100755 --- a/src/plugins/odp/node.c +++ b/src/plugins/odp/node.c @@ -177,6 +177,8 @@ odp_adjust_buffer (vlib_buffer_t * buf, odp_packet_t pkt, { buf->current_length = odp_packet_len (pkt); buf->current_data = 0; + buf->current_data = (int) ((intptr_t) odp_packet_data (pkt) - + (intptr_t) buf->data); buf->total_length_not_including_first_buffer = 0; buf->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID; buf->free_list_index = VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX; @@ -355,8 +357,9 @@ odp_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, else next0 = odp_rx_next_from_etype (pkt, b0); - if (next0 != VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT) - vlib_buffer_advance (b0, sizeof (ethernet_header_t)); + b0->current_data = (int) ((intptr_t) odp_packet_data (pkt) - + (intptr_t) b0->data); + vlib_buffer_advance (b0, sizeof (ethernet_header_t)); /* trace */ ODP_TRACE_BUFFER (n_trace, b0, next0, vm, node, oif); diff --git a/src/plugins/odp/odp_packet.c b/src/plugins/odp/odp_packet.c index 7f5f05ce..29b2ef01 100755 --- a/src/plugins/odp/odp_packet.c +++ b/src/plugins/odp/odp_packet.c @@ -26,6 +26,7 @@ odp_crypto_main_t odp_crypto_main; u8 enable_odp_crypto; u8 ipsec_api; u8 is_async; +u8 is_inline; static u32 odp_packet_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, @@ -437,9 +438,13 @@ odp_config (vlib_main_t * vm, unformat_input_t * input) ipsec_api = 1; } else if (unformat (input, "async")) - { - is_async = 1; - } + { + is_async = 1; + } + else if (unformat (input, "inline")) + { + is_inline = 1; + } else if (unformat (input, "%s", ¶m)) { clib_warning ("%s: Unknown option %s\n", __func__, param); diff --git a/src/plugins/odp/odp_packet.h b/src/plugins/odp/odp_packet.h index e8409477..ac984156 100755 --- a/src/plugins/odp/odp_packet.h +++ b/src/plugins/odp/odp_packet.h @@ -83,6 +83,7 @@ extern odp_if_mode_t def_if_mode; extern u8 enable_odp_crypto; extern u8 ipsec_api; extern u8 is_async; +extern u8 is_inline; u32 odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set, u32 * sw_if_index, diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index 8b05286a..3d4f7c30 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -138,6 +138,9 @@ cpu { ## To use asynchronous mode of the crypto/ipsec operations # async + + ## To use inline mode of ipsec + # inline # } # Adjusting the plugin path depending on where the VPP plugins are: |