aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzymon Sliwa <szs@semihalf.com>2018-01-24 14:05:06 +0100
committerSzymon Sliwa <szs@semihalf.com>2018-02-19 17:47:48 +0100
commit84cc712ed30960bd4b4598ce387fc9ed6a610987 (patch)
treef4e3a9bed98f9c54b65e7069a00883f73d577c65
parent97495b8966f4b25959719e3e1570b3f5942b1d64 (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.c93
-rw-r--r--src/plugins/odp/ipsec/ipsec.c30
-rwxr-xr-xsrc/plugins/odp/node.c7
-rwxr-xr-xsrc/plugins/odp/odp_packet.c11
-rwxr-xr-xsrc/plugins/odp/odp_packet.h1
-rw-r--r--src/vpp/conf/startup.conf3
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", &param))
{
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: