[PATCH 5/6] ladpm: Fix msgb handling and SAPI=3 establishment delay

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/OpenBSC@lists.osmocom.org/.

Jacob Erlbeck jerlbeck at sysmocom.de
Tue Mar 4 12:44:42 UTC 2014


Currently it takes 3s to establish a SAPI 3 SACCH connection with
osmo-bts. This is due to the fact, that a broken SABME request is
sent first and and is ignored by the MS. Then, after a T200 timeout
(2s) the SABME command is sent again (this time correctly) and
answered by the MS.

The first SABME message is broken (it has a length field of 3 and
ends with 3 bytes from the tail of the original RSL message),
because of it is expected throughout lapdm.c that msg buffers
containing RSL have msg->l2h == msg->data. Some abis input drivers
fulfill this but IPA doesn't, thus the 3 bytes of the IPA header
are still part of the msg and confuse length computation.

Since internal fields of the msg are modified directly, this is
difficult to see.

This patch adds a new function msgb_pull_to_l3() that explicitely
skips over all headers prepending L3 and therefore resets l1h and
l2h. This function is then used instead of msgb_pull_l2h() which
only worked correctly when msg->l2h == msg->data. In addition,
code manipulating msg->tail and msg->len directly has been replaced
by calls to msgb_trim().

Note that this patch does not fix all issues of this case in the LADP
related code.

Ticket: #192
Sponsored-by: On-Waves ehf
---
 include/osmocom/core/msgb.h |   15 +++++++++++++++
 src/gsm/lapdm.c             |   41 ++++++++++++++---------------------------
 tests/lapd/lapd_test.ok     |    8 ++++----
 3 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h
index 5d4bd84..33e8081 100644
--- a/include/osmocom/core/msgb.h
+++ b/include/osmocom/core/msgb.h
@@ -300,6 +300,21 @@ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
 	return msgb->data += len;
 }
 
+/*! \brief remove (pull) all headers in front of l3h from the message buffer.
+ *  \param[in] msgb message buffer with a valid l3h
+ *  \returns pointer to new start of msgb (l3h)
+ *
+ * This function moves the \a data pointer of the \ref msgb further back
+ * in the message, thereby shrinking the size of the message.
+ * l1h and l2h will be cleared.
+ */
+static inline unsigned char *msgb_pull_to_l3(struct msgb *msg)
+{
+	unsigned char *ret = msgb_pull(msg, msg->l3h - msg->data);
+	msg->l1h = msg->l2h = NULL;
+	return ret;
+}
+
 /*! \brief remove uint8 from front of message
  *  \param[in] msgb message buffer
  *  \returns 8bit value taken from end of msgb
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index 19f78a1..41f4be7 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -193,14 +193,6 @@ static struct lapdm_datalink *datalink_for_sapi(struct lapdm_entity *le, uint8_t
 	}
 }
 
-/* remove the L2 header from a MSGB */
-static inline unsigned char *msgb_pull_l2h(struct msgb *msg)
-{
-	unsigned char *ret = msgb_pull(msg, msg->l3h - msg->l2h);
-	msg->l2h = NULL;
-	return ret;
-}
-
 /* Append padding (if required) */
 static void lapdm_pad_msgb(struct msgb *msg, uint8_t n201)
 {
@@ -611,7 +603,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le,
 			lctx.length = n201;
 			lctx.more = 0;
 			msg->l3h = msg->l2h + 2;
-			msgb_pull_l2h(msg);
+			msgb_pull_to_l3(msg);
 		} else {
 			/* length field */
 			if (!(msg->l2h[2] & LAPDm_EL)) {
@@ -629,7 +621,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le,
 			lctx.length = msg->l2h[2] >> 2;
 			lctx.more = !!(msg->l2h[2] & LAPDm_MORE);
 			msg->l3h = msg->l2h + 3;
-			msgb_pull_l2h(msg);
+			msgb_pull_to_l3(msg);
 		}
 		/* store context for messages from lapd */
 		memcpy(&mctx.dl->mctx, &mctx, sizeof(mctx.dl->mctx));
@@ -644,7 +636,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le,
 		/* directly pass up to layer3 */
 		LOGP(DLLAPD, LOGL_INFO, "fmt=Bbis UI\n");
 		msg->l3h = msg->l2h;
-		msgb_pull_l2h(msg);
+		msgb_pull_to_l3(msg);
 		rc = send_rslms_rll_l3(RSL_MT_UNIT_DATA_IND, &mctx, msg);
 		break;
 	default:
@@ -807,9 +799,8 @@ static int rslms_rx_rll_est_req(struct msgb *msg, struct lapdm_datalink *dl)
 	}
 
 	/* Remove RLL header from msgb and set length to L3-info */
-	msgb_pull_l2h(msg);
-	msg->len = length;
-	msg->tail = msg->l3h + length;
+	msgb_pull_to_l3(msg);
+	msgb_trim(msg, length);
 
 	/* prepare prim */
 	osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
@@ -861,9 +852,8 @@ static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
 		le->tx_power, le->ta);
 
 	/* Remove RLL header from msgb and set length to L3-info */
-	msgb_pull_l2h(msg);
-	msg->len = length;
-	msg->tail = msg->l3h + length;
+	msgb_pull_to_l3(msg);
+	msgb_trim(msg, length);
 
 	/* Push L1 + LAPDm header on msgb */
 	msg->l2h = msgb_push(msg, 2 + !ui_bts);
@@ -900,9 +890,8 @@ static int rslms_rx_rll_data_req(struct msgb *msg, struct lapdm_datalink *dl)
 	length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
 
 	/* Remove RLL header from msgb and set length to L3-info */
-	msgb_pull_l2h(msg);
-	msg->len = length;
-	msg->tail = msg->l3h + length;
+	msgb_pull_to_l3(msg);
+	msgb_trim(msg, length);
 
 	/* prepare prim */
 	osmo_prim_init(&dp.oph, 0, PRIM_DL_DATA, PRIM_OP_REQUEST, msg);
@@ -957,9 +946,8 @@ static int rslms_rx_rll_res_req(struct msgb *msg, struct lapdm_datalink *dl)
 	length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
 
 	/* Remove RLL header from msgb and set length to L3-info */
-	msgb_pull_l2h(msg);
-	msg->len = length;
-	msg->tail = msg->l3h + length;
+	msgb_pull_to_l3(msg);
+	msgb_trim(msg, length);
 
 	/* prepare prim */
 	osmo_prim_init(&dp.oph, 0, (msg_type == RSL_MT_RES_REQ) ? PRIM_DL_RES
@@ -981,12 +969,11 @@ static int rslms_rx_rll_rel_req(struct msgb *msg, struct lapdm_datalink *dl)
 		mode = rllh->data[1] & 1;
 
 	/* Pull rllh */
-	msgb_pull_l2h(msg);
+	msgb_pull_to_l3(msg);
 
 	/* 04.06 3.8.3: No information field is permitted with the DISC
 	 * command. */
-	msg->len = 0;
-	msg->tail = msg->l3h = msg->data;
+	msgb_trim(msg, 0);
 
 	/* prepare prim */
 	osmo_prim_init(&dp.oph, 0, PRIM_DL_REL, PRIM_OP_REQUEST, msg);
@@ -1045,7 +1032,7 @@ static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t f
 
 	gsm_fn2gsmtime(&tm, frame_nr);
 
-	msgb_pull_l2h(msg);
+	msgb_pull_to_l3(msg);
 	msg->l2h = msgb_push(msg, sizeof(*ch) + sizeof(*ref));
 	ch = (struct abis_rsl_cchan_hdr *)msg->l2h;
 	rsl_init_cchan_hdr(ch, RSL_MT_CHAN_CONF);
diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok
index 7d266bd..9fb58e0 100644
--- a/tests/lapd/lapd_test.ok
+++ b/tests/lapd/lapd_test.ok
@@ -33,9 +33,9 @@ Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0,
 Message: [L2]> 01 73 41 [L3]> 05 24 31 03 50 18 93 08 29 47 80 00 00 00 00 80 2b 2b 2b 2b 
 I test RF channel establishment.
 Testing SAPI3/SDCCH
-Took message from DCCH queue: L2 header size 6, L3 size 17, SAP 0x1000000, 0/0, Link 0x03
-Message: [L2]> 0f 3f 0d 20 02 03 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+Took message from DCCH queue: L2 header size 3, L3 size 20, SAP 0x1000000, 0/0, Link 0x03
+Message: [L2]> 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 Testing SAPI3/SACCH
-Took message from ACCH queue: L2 header size 8, L3 size 15, SAP 0x1000000, 0/0, Link 0x43
-Message: [L2]> 00 00 0f 3f 0d 0b 02 43 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+Took message from ACCH queue: L2 header size 5, L3 size 18, SAP 0x1000000, 0/0, Link 0x43
+Message: [L2]> 00 00 0f 3f 01 [L3]> 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 Success.
-- 
1.7.9.5





More information about the OpenBSC mailing list