laforge has submitted this change. (
https://gerrit.osmocom.org/c/osmo-hnbgw/+/40627?usp=email )
Change subject: Make sure MSC/SGSN PC are added to sccp-addressbook
......................................................................
Make sure MSC/SGSN PC are added to sccp-addressbook
This way they can used by libosmo-sigtran to figure out interesting
remote PCs it should track availability for.
Related: OS#5917
Related: SYS#7501
Depends: libosmo-sigtran.git Change-Id I9d2452d9cc8e443050927a047b7ebacd2b2f37e1
Change-Id: I6a537adca27dd2bbad33d0f2be71eb41d6ad3a27
---
M TODO-RELEASE
M include/osmocom/hnbgw/hnbgw.h
M include/osmocom/hnbgw/hnbgw_cn.h
M src/osmo-hnbgw/cnlink.c
M src/osmo-hnbgw/hnbgw_cn.c
M tests/cnpool.vty
6 files changed, 131 insertions(+), 77 deletions(-)
Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
osmith: Looks good to me, but someone else must approve
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 0ed7189..895cb3c 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
+libosmo-sigtran >2.1.0 osmo_sccp_addr_{create,update}()
diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h
index 685bc12..f4ec21c 100644
--- a/include/osmocom/hnbgw/hnbgw.h
+++ b/include/osmocom/hnbgw/hnbgw.h
@@ -56,6 +56,8 @@
#define DEFAULT_PC_HNBGW ((23 << 3) + 5)
#define DEFAULT_PC_MSC ((23 << 3) + 1)
#define DEFAULT_PC_SGSN ((23 << 3) + 4)
+#define DEFAULT_ADDR_NAME_MSC "addr-dyn-msc-default"
+#define DEFAULT_ADDR_NAME_SGSN "addr-dyn-sgsn-default"
/* 25.467 Section 7.1 */
#define IUH_DEFAULT_SCTP_PORT 29169
diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h
index 8e765c8..68a0ac5 100644
--- a/include/osmocom/hnbgw/hnbgw_cn.h
+++ b/include/osmocom/hnbgw/hnbgw_cn.h
@@ -37,6 +37,7 @@
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;
+ const char *default_addr_name;
struct hnbgw_cnpool_cfg vty;
struct hnbgw_cnpool_cfg use;
diff --git a/src/osmo-hnbgw/cnlink.c b/src/osmo-hnbgw/cnlink.c
index ea53ee0..83ca51f 100644
--- a/src/osmo-hnbgw/cnlink.c
+++ b/src/osmo-hnbgw/cnlink.c
@@ -385,45 +385,22 @@
return hnbgw_cnlink_tx_sccp_unitdata_req(cnlink, msg);
}
-static bool addr_has_pc_and_ssn(const struct osmo_sccp_addr *addr)
+/* Return address found in sccp address-book, and fill in missing fields in the
+ * entry with default values. */
+static struct osmo_ss7_instance *sccp_addr_by_name_filled(struct osmo_sccp_addr *dest,
const char *addr_name, uint32_t default_pc)
{
- if (!(addr->presence & OSMO_SCCP_ADDR_T_SSN))
- return false;
- if (!(addr->presence & OSMO_SCCP_ADDR_T_PC))
- return false;
- return true;
-}
+ struct osmo_ss7_instance *s7i;
+ s7i = osmo_sccp_addr_by_name(dest, addr_name);
+ if (!s7i)
+ return NULL;
-static int resolve_addr_name(struct osmo_sccp_addr *dest, struct osmo_ss7_instance
**ss7,
- const char *addr_name, const char *label,
- uint32_t default_pc)
-{
- if (!addr_name) {
+ /* Address exists in address-book but may not be filled entirely: */
+ if (!dest->presence)
osmo_sccp_make_addr_pc_ssn(dest, default_pc, OSMO_SCCP_SSN_RANAP);
- if (label)
- LOGP(DCN, LOGL_INFO, "%s remote addr not configured, using default: %s\n",
label,
- osmo_sccp_addr_name(*ss7, dest));
- return 0;
- }
+ else if (!(dest->presence & OSMO_SCCP_ADDR_T_SSN))
+ osmo_sccp_addr_set_ssn(dest, OSMO_SCCP_SSN_RANAP);
- *ss7 = osmo_sccp_addr_by_name(dest, addr_name);
- if (!*ss7) {
- if (label)
- LOGP(DCN, 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)) {
- if (label)
- LOGP(DCN, LOGL_ERROR, "Invalid/incomplete %s remote-addr: %s\n",
- label, osmo_sccp_addr_name(*ss7, dest));
- return -1;
- }
-
- return 0;
+ return s7i;
}
char *hnbgw_cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct
osmo_sccp_addr *addr)
@@ -451,13 +428,17 @@
bool changed = false;
if (cnlink->vty.remote_addr_name && cnlink->use.remote_addr_name) {
- struct osmo_ss7_instance *ss7;
+ struct osmo_ss7_instance *s7i;
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,
cnlink->pool->default_remote_pc);
- if (osmo_sccp_addr_cmp(&remote_addr, &cnlink->remote_addr,
OSMO_SCCP_ADDR_T_PC | OSMO_SCCP_ADDR_T_SSN))
+ s7i = sccp_addr_by_name_filled(&remote_addr, cnlink->vty.remote_addr_name,
+ cnlink->pool->default_remote_pc);
+ if (!s7i)
+ return true;
+ 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. */
@@ -465,7 +446,6 @@
}
/* if more cnlink configuration is added in the future, it needs to be compared here.
*/
-
return changed;
}
@@ -485,19 +465,20 @@
* Set cnlink->hnbgw_sccp_user to the new SCCP instance. Return 0 on success, negative
on error. */
int hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink)
{
- struct osmo_ss7_instance *ss7 = NULL;
+ struct osmo_ss7_instance *s7i = NULL;
struct hnbgw_sccp_user *hsu;
+ uint32_t ss7_id;
+ int rc;
/* If a hnbgw_sccp_user has already been set up, use that. */
if (cnlink->hnbgw_sccp_user) {
- if (hnbgw_cnlink_sccp_cfg_changed(cnlink)) {
- LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "config changed, restarting SCCP\n");
- hnbgw_cnlink_drop_sccp(cnlink);
- } else {
+ if (!hnbgw_cnlink_sccp_cfg_changed(cnlink)) {
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "SCCP instance already set up, using
%s\n",
cnlink->hnbgw_sccp_user->name);
return 0;
}
+ LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "config changed, restarting SCCP\n");
+ hnbgw_cnlink_drop_sccp(cnlink);
} else {
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "no SCCP instance selected yet\n");
}
@@ -505,49 +486,64 @@
/* 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->use.remote_addr_name) {
- if (resolve_addr_name(&cnlink->remote_addr, &ss7,
cnlink->use.remote_addr_name, cnlink->name,
- cnlink->pool->default_remote_pc)) {
+ if (!cnlink->use.remote_addr_name) {
+ /* No remote address configured in VTY, set a default one and
+ * make sure it becomes registered in the sccp address-book: */
+ cnlink->use.remote_addr_name = talloc_strdup(cnlink,
cnlink->pool->default_addr_name);
+ s7i = osmo_sccp_addr_by_name(&cnlink->remote_addr,
cnlink->use.remote_addr_name);
+ if (!s7i) {
+ LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "To auto-configure cnlink, creating cs7
instance 0 implicitly\n");
+ s7i = osmo_ss7_instance_find_or_create(g_hnbgw, 0);
+ OSMO_ASSERT(s7i);
+ osmo_sccp_make_addr_pc_ssn(&cnlink->remote_addr,
+ cnlink->pool->default_remote_pc,
+ OSMO_SCCP_SSN_RANAP);
+ rc = osmo_sccp_addr_create(s7i, cnlink->use.remote_addr_name,
&cnlink->remote_addr);
+ if (rc < 0) {
+ LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Failed adding address '%s' to sccp
address-book!\n",
+ cnlink->use.remote_addr_name);
+ return -EINVAL;
+ }
+ }
+ /* Update VTY config to show & point to the address dynamically added to
address-book: */
+ cnlink->vty.remote_addr_name = talloc_strdup(cnlink,
cnlink->use.remote_addr_name);
+ } else {
+ s7i = sccp_addr_by_name_filled(&cnlink->remote_addr,
cnlink->use.remote_addr_name, cnlink->pool->default_remote_pc);
+ if (!s7i) {
LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "cannot initialize SCCP: there is no SCCP
address named '%s'\n",
cnlink->use.remote_addr_name);
return -ENOENT;
}
-
LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "remote-addr is '%s', using cs7
instance %u\n",
- cnlink->use.remote_addr_name, osmo_ss7_instance_get_id(ss7));
- } else {
- /* If no address is configured, use the default remote CN address, according to legacy
behavior. */
- 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.
- * If it doesn't exist, it will get created by osmo_sccp_simple_client_on_ss7_id().
*/
- if (!ss7) {
- ss7 = osmo_ss7_instance_find(0);
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "Using default 'cs7 instance 0'
(%s)\n", ss7 ? "already exists" : "will create");
- }
-
- if (ss7) {
- /* Has another cnlink already set up an SCCP instance for this ss7? */
- llist_for_each_entry(hsu, &g_hnbgw->sccp.users, entry) {
- if (hsu->ss7 != ss7)
- continue;
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "using existing SCCP instance %s on cs7
instance %u\n",
- hsu->name, osmo_ss7_instance_get_id(ss7));
- cnlink->hnbgw_sccp_user = hsu;
- hnbgw_sccp_user_get(cnlink->hnbgw_sccp_user, HSU_USE_CNLINK);
- hnbgw_cnlink_log_self(cnlink);
- return 0;
+ cnlink->use.remote_addr_name, osmo_ss7_instance_get_id(s7i));
+ /* Address exists in address-book but may not be filled entirely: */
+ rc = osmo_sccp_addr_update(s7i, cnlink->use.remote_addr_name,
&cnlink->remote_addr);
+ if (rc < 0) {
+ LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Failed updating address '%s' in sccp
address-book!\n",
+ cnlink->use.remote_addr_name);
+ return -EINVAL;
}
- /* else cnlink->hnbgw_sccp_user stays NULL and is set up below. */
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "cs7 instance %u has no configured SCCP
instance yet\n", osmo_ss7_instance_get_id(ss7));
}
+ ss7_id = osmo_ss7_instance_get_id(s7i);
+
+ /* Has another cnlink already set up an SCCP instance for this s7i? */
+ llist_for_each_entry(hsu, &g_hnbgw->sccp.users, entry) {
+ if (hsu->ss7 != s7i)
+ continue;
+ LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "using existing SCCP instance %s on cs7
instance %u\n",
+ hsu->name, ss7_id);
+ cnlink->hnbgw_sccp_user = hsu;
+ hnbgw_sccp_user_get(cnlink->hnbgw_sccp_user, HSU_USE_CNLINK);
+ hnbgw_cnlink_log_self(cnlink);
+ return 0;
+ }
+ /* else cnlink->hnbgw_sccp_user stays NULL and is set up below. */
+ LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "cs7 instance %u has no configured SCCP
instance yet\n", ss7_id);
+
/* No SCCP instance yet for this ss7. Create it. If no address name is given that
resolves to a
* particular cs7 instance above, use 'cs7 instance 0'. */
- cnlink->hnbgw_sccp_user = hnbgw_sccp_user_alloc(ss7 ? osmo_ss7_instance_get_id(ss7) :
0);
+ cnlink->hnbgw_sccp_user = hnbgw_sccp_user_alloc(ss7_id);
hnbgw_sccp_user_get(cnlink->hnbgw_sccp_user, HSU_USE_CNLINK);
hnbgw_cnlink_log_self(cnlink);
return 0;
diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c
index f881dc1..ab800f7 100644
--- a/src/osmo-hnbgw/hnbgw_cn.c
+++ b/src/osmo-hnbgw/hnbgw_cn.c
@@ -312,12 +312,14 @@
cnpool->pool_name = "iucs";
cnpool->peer_name = "msc";
cnpool->default_remote_pc = DEFAULT_PC_MSC;
+ cnpool->default_addr_name = DEFAULT_ADDR_NAME_MSC;
cnpool->ctrs = rate_ctr_group_alloc(cnpool, &iucs_ctrg_desc, 0);
break;
case DOMAIN_PS:
cnpool->pool_name = "iups";
cnpool->peer_name = "sgsn";
cnpool->default_remote_pc = DEFAULT_PC_SGSN;
+ cnpool->default_addr_name = DEFAULT_ADDR_NAME_SGSN;
cnpool->ctrs = rate_ctr_group_alloc(cnpool, &iups_ctrg_desc, 0);
break;
default:
diff --git a/tests/cnpool.vty b/tests/cnpool.vty
index 78f660f..83d7352 100644
--- a/tests/cnpool.vty
+++ b/tests/cnpool.vty
@@ -134,10 +134,23 @@
OsmoHNBGW(config)# ### The config file has no 'msc' or 'sgsn', so
defaults have been set up
OsmoHNBGW(config)# show running-config
...
+cs7 instance 0
+ point-code 0.23.5
+...
+ sccp-address addr-dyn-msc-default
+ routing-indicator PC
+ point-code 0.23.1
+ subsystem-number 142
+ sccp-address addr-dyn-sgsn-default
+ routing-indicator PC
+ point-code 0.23.4
+...
msc 0
name msc-0
+ remote-addr addr-dyn-msc-default
sgsn 0
name sgsn-0
+ remote-addr addr-dyn-sgsn-default
...
OsmoHNBGW(config)# msc 1
@@ -227,10 +240,12 @@
...
msc 0
name msc-0
+ remote-addr addr-dyn-msc-default
msc 1
name msc-1
sgsn 0
name sgsn-0
+ remote-addr addr-dyn-sgsn-default
sgsn 1
name sgsn-1
...
@@ -259,6 +274,7 @@
...
msc 0
name msc-0
+ remote-addr addr-dyn-msc-default
msc 1
name msc-1
msc 2
@@ -271,6 +287,7 @@
allow-emergency
sgsn 0
name sgsn-0
+ remote-addr addr-dyn-sgsn-default
sgsn 1
name sgsn-1
sgsn 2
@@ -297,6 +314,7 @@
...
msc 0
name msc-0
+ remote-addr addr-dyn-msc-default
msc 1
name msc-1
msc 2
@@ -307,6 +325,7 @@
remote-addr addr-msc4
sgsn 0
name sgsn-0
+ remote-addr addr-dyn-sgsn-default
sgsn 1
name sgsn-1
sgsn 2
@@ -378,3 +397,36 @@
...
msc 0
...
+
+OsmoHNBGW(config-hnbgw)# exit
+OsmoHNBGW(config)# ### Apply all SCCP changes:
+OsmoHNBGW(config)# apply sccp
+OsmoHNBGW(config)# show running-config
+...
+hnbgw
+...
+msc 0
+ name msc-0
+ remote-addr addr-msc0
+msc 1
+ name msc-1
+ remote-addr addr-dyn-msc-default
+msc 2
+ name msc-2
+ remote-addr addr-msc2
+msc 3
+ name msc-3
+ remote-addr addr-msc4
+sgsn 0
+ name sgsn-0
+ remote-addr addr-sgsn0
+sgsn 1
+ name sgsn-1
+ remote-addr addr-dyn-sgsn-default
+sgsn 2
+ name sgsn-2
+ remote-addr addr-sgsn4
+sgsn 3
+ name sgsn-3
+ remote-addr addr-sgsn3
+...
--
To view, visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/40627?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: I6a537adca27dd2bbad33d0f2be71eb41d6ad3a27
Gerrit-Change-Number: 40627
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>