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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gbproxy: Add SGSN NRI configuration<br><br>In order to support SGSN pooling we need to configure the various NRI<br>parameters such as the bitlen, NULL NRI, and which NRIs are assigned to<br>which SGSN.<br><br>Related: OS#4890, OS#4472<br>Change-Id: Id67592aa7712e5e04e7264b2fb8f26d57eb7e69e<br>---<br>A doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg<br>M doc/examples/osmo-gbproxy/osmo-gbproxy.cfg<br>M include/osmocom/sgsn/gb_proxy.h<br>M src/gbproxy/gb_proxy.c<br>M src/gbproxy/gb_proxy_peer.c<br>M src/gbproxy/gb_proxy_vty.c<br>M tests/Makefile.am<br>A tests/osmo-gbproxy-pool_test-nodes.vty<br>A tests/osmo-gbproxy_test-nodes.vty<br>R tests/osmo-sgsn_test-nodes.vty<br>10 files changed, 558 insertions(+), 21 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg</span><br><span>new file mode 100644</span><br><span>index 0000000..df765c0</span><br><span>--- /dev/null</span><br><span>+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg</span><br><span>@@ -0,0 +1,38 @@</span><br><span style="color: hsl(120, 100%, 40%);">+!</span><br><span style="color: hsl(120, 100%, 40%);">+! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty</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%);">+line vty</span><br><span style="color: hsl(120, 100%, 40%);">+ no login</span><br><span style="color: hsl(120, 100%, 40%);">+!</span><br><span style="color: hsl(120, 100%, 40%);">+gbproxy</span><br><span style="color: hsl(120, 100%, 40%);">+  nri bitlen 4</span><br><span style="color: hsl(120, 100%, 40%);">+  nri null add 0 4</span><br><span style="color: hsl(120, 100%, 40%);">+sgsn nsei 101</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 1</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 11</span><br><span style="color: hsl(120, 100%, 40%);">+sgsn nsei 102</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 2</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 12</span><br><span style="color: hsl(120, 100%, 40%);">+ns</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 101 nsvci 101</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 101 remote-role sgsn</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 101 encapsulation udp</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 101 remote-ip 192.168.100.239</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 101 remote-port 7777</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 102 nsvci 102</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 102 remote-role sgsn</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 102 encapsulation udp</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 102 remote-ip 192.168.100.239</span><br><span style="color: hsl(120, 100%, 40%);">+ nse 102 remote-port 7778</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-block 3</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-block-retries 3</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-reset 3</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-reset-retries 3</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-test 30</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-alive 3</span><br><span style="color: hsl(120, 100%, 40%);">+ timer tns-alive-retries 10</span><br><span style="color: hsl(120, 100%, 40%);">+ encapsulation framerelay-gre enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+ encapsulation framerelay-gre local-ip 0.0.0.0</span><br><span style="color: hsl(120, 100%, 40%);">+ encapsulation udp local-ip 127.0.0.100</span><br><span style="color: hsl(120, 100%, 40%);">+ encapsulation udp local-port 23000</span><br><span>diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg</span><br><span>index 29f698f..5cabc6d 100644</span><br><span>--- a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg</span><br><span>+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg</span><br><span>@@ -6,7 +6,7 @@</span><br><span>  no login</span><br><span> !</span><br><span> gbproxy</span><br><span style="color: hsl(0, 100%, 40%);">- sgsn nsei 101</span><br><span style="color: hsl(120, 100%, 40%);">+sgsn nsei 101</span><br><span> ns</span><br><span>  nse 101 nsvci 101</span><br><span>  nse 101 remote-role sgsn</span><br><span>diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h</span><br><span>index 200a539..46decc0 100644</span><br><span>--- a/include/osmocom/sgsn/gb_proxy.h</span><br><span>+++ b/include/osmocom/sgsn/gb_proxy.h</span><br><span>@@ -7,6 +7,7 @@</span><br><span> #include <osmocom/core/fsm.h></span><br><span> #include <osmocom/core/hashtable.h></span><br><span> #include <osmocom/gsm/gsm23003.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm23236.h></span><br><span> </span><br><span> #include <osmocom/gprs/gprs_ns2.h></span><br><span> #include <osmocom/vty/command.h></span><br><span>@@ -16,6 +17,7 @@</span><br><span> #include <stdbool.h></span><br><span> </span><br><span> #define GBPROXY_INIT_VU_GEN_TX 256</span><br><span style="color: hsl(120, 100%, 40%);">+#define GBPROXY_MAX_NR_SGSN     16</span><br><span> </span><br><span> /* BVCI uses 16 bits */</span><br><span> #define BVC_LOG_CTX_FLAG (1<<17)</span><br><span>@@ -55,9 +57,12 @@</span><br><span>     struct {</span><br><span>             /* percentage of BVC flow control advertised to each SGSN in the pool */</span><br><span>             uint8_t bvc_fc_ratio;</span><br><span style="color: hsl(120, 100%, 40%);">+         /* NRI bitlen and usable NULL-NRI ranges */</span><br><span style="color: hsl(120, 100%, 40%);">+           uint8_t nri_bitlen;</span><br><span style="color: hsl(120, 100%, 40%);">+           struct osmo_nri_ranges *null_nri_ranges;</span><br><span>     } pool;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Linked list of all BSS side Gb peers */</span><br><span style="color: hsl(120, 100%, 40%);">+    /* hash table of all BSS side Gb peers */</span><br><span>    DECLARE_HASHTABLE(bss_nses, 8);</span><br><span> </span><br><span>  /* hash table of all SGSN-side Gb peers */</span><br><span>@@ -66,6 +71,9 @@</span><br><span>       /* hash table of all gbproxy_cell */</span><br><span>         DECLARE_HASHTABLE(cells, 8);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* List of all SGSNs */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct llist_head sgsns;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* Counter */</span><br><span>        struct rate_ctr_group *ctrg;</span><br><span> };</span><br><span>@@ -88,7 +96,7 @@</span><br><span>       struct gbproxy_bvc *bss_bvc;</span><br><span> </span><br><span>     /* pointers to SGSN-side BVC (one for each pool member) */</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_bvc *sgsn_bvc[16];</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gbproxy_bvc *sgsn_bvc[GBPROXY_MAX_NR_SGSN];</span><br><span> };</span><br><span> </span><br><span> /* One BVC inside an NSE */</span><br><span>@@ -133,6 +141,21 @@</span><br><span>   DECLARE_HASHTABLE(bvcs, 10);</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* SGSN configuration such as pool options (only for NSE where sgsn_facing == true) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* linked to gbproxy_config.sgsns */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* The NSE belonging to this SGSN */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gbproxy_nse *nse;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Pool configuration for the sgsn (only valid if sgsn_facing == true) */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              bool allow_attach;</span><br><span style="color: hsl(120, 100%, 40%);">+            struct osmo_nri_ranges *nri_ranges;</span><br><span style="color: hsl(120, 100%, 40%);">+   } pool;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Convenience logging macros for NSE/BVC */</span><br><span> #define LOGPNSE_CAT(NSE, SUBSYS, LEVEL, FMT, ARGS...) \</span><br><span>     LOGP(SUBSYS, LEVEL, "NSE(%05u/%s) " FMT, (NSE)->nsei, \</span><br><span>@@ -152,6 +175,11 @@</span><br><span> #define LOGPCELL(CELL, LEVEL, FMT, ARGS...) \</span><br><span>         LOGPCELL_CAT(CELL, DGPRS, LEVEL, FMT, ## ARGS)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGPSGSN_CAT(SGSN, SUBSYS, LEVEL, FMT, ARGS...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(SUBSYS, LEVEL, "NSE(%05u)-SGSN " FMT, (SGSN)->nse->nsei, ## ARGS)</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGPSGSN(SGSN, LEVEL, FMT, ARGS...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPSGSN_CAT(SGSN, DGPRS, LEVEL, FMT, ## ARGS)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* gb_proxy_vty .c */</span><br><span> </span><br><span> int gbproxy_vty_init(void);</span><br><span>@@ -195,4 +223,11 @@</span><br><span> struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags);</span><br><span> struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* SGSN handling */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif</span><br><span>diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c</span><br><span>index ca1c07c..4b6dc09 100644</span><br><span>--- a/src/gbproxy/gb_proxy.c</span><br><span>+++ b/src/gbproxy/gb_proxy.c</span><br><span>@@ -33,6 +33,7 @@</span><br><span> </span><br><span> #include <osmocom/core/hashtable.h></span><br><span> #include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/select.h></span><br><span> #include <osmocom/core/rate_ctr.h></span><br><span>@@ -1286,9 +1287,13 @@</span><br><span> </span><br><span>      /* by default we advertise 100% of the BSS-side capacity to _each_ SGSN */</span><br><span>   cfg->pool.bvc_fc_ratio = 100;</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg->pool.null_nri_ranges = osmo_nri_ranges_alloc(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         hash_init(cfg->bss_nses);</span><br><span>         hash_init(cfg->sgsn_nses);</span><br><span>        hash_init(cfg->cells);</span><br><span style="color: hsl(120, 100%, 40%);">+     INIT_LLIST_HEAD(&cfg->sgsns);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);</span><br><span>        if (!cfg->ctrg) {</span><br><span>                 LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n");</span><br><span>diff --git a/src/gbproxy/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c</span><br><span>index c38b2f7..863ec50 100644</span><br><span>--- a/src/gbproxy/gb_proxy_peer.c</span><br><span>+++ b/src/gbproxy/gb_proxy_peer.c</span><br><span>@@ -26,6 +26,7 @@</span><br><span> </span><br><span> #include <osmocom/gprs/protocol/gsm_08_18.h></span><br><span> #include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/rate_ctr.h></span><br><span> #include <osmocom/core/stats.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span>@@ -273,7 +274,7 @@</span><br><span>      return nse;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_nse_free(struct gbproxy_nse *nse)</span><br><span style="color: hsl(120, 100%, 40%);">+static void _nse_free(struct gbproxy_nse *nse)</span><br><span> {</span><br><span>      struct gbproxy_bvc *bvc;</span><br><span>     struct hlist_node *tmp;</span><br><span>@@ -291,6 +292,22 @@</span><br><span> </span><br><span>   talloc_free(nse);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+static void _sgsn_free(struct gbproxy_sgsn *sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void gbproxy_nse_free(struct gbproxy_nse *nse)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!nse)</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(nse->cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (nse->sgsn_facing) {</span><br><span style="color: hsl(120, 100%, 40%);">+            struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_nsei(nse->cfg, nse->nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_ASSERT(sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+            _sgsn_free(sgsn);</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%);">+   _nse_free(nse);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags)</span><br><span> {</span><br><span>@@ -325,3 +342,104 @@</span><br><span> </span><br><span>        return nse;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* SGSN */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   sgsn = talloc_zero(tall_sgsn_ctx, struct gbproxy_sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!sgsn)</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        sgsn->nse = gbproxy_nse_alloc(cfg, nsei, true);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!sgsn->nse) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "Could not allocate NSE(%05u) for SGSN\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+               talloc_free(sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</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%);">+   sgsn->pool.allow_attach = true;</span><br><span style="color: hsl(120, 100%, 40%);">+    sgsn->pool.nri_ranges = osmo_nri_ranges_alloc(sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     llist_add_tail(&sgsn->list, &cfg->sgsns);</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Created\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      return sgsn;</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%);">+/* Only free gbproxy_sgsn, sgsn can't be NULL */</span><br><span style="color: hsl(120, 100%, 40%);">+static void _sgsn_free(struct gbproxy_sgsn *sgsn) {</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gbproxy_config *cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(sgsn->nse);</span><br><span style="color: hsl(120, 100%, 40%);">+    cfg = sgsn->nse->cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Destroying\n");</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_del(&sgsn->list);</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(sgsn);</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%);">+void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sgsn)</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(sgsn->nse)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   _nse_free(sgsn->nse);</span><br><span style="color: hsl(120, 100%, 40%);">+      _sgsn_free(sgsn);</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_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each_entry(sgsn, &cfg->sgsns, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (sgsn->nse->nsei == nsei)</span><br><span style="color: hsl(120, 100%, 40%);">+                    return sgsn;</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%);">+   return NULL;</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_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   sgsn = gbproxy_sgsn_by_nsei(cfg, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!sgsn)</span><br><span style="color: hsl(120, 100%, 40%);">+            sgsn = gbproxy_sgsn_alloc(cfg, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return sgsn;</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%);">+/*! Return the gbproxy_sgsn matching that NRI</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cfg proxy in which we operate</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nri NRI to look for</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] null_nri If not NULL this indicates whether the NRI is a null NRI</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \return The SGSN this NRI has been added to, NULL if no matching SGSN could be found</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each_entry(sgsn, &cfg->sgsns, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (osmo_nri_v_matches_ranges(nri, sgsn->pool.nri_ranges)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       /* Also check if the NRI we're looking for is a NULL NRI */</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (sgsn && null_nri) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               if (osmo_nri_v_matches_ranges(nri, cfg->pool.null_nri_ranges))</span><br><span style="color: hsl(120, 100%, 40%);">+                                     *null_nri = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                             else</span><br><span style="color: hsl(120, 100%, 40%);">+                                  *null_nri = false;</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+                     return sgsn;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/gbproxy/gb_proxy_vty.c b/src/gbproxy/gb_proxy_vty.c</span><br><span>index 595ac02..92915fe 100644</span><br><span>--- a/src/gbproxy/gb_proxy_vty.c</span><br><span>+++ b/src/gbproxy/gb_proxy_vty.c</span><br><span>@@ -25,14 +25,17 @@</span><br><span> #include <time.h></span><br><span> #include <inttypes.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/hashtable.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/timer.h></span><br><span> #include <osmocom/core/rate_ctr.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/gsm48.h></span><br><span> </span><br><span> #include <osmocom/gprs/gprs_ns2.h></span><br><span> #include <osmocom/gprs/bssgp_bvc_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/gsm/apn.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm23236.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm48.h></span><br><span> </span><br><span> #include <osmocom/sgsn/debug.h></span><br><span> #include <osmocom/sgsn/gb_proxy.h></span><br><span>@@ -44,6 +47,17 @@</span><br><span> #include <osmocom/vty/vty.h></span><br><span> #include <osmocom/vty/misc.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define NRI_STR "Mapping of Network Resource Indicators to this SGSN, for SGSN pooling\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define NULL_NRI_STR "Define NULL-NRI values that cause re-assignment of an MS to a different SGSN, for SGSN pooling.\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+        "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \</span><br><span style="color: hsl(120, 100%, 40%);">+        " first value; if omitted, apply only the first value.\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define NRI_ARGS_TO_STR_FMT "%s%s%s"</span><br><span style="color: hsl(120, 100%, 40%);">+#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""</span><br><span style="color: hsl(120, 100%, 40%);">+#define NRI_WARN(SGSN, FORMAT, args...) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "%% Warning: NSE(%05d/SGSN): " FORMAT "%s", (SGSN)->nse->nsei, ##args, VTY_NEWLINE); \</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DLBSSGP, LOGL_ERROR, "NSE(%05d/SGSN): " FORMAT "\n", (SGSN)->nse->nsei, ##args); \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span> </span><br><span> static struct gbproxy_config *g_cfg = NULL;</span><br><span> </span><br><span>@@ -111,18 +125,22 @@</span><br><span> </span><br><span> static int config_write_gbproxy(struct vty *vty)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct gbproxy_nse *nse;</span><br><span style="color: hsl(0, 100%, 40%);">-        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_nri_range *r;</span><br><span> </span><br><span>        vty_out(vty, "gbproxy%s", VTY_NEWLINE);</span><br><span> </span><br><span>        if (g_cfg->pool.bvc_fc_ratio != 100)</span><br><span>              vty_out(vty, " pool bvc-flow-control-ratio %u%s", g_cfg->pool.bvc_fc_ratio, VTY_NEWLINE);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      hash_for_each(g_cfg->sgsn_nses, i, nse, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-              vty_out(vty, " sgsn nsei %u%s", nse->nsei, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (g_cfg->pool.nri_bitlen != OSMO_NRI_BITLEN_DEFAULT)</span><br><span style="color: hsl(120, 100%, 40%);">+             vty_out(vty, " nri bitlen %u%s", g_cfg->pool.nri_bitlen, VTY_NEWLINE);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       llist_for_each_entry(r, &g_cfg->pool.null_nri_ranges->entries, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+             vty_out(vty, " nri null add %d", r->first);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (r->first != r->last)</span><br><span style="color: hsl(120, 100%, 40%);">+                        vty_out(vty, " %d", r->last);</span><br><span style="color: hsl(120, 100%, 40%);">+            vty_out(vty, "%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span>    return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -135,30 +153,89 @@</span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* VTY code for SGSN (pool) configuration */</span><br><span> extern const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops;</span><br><span> #include <osmocom/gprs/protocol/gsm_08_18.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_nsip_sgsn_nsei,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_nsip_sgsn_nsei_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+static struct cmd_node sgsn_node = {</span><br><span style="color: hsl(120, 100%, 40%);">+       SGSN_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+    "%s(config-sgsn)# ",</span><br><span style="color: hsl(120, 100%, 40%);">+        1,</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%);">+static void sgsn_write_nri(struct vty *vty, struct gbproxy_sgsn *sgsn, bool verbose)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_nri_range *r;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (verbose) {</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "sgsn nsei %d%s", sgsn->nse->nsei, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (llist_empty(&sgsn->pool.nri_ranges->entries)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 vty_out(vty, " %% no NRI mappings%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each_entry(r, &sgsn->pool.nri_ranges->entries, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (osmo_nri_range_validate(r, 255))</span><br><span style="color: hsl(120, 100%, 40%);">+                  vty_out(vty, " %% INVALID RANGE:");</span><br><span style="color: hsl(120, 100%, 40%);">+         vty_out(vty, " nri add %d", r->first);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (r->first != r->last)</span><br><span style="color: hsl(120, 100%, 40%);">+                        vty_out(vty, " %d", r->last);</span><br><span style="color: hsl(120, 100%, 40%);">+            vty_out(vty, "%s", VTY_NEWLINE);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void write_sgsn(struct vty *vty, struct gbproxy_sgsn *sgsn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "sgsn nsei %u%s", sgsn->nse->nsei, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " %sallow-attach%s", sgsn->pool.allow_attach ? "" : "no ", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+        sgsn_write_nri(vty, sgsn, false);</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%);">+static int config_write_sgsn(struct vty *vty)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(sgsn, &g_cfg->sgsns, list)</span><br><span style="color: hsl(120, 100%, 40%);">+                write_sgsn(vty, sgsn);</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_sgsn_nsei,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_sgsn_nsei_cmd,</span><br><span>       "sgsn nsei <0-65534>",</span><br><span style="color: hsl(0, 100%, 40%);">-      "SGSN information\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "Configure the SGSN\n"</span><br><span>       "NSEI to be used in the connection with the SGSN\n"</span><br><span>       "The NSEI\n")</span><br><span> {</span><br><span>    uint32_t features = 0; // FIXME: make configurable</span><br><span>   unsigned int nsei = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int num_sgsn = llist_count(&g_cfg->sgsns);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gbproxy_sgsn *sgsn;</span><br><span>   struct gbproxy_nse *nse;</span><br><span>     struct gbproxy_bvc *bvc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    nse = gbproxy_nse_by_nsei_or_new(g_cfg, nsei, true);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!nse)</span><br><span style="color: hsl(120, 100%, 40%);">+     if (num_sgsn >= GBPROXY_MAX_NR_SGSN) {</span><br><span style="color: hsl(120, 100%, 40%);">+             vty_out(vty, "%% Too many SGSN NSE defined (%d), increase GBPROXY_MAX_NR_SGSN%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                   num_sgsn, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+               return CMD_WARNING;</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%);">+   /* This will have created the gbproxy_nse as well */</span><br><span style="color: hsl(120, 100%, 40%);">+  sgsn = gbproxy_sgsn_by_nsei_or_new(g_cfg, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!sgsn)</span><br><span>           goto free_nothing;</span><br><span style="color: hsl(120, 100%, 40%);">+    nse = sgsn->nse;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (num_sgsn > 1 && g_cfg->pool.nri_bitlen == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "%% Multiple SGSNs defined, but no pooling enabled%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span>    if (!gbproxy_bvc_by_bvci(nse, 0)) {</span><br><span>          uint8_t cause = BSSGP_CAUSE_OML_INTERV;</span><br><span>              bvc = gbproxy_bvc_alloc(nse, 0);</span><br><span>             if (!bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-                       goto free_nse;</span><br><span style="color: hsl(120, 100%, 40%);">+                        goto free_sgsn;</span><br><span>              bvc->fi = bssgp_bvc_fsm_alloc_sig_bss(bvc, nse->cfg->nsi, nsei, features);</span><br><span>          if (!bvc->fi)</span><br><span>                     goto free_bvc;</span><br><span>@@ -166,17 +243,134 @@</span><br><span>              osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ vty->node = SGSN_NODE;</span><br><span style="color: hsl(120, 100%, 40%);">+     vty->index = sgsn;</span><br><span>        return CMD_SUCCESS;</span><br><span> </span><br><span> free_bvc:</span><br><span>         gbproxy_bvc_free(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-free_nse:</span><br><span style="color: hsl(0, 100%, 40%);">- gbproxy_nse_free(nse);</span><br><span style="color: hsl(120, 100%, 40%);">+free_sgsn:</span><br><span style="color: hsl(120, 100%, 40%);">+    gbproxy_sgsn_free(sgsn);</span><br><span> free_nothing:</span><br><span>    vty_out(vty, "%% Unable to create NSE for NSEI=%05u%s", nsei, VTY_NEWLINE);</span><br><span>        return CMD_WARNING;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN_ATTR(cfg_sgsn_nri_add, cfg_sgsn_nri_add_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+         "nri add <0-32767> [<0-32767>]",</span><br><span style="color: hsl(120, 100%, 40%);">+        NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"</span><br><span style="color: hsl(120, 100%, 40%);">+          NRI_FIRST_LAST_STR,</span><br><span style="color: hsl(120, 100%, 40%);">+           CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gbproxy_sgsn *sgsn = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gbproxy_sgsn *other_sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+      bool before;</span><br><span style="color: hsl(120, 100%, 40%);">+  int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *message;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_nri_range add_range;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = osmo_nri_ranges_vty_add(&message, &add_range, sgsn->pool.nri_ranges, argc, argv, g_cfg->pool.nri_bitlen);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (message) {</span><br><span style="color: hsl(120, 100%, 40%);">+                NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Issue a warning about NRI range overlaps (but still allow them).</span><br><span style="color: hsl(120, 100%, 40%);">+    * Overlapping ranges will map to whichever SGSN comes fist in the gbproxy_config->sgsns llist,</span><br><span style="color: hsl(120, 100%, 40%);">+     * which should be the first one defined in the config */</span><br><span style="color: hsl(120, 100%, 40%);">+     before = true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      llist_for_each_entry(other_sgsn, &g_cfg->sgsns, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (other_sgsn == sgsn) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     before = false;</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (osmo_nri_range_overlaps_ranges(&add_range, other_sgsn->pool.nri_ranges)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 uint16_t nsei = sgsn->nse->nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t other_nsei = other_sgsn->nse->nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+                    NRI_WARN(sgsn, "NRI range [%d..%d] overlaps between NSE %05d and NSE %05d."</span><br><span style="color: hsl(120, 100%, 40%);">+                          " For overlaps, NSE %05d has higher priority than NSE %05d",</span><br><span style="color: hsl(120, 100%, 40%);">+                                add_range.first, add_range.last, nsei, other_nsei,</span><br><span style="color: hsl(120, 100%, 40%);">+                            before ? other_nsei : nsei, before ? nsei : other_nsei);</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%);">+     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_ATTR(cfg_sgsn_nri_del, cfg_sgsn_nri_del_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+     "nri del <0-32767> [<0-32767>]",</span><br><span style="color: hsl(120, 100%, 40%);">+        NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"</span><br><span style="color: hsl(120, 100%, 40%);">+     NRI_FIRST_LAST_STR,</span><br><span style="color: hsl(120, 100%, 40%);">+           CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gbproxy_sgsn *sgsn = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *message;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = osmo_nri_ranges_vty_del(&message, NULL, sgsn->pool.nri_ranges, argc, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (message) {</span><br><span style="color: hsl(120, 100%, 40%);">+                NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return CMD_WARNING;</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_ATTR(cfg_sgsn_allow_attach, cfg_sgsn_allow_attach_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+           "allow-attach",</span><br><span style="color: hsl(120, 100%, 40%);">+     "Allow this SGSN to attach new subscribers (default).\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gbproxy_sgsn *sgsn = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+    sgsn->pool.allow_attach = true;</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_ATTR(cfg_sgsn_no_allow_attach, cfg_sgsn_no_allow_attach_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+     "no allow-attach",</span><br><span style="color: hsl(120, 100%, 40%);">+          NO_STR</span><br><span style="color: hsl(120, 100%, 40%);">+        "Do not assign new subscribers to this MSC."</span><br><span style="color: hsl(120, 100%, 40%);">+        " Useful if an MSC in an MSC pool is configured to off-load subscribers."</span><br><span style="color: hsl(120, 100%, 40%);">+           " The MSC will still be operational for already IMSI-Attached subscribers,"</span><br><span style="color: hsl(120, 100%, 40%);">+         " but the NAS node selection function will skip this MSC for new subscribers\n",</span><br><span style="color: hsl(120, 100%, 40%);">+    CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gbproxy_sgsn *sgsn = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+    sgsn->pool.allow_attach = false;</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_sgsn_show_nri_all, show_nri_all_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "show nri all",</span><br><span style="color: hsl(120, 100%, 40%);">+      SHOW_STR NRI_STR "Show all SGSNs\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(sgsn, &g_cfg->sgsns, list)</span><br><span style="color: hsl(120, 100%, 40%);">+                sgsn_write_nri(vty, sgsn, true);</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(show_nri, show_nri_nsei_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "show nri nsei <0-65535>",</span><br><span style="color: hsl(120, 100%, 40%);">+      SHOW_STR NRI_STR "Identify SGSN by NSEI\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "NSEI of the SGSN\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gbproxy_sgsn *sgsn;</span><br><span style="color: hsl(120, 100%, 40%);">+    int nsei = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   sgsn = gbproxy_sgsn_by_nsei(g_cfg, nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!sgsn) {</span><br><span style="color: hsl(120, 100%, 40%);">+          vty_out(vty, "%% No SGSN with found for NSEI %05d%s", nsei, VTY_NEWLINE);</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%);">+     sgsn_write_nri(vty, sgsn, true);</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> DEFUN(cfg_pool_bvc_fc_ratio,</span><br><span>       cfg_pool_bvc_fc_ratio_cmd,</span><br><span>       "pool bvc-flow-control-ratio <1-100>",</span><br><span>@@ -187,6 +381,64 @@</span><br><span>  g_cfg->pool.bvc_fc_ratio = atoi(argv[0]);</span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN_ATTR(cfg_gbproxy_nri_bitlen,</span><br><span style="color: hsl(120, 100%, 40%);">+     cfg_gbproxy_nri_bitlen_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+           "nri bitlen <0-15>",</span><br><span style="color: hsl(120, 100%, 40%);">+          NRI_STR</span><br><span style="color: hsl(120, 100%, 40%);">+       "Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet).\n"</span><br><span style="color: hsl(120, 100%, 40%);">+         "bit count (0 disables) pooling)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+        CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     g_cfg->pool.nri_bitlen = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (llist_count(&g_cfg->sgsns) > 1 && g_cfg->pool.nri_bitlen == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               vty_out(vty, "%% Pooling disabled, but multiple SGSNs defined%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* TODO: Verify all nri ranges and warn on mismatch */</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_ATTR(cfg_gbproxy_nri_null_add,</span><br><span style="color: hsl(120, 100%, 40%);">+           cfg_gbproxy_nri_null_add_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+         "nri null add <0-32767> [<0-32767>]",</span><br><span style="color: hsl(120, 100%, 40%);">+           NRI_STR NULL_NRI_STR "Add NULL-NRI value (or range)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      NRI_FIRST_LAST_STR,</span><br><span style="color: hsl(120, 100%, 40%);">+           CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *message;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = osmo_nri_ranges_vty_add(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv,</span><br><span style="color: hsl(120, 100%, 40%);">+                               g_cfg->pool.nri_bitlen);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (message) {</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "%% nri null add: %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),</span><br><span style="color: hsl(120, 100%, 40%);">+                 VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+         vty_out(vty, "%s: \n" NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return CMD_WARNING;</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_ATTR(cfg_gbproxy_nri_null_del,</span><br><span style="color: hsl(120, 100%, 40%);">+           cfg_gbproxy_nri_null_del_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+         "nri null del <0-32767> [<0-32767>]",</span><br><span style="color: hsl(120, 100%, 40%);">+           NRI_STR NULL_NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"</span><br><span style="color: hsl(120, 100%, 40%);">+        NRI_FIRST_LAST_STR,</span><br><span style="color: hsl(120, 100%, 40%);">+           CMD_ATTR_IMMEDIATE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *message;</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = osmo_nri_ranges_vty_del(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (message) {</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),</span><br><span style="color: hsl(120, 100%, 40%);">+                       VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> static void log_set_bvc_filter(struct log_target *target,</span><br><span>                              const uint16_t *bvci)</span><br><span>@@ -379,6 +631,8 @@</span><br><span>  install_element_ve(&show_gbproxy_bvc_cmd);</span><br><span>       install_element_ve(&show_gbproxy_cell_cmd);</span><br><span>      install_element_ve(&show_gbproxy_links_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_element_ve(&show_nri_all_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+    install_element_ve(&show_nri_nsei_cmd);</span><br><span>  install_element_ve(&logging_fltr_bvc_cmd);</span><br><span> </span><br><span>   install_element(ENABLE_NODE, &delete_gb_bvci_cmd);</span><br><span>@@ -386,8 +640,18 @@</span><br><span> </span><br><span>    install_element(CONFIG_NODE, &cfg_gbproxy_cmd);</span><br><span>  install_node(&gbproxy_node, config_write_gbproxy);</span><br><span style="color: hsl(0, 100%, 40%);">-  install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd);</span><br><span>  install_element(GBPROXY_NODE, &cfg_pool_bvc_fc_ratio_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+        install_element(GBPROXY_NODE, &cfg_gbproxy_nri_bitlen_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+       install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_add_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_del_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   install_element(CONFIG_NODE, &cfg_sgsn_nsei_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_node(&sgsn_node, config_write_sgsn);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_element(SGSN_NODE, &cfg_sgsn_allow_attach_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+   install_element(SGSN_NODE, &cfg_sgsn_no_allow_attach_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+        install_element(SGSN_NODE, &cfg_sgsn_nri_add_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+        install_element(SGSN_NODE, &cfg_sgsn_nri_del_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span>         return 0;</span><br><span> }</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index 4a9449a..32ed472 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -32,7 +32,9 @@</span><br><span>  $(TESTSUITE) \</span><br><span>       vty_test_runner.py \</span><br><span>         ctrl_test_runner.py \</span><br><span style="color: hsl(0, 100%, 40%);">-   test_nodes.vty \</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo-sgsn_test-nodes.vty \</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo-gbproxy_test-nodes.vty \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo-gbproxy-pool_test-nodes.vty \</span><br><span>   $(NULL)</span><br><span> </span><br><span> TESTSUITE = $(srcdir)/testsuite</span><br><span>@@ -61,9 +63,17 @@</span><br><span> #   make vty-transcript-test U=-u</span><br><span> vty-transcript-test:</span><br><span>     osmo_verify_transcript_vty.py -v \</span><br><span style="color: hsl(120, 100%, 40%);">+            -n OsmoGbProxy -p 4246 \</span><br><span style="color: hsl(120, 100%, 40%);">+              -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg" \</span><br><span style="color: hsl(120, 100%, 40%);">+         $(U) $${T:-$(srcdir)/osmo-gbproxy_test-nodes.vty}</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_verify_transcript_vty.py -v \</span><br><span style="color: hsl(120, 100%, 40%);">+            -n OsmoGbProxy -p 4246 \</span><br><span style="color: hsl(120, 100%, 40%);">+              -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg" \</span><br><span style="color: hsl(120, 100%, 40%);">+            $(U) $${T:-$(srcdir)/osmo-gbproxy-pool_test-nodes.vty}</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_verify_transcript_vty.py -v \</span><br><span>           -n OsmoSGSN -p 4245 \</span><br><span>                -r "$(top_builddir)/src/sgsn/osmo-sgsn -c $(top_srcdir)/doc/examples/osmo-sgsn/osmo-sgsn.cfg" \</span><br><span style="color: hsl(0, 100%, 40%);">-               $(U) $${T:-$(srcdir)/*.vty}</span><br><span style="color: hsl(120, 100%, 40%);">+           $(U) $${T:-$(srcdir)/osmo-sgsn*.vty}</span><br><span>         rm -f $(builddir)/sms.db $(builddir)/gsn_restart</span><br><span> </span><br><span> # don't run multiple tests concurrently so that the ports don't conflict</span><br><span>diff --git a/tests/osmo-gbproxy-pool_test-nodes.vty b/tests/osmo-gbproxy-pool_test-nodes.vty</span><br><span>new file mode 100644</span><br><span>index 0000000..a741e48</span><br><span>--- /dev/null</span><br><span>+++ b/tests/osmo-gbproxy-pool_test-nodes.vty</span><br><span>@@ -0,0 +1,35 @@</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy> enable</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy# show nri all</span><br><span style="color: hsl(120, 100%, 40%);">+sgsn nsei 101</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 1</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 11</span><br><span style="color: hsl(120, 100%, 40%);">+sgsn nsei 102</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 2</span><br><span style="color: hsl(120, 100%, 40%);">+ nri add 12</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy# configure terminal</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config)# list</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+  gbproxy</span><br><span style="color: hsl(120, 100%, 40%);">+  sgsn nsei <0-65534></span><br><span style="color: hsl(120, 100%, 40%);">+  ns</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%);">+OsmoGbProxy(config)# sgsn nsei 101</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config-sgsn)# list</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+  allow-attach</span><br><span style="color: hsl(120, 100%, 40%);">+  no allow-attach</span><br><span style="color: hsl(120, 100%, 40%);">+  nri add <0-32767> [<0-32767>]</span><br><span style="color: hsl(120, 100%, 40%);">+  nri del <0-32767> [<0-32767>]</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%);">+OsmoGbProxy(config-sgsn)# exit</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config)# gbproxy</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config-gbproxy)# list</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+  pool bvc-flow-control-ratio <1-100></span><br><span style="color: hsl(120, 100%, 40%);">+  nri bitlen <0-15></span><br><span style="color: hsl(120, 100%, 40%);">+  nri null add <0-32767> [<0-32767>]</span><br><span style="color: hsl(120, 100%, 40%);">+  nri null del <0-32767> [<0-32767>]</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span>diff --git a/tests/osmo-gbproxy_test-nodes.vty b/tests/osmo-gbproxy_test-nodes.vty</span><br><span>new file mode 100644</span><br><span>index 0000000..8a47aa0</span><br><span>--- /dev/null</span><br><span>+++ b/tests/osmo-gbproxy_test-nodes.vty</span><br><span>@@ -0,0 +1,32 @@</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy> enable</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy# show nri all</span><br><span style="color: hsl(120, 100%, 40%);">+sgsn nsei 101</span><br><span style="color: hsl(120, 100%, 40%);">+ % no NRI mappings</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy# configure terminal</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config)# list</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+  gbproxy</span><br><span style="color: hsl(120, 100%, 40%);">+  sgsn nsei <0-65534></span><br><span style="color: hsl(120, 100%, 40%);">+  ns</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%);">+OsmoGbProxy(config)# sgsn nsei 101</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config-sgsn)# list</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+  allow-attach</span><br><span style="color: hsl(120, 100%, 40%);">+  no allow-attach</span><br><span style="color: hsl(120, 100%, 40%);">+  nri add <0-32767> [<0-32767>]</span><br><span style="color: hsl(120, 100%, 40%);">+  nri del <0-32767> [<0-32767>]</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%);">+OsmoGbProxy(config-sgsn)# exit</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config)# gbproxy</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoGbProxy(config-gbproxy)# list</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span style="color: hsl(120, 100%, 40%);">+  pool bvc-flow-control-ratio <1-100></span><br><span style="color: hsl(120, 100%, 40%);">+  nri bitlen <0-15></span><br><span style="color: hsl(120, 100%, 40%);">+  nri null add <0-32767> [<0-32767>]</span><br><span style="color: hsl(120, 100%, 40%);">+  nri null del <0-32767> [<0-32767>]</span><br><span style="color: hsl(120, 100%, 40%);">+...</span><br><span>diff --git a/tests/test_nodes.vty b/tests/osmo-sgsn_test-nodes.vty</span><br><span>similarity index 100%</span><br><span>rename from tests/test_nodes.vty</span><br><span>rename to tests/osmo-sgsn_test-nodes.vty</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-sgsn/+/21705">change 21705</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-sgsn/+/21705"/><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-Change-Id: Id67592aa7712e5e04e7264b2fb8f26d57eb7e69e </div>
<div style="display:none"> Gerrit-Change-Number: 21705 </div>
<div style="display:none"> Gerrit-PatchSet: 8 </div>
<div style="display:none"> Gerrit-Owner: daniel <dwillmann@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: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>