diff --git a/include/osmocom/sgsn/gprs_sndcp.h b/include/osmocom/sgsn/gprs_sndcp.h index d970240e4..5334d92c0 100644 --- a/include/osmocom/sgsn/gprs_sndcp.h +++ b/include/osmocom/sgsn/gprs_sndcp.h @@ -76,4 +76,7 @@ int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, struct gprs_llc_xid_field *xid_field_request, struct gprs_llc_lle *lle); +/* Clean up all gprs_sndcp_entities related to llme (OS#4824) */ +void gprs_sndcp_sm_deactivate_ind_by_llme(struct gprs_llc_llme *llme); + #endif /* INT_SNDCP_H */ diff --git a/src/sgsn/gprs_llc.c b/src/sgsn/gprs_llc.c index eea1cecfa..453ded5db 100644 --- a/src/sgsn/gprs_llc.c +++ b/src/sgsn/gprs_llc.c @@ -590,6 +590,7 @@ static struct gprs_llc_llme *llme_alloc(uint32_t tlli) static void llme_free(struct gprs_llc_llme *llme) { + gprs_sndcp_sm_deactivate_ind_by_llme(llme); gprs_sndcp_comp_free(llme->comp.proto); gprs_sndcp_comp_free(llme->comp.data); llist_del(&llme->list); diff --git a/src/sgsn/gprs_sndcp.c b/src/sgsn/gprs_sndcp.c index 6692f1ae5..d8982accb 100644 --- a/src/sgsn/gprs_sndcp.c +++ b/src/sgsn/gprs_sndcp.c @@ -544,6 +544,20 @@ int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi) return 0; } +/* Clean up all gprs_sndcp_entities related to llme (OS#4824) */ +void gprs_sndcp_sm_deactivate_ind_by_llme(struct gprs_llc_llme *llme) +{ + struct gprs_sndcp_entity *sne, *sne2; + + llist_for_each_entry_safe(sne, sne2, &gprs_sndcp_entities, list) { + if (sne->lle->llme == llme) { + LOGP(DSNDCP, LOGL_INFO, "SNSM-DEACTIVATE.ind for SNDCP attached to llme=%p\n", llme); + /* Free and remove from list */ + sndcp_sm_deactivate_ind(sne->lle, sne->nsapi); + } + } +} + /* Fragmenter state */ struct sndcp_frag_state { uint8_t frag_nr;