aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2021-02-02 19:54:10 +0100
committerHarald Welte <laforge@osmocom.org>2021-02-08 18:36:21 +0100
commit93740619afd785cc23c129f464e38794bab46061 (patch)
tree1d3edc11b07fea03c5aeb7f25e9a7fa8fee3c973
parentb339cbb3efc8eb4fc69785588f1d1686d8fabe68 (diff)
ns2: Don't queue Q.933 LMI messages; only store most recent ones
There's not really any point in storing multiple LMI messages, and then transmitting them in inverse order, as the existing code does. Instead, we shall store only the last (failed) LMI message and try to transmit that at highest priority, before any NS messages in the actual queue. Change-Id: I5407a76a34d7e687966fe1a915febf3a87256593
-rw-r--r--src/gb/gprs_ns2_fr.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c
index 78abddc0..cae03eed 100644
--- a/src/gb/gprs_ns2_fr.c
+++ b/src/gb/gprs_ns2_fr.c
@@ -105,7 +105,9 @@ struct priv_bind {
struct {
/* file-descriptor for AF_PACKET socket */
struct osmo_fd ofd;
- /* list of msgb (backlog) */
+ /* LMI bucket (we only store the last LMI message, no need to queue */
+ struct msgb *lmi_msg;
+ /* list of NS msgb (backlog) */
struct llist_head list;
/* timer to trigger next attempt of AF_PACKET write */
struct osmo_timer_list timer;
@@ -173,6 +175,7 @@ static void free_bind(struct gprs_ns2_vc_bind *bind)
llist_for_each_entry_safe(msg, msg2, &priv->backlog.list, list) {
msgb_free(msg);
}
+ msgb_free(priv->backlog.lmi_msg);
osmo_fr_link_free(priv->link);
osmo_fd_close(&priv->backlog.ofd);
@@ -357,6 +360,7 @@ static void enqueue_at_tail(struct gprs_ns2_vc_bind *bind, struct msgb *msg)
/* enqueue to backlog (LMI, signaling) or drop (userdata msg) */
static int backlog_enqueue_or_free(struct gprs_ns2_vc_bind *bind, struct msgb *msg)
{
+ struct priv_bind *priv = bind->priv;
uint8_t dlci = msg->data[0];
uint8_t ns_pdu_type;
uint16_t bvci;
@@ -367,8 +371,9 @@ static int backlog_enqueue_or_free(struct gprs_ns2_vc_bind *bind, struct msgb *m
/* we want to enqueue only Q.933 LMI traffic or NS signaling; NOT user traffic */
switch (dlci) {
case LMI_Q933A_DLCI:
- /* enqueue Q.933 LMI at head of queue */
- enqueue_at_head(bind, msg);
+ /* always store only the last LMI message in the lmi_msg bucket */
+ msgb_free(priv->backlog.lmi_msg);
+ priv->backlog.lmi_msg = msg;
return 0;
default:
if (msgb_length(msg) < 3)
@@ -405,6 +410,15 @@ static void fr_backlog_timer_cb(void *data)
struct priv_bind *priv = bind->priv;
int i, rc;
+ /* first try to get rid of the LMI message, if any */
+ if (priv->backlog.lmi_msg) {
+ rc = fr_netif_write_one(bind, priv->backlog.lmi_msg);
+ if (rc < 0)
+ goto restart_timer;
+ /* fr_netif_write_one() has just free'd it */
+ priv->backlog.lmi_msg = NULL;
+ }
+
/* attempt to send up to 10 messages in every timer */
for (i = 0; i < 10; i++) {
struct msgb *msg = msgb_dequeue(&priv->backlog.list);
@@ -420,6 +434,7 @@ static void fr_backlog_timer_cb(void *data)
osmo_stat_item_dec(bind->statg->items[NS2_BIND_STAT_BACKLOG_LEN], 1);
}
+restart_timer:
/* re-start timer if we still have data in the queue */
if (!llist_empty(&priv->backlog.list))
osmo_timer_schedule(&priv->backlog.timer, 0, priv->backlog.retry_us);