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 <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>

Reply via email to