<p>Pau Espin Pedrol <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/10486">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gbproxy: Add new VTY-managed timer: link-list clean-stale-timer<br><br>This timer allows periodically cleaning up stale links in link-list of<br>each gbproxy_peer. Previous to this patch, this kind of cleanup<br>(gbproxy_remove_stale_link_infos) was being done only as a consequence<br>of external events being triggered, such as a message from that peer<br>being received.<br>It was found in a production network agreggating several BSS that some<br>of them were offline for a longtime but gbproxy was still caching big<br>amounts of really old link_info for the NSEI assigned to those BSS,<br>because since they were probably turned off abruptely, no new messages<br>were received from it which would trigger the cleanup.<br>As a consequence, it has been observed that a timer to periodically<br>clean up old entries (link-list max-age) is requird in case w don't<br>receive messages from that NSEI periodically.<br><br>Related: SYS#4431<br>Change-Id: Ic777016f6d4f0e30fb736484774ca46878f17b7a<br>---<br>M include/osmocom/sgsn/gb_proxy.h<br>M src/gprs/gb_proxy_peer.c<br>M src/gprs/gb_proxy_vty.c<br>3 files changed, 67 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h</span><br><span>index 16082fc..7e2ae42 100644</span><br><span>--- a/include/osmocom/sgsn/gb_proxy.h</span><br><span>+++ b/include/osmocom/sgsn/gb_proxy.h</span><br><span>@@ -105,6 +105,8 @@</span><br><span>      struct osmo_plmn_id core_plmn;</span><br><span>       uint8_t* core_apn;</span><br><span>   size_t core_apn_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Frequency (sec) at which timer to clean stale links is fired (0 disabled) */</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int clean_stale_timer_freq;</span><br><span>         /* If !0, Max age to consider a struct gbproxy_link_info as stale */</span><br><span>         int tlli_max_age;</span><br><span>    /* If !0, Max len of gbproxy_peer->list (list of struct gbproxy_link_info) */</span><br><span>@@ -151,6 +153,9 @@</span><br><span>       struct rate_ctr_group *ctrg;</span><br><span> </span><br><span>     struct gbproxy_patch_state patch_state;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Fired periodically to clean up stale links from list */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_timer_list clean_stale_timer;</span><br><span> };</span><br><span> </span><br><span> struct gbproxy_tlli_state {</span><br><span>diff --git a/src/gprs/gb_proxy_peer.c b/src/gprs/gb_proxy_peer.c</span><br><span>index f2cdd93..8e28fc4 100644</span><br><span>--- a/src/gprs/gb_proxy_peer.c</span><br><span>+++ b/src/gprs/gb_proxy_peer.c</span><br><span>@@ -167,6 +167,19 @@</span><br><span>       return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void clean_stale_timer_cb(void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        time_t now;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct timespec ts = {0,};</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gbproxy_peer *peer = (struct gbproxy_peer *) data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_clock_gettime(CLOCK_MONOTONIC, &ts);</span><br><span style="color: hsl(120, 100%, 40%);">+ now = ts.tv_sec;</span><br><span style="color: hsl(120, 100%, 40%);">+      gbproxy_remove_stale_link_infos(peer, now);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (peer->cfg->clean_stale_timer_freq != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_timer_schedule(&peer->clean_stale_timer,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  peer->cfg->clean_stale_timer_freq, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci)</span><br><span> {</span><br><span>@@ -188,13 +201,18 @@</span><br><span> </span><br><span>   INIT_LLIST_HEAD(&peer->patch_state.logical_links);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_setup(&peer->clean_stale_timer, clean_stale_timer_cb, peer);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (peer->cfg->clean_stale_timer_freq != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_timer_schedule(&peer->clean_stale_timer,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  peer->cfg->clean_stale_timer_freq, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       return peer;</span><br><span> }</span><br><span> </span><br><span> void gbproxy_peer_free(struct gbproxy_peer *peer)</span><br><span> {</span><br><span>      llist_del(&peer->list);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_timer_del(&peer->clean_stale_timer);</span><br><span>     gbproxy_delete_link_infos(peer);</span><br><span> </span><br><span>         rate_ctr_group_free(peer->ctrg);</span><br><span>@@ -220,4 +238,3 @@</span><br><span> </span><br><span>        return counter;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/src/gprs/gb_proxy_vty.c b/src/gprs/gb_proxy_vty.c</span><br><span>index d743355..52c39fd 100644</span><br><span>--- a/src/gprs/gb_proxy_vty.c</span><br><span>+++ b/src/gprs/gb_proxy_vty.c</span><br><span>@@ -120,6 +120,9 @@</span><br><span>          vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei,</span><br><span>                       VTY_NEWLINE);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     if (g_cfg->clean_stale_timer_freq > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          vty_out(vty, " link-list clean-stale-timer %u%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                   g_cfg->clean_stale_timer_freq, VTY_NEWLINE);</span><br><span>      if (g_cfg->tlli_max_age > 0)</span><br><span>           vty_out(vty, " link-list max-age %d%s",</span><br><span>                    g_cfg->tlli_max_age, VTY_NEWLINE);</span><br><span>@@ -407,6 +410,44 @@</span><br><span> </span><br><span> #define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n"</span><br><span> #define GBPROXY_LINK_STR "Set TLLI parameters\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define GBPROXY_CLEAN_STALE_TIMER_STR "Periodic timer to clean stale links\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_gbproxy_link_list_clean_stale_timer,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_gbproxy_link_list_clean_stale_timer_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "link-list clean-stale-timer <1-999999>",</span><br><span style="color: hsl(120, 100%, 40%);">+      GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR</span><br><span style="color: hsl(120, 100%, 40%);">+      "Frequency at which the periodic timer is fired (in seconds)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gbproxy_peer *peer;</span><br><span style="color: hsl(120, 100%, 40%);">+    g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Re-schedule running timers soon in case prev frequency was really big</span><br><span style="color: hsl(120, 100%, 40%);">+         and new frequency is desired to be lower. After initial run, periodic</span><br><span style="color: hsl(120, 100%, 40%);">+         time is used. Use random() to avoid firing timers for all peers at</span><br><span style="color: hsl(120, 100%, 40%);">+    the same time */</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each_entry(peer, &g_cfg->bts_peers, list)</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_timer_schedule(&peer->clean_stale_timer,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  random() % 5, random() % 1000000);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_gbproxy_link_list_no_clean_stale_timer_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "no link-list clean-stale-timer",</span><br><span style="color: hsl(120, 100%, 40%);">+      NO_STR GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gbproxy_peer *peer;</span><br><span style="color: hsl(120, 100%, 40%);">+    g_cfg->clean_stale_timer_freq = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       llist_for_each_entry(peer, &g_cfg->bts_peers, list)</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_timer_del(&peer->clean_stale_timer);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define GBPROXY_MAX_AGE_STR "Limit maximum age\n"</span><br><span> </span><br><span> DEFUN(cfg_gbproxy_link_list_max_age,</span><br><span>@@ -846,6 +887,7 @@</span><br><span>    install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd);</span><br><span>  install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);</span><br><span>     install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_clean_stale_timer_cmd);</span><br><span>     install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd);</span><br><span>       install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd);</span><br><span>       install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd);</span><br><span>@@ -857,6 +899,7 @@</span><br><span>       install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd);</span><br><span>       install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);</span><br><span>  install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+  install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_clean_stale_timer_cmd);</span><br><span>  install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);</span><br><span>    install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);</span><br><span>    install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_max_len_cmd);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10486">change 10486</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/10486"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-sgsn </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ic777016f6d4f0e30fb736484774ca46878f17b7a </div>
<div style="display:none"> Gerrit-Change-Number: 10486 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Stefan Sperling <ssperling@sysmocom.de> </div>