neels has submitted this change. (
https://gerrit.osmocom.org/c/osmo-hnbgw/+/32324 )
Change subject: cnpool: add multiple 'msc' and 'sgsn' cfg (use only the
first)
......................................................................
cnpool: add multiple 'msc' and 'sgsn' cfg (use only the first)
Allow configuring multiple MSCs and SGSNs. Show this in new transcript
test cnpool.vty and in sccp.dot chart.
Still use only the first CN link; actual CN link selection from the pool
follows in I66fba27cfbe6e2b27ee3443718846ecfbbd8a974.
Config examples and VTY tests cfg files will be adjusted to the new cfg
syntax in patch If999b71a8a8237699f6ccfcaa31d1885e66c0518. Only the VTY
write() changes are visible here, to pass all transcript tests.
Related: SYS#6412
Change-Id: I5479eded786ec26062d49403a8be12967f113cdb
---
M doc/charts/sccp.dot
M include/osmocom/hnbgw/hnbgw.h
M include/osmocom/hnbgw/hnbgw_cn.h
M include/osmocom/hnbgw/vty.h
M src/osmo-hnbgw/context_map_sccp.c
M src/osmo-hnbgw/hnbgw.c
M src/osmo-hnbgw/hnbgw_cn.c
M src/osmo-hnbgw/hnbgw_vty.c
M src/osmo-hnbgw/osmo_hnbgw_main.c
A tests/cnpool.vty
M tests/config/one_cs7_with_addrs.vty
M tests/config/one_cs7_with_iucs_addr.vty
M tests/config/one_cs7_with_iups_addr.vty
M tests/config/two_cs7_with_addrs.vty
14 files changed, 670 insertions(+), 160 deletions(-)
Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
diff --git a/doc/charts/sccp.dot b/doc/charts/sccp.dot
index ed11ab9..53d6ca4 100644
--- a/doc/charts/sccp.dot
+++ b/doc/charts/sccp.dot
@@ -9,13 +9,15 @@
ss0 -> ss0ab
msc0a [label="2.2.2"]
- ss0ab -> msc0a
+ sgsn0a [label="3.3.3"]
+ msc1a [label="5.5.5"]
+ ss0ab -> msc0a,sgsn0a,msc1a
}
- sccp0 [label="hnbgw_sccp_user for '0'\n .osmo_ss7_instance 0\n
.osmo_sccp_user SSN: RANAP\n PC: ss7 primary = 1.1.1"];
+ sccp0 [label="hnbgw_sccp_user for '0'\n .osmo_sccp_instance\n
.osmo_ss7_user SSN: RANAP"];
ss0 -> sccp0 [dir=back]
- msc0 [label="hnbgw_cnlink for IuCS\n .remote_addr -> 2.2.2"]
+ msc0 [label="hnbgw_cnlink 'msc0'\n .domain = IuCS\n .sccp_addr ->
2.2.2"]
sccp0 -> msc0 [dir=back]
msc0a -> msc0 [dir=back]
@@ -23,26 +25,39 @@
cs1 [label="UE CS conn\n hnbgw_context_map"]
msc0 -> cs0,cs1
+ sgsn0 [label="hnbgw_cnlink 'sgsn0'\n .domain = IuPS\n .sccp_addr ->
3.3.3"]
+ sccp0 -> sgsn0 [dir=back]
+ sgsn0a -> sgsn0 [dir=back]
+
+ ps0 [label="UE PS conn\n hnbgw_context_map"]
+ sgsn0 -> ps0
+
subgraph cluster_ss1 {
label=""
ss1 [label="cs7 instance 1\n local pc: 4.4.4"]
ss1ab [label="address book"]
ss1 -> ss1ab
- sgsn0a [label="3.3.3"]
- ss1ab -> sgsn0a
+ sgsn1a [label="6.6.6"]
+ ss1ab -> sgsn1a
}
- sccp1 [label="hnbgw_sccp_user for '1'\n .osmo_ss7_instance 1\n
.osmo_sccp_user SSN: RANAP\n PC: ss7 primary = 4.4.4"];
+ sccp1 [label="hnbgw_sccp_user for '1'\n .osmo_sccp_instance\n
.osmo_ss7_user SSN: RANAP"];
ss1 -> sccp1 [dir=back]
- sgsn0 [label="hnbgw_cnlink for IuPS\n .remote_addr -> 3.3.3"]
- sccp1 -> sgsn0 [dir=back]
- sgsn0a -> sgsn0 [dir=back]
+ msc1 [label="hnbgw_cnlink 'msc1'\n .domain = IuCS\n .sccp_addr ->
5.5.5"]
+ sccp0 -> msc1 [dir=back]
+ msc1a -> msc1 [dir=back]
- ps0 [label="UE PS conn\n hnbgw_context_map"]
- ps1 [label="UE PS conn\n hnbgw_context_map"]
- sgsn0 -> ps0,ps1
+ cs2 [label="UE CS conn\n hnbgw_context_map"]
+ msc1 -> cs2
+
+ sgsn1 [label="hnbgw_cnlink 'sgsn1'\n .domain = IuPS\n .sccp_addr ->
6.6.6"]
+ sccp1 -> sgsn1 [dir=back]
+ sgsn1a -> sgsn1 [dir=back]
+
+ ps2 [label="UE PS conn\n hnbgw_context_map"]
+ sgsn1 -> ps2
subgraph cluster_sccp_inst {
label="global sccp.users (llist)"
@@ -50,9 +65,14 @@
sccp1
}
- subgraph cluster_hnbgw {
- label="global hnbgw"
+ subgraph cluster_cnpool_iucs {
+ label="global cnpool_iucs"
msc0
+ msc1
+ }
+ subgraph cluster_cnpool_iups {
+ label="global cnpool_iups"
sgsn0
+ sgsn1
}
}
diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h
index 7e6bda7..14552fb 100644
--- a/include/osmocom/hnbgw/hnbgw.h
+++ b/include/osmocom/hnbgw/hnbgw.h
@@ -71,6 +71,8 @@
uint32_t cid; /*!< Cell ID */
};
+struct hnbgw_context_map;
+
/* osmo-hnbgw keeps a single hnbgw_sccp_user per osmo_sccp_instance, for the local
point-code and SSN == RANAP.
* This relates the (opaque) osmo_sccp_user to osmo-hnbgw's per-ss7 state. */
struct hnbgw_sccp_user {
@@ -97,19 +99,62 @@
#define LOG_HSI(HNBGW_SCCP_INST, SUBSYS, LEVEL, FMT, ARGS...) \
LOGP(SUBSYS, LEVEL, "(%s) " FMT, (HNBGW_SCCP_INST) ?
(HNBGW_SCCP_INST)->name : "null", ##ARGS)
-/* A CN peer, like MSC or SGSN. */
+/* User provided configuration for struct hnbgw_cnpool. */
+struct hnbgw_cnpool_cfg {
+ /* FUTURE: This will be added here shortly:
+ * - global NRI config: bitlen and NULL-NRI.
+ */
+};
+
+/* User provided configuration for struct hnbgw_cnlink. */
+struct hnbgw_cnlink_cfg {
+ /* cs7 address book entry to indicate both the remote point-code of the peer, as well as
which cs7 instance to
+ * use. */
+ char *remote_addr_name;
+
+ /* FUTURE: This will be added here shortly:
+ * - per peer NRI config: NRI ranges assigned to this peer.
+ */
+};
+
+/* Collection of CN peers to distribute UE connections across. MSCs for DOMAIN_CS, SGSNs
for DOMAIN_PS. */
+struct hnbgw_cnpool {
+ RANAP_CN_DomainIndicator_t domain;
+
+ /* CN pool string used in VTY config and logging, "iucs" or "iups".
*/
+ const char *pool_name;
+ /* CN peer string used in VTY config and logging, "msc" or "sgsn".
*/
+ const char *peer_name;
+ /* What we use as the remote MSC/SGSN point-code if the user does not configure any
address. */
+ uint32_t default_remote_pc;
+
+ struct hnbgw_cnpool_cfg vty;
+ struct hnbgw_cnpool_cfg use;
+
+ /* List of struct hnbgw_cnlink */
+ struct llist_head cnlinks;
+
+ /* FUTURE: This will be added here shortly:
+ * - round robin state for new conns
+ */
+};
+
+/* A CN peer, like 'msc 0' or 'sgsn 23' */
struct hnbgw_cnlink {
+ struct llist_head entry;
+
+ /* backpointer to CS or PS CN pool. */
+ struct hnbgw_cnpool *pool;
+
+ int nr;
+
+ struct hnbgw_cnlink_cfg vty;
+ struct hnbgw_cnlink_cfg use;
+
/* To print in logging/VTY */
char *name;
- /* IuCS or IuPS? */
- RANAP_CN_DomainIndicator_t domain;
-
- /* cs7 address book entry to indicate both the remote point-code of the peer, as well as
which cs7 instance to
- * use. */
- const char *remote_addr_name;
-
- /* Copy of the address pointed at by remote_addr_name. */
+ /* Copy of the address book entry use.remote_addr_name. */
struct osmo_sccp_addr remote_addr;
/* The SCCP instance for the cs7 instance indicated by remote_addr_name. (Multiple
hnbgw_cnlinks may use the
@@ -123,14 +168,16 @@
#define LOG_CNLINK(CNLINK, SUBSYS, LEVEL, FMT, ARGS...) \
LOGP(SUBSYS, LEVEL, "(%s) " FMT, (CNLINK) ? (CNLINK)->name :
"null", ##ARGS)
+struct hnbgw_cnlink *cnlink_get_nr(struct hnbgw_cnpool *cnpool, int nr, bool
create_if_missing);
+
static inline bool cnlink_is_cs(const struct hnbgw_cnlink *cnlink)
{
- return cnlink && cnlink->domain == DOMAIN_CS;
+ return cnlink && cnlink->pool->domain == DOMAIN_CS;
}
static inline bool cnlink_is_ps(const struct hnbgw_cnlink *cnlink)
{
- return cnlink && cnlink->domain == DOMAIN_PS;
+ return cnlink && cnlink->pool->domain == DOMAIN_PS;
}
static inline struct osmo_sccp_instance *cnlink_sccp(const struct hnbgw_cnlink *cnlink)
@@ -186,8 +233,6 @@
/*! The UDP port where we receive multiplexed CS user
* plane traffic from HNBs */
uint16_t iuh_cs_mux_port;
- const char *iucs_remote_addr_name;
- const char *iups_remote_addr_name;
uint16_t rnc_id;
bool hnbap_allow_tmsi;
/*! print hnb-id (true) or MCC-MNC-LAC-RAC-SAC (false) in logs */
@@ -213,9 +258,11 @@
struct {
/* List of hnbgw_sccp_user */
struct llist_head users;
- /* FUTURE: cnlink_iucs, cnlink_iups will be replaced with llist cnpool. */
- struct hnbgw_cnlink *cnlink_iucs;
- struct hnbgw_cnlink *cnlink_iups;
+
+ /* Pool of core network peers: MSCs for IuCS */
+ struct hnbgw_cnpool cnpool_iucs;
+ /* Pool of core network peers: SGSNs for IuPS */
+ struct hnbgw_cnpool cnpool_iups;
} sccp;
/* MGW pool, also includes the single MGCP client as fallback if no
* pool is configured. */
diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h
index a684c98..79d3c27 100644
--- a/include/osmocom/hnbgw/hnbgw_cn.h
+++ b/include/osmocom/hnbgw/hnbgw_cn.h
@@ -2,12 +2,14 @@
#include <osmocom/hnbgw/hnbgw.h>
-struct hnbgw_cnlink *hnbgw_cnlink_alloc(const char *remote_addr_name,
RANAP_CN_DomainIndicator_t domain);
-
-const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(bool is_ps);
-
struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu,
const struct osmo_sccp_addr *remote_addr);
-struct hnbgw_cnlink *hnbgw_cnlink_select(bool is_ps);
+struct hnbgw_cnlink *hnbgw_cnlink_select(struct hnbgw_context_map *map);
+
+void hnbgw_cnpool_start(struct hnbgw_cnpool *cnpool);
+void hnbgw_cnpool_apply_cfg(struct hnbgw_cnpool *cnpool);
+void hnbgw_cnpool_cnlinks_start_or_restart(struct hnbgw_cnpool *cnpool);
+int hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink);
char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr
*addr);
+
diff --git a/include/osmocom/hnbgw/vty.h b/include/osmocom/hnbgw/vty.h
index cf4a1eb..da0c469 100644
--- a/include/osmocom/hnbgw/vty.h
+++ b/include/osmocom/hnbgw/vty.h
@@ -10,5 +10,7 @@
MGCP_NODE,
MGW_NODE,
PFCP_NODE,
+ MSC_NODE,
+ SGSN_NODE,
};
diff --git a/src/osmo-hnbgw/context_map_sccp.c b/src/osmo-hnbgw/context_map_sccp.c
index cc65b6e..0e3d2b0 100644
--- a/src/osmo-hnbgw/context_map_sccp.c
+++ b/src/osmo-hnbgw/context_map_sccp.c
@@ -137,7 +137,7 @@
prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim));
osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT,
PRIM_OP_REQUEST, ranap_msg);
- prim->u.connect.called_addr = *hnbgw_cn_get_remote_addr(map->is_ps);
+ prim->u.connect.called_addr = map->cnlink->remote_addr;
prim->u.connect.calling_addr = map->cnlink->hnbgw_sccp_user->local_addr;
prim->u.connect.sccp_class = 2;
prim->u.connect.conn_id = map->scu_conn_id;
diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c
index b07dbc7..205c683 100644
--- a/src/osmo-hnbgw/hnbgw.c
+++ b/src/osmo-hnbgw/hnbgw.c
@@ -60,6 +60,32 @@
#if ENABLE_PFCP
g_hnbgw->config.pfcp.remote_port = OSMO_PFCP_PORT;
#endif
+
+ g_hnbgw->sccp.cnpool_iucs = (struct hnbgw_cnpool){
+ .domain = DOMAIN_CS,
+ .pool_name = "iucs",
+ .peer_name = "msc",
+ .default_remote_pc = DEFAULT_PC_MSC,
+ .vty = {
+ /* FUTURE: This will be added here shortly:
+ * - defaults for global NRI config: bitlen and NULL-NRI.
+ */
+ },
+ };
+ INIT_LLIST_HEAD(&g_hnbgw->sccp.cnpool_iucs.cnlinks);
+
+ g_hnbgw->sccp.cnpool_iups = (struct hnbgw_cnpool){
+ .domain = DOMAIN_PS,
+ .pool_name = "iups",
+ .peer_name = "sgsn",
+ .default_remote_pc = DEFAULT_PC_SGSN,
+ .vty = {
+ /* FUTURE: This will be added here shortly:
+ * - defaults for global NRI config: bitlen and NULL-NRI.
+ */
+ },
+ };
+ INIT_LLIST_HEAD(&g_hnbgw->sccp.cnpool_iups.cnlinks);
}
static struct hnb_context *hnb_context_by_id(uint32_t cid)
diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c
index 0175498..d829718 100644
--- a/src/osmo-hnbgw/hnbgw_cn.c
+++ b/src/osmo-hnbgw/hnbgw_cn.c
@@ -60,7 +60,7 @@
cnlink_is_cs(cnlink) ? "IuCS" : "IuPS",
osmo_sccp_inst_addr_name(cnlink->hnbgw_sccp_user->sccp,
&cnlink->remote_addr));
- msg = ranap_new_msg_reset(cnlink->domain, &cause);
+ msg = ranap_new_msg_reset(cnlink->pool->domain, &cause);
return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user,
&cnlink->local_addr,
@@ -84,7 +84,7 @@
cnlink_sccp_addr_to_str(cnlink, &cnlink->hnbgw_sccp_user->local_addr),
cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr));
- msg = ranap_new_msg_reset_ack(cnlink->domain, NULL);
+ msg = ranap_new_msg_reset_ack(cnlink->pool->domain, NULL);
return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user,
&cnlink->hnbgw_sccp_user->local_addr,
@@ -422,35 +422,83 @@
{
if (!addr_name) {
osmo_sccp_make_addr_pc_ssn(dest, default_pc, OSMO_SCCP_SSN_RANAP);
- LOGP(DMAIN, LOGL_INFO, "%s remote addr not configured, using default: %s\n",
label,
- osmo_sccp_addr_name(*ss7, dest));
+ if (label)
+ LOGP(DMAIN, LOGL_INFO, "%s remote addr not configured, using default: %s\n",
label,
+ osmo_sccp_addr_name(*ss7, dest));
return 0;
}
*ss7 = osmo_sccp_addr_by_name(dest, addr_name);
if (!*ss7) {
- LOGP(DMAIN, LOGL_ERROR, "%s remote addr: no such SCCP address book entry:
'%s'\n",
- label, addr_name);
+ if (label)
+ LOGP(DMAIN, LOGL_ERROR, "%s remote addr: no such SCCP address book entry:
'%s'\n",
+ label, addr_name);
return -1;
}
osmo_sccp_addr_set_ssn(dest, OSMO_SCCP_SSN_RANAP);
if (!addr_has_pc_and_ssn(dest)) {
- LOGP(DMAIN, LOGL_ERROR, "Invalid/incomplete %s remote-addr: %s\n",
- label, osmo_sccp_addr_name(*ss7, dest));
+ if (label)
+ LOGP(DMAIN, LOGL_ERROR, "Invalid/incomplete %s remote-addr: %s\n",
+ label, osmo_sccp_addr_name(*ss7, dest));
return -1;
}
- LOGP(DRANAP, LOGL_NOTICE, "Remote %s SCCP addr: %s\n",
- label, osmo_sccp_addr_name(*ss7, dest));
+ if (label)
+ LOGP(DRANAP, LOGL_NOTICE, "Remote %s SCCP addr: %s\n",
+ label, osmo_sccp_addr_name(*ss7, dest));
return 0;
}
+void hnbgw_cnpool_apply_cfg(struct hnbgw_cnpool *cnpool)
+{
+ cnpool->use = cnpool->vty;
+}
+
+static void hnbgw_cnlink_cfg_copy(struct hnbgw_cnlink *cnlink)
+{
+ osmo_talloc_replace_string(cnlink, &cnlink->use.remote_addr_name,
cnlink->vty.remote_addr_name);
+}
+
+static bool hnbgw_cnlink_sccp_cfg_changed(struct hnbgw_cnlink *cnlink)
+{
+ bool changed = false;
+
+ if (cnlink->vty.remote_addr_name && cnlink->use.remote_addr_name) {
+ struct osmo_ss7_instance *ss7;
+ struct osmo_sccp_addr remote_addr = {};
+
+ /* Instead of comparing whether the address book entry names are different, actually
resolve the
+ * resulting SCCP address, and only restart the cnlink if the resulting address
changed. */
+ resolve_addr_name(&remote_addr, &ss7, cnlink->vty.remote_addr_name, NULL,
DEFAULT_PC_HNBGW);
+ if (osmo_sccp_addr_cmp(&remote_addr, &cnlink->remote_addr,
OSMO_SCCP_ADDR_T_PC | OSMO_SCCP_ADDR_T_SSN))
+ changed = true;
+ } else if (cnlink->vty.remote_addr_name != cnlink->use.remote_addr_name) {
+ /* One of them is NULL, the other is not. */
+ changed = true;
+ }
+
+ /* if more cnlink configuration is added in the future, it needs to be compared here.
*/
+
+ return changed;
+}
+
+static void hnbgw_cnlink_drop_sccp(struct hnbgw_cnlink *cnlink)
+{
+ struct hnbgw_context_map *map, *map2;
+
+ llist_for_each_entry_safe(map, map2, &cnlink->map_list, hnbgw_cnlink_entry) {
+ map_sccp_dispatch(map, MAP_SCCP_EV_USER_ABORT, NULL);
+ }
+
+ cnlink->hnbgw_sccp_user = NULL;
+}
+
/* If not present yet, set up all of osmo_ss7_instance, osmo_sccp_instance and
hnbgw_sccp_user for the given cnlink.
* The cs7 instance nr to use is determined by cnlink->remote_addr_name, or cs7
instance 0 if that is not present.
* Set cnlink->hnbgw_sccp_user to the new SCCP instance. Return 0 on success, negative
on error. */
-int cnlink_ensure_sccp(struct hnbgw_cnlink *cnlink)
+int hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink)
{
struct osmo_ss7_instance *ss7 = NULL;
struct osmo_sccp_instance *sccp;
@@ -460,39 +508,36 @@
/* If a hnbgw_sccp_user has already been set up, use that. */
if (cnlink->hnbgw_sccp_user) {
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "SCCP instance already set up, using
%s\n",
- cnlink->hnbgw_sccp_user->name);
- return 0;
+ if (hnbgw_cnlink_sccp_cfg_changed(cnlink)) {
+ LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "config changed, restarting SCCP\n");
+ hnbgw_cnlink_drop_sccp(cnlink);
+ } else {
+ LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "SCCP instance already set up, using
%s\n",
+ cnlink->hnbgw_sccp_user->name);
+ return 0;
+ }
+ } else {
+ LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "no SCCP instance selected yet\n");
}
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "no SCCP instance selected yet\n");
+
+ /* Copy the current configuration: cnlink->use = cnlink->vty */
+ hnbgw_cnlink_cfg_copy(cnlink);
/* Figure out which cs7 instance to use. If cnlink->remote_addr_name is set, it
points to an address book entry
* in a specific cs7 instance. If it is not set, leave ss7 == NULL to use cs7 instance
0. */
- if (cnlink->remote_addr_name) {
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "resolving 'remote-addr %s'\n",
cnlink->remote_addr_name);
- if (resolve_addr_name(&cnlink->remote_addr, &ss7,
cnlink->remote_addr_name, cnlink->name,
+ if (cnlink->use.remote_addr_name) {
+ if (resolve_addr_name(&cnlink->remote_addr, &ss7,
cnlink->use.remote_addr_name, cnlink->name,
DEFAULT_PC_HNBGW)) {
LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "cannot initialize SCCP: there is no SCCP
address named '%s'\n",
- cnlink->remote_addr_name);
+ cnlink->use.remote_addr_name);
return -ENOENT;
}
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "remote-addr is '%s', using cs7
instance %u\n",
- cnlink->remote_addr_name, ss7->cfg.id);
+ cnlink->use.remote_addr_name, ss7->cfg.id);
} else {
/* If no address is configured, use the default remote CN address, according to legacy
behavior. */
- uint32_t remote_pc;
- switch (cnlink->domain) {
- case DOMAIN_CS:
- remote_pc = DEFAULT_PC_MSC;
- break;
- case DOMAIN_PS:
- remote_pc = DEFAULT_PC_SGSN;
- break;
- default:
- return -EINVAL;
- }
- osmo_sccp_make_addr_pc_ssn(&cnlink->remote_addr, remote_pc,
OSMO_SCCP_SSN_RANAP);
+ osmo_sccp_make_addr_pc_ssn(&cnlink->remote_addr,
cnlink->pool->default_remote_pc, OSMO_SCCP_SSN_RANAP);
}
/* If no 'cs7 instance' has been selected by the address, see if there already
is a cs7 0 we can use by default.
@@ -563,47 +608,54 @@
return 0;
}
-struct hnbgw_cnlink *hnbgw_cnlink_alloc(const char *remote_addr_name,
RANAP_CN_DomainIndicator_t domain)
+void hnbgw_cnpool_cnlinks_start_or_restart(struct hnbgw_cnpool *cnpool)
{
struct hnbgw_cnlink *cnlink;
+ hnbgw_cnpool_apply_cfg(cnpool);
+ llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) {
+ hnbgw_cnlink_start_or_restart(cnlink);
+ }
+}
+void hnbgw_cnpool_start(struct hnbgw_cnpool *cnpool)
+{
+ /* Legacy compat: when there is no 'msc N' at all in the config file, set up
'msc 0' with default values (or
+ * 'sgsn' depending on cnpool). */
+ if (llist_empty(&cnpool->cnlinks))
+ cnlink_get_nr(cnpool, 0, true);
+ hnbgw_cnpool_cnlinks_start_or_restart(cnpool);
+}
+
+static struct hnbgw_cnlink *cnlink_alloc(struct hnbgw_cnpool *cnpool, int nr)
+{
+ struct hnbgw_cnlink *cnlink;
cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink);
*cnlink = (struct hnbgw_cnlink){
- .name = (domain == DOMAIN_CS ? "msc-0" : "sgsn-0"),
- .domain = domain,
- .remote_addr_name = talloc_strdup(cnlink, remote_addr_name),
+ .name = talloc_asprintf(cnlink, "%s-%d", cnpool->peer_name, nr),
+ .pool = cnpool,
+ .nr = nr,
+ .vty = {
+ /* VTY config defaults for the new cnlink */
+ },
};
-
INIT_LLIST_HEAD(&cnlink->map_list);
- if (cnlink_ensure_sccp(cnlink)) {
- /* error logging already in cnlink_ensure_sccp() */
- talloc_free(cnlink);
- return NULL;
- }
-
- switch (domain) {
- case DOMAIN_CS:
- OSMO_ASSERT(!g_hnbgw->sccp.cnlink_iucs);
- g_hnbgw->sccp.cnlink_iucs = cnlink;
- break;
- case DOMAIN_PS:
- OSMO_ASSERT(!g_hnbgw->sccp.cnlink_iups);
- g_hnbgw->sccp.cnlink_iups = cnlink;
- break;
- default:
- OSMO_ASSERT(false);
- }
-
+ llist_add_tail(&cnlink->entry, &cnpool->cnlinks);
return cnlink;
}
-const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(bool is_ps)
+struct hnbgw_cnlink *cnlink_get_nr(struct hnbgw_cnpool *cnpool, int nr, bool
create_if_missing)
{
- struct hnbgw_cnlink *cnlink = is_ps ? g_hnbgw->sccp.cnlink_iups :
g_hnbgw->sccp.cnlink_iucs;
- if (!cnlink)
+ struct hnbgw_cnlink *cnlink;
+ llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) {
+ if (cnlink->nr == nr)
+ return cnlink;
+ }
+
+ if (!create_if_missing)
return NULL;
- return &cnlink->remote_addr;
+
+ return cnlink_alloc(cnpool, nr);
}
static bool cnlink_matches(const struct hnbgw_cnlink *cnlink, const struct
hnbgw_sccp_user *hsu, const struct osmo_sccp_addr *remote_addr)
@@ -614,24 +666,37 @@
return false;
return true;
}
+
struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu,
const struct osmo_sccp_addr *remote_addr)
{
- /* FUTURE: loop over llist g_hnb_gw->sccp.cnpool */
- if (cnlink_matches(g_hnbgw->sccp.cnlink_iucs, hsu, remote_addr))
- return g_hnbgw->sccp.cnlink_iucs;
- if (cnlink_matches(g_hnbgw->sccp.cnlink_iups, hsu, remote_addr))
- return g_hnbgw->sccp.cnlink_iups;
+ struct hnbgw_cnlink *cnlink;
+ llist_for_each_entry(cnlink, &g_hnbgw->sccp.cnpool_iucs.cnlinks, entry) {
+ if (cnlink_matches(cnlink, hsu, remote_addr))
+ return cnlink;
+ }
+ llist_for_each_entry(cnlink, &g_hnbgw->sccp.cnpool_iups.cnlinks, entry) {
+ if (cnlink_matches(cnlink, hsu, remote_addr))
+ return cnlink;
+ }
return NULL;
}
-struct hnbgw_cnlink *hnbgw_cnlink_select(bool is_ps)
+struct hnbgw_cnlink *hnbgw_cnlink_select(struct hnbgw_context_map *map)
{
+ struct hnbgw_cnpool *cnpool = map->is_ps ? &g_hnbgw->sccp.cnpool_iups :
&g_hnbgw->sccp.cnpool_iucs;
+ struct hnbgw_cnlink *cnlink;
/* FUTURE: soon we will pick one of many configurable CN peers from a pool. There will
be more input arguments
* (MI, or TMSI, or NRI decoded from RANAP) and this function will do round robin for
new subscribers. */
- if (is_ps)
- return g_hnbgw->sccp.cnlink_iups;
- return g_hnbgw->sccp.cnlink_iucs;
+ llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) {
+ if (!cnlink->hnbgw_sccp_user || !cnlink->hnbgw_sccp_user->sccp_user)
+ continue;
+ LOG_MAP(map, DCN, LOGL_INFO, "Selected %s / %s\n",
+ cnlink->name,
+ cnlink->hnbgw_sccp_user->name);
+ return cnlink;
+ }
+ return NULL;
}
char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr
*addr)
diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c
index c1ff268..d4d1bad 100644
--- a/src/osmo-hnbgw/hnbgw_vty.c
+++ b/src/osmo-hnbgw/hnbgw_vty.c
@@ -74,6 +74,7 @@
"iucs", "Configure IuCS options")
{
vty->node = IUCS_NODE;
+ vty->index = &g_hnbgw->sccp.cnpool_iucs;
return CMD_SUCCESS;
}
@@ -87,6 +88,7 @@
"iups", "Configure IuPS options")
{
vty->node = IUPS_NODE;
+ vty->index = &g_hnbgw->sccp.cnpool_iups;
return CMD_SUCCESS;
}
@@ -138,8 +140,8 @@
vty_out(vty, "%s <->",
osmo_sccp_user_name(cnlink->hnbgw_sccp_user->sccp_user));
vty_out(vty, " %s%s%s%s",
- cnlink->remote_addr_name ? : "",
- cnlink->remote_addr_name ? "=" : "",
+ cnlink->use.remote_addr_name ? : "",
+ cnlink->use.remote_addr_name ? "=" : "",
cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr),
VTY_NEWLINE);
@@ -150,10 +152,13 @@
DEFUN(show_cnlink, show_cnlink_cmd, "show cnlink",
SHOW_STR "Display information on core network link\n")
{
+ struct hnbgw_cnlink *cnlink;
vty_out(vty, "IuCS: ");
- _show_cnlink(vty, g_hnbgw->sccp.cnlink_iucs);
+ llist_for_each_entry(cnlink, &g_hnbgw->sccp.cnpool_iucs.cnlinks, entry)
+ _show_cnlink(vty, cnlink);
vty_out(vty, "IuPS: ");
- _show_cnlink(vty, g_hnbgw->sccp.cnlink_iups);
+ llist_for_each_entry(cnlink, &g_hnbgw->sccp.cnpool_iups.cnlinks, entry)
+ _show_cnlink(vty, cnlink);
return CMD_SUCCESS;
}
@@ -341,23 +346,130 @@
return CMD_WARNING;
}
-DEFUN(cfg_hnbgw_iucs_remote_addr,
- cfg_hnbgw_iucs_remote_addr_cmd,
- "remote-addr NAME",
- "SCCP address to send IuCS to (MSC)\n"
- "SCCP address book entry name (see 'cs7-instance')\n")
+/* Legacy from when there was only one IuCS and one IuPS peer. Instead, there are now
'msc 123' / 'sgsn 123' sub nodes.
+ * To yield legacy behavior, set the first cnlink config in this pool ('msc 0' /
'sgsn 0'). */
+DEFUN_DEPRECATED(cfg_hnbgw_cnpool_remote_addr,
+ cfg_hnbgw_cnpool_remote_addr_cmd,
+ "remote-addr NAME",
+ "Deprecated command: same as '{msc,sgsn} 0' / 'remote-addr
NAME'\n-\n")
{
- g_hnbgw->config.iucs_remote_addr_name = talloc_strdup(g_hnbgw, argv[0]);
+ const char *logmsg;
+ struct hnbgw_cnpool *cnpool = vty->index;
+ struct hnbgw_cnlink *cnlink = cnlink_get_nr(cnpool, 0, true);
+ OSMO_ASSERT(cnlink);
+ cnlink->vty.remote_addr_name = talloc_strdup(cnlink, argv[0]);
+
+ logmsg = talloc_asprintf(OTC_SELECT,
+ "Deprecated: instead of hnbgw/%s/remote-addr,"
+ " use '%s 0'/remote-addr",
+ cnpool->pool_name,
+ cnpool->peer_name);
+ vty_out(vty, "%% %s%s", logmsg, VTY_NEWLINE);
+ LOGP(DLGLOBAL, LOGL_ERROR, "config: %s\n", logmsg);
return CMD_SUCCESS;
}
-DEFUN(cfg_hnbgw_iups_remote_addr,
- cfg_hnbgw_iups_remote_addr_cmd,
- "remote-addr NAME",
- "SCCP address to send IuPS to (SGSN)\n"
- "SCCP address book entry name (see 'cs7-instance')\n")
+#define CNLINK_NR_RANGE "<0-1000>"
+
+static struct cmd_node msc_node = {
+ MSC_NODE,
+ "%s(config-msc)# ",
+ 1,
+};
+
+static struct cmd_node sgsn_node = {
+ SGSN_NODE,
+ "%s(config-sgsn)# ",
+ 1,
+};
+
+/* Commands that are common for 'msc 0' and 'sgsn 0' */
+
+static int cnlink_nr(struct vty *vty, struct hnbgw_cnpool *cnpool, int argc, const char
**argv)
{
- g_hnbgw->config.iups_remote_addr_name = talloc_strdup(g_hnbgw, argv[0]);
+ int nr = atoi(argv[0]);
+ struct hnbgw_cnlink *cnlink = cnlink_get_nr(cnpool, nr, true);
+ OSMO_ASSERT(cnlink);
+ switch (cnpool->domain) {
+ case DOMAIN_CS:
+ vty->node = MSC_NODE;
+ break;
+ case DOMAIN_PS:
+ vty->node = SGSN_NODE;
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+ vty->index = cnlink;
+ return CMD_SUCCESS;
+}
+
+/* 'msc 0' */
+DEFUN(cfg_msc_nr, cfg_msc_nr_cmd,
+ "msc " CNLINK_NR_RANGE,
+ "Configure an IuCS link to an MSC\n"
+ "MSC nr\n")
+{
+ return cnlink_nr(vty, &g_hnbgw->sccp.cnpool_iucs, argc, argv);
+}
+
+/* 'sgsn 0' */
+DEFUN(cfg_sgsn_nr, cfg_sgsn_nr_cmd,
+ "sgsn " CNLINK_NR_RANGE,
+ "Configure an IuPS link to an SGSN\n"
+ "SGSN nr\n")
+{
+ return cnlink_nr(vty, &g_hnbgw->sccp.cnpool_iups, argc, argv);
+}
+
+/* 'msc 0' / 'remote-addr my-msc' and
+ * 'sgsn 0' / 'remote-addr my-sgsn'
+ */
+DEFUN(cfg_cnlink_remote_addr,
+ cfg_cnlink_remote_addr_cmd,
+ "remote-addr NAME",
+ "SCCP address to send RANAP/SCCP to\n"
+ "SCCP address book entry name (see 'cs7 instance' /
'sccp-address')\n")
+{
+ struct hnbgw_cnlink *cnlink = vty->index;
+ cnlink->vty.remote_addr_name = talloc_strdup(cnlink, argv[0]);
+ return CMD_SUCCESS;
+}
+
+#define APPLY_STR "Immediately use configuration modified via telnet VTY, and
restart components as needed.\n"
+#define SCCP_RESTART_STR \
+ " If 'remote-addr' changed, related SCCP links will be restarted,
possibly dropping active UE contexts."
+#define IMPLICIT_ON_STARTUP_STR \
+ " This is run implicitly on program startup, only useful to apply changes made
later via telnet VTY."
+
+DEFUN(cfg_cnlink_apply_sccp, cfg_cnlink_apply_sccp_cmd,
+ "apply sccp",
+ APPLY_STR
+ "For telnet VTY: apply SCCP and NRI config changes made to this CN link in the
running osmo-hnbgw process."
+ SCCP_RESTART_STR IMPLICIT_ON_STARTUP_STR "\n")
+{
+ struct hnbgw_cnlink *cnlink = vty->index;
+ hnbgw_cnlink_start_or_restart(cnlink);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_config_apply_sccp, cfg_config_apply_sccp_cmd,
+ "apply sccp",
+ APPLY_STR
+ "For telnet VTY: apply all SCCP and NRI config changes made to any CN pools
and CN links in the running"
+ " osmo-hnbgw process."
+ SCCP_RESTART_STR IMPLICIT_ON_STARTUP_STR "\n")
+{
+ struct hnbgw_cnpool *cnpool;
+
+ cnpool = &g_hnbgw->sccp.cnpool_iucs;
+ hnbgw_cnpool_apply_cfg(cnpool);
+ hnbgw_cnpool_cnlinks_start_or_restart(cnpool);
+
+ cnpool = &g_hnbgw->sccp.cnpool_iups;
+ hnbgw_cnpool_apply_cfg(cnpool);
+ hnbgw_cnpool_cnlinks_start_or_restart(cnpool);
+
return CMD_SUCCESS;
}
@@ -440,27 +552,31 @@
return CMD_SUCCESS;
}
-static int config_write_hnbgw_iucs(struct vty *vty)
+/* hnbgw
+ * msc 0 } this part
+ * sgsn 0 }
+ */
+static void _config_write_cnlink(struct vty *vty, struct hnbgw_cnpool *cnpool)
{
- if (!g_hnbgw->config.iucs_remote_addr_name)
- return CMD_SUCCESS;
+ struct hnbgw_cnlink *cnlink;
- vty_out(vty, " iucs%s", VTY_NEWLINE);
- vty_out(vty, " remote-addr %s%s", g_hnbgw->config.iucs_remote_addr_name,
- VTY_NEWLINE);
+ llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) {
+ vty_out(vty, "%s %d%s", cnpool->peer_name, cnlink->nr, VTY_NEWLINE);
+ if (cnlink->vty.remote_addr_name)
+ vty_out(vty, " remote-addr %s%s", cnlink->vty.remote_addr_name,
VTY_NEWLINE);
+ /* FUTURE: NRI config */
+ }
+}
+static int config_write_msc(struct vty *vty)
+{
+ _config_write_cnlink(vty, &g_hnbgw->sccp.cnpool_iucs);
return CMD_SUCCESS;
}
-static int config_write_hnbgw_iups(struct vty *vty)
+static int config_write_sgsn(struct vty *vty)
{
- if (!g_hnbgw->config.iups_remote_addr_name)
- return CMD_SUCCESS;
-
- vty_out(vty, " iups%s", VTY_NEWLINE);
- vty_out(vty, " remote-addr %s%s", g_hnbgw->config.iups_remote_addr_name,
- VTY_NEWLINE);
-
+ _config_write_cnlink(vty, &g_hnbgw->sccp.cnpool_iups);
return CMD_SUCCESS;
}
@@ -477,6 +593,12 @@
}
#endif
+static void install_cnlink_elements(int node)
+{
+ install_element(node, &cfg_cnlink_remote_addr_cmd);
+ install_element(node, &cfg_cnlink_apply_sccp_cmd);
+}
+
void hnbgw_vty_init(void)
{
install_element(CONFIG_NODE, &cfg_hnbgw_cmd);
@@ -494,14 +616,14 @@
install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd);
install_element(HNBGW_NODE, &cfg_hnbgw_iucs_cmd);
- install_node(&iucs_node, config_write_hnbgw_iucs);
-
- install_element(IUCS_NODE, &cfg_hnbgw_iucs_remote_addr_cmd);
+ install_node(&iucs_node, NULL);
install_element(HNBGW_NODE, &cfg_hnbgw_iups_cmd);
- install_node(&iups_node, config_write_hnbgw_iups);
+ install_node(&iups_node, NULL);
- install_element(IUPS_NODE, &cfg_hnbgw_iups_remote_addr_cmd);
+ /* deprecated: 'remote-addr' outside of 'msc 123' redirects to 'msc
0' / same for 'sgsn' */
+ install_element(IUCS_NODE, &cfg_hnbgw_cnpool_remote_addr_cmd);
+ install_element(IUPS_NODE, &cfg_hnbgw_cnpool_remote_addr_cmd);
install_element_ve(&show_cnlink_cmd);
install_element_ve(&show_hnb_cmd);
@@ -524,5 +646,16 @@
install_element(PFCP_NODE, &cfg_pfcp_remote_addr_cmd);
#endif
+ install_element(CONFIG_NODE, &cfg_msc_nr_cmd);
+ install_node(&msc_node, config_write_msc);
+ install_cnlink_elements(MSC_NODE);
+
+ install_element(CONFIG_NODE, &cfg_sgsn_nr_cmd);
+ install_node(&sgsn_node, config_write_sgsn);
+ install_cnlink_elements(SGSN_NODE);
+
+ /* global 'apply sccp' command. There are two more on MSC_NODE and SGSN_NODE
from install_cnlink_elements(). */
+ install_element(CONFIG_NODE, &cfg_config_apply_sccp_cmd);
+
osmo_tdef_vty_groups_init(HNBGW_NODE, hnbgw_tdef_group);
}
diff --git a/src/osmo-hnbgw/osmo_hnbgw_main.c b/src/osmo-hnbgw/osmo_hnbgw_main.c
index 4994b1f..30f3de9 100644
--- a/src/osmo-hnbgw/osmo_hnbgw_main.c
+++ b/src/osmo-hnbgw/osmo_hnbgw_main.c
@@ -259,14 +259,6 @@
ranap_set_log_area(DRANAP);
- if (!hnbgw_cnlink_alloc(g_hnbgw->config.iucs_remote_addr_name, DOMAIN_CS)
- || !hnbgw_cnlink_alloc(g_hnbgw->config.iups_remote_addr_name, DOMAIN_PS)) {
- LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n");
- exit(1);
- }
- OSMO_ASSERT(g_hnbgw->sccp.cnlink_iucs);
- OSMO_ASSERT(g_hnbgw->sccp.cnlink_iups);
-
LOGP(DHNBAP, LOGL_NOTICE, "Using RNC-Id %u\n", g_hnbgw->config.rnc_id);
OSMO_ASSERT(g_hnbgw->config.iuh_local_ip);
@@ -300,6 +292,9 @@
hnbgw_pfcp_init();
#endif
+ hnbgw_cnpool_start(&g_hnbgw->sccp.cnpool_iucs);
+ hnbgw_cnpool_start(&g_hnbgw->sccp.cnpool_iups);
+
if (hnbgw_cmdline_config.daemonize) {
rc = osmo_daemonize();
if (rc < 0) {
diff --git a/tests/cnpool.vty b/tests/cnpool.vty
new file mode 100644
index 0000000..6b57122
--- /dev/null
+++ b/tests/cnpool.vty
@@ -0,0 +1,194 @@
+OsmoHNBGW> enable
+OsmoHNBGW# configure terminal
+
+OsmoHNBGW(config)# ### cnpool doc strings
+OsmoHNBGW(config)# hnbgw
+OsmoHNBGW(config-hnbgw)# list
+...
+ iucs
+ iups
+...
+OsmoHNBGW(config-hnbgw)# iucs?
+ iucs Configure IuCS options
+OsmoHNBGW(config-hnbgw)# iups?
+ iups Configure IuPS options
+
+OsmoHNBGW(config-hnbgw)# exit
+
+OsmoHNBGW(config)# msc?
+ msc Configure an IuCS link to an MSC
+OsmoHNBGW(config)# msc ?
+ <0-1000> MSC nr
+
+OsmoHNBGW(config)# sgsn?
+ sgsn Configure an IuPS link to an SGSN
+OsmoHNBGW(config)# sgsn ?
+ <0-1000> SGSN nr
+
+OsmoHNBGW(config)# ### The config file has no 'msc' or 'sgsn', so
defaults have been set up
+OsmoHNBGW(config)# show running-config
+...
+msc 0
+sgsn 0
+...
+
+OsmoHNBGW(config)# msc 1
+
+OsmoHNBGW(config-msc)# list
+...
+ remote-addr NAME
+ apply sccp
+...
+
+OsmoHNBGW(config-msc)# remote-addr?
+ remote-addr SCCP address to send RANAP/SCCP to
+OsmoHNBGW(config-msc)# remote-addr ?
+ NAME SCCP address book entry name (see 'cs7 instance' /
'sccp-address')
+
+OsmoHNBGW(config-msc)# apply?
+ apply Immediately use configuration modified via telnet VTY, and restart components as
needed.
+OsmoHNBGW(config-msc)# apply ?
+ sccp For telnet VTY: apply SCCP and NRI config changes made to this CN link in the
running osmo-hnbgw process. If 'remote-addr' changed, related SCCP links will be
restarted, possibly dropping active UE contexts. This is run implicitly on program
startup, only useful to apply changes made later via telnet VTY.
+
+OsmoHNBGW(config-msc)# exit
+
+OsmoHNBGW(config)# sgsn 1
+
+OsmoHNBGW(config-sgsn)# list
+...
+ remote-addr NAME
+ apply sccp
+...
+
+OsmoHNBGW(config-sgsn)# remote-addr?
+ remote-addr SCCP address to send RANAP/SCCP to
+OsmoHNBGW(config-sgsn)# remote-addr ?
+ NAME SCCP address book entry name (see 'cs7 instance' /
'sccp-address')
+
+OsmoHNBGW(config-sgsn)# apply?
+ apply Immediately use configuration modified via telnet VTY, and restart components as
needed.
+OsmoHNBGW(config-sgsn)# apply ?
+ sccp For telnet VTY: apply SCCP and NRI config changes made to this CN link in the
running osmo-hnbgw process. If 'remote-addr' changed, related SCCP links will be
restarted, possibly dropping active UE contexts. This is run implicitly on program
startup, only useful to apply changes made later via telnet VTY.
+
+OsmoHNBGW(config-sgsn)# exit
+
+OsmoHNBGW(config)# ### Just by entering the nodes above, 'msc 1' and 'sgsn
1' now exist
+OsmoHNBGW(config)# show running-config
+...
+msc 0
+msc 1
+sgsn 0
+sgsn 1
+...
+
+OsmoHNBGW(config)# ### Add {msc,sgsn}x{2,3}
+
+OsmoHNBGW(config)# msc 2
+OsmoHNBGW(config-msc)# remote-addr addr-msc2
+OsmoHNBGW(config-msc)# exit
+
+OsmoHNBGW(config)# msc 3
+OsmoHNBGW(config-msc)# remote-addr addr-msc3
+OsmoHNBGW(config-msc)# exit
+
+OsmoHNBGW(config)# sgsn 2
+OsmoHNBGW(config-sgsn)# remote-addr addr-sgsn2
+OsmoHNBGW(config-sgsn)# exit
+
+OsmoHNBGW(config)# sgsn 3
+OsmoHNBGW(config-sgsn)# remote-addr addr-sgsn3
+OsmoHNBGW(config-sgsn)# exit
+
+OsmoHNBGW(config)# show running-config
+...
+msc 0
+msc 1
+msc 2
+ remote-addr addr-msc2
+msc 3
+ remote-addr addr-msc3
+sgsn 0
+sgsn 1
+sgsn 2
+ remote-addr addr-sgsn2
+sgsn 3
+ remote-addr addr-sgsn3
+...
+
+OsmoHNBGW(config)# ### Re-entering existing nodes works (does not create new ones)
+OsmoHNBGW(config)# msc 3
+OsmoHNBGW(config-msc)# remote-addr addr-msc4
+OsmoHNBGW(config-msc)# exit
+OsmoHNBGW(config)# sgsn 2
+OsmoHNBGW(config-sgsn)# remote-addr addr-sgsn4
+OsmoHNBGW(config-sgsn)# exit
+
+OsmoHNBGW(config)# show running-config
+...
+msc 0
+msc 1
+msc 2
+ remote-addr addr-msc2
+msc 3
+ remote-addr addr-msc4
+sgsn 0
+sgsn 1
+sgsn 2
+ remote-addr addr-sgsn4
+sgsn 3
+ remote-addr addr-sgsn3
+...
+
+OsmoHNBGW(config)# ### Legacy configuration {'iups','iucs'} /
'remote-addr' redirects to {'msc 0','sgsn 0'}:
+
+OsmoHNBGW(config)# hnbgw
+OsmoHNBGW(config-hnbgw)# iucs
+OsmoHNBGW(config-hnbgw-iucs)# remote-addr?
+% There is no matched command.
+OsmoHNBGW(config-hnbgw-iucs)# remote-addr ?
+% There is no matched command.
+OsmoHNBGW(config-hnbgw-iucs)# remote-addr addr-msc0
+% Deprecated: instead of hnbgw/iucs/remote-addr, use 'msc 0'/remote-addr
+OsmoHNBGW(config-hnbgw-iucs)# exit
+
+OsmoHNBGW(config-hnbgw)# iups
+OsmoHNBGW(config-hnbgw-iups)# remote-addr?
+% There is no matched command.
+OsmoHNBGW(config-hnbgw-iups)# remote-addr ?
+% There is no matched command.
+OsmoHNBGW(config-hnbgw-iups)# remote-addr addr-sgsn0
+% Deprecated: instead of hnbgw/iups/remote-addr, use 'sgsn 0'/remote-addr
+OsmoHNBGW(config-hnbgw-iups)# exit
+
+OsmoHNBGW(config-hnbgw)# show running-config
+...
+hnbgw
+...
+msc 0
+ remote-addr addr-msc0
+msc 1
+msc 2
+ remote-addr addr-msc2
+msc 3
+ remote-addr addr-msc4
+sgsn 0
+ remote-addr addr-sgsn0
+sgsn 1
+sgsn 2
+ remote-addr addr-sgsn4
+sgsn 3
+ remote-addr addr-sgsn3
+...
+
+
+OsmoHNBGW(config-hnbgw)# ### placement of the new 'msc' and 'sgsn' nodes
must be below 'pfcp' and 'mgw' nodes
+OsmoHNBGW(config-hnbgw)# show running-config
+...
+hnbgw
+... !msc
+ iuh
+... !msc
+ mgw 0
+...
+msc 0
+...
diff --git a/tests/config/one_cs7_with_addrs.vty b/tests/config/one_cs7_with_addrs.vty
index 2975ade..4df44a5 100644
--- a/tests/config/one_cs7_with_addrs.vty
+++ b/tests/config/one_cs7_with_addrs.vty
@@ -39,8 +39,9 @@
rnc-id 23
log-prefix hnb-id
iuh
- iucs
- remote-addr my-msc
- iups
- remote-addr my-sgsn
+...
+msc 0
+ remote-addr my-msc
+sgsn 0
+ remote-addr my-sgsn
...
diff --git a/tests/config/one_cs7_with_iucs_addr.vty
b/tests/config/one_cs7_with_iucs_addr.vty
index 7fc4ed1..f9ee384 100644
--- a/tests/config/one_cs7_with_iucs_addr.vty
+++ b/tests/config/one_cs7_with_iucs_addr.vty
@@ -32,6 +32,8 @@
rnc-id 23
log-prefix hnb-id
iuh
- iucs
- remote-addr my-msc
...
+msc 0
+ remote-addr my-msc
+sgsn 0
+... !remote-addr
diff --git a/tests/config/one_cs7_with_iups_addr.vty
b/tests/config/one_cs7_with_iups_addr.vty
index bd5f261..7d66615 100644
--- a/tests/config/one_cs7_with_iups_addr.vty
+++ b/tests/config/one_cs7_with_iups_addr.vty
@@ -32,6 +32,8 @@
rnc-id 23
log-prefix hnb-id
iuh
- iups
- remote-addr my-sgsn
+...
+msc 0
+sgsn 0
+ remote-addr my-sgsn
...
diff --git a/tests/config/two_cs7_with_addrs.vty b/tests/config/two_cs7_with_addrs.vty
index 59240d1..0fb4b76 100644
--- a/tests/config/two_cs7_with_addrs.vty
+++ b/tests/config/two_cs7_with_addrs.vty
@@ -50,8 +50,9 @@
rnc-id 23
log-prefix hnb-id
iuh
- iucs
- remote-addr my-msc
- iups
- remote-addr my-sgsn
+...
+msc 0
+ remote-addr my-msc
+sgsn 0
+ remote-addr my-sgsn
...
--
To view, visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/32324
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: I5479eded786ec26062d49403a8be12967f113cdb
Gerrit-Change-Number: 32324
Gerrit-PatchSet: 5
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged