Change in libosmo-netif[master]: prim: Add internal CTL SAPI to negotiate SAP versions

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

pespin gerrit-no-reply at lists.osmocom.org
Wed Dec 1 18:52:40 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-netif/+/26435 )


Change subject: prim: Add internal CTL SAPI to negotiate SAP versions
......................................................................

prim: Add internal CTL SAPI to negotiate SAP versions

This commits adds a generic mechansim for applications to validate
support for SAPs and specific versions of them.

A new special SAPI is introduced to manage inbound control messages for
the protocol.
In that SAPI a new primitive HELLO.ind/.cnf is added to negotiate
support for versions of any given SAP.
The idea is that the client upon connecting submits a HELLO.ind(SAP,
VER) for each SAP it plans to use, including the version of the special
CTL SAPI itself (preferrably to be checked first).
Upon receiving such a message, osmo_prim_srv handles it using a special
path, which ends up calling the user provided rx_sapi_version_cb(SAP,
VER). In there, the user can either:
* Accept the version (return same VER value)
* Reject the requested version but propose another candidate version
  (return some positive VER value other than received VER). In this
  case, the client can decide whether to request another VER or close the
  connection.
* Reject the proposed version and close the connection.

Change-Id: I0c2d92cfdb5433e3caab51d712fd947d51eeef23
---
M include/osmocom/netif/prim.h
M src/prim.c
2 files changed, 122 insertions(+), 3 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/35/26435/1

diff --git a/include/osmocom/netif/prim.h b/include/osmocom/netif/prim.h
index 4c99cd7..facc555 100644
--- a/include/osmocom/netif/prim.h
+++ b/include/osmocom/netif/prim.h
@@ -31,6 +31,15 @@
 /*! oph and related msgb is owned by srv and wll be freed after the callback returns. */
 typedef int (*osmo_prim_srv_rx_cb)(struct osmo_prim_srv *prim_srv, struct osmo_prim_hdr *oph);
 
+/*! Return value:
+ * RET=rem_version: Accept the version
+ * RET!=rem_version && RET > 0: Reject the requested version but propose another candidate version
+ *				 In this case, the client can decide whether to request another VER
+ * 				or close the connection.
+ * RET<0: Reject the proposed version and close the connection.
+ */
+typedef int (*osmo_prim_srv_rx_sapi_version)(struct osmo_prim_srv *prim_srv, uint32_t sapi, uint16_t rem_version);
+
 struct osmo_prim_hdr *osmo_prim_msgb_alloc(unsigned int sap, unsigned int primitive,
 					  enum osmo_prim_operation operation, size_t alloc_len);
 
@@ -42,6 +51,7 @@
 void *osmo_prim_srv_link_get_priv(const struct osmo_prim_srv_link *prim_link);
 void osmo_prim_srv_link_set_log_category(struct osmo_prim_srv_link *prim_link, int log_cat);
 void osmo_prim_srv_link_set_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb);
+void osmo_prim_srv_link_set_rx_sapi_version_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_sapi_version rx_sapi_version_cb);
 void osmo_prim_srv_link_set_opened_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb opened_conn_cb);
 void osmo_prim_srv_link_set_closed_conn_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_conn_cb closed_conn_cb);
 int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link);
diff --git a/src/prim.c b/src/prim.c
index fc271a4..463463b 100644
--- a/src/prim.c
+++ b/src/prim.c
@@ -83,6 +83,7 @@
 	osmo_prim_srv_conn_cb opened_conn_cb;
 	osmo_prim_srv_conn_cb closed_conn_cb;
 	osmo_prim_srv_rx_cb rx_cb;
+	osmo_prim_srv_rx_sapi_version rx_sapi_version_cb;
 };
 
 struct osmo_prim_srv {
@@ -92,10 +93,106 @@
 };
 
 /******************************
+ * CONTROL SAP
+ ******************************/
+#define OSMO_PRIM_CTL_SAPI 		0xffffffff
+#define OSMO_PRIM_CTL_API_VERSION 	0
+
+enum sap_ctl_prim_type {
+	SAP_CTL_PRIM_HELLO,
+	_SAP_CTL_PRIM_MAX
+};
+
+const struct value_string sap_ctl_prim_type_names[] = {
+	OSMO_VALUE_STRING(SAP_CTL_PRIM_HELLO),
+	{ 0, NULL }
+};
+
+/* HNB_CTL_PRIM_HELLO.ind, UL */
+struct sap_ctl_hello_param {
+	uint16_t sapi; /* SAPI for which we negotiate version */
+	uint16_t api_version; /* The intended version */
+} __attribute__ ((packed));
+
+struct sap_ctl_prim {
+	struct osmo_prim_hdr hdr;
+	union {
+		struct sap_ctl_hello_param hello_ind;
+		struct sap_ctl_hello_param hello_cnf;
+	} u;
+} __attribute__ ((packed));
+
+static struct sap_ctl_prim *_sap_ctl_makeprim_hello_cnf(uint32_t sapi, uint16_t api_version)
+{
+	struct sap_ctl_prim *ctl_prim;
+
+	ctl_prim = (struct sap_ctl_prim *)osmo_prim_msgb_alloc(
+						OSMO_PRIM_CTL_SAPI, SAP_CTL_PRIM_HELLO, PRIM_OP_CONFIRM,
+						sizeof(struct osmo_prim_hdr) + sizeof(struct sap_ctl_hello_param));
+	ctl_prim->u.hello_cnf.sapi = sapi;
+	ctl_prim->u.hello_cnf.api_version = api_version;
+
+	return ctl_prim;
+}
+
+/******************************
  * osmo_prim_srv
  ******************************/
 #define LOGSRV(srv, lvl, fmt, args...) LOGP((srv)->link->log_cat, lvl, fmt, ## args)
 
+static int _srv_sap_ctl_rx_hello_ind(struct osmo_prim_srv *prim_srv, struct sap_ctl_hello_param *hello_ind)
+{
+	struct sap_ctl_prim *prim_resp;
+	int rc;
+
+	LOGSRV(prim_srv, LOGL_INFO, "Rx CTL::HELLO.ind SAPI=%u API_VERSION=%u\n", hello_ind->sapi, hello_ind->api_version);
+
+	if (hello_ind->sapi == OSMO_PRIM_CTL_SAPI)
+		rc = hello_ind->api_version ==  OSMO_PRIM_CTL_API_VERSION ? OSMO_PRIM_CTL_API_VERSION : -1;
+	else if (prim_srv->link->rx_sapi_version_cb)
+		rc = prim_srv->link->rx_sapi_version_cb(prim_srv, hello_ind->sapi, hello_ind->api_version);
+	else	/* Accept whatever version by default: */
+		rc = hello_ind->api_version;
+
+	if (rc < 0) {
+		LOGSRV(prim_srv, LOGL_ERROR,
+		       "SAPI=%u API_VERSION=%u not supported! destroying connection\n",
+		       hello_ind->sapi, hello_ind->api_version);
+		osmo_stream_srv_set_flush_and_destroy(prim_srv->stream);
+		return rc;
+	}
+	prim_resp = _sap_ctl_makeprim_hello_cnf(hello_ind->sapi, (uint16_t)rc);
+	LOGSRV(prim_srv, LOGL_INFO, "Tx CTL::HELLO.cnf SAPI=%u API_VERSION=%u\n",
+	       hello_ind->sapi, prim_resp->u.hello_cnf.api_version);
+	osmo_prim_srv_send(prim_srv, prim_resp->hdr.msg);
+	return rc;
+}
+
+static int _srv_sap_ctl_rx(struct osmo_prim_srv *prim_srv, struct osmo_prim_hdr *oph)
+{
+	switch (oph->operation) {
+	case PRIM_OP_INDICATION:
+		switch (oph->primitive) {
+		case SAP_CTL_PRIM_HELLO:
+			return _srv_sap_ctl_rx_hello_ind(prim_srv, (struct sap_ctl_hello_param *)msgb_data(oph->msg));
+		default:
+			LOGSRV(prim_srv, LOGL_ERROR, "Rx unknown CTL SAP primitive %u (len=%u)\n",
+			     oph->primitive, msgb_length(oph->msg));
+			return -EINVAL;
+		}
+		break;
+	case PRIM_OP_RESPONSE:
+	case PRIM_OP_REQUEST:
+	case PRIM_OP_CONFIRM:
+	default:
+		LOGSRV(prim_srv, LOGL_ERROR, "Rx CTL SAP unexpected primitive operation %s::%s (len=%u)\n",
+		     get_value_string(sap_ctl_prim_type_names, oph->primitive),
+		     get_value_string(osmo_prim_op_names, oph->operation),
+		     msgb_length(oph->msg));
+		return -EINVAL;
+	}
+}
+
 static int _osmo_prim_srv_read_cb(struct osmo_stream_srv *srv)
 {
 	struct osmo_prim_srv *prim_srv = osmo_stream_srv_get_data(srv);
@@ -131,9 +228,15 @@
 	osmo_prim_init(&oph, pkth->sap, pkth->primitive, pkth->operation, msg);
 	msgb_pull(msg, sizeof(*pkth));
 
-	if (prim_srv->link->rx_cb)
-		rc = prim_srv->link->rx_cb(prim_srv, &oph);
-
+	switch (oph.sap) {
+	case OSMO_PRIM_CTL_SAPI:
+		rc = _srv_sap_ctl_rx(prim_srv, &oph);
+		break;
+	default:
+		if (prim_srv->link->rx_cb)
+			rc = prim_srv->link->rx_cb(prim_srv, &oph);
+		break;
+	}
 	/* as we always synchronously process the message in _osmo_prim_srv_link_rx() and
 	 * its callbacks, we can free the message here. */
 	msgb_free(msg);
@@ -327,6 +430,12 @@
 	prim_link->rx_cb = rx_cb;
 }
 
+void osmo_prim_srv_link_set_rx_sapi_version_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_sapi_version rx_sapi_version_cb)
+{
+	prim_link->rx_sapi_version_cb = rx_sapi_version_cb;
+
+}
+
 int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link)
 {
 	int rc;

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

Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I0c2d92cfdb5433e3caab51d712fd947d51eeef23
Gerrit-Change-Number: 26435
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211201/dbb551a5/attachment.htm>


More information about the gerrit-log mailing list