<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25182">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">fix: handle NULL return of as_dl_tbf() and as_ul_tbf()<br><br>Go through all callers of as_dl_tbf() and as_ul_tbf(), and make sure<br>they can handle the possible NULL return value.<br><br>OS#5205 reports a NULL deref crash of osmo-pcu at pdch.cpp:525. The<br>immediate cause is that as_dl_tbf() may well return NULL, which this<br>caller does not handle and instead dereferences immediately.<br>This is a code path that apparently assumes that a DL-TBF should always<br>be present. The higher level cause for the NULL DL-TBF has not been<br>identified.<br><br>Related: OS#5205 SYS#5561<br>Change-Id: I8ce21be6836549b47a606c00b793d6f005964c5c<br>---<br>M src/bts.cpp<br>M src/gprs_ms.c<br>M src/gprs_rlcmac_sched.cpp<br>M src/gprs_rlcmac_ts_alloc.cpp<br>M src/pdch.cpp<br>M src/tbf.cpp<br>6 files changed, 57 insertions(+), 37 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/bts.cpp b/src/bts.cpp</span><br><span>index a91fe8d..b5fdfee 100644</span><br><span>--- a/src/bts.cpp</span><br><span>+++ b/src/bts.cpp</span><br><span>@@ -1162,22 +1162,21 @@</span><br><span> {</span><br><span>       struct gprs_rlcmac_pdch *pdch = &bts->trx[trx_no].pdch[ts];</span><br><span>   struct pdch_ulc_node *poll = pdch_ulc_get_node(pdch->ulc, fn);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gprs_rlcmac_ul_tbf *tbf;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(poll->tbf_poll.poll_tbf);</span><br><span>   if (!poll || poll->type !=PDCH_ULC_NODE_TBF_POLL ||</span><br><span>           poll->tbf_poll.poll_tbf->direction != GPRS_RLCMAC_UL_TBF)</span><br><span>          LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to "</span><br><span>                   "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n",</span><br><span>                  p, ta, trx_no, ts, fn);</span><br><span style="color: hsl(0, 100%, 40%);">-    else {</span><br><span style="color: hsl(0, 100%, 40%);">-          tbf = as_ul_tbf(poll->tbf_poll.poll_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  else if (ul_tbf) {</span><br><span>           /* we need to distinguish TA information provided by L1</span><br><span>               * from PH-DATA-IND and PHY-RA-IND so that we can properly</span><br><span>            * update TA for given TBF</span><br><span>            */</span><br><span>          if (is_rach)</span><br><span style="color: hsl(0, 100%, 40%);">-                    set_tbf_ta(tbf, (uint8_t)ta);</span><br><span style="color: hsl(120, 100%, 40%);">+                 set_tbf_ta(ul_tbf, (uint8_t)ta);</span><br><span>             else</span><br><span style="color: hsl(0, 100%, 40%);">-                    update_tbf_ta(tbf, ta);</span><br><span style="color: hsl(120, 100%, 40%);">+                       update_tbf_ta(ul_tbf, ta);</span><br><span> </span><br><span>       }</span><br><span> }</span><br><span>diff --git a/src/gprs_ms.c b/src/gprs_ms.c</span><br><span>index 0d6be4d..b9d130a 100644</span><br><span>--- a/src/gprs_ms.c</span><br><span>+++ b/src/gprs_ms.c</span><br><span>@@ -335,9 +335,13 @@</span><br><span> </span><br><span> void ms_attach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   if (tbf_direction(tbf) == GPRS_RLCMAC_DL_TBF)</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+   /* cannot be both DL and UL */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(!(dl_tbf && ul_tbf));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dl_tbf)</span><br><span>          ms_attach_dl_tbf(ms, as_dl_tbf(tbf));</span><br><span style="color: hsl(0, 100%, 40%);">-   else</span><br><span style="color: hsl(120, 100%, 40%);">+  if (ul_tbf)</span><br><span>          ms_attach_ul_tbf(ms, as_ul_tbf(tbf));</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp</span><br><span>index 2adf1f3..b99ef9e 100644</span><br><span>--- a/src/gprs_rlcmac_sched.cpp</span><br><span>+++ b/src/gprs_rlcmac_sched.cpp</span><br><span>@@ -50,7 +50,8 @@</span><br><span> </span><br><span>      llist_for_each_entry(pos, &pdch->trx->ul_tbfs, list) {</span><br><span>             ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);</span><br><span style="color: hsl(0, 100%, 40%);">-            OSMO_ASSERT(ul_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!ul_tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</span><br><span>            /* this trx, this ts */</span><br><span>              if (!ul_tbf->is_control_ts(pdch->ts_no))</span><br><span>                       continue;</span><br><span>@@ -69,7 +70,8 @@</span><br><span>        }</span><br><span>    llist_for_each_entry(pos, &pdch->trx->dl_tbfs, list) {</span><br><span>             dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);</span><br><span style="color: hsl(0, 100%, 40%);">-            OSMO_ASSERT(dl_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!dl_tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</span><br><span>            /* this trx, this ts */</span><br><span>              if (!dl_tbf->is_control_ts(pdch->ts_no))</span><br><span>                       continue;</span><br><span>@@ -459,6 +461,7 @@</span><br><span>                      "single block allocation at FN=%d\n", fn, block_nr, sba->fn);</span><br><span>   /* else, check uplink resource for polling */</span><br><span>        } else if ((poll_tbf = pdch_ulc_get_tbf_poll(pdch->ulc, poll_fn))) {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span>           LOGPDCH(pdch, DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: FN=%d "</span><br><span>                    "block_nr=%d scheduling free USF for polling at FN=%d of %s\n",</span><br><span>                    fn, block_nr, poll_fn, tbf_name(poll_tbf));</span><br><span>@@ -466,8 +469,9 @@</span><br><span>             * let's set its USF in the DL msg. This is not really needed,</span><br><span>            * but it helps understand better the flow when looking at</span><br><span>            * pcaps. */</span><br><span style="color: hsl(0, 100%, 40%);">-            if (poll_tbf->direction == GPRS_RLCMAC_UL_TBF && as_ul_tbf(poll_tbf)->m_usf[ts] != USF_INVALID)</span><br><span style="color: hsl(0, 100%, 40%);">-                   usf_tbf = as_ul_tbf(poll_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+                ul_tbf = as_ul_tbf(poll_tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (ul_tbf && poll_tbf->direction == GPRS_RLCMAC_UL_TBF && ul_tbf->m_usf[ts] != USF_INVALID)</span><br><span style="color: hsl(120, 100%, 40%);">+                    usf_tbf = ul_tbf;</span><br><span>    /* else, search for uplink tbf */</span><br><span>    } else if ((usf_tbf = sched_select_uplink(pdch, require_gprs_only))) {</span><br><span>               LOGPDCH(pdch, DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: FN=%d "</span><br><span>diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>index 5ccbb9f..88dc024 100644</span><br><span>--- a/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>+++ b/src/gprs_rlcmac_ts_alloc.cpp</span><br><span>@@ -357,6 +357,8 @@</span><br><span>         struct GprsMs *ms = tbf_->ms();</span><br><span>   const gprs_rlcmac_tbf *tbf = tbf_;</span><br><span>   gprs_rlcmac_trx *trx = ms_current_trx(ms);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span> </span><br><span>       LOGPAL(tbf, "A", single, use_trx, LOGL_DEBUG, "Alloc start\n");</span><br><span> </span><br><span>@@ -406,12 +408,15 @@</span><br><span> </span><br><span>  /* The allocation will be successful, so the system state and tbf_/ms_</span><br><span>        * may be modified from now on. */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (tbf->direction == GPRS_RLCMAC_UL_TBF) {</span><br><span style="color: hsl(0, 100%, 40%);">-          struct gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf_);</span><br><span style="color: hsl(120, 100%, 40%);">+  dl_tbf = as_dl_tbf(tbf_);</span><br><span style="color: hsl(120, 100%, 40%);">+     ul_tbf = as_ul_tbf(tbf_);</span><br><span style="color: hsl(120, 100%, 40%);">+     /* cannot be both DL and UL */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(!(dl_tbf && ul_tbf));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ul_tbf) {</span><br><span>                LOGPSL(tbf, LOGL_DEBUG, "Assign uplink TS=%d TFI=%d USF=%d\n", ts, tfi, usf);</span><br><span>              assign_uplink_tbf_usf(pdch, ul_tbf, tfi, usf);</span><br><span style="color: hsl(0, 100%, 40%);">-  } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                struct gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf_);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dl_tbf) {</span><br><span>                LOGPSL(tbf, LOGL_DEBUG, "Assign downlink TS=%d TFI=%d\n", ts, tfi);</span><br><span>                assign_dlink_tbf(pdch, dl_tbf, tfi);</span><br><span>         }</span><br><span>@@ -878,6 +883,8 @@</span><br><span>      struct GprsMs *ms = tbf_->ms();</span><br><span>   const gprs_rlcmac_tbf *tbf = tbf_;</span><br><span>   gprs_rlcmac_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gprs_rlcmac_dl_tbf *dl_tbf;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gprs_rlcmac_ul_tbf *ul_tbf;</span><br><span> </span><br><span>       LOGPAL(tbf, "B", single, use_trx, LOGL_DEBUG, "Alloc start\n");</span><br><span> </span><br><span>@@ -960,10 +967,14 @@</span><br><span>      tbf_->first_common_ts = first_common_ts;</span><br><span>  tbf_->first_ts = first_ts;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       if (tbf->direction == GPRS_RLCMAC_DL_TBF)</span><br><span style="color: hsl(0, 100%, 40%);">-            assign_dl_tbf_slots(as_dl_tbf(tbf_), trx, dl_slots, tfi);</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            assign_ul_tbf_slots(as_ul_tbf(tbf_), trx, ul_slots, tfi, usf);</span><br><span style="color: hsl(120, 100%, 40%);">+        dl_tbf = as_dl_tbf(tbf_);</span><br><span style="color: hsl(120, 100%, 40%);">+     ul_tbf = as_ul_tbf(tbf_);</span><br><span style="color: hsl(120, 100%, 40%);">+     /* cannot be both DL and UL */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(!(dl_tbf && ul_tbf));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dl_tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+           assign_dl_tbf_slots(dl_tbf, trx, dl_slots, tfi);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ul_tbf)</span><br><span style="color: hsl(120, 100%, 40%);">+           assign_ul_tbf_slots(ul_tbf, trx, ul_slots, tfi, usf);</span><br><span> </span><br><span>    bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_B);</span><br><span> </span><br><span>diff --git a/src/pdch.cpp b/src/pdch.cpp</span><br><span>index 2ec40ce..f955444 100644</span><br><span>--- a/src/pdch.cpp</span><br><span>+++ b/src/pdch.cpp</span><br><span>@@ -452,7 +452,7 @@</span><br><span>               return;</span><br><span>      }</span><br><span>    tbf = as_dl_tbf(poll->tbf_poll.poll_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (tbf->tfi() != tfi) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!tbf || tbf->tfi() != tfi) {</span><br><span>          LOGPTBFDL(tbf, LOGL_NOTICE,</span><br><span>                    "PACKET DOWNLINK ACK with wrong TFI=%d, ignoring!\n", tfi);</span><br><span>              return;</span><br><span>@@ -522,7 +522,7 @@</span><br><span>                return;</span><br><span>      }</span><br><span>    tbf = as_dl_tbf(poll->tbf_poll.poll_tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (tbf->tfi() != tfi) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!tbf || tbf->tfi() != tfi) {</span><br><span>          LOGPDCH(this, DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with "</span><br><span>                      "wrong TFI=%d, ignoring!\n", tfi);</span><br><span>                 return;</span><br><span>@@ -1063,8 +1063,8 @@</span><br><span>                      m_tbfs[tbf->direction][tbf->tfi()]->name());</span><br><span> </span><br><span>    m_num_tbfs[tbf->direction] += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (tbf->direction == GPRS_RLCMAC_UL_TBF) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ul_tbf) {</span><br><span>                m_assigned_usf |= 1 << ul_tbf->m_usf[ts_no];</span><br><span>        }</span><br><span>    m_assigned_tfi[tbf->direction] |= 1UL << tbf->tfi();</span><br><span>@@ -1083,8 +1083,8 @@</span><br><span>     OSMO_ASSERT(m_num_tbfs[tbf->direction] > 0);</span><br><span> </span><br><span>       m_num_tbfs[tbf->direction] -= 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (tbf->direction == GPRS_RLCMAC_UL_TBF) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+      ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ul_tbf) {</span><br><span>                m_assigned_usf &= ~(1 << ul_tbf->m_usf[ts_no]);</span><br><span>         }</span><br><span>    m_assigned_tfi[tbf->direction] &= ~(1UL << tbf->tfi());</span><br><span>diff --git a/src/tbf.cpp b/src/tbf.cpp</span><br><span>index fcad879..e9e584f 100644</span><br><span>--- a/src/tbf.cpp</span><br><span>+++ b/src/tbf.cpp</span><br><span>@@ -270,15 +270,18 @@</span><br><span> void tbf_free(struct gprs_rlcmac_tbf *tbf)</span><br><span> {</span><br><span>  /* update counters */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (tbf->direction == GPRS_RLCMAC_UL_TBF) {</span><br><span style="color: hsl(0, 100%, 40%);">-          gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  /* cannot be both DL and UL */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(!(dl_tbf && ul_tbf));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ul_tbf) {</span><br><span>                bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_FREED);</span><br><span>          if (tbf->state_is(TBF_ST_FLOW))</span><br><span>                   bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ABORTED);</span><br><span>                rate_ctr_group_free(ul_tbf->m_ul_egprs_ctrs);</span><br><span>             rate_ctr_group_free(ul_tbf->m_ul_gprs_ctrs);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dl_tbf) {</span><br><span>                if (tbf->is_egprs_enabled()) {</span><br><span>                    rate_ctr_group_free(dl_tbf->m_dl_egprs_ctrs);</span><br><span>             } else {</span><br><span>@@ -291,9 +294,7 @@</span><br><span> </span><br><span>   /* Give final measurement report */</span><br><span>  gprs_rlcmac_rssi_rep(tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (tbf->direction == GPRS_RLCMAC_DL_TBF) {</span><br><span style="color: hsl(0, 100%, 40%);">-          gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+  if (dl_tbf) {</span><br><span>                dl_tbf->abort();</span><br><span>          dl_tbf->cleanup();</span><br><span>        }</span><br><span>@@ -623,7 +624,10 @@</span><br><span> void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_fn, enum pdch_ulc_tbf_poll_reason reason)</span><br><span> {</span><br><span>   uint16_t pgroup;</span><br><span style="color: hsl(120, 100%, 40%);">+      gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);</span><br><span>        gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* cannot be both DL and UL */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(!(dl_tbf && ul_tbf));</span><br><span> </span><br><span>        LOGPTBF(this, LOGL_NOTICE, "poll timeout for FN=%d, TS=%d (curr FN %d)\n",</span><br><span>                 poll_fn, pdch->ts_no, bts_current_frame_number(bts));</span><br><span>@@ -690,9 +694,7 @@</span><br><span>               /* Timeout waiting for CTRL ACK acking Pkt Cell Change Continue */</span><br><span>           osmo_fsm_inst_dispatch(m_ms->nacc->fi, NACC_EV_TIMEOUT_CELL_CHG_CONTINUE, NULL);</span><br><span>               return;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (direction == GPRS_RLCMAC_DL_TBF) {</span><br><span style="color: hsl(0, 100%, 40%);">-           gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (dl_tbf) {</span><br><span>                 if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {</span><br><span>                       LOGPTBF(this, LOGL_NOTICE,</span><br><span>                           "Timeout for polling PACKET DOWNLINK ACK: %s\n",</span><br><span>@@ -784,6 +786,7 @@</span><br><span> void gprs_rlcmac_tbf::handle_timeout()</span><br><span> {</span><br><span>      int current_fn = bts_current_frame_number(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+       gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);</span><br><span> </span><br><span>    LOGPTBF(this, LOGL_DEBUG, "timer 0 expired. cur_fn=%d\n", current_fn);</span><br><span> </span><br><span>@@ -798,8 +801,7 @@</span><br><span>   }</span><br><span> </span><br><span>        /* Finish waiting after IMM.ASS confirm timer for CCCH assignment (see timer X2002) */</span><br><span style="color: hsl(0, 100%, 40%);">-  if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {</span><br><span style="color: hsl(0, 100%, 40%);">-           gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dl_tbf && (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {</span><br><span>              dl_tbf->m_wait_confirm = 0;</span><br><span>               if (dl_tbf->state_is(TBF_ST_ASSIGN)) {</span><br><span>                    tbf_assign_control_ts(dl_tbf);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/25182">change 25182</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-pcu/+/25182"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I8ce21be6836549b47a606c00b793d6f005964c5c </div>
<div style="display:none"> Gerrit-Change-Number: 25182 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>