gprs_ns2: truncate the NS_STATUS to the MTU
A NS Status can contain the original NS message which might result
in a NS PDU which exceeds the MTU of the NS-VC.
Truncate the original message to the maximum possible.
Based on truncate BSSGP status message.
Related: OS#4889
Change-Id: I35d8f8bf0eae890f4db56423da0b23b638d24311
diff --git a/src/gb/gprs_ns2_message.c b/src/gb/gprs_ns2_message.c
index bfb8781..7f52c4b 100644
--- a/src/gb/gprs_ns2_message.c
+++ b/src/gb/gprs_ns2_message.c
@@ -432,6 +432,7 @@
struct msgb *msg = ns2_msgb_alloc();
struct gprs_ns_hdr *nsh;
uint16_t nsvci = osmo_htons(nsvc->nsvci);
+ unsigned int orig_len, max_orig_len;
log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
log_set_context(LOG_CTX_GB_NSVC, nsvc);
@@ -461,8 +462,12 @@
case NS_CAUSE_PROTO_ERR_UNSPEC:
case NS_CAUSE_INVAL_ESSENT_IE:
case NS_CAUSE_MISSING_ESSENT_IE:
- msgb_tvlv_put(msg, NS_IE_PDU, msgb_l2len(orig_msg),
- orig_msg->l2h);
+ /* ensure the PDU doesn't exceed the MTU */
+ orig_len = msgb_l2len(orig_msg);
+ max_orig_len = msgb_length(msg) + TVLV_GROSS_LEN(orig_len);
+ if (max_orig_len > nsvc->bind->mtu)
+ orig_len -= max_orig_len - nsvc->bind->mtu;
+ msgb_tvlv_put(msg, NS_IE_PDU, orig_len, orig_msg->l2h);
break;
default:
break;