Change in libosmocore[master]: gprs_ns2: introduce NS dialects

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/.

lynxis lazus gerrit-no-reply at lists.osmocom.org
Tue Dec 15 11:46:45 UTC 2020


lynxis lazus has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/21484 )

Change subject: gprs_ns2: introduce NS dialects
......................................................................

gprs_ns2: introduce NS dialects

A NS dialect describes how the NS Entity interacts with
different virtual circuits. E.g. ipaccess use reset/block on udp
and is a dynamic connection.
A single NS Entity can only support one dialect. This can be later
used to protect a NS Entity against dynamic NS virtual circuits of a
different type.

It further allows a bind to support multiple dialects at the same time.

Change-Id: Ia118bb6f994845d84db09de7a94856f5ca573404
---
M include/osmocom/gprs/gprs_ns2.h
M src/gb/gprs_ns2.c
M src/gb/gprs_ns2_fr.c
M src/gb/gprs_ns2_frgre.c
M src/gb/gprs_ns2_internal.h
M src/gb/gprs_ns2_udp.c
M src/gb/gprs_ns2_vty.c
M src/gb/libosmogb.map
8 files changed, 79 insertions(+), 86 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/include/osmocom/gprs/gprs_ns2.h b/include/osmocom/gprs/gprs_ns2.h
index 4575329..6140da2 100644
--- a/include/osmocom/gprs/gprs_ns2.h
+++ b/include/osmocom/gprs/gprs_ns2.h
@@ -32,6 +32,14 @@
 	NS2_VC_MODE_ALIVE,
 };
 
+enum gprs_ns2_dialect {
+	NS2_DIALECT_UNDEF,
+	NS2_DIALECT_STATIC_ALIVE,
+	NS2_DIALECT_STATIC_RESETBLOCK,
+	NS2_DIALECT_IPACCESS,
+	NS2_DIALECT_SNS,
+};
+
 /*! Osmocom NS link layer types */
 enum gprs_ns2_ll {
 	GPRS_NS2_LL_UDP,	/*!< NS/UDP/IP */
@@ -144,7 +152,8 @@
 			      gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
 struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t nsei);
 struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
-					 enum gprs_ns2_ll linklayer);
+					 enum gprs_ns2_ll linklayer,
+					 enum gprs_ns2_dialect dialect);
 uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
 void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
 void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
@@ -160,7 +169,6 @@
 		     struct gprs_ns2_vc_bind **result);
 struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi,
 						      const struct osmo_sockaddr *sockaddr);
-void gprs_ns2_bind_set_mode(struct gprs_ns2_vc_bind *bind, enum gprs_ns2_vc_mode mode);
 
 /* FR VL driver */
 struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
@@ -188,7 +196,8 @@
 struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
 					 const struct osmo_sockaddr *remote,
 					 uint16_t nsei,
-					 uint16_t nsvci);
+					 uint16_t nsvci,
+					 enum gprs_ns2_dialect dialect);
 struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
 					const struct osmo_sockaddr *remote,
 					struct gprs_ns2_nse *nse,
@@ -238,7 +247,5 @@
 int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi,
 		      const struct osmo_sockaddr_str *default_bind);
 int gprs_ns2_vty_create();
-void gprs_ns2_vty_force_vc_mode(bool force, enum gprs_ns2_vc_mode mode, const char *reason);
-
 
 /*! @} */
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index d90ba85..920fa68 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -492,7 +492,8 @@
  * \param[in] nse The NS Entity on which we operate
  * \param[in] initiater - if this is an incoming remote (!initiater) or a local outgoing connection (initater)
  * \return newly allocated NS-VC on success; NULL on error */
-struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind, struct gprs_ns2_nse *nse, bool initiater)
+struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind, struct gprs_ns2_nse *nse, bool initiater,
+				 enum gprs_ns2_vc_mode vc_mode)
 {
 	struct gprs_ns2_vc *nsvc = talloc_zero(bind, struct gprs_ns2_vc);
 
@@ -501,7 +502,7 @@
 
 	nsvc->bind = bind;
 	nsvc->nse = nse;
-	nsvc->mode = bind->vc_mode;
+	nsvc->mode = vc_mode;
 	nsvc->sig_weight = 1;
 	nsvc->data_weight = 1;
 
@@ -672,7 +673,8 @@
  *  \param[in] nsi NS instance in which to create NS Entity
  *  \param[in] nsei NS Entity Identifier of to-be-created NSE
  *  \returns newly-allocated NS-E in successful case; NULL on error */
-struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei, enum gprs_ns2_ll linklayer)
+struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
+					 enum gprs_ns2_ll linklayer, enum gprs_ns2_dialect dialect)
 {
 	struct gprs_ns2_nse *nse;
 
@@ -686,6 +688,7 @@
 	if (!nse)
 		return NULL;
 
+	nse->dialect = dialect;
 	nse->ll = linklayer;
 	nse->nsei = nsei;
 	nse->nsi = nsi;
@@ -765,6 +768,8 @@
 	struct tlv_parsed tp;
 	struct gprs_ns2_vc *nsvc;
 	struct gprs_ns2_nse *nse;
+	enum gprs_ns2_dialect dialect;
+	enum gprs_ns2_vc_mode vc_mode;
 	uint16_t nsvci;
 	uint16_t nsei;
 
@@ -794,8 +799,10 @@
 		return GPRS_NS2_CS_SKIPPED;
 	case NS_PDUT_RESET:
 		/* accept PDU RESET when vc_mode matches */
-		if (bind->vc_mode == NS2_VC_MODE_BLOCKRESET)
+		if (bind->accept_ipaccess) {
+			dialect = NS2_DIALECT_IPACCESS;
 			break;
+		}
 
 		rc = reject_status_msg(msg, &tp, reject, NS_CAUSE_PDU_INCOMP_PSTATE);
 		if (rc < 0) {
@@ -837,13 +844,14 @@
 			return GPRS_NS2_CS_SKIPPED;
 		}
 
-		nse = gprs_ns2_create_nse(bind->nsi, nsei, bind->ll);
+		nse = gprs_ns2_create_nse(bind->nsi, nsei, bind->ll, dialect);
 		if (!nse) {
 			return GPRS_NS2_CS_ERROR;
 		}
 	}
 
-	nsvc = ns2_vc_alloc(bind, nse, false);
+	vc_mode = gprs_ns2_dialect_to_vc_mode(dialect);
+	nsvc = ns2_vc_alloc(bind, nse, false, vc_mode);
 	if (!nsvc)
 		return GPRS_NS2_CS_SKIPPED;
 
@@ -911,12 +919,13 @@
 struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
 					 const struct osmo_sockaddr *remote,
 					 uint16_t nsei,
-					 uint16_t nsvci)
+					 uint16_t nsvci,
+					 enum gprs_ns2_dialect dialect)
 {
 	struct gprs_ns2_nse *nse = gprs_ns2_nse_by_nsei(bind->nsi, nsei);
 
 	if (!nse) {
-		nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP);
+		nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP, dialect);
 		if (!nse)
 			return NULL;
 	}
@@ -937,11 +946,19 @@
 	struct gprs_ns2_vc *nsvc;
 
 	if (!nse) {
-		nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP);
+		nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP, NS2_DIALECT_SNS);
 		if (!nse)
 			return -1;
 	}
 
+	if (nse->ll != GPRS_NS2_LL_UDP) {
+		return -2;
+	}
+
+	if (nse->dialect != NS2_DIALECT_SNS) {
+		return -2;
+	}
+
 	nsvc = gprs_ns2_ip_bind_connect(bind, nse, remote);
 	if (!nsvc)
 		return -1;
@@ -1199,14 +1216,6 @@
 	}
 }
 
-/*! Set the mode of given bind.
- *  \param[in] bind the bind we want to set the mode of
- *  \param[in] mode mode to set bind to */
-void gprs_ns2_bind_set_mode(struct gprs_ns2_vc_bind *bind, enum gprs_ns2_vc_mode mode)
-{
-	bind->vc_mode = mode;
-}
-
 /*! Destroy a given bind.
  *  \param[in] bind the bind we want to destroy */
 void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind)
@@ -1234,4 +1243,20 @@
 		gprs_ns2_free_bind(bind);
 	}
 }
+
+enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode(
+		enum gprs_ns2_dialect dialect)
+{
+	switch (dialect) {
+	case NS2_DIALECT_SNS:
+	case NS2_DIALECT_STATIC_ALIVE:
+		return NS2_VC_MODE_ALIVE;
+	case NS2_DIALECT_STATIC_RESETBLOCK:
+	case NS2_DIALECT_IPACCESS:
+		return NS2_VC_MODE_BLOCKRESET;
+	default:
+		return -1;
+	}
+}
+
 /*! @} */
diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c
index 2d5b021..6b4fa52 100644
--- a/src/gb/gprs_ns2_fr.c
+++ b/src/gb/gprs_ns2_fr.c
@@ -486,7 +486,6 @@
 	}
 	strncpy(priv->netif, netif, sizeof(priv->netif));
 
-	ns2_vty_bind_apply(bind);
 	if (result)
 		*result = bind;
 
@@ -600,7 +599,7 @@
 	struct priv_vc *priv = NULL;
 	struct gprs_ns2_nse *nse = gprs_ns2_nse_by_nsei(bind->nsi, nsei);
 	if (!nse) {
-		nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_FR);
+		nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_FR, NS2_DIALECT_STATIC_RESETBLOCK);
 		if (!nse)
 			return NULL;
 		created_nse = true;
@@ -611,7 +610,7 @@
 		goto err_nse;
 	}
 
-	nsvc = ns2_vc_alloc(bind, nse, true);
+	nsvc = ns2_vc_alloc(bind, nse, true, NS2_VC_MODE_BLOCKRESET);
 	if (!nsvc)
 		goto err_nse;
 
diff --git a/src/gb/gprs_ns2_frgre.c b/src/gb/gprs_ns2_frgre.c
index 3c276bc..423ea4b 100644
--- a/src/gb/gprs_ns2_frgre.c
+++ b/src/gb/gprs_ns2_frgre.c
@@ -592,8 +592,6 @@
 				dscp, rc, errno);
 	}
 
-	ns2_vty_bind_apply(bind);
-
 	if (result)
 		*result = bind;
 
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index e72deff..8c0c135 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -130,6 +130,9 @@
 	/*! which link-layer are we based on? */
 	enum gprs_ns2_ll ll;
 
+	/*! which dialect does this NSE speaks? */
+	enum gprs_ns2_dialect dialect;
+
 	struct osmo_fsm_inst *bss_sns_fi;
 };
 
@@ -188,8 +191,8 @@
 	struct gprs_ns2_inst *nsi;
 	struct gprs_ns2_vc_driver *driver;
 
-	/*! if VCs use reset/block/unblock method. IP shall not use this */
-	enum gprs_ns2_vc_mode vc_mode;
+	bool accept_ipaccess;
+	bool accept_sns;
 
 	/*! which link-layer are we based on? */
 	enum gprs_ns2_ll ll;
@@ -222,7 +225,8 @@
 
 struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind,
 				 struct gprs_ns2_nse *nse,
-				 bool initiater);
+				 bool initiater,
+				 enum gprs_ns2_vc_mode vc_mode);
 
 struct msgb *gprs_ns2_msgb_alloc(void);
 
@@ -298,8 +302,6 @@
 int gprs_ns2_vc_is_alive(struct gprs_ns2_vc *nsvc);
 int gprs_ns2_vc_is_unblocked(struct gprs_ns2_vc *nsvc);
 
-/* vty.c */
-void ns2_vty_bind_apply(struct gprs_ns2_vc_bind *bind);
-
 /* nse */
 void ns2_nse_notify_unblocked(struct gprs_ns2_vc *nsvc, bool unblocked);
+enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode(enum gprs_ns2_dialect dialect);
diff --git a/src/gb/gprs_ns2_udp.c b/src/gb/gprs_ns2_udp.c
index 928116d..b923e81 100644
--- a/src/gb/gprs_ns2_udp.c
+++ b/src/gb/gprs_ns2_udp.c
@@ -359,8 +359,6 @@
 	}
 
 	llist_add(&bind->list, &nsi->binding);
-	ns2_vty_bind_apply(bind);
-
 	if (result)
 		*result = bind;
 
@@ -378,8 +376,16 @@
 {
 	struct gprs_ns2_vc *nsvc;
 	struct priv_vc *priv;
+	enum gprs_ns2_vc_mode vc_mode;
 
-	nsvc = ns2_vc_alloc(bind, nse, true);
+	vc_mode = gprs_ns2_dialect_to_vc_mode(nse->dialect);
+	if ((int) vc_mode == -1) {
+		LOGP(DLNS, LOGL_ERROR, "Can not derive vc mode from dialect %d. Maybe libosmocore is too old.\n",
+		     nse->dialect);
+		return NULL;
+	}
+
+	nsvc = ns2_vc_alloc(bind, nse, true, vc_mode);
 	if (!nsvc)
 		return NULL;
 
diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c
index 43e9c2c..d285c22 100644
--- a/src/gb/gprs_ns2_vty.c
+++ b/src/gb/gprs_ns2_vty.c
@@ -62,10 +62,6 @@
 	struct osmo_sockaddr_str frgreaddr;
 	int dscp;
 	enum gprs_ns2_vc_mode vc_mode;
-	/* force vc mode if another configuration forces
-	 * the vc mode. E.g. SNS configuration */
-	bool force_vc_mode;
-	const char *force_vc_mode_reason;
 	bool frgre;
 
 	struct llist_head vtyvc;
@@ -714,30 +710,14 @@
 	"Disable NS-{RESET,BLOCK,UNBLOCK}\n")
 {
 	enum gprs_ns2_vc_mode vc_mode;
-	struct gprs_ns2_vc_bind *bind;
 
 	if (!strcmp(argv[0], "enabled"))
 		vc_mode = NS2_VC_MODE_BLOCKRESET;
 	else
 		vc_mode = NS2_VC_MODE_ALIVE;
 
-	if (priv.force_vc_mode) {
-		if (priv.vc_mode != vc_mode)
-		{
-			vty_out(vty, "Ignoring use-reset-block because it's already set by %s.%s",
-				priv.force_vc_mode_reason, VTY_NEWLINE);
-			return CMD_WARNING;
-		}
-
-		return CMD_SUCCESS;
-	}
-
 	priv.vc_mode = vc_mode;
 
-	llist_for_each_entry(bind, &vty_nsi->binding, list) {
-		gprs_ns2_bind_set_mode(bind, priv.vc_mode);
-	}
-
 	return CMD_SUCCESS;
 }
 
@@ -902,6 +882,7 @@
 	struct gprs_ns2_nse *nse;
 	struct gprs_ns2_vc *nsvc;
 	struct osmo_sockaddr sockaddr;
+	enum gprs_ns2_dialect dialect = NS2_DIALECT_UNDEF;
 	int rc = 0;
 
 	if (!vty_nsi)
@@ -918,7 +899,7 @@
 			/* TODO: could not bind on the specific address */
 			return -1;
 		}
-		gprs_ns2_bind_set_mode(bind, priv.vc_mode);
+		bind->accept_ipaccess = true;
 	}
 
 	/* create vcs */
@@ -926,6 +907,7 @@
 		/* validate settings */
 		switch (vtyvc->ll) {
 		case GPRS_NS2_LL_UDP:
+			dialect = NS2_DIALECT_IPACCESS;
 			if (strlen(vtyvc->remote.ip) == 0) {
 				/* Invalid IP for VC */
 				continue;
@@ -942,14 +924,16 @@
 			}
 			break;
 		case GPRS_NS2_LL_FR:
+			dialect = NS2_DIALECT_STATIC_RESETBLOCK;
 			break;
 		case GPRS_NS2_LL_FR_GRE:
+			dialect = NS2_DIALECT_STATIC_RESETBLOCK;
 			continue;
 		}
 
 		nse = gprs_ns2_nse_by_nsei(vty_nsi, vtyvc->nsei);
 		if (!nse) {
-			nse = gprs_ns2_create_nse(vty_nsi, vtyvc->nsei, vtyvc->ll);
+			nse = gprs_ns2_create_nse(vty_nsi, vtyvc->nsei, vtyvc->ll, dialect);
 			if (!nse) {
 				/* Could not create NSE for VTY */
 				continue;
@@ -1001,29 +985,3 @@
 
 	return 0;
 }
-
-/*!
- * \brief ns2_vty_bind_apply will be called when a new bind is created to apply vty settings
- * \param bind
- * \return
- */
-void ns2_vty_bind_apply(struct gprs_ns2_vc_bind *bind)
-{
-	gprs_ns2_bind_set_mode(bind, priv.vc_mode);
-}
-
-/*!
- * \brief ns2_vty_force_vc_mode force a mode and prevents the vty from overwriting it.
- * \param force if true mode and reason will be set. false to allow modification via vty.
- * \param mode
- * \param reason A description shown to the user when a vty command wants to change the mode.
- */
-void gprs_ns2_vty_force_vc_mode(bool force, enum gprs_ns2_vc_mode mode, const char *reason)
-{
-	priv.force_vc_mode = force;
-
-	if (force) {
-		priv.vc_mode = mode;
-		priv.force_vc_mode_reason = reason;
-	}
-}
diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map
index f8ad901..e3301be 100644
--- a/src/gb/libosmogb.map
+++ b/src/gb/libosmogb.map
@@ -109,7 +109,6 @@
 gprs_ns_msgb_alloc;
 
 gprs_ns2_aff_cause_prim_strs;
-gprs_ns2_bind_set_mode;
 gprs_ns2_cause_strs;
 gprs_ns2_create_nse;
 gprs_ns2_dynamic_create_nse;
@@ -159,7 +158,6 @@
 gprs_ns2_reset_persistent_nsvcs;
 gprs_ns2_start_alive_all_nsvcs;
 gprs_ns2_vty_create;
-gprs_ns2_vty_force_vc_mode;
 gprs_ns2_vty_init;
 
 gprs_nsvc_create2;

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/21484
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Ia118bb6f994845d84db09de7a94856f5ca573404
Gerrit-Change-Number: 21484
Gerrit-PatchSet: 11
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201215/b7171903/attachment.htm>


More information about the gerrit-log mailing list