<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-gbproxy/+/22804">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gb_proxy: add support for relaying BSSGP RIM messages<br><br>BSSGP RIM messages are routed from a source to a destination cell by a<br>RIM routing information IE. Add parsing for the routing information and<br>support for relaying RIM messages to the destination cell/PCU. If the<br>destination cell/PCU is not directly connected to osmo-gbproxy route the<br>rim message to the first connected SGSN.<br><br>Change-Id: Idd1ea46832e044f0ade15af32250f90517d848d8<br>Related: SYS#5103<br>---<br>M src/gb_proxy.c<br>1 file changed, 126 insertions(+), 5 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-gbproxy refs/changes/04/22804/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/gb_proxy.c b/src/gb_proxy.c</span><br><span>index f773584..907a6eb 100644</span><br><span>--- a/src/gb_proxy.c</span><br><span>+++ b/src/gb_proxy.c</span><br><span>@@ -46,6 +46,7 @@</span><br><span> #include <osmocom/gprs/gprs_bssgp2.h></span><br><span> #include <osmocom/gprs/gprs_bssgp_bss.h></span><br><span> #include <osmocom/gprs/bssgp_bvc_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/protocol/gsm_08_18.h></span><br><span> </span><br><span> #include <osmocom/gsm/gsm23236.h></span><br><span> #include <osmocom/gsm/gsm_utils.h></span><br><span>@@ -887,6 +888,82 @@</span><br><span>  return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Receive an incoming RIM message from a BSS-side NS-VC */</span><br><span style="color: hsl(120, 100%, 40%);">+static int gbprox_rx_rim_from_bss(struct tlv_parsed *tp, struct gbproxy_nse *nse, struct msgb *msg, char *log_pfx,</span><br><span style="color: hsl(120, 100%, 40%);">+                             const char *pdut_name)</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%);">+    struct gbproxy_cell *dest_cell;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gbproxy_cell *src_cell;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct bssgp_rim_routing_info dest_ri;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct bssgp_rim_routing_info src_ri;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_parse_rim_ri(&dest_ri, TLVP_VAL(&tp[0], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+                                TLVP_LEN(&tp[0], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DGPRS, LOGL_ERROR, "%s %s cannot parse destination RIM routing info\n", log_pfx, pdut_name);</span><br><span style="color: hsl(120, 100%, 40%);">+           return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_parse_rim_ri(&src_ri, TLVP_VAL(&tp[1], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+                         TLVP_LEN(&tp[1], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DGPRS, LOGL_ERROR, "%s %s cannot parse source RIM routing info\n", log_pfx, pdut_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);</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%);">+   /* Since gbproxy is 2G only we do not expect to get RIM messages only from GERAN cells. */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (src_ri.discr != BSSGP_RIM_ROUTING_INFO_GERAN) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DGPRS, LOGL_ERROR, "%s %s source RIM routing info is not GERAN (%s)\n", log_pfx, pdut_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                 bssgp_rim_ri_name(&src_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+         return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);</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%);">+   /* Lookup source cell to make sure that the source RIM routing information actually belongs</span><br><span style="color: hsl(120, 100%, 40%);">+    * to a valid cell that we know */</span><br><span style="color: hsl(120, 100%, 40%);">+    src_cell = gbproxy_cell_by_cellid(nse->cfg, &src_ri.geran.raid, src_ri.geran.cid);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!src_cell) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DGPRS, LOGL_NOTICE, "%s %s cannot find cell for source RIM routing info (%s)\n", log_pfx,</span><br><span style="color: hsl(120, 100%, 40%);">+                   pdut_name, bssgp_rim_ri_name(&src_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+              return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);</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%);">+   /* TODO: Use bssgp_bvc_get_features_negotiated(src_cell->bss_bvc->fi) to check if the the BSS sided BVC actually</span><br><span style="color: hsl(120, 100%, 40%);">+         * did negotiate RIM support. If not we should respond with a BSSGP STATUS message. The cause code should be</span><br><span style="color: hsl(120, 100%, 40%);">+   * BSSGP_CAUSE_PDU_INCOMP_FEAT. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* If Destination is known by gbproxy, route directly */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (dest_ri.discr == BSSGP_RIM_ROUTING_INFO_GERAN) {</span><br><span style="color: hsl(120, 100%, 40%);">+          dest_cell = gbproxy_cell_by_cellid(nse->cfg, &dest_ri.geran.raid, dest_ri.geran.cid);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (dest_cell) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* TODO: Also check if dest_cell->bss_bvc is RIM-capable (see also above). If not we shoud</span><br><span style="color: hsl(120, 100%, 40%);">+                  * respond with a BSSGP STATUS message as well because it also would make no sense to try</span><br><span style="color: hsl(120, 100%, 40%);">+                      * routing the RIM message to the next RIM-capable SGSN. */</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGP(DLBSSGP, LOGL_DEBUG, "%s %s relaying RIM-PDU: src=%s, dest=%s\n", log_pfx, pdut_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                       bssgp_rim_ri_name(&src_ri), bssgp_rim_ri_name(&dest_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+                        return gbprox_relay2peer(msg, dest_cell->bss_bvc, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DGPRS, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                   "%s %s cannot find cell for destination RIM routing info (%s), will try to route to any RIM capable SGSN instead.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+               log_pfx, pdut_name, bssgp_rim_ri_name(&src_ri));</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%);">+   /* Otherwise pass on to a RIM-capable SGSN */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TODO: We need to extend gbproxy_select_sgsn() so that it selects a RIM-capable SGSN, at the moment we just</span><br><span style="color: hsl(120, 100%, 40%);">+  * get any SGSN and just assume that it is RIM-capable. */</span><br><span style="color: hsl(120, 100%, 40%);">+    sgsn = gbproxy_select_sgsn(nse->cfg, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sgsn) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DGPRS, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                   "%s %s cannot route RIM message (%s to %s) since no RIM capable SGSN is found!\n", log_pfx,</span><br><span style="color: hsl(120, 100%, 40%);">+                 pdut_name, bssgp_rim_ri_name(&src_ri), bssgp_rim_ri_name(&dest_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+             return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGP(DLBSSGP, LOGL_DEBUG, "%s %s relaying RIM-PDU: src=%s, dest=%s\n", log_pfx, pdut_name,</span><br><span style="color: hsl(120, 100%, 40%);">+       bssgp_rim_ri_name(&src_ri), bssgp_rim_ri_name(&dest_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return gbprox_relay2nse(msg, sgsn->nse, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Receive an incoming signalling message from a BSS-side NS-VC */</span><br><span> static int gbprox_rx_sig_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)</span><br><span> {</span><br><span>@@ -985,8 +1062,7 @@</span><br><span>      case BSSGP_PDUT_RAN_INFO_ACK:</span><br><span>        case BSSGP_PDUT_RAN_INFO_ERROR:</span><br><span>      case BSSGP_PDUT_RAN_INFO_APP_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">-             /* FIXME: route based in RIM Routing IE */</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = gbprox_rx_rim_from_bss(tp, nse, msg, log_pfx, pdut_name);</span><br><span>               break;</span><br><span>       case BSSGP_PDUT_LLC_DISCARD:</span><br><span>         case BSSGP_PDUT_FLUSH_LL_ACK:</span><br><span>@@ -1135,6 +1211,53 @@</span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Receive an incoming RIM message from the SGSN-side NS-VC */</span><br><span style="color: hsl(120, 100%, 40%);">+static int gbprox_rx_rim_from_sgsn(struct tlv_parsed *tp, struct gbproxy_nse *nse, struct msgb *msg, char *log_pfx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  const char *pdut_name)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gbproxy_cell *dest_cell;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct bssgp_rim_routing_info dest_ri;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct bssgp_rim_routing_info src_ri;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_parse_rim_ri(&dest_ri, TLVP_VAL(&tp[0], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+                                TLVP_LEN(&tp[0], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DGPRS, LOGL_ERROR, "%s %s cannot parse destination RIM routing info\n", log_pfx, pdut_name);</span><br><span style="color: hsl(120, 100%, 40%);">+           return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_parse_rim_ri(&src_ri, TLVP_VAL(&tp[1], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+                         TLVP_LEN(&tp[1], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DGPRS, LOGL_ERROR, "%s %s cannot parse source RIM routing info\n", log_pfx, pdut_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);</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%);">+   /* Since gbproxy is 2G only we do not expect to get RIM messages that target GERAN cells. */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (dest_ri.discr != BSSGP_RIM_ROUTING_INFO_GERAN) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DGPRS, LOGL_ERROR, "%s %s destination RIM routing info is not GERAN (%s)\n", log_pfx, pdut_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                    bssgp_rim_ri_name(&dest_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+                return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);</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%);">+   /* TODO: Reply with STATUS if BSSGP didn't negotiate RIM feature, see also comments in</span><br><span style="color: hsl(120, 100%, 40%);">+       gbprox_rx_rim_from_bss() */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Lookup destination cell */</span><br><span style="color: hsl(120, 100%, 40%);">+ dest_cell = gbproxy_cell_by_cellid(nse->cfg, &dest_ri.geran.raid, dest_ri.geran.cid);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!dest_cell) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DGPRS, LOGL_NOTICE, "%s %s cannot find cell for destination RIM routing info (%s)\n", log_pfx,</span><br><span style="color: hsl(120, 100%, 40%);">+              pdut_name, bssgp_rim_ri_name(&dest_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+             return bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);</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%);">+   /* TODO: Check if the BVC of the destination cell actually did negotiate RIM support, see also comments</span><br><span style="color: hsl(120, 100%, 40%);">+        * in gbprox_rx_rim_from_bss() */</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGP(DLBSSGP, LOGL_DEBUG, "%s %s relaying RIM-PDU: src=%s, dest=%s\n", log_pfx, pdut_name,</span><br><span style="color: hsl(120, 100%, 40%);">+       bssgp_rim_ri_name(&src_ri), bssgp_rim_ri_name(&dest_ri));</span><br><span style="color: hsl(120, 100%, 40%);">+        return gbprox_relay2peer(msg, dest_cell->bss_bvc, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Receive an incoming signalling message from the SGSN-side NS-VC */</span><br><span> static int gbprox_rx_sig_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)</span><br><span> {</span><br><span>@@ -1287,9 +1410,7 @@</span><br><span>       case BSSGP_PDUT_RAN_INFO_ACK:</span><br><span>        case BSSGP_PDUT_RAN_INFO_ERROR:</span><br><span>      case BSSGP_PDUT_RAN_INFO_APP_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">-             /* FIXME: route based in RIM Routing IE */</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = gbprox_rx_rim_from_sgsn(tp, nse, msg, log_pfx, pdut_name);</span><br><span>      default:</span><br><span>             LOGPNSE(nse, LOGL_NOTICE, "Rx %s: Not supported\n", pdut_name);</span><br><span>            rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-gbproxy/+/22804">change 22804</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-gbproxy/+/22804"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-gbproxy </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Idd1ea46832e044f0ade15af32250f90517d848d8 </div>
<div style="display:none"> Gerrit-Change-Number: 22804 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>