X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fipsec%2Fipsec_if.c;h=8e2b4b5be1bdf74751fbbbbf7e48b2234ff202f3;hb=e8915fc707a03260c05624425f9548d796c089fb;hp=17f28a09ac82a3a121a147c547e0d4fc50a6f457;hpb=d7603d97e046d59aba6864b208c181b39fc72b52;p=vpp.git diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c index 17f28a09ac8..8e2b4b5be1b 100644 --- a/src/vnet/ipsec/ipsec_if.c +++ b/src/vnet/ipsec/ipsec_if.c @@ -230,6 +230,28 @@ ipsec_tun_mk_output_sa_id (u32 ti) return (0xc0000000 | ti); } +static void +ipsec_tunnel_feature_set (ipsec_main_t * im, ipsec_tunnel_if_t * t, u8 enable) +{ + u8 arc; + + arc = vnet_get_feature_arc_index ("ip4-output"); + + vnet_feature_enable_disable_with_index (arc, + im->esp4_encrypt_tun_feature_index, + t->sw_if_index, enable, + &t->output_sa_index, + sizeof (t->output_sa_index)); + + arc = vnet_get_feature_arc_index ("ip6-output"); + + vnet_feature_enable_disable_with_index (arc, + im->esp6_encrypt_tun_feature_index, + t->sw_if_index, enable, + &t->output_sa_index, + sizeof (t->output_sa_index)); +} + int ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args, @@ -306,8 +328,9 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, &crypto_key, args->integ_alg, &integ_key, - flags, + (flags | IPSEC_SA_FLAG_IS_INBOUND), args->tx_table_id, + args->salt, &args->remote_ip, &args->local_ip, &t->input_sa_index); @@ -328,6 +351,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, &integ_key, flags, args->tx_table_id, + args->salt, &args->local_ip, &args->remote_ip, &t->output_sa_index); @@ -360,16 +384,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ~0); im->ipsec_if_by_sw_if_index[t->sw_if_index] = dev_instance; - vnet_feature_enable_disable ("ip4-output", - "esp4-encrypt-tun", - t->sw_if_index, 1, - &t->output_sa_index, - sizeof (t->output_sa_index)); - vnet_feature_enable_disable ("ip6-output", - "esp6-encrypt-tun", - t->sw_if_index, 1, - &t->output_sa_index, - sizeof (t->output_sa_index)); + ipsec_tunnel_feature_set (im, t, 1); /*1st interface, register protocol */ if (pool_elts (im->tunnel_interfaces) == 1) @@ -394,16 +409,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, hi = vnet_get_hw_interface (vnm, t->hw_if_index); vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0); /* admin down */ - vnet_feature_enable_disable ("ip4-output", - "esp4-encrypt-tun", - hi->sw_if_index, 0, - &t->output_sa_index, - sizeof (t->output_sa_index)); - vnet_feature_enable_disable ("ip6-output", - "esp6-encrypt-tun", - hi->sw_if_index, 0, - &t->output_sa_index, - sizeof (t->output_sa_index)); + ipsec_tunnel_feature_set (im, t, 0); vnet_delete_hw_interface (vnm, t->hw_if_index); if (is_ip6) @@ -429,7 +435,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, int ipsec_add_del_ipsec_gre_tunnel (vnet_main_t * vnm, - ipsec_add_del_ipsec_gre_tunnel_args_t * args) + const ipsec_gre_tunnel_add_del_args_t * args) { ipsec_tunnel_if_t *t = 0; ipsec_main_t *im = &ipsec_main; @@ -441,22 +447,27 @@ ipsec_add_del_ipsec_gre_tunnel (vnet_main_t * vnm, p = hash_get (im->sa_index_by_sa_id, args->local_sa_id); if (!p) return VNET_API_ERROR_INVALID_VALUE; - isa = p[0]; + osa = p[0]; + sa = pool_elt_at_index (im->sad, p[0]); + ipsec_sa_set_IS_GRE (sa); p = hash_get (im->sa_index_by_sa_id, args->remote_sa_id); if (!p) return VNET_API_ERROR_INVALID_VALUE; - osa = p[0]; + isa = p[0]; sa = pool_elt_at_index (im->sad, p[0]); + ipsec_sa_set_IS_GRE (sa); + /* we form the key from the input/remote SA whose tunnel is srouce + * at the remote end */ if (ipsec_sa_is_set_IS_TUNNEL (sa)) { - key.remote_ip = sa->tunnel_dst_addr.ip4.as_u32; + key.remote_ip = sa->tunnel_src_addr.ip4.as_u32; key.spi = clib_host_to_net_u32 (sa->spi); } else { - key.remote_ip = args->remote_ip.as_u32; + key.remote_ip = args->src.as_u32; key.spi = clib_host_to_net_u32 (sa->spi); } @@ -506,6 +517,7 @@ int ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, ipsec_if_set_key_type_t type, u8 alg, u8 * key) { + vlib_main_t *vm = vlib_get_main (); ipsec_main_t *im = &ipsec_main; vnet_hw_interface_t *hi; ipsec_tunnel_if_t *t; @@ -522,24 +534,36 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, sa = pool_elt_at_index (im->sad, t->output_sa_index); ipsec_sa_set_crypto_alg (sa, alg); ipsec_mk_key (&sa->crypto_key, key, vec_len (key)); + sa->crypto_calg = im->crypto_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg, + key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG) { sa = pool_elt_at_index (im->sad, t->output_sa_index); ipsec_sa_set_integ_alg (sa, alg); ipsec_mk_key (&sa->integ_key, key, vec_len (key)); + sa->integ_calg = im->integ_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg, + key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO) { sa = pool_elt_at_index (im->sad, t->input_sa_index); ipsec_sa_set_crypto_alg (sa, alg); ipsec_mk_key (&sa->crypto_key, key, vec_len (key)); + sa->crypto_calg = im->crypto_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg, + key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG) { sa = pool_elt_at_index (im->sad, t->input_sa_index); ipsec_sa_set_integ_alg (sa, alg); ipsec_mk_key (&sa->integ_key, key, vec_len (key)); + sa->integ_calg = im->integ_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg, + key, vec_len (key)); } else return VNET_API_ERROR_INVALID_VALUE; @@ -642,7 +666,13 @@ ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index, u32 sa_id, return VNET_API_ERROR_INVALID_VALUE; } + /* + * re-enable the feature to get the new SA in + * the workers are stopped so no packets are sent in the clear + */ + ipsec_tunnel_feature_set (im, t, 0); t->output_sa_index = sa_index; + ipsec_tunnel_feature_set (im, t, 1); } /* remove sa_id to sa_index mapping on old SA */ @@ -654,12 +684,11 @@ ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index, u32 sa_id, clib_warning ("IPsec backend add/del callback returned error"); return VNET_API_ERROR_SYSCALL_ERROR_1; } - pool_put (im->sad, old_sa); + ipsec_sa_del (old_sa->id); return 0; } - clib_error_t * ipsec_tunnel_if_init (vlib_main_t * vm) {