[PATCH] libosmo-sccp[master]: xua_rkm: Make dynamic registration of Routing Keys work

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
Thu Apr 13 16:23:25 UTC 2017


Review at  https://gerrit.osmocom.org/2323

xua_rkm: Make dynamic registration of Routing Keys work

The existign xua_rkm code was merged a bit pre-maturely as it was not
properly tested.  This adds a lot of fixes to make it work at all in the
first place, as well as the configurable option for fully dynamic
routing key management, where ASs and routing keys must not be
configured statically by administrative means, but clients (ASPs) can
simply come and register for whatever point code they want.

Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278
---
M include/osmocom/sigtran/osmo_ss7.h
M src/xua_rkm.c
2 files changed, 100 insertions(+), 30 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/23/2323/1

diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index c3a81bb..49a8ca5 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -86,6 +86,7 @@
 		/* capability PCs */
 		uint8_t network_indicator;
 		struct osmo_ss7_pc_fmt pc_fmt;
+		bool permit_dyn_rkm_alloc;
 	} cfg;
 };
 
@@ -276,6 +277,9 @@
 	/*! AS FSM */
 	struct osmo_fsm_inst *fi;
 
+	/*! Were we dynamically allocated by RKM? */
+	bool rkm_dyn_allocated;
+
 	struct {
 		char *name;
 		char *description;
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index aa29866..38cbbda 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <string.h>
 #include <arpa/inet.h>
 
 #include <osmocom/core/logging.h>
@@ -26,6 +27,7 @@
 #include <osmocom/sigtran/protocol/m3ua.h>
 
 #include "xua_internal.h"
+#include "xua_as_fsm.h"
 
 const struct value_string m3ua_rkm_reg_status_vals[] = {
 	{ M3UA_RKM_REG_SUCCESS,			"SUCCESS" },
@@ -137,11 +139,15 @@
 	osmo_ss7_asp_send(asp, msg);
 }
 
+/* maximum number of newly-assigned Application Servers in one dynamic
+ * RKM REG request */
+#define MAX_NEW_AS 16
 
 /* SG: handle a single registration request IE (nested IEs in 'innner' */
 static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner,
-			   struct msgb *resp)
+			   struct msgb *resp, struct osmo_ss7_as **newly_assigned_as)
 {
+	unsigned int nas_idx = 0;
 	uint32_t rk_id, rctx, _tmode, dpc;
 	enum osmo_ss7_as_traffic_mode tmode;
 	struct osmo_ss7_as *as;
@@ -188,35 +194,67 @@
 	LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: Registering routing key %u for DPC %s\n",
 		rctx, osmo_ss7_pointcode_print(asp->inst, dpc));
 
+	/* We have two cases here:
+	 * a) pre-configured routing context on both ASP and SG: We will
+	 *    find the AS based on the RCTX send by the client, check if
+	 *    the routing key matches, associated AS with ASP and return
+	 *    success.
+	 * b) no routing context set on ASP, no pre-existing AS
+	 *    definition on SG.  We have to create the AS, set the RK,
+	 *    allocate the RCTX and return that RCTX to the client. This
+	 *    is a slightly non-standard interpretation of M3UA RKM
+	 *    which requires the SG to not have a-priori-knowledge of
+	 *    all AS/RK in situations where the ASP are trusted.
+	 */ 
+
 	/* check if there is already an AS for this routing key */
-	if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) {
-		LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: RCTX %u already in use\n", rctx);
-		msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0);
-		return -1;
-	}
+	as = osmo_ss7_as_find_by_rctx(asp->inst, rctx);
+	if (as) {
+		LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Found existing AS for RCTX %u\n", rctx);
+		if (as->cfg.routing_key.pc != dpc) {
+			LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: DPC doesn't match (%u != %u)\n",
+				as->cfg.routing_key.pc, dpc);
+			msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INVAL_RKEY, 0);
+			return -1;
+		}
+	} else if (asp->inst->cfg.permit_dyn_rkm_alloc) {
+		/* Create an AS for this routing key */
+		snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx);
+		as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA);
+		if (!as) {
+			LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf);
+			msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0);
+			return -1;
+		}
 
-	/* Create an AS for this routing key */
-	snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx);
-	as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA);
-	if (!as) {
-		LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf);
-		msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0);
-		return -1;
-	}
+		as->cfg.description = talloc_strdup(as, "Auto-generated by RKM");
+		as->rkm_dyn_allocated = true;
+		as->cfg.mode = tmode;
+		/* fill routing key */
+		as->cfg.routing_key.pc = dpc;
+		as->cfg.routing_key.context = rctx;
 
-	as->cfg.description = talloc_strdup(as, "Auto-generated by RKM");
-	as->cfg.mode = tmode;
-	/* fill routing key */
-	as->cfg.routing_key.context = rctx;
-	as->cfg.routing_key.pc = dpc;
+		/* add route for that routing key */
+		rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf);
+		if (!rt) {
+			LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n",
+				osmo_ss7_pointcode_print(asp->inst, dpc), namebuf);
+			osmo_ss7_as_destroy(as);
+			msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0);
+			return -1;
+		}
 
-	/* add route for that routing key */
-	rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf);
-	if (!rt) {
-		LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n",
-			osmo_ss7_pointcode_print(asp->inst, dpc), namebuf);
-		osmo_ss7_as_destroy(as);
-		msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0);
+		/* append to list of newly assigned as */
+		if (nas_idx >= MAX_NEW_AS) {
+			osmo_ss7_route_destroy(rt);
+			osmo_ss7_as_destroy(as);
+			msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0);
+			return -1;
+		}
+		newly_assigned_as[nas_idx++] = as;
+	} else {
+		/* not permitted to create dynamic RKM entries */
+		msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_PERM_DENIED, 0);
 		return -1;
 	}
 
@@ -231,6 +269,10 @@
 {
 	struct xua_msg_part *part;
 	struct msgb *resp = m3ua_msgb_alloc(__func__);
+	struct osmo_ss7_as *newly_assigned_as[MAX_NEW_AS];
+	unsigned int i;
+
+	memset(newly_assigned_as, 0, sizeof(newly_assigned_as));
 
 	/* iterate over all routing key IEs in message */
 	llist_for_each_entry(part, &xua->headers, entry) {
@@ -247,10 +289,24 @@
 		}
 		/* handle single registration and append result to
 		 * 'resp' */
-		handle_rkey_reg(asp, inner, resp);
+		handle_rkey_reg(asp, inner, resp, newly_assigned_as);
+
+		xua_msg_free(inner);
 	}
+	/* now first send the RKM REG Response */
 	msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP);
 	osmo_ss7_asp_send(asp, resp);
+
+	/* and *after* the RKM REG Response inform the newly assigned
+	 * ASs about the fact that there's an INACTIVE ASP for them,
+	 * which will cause them to send NOTIFY to the client */
+	for (i = 0; i < ARRAY_SIZE(newly_assigned_as); i++) {
+		struct osmo_ss7_as *as = newly_assigned_as[i];
+		if (!as)
+			continue;
+		/* Notify AS that it has an INACTIVE ASP */
+		osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, asp);
+	}
 
 	return 0;
 }
@@ -286,9 +342,19 @@
 	LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n",
 		rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc));
 
-	/* remove route + AS definition */
-	osmo_ss7_route_destroy(rt);
-	osmo_ss7_as_destroy(as);
+	/* remove ASP from AS */
+	osmo_ss7_as_del_asp(as, asp->cfg.name);
+	/* FIXME: Rather than spoofing teh ASP-DOWN.ind to the AS here,
+	 * we should refuse RKM DEREG if the ASP is still ACTIVE */
+	osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_DOWN_IND, asp);
+
+	/* if we were dynamically allocated, release the associated
+	 * route and destroy the AS */
+	if (as->rkm_dyn_allocated) {
+		/* remove route + AS definition */
+		osmo_ss7_route_destroy(rt);
+		osmo_ss7_as_destroy(as);
+	}
 	/* report success */
 	msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx);
 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278
Gerrit-PatchSet: 1
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>



More information about the gerrit-log mailing list