aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2021-04-27 17:26:34 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2021-04-27 17:34:23 +0200
commit18abd1a808f60e2825d022a683e8b4fbc266c8c6 (patch)
treee47540213d421f953200c7d4325d67853e82decd
parent5979f2bcceb8f9352c79ce67170fa19ff7a0b312 (diff)
Lb: stop RESET FSM when sccp_user is unbound
A crash was reported in bssmap_le_tx_reset() sending a RESET with sccp_user == NULL. Looking at the issue I noticed that when the sccp_user is torn down, the RESET FSM should also be terminated. Add bssmap_reset_term_and_free() to the generic RESET FSM implementation and call from lb_stop() before sccp_user is set to NULL. Related: OS#5134 Change-Id: If412ef990fcdde8ff88098a5169e86f05cd1c7f0
-rw-r--r--include/osmocom/bsc/bssmap_reset.h1
-rw-r--r--src/osmo-bsc/bssmap_reset.c8
-rw-r--r--src/osmo-bsc/lb.c7
-rw-r--r--tests/handover/handover_test.c1
4 files changed, 17 insertions, 0 deletions
diff --git a/include/osmocom/bsc/bssmap_reset.h b/include/osmocom/bsc/bssmap_reset.h
index 560c54307..f90f5ec56 100644
--- a/include/osmocom/bsc/bssmap_reset.h
+++ b/include/osmocom/bsc/bssmap_reset.h
@@ -27,3 +27,4 @@ struct bssmap_reset {
struct bssmap_reset *bssmap_reset_alloc(void *ctx, const char *label, const struct bssmap_reset_cfg *cfg);
bool bssmap_reset_is_conn_ready(const struct bssmap_reset *bssmap_reset);
+void bssmap_reset_term_and_free(struct bssmap_reset *bssmap_reset);
diff --git a/src/osmo-bsc/bssmap_reset.c b/src/osmo-bsc/bssmap_reset.c
index fcf2bab30..6c54560e7 100644
--- a/src/osmo-bsc/bssmap_reset.c
+++ b/src/osmo-bsc/bssmap_reset.c
@@ -70,6 +70,14 @@ struct bssmap_reset *bssmap_reset_alloc(void *ctx, const char *label, const stru
return bssmap_reset;
}
+void bssmap_reset_term_and_free(struct bssmap_reset *bssmap_reset)
+{
+ if (!bssmap_reset)
+ return;
+ osmo_fsm_inst_term(bssmap_reset->fi, OSMO_FSM_TERM_REQUEST, NULL);
+ talloc_free(bssmap_reset);
+}
+
static void link_up(struct bssmap_reset *bssmap_reset)
{
LOGPFSML(bssmap_reset->fi, LOGL_NOTICE, "link up\n");
diff --git a/src/osmo-bsc/lb.c b/src/osmo-bsc/lb.c
index be7d4461a..0ff7c5c82 100644
--- a/src/osmo-bsc/lb.c
+++ b/src/osmo-bsc/lb.c
@@ -399,6 +399,12 @@ static void lb_start_reset_fsm()
bsc_gsmnet->smlc->bssmap_reset = bssmap_reset_alloc(bsc_gsmnet, "Lb", &cfg);
}
+static void lb_stop_reset_fsm()
+{
+ bssmap_reset_term_and_free(bsc_gsmnet->smlc->bssmap_reset);
+ bsc_gsmnet->smlc->bssmap_reset = NULL;
+}
+
static int lb_start()
{
uint32_t default_pc;
@@ -482,6 +488,7 @@ static int lb_stop()
LOGP(DLCS, LOGL_INFO, "Shutting down Lb link\n");
lb_cancel_all();
+ lb_stop_reset_fsm();
osmo_sccp_user_unbind(bsc_gsmnet->smlc->sccp_user);
bsc_gsmnet->smlc->sccp_user = NULL;
return 0;
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 917372bac..d2b175711 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -1405,6 +1405,7 @@ void osmo_bsc_sigtran_tx_reset_ack(void) {}
void osmo_bsc_sigtran_reset(void) {}
void bssmap_reset_alloc(void) {}
void bssmap_reset_is_conn_ready(void) {}
+void bssmap_reset_term_and_free(void) {}
const char *osmo_mgcpc_ep_name(const struct osmo_mgcpc_ep *ep)
{
return "fake-ep";