Change in osmo-pcu[master]: Support proto IPAC_PROTO_EXT_PCU BSC<->PCU

pespin gerrit-no-reply at lists.osmocom.org
Wed Jun 23 17:52:22 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-pcu/+/24756 )


Change subject: Support proto IPAC_PROTO_EXT_PCU BSC<->PCU
......................................................................

Support proto IPAC_PROTO_EXT_PCU BSC<->PCU

Related: SYS#5303
Change-Id: I633db291107883c2e370a9b56606d562a990b714
---
M src/osmobts_sock.c
M src/pcu_l1_if.cpp
M src/pcu_l1_if.h
M tests/app_info/AppInfoTest.cpp
4 files changed, 65 insertions(+), 12 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/56/24756/1

diff --git a/src/osmobts_sock.c b/src/osmobts_sock.c
index 4e1171f..5c6415f 100644
--- a/src/osmobts_sock.c
+++ b/src/osmobts_sock.c
@@ -133,10 +133,12 @@
 
 static int pcu_sock_read(struct osmo_fd *bfd)
 {
-	struct gsm_pcu_if pcu_prim;
+	const size_t max_len = sizeof(struct gsm_pcu_if) + 1000;
+	uint8_t *buf = alloca(max_len);
+	struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *)buf;
 	int rc;
 
-	rc = recv(bfd->fd, &pcu_prim, sizeof(pcu_prim), 0);
+	rc = recv(bfd->fd, buf, max_len, 0);
 	if (rc < 0 && errno == EAGAIN)
 		return 0; /* Try again later */
 	if (rc <= 0) {
@@ -144,7 +146,13 @@
 		return -EIO;
 	}
 
-	return pcu_rx(pcu_prim.msg_type, &pcu_prim);
+	if (rc < PCUIF_HDR_SIZE) {
+		LOGP(DL1IF, LOGL_ERROR, "Received %d bytes on PCU Socket, but primitive "
+		     "hdr size is %zu, discarding\n", rc, PCUIF_HDR_SIZE);
+		return -EINVAL;
+	}
+
+	return pcu_rx(pcu_prim, rc);
 }
 
 static int pcu_sock_write(struct osmo_fd *bfd)
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index b35c990..2373f60 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -951,9 +951,32 @@
 	return 0;
 }
 
-int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
+static int pcu_rx_container(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_container *container)
+{
+	int rc;
+
+	switch (container->msg_type) {
+	default:
+		LOGP(DL1IF, LOGL_NOTICE, "(bts=%d) Rx unexpected msg type (%u) inside container!\n",
+		     bts->nr, container->msg_type);
+		rc = -1;
+	}
+	return rc;
+}
+
+#define CHECK_IF_MSG_SIZE(prim_len, prim_msg) \
+	do { \
+		size_t _len = PCUIF_HDR_SIZE + sizeof(prim_msg); \
+		if (prim_len < _len) { \
+			LOGP(DL1IF, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive %s " \
+			     "size is %zu, discarding\n", prim_len, #prim_msg, _len); \
+			return -EINVAL; \
+		} \
+	} while(0);
+int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length)
 {
 	int rc = 0;
+	size_t exp_len;
 	struct gprs_rlcmac_bts *bts = gprs_pcu_get_bts_by_nr(the_pcu, pcu_prim->bts_nr);
 	if (!bts) {
 		LOGP(DL1IF, LOGL_NOTICE, "Received message for new BTS%d\n", pcu_prim->bts_nr);
@@ -964,40 +987,59 @@
 		}
 	}
 
-	switch (msg_type) {
+	switch (pcu_prim->msg_type) {
 	case PCU_IF_MSG_DATA_IND:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_ind);
 		rc = pcu_rx_data_ind(bts, &pcu_prim->u.data_ind);
 		break;
 	case PCU_IF_MSG_DATA_CNF:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_cnf);
 		rc = pcu_rx_data_cnf(bts, &pcu_prim->u.data_cnf);
 		break;
 	case PCU_IF_MSG_RTS_REQ:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rts_req);
 		rc = pcu_rx_rts_req(bts, &pcu_prim->u.rts_req);
 		break;
 	case PCU_IF_MSG_RACH_IND:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rach_ind);
 		rc = pcu_rx_rach_ind(bts, &pcu_prim->u.rach_ind);
 		break;
 	case PCU_IF_MSG_INFO_IND:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.info_ind);
 		rc = pcu_rx_info_ind(bts, &pcu_prim->u.info_ind);
 		break;
 	case PCU_IF_MSG_TIME_IND:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.time_ind);
 		rc = pcu_rx_time_ind(bts, &pcu_prim->u.time_ind);
 		break;
 	case PCU_IF_MSG_PAG_REQ:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.pag_req);
 		rc = pcu_rx_pag_req(bts, &pcu_prim->u.pag_req);
 		break;
 	case PCU_IF_MSG_SUSP_REQ:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.susp_req);
 		rc = pcu_rx_susp_req(bts, &pcu_prim->u.susp_req);
 		break;
 	case PCU_IF_MSG_APP_INFO_REQ:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.app_info_req);
 		rc = pcu_rx_app_info_req(bts, &pcu_prim->u.app_info_req);
 		break;
 	case PCU_IF_MSG_INTERF_IND:
 		/* TODO: handle interference reports */
 		break;
+	case PCU_IF_MSG_CONTAINER:
+		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.container);
+		/* ^ check if we can access container fields, v check with container data length */
+		exp_len = PCUIF_HDR_SIZE + sizeof(pcu_prim->u.container) + osmo_load16be(&pcu_prim->u.container.length);
+		if (pcu_prim_length < exp_len) {
+			LOGP(DL1IF, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive container size" \
+			     "is %zu, discarding\n", pcu_prim_length, exp_len);
+		}
+		rc = pcu_rx_container(bts, &pcu_prim->u.container);
+		break;
 	default:
 		LOGP(DL1IF, LOGL_ERROR, "Received unknown PCU msg type %d\n",
-			msg_type);
+			pcu_prim->msg_type);
 		rc = -EINVAL;
 	}
 
diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h
index 246444c..2a4f0ea 100644
--- a/src/pcu_l1_if.h
+++ b/src/pcu_l1_if.h
@@ -160,7 +160,7 @@
 #endif
 struct gprs_rlcmac_bts;
 
-int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim);
+int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length);
 int pcu_l1if_open(void);
 void pcu_l1if_close(void);
 int pcu_sock_send(struct msgb *msg);
@@ -178,6 +178,9 @@
 
 void pcu_rx_block_time(struct gprs_rlcmac_bts *bts, uint16_t arfcn, uint32_t fn, uint8_t ts_no);
 uint16_t imsi2paging_group(const char* imsi);
+
+#define PCUIF_HDR_SIZE ( sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u) )
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tests/app_info/AppInfoTest.cpp b/tests/app_info/AppInfoTest.cpp
index e89680b..d3a047e 100644
--- a/tests/app_info/AppInfoTest.cpp
+++ b/tests/app_info/AppInfoTest.cpp
@@ -72,7 +72,7 @@
 	struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
 
 	fprintf(stderr, "--- %s ---\n",  __func__);
-	pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
+	pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
 	fprintf(stderr, "\n");
 }
 
@@ -106,7 +106,7 @@
 
 	fprintf(stderr, "--- %s ---\n",  __func__);
 	pcu_prim.u.app_info_req = *req;
-	pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
+	pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
 
 	msg = sched_app_info(tbf1);
 	assert(msg);
@@ -126,7 +126,7 @@
 
 	fprintf(stderr, "--- %s ---\n",  __func__);
 	pcu_prim.u.app_info_req = *req;
-	pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
+	pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
 
 	msgb_free(bts->app_info);
 	bts->app_info = NULL;
@@ -142,8 +142,8 @@
 
 	fprintf(stderr, "--- %s ---\n",  __func__);
 	pcu_prim.u.app_info_req = *req;
-	pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
-	pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
+	pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
+	pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
 	fprintf(stderr, "\n");
 }
 

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

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: I633db291107883c2e370a9b56606d562a990b714
Gerrit-Change-Number: 24756
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/20210623/aee3e339/attachment.htm>


More information about the gerrit-log mailing list