[PATCH] libosmo-sccp[master]: sccp: make simple client configurable via VTY

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

dexter gerrit-no-reply at lists.osmocom.org
Fri Jul 21 11:35:28 UTC 2017


Hello Neels Hofmeyr, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/3303

to look at the new patch set (#2).

sccp: make simple client configurable via VTY

The osmo_sccp_simple_client_on_ss7_id and osmo_sccp_simple_client
are not entirely configurable via VTY commands.

Add additional logic that checks for a still existing, valid
configuration. If no or an insufficient configuration is detected,
assume use the caller supplied parameters as standard configuration.

Change-Id: I293f3526ce6182dca74a169a23449dbc7af57c7c
---
M include/osmocom/sigtran/osmo_ss7.h
M src/osmo_ss7.c
M src/sccp_user.c
3 files changed, 153 insertions(+), 35 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/03/3303/2

diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 57a4e06..87ace4a 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -307,6 +307,8 @@
 osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx);
 struct osmo_ss7_as *
 osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id);
+struct osmo_ss7_as *osmo_ss7_as_find_by_proto(struct osmo_ss7_instance *inst,
+					      enum osmo_ss7_asp_protocol proto);
 struct osmo_ss7_as *
 osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name,
 			  enum osmo_ss7_asp_protocol proto);
@@ -383,6 +385,9 @@
 
 struct osmo_ss7_asp *
 osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name);
+struct osmo_ss7_asp
+*osmo_ss7_asp_find_by_proto(struct osmo_ss7_as *as,
+			    enum osmo_ss7_asp_protocol proto);
 struct osmo_ss7_asp *
 osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name,
 			    uint16_t remote_port, uint16_t local_port,
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index c13c588..eb5a4ef 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -833,6 +833,41 @@
 	return NULL;
 }
 
+/*! \brief Find Application Server (AS) by given protocol.
+ *  \param[in] inst SS7 Instance on which we operate
+ *  \param[in] proto Protocol identifier that must match
+ *  \returns pointer to AS on success; NULL otherwise
+ *  If an AS has an ASP also matching the given protocol, that AS is preferred.
+ *  If there are multiple matches, return the first matching AS. */
+struct osmo_ss7_as *osmo_ss7_as_find_by_proto(struct osmo_ss7_instance *inst,
+					      enum osmo_ss7_asp_protocol proto)
+{
+	struct osmo_ss7_as *as;
+	struct osmo_ss7_as *as_without_asp = NULL;
+
+	OSMO_ASSERT(ss7_initialized);
+
+	/* Loop through the list with AS and try to find one where the proto
+	   matches up */
+	llist_for_each_entry(as, &inst->as_list, list) {
+		if (as->cfg.proto == proto) {
+
+			/* Put down the first AS that matches the proto, just in
+			 * case we will not find any matching ASP */
+			if (!as_without_asp)
+				as_without_asp = as;
+
+			/* Check if the candicate we have here has any suitable
+			 * ASP */
+			if (osmo_ss7_asp_find_by_proto(as, proto))
+				return as;
+		}
+	}
+
+	/* Return with the second best find, if there is any */
+	return as_without_asp;
+}
+
 /*! \brief Find or Create Application Server
  *  \param[in] inst SS7 Instance on which we operate
  *  \param[in] name Name of Application Server
@@ -1044,6 +1079,23 @@
 	return NULL;
 }
 
+/*! \brief Find an ASP that matches the given protocol.
+ *  \param[in] as Application Server in which to look for \ref asp
+ *  \returns SS7 ASP in case a matching one is found; NULL otherwise */
+struct osmo_ss7_asp
+*osmo_ss7_asp_find_by_proto(struct osmo_ss7_as *as,
+			    enum osmo_ss7_asp_protocol proto)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
+		if (as->cfg.asps[i] && as->cfg.asps[i]->cfg.proto == proto)
+			return as->cfg.asps[i];
+	}
+
+	return NULL;
+}
+
 struct osmo_ss7_asp *
 osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name,
 			    uint16_t remote_port, uint16_t local_port,
diff --git a/src/sccp_user.c b/src/sccp_user.c
index b21a756..c9443a2 100644
--- a/src/sccp_user.c
+++ b/src/sccp_user.c
@@ -242,54 +242,113 @@
 				  int remote_port, const char *remote_ip)
 {
 	struct osmo_ss7_instance *ss7;
+	bool ss7_created = false;
 	struct osmo_ss7_as *as;
+	bool as_created = false;
 	struct osmo_ss7_route *rt;
+	bool rt_created = false;
 	struct osmo_ss7_asp *asp;
-	char *as_name, *asp_name;
+	bool asp_created = false;
+	char *as_name, *asp_name = NULL;
 
+	/* Choose default ports when the caller does not supply valid port
+	 * numbers. */
 	if (!remote_port || remote_port < 0)
 		remote_port = osmo_ss7_asp_protocol_port(prot);
 	if (local_port < 0)
 		local_port = osmo_ss7_asp_protocol_port(prot);
 
-	/* allocate + initialize SS7 instance */
-	ss7 = osmo_ss7_instance_find_or_create(ctx, ss7_id);
+	/* Check if there is already an ss7 instance present under
+	 * the given id. If not, we will create a new one. */
+	ss7 = osmo_ss7_instance_find(ss7_id);
 	if (!ss7) {
-		LOGP(DLSCCP, LOGL_ERROR, "Failed to find or create SS7 instance\n");
-		return NULL;
+		LOGP(DLSCCP, LOGL_NOTICE, "%s: Creating SS7 instance\n",
+		     name);
+
+		/* Create a new ss7 instance */
+		ss7 = osmo_ss7_instance_find_or_create(ctx, ss7_id);
+		if (!ss7) {
+			LOGP(DLSCCP, LOGL_ERROR,
+			     "Failed to find or create SS7 instance\n");
+			return NULL;
+		}
+
+		/* Setup primary pointcode
+		 * NOTE: This means that the user must set the pointcode to a
+		 * proper value when a cs7 instance is defined via the VTY. */
+		ss7->cfg.primary_pc = pc;
+		ss7_created = true;
 	}
-	ss7->cfg.primary_pc = pc;
+	LOGP(DLSCCP, LOGL_NOTICE, "%s: Using SS7 instance %u, pc:%s\n", name,
+	     ss7->cfg.id, osmo_ss7_pointcode_print(ss7, ss7->cfg.primary_pc));
 
-	as_name = talloc_asprintf(ctx, "as-clnt-%s", name);
-	asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name);
+	/* There must not be an existing SCCP istance, regarless if the simple
+	 * client has created the SS7 instance or if it was already present.
+	 * An already existing SCCP instance would be an indication that this
+	 * function has been called twice with the same SS7 instance, which
+	 * must not be the case! */
+	OSMO_ASSERT(ss7->sccp == NULL);
 
-	/* application server */
-	as = osmo_ss7_as_find_or_create(ss7, as_name, prot);
-	if (!as)
-		goto out_strings;
+	/* Check if there is already an application server that matches
+	 * the protocol we intend to use. If not, we will create one. */
+	as = osmo_ss7_as_find_by_proto(ss7, prot);
+	if (!as) {
+		LOGP(DLSCCP, LOGL_NOTICE, "%s: Creating AS instance\n",
+		     name);
+		as_name = talloc_asprintf(ctx, "as-clnt-%s", name);
+		as = osmo_ss7_as_find_or_create(ss7, as_name, prot);
+		talloc_free(as_name);
+		if (!as)
+			goto out_ss7;
+		as_created = true;
 
-	as->cfg.routing_key.pc = pc;
+		as->cfg.routing_key.pc = ss7->cfg.primary_pc;
 
-	/* install default route */
-	rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name);
-	if (!rt)
-		goto out_as;
-	talloc_free(as_name);
+		/* install default route */
+		rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0,
+					   as->cfg.name);
+		if (!rt)
+			goto out_as;
+		rt_created = true;
+	}
+	LOGP(DLSCCP, LOGL_NOTICE, "%s: Using AS instance %s\n", name,
+	     as->cfg.name);
 
-	/* application server process */
-	asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port,
-					  prot);
-	if (!asp)
-		goto out_rt;
-	asp->cfg.local.host = talloc_strdup(asp, local_ip);
-	asp->cfg.remote.host = talloc_strdup(asp, remote_ip);
-	osmo_ss7_as_add_asp(as, asp_name);
+	/* Check if we do already have an application server process
+	 * that is associated with the application server we have choosen
+	 * the application server process must also match the protocol
+	 * we intend to use. */
+	asp = osmo_ss7_asp_find_by_proto(as, prot);
+	if (!asp) {
+		LOGP(DLSCCP, LOGL_NOTICE, "%s: Creating ASP instance\n",
+		     name);
+		asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name);
+		asp =
+		    osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port,
+						local_port, prot);
+		talloc_free(asp_name);
+		if (!asp)
+			goto out_rt;
+		asp_created = true;
+
+		asp->cfg.local.host = talloc_strdup(asp, local_ip);
+		asp->cfg.remote.host = talloc_strdup(asp, remote_ip);
+
+		osmo_ss7_as_add_asp(as, asp->cfg.name);
+	}
+
+	/* Ensure that the ASP we use is set to client mode. */
+	asp->cfg.is_server = false;
+
+	/* Restart ASP */
 	if (prot != OSMO_SS7_ASP_PROT_IPA)
 		osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG);
-	talloc_free(asp_name);
 	osmo_ss7_asp_restart(asp);
+	LOGP(DLSCCP, LOGL_NOTICE, "%s: Using ASP instance %s\n", name,
+	     asp->cfg.name);
 
-	/* Allocate SCCP stack + SCCP user */
+	/* Allocate SCCP instance */
+	LOGP(DLSCCP, LOGL_NOTICE, "%s: Creating SCCP instance\n", name);
 	ss7->sccp = osmo_sccp_instance_create(ss7, NULL);
 	if (!ss7->sccp)
 		goto out_asp;
@@ -297,15 +356,17 @@
 	return ss7->sccp;
 
 out_asp:
-	osmo_ss7_asp_destroy(asp);
+	if (asp_created)
+		osmo_ss7_asp_destroy(asp);
 out_rt:
-	osmo_ss7_route_destroy(rt);
+	if (rt_created)
+		osmo_ss7_route_destroy(rt);
 out_as:
-	osmo_ss7_as_destroy(as);
-out_strings:
-	talloc_free(as_name);
-	talloc_free(asp_name);
-	osmo_ss7_instance_destroy(ss7);
+	if (as_created)
+		osmo_ss7_as_destroy(as);
+out_ss7:
+	if (ss7_created)
+		osmo_ss7_instance_destroy(ss7);
 
 	return NULL;
 }

-- 
To view, visit https://gerrit.osmocom.org/3303
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I293f3526ce6182dca74a169a23449dbc7af57c7c
Gerrit-PatchSet: 2
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list