aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2020-05-26 03:58:14 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2020-06-17 00:14:01 +0200
commit4099f1db504c401e3d7211d9761b034d62d15f7c (patch)
tree005bcf955fd1f5410a7439f132d3618b727461a1
parentdaf5d8b6c7ed56de786529d318264409278eedc7 (diff)
MSC pooling: make NRI mappings VTY configurable
Use the osmo_nri_ranges API to manage each MSC's NRI ranges by VTY configuration. Change-Id: I6c251f2744d7be26fc4ad74adefc96a6a3fe08b0
-rw-r--r--include/osmocom/bsc/bsc_msc_data.h2
-rw-r--r--include/osmocom/bsc/gsm_data.h3
-rw-r--r--src/osmo-bsc/bsc_vty.c69
-rw-r--r--src/osmo-bsc/net_init.c4
-rw-r--r--src/osmo-bsc/osmo_bsc_msc.c3
-rw-r--r--src/osmo-bsc/osmo_bsc_vty.c135
-rw-r--r--tests/nri_cfg.vty152
7 files changed, 367 insertions, 1 deletions
diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h
index 43adaec00..6e29bfe55 100644
--- a/include/osmocom/bsc/bsc_msc_data.h
+++ b/include/osmocom/bsc/bsc_msc_data.h
@@ -179,6 +179,8 @@ struct bsc_msc_data {
/* UDP socket for proxying MGCP via SCCPlite/IPA */
struct osmo_fd ofd;
} mgcp_ipa;
+
+ struct osmo_nri_ranges *nri_ranges;
};
int osmo_bsc_msc_init(struct bsc_msc_data *msc);
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index bc4c01771..38047d29d 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1716,6 +1716,9 @@ struct gsm_network {
/* Don't refuse to start with mutually exclusive codec settings */
bool allow_unusable_timeslots;
+
+ uint8_t nri_bitlen;
+ struct osmo_nri_ranges *null_nri_ranges;
};
struct gsm_audio_support {
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 80658ece8..916ab96bf 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -35,6 +35,7 @@
#include <osmocom/ctrl/control_if.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/gsm23236.h>
#include <arpa/inet.h>
@@ -1110,6 +1111,7 @@ static int config_write_net(struct vty *vty)
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
int i;
+ struct osmo_nri_range *r;
vty_out(vty, "network%s", VTY_NEWLINE);
vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
@@ -1159,6 +1161,16 @@ static int config_write_net(struct vty *vty)
if (gsmnet->allow_unusable_timeslots)
vty_out(vty, " allow-unusable-timeslots%s", VTY_NEWLINE);
+ if (gsmnet->nri_bitlen != OSMO_NRI_BITLEN_DEFAULT)
+ vty_out(vty, " nri bitlen %u%s", gsmnet->nri_bitlen, VTY_NEWLINE);
+
+ llist_for_each_entry(r, &gsmnet->null_nri_ranges->entries, entry) {
+ vty_out(vty, " nri null add %d", r->first);
+ if (r->first != r->last)
+ vty_out(vty, " %d", r->last);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
return CMD_SUCCESS;
}
@@ -2058,6 +2070,60 @@ DEFUN_DEPRECATED(cfg_net_dtx,
return CMD_SUCCESS;
}
+#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
+#define NULL_NRI_STR "Define NULL-NRI values that cause re-assignment of an MS to a different MSC, for MSC pooling.\n"
+#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
+ "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
+ " first value; if omitted, apply only the first value.\n"
+#define NRI_ARGS_TO_STR_FMT "%s%s%s"
+#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
+
+DEFUN(cfg_net_nri_bitlen,
+ cfg_net_nri_bitlen_cmd,
+ "nri bitlen <1-15>",
+ NRI_STR
+ "Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet).\n"
+ "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ gsmnet->nri_bitlen = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_nri_null_add, cfg_net_nri_null_add_cmd,
+ "nri null add <0-32767> [<0-32767>]",
+ NRI_STR NULL_NRI_STR "Add NULL-NRI value (or range)\n"
+ NRI_FIRST_LAST_STR)
+{
+ int rc;
+ const char *message;
+ rc = osmo_nri_ranges_vty_add(&message, NULL, bsc_gsmnet->null_nri_ranges, argc, argv,
+ bsc_gsmnet->nri_bitlen);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_nri_null_del, cfg_net_nri_null_del_cmd,
+ "nri null del <0-32767> [<0-32767>]",
+ NRI_STR NULL_NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ int rc;
+ const char *message;
+ rc = osmo_nri_ranges_vty_del(&message, NULL, bsc_gsmnet->null_nri_ranges, argc, argv);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),
+ VTY_NEWLINE);
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
/* per-BTS configuration */
DEFUN(cfg_bts,
cfg_bts_cmd,
@@ -5400,6 +5466,9 @@ int bsc_vty_init(struct gsm_network *network)
install_element(GSMNET_NODE, &cfg_net_neci_cmd);
install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
+ install_element(GSMNET_NODE, &cfg_net_nri_bitlen_cmd);
+ install_element(GSMNET_NODE, &cfg_net_nri_null_add_cmd);
+ install_element(GSMNET_NODE, &cfg_net_nri_null_del_cmd);
install_element(GSMNET_NODE, &cfg_bts_cmd);
install_node(&bts_node, config_write_bts);
diff --git a/src/osmo-bsc/net_init.c b/src/osmo-bsc/net_init.c
index 34403fa1f..353099ddd 100644
--- a/src/osmo-bsc/net_init.c
+++ b/src/osmo-bsc/net_init.c
@@ -18,6 +18,7 @@
*/
#include <osmocom/core/tdef.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/bsc/osmo_bsc.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
@@ -90,5 +91,8 @@ struct gsm_network *gsm_network_init(void *ctx)
net->mgw.tdefs = g_mgw_tdefs;
osmo_tdefs_reset(net->mgw.tdefs);
+ net->null_nri_ranges = osmo_nri_ranges_alloc(net);
+ net->nri_bitlen = OSMO_NRI_BITLEN_DEFAULT;
+
return net;
}
diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c
index 30b54f3d5..ce0751806 100644
--- a/src/osmo-bsc/osmo_bsc_msc.c
+++ b/src/osmo-bsc/osmo_bsc_msc.c
@@ -34,6 +34,7 @@
#include <osmocom/core/socket.h>
#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/abis/ipa.h>
@@ -228,6 +229,8 @@ struct bsc_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr)
msc_data->mgcp_ipa.local_addr = talloc_strdup(msc_data, "0.0.0.0");
msc_data->mgcp_ipa.local_port = 0; /* dynamic */
+ msc_data->nri_ranges = osmo_nri_ranges_alloc(msc_data);
+
return msc_data;
}
diff --git a/src/osmo-bsc/osmo_bsc_vty.c b/src/osmo-bsc/osmo_bsc_vty.c
index 34a56dedb..c860cfef8 100644
--- a/src/osmo-bsc/osmo_bsc_vty.c
+++ b/src/osmo-bsc/osmo_bsc_vty.c
@@ -29,6 +29,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/vty/logging.h>
#include <osmocom/mgcp_client/mgcp_client.h>
@@ -52,8 +53,10 @@ static struct cmd_node msc_node = {
1,
};
+#define MSC_NR_RANGE "<0-1000>"
+
DEFUN(cfg_net_msc, cfg_net_msc_cmd,
- "msc [<0-1000>]", "Configure MSC details\n" "MSC connection to configure\n")
+ "msc [" MSC_NR_RANGE "]", "Configure MSC details\n" "MSC connection to configure\n")
{
int index = argc == 1 ? atoi(argv[0]) : 0;
struct bsc_msc_data *msc;
@@ -99,6 +102,8 @@ static void write_msc_amr_options(struct vty *vty, struct bsc_msc_data *msc)
vty_out(vty, " amr-payload bandwith-efficient%s", VTY_NEWLINE);
}
+static void msc_write_nri(struct vty *vty, struct bsc_msc_data *msc, bool verbose);
+
static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
{
vty_out(vty, "msc %d%s", msc->nr, VTY_NEWLINE);
@@ -170,6 +175,8 @@ static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
vty_out(vty, " osmux %s%s", msc->use_osmux == OSMUX_USAGE_ON ? "on" : "only",
VTY_NEWLINE);
}
+
+ msc_write_nri(vty, msc, false);
}
static int config_write_msc(struct vty *vty)
@@ -784,6 +791,128 @@ DEFUN(cfg_net_msc_amr_octet_align,
return CMD_SUCCESS;
}
+#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
+#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
+ "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
+ " first value; if omitted, apply only the first value.\n"
+
+#define NRI_WARN(MSC, FORMAT, args...) do { \
+ vty_out(vty, "%% Warning: msc %d: " FORMAT "%s", MSC->nr, ##args, VTY_NEWLINE); \
+ LOGP(DMSC, LOGL_ERROR, "msc %d: " FORMAT "\n", MSC->nr, ##args); \
+ } while (0)
+
+#define NRI_ARGS_TO_STR_FMT "%s%s%s"
+#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
+
+DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd,
+ "nri add <0-32767> [<0-32767>]",
+ NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ struct bsc_msc_data *msc = bsc_msc_data(vty);
+ struct bsc_msc_data *other_msc;
+ bool before;
+ int rc;
+ const char *message;
+ struct osmo_nri_range add_range;
+
+ rc = osmo_nri_ranges_vty_add(&message, &add_range, msc->nri_ranges, argc, argv, bsc_gsmnet->nri_bitlen);
+ if (message) {
+ NRI_WARN(msc, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+
+ /* Issue a warning about NRI range overlaps (but still allow them).
+ * Overlapping ranges will map to whichever MSC comes fist in the bsc_gsmnet->mscs llist,
+ * which is not necessarily in the order of increasing msc->nr. */
+ before = true;
+ llist_for_each_entry(other_msc, &bsc_gsmnet->mscs, entry) {
+ if (other_msc == msc) {
+ before = false;
+ continue;
+ }
+ if (osmo_nri_range_overlaps_ranges(&add_range, other_msc->nri_ranges)) {
+ NRI_WARN(msc, "NRI range [%d..%d] overlaps between msc %d and msc %d."
+ " For overlaps, msc %d has higher priority than msc %d",
+ add_range.first, add_range.last, msc->nr, other_msc->nr,
+ before ? other_msc->nr : msc->nr, before ? msc->nr : other_msc->nr);
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd,
+ "nri del <0-32767> [<0-32767>]",
+ NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ struct bsc_msc_data *msc = bsc_msc_data(vty);
+ int rc;
+ const char *message;
+
+ rc = osmo_nri_ranges_vty_del(&message, NULL, msc->nri_ranges, argc, argv);
+ if (message) {
+ NRI_WARN(msc, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
+static void msc_write_nri(struct vty *vty, struct bsc_msc_data *msc, bool verbose)
+{
+ struct osmo_nri_range *r;
+
+ if (verbose) {
+ vty_out(vty, "msc %d%s", msc->nr, VTY_NEWLINE);
+ if (llist_empty(&msc->nri_ranges->entries)) {
+ vty_out(vty, " %% no NRI mappings%s", VTY_NEWLINE);
+ return;
+ }
+ }
+
+ llist_for_each_entry(r, &msc->nri_ranges->entries, entry) {
+ if (osmo_nri_range_validate(r, 255))
+ vty_out(vty, " %% INVALID RANGE:");
+ vty_out(vty, " nri add %d", r->first);
+ if (r->first != r->last)
+ vty_out(vty, " %d", r->last);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+}
+
+DEFUN(cfg_msc_show_nri, cfg_msc_show_nri_cmd,
+ "show nri",
+ SHOW_STR NRI_STR)
+{
+ struct bsc_msc_data *msc = bsc_msc_data(vty);
+ msc_write_nri(vty, msc, true);
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_nri, show_nri_cmd,
+ "show nri [" MSC_NR_RANGE "]",
+ SHOW_STR NRI_STR "Optional MSC number to limit to\n")
+{
+ struct bsc_msc_data *msc;
+ if (argc > 0) {
+ int msc_nr = atoi(argv[0]);
+ msc = osmo_msc_data_find(bsc_gsmnet, msc_nr);
+ if (!msc) {
+ vty_out(vty, "%% No such MSC%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+ msc_write_nri(vty, msc, true);
+ return CMD_SUCCESS;
+ }
+
+ llist_for_each_entry(msc, &bsc_gsmnet->mscs, entry) {
+ msc_write_nri(vty, msc, true);
+ }
+ return CMD_SUCCESS;
+}
+
int bsc_vty_init_extra(void)
{
struct gsm_network *net = bsc_gsmnet;
@@ -831,6 +960,9 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_msc_cs7_bsc_addr_cmd);
install_element(MSC_NODE, &cfg_msc_cs7_msc_addr_cmd);
install_element(MSC_NODE, &cfg_msc_cs7_asp_proto_cmd);
+ 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);
/* Deprecated: ping time config, kept to support legacy config files. */
install_element(MSC_NODE, &cfg_net_msc_no_ping_time_cmd);
@@ -842,6 +974,7 @@ int bsc_vty_init_extra(void)
install_element_ve(&show_pos_cmd);
install_element_ve(&logging_fltr_imsi_cmd);
install_element_ve(&show_subscr_all_cmd);
+ install_element_ve(&show_nri_cmd);
install_element(ENABLE_NODE, &gen_position_trap_cmd);
diff --git a/tests/nri_cfg.vty b/tests/nri_cfg.vty
new file mode 100644
index 000000000..680b8efe8
--- /dev/null
+++ b/tests/nri_cfg.vty
@@ -0,0 +1,152 @@
+OsmoBSC> show nri
+msc 0
+ % no NRI mappings
+
+OsmoBSC> enable
+OsmoBSC# configure terminal
+
+OsmoBSC(config)# msc 0
+
+OsmoBSC(config-msc)# list
+...
+ nri add <0-32767> [<0-32767>]
+ nri del <0-32767> [<0-32767>]
+ show nri
+...
+OsmoBSC(config-msc)# nri ?
+ add Add NRI value or range to the NRI mapping for this MSC
+ del Remove NRI value or range from the NRI mapping for this MSC
+OsmoBSC(config-msc)# nri add ?
+ <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'.
+OsmoBSC(config-msc)# nri add 23 ?
+ [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value.
+
+OsmoBSC(config-msc)# nri add 23
+OsmoBSC(config-msc)# nri add 256 511
+OsmoBSC(config-msc)# nri add 100 200
+OsmoBSC(config-msc)# nri add 1024 1024
+% Warning: msc 0: Warning: NRI range surpasses current NRI bitlen: 1024..1024
+OsmoBSC(config-msc)# show nri
+msc 0
+ nri add 23
+ nri add 100 200
+ nri add 256 511
+ nri add 1024
+OsmoBSC(config-msc)# exit
+
+OsmoBSC(config)# ### Do msc 2 first, to see that the order of mscs in the internal list is not determined by the msc->nr,
+OsmoBSC(config)# ### and whichever was configured first gets higher priority for overlaps.
+
+OsmoBSC(config)# msc 2
+OsmoBSC(config-msc)# nri add 200 300
+% Warning: msc 2: NRI range [200..300] overlaps between msc 2 and msc 0. For overlaps, msc 0 has higher priority than msc 2
+OsmoBSC(config-msc)# nri add 1024 1025
+% Warning: msc 2: Warning: NRI range surpasses current NRI bitlen: 1024..1025
+% Warning: msc 2: NRI range [1024..1025] overlaps between msc 2 and msc 0. For overlaps, msc 0 has higher priority than msc 2
+OsmoBSC(config-msc)# exit
+
+OsmoBSC(config)# msc 1
+OsmoBSC(config-msc)# nri add 42
+OsmoBSC(config-msc)# nri add 512 767
+OsmoBSC(config-msc)# nri add 200 300
+% Warning: msc 1: NRI range [200..300] overlaps between msc 1 and msc 0. For overlaps, msc 0 has higher priority than msc 1
+% Warning: msc 1: NRI range [200..300] overlaps between msc 1 and msc 2. For overlaps, msc 2 has higher priority than msc 1
+OsmoBSC(config-msc)# nri add 1024 1025
+% Warning: msc 1: Warning: NRI range surpasses current NRI bitlen: 1024..1025
+% Warning: msc 1: NRI range [1024..1025] overlaps between msc 1 and msc 0. For overlaps, msc 0 has higher priority than msc 1
+% Warning: msc 1: NRI range [1024..1025] overlaps between msc 1 and msc 2. For overlaps, msc 2 has higher priority than msc 1
+OsmoBSC(config-msc)# show nri
+msc 1
+ nri add 42
+ nri add 200 300
+ nri add 512 767
+ nri add 1024 1025
+OsmoBSC(config-msc)# exit
+
+OsmoBSC(config)# do show nri
+msc 0
+ nri add 23
+ nri add 100 200
+ nri add 256 511
+ nri add 1024
+msc 2
+ nri add 200 300
+ nri add 1024 1025
+msc 1
+ nri add 42
+ nri add 200 300
+ nri add 512 767
+ nri add 1024 1025
+
+OsmoBSC(config)# network
+OsmoBSC(config-net)# nri bitlen 11
+OsmoBSC(config-net)# show running-config
+...
+network
+...
+ nri bitlen 11
+...
+msc 0
+...
+ nri add 23
+ nri add 100 200
+ nri add 256 511
+ nri add 1024
+...
+msc 2
+...
+ nri add 200 300
+ nri add 1024 1025
+...
+msc 1
+...
+ nri add 42
+ nri add 200 300
+ nri add 512 767
+ nri add 1024 1025
+...
+OsmoBSC(config-net)# exit
+
+OsmoBSC(config)# msc 0
+OsmoBSC(config-msc)# nri del 0 10000
+OsmoBSC(config-msc)# exit
+OsmoBSC(config)# msc 1
+OsmoBSC(config-msc)# nri del 0 10000
+OsmoBSC(config-msc)# exit
+OsmoBSC(config)# msc 2
+OsmoBSC(config-msc)# nri del 0 10000
+OsmoBSC(config-msc)# exit
+OsmoBSC(config)# do show nri
+msc 0
+ % no NRI mappings
+msc 2
+ % no NRI mappings
+msc 1
+ % no NRI mappings
+
+OsmoBSC(config)# msc 0
+OsmoBSC(config-msc)# nri add 0 1000
+OsmoBSC(config-msc)# show nri
+msc 0
+ nri add 0 1000
+OsmoBSC(config-msc)# nri del 23
+OsmoBSC(config-msc)# nri del 200 300
+OsmoBSC(config-msc)# nri del 1000 2000
+OsmoBSC(config-msc)# show nri
+msc 0
+ nri add 0 22
+ nri add 24 199
+ nri add 301 999
+OsmoBSC(config-msc)# nri add 23
+OsmoBSC(config-msc)# show nri
+msc 0
+ nri add 0 199
+ nri add 301 999
+OsmoBSC(config-msc)# nri add 200 300
+OsmoBSC(config-msc)# show nri
+msc 0
+ nri add 0 999
+OsmoBSC(config-msc)# nri add 1000
+OsmoBSC(config-msc)# show nri
+msc 0
+ nri add 0 1000