From 2652867480a185ccdeccf9ca9210a1213b82cf26 Mon Sep 17 00:00:00 2001 From: Denys Haryachyy Date: Wed, 12 Jul 2023 17:32:55 +0300 Subject: ikev2: cleanup stuck sessions The following issues are fixed: * in responder code: do lookup again as the old pointer could be invalidated during the cleanup operation * in initiar code: do the cleanup of session if there're no child SAs or if there's no response from the responder during initial request (this can easily happen if the response packet was lost/dropped/etc) * print the state of ikev2 profile (for easier tshooting) Type: fix Change-Id: I853d9851c0cf131696585e3c98fa97e66789badd Signed-off-by: Stanislav Zaikin --- src/plugins/ikev2/ikev2.c | 36 +++++++++++++++++++++--------------- src/plugins/ikev2/ikev2_cli.c | 11 +++++++++++ src/plugins/ikev2/ikev2_priv.h | 21 +++++++++++++-------- 3 files changed, 45 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index f0eaa7a4355..3e808736078 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -3269,6 +3269,8 @@ ikev2_node_internal (vlib_main_t *vm, vlib_node_runtime_t *node, if (sa0->state == IKEV2_STATE_AUTHENTICATED) { ikev2_initial_contact_cleanup (ptd, sa0); + p = hash_get (ptd->sa_by_rspi, + clib_net_to_host_u64 (ike0->rspi)); ikev2_sa_match_ts (sa0); if (sa0->state != IKEV2_STATE_TS_UNACCEPTABLE) ikev2_create_tunnel_interface (vm, sa0, &sa0->childs[0], @@ -5334,24 +5336,28 @@ ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt, ikev2_child_sa_t *c; u8 del_old_ids = 0; - if (sa->state != IKEV2_STATE_AUTHENTICATED) - continue; + if (sa->state == IKEV2_STATE_SA_INIT) + { + if (vec_len (sa->childs) > 0) + vec_add1 (to_be_deleted, sa - tkm->sas); + } + else if (sa->state != IKEV2_STATE_AUTHENTICATED) + continue; - if (sa->old_remote_id_present && 0 > sa->old_id_expiration) - { - sa->old_remote_id_present = 0; - del_old_ids = 1; - } - else - sa->old_id_expiration -= 1; + if (sa->old_remote_id_present && 0 > sa->old_id_expiration) + { + sa->old_remote_id_present = 0; + del_old_ids = 1; + } + else + sa->old_id_expiration -= 1; - vec_foreach (c, sa->childs) - ikev2_mngr_process_child_sa(sa, c, del_old_ids); + vec_foreach (c, sa->childs) + ikev2_mngr_process_child_sa (sa, c, del_old_ids); - if (!km->dpd_disabled && ikev2_mngr_process_responder_sas (sa)) - vec_add1 (to_be_deleted, sa - tkm->sas); - } - /* *INDENT-ON* */ + if (!km->dpd_disabled && ikev2_mngr_process_responder_sas (sa)) + vec_add1 (to_be_deleted, sa - tkm->sas); + } vec_foreach (sai, to_be_deleted) { diff --git a/src/plugins/ikev2/ikev2_cli.c b/src/plugins/ikev2/ikev2_cli.c index 382f1e19eba..285a8993311 100644 --- a/src/plugins/ikev2/ikev2_cli.c +++ b/src/plugins/ikev2/ikev2_cli.c @@ -121,6 +121,12 @@ format_ikev2_child_sa (u8 * s, va_list * va) return s; } +static char *stateNames[] = { +#define _(v, f, s) s, + foreach_ikev2_state +#undef _ +}; + static u8 * format_ikev2_sa (u8 * s, va_list * va) { @@ -150,6 +156,11 @@ format_ikev2_sa (u8 * s, va_list * va) tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH); s = format (s, "%U", format_ikev2_sa_transform, tr); + if (sa->state <= IKEV2_STATE_NO_PROPOSAL_CHOSEN) + { + s = format (s, "\n state: %s", stateNames[sa->state]); + } + s = format (s, "\n%U", format_white_space, indent); s = format (s, "nonce i:%U\n%Ur:%U\n", diff --git a/src/plugins/ikev2/ikev2_priv.h b/src/plugins/ikev2/ikev2_priv.h index faa0ca75d66..dca2fe80c57 100644 --- a/src/plugins/ikev2/ikev2_priv.h +++ b/src/plugins/ikev2/ikev2_priv.h @@ -184,16 +184,21 @@ do { \ #define ikev2_log_debug(...) \ vlib_log(VLIB_LOG_LEVEL_DEBUG, ikev2_main.log_class, __VA_ARGS__) +#define foreach_ikev2_state \ + _ (0, UNKNOWN, "UNKNOWN") \ + _ (1, SA_INIT, "SA_INIT") \ + _ (2, DELETED, "DELETED") \ + _ (3, AUTH_FAILED, "AUTH_FAILED") \ + _ (4, AUTHENTICATED, "AUTHENTICATED") \ + _ (5, NOTIFY_AND_DELETE, "NOTIFY_AND_DELETE") \ + _ (6, TS_UNACCEPTABLE, "TS_UNACCEPTABLE") \ + _ (7, NO_PROPOSAL_CHOSEN, "NO_PROPOSAL_CHOSEN") + typedef enum { - IKEV2_STATE_UNKNOWN, - IKEV2_STATE_SA_INIT, - IKEV2_STATE_DELETED, - IKEV2_STATE_AUTH_FAILED, - IKEV2_STATE_AUTHENTICATED, - IKEV2_STATE_NOTIFY_AND_DELETE, - IKEV2_STATE_TS_UNACCEPTABLE, - IKEV2_STATE_NO_PROPOSAL_CHOSEN, +#define _(v, f, s) IKEV2_STATE_##f = v, + foreach_ikev2_state +#undef _ } ikev2_state_t; typedef struct -- cgit 1.2.3-korg