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
Fri Dec 10 14:38:16 UTC 2021


pespin has submitted this change. ( 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 mechanism 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.req/.cnf is added to negotiate
support for versions of any given SAP.
The idea is that the client upon connecting submits a HELLO.req(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(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  osmith: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/include/osmocom/netif/prim.h b/include/osmocom/netif/prim.h
index 4f17622..78406dd 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);
 
@@ -43,6 +52,7 @@
 void osmo_prim_srv_link_set_log_category(struct osmo_prim_srv_link *prim_link, int log_cat);
 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);
+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_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb);
 void osmo_prim_srv_link_set_rx_msgb_alloc_len(struct osmo_prim_srv_link *prim_link, size_t alloc_len);
 int osmo_prim_srv_link_open(struct osmo_prim_srv_link *prim_link);
diff --git a/src/prim.c b/src/prim.c
index 6c6da6e..5189c4c 100644
--- a/src/prim.c
+++ b/src/prim.c
@@ -82,6 +82,7 @@
 	struct osmo_stream_srv_link *stream;
 	osmo_prim_srv_conn_cb opened_conn_cb;
 	osmo_prim_srv_conn_cb closed_conn_cb;
+	osmo_prim_srv_rx_sapi_version rx_sapi_version_cb;
 	osmo_prim_srv_rx_cb rx_cb;
 	size_t rx_msgb_alloc_len;
 };
@@ -93,10 +94,107 @@
 };
 
 /******************************
+ * 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 {
+	uint32_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_req;
+		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));
+	msgb_put(ctl_prim->hdr.msg, 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_req(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.req 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_REQUEST:
+		switch (oph->primitive) {
+		case SAP_CTL_PRIM_HELLO:
+			return _srv_sap_ctl_rx_hello_req(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_INDICATION:
+	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);
@@ -133,9 +231,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);
@@ -325,6 +429,11 @@
 	prim_link->closed_conn_cb = closed_conn_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;
+}
+
 void osmo_prim_srv_link_set_rx_cb(struct osmo_prim_srv_link *prim_link, osmo_prim_srv_rx_cb rx_cb)
 {
 	prim_link->rx_cb = rx_cb;

-- 
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: 9
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
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/20211210/6355b2e0/attachment.htm>


More information about the gerrit-log mailing list