osmith has uploaded this change for review.

View Change

bssap: forward paging to relevant BSCs only

With osmo-bsc I28e0f9497043e90f999b593602b7ffd812787430, OsmoBSC can be
configured to send a cell identifier list in BSSMAP reset. Use this to
send pagings only to relevant BSCs instead of all BSCs.

Related: SYS#5560
Related: OS#5522
Change-Id: Iad3d1de8339206fa80f9fd10ac9213a7728a3c73
---
M include/osmocom/bsc_nat/bsc.h
M src/osmo-bsc-nat/bsc.c
M src/osmo-bsc-nat/bssap.c
3 files changed, 104 insertions(+), 2 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-bsc-nat refs/changes/67/27767/1
diff --git a/include/osmocom/bsc_nat/bsc.h b/include/osmocom/bsc_nat/bsc.h
index 7c11a82..20af445 100644
--- a/include/osmocom/bsc_nat/bsc.h
+++ b/include/osmocom/bsc_nat/bsc.h
@@ -19,14 +19,19 @@

#pragma once

+#include <osmocom/gsm/gsm0808_utils.h>
#include <osmocom/sigtran/sccp_sap.h>

struct bsc {
struct llist_head list;
struct osmo_sccp_addr addr;
+ struct gsm0808_cell_id_list2 cil;
};

struct bsc *bsc_alloc(struct osmo_sccp_addr *addr);
struct bsc *bsc_get_by_pc(uint32_t pointcode);
+
+bool bsc_cil_match(struct bsc *bsc, struct gsm0808_cell_id_list2 *cil);
+
void bsc_free(struct bsc *bsc);
void bsc_free_subscr_conn_all(struct bsc *bsc);
diff --git a/src/osmo-bsc-nat/bsc.c b/src/osmo-bsc-nat/bsc.c
index 0461909..744ebfc 100644
--- a/src/osmo-bsc-nat/bsc.c
+++ b/src/osmo-bsc-nat/bsc.c
@@ -52,6 +52,60 @@
return NULL;
}

+bool bsc_cil_match(struct bsc *bsc, struct gsm0808_cell_id_list2 *cil)
+{
+ unsigned int i, j;
+ const struct osmo_lac_and_ci_id *bsc_id;
+
+ /* OsmoBSC sends cell identifier list with discriminator LAC and CI,
+ * see gsm_bts_cell_id() in osmo-bsc.git. */
+ if (bsc->cil.id_discr != CELL_IDENT_LAC_AND_CI) {
+ LOGP(DMAIN, LOGL_ERROR, "%s: unexpected id_discr 0x%x, assuming match\n", talloc_get_name(bsc),
+ bsc->cil.id_discr);
+ return true;
+ }
+
+ for (i = 0; i < bsc->cil.id_list_len; i++) {
+ bsc_id = &bsc->cil.id_list[i].lac_and_ci;
+
+ for (j = 0; j < cil->id_list_len; j++) {
+ switch (cil->id_discr) {
+ case CELL_IDENT_NO_CELL:
+ case CELL_IDENT_BSS:
+ return true;
+
+ case CELL_IDENT_WHOLE_GLOBAL:
+ if (bsc_id->lac == cil->id_list[j].global.lai.lac
+ && bsc_id->ci == cil->id_list[j].global.cell_identity)
+ return true;
+
+ case CELL_IDENT_LAC_AND_CI:
+ if (bsc_id->lac == cil->id_list[j].lac_and_ci.lac
+ && bsc_id->ci == cil->id_list[j].lac_and_ci.ci)
+ return true;
+
+ case CELL_IDENT_CI:
+ if (bsc_id->ci == cil->id_list[j].ci)
+ return true;
+
+ case CELL_IDENT_LAI_AND_LAC:
+ if (bsc_id->lac == cil->id_list[j].lai_and_lac.lac)
+ return true;
+
+ case CELL_IDENT_LAC:
+ if (bsc_id->lac == cil->id_list[j].lac)
+ return true;
+ default:
+ LOGP(DMAIN, LOGL_ERROR, "%s(0x%x) is not implemented, assuming match\n", __func__, cil->id_discr);
+ return true;
+ }
+
+ }
+ }
+
+ return false;
+}
+
void bsc_free_subscr_conn_all(struct bsc *bsc)
{
struct subscr_conn *subscr_conn;
diff --git a/src/osmo-bsc-nat/bssap.c b/src/osmo-bsc-nat/bssap.c
index 8e73a50..893d1a6 100644
--- a/src/osmo-bsc-nat/bssap.c
+++ b/src/osmo-bsc-nat/bssap.c
@@ -45,6 +45,9 @@
struct bsc *bsc;
int ret = 0;
int rc;
+ struct tlv_parsed tp;
+ struct tlv_p_entry *e;
+ struct gsm0808_cell_id_list2 cil;

if (msc->addr.pc != addr->pc) {
LOGP(DMAIN, LOGL_ERROR, "Unexpected Rx PAGING in CN from %s, which is not %s\n",
@@ -54,10 +57,32 @@

LOGP(DMAIN, LOGL_DEBUG, "Rx PAGING from %s\n", talloc_get_name(msc));

+ tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, length - 1, 0, 0);
+
+ if (!(e = TLVP_GET(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST))) {
+ LOGP(DMAIN, LOGL_ERROR, "Missing IE: cell identifier list\n");
+ return -1;
+ }
+ if (gsm0808_dec_cell_id_list2(&cil, e->val, e->len) < 0) {
+ LOGP(DMAIN, LOGL_ERROR, "Invalid IE: cell identifier list\n");
+ return -1;
+ }
+
msgb_pull_to_l2(msg);

- /* Page all BSCs */
+ /* Page all relevant BSCs */
llist_for_each_entry(bsc, &g_bsc_nat->ran.bscs, list) {
+ if (bsc->cil.id_list_len) {
+ if (!bsc_cil_match(bsc, &cil)) {
+ LOGP(DMAIN, LOGL_DEBUG, "%s: cell identifier list doesn't match\n",
+ talloc_get_name(bsc));
+ continue;
+ }
+ } else {
+ LOGP(DMAIN, LOGL_DEBUG, "%s: no cell identifier list, can't check if paging is relevant\n",
+ talloc_get_name(bsc));
+ }
+
LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", talloc_get_name(bsc));
rc = osmo_sccp_tx_unitdata(sccp_inst->scu,
&sccp_inst->addr,
@@ -112,13 +137,31 @@
{
struct bsc_nat_sccp_inst *sccp_inst = g_bsc_nat->ran.sccp_inst;
struct bsc *bsc;
+ struct tlv_parsed tp;
+ struct tlv_p_entry *e;
+ struct gsm0808_cell_id_list2 cil;
+
+ tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, length - 1, 0, 0);
+
+ /* Osmocom extension: BSSMAP RESET may contain a cell identifier list,
+ * which OsmoBSCNAT uses in paging code (OS#5522) */
+ if ((e = TLVP_GET(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST))) {
+ if (gsm0808_dec_cell_id_list2(&cil, e->val, e->len) < 0) {
+ LOGP(DMAIN, LOGL_ERROR, "Invalid IE: cell identifier list\n");
+ return -1;
+ }
+ }

/* Store the BSC, since RESET was done the BSCNAT should accept its messages */
bsc = bsc_get_by_pc(addr->pc);
if (!bsc)
bsc = bsc_alloc(addr);

- LOGP(DMAIN, LOGL_NOTICE, "Rx RESET from %s\n", bsc_nat_print_addr_ran(addr));
+ if (e)
+ bsc->cil = cil;
+
+ LOGP(DMAIN, LOGL_NOTICE, "Rx RESET from %s (%s cell identifier list)\n", bsc_nat_print_addr_ran(addr),
+ e ? "with" : "without");

LOGP(DMAIN, LOGL_NOTICE, "Tx RESET ACK to %s\n", bsc_nat_print_addr_ran(addr));
msg = gsm0808_create_reset_ack();

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

Gerrit-Project: osmo-bsc-nat
Gerrit-Branch: master
Gerrit-Change-Id: Iad3d1de8339206fa80f9fd10ac9213a7728a3c73
Gerrit-Change-Number: 27767
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osmith@sysmocom.de>
Gerrit-MessageType: newchange