Close LLSK during shutdown procedure

This way we notify the lower layers that state must be reset, eg. when
Iuh conn drops.

Related: OS#6826
Change-Id: I282f3e75d31b3e481136aade34b30074300ab631
This commit is contained in:
Pau Espin Pedrol
2024-03-12 18:47:22 +01:00
parent b04885005b
commit a9b33a40af
4 changed files with 44 additions and 15 deletions

View File

@@ -28,6 +28,7 @@
enum hnb_shutdown_fsm_states { enum hnb_shutdown_fsm_states {
HNB_SHUTDOWN_ST_NONE, HNB_SHUTDOWN_ST_NONE,
HNB_SHUTDOWN_ST_IN_PROGRESS,
HNB_SHUTDOWN_ST_EXIT, HNB_SHUTDOWN_ST_EXIT,
}; };

View File

@@ -34,6 +34,7 @@ void hnb_llsk_free(struct hnb *hnb);
int hnb_llsk_start_listen(struct hnb *hnb); int hnb_llsk_start_listen(struct hnb *hnb);
bool hnb_llsk_connected(const struct hnb *hnb); bool hnb_llsk_connected(const struct hnb *hnb);
bool hnb_llsk_can_be_configured(struct hnb *hnb); bool hnb_llsk_can_be_configured(struct hnb *hnb);
void hnb_llsk_close_conn(const struct hnb *hnb);
int ll_addr_type2af(enum u_addr_type t); int ll_addr_type2af(enum u_addr_type t);
int ll_addr2osa(enum u_addr_type t, const union u_addr *uaddr, uint16_t port, struct osmo_sockaddr *osa); int ll_addr2osa(enum u_addr_type t, const union u_addr *uaddr, uint16_t port, struct osmo_sockaddr *osa);

View File

@@ -43,15 +43,20 @@ static void st_none_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
} }
static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data) static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case HNB_SHUTDOWN_EV_START:
hnb_shutdown_fsm_state_chg(fi, HNB_SHUTDOWN_ST_IN_PROGRESS);
break;
}
}
static void st_in_progress_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{ {
struct hnb *hnb = (struct hnb *)fi->priv; struct hnb *hnb = (struct hnb *)fi->priv;
struct hnb_ue *ue, *ue_tmp; struct hnb_ue *ue, *ue_tmp;
switch (event) { /* TODO: Also, if Iuh link is still up, maybe send a Hnb deregister req towards HNBGW */
case HNB_SHUTDOWN_EV_START:
/* TODO: here we may want to communicate to lower layers over UDsocket that we are shutting down...
* TODO: Also, if Iuh link is still up, maybe send a Hnb deregister req towards HNBGW
*/
/* Drop active UE contexts, together with their GTP/AUDIO sessions: */ /* Drop active UE contexts, together with their GTP/AUDIO sessions: */
llist_for_each_entry_safe(ue, ue_tmp, &hnb->ue_list, list) llist_for_each_entry_safe(ue, ue_tmp, &hnb->ue_list, list)
@@ -60,9 +65,12 @@ static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
if (osmo_stream_cli_is_connected(hnb->iuh.client)) if (osmo_stream_cli_is_connected(hnb->iuh.client))
osmo_stream_cli_close(hnb->iuh.client); osmo_stream_cli_close(hnb->iuh.client);
/* Close LLSK to notify lower layers that we are shutting down
* even if we are not exiting the process. */
if (hnb_llsk_connected(hnb))
hnb_llsk_close_conn(hnb);
hnb_shutdown_fsm_state_chg(fi, HNB_SHUTDOWN_ST_EXIT); hnb_shutdown_fsm_state_chg(fi, HNB_SHUTDOWN_ST_EXIT);
break;
}
} }
static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
@@ -82,11 +90,17 @@ static struct osmo_fsm_state hnb_shutdown_fsm_states[] = {
.in_event_mask = .in_event_mask =
X(HNB_SHUTDOWN_EV_START), X(HNB_SHUTDOWN_EV_START),
.out_state_mask = .out_state_mask =
X(HNB_SHUTDOWN_ST_EXIT), X(HNB_SHUTDOWN_ST_IN_PROGRESS),
.name = "NONE", .name = "NONE",
.onenter = st_none_on_enter, .onenter = st_none_on_enter,
.action = st_none, .action = st_none,
}, },
[HNB_SHUTDOWN_ST_IN_PROGRESS] = {
.out_state_mask =
X(HNB_SHUTDOWN_ST_EXIT),
.name = "IN_PROGRESS",
.onenter = st_in_progress_on_enter,
},
[HNB_SHUTDOWN_ST_EXIT] = { [HNB_SHUTDOWN_ST_EXIT] = {
.name = "EXIT", .name = "EXIT",
.out_state_mask = .out_state_mask =

View File

@@ -113,7 +113,12 @@ static int llsk_closed_cb(struct osmo_prim_srv *srv)
hnb->llsk.srv = NULL; hnb->llsk.srv = NULL;
hnb->llsk.valid_sapi_mask = 0x0; hnb->llsk.valid_sapi_mask = 0x0;
osmo_timer_del(&hnb->llsk.defer_configure_ind_timer); osmo_timer_del(&hnb->llsk.defer_configure_ind_timer);
/* We actively close the llsk conn during hnb_shutdown, no need to
* re-enter shutdown procedure thin that case: */
if (!hnb_shutdown_in_progress(hnb))
hnb_shutdown(hnb, "LLSK conn dropped", false); hnb_shutdown(hnb, "LLSK conn dropped", false);
return 0; return 0;
} }
@@ -136,6 +141,14 @@ bool hnb_llsk_can_be_configured(struct hnb *hnb)
return false; return false;
} }
void hnb_llsk_close_conn(const struct hnb *hnb)
{
if (!hnb_llsk_connected(hnb))
return;
osmo_prim_srv_close(hnb->llsk.srv);
/* pointer NULLed in llsk_closed_cb() */
}
static void llsk_defer_configure_ind_timer_cb(void *data) static void llsk_defer_configure_ind_timer_cb(void *data)
{ {
struct hnb *hnb = (struct hnb *)data; struct hnb *hnb = (struct hnb *)data;