diff options
author | Szymon Sliwa <szs@semihalf.com> | 2018-01-05 16:26:31 +0100 |
---|---|---|
committer | Szymon Sliwa <szs@semihalf.com> | 2018-02-19 17:47:48 +0100 |
commit | 3a6b2d99d969bbb90792e1d09e97aa1be40d10df (patch) | |
tree | c4738c6a4c85c8515a3675e51583cafa3cb591cc /src/plugins/odp/ipsec/ipsec.c | |
parent | 808c3e6e7b1c764bd77b12d4bc5ffc68707971a9 (diff) |
plugins: odp: Add new nodes using ODP IPsec API
Created two new nodes for encryption/decryption,
based on user preferences we can use them to accellerate
IPsec by offloading it to hardware or optimized software
implementations
To use the new nodes two flags are needed in the odp
section of the startup.conf file, like this:
To use the new nodes put the enable-odp-ipsec flag to
startup.conf file, like this:
odp {
enable-odp-ipsec
}
Change-Id: Ib4bbc481efad7e90d63994580b57849b74400947
Signed-off-by: Szymon Sliwa <szs@semihalf.com>
Diffstat (limited to 'src/plugins/odp/ipsec/ipsec.c')
-rw-r--r-- | src/plugins/odp/ipsec/ipsec.c | 101 |
1 files changed, 91 insertions, 10 deletions
diff --git a/src/plugins/odp/ipsec/ipsec.c b/src/plugins/odp/ipsec/ipsec.c index 0e552fba..44a7714b 100644 --- a/src/plugins/odp/ipsec/ipsec.c +++ b/src/plugins/odp/ipsec/ipsec.c @@ -64,7 +64,9 @@ add_del_sa_sess (u32 sa_index, u8 is_add) return 0; } -int vpp_to_odp_auth_alg(int vpp_auth_alg) { +int +vpp_to_odp_auth_alg (int vpp_auth_alg) +{ switch (vpp_auth_alg) { case IPSEC_INTEG_ALG_SHA_512_256: @@ -78,6 +80,79 @@ int vpp_to_odp_auth_alg(int vpp_auth_alg) { } } +int // should flow_label be here? +create_odp_sa (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int flow_label, + int is_outbound) +{ + odp_ipsec_sa_param_t sa_params; + odp_ipsec_sa_param_init (&sa_params); + + sa_params.dir = + (is_outbound ? ODP_IPSEC_DIR_OUTBOUND : ODP_IPSEC_DIR_INBOUND); + /* VPP does not currently support Authentication Headers (AH), + Encapsulating Security Payload (ESP), neither does this code. + Code needs modification, not only in this place. */ + sa_params.proto = ODP_IPSEC_ESP; + sa_params.mode = + (sa->is_tunnel ? ODP_IPSEC_MODE_TUNNEL : ODP_IPSEC_MODE_TRANSPORT); + + if (sa_params.mode == ODP_IPSEC_MODE_TUNNEL + && sa_params.dir == ODP_IPSEC_DIR_OUTBOUND) + { + if (sa->is_tunnel_ip6) + { + sa_sess_data->tunnel_src.ip6 = sa->tunnel_src_addr.ip6; + sa_sess_data->tunnel_dst.ip6 = sa->tunnel_dst_addr.ip6; + sa_params.outbound.tunnel.type = ODP_IPSEC_TUNNEL_IPV6; + sa_params.outbound.tunnel.ipv6.dst_addr = + &sa_sess_data->tunnel_dst.ip6; + sa_params.outbound.tunnel.ipv6.src_addr = + &sa_sess_data->tunnel_src.ip6; + sa_params.outbound.tunnel.ipv6.hlimit = 42; + sa_params.outbound.tunnel.ipv6.dscp = 0; + sa_params.outbound.tunnel.ipv6.flabel = flow_label; + } + else + { + sa_sess_data->tunnel_src.ip4 = sa->tunnel_src_addr.ip4; + sa_sess_data->tunnel_dst.ip4 = sa->tunnel_dst_addr.ip4; + sa_params.outbound.tunnel.type = ODP_IPSEC_TUNNEL_IPV4; + sa_params.outbound.tunnel.ipv4.dst_addr = + &sa_sess_data->tunnel_dst.ip4; + sa_params.outbound.tunnel.ipv4.src_addr = + &sa_sess_data->tunnel_src.ip4; + sa_params.outbound.tunnel.ipv4.ttl = 42; + sa_params.outbound.tunnel.ipv4.df = 42; + } + } + + 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; + + sa_params.crypto.auth_alg = vpp_to_odp_auth_alg (sa->integ_alg); + sa_params.crypto.auth_key.data = sa->integ_key; + sa_params.crypto.auth_key.length = sa->integ_key_len; + + sa_params.lifetime.soft_limit.packets = 0; + sa_params.lifetime.hard_limit.packets = 0; + + sa_params.spi = sa->spi; + + sa_params.dest_queue = ODP_QUEUE_INVALID; + sa_params.context = NULL; + sa_params.context_len = 0; + + sa_sess_data->odp_sa = odp_ipsec_sa_create (&sa_params); // check if there are no errors + + if (sa_sess_data->odp_sa == ODP_IPSEC_SA_INVALID) + return -1; + + sa_sess_data->is_odp_sa_present = 1; + + return 0; +} + int create_sess (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int is_outbound) { @@ -114,11 +189,11 @@ create_sess (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int is_outbound) crypto_params.cipher_alg = ODP_CIPHER_ALG_NULL; } - crypto_params.auth_alg = vpp_to_odp_auth_alg(sa->integ_alg); + crypto_params.auth_alg = vpp_to_odp_auth_alg (sa->integ_alg); actual_capa_amount = odp_crypto_auth_capability (crypto_params.auth_alg, - capa, - max_auth_capa_amount); + capa, + max_auth_capa_amount); int picked_capa = -1; int i; @@ -136,8 +211,8 @@ create_sess (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int is_outbound) { if (actual_capa_amount) clib_warning - ("Failed to get matching capabilities, algorithm appears to be supported "\ - "but key or digest length incompatible\n"); + ("Failed to get matching capabilities, algorithm appears to be supported " + "but key or digest length incompatible\n"); else clib_warning ("Failed to get matching capabilities, algorithm probably not supported\n"); @@ -210,9 +285,9 @@ odp_ipsec_check_support (ipsec_sa_t * sa) } clib_error_t * -ipsec_init (vlib_main_t * vm) +ipsec_init (vlib_main_t * vm, u8 ipsec_api) { - if (!enable_odp_crypto) + if (!enable_odp_crypto && !ipsec_api) return 0; ipsec_main_t *im = &ipsec_main; odp_crypto_main_t *ocm = &odp_crypto_main; @@ -239,7 +314,10 @@ ipsec_init (vlib_main_t * vm) ipsec_node = vlib_get_node_by_name (vm, (u8 *) "ipsec-output-ip4"); ASSERT (ipsec_node); - crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-encrypt"); + if (ipsec_api) + crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-ipsec-esp-encrypt"); + else + crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-encrypt"); ASSERT (crypto_node); im->esp_encrypt_node_index = crypto_node->index; im->esp_encrypt_next_index = @@ -247,7 +325,10 @@ ipsec_init (vlib_main_t * vm) ipsec_node = vlib_get_node_by_name (vm, (u8 *) "ipsec-input-ip4"); ASSERT (ipsec_node); - crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-decrypt"); + if (ipsec_api) + crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-ipsec-esp-decrypt"); + else + crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-decrypt"); ASSERT (crypto_node); im->esp_decrypt_node_index = crypto_node->index; im->esp_decrypt_next_index = |