iu_rnc: Introduce helper API iu_rnc_discard_all_ue_ctx()

This is a preparation commit to introduce iu_rnc_fsm in follow-up patch.
The helper API will be used whenever the entire RNC is considered reset.

* Code inside handle_notice_ind() is moved to its own function
  iu_rnc_discard_all_ue_ctx().
* Dependent helper ue_ctx_link_invalidated_free() API is properly
  prefixed/renamed to ue_conn_ctx_link_invalidated_free(), where methods
  for ue_conn_ctx object are placed.
* ue_conn_ctx_find() is properly prefixed/renamed to
  sgsn_scu_iups_ue_conn_ctx_find() and made available to functions in
  other files.

Change-Id: Ie3a4732a85a69d115dd5756bfa64b296e9e5edd2
This commit is contained in:
Pau Espin Pedrol
2025-09-01 13:30:09 +02:00
parent 611b32811e
commit a24ebc7051
6 changed files with 40 additions and 27 deletions

View File

@@ -88,6 +88,8 @@ int ranap_iu_page_ps2(const char *imsi, const uint32_t *ptmsi, const struct osmo
struct ranap_ue_conn_ctx *ue_conn_ctx_alloc(struct ranap_iu_rnc *rnc, uint32_t conn_id);
void ue_conn_ctx_link_invalidated_free(struct ranap_ue_conn_ctx *ue);
/* freeing the UE will release all resources
* This will close the SCCP connection connected to the UE */
void sgsn_ranap_iu_free_ue(struct ranap_ue_conn_ctx *ue_ctx);

View File

@@ -35,3 +35,5 @@ struct ranap_iu_rnc *iu_rnc_find_or_create(const struct osmo_rnc_id *rnc_id,
struct sgsn_sccp_user_iups *scu_iups,
const struct osmo_sccp_addr *addr);
void iu_rnc_update_rai_seen(struct ranap_iu_rnc *rnc, const struct osmo_routing_area_id *rai);
void iu_rnc_discard_all_ue_ctx(struct ranap_iu_rnc *rnc);

View File

@@ -38,6 +38,8 @@ void sgsn_scu_iups_free(struct sgsn_sccp_user_iups *scu_iups);
int sgsn_scu_iups_tx_data_req(struct sgsn_sccp_user_iups *scu_iups, uint32_t conn_id, struct msgb *ranap_msg);
struct ranap_ue_conn_ctx *sgsn_scu_iups_ue_conn_ctx_find(struct sgsn_sccp_user_iups *scu_iups, uint32_t conn_id);
int sgsn_sccp_init(struct sgsn_instance *sgsn);
void sgsn_sccp_release(struct sgsn_instance *sgsn);

View File

@@ -105,6 +105,22 @@ void sgsn_ranap_iu_free_ue(struct ranap_ue_conn_ctx *ue_ctx)
talloc_free(ue_ctx);
}
void ue_conn_ctx_link_invalidated_free(struct ranap_ue_conn_ctx *ue)
{
uint32_t conn_id = ue->conn_id;
struct sgsn_sccp_user_iups *scu_iups = ue->rnc->scu_iups;
global_iu_event(ue, RANAP_IU_EVENT_LINK_INVALIDATED, NULL);
/* A RANAP_IU_EVENT_LINK_INVALIDATED, can lead to a free */
ue = sgsn_scu_iups_ue_conn_ctx_find(scu_iups, conn_id);
if (!ue)
return;
if (ue->free_on_release)
sgsn_ranap_iu_free_ue(ue);
}
/***********************************************************************
* Paging
***********************************************************************/

View File

@@ -170,3 +170,14 @@ void iu_rnc_update_rai_seen(struct ranap_iu_rnc *rnc, const struct osmo_routing_
}
/* else, LAC,RAC already recorded with the current RNC. */
}
void iu_rnc_discard_all_ue_ctx(struct ranap_iu_rnc *rnc)
{
struct ranap_ue_conn_ctx *ue_ctx, *ue_ctx_tmp;
llist_for_each_entry_safe(ue_ctx, ue_ctx_tmp, &sgsn->sccp.scu_iups->ue_conn_ctx_list, list) {
if (ue_ctx->rnc != rnc)
continue;
ue_conn_ctx_link_invalidated_free(ue_ctx);
}
}

View File

@@ -100,7 +100,7 @@ int sgsn_scu_iups_tx_data_req(struct sgsn_sccp_user_iups *scu_iups, uint32_t con
return rc;
}
static struct ranap_ue_conn_ctx *ue_conn_ctx_find(struct sgsn_sccp_user_iups *scu_iups, uint32_t conn_id)
struct ranap_ue_conn_ctx *sgsn_scu_iups_ue_conn_ctx_find(struct sgsn_sccp_user_iups *scu_iups, uint32_t conn_id)
{
struct ranap_ue_conn_ctx *ctx;
@@ -143,21 +143,6 @@ static void ue_conn_sccp_addr_del(struct sgsn_sccp_user_iups *scu_iups, uint32_t
}
}
static void ue_ctx_link_invalidated_free(struct ranap_ue_conn_ctx *ue)
{
uint32_t conn_id = ue->conn_id;
struct sgsn_sccp_user_iups *scu_iups = ue->rnc->scu_iups;
global_iu_event(ue, RANAP_IU_EVENT_LINK_INVALIDATED, NULL);
/* A RANAP_IU_EVENT_LINK_INVALIDATED, can lead to a free */
ue = ue_conn_ctx_find(scu_iups, conn_id);
if (!ue)
return;
if (ue->free_on_release)
sgsn_ranap_iu_free_ue(ue);
}
static void handle_notice_ind(struct sgsn_sccp_user_iups *scu_iups, const struct osmo_scu_notice_param *ni)
{
struct ranap_iu_rnc *rnc;
@@ -178,7 +163,6 @@ static void handle_notice_ind(struct sgsn_sccp_user_iups *scu_iups, const struct
/* Messages are not arriving to RNC. Signal to user that all related ue_ctx are invalid. */
llist_for_each_entry(rnc, &sgsn->rnc_list, entry) {
struct ranap_ue_conn_ctx *ue_ctx, *ue_ctx_tmp;
if (osmo_sccp_addr_ri_cmp(&rnc->sccp_addr, &ni->calling_addr))
continue;
LOGP(DSUA, LOGL_NOTICE,
@@ -186,11 +170,7 @@ static void handle_notice_ind(struct sgsn_sccp_user_iups *scu_iups, const struct
osmo_rnc_id_name(&rnc->rnc_id),
ni->cause, osmo_sccp_return_cause_name(ni->cause),
ni->importance);
llist_for_each_entry_safe(ue_ctx, ue_ctx_tmp, &scu_iups->ue_conn_ctx_list, list) {
if (ue_ctx->rnc != rnc)
continue;
ue_ctx_link_invalidated_free(ue_ctx);
}
iu_rnc_discard_all_ue_ctx(rnc);
/* TODO: ideally we'd have some event to submit to upper
* layer to inform about peer availability change... */
}
@@ -279,7 +259,7 @@ static void handle_pcstate_ind(struct sgsn_sccp_user_iups *scu_iups, const struc
llist_for_each_entry_safe(ue_ctx, ue_ctx_tmp, &scu_iups->ue_conn_ctx_list, list) {
if (ue_ctx->rnc != rnc)
continue;
ue_ctx_link_invalidated_free(ue_ctx);
ue_conn_ctx_link_invalidated_free(ue_ctx);
}
/* TODO: ideally we'd have some event to submit to upper
* layer to inform about peer availability change... */
@@ -355,7 +335,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
LOGP(DSUA, LOGL_DEBUG, "N-DISCONNECT.ind(%u)\n", conn_id);
ue_conn_sccp_addr_del(scu_iups, conn_id);
ue = ue_conn_ctx_find(scu_iups, conn_id);
ue = sgsn_scu_iups_ue_conn_ctx_find(scu_iups, conn_id);
if (!ue)
break;
@@ -364,10 +344,10 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
rc = sgsn_ranap_iu_rx_co_msg(ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
/* A Iu Release event might be used to free the UE in cn_ranap_handle_co(). */
ue = ue_conn_ctx_find(scu_iups, conn_id);
ue = sgsn_scu_iups_ue_conn_ctx_find(scu_iups, conn_id);
if (!ue)
break;
ue_ctx_link_invalidated_free(ue);
ue_conn_ctx_link_invalidated_free(ue);
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
/* connection-oriented data received */
@@ -376,7 +356,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
/* resolve UE context */
ue = ue_conn_ctx_find(scu_iups, conn_id);
ue = sgsn_scu_iups_ue_conn_ctx_find(scu_iups, conn_id);
if (!ue) {
/* Could be an InitialUE-Message after an empty CR, recreate new_ctx */
const struct osmo_sccp_addr *sccp_addr = ue_conn_sccp_addr_find(scu_iups, conn_id);