gbproxy_peer: Free a cell as soon as no BSS BVC uses it

This patch adds gbproxy_cell_cleanup_bvc() which removes the bvc pointer
to the cell. If the BSS BVC of this cell is removed it frees the whole
cell (removing all the SGSN BVC pointers to the cell). The SGSN-side
BVCs are blocked at this point and will only be reestablished if this
BVC is reset again from the BSS.

Before this patch cells were never freed and might accumulate over time.
They would only be reused if the bvci matched that of a previous cell.

Related: OS#4960
Change-Id: Ib874cbebcea58fa4bf15e1ff40fe11601573e531
This commit is contained in:
Daniel Willmann 2021-07-14 18:10:16 +02:00
parent 990b151fbb
commit a631a3a268
2 changed files with 18 additions and 15 deletions

View File

@ -288,6 +288,7 @@ struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t b
struct gbproxy_cell *gbproxy_cell_by_cellid(struct gbproxy_config *cfg, const struct gprs_ra_id *raid, uint16_t cid);
void gbproxy_cell_free(struct gbproxy_cell *cell);
bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc);
void gbproxy_cell_cleanup_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc);
/* NSE handling */
struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);

View File

@ -103,8 +103,6 @@ struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci)
void gbproxy_bvc_free(struct gbproxy_bvc *bvc)
{
struct gbproxy_cell *cell;
if (!bvc)
return;
@ -117,21 +115,10 @@ void gbproxy_bvc_free(struct gbproxy_bvc *bvc)
osmo_fsm_inst_free(bvc->fi);
cell = bvc->cell;
if (cell) {
int i;
if (cell->bss_bvc == bvc)
cell->bss_bvc = NULL;
/* we could also be a SGSN-side BVC */
for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
if (cell->sgsn_bvc[i] == bvc)
cell->sgsn_bvc[i] = NULL;
}
if (bvc->cell) {
gbproxy_cell_cleanup_bvc(bvc->cell, bvc);
bvc->cell = NULL;
}
talloc_free(bvc);
}
@ -214,6 +201,21 @@ struct gbproxy_cell *gbproxy_cell_by_cellid(struct gbproxy_config *cfg, const st
return NULL;
}
void gbproxy_cell_cleanup_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc)
{
int i;
if (cell->bss_bvc == bvc)
return gbproxy_cell_free(cell);
/* we could also be a SGSN-side BVC */
for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
if (cell->sgsn_bvc[i] == bvc)
cell->sgsn_bvc[i] = NULL;
}
}
void gbproxy_cell_free(struct gbproxy_cell *cell)
{
unsigned int i;