From b69db82b1c15e6c896b723f159eab456950059ed Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Thu, 11 Jun 2020 02:36:29 +0200 Subject: [PATCH] MSC pooling: add 'no allow-attach' for MSC off-loading As in 3GPP TS 23.236, to offload an MSC, the BSC must be able to avoid attaching new subscribers to it: 4.5a.1: "UEs being moved from one CN node are stopped from registering to the same CN node again by an O&M command in BSCs and RNCs connected to the pool." Change-Id: I6249201c15d0f6565aca643c21d2375c9ca58584 --- include/osmocom/bsc/bsc_msc_data.h | 1 + src/osmo-bsc/gsm_08_08.c | 13 ++++++++++++- src/osmo-bsc/osmo_bsc_msc.c | 1 + src/osmo-bsc/osmo_bsc_vty.c | 27 +++++++++++++++++++++++++++ tests/nri_cfg.vty | 14 ++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h index 6e29bfe55..f19b9a04b 100644 --- a/include/osmocom/bsc/bsc_msc_data.h +++ b/include/osmocom/bsc/bsc_msc_data.h @@ -181,6 +181,7 @@ struct bsc_msc_data { } mgcp_ipa; struct osmo_nri_ranges *nri_ranges; + bool allow_attach; }; int osmo_bsc_msc_init(struct bsc_msc_data *msc); diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c index 46ef9afea..c002ebb96 100644 --- a/src/osmo-bsc/gsm_08_08.c +++ b/src/osmo-bsc/gsm_08_08.c @@ -280,7 +280,18 @@ static struct bsc_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn, /* Figure out the next round-robin MSC. The MSCs may appear unsorted in net->mscs. Make sure to linearly * round robin the MSCs by number: pick the lowest msc->nr >= round_robin_next_nr, and also remember the - * lowest available msc->nr to wrap back to that in case no next MSC is left. */ + * lowest available msc->nr to wrap back to that in case no next MSC is left. + * + * MSCs configured with `no allow-attach` do not accept new subscribers and hence must not be picked by + * round-robin. Such an MSC still provides service for already attached subscribers: those that + * successfully performed IMSI-Attach and have a TMSI with an NRI pointing at that MSC. We only avoid + * adding IMSI-Attach of new subscribers. The idea is that the MSC is in a mode of off-loading + * subscribers, and the MSC decides when each subscriber is off-loaded, by assigning the NULL-NRI in a + * new TMSI (at the next periodical LU). So until the MSC decides to offload, an attached subscriber + * remains attached to that MSC and is free to use its services. + */ + if (!msc->allow_attach) + continue; if (!msc_round_robin_first || msc->nr < msc_round_robin_first->nr) msc_round_robin_first = msc; if (msc->nr >= round_robin_next_nr diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c index ce0751806..157808e95 100644 --- a/src/osmo-bsc/osmo_bsc_msc.c +++ b/src/osmo-bsc/osmo_bsc_msc.c @@ -230,6 +230,7 @@ struct bsc_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr) msc_data->mgcp_ipa.local_port = 0; /* dynamic */ msc_data->nri_ranges = osmo_nri_ranges_alloc(msc_data); + msc_data->allow_attach = true; return msc_data; } diff --git a/src/osmo-bsc/osmo_bsc_vty.c b/src/osmo-bsc/osmo_bsc_vty.c index c860cfef8..5c624dd1c 100644 --- a/src/osmo-bsc/osmo_bsc_vty.c +++ b/src/osmo-bsc/osmo_bsc_vty.c @@ -177,6 +177,9 @@ static void write_msc(struct vty *vty, struct bsc_msc_data *msc) } msc_write_nri(vty, msc, false); + + if (!msc->allow_attach) + vty_out(vty, " no allow-attach%s", VTY_NEWLINE); } static int config_write_msc(struct vty *vty) @@ -860,6 +863,28 @@ DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd, return CMD_SUCCESS; } +DEFUN(cfg_msc_allow_attach, cfg_msc_allow_attach_cmd, + "allow-attach", + "Allow this MSC to attach new subscribers (default).\n") +{ + struct bsc_msc_data *msc = bsc_msc_data(vty); + msc->allow_attach = true; + return CMD_SUCCESS; +} + +DEFUN(cfg_msc_no_allow_attach, cfg_msc_no_allow_attach_cmd, + "no allow-attach", + NO_STR + "Do not assign new subscribers to this MSC." + " Useful if an MSC in an MSC pool is configured to off-load subscribers." + " The MSC will still be operational for already IMSI-Attached subscribers," + " but the NAS node selection function will skip this MSC for new subscribers\n") +{ + struct bsc_msc_data *msc = bsc_msc_data(vty); + msc->allow_attach = false; + return CMD_SUCCESS; +} + static void msc_write_nri(struct vty *vty, struct bsc_msc_data *msc, bool verbose) { struct osmo_nri_range *r; @@ -963,6 +988,8 @@ int bsc_vty_init_extra(void) install_element(MSC_NODE, &cfg_msc_nri_add_cmd); install_element(MSC_NODE, &cfg_msc_nri_del_cmd); install_element(MSC_NODE, &cfg_msc_show_nri_cmd); + install_element(MSC_NODE, &cfg_msc_allow_attach_cmd); + install_element(MSC_NODE, &cfg_msc_no_allow_attach_cmd); /* Deprecated: ping time config, kept to support legacy config files. */ install_element(MSC_NODE, &cfg_net_msc_no_ping_time_cmd); diff --git a/tests/nri_cfg.vty b/tests/nri_cfg.vty index 680b8efe8..8287eab38 100644 --- a/tests/nri_cfg.vty +++ b/tests/nri_cfg.vty @@ -150,3 +150,17 @@ OsmoBSC(config-msc)# nri add 1000 OsmoBSC(config-msc)# show nri msc 0 nri add 0 1000 + +OsmoBSC(config-msc)# show running-config +... ! no allow-attach +OsmoBSC(config-msc)# no allow-attach +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + nri add 0 1000 + no allow-attach +... ! no allow-attach +OsmoBSC(config-msc)# allow-attach +OsmoBSC(config-msc)# show running-config +... ! no allow-attach