diff options
author | Filip Tehlar <ftehlar@cisco.com> | 2019-11-30 20:49:40 +0000 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-12-12 23:01:10 +0000 |
commit | 4c6b1b6da5d884c80363aeba75bc318a06e29031 (patch) | |
tree | ad9ea0a501983a381a981abfd381b1e22da22ce9 | |
parent | 64cf459bc9353935a72c3e37892b7b7444029795 (diff) |
ikev2: fix crash during SA rekey
Type: fix
Change-Id: Ib00ab9b2f28c0f4d85e96bf95697f61b8e415f37
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
-rw-r--r-- | src/plugins/ikev2/ikev2.c | 24 | ||||
-rw-r--r-- | src/plugins/ikev2/ikev2_priv.h | 3 | ||||
-rw-r--r-- | src/vnet/ipip/ipip.c | 6 |
3 files changed, 32 insertions, 1 deletions
diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index a260bb16617..b94311ba5fc 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -1538,13 +1538,31 @@ typedef struct static void ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a) { + ikev2_main_t *km = &ikev2_main; u32 sw_if_index; int rv; + uword *p = 0; rv = ipip_add_tunnel (IPIP_TRANSPORT_IP4, ~0, &a->local_ip, &a->remote_ip, 0, IPIP_TUNNEL_FLAG_NONE, IP_DSCP_CS0, &sw_if_index); + if (rv == VNET_API_ERROR_IF_ALREADY_EXISTS) + { + p = hash_get (km->sw_if_indices, sw_if_index); + if (p) + /* interface is managed by IKE; proceed with updating SAs */ + rv = 0; + } + + if (rv) + { + clib_warning ("installing ipip tunnel failed! loc:%U rem:%U", + format_ip4_address, &a->local_ip, + format_ip4_address, &a->remote_ip); + return; + } + rv |= ipsec_sa_add_and_lock (a->local_sa_id, a->local_spi, IPSEC_PROTOCOL_ESP, a->encr_type, @@ -1561,6 +1579,7 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a) u32 *sas_in = NULL; vec_add1 (sas_in, a->remote_sa_id); rv |= ipsec_tun_protect_update (sw_if_index, a->local_sa_id, sas_in); + hash_set1 (km->sw_if_indices, sw_if_index); } static int @@ -1779,6 +1798,7 @@ typedef struct static void ikev2_del_tunnel_from_main (ikev2_del_ipsec_tunnel_args_t * a) { + ikev2_main_t *km = &ikev2_main; /* *INDENT-OFF* */ ipip_tunnel_key_t key = { .src = a->local_ip, @@ -1793,6 +1813,7 @@ ikev2_del_tunnel_from_main (ikev2_del_ipsec_tunnel_args_t * a) if (ipip) { + hash_unset (km->sw_if_indices, ipip->sw_if_index); ipsec_tun_protect_del (ipip->sw_if_index); ipsec_sa_unlock_id (a->remote_sa_id); ipsec_sa_unlock_id (a->local_sa_id); @@ -2535,6 +2556,8 @@ ikev2_node_fn (vlib_main_t * vm, { if (sa0->rekey[0].protocol_id != IKEV2_PROTOCOL_IKE) { + if (sa0->childs) + vec_free (sa0->childs); ikev2_child_sa_t *child; vec_add2 (sa0->childs, child, 1); child->r_proposals = sa0->rekey[0].r_proposal; @@ -3480,6 +3503,7 @@ ikev2_init (vlib_main_t * vm) } km->sa_by_ispi = hash_create (0, sizeof (uword)); + km->sw_if_indices = hash_create (0, 0); udp_register_dst_port (vm, 500, ikev2_node.index, 1); diff --git a/src/plugins/ikev2/ikev2_priv.h b/src/plugins/ikev2/ikev2_priv.h index c1bc41c0e54..630ba1ba351 100644 --- a/src/plugins/ikev2/ikev2_priv.h +++ b/src/plugins/ikev2/ikev2_priv.h @@ -297,6 +297,9 @@ typedef struct ikev2_main_per_thread_data_t *per_thread_data; + /* interface indices managed by IKE */ + uword *sw_if_indices; + /* API message ID base */ u16 msg_id_base; } ikev2_main_t; diff --git a/src/vnet/ipip/ipip.c b/src/vnet/ipip/ipip.c index fc71b5b76df..d68e8152972 100644 --- a/src/vnet/ipip/ipip.c +++ b/src/vnet/ipip/ipip.c @@ -430,7 +430,11 @@ ipip_add_tunnel (ipip_transport_t transport, }; t = ipip_tunnel_db_find (&key); if (t) - return VNET_API_ERROR_IF_ALREADY_EXISTS; + { + if (sw_if_indexp) + sw_if_indexp[0] = t->sw_if_index; + return VNET_API_ERROR_IF_ALREADY_EXISTS; + } pool_get_aligned (gm->tunnels, t, CLIB_CACHE_LINE_BYTES); clib_memset (t, 0, sizeof (*t)); |