[MERGED] 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/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Sat Jul 22 09:08:14 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: sccp: make simple client configurable via VTY
......................................................................


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. The relation to
the VTY is implicit. The user may set up instance objects via
VTY (cs7/ss7, AS, ASP), which are then automatically created on
startup.

Each cs7 instance gets its own ID via the VTY configuration. When
osmo_sccp_simple_client_on_ss7_id() is called with the cs7 instance
id. (for osmo_sccp_simple_client() the ID will be hardcoded to 1),
the function automatically checks if the CS7 instance is present,
if not it will create one automatically using the caller supplied
parameters as a defult. If a CS7 instance is present, the function
checks for the presence of an AS and an ASP. These objects are
present, they will be used. If not, new objects will be created.

Both functions must not be called if an SCCP instance is already
present. Since there can only be one SCCP instance per CS7 instance,
this is an error condition.

Add additional logic that checks to detect an already existing, valid
configuration. If no or an insufficient configuration is detected,
use the caller supplied parameters as default 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(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



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: merged
Gerrit-Change-Id: I293f3526ce6182dca74a169a23449dbc7af57c7c
Gerrit-PatchSet: 4
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list