diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2020-05-27 00:04:26 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2020-06-19 03:58:13 +0200 |
commit | 9aac5c2d215d6309445801d1f3cd954933942615 (patch) | |
tree | 8cd996b3f5582565c08eaddce0ed2e75d23788cd /src | |
parent | 46d526a3dff7527ba23fde1df3d6243e7edf6486 (diff) |
add rudimentary NRI support for MSC pooling
This patch served for a manual testing counterpart for osmo-bsc to implement
MSC pooling.
This enables a basic MSC pooling setup, but for a production setup, osmo-msc
would still lack various features related to unloading subscribers to another
MSC as explained in 3GPP TS 23.236.
Change-Id: Iafe0878a0a2c8669080d757b34a398ea75fced36
Diffstat (limited to 'src')
-rw-r--r-- | src/libmsc/msc_vty.c | 77 | ||||
-rw-r--r-- | src/libvlr/vlr.c | 12 |
2 files changed, 89 insertions, 0 deletions
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index a92609d7f..29deb5e82 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -33,6 +33,7 @@ #include <osmocom/gsm/protocol/gsm_08_58.h> #include <osmocom/gsm/protocol/gsm_04_14.h> #include <osmocom/gsm/protocol/gsm_08_08.h> +#include <osmocom/gsm/gsm23236.h> #include <osmocom/sigtran/sccp_helpers.h> @@ -657,6 +658,76 @@ DEFUN(cfg_msc_osmux, return CMD_SUCCESS; } +#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n" +DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd, + "nri bitlen <0-15>", + NRI_STR + "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n" + "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n") +{ + gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]); + return CMD_SUCCESS; +} + +#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\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] : "" +#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" + +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) +{ + const char *message; + int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.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_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) +{ + const char *message; + int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv); + 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; +} + +static void msc_write_nri(struct vty *vty) +{ + struct osmo_nri_range *r; + + llist_for_each_entry(r, &gsmnet->vlr->cfg.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(show_nri, show_nri_cmd, + "show nri", + SHOW_STR NRI_STR) +{ + msc_write_nri(vty); + return CMD_SUCCESS; +} + static int config_write_msc(struct vty *vty) { vty_out(vty, "msc%s", VTY_NEWLINE); @@ -722,6 +793,8 @@ static int config_write_msc(struct vty *vty) /* Timer introspection commands (generic osmo_tdef API) */ osmo_tdef_vty_groups_write(vty, " "); + msc_write_nri(vty); + return CMD_SUCCESS; } @@ -2002,6 +2075,9 @@ void msc_vty_init(struct gsm_network *msc_network) install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd); install_element(MSC_NODE, &cfg_msc_osmux_cmd); install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd); + install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd); + install_element(MSC_NODE, &cfg_msc_nri_add_cmd); + install_element(MSC_NODE, &cfg_msc_nri_del_cmd); neighbor_ident_vty_init(msc_network); @@ -2023,6 +2099,7 @@ void msc_vty_init(struct gsm_network *msc_network) install_element_ve(&show_bsc_cmd); install_element_ve(&show_msc_conn_cmd); install_element_ve(&show_msc_transaction_cmd); + install_element_ve(&show_nri_cmd); install_element_ve(&sms_send_pend_cmd); install_element_ve(&sms_delete_expired_cmd); diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c index 3a44d3090..33d6331c0 100644 --- a/src/libvlr/vlr.c +++ b/src/libvlr/vlr.c @@ -25,6 +25,7 @@ #include <osmocom/core/timer.h> #include <osmocom/core/tdef.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h> +#include <osmocom/gsm/gsm23236.h> #include <osmocom/gsm/gsup.h> #include <osmocom/gsm/apn.h> #include <osmocom/gsm/gsm48.h> @@ -329,6 +330,15 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub) LOGP(DDB, LOGL_ERROR, "osmo_get_rand_id() failed: %s\n", strerror(-rc)); return rc; } + + if (!llist_empty(&vlr->cfg.nri_ranges->entries)) { + int16_t nri_v; + osmo_tmsi_nri_v_limit_by_ranges(&tmsi, vlr->cfg.nri_ranges, vlr->cfg.nri_bitlen); + osmo_tmsi_nri_v_get(&nri_v, tmsi, vlr->cfg.nri_bitlen); + LOGP(DVLR, LOGL_DEBUG, "New NRI from range [%s] = 0x%x --> TMSI 0x%08x\n", + osmo_nri_ranges_to_str_c(OTC_SELECT, vlr->cfg.nri_ranges), nri_v, tmsi); + } + /* throw the dice again, if the TSMI doesn't fit */ if (tmsi == GSM_RESERVED_TMSI) continue; @@ -1246,6 +1256,8 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) /* defaults */ vlr->cfg.assign_tmsi = true; + vlr->cfg.nri_bitlen = OSMO_NRI_BITLEN_DEFAULT; + vlr->cfg.nri_ranges = osmo_nri_ranges_alloc(vlr); /* reset shared timer definitions */ osmo_tdefs_reset(msc_tdefs_vlr); |