[PATCH] BSSGP: prevent divide-by-zero in flow control

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

Harald Welte laforge at gnumonks.org
Sat Jun 22 07:44:00 UTC 2013


If the BTS tells us to not send any data at all anymore (bucket leak
rate of 0 bits per second), then we should respect this and not run into
a divide-by-zero.  However, as this indicates complete overload, we
print a log message to that regard.
---
 src/gb/gprs_bssgp.c | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c
index e41c7ef..5ef1887 100644
--- a/src/gb/gprs_bssgp.c
+++ b/src/gb/gprs_bssgp.c
@@ -590,16 +590,20 @@ static int fc_queue_timer_cfg(struct bssgp_flow_control *fc)
 	fcqe = llist_entry(&fc->queue.next, struct bssgp_fc_queue_element,
 			   list);
 
-	/* Calculate the point in time at which we will have leaked
-	 * a sufficient number of bytes from the bucket to transmit
-	 * the first PDU in the queue */
-	msecs = (fcqe->llc_pdu_len * 1000) / fc->bucket_leak_rate;
-	/* FIXME: add that time to fc->time_last_pdu and subtract it from
-	 * current time */
-
-	fc->timer.data = fc;
-	fc->timer.cb = &fc_timer_cb;
-	osmo_timer_schedule(&fc->timer, msecs / 1000, (msecs % 1000) * 1000);
+	if (fc->bucket_leak_rate != 0) {
+		/* Calculate the point in time at which we will have leaked
+		 * a sufficient number of bytes from the bucket to transmit
+		 * the first PDU in the queue */
+		msecs = (fcqe->llc_pdu_len * 1000) / fc->bucket_leak_rate;
+		/* FIXME: add that time to fc->time_last_pdu and subtract it from
+		 * current time */
+		fc->timer.data = fc;
+		fc->timer.cb = &fc_timer_cb;
+		osmo_timer_schedule(&fc->timer, msecs / 1000, (msecs % 1000) * 1000);
+	} else {
+		/* If the PCU is telling us to not send any more data at all,
+		* there's no point starting a timer. */
+	}
 
 	return 0;
 }
@@ -742,6 +746,8 @@ int bssgp_fc_ms_init(struct bssgp_flow_control *fc_ms, uint16_t bvci,
 static int bssgp_rx_fc_bvc(struct msgb *msg, struct tlv_parsed *tp,
 			   struct bssgp_bvc_ctx *bctx)
 {
+	uint32_t old_leak_rate = bctx->fc->bucket_leak_rate;
+	uint32_t old_r_def_ms = bctx->r_default_ms;
 
 	DEBUGP(DBSSGP, "BSSGP BVCI=%u Rx Flow Control BVC\n",
 		bctx->bvci);
@@ -769,6 +775,23 @@ static int bssgp_rx_fc_bvc(struct msgb *msg, struct tlv_parsed *tp,
 	bctx->r_default_ms = 100 *
 		ntohs(*(uint16_t *)TLVP_VAL(tp, BSSGP_IE_R_DEFAULT_MS)) / 8;
 
+	if (old_leak_rate != 0 && bctx->fc->bucket_leak_rate == 0)
+		LOGP(DBSSGP, LOGL_NOTICE, "BSS instructs us to bucket leak "
+			"rate of 0, stopping all DL GPRS!\n");
+	else if (old_leak_rate == 0 && bctx->fc->bucket_leak_rate != 0)
+		LOGP(DBSSGP, LOGL_NOTICE, "BSS instructs us to bucket leak "
+			"rate of != 0, restarting all DL GPRS!\n");
+
+	if (old_r_def_ms != 0 && bctx->r_default_ms == 0)
+		LOGP(DBSSGP, LOGL_NOTICE, "BSS instructs us to MS default "
+			"bucket leak rate of 0, stopping DL GPRS!\n");
+	else if (old_r_def_ms == 0 && bctx->r_default_ms != 0)
+		LOGP(DBSSGP, LOGL_NOTICE, "BSS instructs us to MS default "
+			"bucket leak rate != 0, restarting DL GPRS!\n");
+
+	/* reconfigure the timer for flow control based on new values */
+	fc_queue_timer_cfg(bctx->fc);
+
 	/* Send FLOW_CONTROL_BVC_ACK */
 	return bssgp_tx_fc_bvc_ack(msgb_nsei(msg), *TLVP_VAL(tp, BSSGP_IE_TAG),
 				   msgb_bvci(msg));
-- 
1.8.3.1


--wac7ysb48OaltWcw--




More information about the OpenBSC mailing list