osmith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27472 )
Change subject: Store BSCs ......................................................................
Store BSCs
Once a BSC has sent a RESET to BSCNAT, store it. This will be used in future patches to build connection mappings between MSC and BSCs, and to block messages from BSCs that did not send a RESET.
I've considered using a FSM, but at least right now there doesn't seem to be multiple states worth storing. We only have the BSC before it has done the RESET (and then it's simply not in our list) and after it did the RESET (in the list).
Don't use the stored BSCs in the forwarding logic just yet, a future commit will replace the current forwarding code with proper connection mappings.
Related: SYS#5560 Change-Id: Icd7316c49ef26fb45ad45a2ccc1a7916bfb0a387 --- M include/osmocom/bsc_nat/bsc_nat.h M src/osmo-bsc-nat/bsc_nat.c M src/osmo-bsc-nat/bssap.c 3 files changed, 64 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc-nat refs/changes/72/27472/1
diff --git a/include/osmocom/bsc_nat/bsc_nat.h b/include/osmocom/bsc_nat/bsc_nat.h index 3e47782..eb48f08 100644 --- a/include/osmocom/bsc_nat/bsc_nat.h +++ b/include/osmocom/bsc_nat/bsc_nat.h @@ -29,16 +29,27 @@ struct osmo_sccp_user *scu; };
+struct bsc { + struct llist_head list; + struct osmo_sccp_addr addr; +}; + struct bsc_nat { struct osmo_fsm_inst *fi;
struct bsc_nat_sccp_inst *cn; struct bsc_nat_sccp_inst *ran; + + struct llist_head bscs; /* list of struct bsc */ };
struct bsc_nat *bsc_nat_alloc(void *tall_ctx); void bsc_nat_free(struct bsc_nat *bsc_nat);
+struct bsc *bsc_nat_bsc_add(struct bsc_nat *bsc_nat, struct osmo_sccp_addr *addr); +struct bsc *bsc_nat_bsc_get_by_pc(struct bsc_nat *bsc_nat, uint32_t pointcode); +void bsc_nat_bsc_del(struct bsc_nat *bsc_nat, struct bsc *bsc); + const char *bsc_nat_print_addr(struct bsc_nat_sccp_inst *sccp_inst, struct osmo_sccp_addr *addr);
extern void *tall_bsc_nat_ctx; diff --git a/src/osmo-bsc-nat/bsc_nat.c b/src/osmo-bsc-nat/bsc_nat.c index 579c6aa..5a6e84e 100644 --- a/src/osmo-bsc-nat/bsc_nat.c +++ b/src/osmo-bsc-nat/bsc_nat.c @@ -20,6 +20,7 @@ #include "config.h" #include <osmocom/bsc_nat/bsc_nat.h> #include <osmocom/bsc_nat/bsc_nat_fsm.h> +#include <osmocom/bsc_nat/logging.h> #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h>
@@ -38,18 +39,62 @@ OSMO_ASSERT(bsc_nat->ran); talloc_set_name_const(bsc_nat->ran, "struct bsc_nat_sccp_inst (RAN)");
+ INIT_LLIST_HEAD(&bsc_nat->bscs); + bsc_nat_fsm_alloc(bsc_nat);
return bsc_nat; }
+struct bsc *bsc_nat_bsc_add(struct bsc_nat *bsc_nat, struct osmo_sccp_addr *addr) +{ + struct bsc *bsc = talloc_zero(bsc_nat, struct bsc); + + OSMO_ASSERT(bsc); + talloc_set_name(bsc, "BSC(PC=%s)", osmo_ss7_pointcode_print(NULL, addr->pc)); + + LOGP(DMAIN, LOGL_DEBUG, "Add %s\n", talloc_get_name(bsc)); + + bsc->addr = *addr; + + INIT_LLIST_HEAD(&bsc->list); + llist_add(&bsc->list, &bsc_nat->bscs); + + return bsc; +} + +struct bsc *bsc_nat_bsc_get_by_pc(struct bsc_nat *bsc_nat, uint32_t pointcode) +{ + struct bsc *bsc; + + llist_for_each_entry(bsc, &bsc_nat->bscs, list) { + if (bsc->addr.pc == pointcode) + return bsc; + } + + return NULL; +} + +void bsc_nat_bsc_del(struct bsc_nat *bsc_nat, struct bsc *bsc) +{ + LOGP(DMAIN, LOGL_DEBUG, "Del %s\n", talloc_get_name(bsc)); + llist_del(&bsc->list); + talloc_free(bsc); +} + void bsc_nat_free(struct bsc_nat *bsc_nat) { + struct bsc *bsc; + if (bsc_nat->fi) { osmo_fsm_inst_free(bsc_nat->fi); bsc_nat->fi = NULL; }
+ llist_for_each_entry(bsc, &bsc_nat->bscs, list) { + bsc_nat_bsc_del(bsc_nat, bsc); + } + talloc_free(bsc_nat); }
diff --git a/src/osmo-bsc-nat/bssap.c b/src/osmo-bsc-nat/bssap.c index dfeea73..af6c8b3 100644 --- a/src/osmo-bsc-nat/bssap.c +++ b/src/osmo-bsc-nat/bssap.c @@ -36,7 +36,14 @@
static int bssap_ran_handle_reset(struct osmo_sccp_addr *addr, struct msgb *msg, unsigned int length) { - LOGP(DMAIN, LOGL_NOTICE, "Rx RESET from %s\n", bsc_nat_print_addr(g_bsc_nat->ran, addr)); + struct bsc *bsc; + + /* Store the BSC, since RESET was done the BSCNAT should accept its messages */ + bsc = bsc_nat_bsc_get_by_pc(g_bsc_nat, addr->pc); + if (!bsc) + bsc = bsc_nat_bsc_add(g_bsc_nat, addr); + + LOGP(DMAIN, LOGL_NOTICE, "Rx RESET from %s\n", talloc_get_name(bsc)); return tx_reset_ack(g_bsc_nat->ran, addr); }