lynxis lazus has uploaded this change for review.

View Change

BSSGP: reset cells when receiving a Reset on Signal BVCI

When a PCU sends a BVC Reset over BSSGP on the Signal BVCI,
all cells which has been setuped previously via PtP BVCIs
has to be removed.

They might be introduced after the Signal BVCI is reseted.

Change-Id: I380c8f9ef90d8c7face5c380d923ab5168f5b484
---
M include/osmocom/sgsn/gprs_routing_area.h
M src/sgsn/gprs_bssgp.c
M src/sgsn/gprs_routing_area.c
M tests/gprs_routing_area/gprs_routing_area_test.c
M tests/gprs_routing_area/gprs_routing_area_test.ok
5 files changed, 90 insertions(+), 13 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/10/40810/1
diff --git a/include/osmocom/sgsn/gprs_routing_area.h b/include/osmocom/sgsn/gprs_routing_area.h
index 90cb0f4..1e60ccc 100644
--- a/include/osmocom/sgsn/gprs_routing_area.h
+++ b/include/osmocom/sgsn/gprs_routing_area.h
@@ -91,8 +91,11 @@
struct sgsn_ra_cell *sgsn_ra_cell_alloc_geran(struct sgsn_ra *ra, uint16_t cell_id, uint16_t nsei, uint16_t bvci);
void sgsn_ra_cell_free(struct sgsn_ra_cell *cell);

-/* Called by BSSGP layer to inform about a reset on a BVCI */
-int sgsn_ra_bvc_reset_ind(uint16_t nsei, uint16_t bvci, struct osmo_cell_global_id_ps *cgi_ps);
+/* GERAN */
+/* Called by BSSGP layer to inform about a reset on a PtP BVCI */
+int sgsn_ra_bvc_cell_reset_ind(uint16_t nsei, uint16_t bvci, struct osmo_cell_global_id_ps *cgi_ps);
+/* Called by BSSGP layer to inform about a reset on a Signal BVCI */
+void sgsn_ra_bvc_sign_reset_ind(uint16_t nsei);
/* FIXME: handle BVC BLOCK/UNBLOCK/UNAVAILABLE */
/* Called by NS-VC layer to inform about an unavailable NSEI (and all BVCI on them) */
int sgsn_ra_nsei_failure_ind(uint16_t nsei);
diff --git a/src/sgsn/gprs_bssgp.c b/src/sgsn/gprs_bssgp.c
index 58aeb75..42cd073 100644
--- a/src/sgsn/gprs_bssgp.c
+++ b/src/sgsn/gprs_bssgp.c
@@ -40,6 +40,14 @@
{
struct osmo_cell_global_id_ps cgi_ps = {};

+ /* Signalling: BVCI == 0, no CGI-PS
+ * PtP BVCI: BVCI != 0, CGI-PS */
+
+ if (bp->bvci == 0) {
+ sgsn_ra_bvc_sign_reset_ind(bp->nsei);
+ return 0;
+ }
+
if (!bp->tp)
return -EINVAL;

@@ -47,7 +55,7 @@
return -EINVAL;

bssgp_parse_cell_id2(&cgi_ps.rai, &cgi_ps.cell_identity, TLVP_VAL(bp->tp, BSSGP_IE_CELL_ID), 8);
- return sgsn_ra_bvc_reset_ind(bp->nsei, bp->bvci, &cgi_ps);
+ return sgsn_ra_bvc_cell_reset_ind(bp->nsei, bp->bvci, &cgi_ps);
}

/* call-back function for the BSSGP protocol */
diff --git a/src/sgsn/gprs_routing_area.c b/src/sgsn/gprs_routing_area.c
index 3ee730f..40bee05 100644
--- a/src/sgsn/gprs_routing_area.c
+++ b/src/sgsn/gprs_routing_area.c
@@ -283,14 +283,14 @@
return sgsn_ra_get_cell_by_lai(&cgi->lai, cgi->cell_identity);
}

-/*! Callback from the BSSGP layer on NM RESET IND
+/*! Callback from the BSSGP layer on NM RESET IND for a cell (PtP BVCI).
*
* \param nsei
* \param bvci
* \param cgi_ps
* \return 0 on success or -ENOMEM
*/
-int sgsn_ra_bvc_reset_ind(uint16_t nsei, uint16_t bvci, struct osmo_cell_global_id_ps *cgi_ps)
+int sgsn_ra_bvc_cell_reset_ind(uint16_t nsei, uint16_t bvci, struct osmo_cell_global_id_ps *cgi_ps)
{
struct sgsn_ra *ra;
struct sgsn_ra_cell *cell;
@@ -385,6 +385,11 @@
return found ? 0 : -ENOENT;
}

+void sgsn_ra_bvc_sign_reset_ind(uint16_t nsei)
+{
+ sgsn_ra_nsei_failure_ind(nsei);
+}
+
int sgsn_ra_geran_page_ra(const struct osmo_routing_area_id *rai, struct sgsn_mm_ctx *mmctx)
{
struct sgsn_ra *ra;
diff --git a/tests/gprs_routing_area/gprs_routing_area_test.c b/tests/gprs_routing_area/gprs_routing_area_test.c
index e61377c..b3f8ed1 100644
--- a/tests/gprs_routing_area/gprs_routing_area_test.c
+++ b/tests/gprs_routing_area/gprs_routing_area_test.c
@@ -268,14 +268,14 @@
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
OSMO_ASSERT(llist_count(&ra_a->cells_alive_list) == 0);

- rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci, &cgi_ps);
OSMO_ASSERT(rc == 0);
OSMO_ASSERT(llist_count(&ra_a->cells_alive_list) == 1);

cell_a = sgsn_ra_get_cell_by_cgi(&cgi);
OSMO_ASSERT(cell_a);

- rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci, &cgi_ps);
OSMO_ASSERT(rc == 0);

cell_b = sgsn_ra_get_cell_by_cgi(&cgi);
@@ -285,7 +285,7 @@
sgsn_ra_free(ra_a);
OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list));

- rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci, &cgi_ps);
OSMO_ASSERT(rc == 0);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);

@@ -320,7 +320,7 @@

sgsn = sgsn_instance_alloc(tall_sgsn_ctx);

- rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci, &cgi_ps);
OSMO_ASSERT(rc == 0);

ra_a = sgsn_ra_get_ra(&cgi_ps.rai);
@@ -402,11 +402,11 @@
g_paging[0].valid = true;
g_paging[0].paged = false;

- rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci, &cgi_ps);
OSMO_ASSERT(rc == 0);

cgi_ps.cell_identity++;
- rc = sgsn_ra_bvc_reset_ind(nsei, bvci+1, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci+1, &cgi_ps);
OSMO_ASSERT(rc == 0);

g_paging[1].bvci = bvci+1;
@@ -424,6 +424,59 @@
cleanup_test();
}

+/* check if a GERAN cell got removed when sending a Reset Ind on Sig BVCI */
+void test_routing_area_geran_geran_sig_reset(void)
+{
+ int rc;
+
+ /* GERAN */
+ struct osmo_routing_area_id geran_rai = {
+ .lac = {
+ .plmn = { .mcc = 262, .mnc = 42, .mnc_3_digits = false },
+ .lac = 24
+ },
+ .rac = 43
+ };
+ struct osmo_cell_global_id_ps cgi_ps = {
+ .rai = geran_rai,
+ .cell_identity = 9998,
+ };
+ uint16_t nsei = 2, bvci = 5;
+
+ struct sgsn_ra_cell *cell;
+
+ sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
+
+ printf("Testing Routing Area GERAN BVCI Signalling Reset Ind\n");
+
+ printf(" Registering GERAN RA/cell via BVCI 5/BVC Reset Ind\n");
+ sgsn_ra_bvc_sign_reset_ind(nsei);
+
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci, &cgi_ps);
+ OSMO_ASSERT(rc == 0);
+
+ printf(" Checking cell on BVCI 5\n");
+ cell = sgsn_ra_get_cell_by_cgi_ps(&cgi_ps);
+ OSMO_ASSERT(cell);
+ OSMO_ASSERT(cell->ran_type == RA_TYPE_GERAN_Gb);
+ OSMO_ASSERT(cell->u.geran.bvci == bvci);
+
+ printf(" Ensure only 1 RA is present\n");
+ OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
+
+ printf(" Ensure only 1 cell is present\n");
+ OSMO_ASSERT(llist_count(&cell->ra->cells_alive_list) == 1);
+
+ printf(" Drop all cells via BVC Reset Ind on Signalling BVCI\n");
+ sgsn_ra_bvc_sign_reset_ind(nsei);
+
+ printf(" Ensure only 0 RAs are present\n");
+ OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 0);
+
+ cleanup_test();
+}
+
+
/* check if a GERAN cell X can changed it's BVCI by BVC Reset Ind */
void test_routing_area_geran_geran_bvci_change(void)
{
@@ -450,7 +503,7 @@
printf("Testing Routing Area GERAN to GERAN (BVCI change)\n");

printf(" Registering GERAN RA/cell via BVCI A/BVC Reset Ind\n");
- rc = sgsn_ra_bvc_reset_ind(nsei, bvci_a, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci_a, &cgi_ps);
OSMO_ASSERT(rc == 0);

printf(" Checking cell on BVCI A\n");
@@ -466,7 +519,7 @@
OSMO_ASSERT(llist_count(&cell_a->ra->cells_alive_list) == 1);

printf(" Registering GERAN RA/cell via BVCI B/BVC Reset Ind\n");
- rc = sgsn_ra_bvc_reset_ind(nsei, bvci_b, &cgi_ps);
+ rc = sgsn_ra_bvc_cell_reset_ind(nsei, bvci_b, &cgi_ps);
OSMO_ASSERT(rc == 0);

printf(" Checking cell on BVCI B\n");
@@ -546,6 +599,7 @@
test_routing_area_reset_ind();
test_routing_area_nsei_free();
test_routing_area_paging();
+ test_routing_area_geran_geran_sig_reset();
test_routing_area_geran_geran_bvci_change();
printf("Done\n");

diff --git a/tests/gprs_routing_area/gprs_routing_area_test.ok b/tests/gprs_routing_area/gprs_routing_area_test.ok
index c506abc..4ce9944 100644
--- a/tests/gprs_routing_area/gprs_routing_area_test.ok
+++ b/tests/gprs_routing_area/gprs_routing_area_test.ok
@@ -4,6 +4,13 @@
Testing Routing Area BSSGP BVC RESET IND
Testing Routing Area nsei failure
Testing Routing Area paging
+Testing Routing Area GERAN BVCI Signalling Reset Ind
+ Registering GERAN RA/cell via BVCI 5/BVC Reset Ind
+ Checking cell on BVCI 5
+ Ensure only 1 RA is present
+ Ensure only 1 cell is present
+ Drop all cells via BVC Reset Ind on Signalling BVCI
+ Ensure only 0 RAs are present
Testing Routing Area GERAN to GERAN (BVCI change)
Registering GERAN RA/cell via BVCI A/BVC Reset Ind
Checking cell on BVCI A

To view, visit change 40810. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: I380c8f9ef90d8c7face5c380d923ab5168f5b484
Gerrit-Change-Number: 40810
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis@fe80.eu>