pespin submitted this change.

View Change

Approvals: laforge: Looks good to me, but someone else must approve osmith: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified
Move cnlink funcs from hnbgw_cn.c to cnlink.c

This way we finally end up with hnbgw_cnpool related funcionalities in
hnbgw_cn.c, and cnlink related ones in cnlink.c.

Change-Id: Ic9a962877ea000aa1bca6c2c282baac6e53f6489
---
M include/osmocom/hnbgw/cnlink.h
M include/osmocom/hnbgw/hnbgw_cn.h
M src/osmo-hnbgw/cnlink.c
M src/osmo-hnbgw/hnbgw_cn.c
4 files changed, 172 insertions(+), 171 deletions(-)

diff --git a/include/osmocom/hnbgw/cnlink.h b/include/osmocom/hnbgw/cnlink.h
index 3ede801..c4e494d 100644
--- a/include/osmocom/hnbgw/cnlink.h
+++ b/include/osmocom/hnbgw/cnlink.h
@@ -98,6 +98,10 @@
int hnbgw_cnlink_tx_ranap_reset(struct hnbgw_cnlink *cnlink);
int hnbgw_cnlink_tx_ranap_reset_ack(struct hnbgw_cnlink *cnlink);

+int hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink);
+
+char *hnbgw_cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr);
+
static inline struct osmo_sccp_instance *hnbgw_cnlink_sccp(const struct hnbgw_cnlink *cnlink)
{
if (!cnlink)
diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h
index 1a5288a..8e765c8 100644
--- a/include/osmocom/hnbgw/hnbgw_cn.h
+++ b/include/osmocom/hnbgw/hnbgw_cn.h
@@ -61,6 +61,3 @@
void hnbgw_cnpool_cnlinks_start_or_restart(struct hnbgw_cnpool *cnpool);
struct hnbgw_cnlink *cnlink_get_nr(struct hnbgw_cnpool *cnpool, int nr, bool create_if_missing);
void hnbgw_cnpool_apply_cfg(struct hnbgw_cnpool *cnpool);
-
-int hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink);
-char *hnbgw_cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr);
diff --git a/src/osmo-hnbgw/cnlink.c b/src/osmo-hnbgw/cnlink.c
index d02d45b..2ba748c 100644
--- a/src/osmo-hnbgw/cnlink.c
+++ b/src/osmo-hnbgw/cnlink.c
@@ -347,3 +347,171 @@
CNLINK_CTR_INC(cnlink, CNLINK_CTR_RANAP_TX_UDT_RESET_ACK);
return hnbgw_cnlink_tx_sccp_unitdata_req(cnlink, msg);
}
+
+static bool addr_has_pc_and_ssn(const struct osmo_sccp_addr *addr)
+{
+ if (!(addr->presence & OSMO_SCCP_ADDR_T_SSN))
+ return false;
+ if (!(addr->presence & OSMO_SCCP_ADDR_T_PC))
+ return false;
+ return true;
+}
+
+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) {
+ 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;
+ }
+
+ *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;
+}
+
+char *hnbgw_cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr)
+{
+ struct osmo_sccp_instance *sccp = hnbgw_cnlink_sccp(cnlink);
+ if (!sccp)
+ return osmo_sccp_addr_dump(addr);
+ return osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, addr);
+}
+
+static void hnbgw_cnlink_cfg_copy(struct hnbgw_cnlink *cnlink)
+{
+ struct osmo_nri_range *r;
+
+ osmo_talloc_replace_string(cnlink, &cnlink->use.remote_addr_name, cnlink->vty.remote_addr_name);
+
+ osmo_nri_ranges_free(cnlink->use.nri_ranges);
+ cnlink->use.nri_ranges = osmo_nri_ranges_alloc(cnlink);
+ llist_for_each_entry(r, &cnlink->vty.nri_ranges->entries, entry)
+ osmo_nri_ranges_add(cnlink->use.nri_ranges, r);
+}
+
+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_log_self(struct hnbgw_cnlink *cnlink)
+{
+ struct osmo_ss7_instance *ss7 = cnlink->hnbgw_sccp_user->ss7;
+ LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "using: cs7-%u %s <-> %s %s %s\n",
+ osmo_ss7_instance_get_id(ss7),
+ /* printing the entire SCCP address is quite long, rather just print the point-code */
+ osmo_ss7_pointcode_print(ss7, cnlink->hnbgw_sccp_user->local_addr.pc),
+ osmo_ss7_pointcode_print2(ss7, cnlink->remote_addr.pc),
+ cnlink->name, cnlink->use.remote_addr_name ? : "(default remote point-code)");
+}
+
+/* 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 hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink)
+{
+ struct osmo_ss7_instance *ss7 = NULL;
+ struct hnbgw_sccp_user *hsu;
+
+ /* 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 {
+ 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");
+ }
+
+ /* 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,
+ DEFAULT_PC_HNBGW)) {
+ 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;
+ }
+ /* 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));
+ }
+
+ /* 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);
+ 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 f90b945..f881dc1 100644
--- a/src/osmo-hnbgw/hnbgw_cn.c
+++ b/src/osmo-hnbgw/hnbgw_cn.c
@@ -42,47 +42,6 @@
#include <osmocom/hnbgw/hnbgw_cn.h>
#include <osmocom/hnbgw/context_map.h>

-static bool addr_has_pc_and_ssn(const struct osmo_sccp_addr *addr)
-{
- if (!(addr->presence & OSMO_SCCP_ADDR_T_SSN))
- return false;
- if (!(addr->presence & OSMO_SCCP_ADDR_T_PC))
- return false;
- return true;
-}
-
-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) {
- 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;
- }
-
- *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;
-}
-
void hnbgw_cnpool_apply_cfg(struct hnbgw_cnpool *cnpool)
{
struct osmo_nri_range *r;
@@ -95,125 +54,6 @@
osmo_nri_ranges_add(cnpool->use.null_nri_ranges, r);
}

-static void hnbgw_cnlink_cfg_copy(struct hnbgw_cnlink *cnlink)
-{
- struct osmo_nri_range *r;
-
- osmo_talloc_replace_string(cnlink, &cnlink->use.remote_addr_name, cnlink->vty.remote_addr_name);
-
- osmo_nri_ranges_free(cnlink->use.nri_ranges);
- cnlink->use.nri_ranges = osmo_nri_ranges_alloc(cnlink);
- llist_for_each_entry(r, &cnlink->vty.nri_ranges->entries, entry)
- osmo_nri_ranges_add(cnlink->use.nri_ranges, r);
-}
-
-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_log_self(struct hnbgw_cnlink *cnlink)
-{
- struct osmo_ss7_instance *ss7 = cnlink->hnbgw_sccp_user->ss7;
- LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "using: cs7-%u %s <-> %s %s %s\n",
- osmo_ss7_instance_get_id(ss7),
- /* printing the entire SCCP address is quite long, rather just print the point-code */
- osmo_ss7_pointcode_print(ss7, cnlink->hnbgw_sccp_user->local_addr.pc),
- osmo_ss7_pointcode_print2(ss7, cnlink->remote_addr.pc),
- cnlink->name, cnlink->use.remote_addr_name ? : "(default remote point-code)");
-}
-
-/* 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 hnbgw_cnlink_start_or_restart(struct hnbgw_cnlink *cnlink)
-{
- struct osmo_ss7_instance *ss7 = NULL;
- struct hnbgw_sccp_user *hsu;
-
- /* 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 {
- 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");
- }
-
- /* 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,
- DEFAULT_PC_HNBGW)) {
- 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;
- }
- /* 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));
- }
-
- /* 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);
- hnbgw_sccp_user_get(cnlink->hnbgw_sccp_user, HSU_USE_CNLINK);
- hnbgw_cnlink_log_self(cnlink);
- return 0;
-}
-
void hnbgw_cnpool_cnlinks_start_or_restart(struct hnbgw_cnpool *cnpool)
{
struct hnbgw_cnlink *cnlink;
@@ -410,14 +250,6 @@
#undef LOG_NRI
}

-char *hnbgw_cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr)
-{
- struct osmo_sccp_instance *sccp = hnbgw_cnlink_sccp(cnlink);
- if (!sccp)
- return osmo_sccp_addr_dump(addr);
- return osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, addr);
-}
-
static const struct rate_ctr_desc cnpool_ctr_description[] = {
[CNPOOL_CTR_SUBSCR_NO_CNLINK] = {
"cnpool:subscr:no_cnlink",

To view, visit change 40266. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: Ic9a962877ea000aa1bca6c2c282baac6e53f6489
Gerrit-Change-Number: 40266
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: osmith <osmith@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>