<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-sgsn/+/21552">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gbproxy: Remove patching, TLLI-tracking and SGSN2 support<br><br>Those features were introduced a long time ago for one specific use<br>case at one specific user, and they are not needed anymore.  They<br>complicate the code base significantly and are hard to maintain with<br>all the upcoming modifications regarding SGSN pool supoprt.<br><br>Change-Id: Id9cc2e1c63486491ac5bb68876088a615075fde6<br>---<br>M include/osmocom/sgsn/gb_proxy.h<br>M src/gbproxy/Makefile.am<br>M src/gbproxy/gb_proxy.c<br>M src/gbproxy/gb_proxy_ctrl.c<br>D src/gbproxy/gb_proxy_patch.c<br>M src/gbproxy/gb_proxy_peer.c<br>D src/gbproxy/gb_proxy_tlli.c<br>M src/gbproxy/gb_proxy_vty.c<br>8 files changed, 4 insertions(+), 2,900 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/52/21552/1</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 95a3331..8fe845c 100644</span><br><span>--- a/include/osmocom/sgsn/gb_proxy.h</span><br><span>+++ b/include/osmocom/sgsn/gb_proxy.h</span><br><span>@@ -35,7 +35,6 @@</span><br><span>       GBPROX_GLOB_CTR_RESTART_RESET_SGSN,</span><br><span>  GBPROX_GLOB_CTR_TX_ERR_SGSN,</span><br><span>         GBPROX_GLOB_CTR_OTHER_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_GLOB_CTR_PATCH_PEER_ERR,</span><br><span> };</span><br><span> </span><br><span> enum gbproxy_bvc_ctr {</span><br><span>@@ -44,56 +43,9 @@</span><br><span>     GBPROX_PEER_CTR_DROPPED,</span><br><span>     GBPROX_PEER_CTR_INV_NSEI,</span><br><span>    GBPROX_PEER_CTR_TX_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">- GBPROX_PEER_CTR_RAID_PATCHED_BSS,</span><br><span style="color: hsl(0, 100%, 40%);">-       GBPROX_PEER_CTR_RAID_PATCHED_SGSN,</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_PEER_CTR_APN_PATCHED,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_TLLI_PATCHED_BSS,</span><br><span style="color: hsl(0, 100%, 40%);">-       GBPROX_PEER_CTR_TLLI_PATCHED_SGSN,</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_PEER_CTR_PTMSI_PATCHED_BSS,</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN,</span><br><span style="color: hsl(0, 100%, 40%);">-     GBPROX_PEER_CTR_PATCH_CRYPT_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-        GBPROX_PEER_CTR_PATCH_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_PEER_CTR_ATTACH_REQS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_ATTACH_REJS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_ATTACH_ACKS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_ATTACH_COMPLS,</span><br><span style="color: hsl(0, 100%, 40%);">-  GBPROX_PEER_CTR_RA_UPD_REQS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_RA_UPD_REJS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_RA_UPD_ACKS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_RA_UPD_COMPLS,</span><br><span style="color: hsl(0, 100%, 40%);">-  GBPROX_PEER_CTR_GMM_STATUS_BSS,</span><br><span style="color: hsl(0, 100%, 40%);">- GBPROX_PEER_CTR_GMM_STATUS_SGSN,</span><br><span style="color: hsl(0, 100%, 40%);">-        GBPROX_PEER_CTR_DETACH_REQS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_DETACH_ACKS,</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROX_PEER_CTR_PDP_ACT_REQS,</span><br><span style="color: hsl(0, 100%, 40%);">-   GBPROX_PEER_CTR_PDP_ACT_REJS,</span><br><span style="color: hsl(0, 100%, 40%);">-   GBPROX_PEER_CTR_PDP_ACT_ACKS,</span><br><span style="color: hsl(0, 100%, 40%);">-   GBPROX_PEER_CTR_PDP_DEACT_REQS,</span><br><span style="color: hsl(0, 100%, 40%);">- GBPROX_PEER_CTR_PDP_DEACT_ACKS,</span><br><span style="color: hsl(0, 100%, 40%);">- GBPROX_PEER_CTR_TLLI_UNKNOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-   GBPROX_PEER_CTR_TLLI_CACHE_SIZE,</span><br><span>     GBPROX_PEER_CTR_LAST,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum gbproxy_keep_mode {</span><br><span style="color: hsl(0, 100%, 40%);">- GBPROX_KEEP_NEVER,      /* don't ever keep TLLI/IMSI state of de-registered subscribers */</span><br><span style="color: hsl(0, 100%, 40%);">-  GBPROX_KEEP_REATTACH,   /* keep if re-attach has been requested by SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_KEEP_IDENTIFIED, /* keep if we had resolved an IMSI */</span><br><span style="color: hsl(0, 100%, 40%);">-   GBPROX_KEEP_ALWAYS,     /* always keep */</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum gbproxy_match_id {</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_MATCH_PATCHING,  /* match rule on whether or not we should patch */</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROX_MATCH_ROUTING,   /* match rule on whether or not we should route (2-SGSN) */</span><br><span style="color: hsl(0, 100%, 40%);">-     GBPROX_MATCH_LAST</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_match {</span><br><span style="color: hsl(0, 100%, 40%);">-       bool  enable;           /* is this match enabled? */</span><br><span style="color: hsl(0, 100%, 40%);">-    char *re_str;           /* regular expression (for IMSI) in string format */</span><br><span style="color: hsl(0, 100%, 40%);">-    regex_t re_comp;        /* compiled regular expression (for IMSI) */</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* global gb-proxy configuration */</span><br><span> struct gbproxy_config {</span><br><span>     /* parsed from config file */</span><br><span>@@ -107,44 +59,6 @@</span><br><span> </span><br><span>      /* Counter */</span><br><span>        struct rate_ctr_group *ctrg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* MCC/MNC to be patched into RA-ID on the way from BSS to SGSN? */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_plmn_id core_plmn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* APN to be patched into PDP CTX ACT REQ on the way from BSS to SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t* core_apn;</span><br><span style="color: hsl(0, 100%, 40%);">-      size_t core_apn_size;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Frequency (sec) at which timer to clean stale links is fired (0 disabled) */</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int clean_stale_timer_freq;</span><br><span style="color: hsl(0, 100%, 40%);">-    /* If !0, Max age to consider a struct gbproxy_link_info as stale */</span><br><span style="color: hsl(0, 100%, 40%);">-    int tlli_max_age;</span><br><span style="color: hsl(0, 100%, 40%);">-       /* If !0, Max len of gbproxy_bvc->list (list of struct gbproxy_link_info) */</span><br><span style="color: hsl(0, 100%, 40%);">- int tlli_max_len;</span><br><span style="color: hsl(0, 100%, 40%);">-       /* If !0, Max len of gbproxy_link_info->stored_msgs (list of msgb) */</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t stored_msgs_max_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Should the P-TMSI be patched on the fly (required for 2-SGSN config) */</span><br><span style="color: hsl(0, 100%, 40%);">-      bool patch_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Should the IMSI be acquired by the proxy (required for 2-SGSN config) */</span><br><span style="color: hsl(0, 100%, 40%);">-     bool acquire_imsi;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Should we route subscribers to two different SGSNs? */</span><br><span style="color: hsl(0, 100%, 40%);">-       bool route_to_sgsn2;</span><br><span style="color: hsl(0, 100%, 40%);">-    /* NSEI of the second SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-   uint16_t nsip_sgsn2_nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-       /* should we keep a cache of per-subscriber state even after de-registration? */</span><br><span style="color: hsl(0, 100%, 40%);">-        enum gbproxy_keep_mode keep_link_infos;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* IMSI checking/matching for 2-SGSN routing and patching */</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_match matches[GBPROX_MATCH_LAST];</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_patch_state {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_plmn_id local_plmn;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* List of TLLIs for which patching is enabled */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct llist_head logical_links;</span><br><span style="color: hsl(0, 100%, 40%);">-        int logical_link_count;</span><br><span> };</span><br><span> </span><br><span> /* One BVC inside an NSE */</span><br><span>@@ -166,12 +80,6 @@</span><br><span> </span><br><span>   /* Counter */</span><br><span>        struct rate_ctr_group *ctrg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* State related to on-the-fly patching of certain messages */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_patch_state patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Fired periodically to clean up stale links from list */</span><br><span style="color: hsl(0, 100%, 40%);">-      struct osmo_timer_list clean_stale_timer;</span><br><span> };</span><br><span> </span><br><span> /* one NS Entity that we interact with (BSS/PCU) */</span><br><span>@@ -189,58 +97,6 @@</span><br><span>     DECLARE_HASHTABLE(bvcs, 10);</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_tlli_state {</span><br><span style="color: hsl(0, 100%, 40%);">-       /* currently active TLLI */</span><br><span style="color: hsl(0, 100%, 40%);">-     uint32_t current;</span><br><span style="color: hsl(0, 100%, 40%);">-       /* newly-assigned TLLI (e.g. during P-TMSI allocation procedure) */</span><br><span style="color: hsl(0, 100%, 40%);">-     uint32_t assigned;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* has the BSS side validated (confirmed) the new TLLI? */</span><br><span style="color: hsl(0, 100%, 40%);">-      bool bss_validated;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* has the SGSN side validated (confirmed) the new TLLI? */</span><br><span style="color: hsl(0, 100%, 40%);">-     bool net_validated;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* NOTE: once both are validated, we set current = assigned and assigned = 0 */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* The P-TMSI for this subscriber */</span><br><span style="color: hsl(0, 100%, 40%);">-    uint32_t ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* One TLLI (= UE, = Subscriber) served via this proxy */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* link to gbproxy_bvc.patch_state.logical_links */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct llist_head list;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* TLLI on the BSS/PCU side */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_tlli_state tlli;</span><br><span style="color: hsl(0, 100%, 40%);">- /* TLLI on the SGSN side (can be different in case of P-TMSI patching) */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_tlli_state sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-    /* NSEI of the SGSN serving this link */</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t sgsn_nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* timestamp when we last had any contact with this UE */</span><br><span style="color: hsl(0, 100%, 40%);">-       time_t timestamp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* IMSI of the subscriber (if/once known) */</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t *imsi;</span><br><span style="color: hsl(0, 100%, 40%);">-  size_t imsi_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* is the IMSI acquisition still pending? */</span><br><span style="color: hsl(0, 100%, 40%);">-    bool imsi_acq_pending;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* queue of stored UL messages (until IMSI acquisition completes and we can</span><br><span style="color: hsl(0, 100%, 40%);">-      * determine which of the SGSNs we should route this to */</span><br><span style="color: hsl(0, 100%, 40%);">-      struct llist_head stored_msgs;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint32_t stored_msgs_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* generated N(U) we use (required due to IMSI acquisition */</span><br><span style="color: hsl(0, 100%, 40%);">-   unsigned vu_gen_tx_bss;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* is this subscriber deregistered (TLLI invalidated)? */</span><br><span style="color: hsl(0, 100%, 40%);">-       bool is_deregistered;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* does this link match either the (2-SGSN) routing or the patching rule? */</span><br><span style="color: hsl(0, 100%, 40%);">-    bool is_matching[GBPROX_MATCH_LAST];</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 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/BSS) " FMT, (NSE)->nsei, ## ARGS)</span><br><span>@@ -276,74 +132,6 @@</span><br><span> </span><br><span> void gbprox_reset(struct gbproxy_config *cfg);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* TLLI info handling */</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_delete_link_infos(struct gbproxy_bvc *bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_update_link_state_ul(</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_bvc *bvc, time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_gb_parse_context *parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_update_link_state_dl(</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_bvc *bvc, time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_gb_parse_context *parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_update_link_state_after(</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-   time_t now, struct gprs_gb_parse_context *parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_remove_stale_link_infos(struct gbproxy_bvc *bvc, time_t now);</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_delete_link_info(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct gbproxy_link_info *link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_attach_link_info(struct gbproxy_bvc *bvc, time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gbproxy_link_info *link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_update_link_info(struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                         const uint8_t *imsi, size_t imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_detach_link_info(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                            struct gbproxy_link_info *link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_bvc *bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_bvc *bvc, uint32_t tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_bvc *bvc, const uint8_t *imsi, size_t imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_bvc *bvc, uint32_t tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t tlli, uint32_t sgsn_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_ptmsi(</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_imsi_matches(</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg,</span><br><span style="color: hsl(0, 100%, 40%);">-     enum gbproxy_match_id match_id,</span><br><span style="color: hsl(0, 100%, 40%);">- struct gbproxy_link_info *link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t gbproxy_map_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">- uint32_t other_tlli, struct gbproxy_link_info *link_info, int to_bss);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* needed by gb_proxy_tlli.h */</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_bvc *bvc, uint32_t sgsn_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t gbproxy_make_sgsn_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-   uint32_t bss_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_reset_link(struct gbproxy_link_info *link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_check_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">- struct gbproxy_match *match, const uint8_t *imsi, size_t imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Message patching */</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_patch_bssgp(</span><br><span style="color: hsl(0, 100%, 40%);">-      struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-   int *len_change, struct gprs_gb_parse_context *parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_patch_llc(</span><br><span style="color: hsl(0, 100%, 40%);">-        struct msgb *msg, uint8_t *llc, size_t llc_len,</span><br><span style="color: hsl(0, 100%, 40%);">- struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-   int *len_change, struct gprs_gb_parse_context *parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_set_patch_filter(</span><br><span style="color: hsl(0, 100%, 40%);">- struct gbproxy_match *match, const char *filter, const char **err_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_clear_patch_filter(struct gbproxy_match *match);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Peer handling */</span><br><span> struct gbproxy_bvc *gbproxy_bvc_by_bvci(</span><br><span>      struct gbproxy_config *cfg, uint16_t bvci);</span><br><span>diff --git a/src/gbproxy/Makefile.am b/src/gbproxy/Makefile.am</span><br><span>index 6876f68..f8a8773 100644</span><br><span>--- a/src/gbproxy/Makefile.am</span><br><span>+++ b/src/gbproxy/Makefile.am</span><br><span>@@ -27,8 +27,6 @@</span><br><span>     gb_proxy_main.c \</span><br><span>    gb_proxy_vty.c \</span><br><span>     gb_proxy_ctrl.c \</span><br><span style="color: hsl(0, 100%, 40%);">-       gb_proxy_patch.c \</span><br><span style="color: hsl(0, 100%, 40%);">-      gb_proxy_tlli.c \</span><br><span>    gb_proxy_peer.c \</span><br><span>    $(NULL)</span><br><span> osmo_gbproxy_LDADD = \</span><br><span>diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c</span><br><span>index ef2273d..1cf7471 100644</span><br><span>--- a/src/gbproxy/gb_proxy.c</span><br><span>+++ b/src/gbproxy/gb_proxy.c</span><br><span>@@ -82,7 +82,6 @@</span><br><span>                        uint16_t ns_bvci);</span><br><span> static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,</span><br><span>                         uint16_t ns_bvci, uint16_t sgsn_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info);</span><br><span> </span><br><span> static int check_bvc_nsei(struct gbproxy_bvc *bvc, uint16_t nsei)</span><br><span> {</span><br><span>@@ -106,449 +105,6 @@</span><br><span>    msgb_pull(msg, strip_len);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Transmit Chapter 9.2.10 Identity Request */</span><br><span style="color: hsl(0, 100%, 40%);">-static void gprs_put_identity_req(struct msgb *msg, uint8_t id_type)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm48_hdr *gh;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   id_type &= GSM_MI_TYPE_MASK;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);</span><br><span style="color: hsl(0, 100%, 40%);">-       gh->proto_discr = GSM48_PDISC_MM_GPRS;</span><br><span style="color: hsl(0, 100%, 40%);">-       gh->msg_type = GSM48_MT_GMM_ID_REQ;</span><br><span style="color: hsl(0, 100%, 40%);">-  gh->data[0] = id_type;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Transmit Chapter 9.4.6.2 Detach Accept (mobile originated detach) */</span><br><span style="color: hsl(0, 100%, 40%);">-static void gprs_put_mo_detach_acc(struct msgb *msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm48_hdr *gh;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);</span><br><span style="color: hsl(0, 100%, 40%);">-       gh->proto_discr = GSM48_PDISC_MM_GPRS;</span><br><span style="color: hsl(0, 100%, 40%);">-       gh->msg_type = GSM48_MT_GMM_DETACH_ACK;</span><br><span style="color: hsl(0, 100%, 40%);">-      gh->data[0] = 0; /* no force to standby */</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gprs_push_llc_ui(struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                         int is_uplink, unsigned sapi, unsigned nu)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        const uint8_t e_bit = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        const uint8_t pm_bit = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       const uint8_t cr_bit = is_uplink ? 0 : 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t *llc;</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t *fcs_field;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint32_t fcs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   nu &= 0x01ff; /* 9 Bit */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   llc = msgb_push(msg, 3);</span><br><span style="color: hsl(0, 100%, 40%);">-        llc[0] = (cr_bit << 6) | (sapi & 0x0f);</span><br><span style="color: hsl(0, 100%, 40%);">-       llc[1] = 0xc0 | (nu >> 6); /* UI frame */</span><br><span style="color: hsl(0, 100%, 40%);">- llc[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     fcs = gprs_llc_fcs(llc, msgb_length(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-      fcs_field = msgb_put(msg, 3);</span><br><span style="color: hsl(0, 100%, 40%);">-   fcs_field[0] = (uint8_t)(fcs >> 0);</span><br><span style="color: hsl(0, 100%, 40%);">-       fcs_field[1] = (uint8_t)(fcs >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-       fcs_field[2] = (uint8_t)(fcs >> 16);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gprs_push_bssgp_dl_unitdata(struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    uint32_t tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct bssgp_ud_hdr *budh;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t *llc = msgb_data(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-  size_t llc_size = msgb_length(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-     const size_t llc_ie_hdr_size = 3;</span><br><span style="color: hsl(0, 100%, 40%);">-       const uint8_t qos_profile[] = {0x00, 0x50, 0x20}; /* hard-coded */</span><br><span style="color: hsl(0, 100%, 40%);">-      const uint8_t lifetime[] = {0x02, 0x58}; /* 6s hard-coded */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    const size_t bssgp_overhead = sizeof(*budh) +</span><br><span style="color: hsl(0, 100%, 40%);">-           TVLV_GROSS_LEN(sizeof(lifetime)) + llc_ie_hdr_size;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t *ie;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint32_t tlli_be = htonl(tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- budh = (struct bssgp_ud_hdr *)msgb_push(msg, bssgp_overhead);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   budh->pdu_type = BSSGP_PDUT_DL_UNITDATA;</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(&budh->tlli, &tlli_be, sizeof(budh->tlli));</span><br><span style="color: hsl(0, 100%, 40%);">-        memcpy(&budh->qos_profile, qos_profile, sizeof(budh->qos_profile));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   ie = budh->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     tvlv_put(ie, BSSGP_IE_PDU_LIFETIME, sizeof(lifetime), lifetime);</span><br><span style="color: hsl(0, 100%, 40%);">-        ie += TVLV_GROSS_LEN(sizeof(lifetime));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Note: Add alignment before the LLC IE if inserting other IE */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       *(ie++) = BSSGP_IE_LLC_PDU;</span><br><span style="color: hsl(0, 100%, 40%);">-     *(ie++) = llc_size / 256;</span><br><span style="color: hsl(0, 100%, 40%);">-       *(ie++) = llc_size % 256;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(ie == llc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_bssgph(msg) = (uint8_t *)budh;</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_tlli(msg) = tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* update bvc according to the BSS message */</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbprox_update_current_raid(uint8_t *raid_enc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                const char *log_text)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-   const struct osmo_plmn_id old_plmn = state->local_plmn;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gprs_ra_id raid;</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!raid_enc)</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- gsm48_parse_ra(&raid, raid_enc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* save source side MCC/MNC */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!cfg->core_plmn.mcc || raid.mcc == cfg->core_plmn.mcc) {</span><br><span style="color: hsl(0, 100%, 40%);">-              state->local_plmn.mcc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                state->local_plmn.mcc = raid.mcc;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!cfg->core_plmn.mnc</span><br><span style="color: hsl(0, 100%, 40%);">-          || !osmo_mnc_cmp(raid.mnc, raid.mnc_3_digits,</span><br><span style="color: hsl(0, 100%, 40%);">-                            cfg->core_plmn.mnc, cfg->core_plmn.mnc_3_digits)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          state->local_plmn.mnc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-           state->local_plmn.mnc_3_digits = false;</span><br><span style="color: hsl(0, 100%, 40%);">-      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                state->local_plmn.mnc = raid.mnc;</span><br><span style="color: hsl(0, 100%, 40%);">-            state->local_plmn.mnc_3_digits = raid.mnc_3_digits;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (osmo_plmn_cmp(&old_plmn, &state->local_plmn))</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGPBVC(bvc, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-                    "Patching RAID %sactivated, msg: %s, "</span><br><span style="color: hsl(0, 100%, 40%);">-                "local: %s, core: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              state->local_plmn.mcc || state->local_plmn.mnc ?</span><br><span style="color: hsl(0, 100%, 40%);">-                  "" : "de",</span><br><span style="color: hsl(0, 100%, 40%);">-                  log_text,</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_plmn_name(&state->local_plmn),</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_plmn_name2(&cfg->core_plmn));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                         uint32_t sgsn_ptmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   uint32_t bss_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-     int max_retries = 23, rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bvc->nse->cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-             bss_ptmsi = sgsn_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                do {</span><br><span style="color: hsl(0, 100%, 40%);">-                    rc = osmo_get_rand_id((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi));</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                bss_ptmsi = GSM_RESERVED_TMSI;</span><br><span style="color: hsl(0, 100%, 40%);">-                          break;</span><br><span style="color: hsl(0, 100%, 40%);">-                  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       bss_ptmsi = bss_ptmsi | GSM23003_TMSI_SGSN_MASK;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (gbproxy_link_info_by_ptmsi(bvc, bss_ptmsi))</span><br><span style="color: hsl(0, 100%, 40%);">-                         bss_ptmsi = GSM_RESERVED_TMSI;</span><br><span style="color: hsl(0, 100%, 40%);">-          } while (bss_ptmsi == GSM_RESERVED_TMSI && max_retries--);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bss_ptmsi == GSM_RESERVED_TMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPBVC(bvc, LOGL_ERROR, "Failed to allocate a BSS P-TMSI: %d (%s)\n", rc, strerror(-rc));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    return bss_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                              struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                            uint32_t bss_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     uint32_t sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-     int max_retries = 23, rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bvc->nse->cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-             sgsn_tlli = bss_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-   } else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI &&</span><br><span style="color: hsl(0, 100%, 40%);">-                   gprs_tlli_type(bss_tlli) == TLLI_FOREIGN) {</span><br><span style="color: hsl(0, 100%, 40%);">-          sgsn_tlli = gprs_tmsi2tlli(link_info->sgsn_tlli.ptmsi,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          TLLI_FOREIGN);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI &&</span><br><span style="color: hsl(0, 100%, 40%);">-                   gprs_tlli_type(bss_tlli) == TLLI_LOCAL) {</span><br><span style="color: hsl(0, 100%, 40%);">-            sgsn_tlli = gprs_tmsi2tlli(link_info->sgsn_tlli.ptmsi,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          TLLI_LOCAL);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                do {</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* create random TLLI, 0b01111xxx... */</span><br><span style="color: hsl(0, 100%, 40%);">-                 rc = osmo_get_rand_id((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli));</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                sgsn_tlli = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                          break;</span><br><span style="color: hsl(0, 100%, 40%);">-                  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       sgsn_tlli = (sgsn_tlli & 0x7fffffff) | 0x78000000;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                  if (gbproxy_link_info_by_any_sgsn_tlli(bvc, sgsn_tlli))</span><br><span style="color: hsl(0, 100%, 40%);">-                         sgsn_tlli = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-          } while (!sgsn_tlli && max_retries--);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!sgsn_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGPBVC(bvc, LOGL_ERROR, "Failed to allocate an SGSN TLLI: %d (%s)\n", rc, strerror(-rc));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    return sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_reset_link(struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- gbproxy_reset_imsi_acquisition(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Returns != 0 iff IMSI acquisition was in progress */</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_restart_imsi_acquisition(struct gbproxy_link_info* link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     int in_progress = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-         return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (link_info->imsi_acq_pending)</span><br><span style="color: hsl(0, 100%, 40%);">-             in_progress = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        gbproxy_link_info_discard_messages(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-  link_info->imsi_acq_pending = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return in_progress;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    gbproxy_restart_imsi_acquisition(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-    link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Got identity response with IMSI, assuming the request had</span><br><span style="color: hsl(0, 100%, 40%);">- * been generated by the gbproxy */</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_flush_stored_messages(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     struct gbproxy_link_info* link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- struct msgb *stored_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Patch and flush stored messages towards the SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-  while ((stored_msg = msgb_dequeue_count(&link_info->stored_msgs,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         &link_info->stored_msgs_len))) {</span><br><span style="color: hsl(0, 100%, 40%);">-         struct gprs_gb_parse_context tmp_parse_ctx = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-               tmp_parse_ctx.to_bss = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               tmp_parse_ctx.peer_nsei = msgb_nsei(stored_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                int len_change = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             gprs_gb_parse_bssgp(msgb_bssgph(stored_msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                                msgb_bssgp_len(stored_msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                             &tmp_parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-                gbproxy_patch_bssgp(stored_msg, msgb_bssgph(stored_msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                                    msgb_bssgp_len(stored_msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                             bvc, link_info, &len_change,</span><br><span style="color: hsl(0, 100%, 40%);">-                                &tmp_parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                rc = gbproxy_update_link_state_after(bvc, link_info, now,</span><br><span style="color: hsl(0, 100%, 40%);">-                               &tmp_parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (rc == 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGPBVC_CAT(bvc, DLLC, LOGL_NOTICE, "link_info deleted while flushing stored messages\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                    msgb_free(stored_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                  return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               rc = gbprox_relay2sgsn(cfg, stored_msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                msgb_bvci(stored_msg), link_info->sgsn_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGPBVC_CAT(bvc, DLLC, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                           "failed to send stored message "</span><br><span style="color: hsl(0, 100%, 40%);">-                      "(%s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             tmp_parse_ctx.llc_msg_name ?</span><br><span style="color: hsl(0, 100%, 40%);">-                            tmp_parse_ctx.llc_msg_name : "BSSGP");</span><br><span style="color: hsl(0, 100%, 40%);">-           msgb_free(stored_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_gsm48_to_bvc(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                               struct gbproxy_link_info* link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                            uint16_t bvci,</span><br><span style="color: hsl(0, 100%, 40%);">-                          struct msgb *msg /* Takes msg ownership */)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Workaround to avoid N(U) collisions and to enable a restart</span><br><span style="color: hsl(0, 100%, 40%);">-   * of the IMSI acquisition procedure. This will work unless the</span><br><span style="color: hsl(0, 100%, 40%);">-  * SGSN has an initial V(UT) within [256-32, 256+n_retries]</span><br><span style="color: hsl(0, 100%, 40%);">-      * (see GSM 04.64, 8.4.2). */</span><br><span style="color: hsl(0, 100%, 40%);">-   gprs_push_llc_ui(msg, 0, GPRS_SAPI_GMM, link_info->vu_gen_tx_bss);</span><br><span style="color: hsl(0, 100%, 40%);">-   link_info->vu_gen_tx_bss = (link_info->vu_gen_tx_bss + 1) % 512;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  gprs_push_bssgp_dl_unitdata(msg, link_info->tlli.current);</span><br><span style="color: hsl(0, 100%, 40%);">-   msg->l3h = msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = gbprox_relay2peer(msg, bvc, bvci);</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_acquire_imsi(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                             struct gbproxy_link_info* link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                            uint16_t bvci)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct msgb *idreq_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Send IDENT REQ */</span><br><span style="color: hsl(0, 100%, 40%);">-    idreq_msg = gsm48_msgb_alloc_name("GSM 04.08 ACQ IMSI");</span><br><span style="color: hsl(0, 100%, 40%);">-      gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI);</span><br><span style="color: hsl(0, 100%, 40%);">-     gbproxy_gsm48_to_bvc(bvc, link_info, bvci, idreq_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_tx_detach_acc(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 struct gbproxy_link_info* link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                            uint16_t bvci)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct msgb *detacc_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Send DETACH ACC */</span><br><span style="color: hsl(0, 100%, 40%);">-   detacc_msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACC");</span><br><span style="color: hsl(0, 100%, 40%);">-      gprs_put_mo_detach_acc(detacc_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-     gbproxy_gsm48_to_bvc(bvc, link_info, bvci, detacc_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Return != 0 iff msg still needs to be processed */</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_imsi_acquisition(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                               time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-                             struct gbproxy_link_info* link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *stored_msg;</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-         return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info->imsi_acq_pending && link_info->imsi_len > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-           return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->g48_hdr)</span><br><span style="color: hsl(0, 100%, 40%);">-              switch (parse_ctx->g48_hdr->msg_type)</span><br><span style="color: hsl(0, 100%, 40%);">-             {</span><br><span style="color: hsl(0, 100%, 40%);">-               case GSM48_MT_GMM_RA_UPD_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-           case GSM48_MT_GMM_ATTACH_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (gbproxy_restart_imsi_acquisition(link_info)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                              LOGPBVC_CAT(bvc, DLLC, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    " IMSI acquisition was in progress "</span><br><span style="color: hsl(0, 100%, 40%);">-                                  "when receiving an %s.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                    parse_ctx->llc_msg_name);</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_DETACH_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   /* Nothing has been sent to the SGSN yet */</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (link_info->imsi_acq_pending) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           LOGPBVC_CAT(bvc, DLLC, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    "IMSI acquisition was in progress "</span><br><span style="color: hsl(0, 100%, 40%);">-                                   "when receiving a DETACH_REQ.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!parse_ctx->invalidate_tlli) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           LOGPBVC_CAT(bvc, DLLC, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    "IMSI not yet acquired, "</span><br><span style="color: hsl(0, 100%, 40%);">-                                     "faking a DETACH_ACC.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                               gbproxy_tx_detach_acc(bvc, link_info, msgb_bvci(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-                          parse_ctx->invalidate_tlli = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                      }</span><br><span style="color: hsl(0, 100%, 40%);">-                       gbproxy_reset_imsi_acquisition(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-                      gbproxy_update_link_state_after(bvc, link_info, now,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-                     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (link_info->imsi_acq_pending && link_info->imsi_len > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-          int is_ident_resp =</span><br><span style="color: hsl(0, 100%, 40%);">-                     parse_ctx->g48_hdr &&</span><br><span style="color: hsl(0, 100%, 40%);">-                        gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS &&</span><br><span style="color: hsl(0, 100%, 40%);">-                        gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGPBVC_CAT(bvc, DLLC, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                   "IMSI acquisition succeeded, "</span><br><span style="color: hsl(0, 100%, 40%);">-                "flushing stored messages\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           /* The IMSI is now available. If flushing the messages fails,</span><br><span style="color: hsl(0, 100%, 40%);">-            * then link_info has been deleted and we should return</span><br><span style="color: hsl(0, 100%, 40%);">-          * immediately. */</span><br><span style="color: hsl(0, 100%, 40%);">-              if (gbproxy_flush_stored_messages(bvc, now, link_info) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               gbproxy_reset_imsi_acquisition(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* This message is most probably the response to the ident</span><br><span style="color: hsl(0, 100%, 40%);">-               * request sent by gbproxy_acquire_imsi(). Don't forward it to</span><br><span style="color: hsl(0, 100%, 40%);">-               * the SGSN. */</span><br><span style="color: hsl(0, 100%, 40%);">-         return !is_ident_resp;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* The message cannot be processed since the IMSI is still missing */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* If queue is getting too large, drop oldest msgb before adding new one */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (cfg->stored_msgs_max_len > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               int exceeded_max_len = link_info->stored_msgs_len</span><br><span style="color: hsl(0, 100%, 40%);">-                               + 1 - cfg->stored_msgs_max_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           for (; exceeded_max_len > 0; exceeded_max_len--) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct msgb *msgb_drop;</span><br><span style="color: hsl(0, 100%, 40%);">-                 msgb_drop = msgb_dequeue_count(&link_info->stored_msgs,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                 &link_info->stored_msgs_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                     LOGPBVC_CAT(bvc, DLLC, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                            "Dropping stored msgb from list "</span><br><span style="color: hsl(0, 100%, 40%);">-                             "(!acq imsi, length %d, max_len exceeded)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                         link_info->stored_msgs_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                    msgb_free(msgb_drop);</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Enqueue unpatched messages */</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGPBVC_CAT(bvc, DLLC, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-            "IMSI acquisition in progress, "</span><br><span style="color: hsl(0, 100%, 40%);">-      "storing message (%s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-             parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      stored_msg = bssgp_msgb_copy(msg, "process_bssgp_ul");</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_enqueue_count(&link_info->stored_msgs, stored_msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                     &link_info->stored_msgs_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!link_info->imsi_acq_pending) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGPBVC_CAT(bvc, DLLC, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                    "IMSI is required but not available, "</span><br><span style="color: hsl(0, 100%, 40%);">-                "initiating identification procedure (%s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              gbproxy_acquire_imsi(bvc, link_info, msgb_bvci(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           /* There is no explicit retransmission handling, the</span><br><span style="color: hsl(0, 100%, 40%);">-             * implementation relies on the MS doing proper retransmissions</span><br><span style="color: hsl(0, 100%, 40%);">-          * of the triggering message instead */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         link_info->imsi_acq_pending = true;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct gbproxy_bvc *gbproxy_find_bvc(struct gbproxy_config *cfg,</span><br><span>                                      struct msgb *msg,</span><br><span>                                    struct gprs_gb_parse_context *parse_ctx)</span><br><span>@@ -571,220 +127,11 @@</span><br><span>                  msgb_nsei(msg), parse_ctx->to_bss ? "BSS" : "SGSN",</span><br><span>                   parse_ctx->pdu_type);</span><br><span>                /* Increment counter */</span><br><span style="color: hsl(0, 100%, 40%);">-         rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PATCH_PEER_ERR]);</span><br><span style="color: hsl(120, 100%, 40%);">+              rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_OTHER_ERR]);</span><br><span>  }</span><br><span>    return bvc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* patch BSSGP message */</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                               struct gbproxy_bvc *bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gprs_gb_parse_context parse_ctx = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- int len_change = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     time_t now;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct timespec ts = {0,};</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_link_info *link_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint32_t sgsn_nsei = cfg->nsip_sgsn_nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn &&</span><br><span style="color: hsl(0, 100%, 40%);">-        !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-           return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       parse_ctx.to_bss = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   parse_ctx.peer_nsei = msgb_nsei(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Parse BSSGP/LLC */</span><br><span style="color: hsl(0, 100%, 40%);">-   rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                          &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!rc && !parse_ctx.need_decryption) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DGPRS, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "NSE(%05u/BSS) patching: failed to parse invalid %s message\n",</span><br><span style="color: hsl(0, 100%, 40%);">-               msgb_nsei(msg), gprs_gb_message_name(&parse_ctx, "NS_UNITDATA"));</span><br><span style="color: hsl(0, 100%, 40%);">-            gprs_gb_log_parse_context(LOGL_NOTICE, &parse_ctx, "NS_UNITDATA");</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DGPRS, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "NSE(%05u/BSS) invalid message was: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    msgb_nsei(msg), msgb_hexdump(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Get bvc */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-               bvc = gbproxy_find_bvc(cfg, msg, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_clock_gettime(CLOCK_MONOTONIC, &ts);</span><br><span style="color: hsl(0, 100%, 40%);">-   now = ts.tv_sec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  parse_ctx.llc_msg_name);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     gprs_gb_log_parse_context(LOGL_DEBUG, &parse_ctx, "NS_UNITDATA");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- link_info = gbproxy_update_link_state_ul(bvc, now, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (parse_ctx.g48_hdr) {</span><br><span style="color: hsl(0, 100%, 40%);">-                switch (parse_ctx.g48_hdr->msg_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-               case GSM48_MT_GMM_ATTACH_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_DETACH_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_DETACH_REQS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_ATTACH_COMPL:</span><br><span style="color: hsl(0, 100%, 40%);">-                 rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_COMPLS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_RA_UPD_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REQS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_RA_UPD_COMPL:</span><br><span style="color: hsl(0, 100%, 40%);">-                 rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_COMPLS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_STATUS:</span><br><span style="color: hsl(0, 100%, 40%);">-                       rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_BSS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GSM_ACT_PDP_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                  rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REQS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GSM_DEACT_PDP_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-                        rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_REQS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (link_info && cfg->route_to_sgsn2) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (cfg->acquire_imsi && link_info->imsi_len == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                        sgsn_nsei = 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-             else if (gbproxy_imsi_matches(cfg, GBPROX_MATCH_ROUTING,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              link_info))</span><br><span style="color: hsl(0, 100%, 40%);">-                       sgsn_nsei = cfg->nsip_sgsn2_nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-          link_info->sgsn_nsei = sgsn_nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Handle IMSI acquisition */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (cfg->acquire_imsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = gbproxy_imsi_acquisition(bvc, msg, now, link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-          if (rc <= 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                 return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                     bvc, link_info, &len_change, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   gbproxy_update_link_state_after(bvc, link_info, now, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (sgsn_nsei != cfg->nsip_sgsn_nsei) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Send message directly to the selected SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-                rc = gbprox_relay2sgsn(cfg, msg, msgb_bvci(msg), sgsn_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-            /* Don't let the calling code handle the transmission */</span><br><span style="color: hsl(0, 100%, 40%);">-            return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* patch BSSGP message to use core_plmn.mcc/mnc on the SGSN side */</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                               struct gbproxy_bvc *bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_gb_parse_context parse_ctx = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- int len_change = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     time_t now;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct timespec ts = {0,};</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_link_info *link_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn &&</span><br><span style="color: hsl(0, 100%, 40%);">-        !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- parse_ctx.to_bss = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   parse_ctx.peer_nsei = msgb_nsei(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                          &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!rc && !parse_ctx.need_decryption) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DGPRS, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "NSE(%05u/SGSN) patching: failed to parse invalid %s message\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              msgb_nsei(msg), gprs_gb_message_name(&parse_ctx, "NS_UNITDATA"));</span><br><span style="color: hsl(0, 100%, 40%);">-            gprs_gb_log_parse_context(LOGL_NOTICE, &parse_ctx, "NS_UNITDATA");</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DGPRS, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "NSE(%05u/SGSN) invalid message was: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   msgb_nsei(msg), msgb_hexdump(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-                return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Get bvc */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-               bvc = gbproxy_find_bvc(cfg, msg, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-               return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_clock_gettime(CLOCK_MONOTONIC, &ts);</span><br><span style="color: hsl(0, 100%, 40%);">-   now = ts.tv_sec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (parse_ctx.g48_hdr) {</span><br><span style="color: hsl(0, 100%, 40%);">-                switch (parse_ctx.g48_hdr->msg_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-               case GSM48_MT_GMM_ATTACH_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_ACKS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_ATTACH_REJ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REJS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_DETACH_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_DETACH_ACKS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_RA_UPD_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_ACKS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_RA_UPD_REJ:</span><br><span style="color: hsl(0, 100%, 40%);">-                   rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REJS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GMM_STATUS:</span><br><span style="color: hsl(0, 100%, 40%);">-                       rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_SGSN]);</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GSM_ACT_PDP_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                  rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_ACKS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GSM_ACT_PDP_REJ:</span><br><span style="color: hsl(0, 100%, 40%);">-                  rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REJS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_GSM_DEACT_PDP_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                        rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_ACKS]);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       gprs_gb_log_parse_context(LOGL_DEBUG, &parse_ctx, "NS_UNITDATA");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- link_info = gbproxy_update_link_state_dl(bvc, now, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),</span><br><span style="color: hsl(0, 100%, 40%);">-                     bvc, link_info, &len_change, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   gbproxy_update_link_state_after(bvc, link_info, now, &parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* feed a message down the NS-VC associated with the specified bvc */</span><br><span> static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,</span><br><span>                       uint16_t ns_bvci, uint16_t sgsn_nsei)</span><br><span>@@ -924,9 +271,6 @@</span><br><span>                               uint16_t ns_bvci)</span><br><span> {</span><br><span>     struct gbproxy_bvc *bvc;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t pdu_type = bgph->pdu_type;</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc;</span><br><span> </span><br><span>  bvc = gbproxy_bvc_by_bvci(cfg, ns_bvci);</span><br><span>     if (!bvc) {</span><br><span>@@ -941,23 +285,6 @@</span><br><span>   /* TODO: Should we discard this message if the check fails */</span><br><span>        check_bvc_nsei(bvc, nsei);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  rc = gbprox_process_bssgp_ul(cfg, msg, bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!rc)</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (pdu_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case BSSGP_PDUT_FLOW_CONTROL_BVC:</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!cfg->route_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Send a copy to the secondary SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-         gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-          break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);</span><br><span> }</span><br><span> </span><br><span>@@ -967,8 +294,6 @@</span><br><span>                             uint16_t ns_bvci)</span><br><span> {</span><br><span>    struct gbproxy_bvc *bvc;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t pdu_type = bgph->pdu_type;</span><br><span> </span><br><span>    bvc = gbproxy_bvc_by_bvci(cfg, ns_bvci);</span><br><span> </span><br><span>@@ -991,29 +316,12 @@</span><br><span>                 return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg);</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   switch (pdu_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-   case BSSGP_PDUT_BVC_BLOCK_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_PDUT_BVC_UNBLOCK_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei)</span><br><span style="color: hsl(0, 100%, 40%);">-                  /* Hide ACKs from the secondary SGSN, the primary SGSN</span><br><span style="color: hsl(0, 100%, 40%);">-                   * is responsible to send them. */</span><br><span style="color: hsl(0, 100%, 40%);">-                      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Optionally patch the message */</span><br><span style="color: hsl(0, 100%, 40%);">-      gbprox_process_bssgp_dl(cfg, msg, bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      return gbprox_relay2peer(msg, bvc, ns_bvci);</span><br><span> }</span><br><span> </span><br><span> /* process a BVC-RESET message from the BSS side */</span><br><span> static int gbprox_rx_bvc_reset_from_bss(struct gbproxy_config *cfg, struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   uint16_t nsei, struct tlv_parsed *tp,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   int *copy_to_sgsn2)</span><br><span style="color: hsl(120, 100%, 40%);">+                                   uint16_t nsei, struct tlv_parsed *tp)</span><br><span> {</span><br><span>   struct gbproxy_bvc *from_bvc = NULL;</span><br><span>         uint16_t bvci;</span><br><span>@@ -1087,8 +395,6 @@</span><br><span>                        gsm48_parse_ra(&raid, from_bvc->ra);</span><br><span>                  LOGPBVC(from_bvc, LOGL_INFO, "Cell ID %s\n", osmo_rai_name(&raid));</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (cfg->route_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-                     *copy_to_sgsn2 = 1;</span><br><span>  }</span><br><span>    /* continue processing / relaying to SGSN[s] */</span><br><span>      return 1;</span><br><span>@@ -1105,7 +411,6 @@</span><br><span>     int data_len = msgb_bssgp_len(msg) - sizeof(*bgph);</span><br><span>  struct gbproxy_bvc *from_bvc = NULL;</span><br><span>         struct gprs_ra_id raid;</span><br><span style="color: hsl(0, 100%, 40%);">- int copy_to_sgsn2 = 0;</span><br><span>       int rc;</span><br><span> </span><br><span>  if (ns_bvci != 0 && ns_bvci != 1) {</span><br><span>@@ -1147,22 +452,13 @@</span><br><span>                 /* FIXME: This only supports one BSS per RA */</span><br><span>               break;</span><br><span>       case BSSGP_PDUT_BVC_RESET:</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = gbprox_rx_bvc_reset_from_bss(cfg, msg, nsei, &tp, &copy_to_sgsn2);</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = gbprox_rx_bvc_reset_from_bss(cfg, msg, nsei, &tp);</span><br><span>          /* if function retruns 0, we terminate processing here */</span><br><span>            if (rc == 0)</span><br><span>                         return 0;</span><br><span>            break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Normally, we can simply pass on all signalling messages from BSS to</span><br><span style="color: hsl(0, 100%, 40%);">-   * SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = gbprox_process_bssgp_ul(cfg, msg, from_bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!rc)</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (copy_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-              gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>       return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);</span><br><span> err_no_bvc:</span><br><span>  LOGP(DGPRS, LOGL_ERROR, "NSE(%05u/BSS) cannot find bvc based on NSEI\n",</span><br><span>@@ -1337,7 +633,6 @@</span><br><span>    }</span><br><span> </span><br><span>        msg = bssgp_msgb_copy(orig_msg, "rx_sig_from_sgsn");</span><br><span style="color: hsl(0, 100%, 40%);">-  gbprox_process_bssgp_dl(cfg, msg, NULL);</span><br><span>     /* Update message info */</span><br><span>    bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);</span><br><span>         data_len = msgb_bssgp_len(orig_msg) - sizeof(*bgph);</span><br><span>@@ -1348,8 +643,6 @@</span><br><span>          rc = rx_reset_from_sgsn(cfg, msg, orig_msg, &tp, nsei, ns_bvci);</span><br><span>                 break;</span><br><span>       case BSSGP_PDUT_BVC_RESET_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-          if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei)</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span>               /* simple case: BVCI IE is mandatory */</span><br><span>              if (!TLVP_PRES_LEN(&tp, BSSGP_IE_BVCI, 2))</span><br><span>                       goto err_mand_ie;</span><br><span>@@ -1462,8 +755,7 @@</span><br><span> </span><br><span> static int gbproxy_is_sgsn_nsei(struct gbproxy_config *cfg, uint16_t nsei)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return nsei == cfg->nsip_sgsn_nsei ||</span><br><span style="color: hsl(0, 100%, 40%);">-                (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+  return nsei == cfg->nsip_sgsn_nsei;</span><br><span> }</span><br><span> </span><br><span> int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg)</span><br><span>diff --git a/src/gbproxy/gb_proxy_ctrl.c b/src/gbproxy/gb_proxy_ctrl.c</span><br><span>index 157695d..21e56dd 100644</span><br><span>--- a/src/gbproxy/gb_proxy_ctrl.c</span><br><span>+++ b/src/gbproxy/gb_proxy_ctrl.c</span><br><span>@@ -64,10 +64,6 @@</span><br><span>       nse = gprs_ns2_nse_by_nsei(nsi, cfg->nsip_sgsn_nsei);</span><br><span>     if (nse)</span><br><span>             gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-   /* NS-VCs for SGSN2 */</span><br><span style="color: hsl(0, 100%, 40%);">-  nse = gprs_ns2_nse_by_nsei(nsi, cfg->nsip_sgsn2_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (nse)</span><br><span style="color: hsl(0, 100%, 40%);">-                gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);</span><br><span> </span><br><span>    /* NS-VCs for BSS peers */</span><br><span>   hash_for_each(cfg->bss_nses, i, nse_peer, list) {</span><br><span>diff --git a/src/gbproxy/gb_proxy_patch.c b/src/gbproxy/gb_proxy_patch.c</span><br><span>deleted file mode 100644</span><br><span>index e78d31b..0000000</span><br><span>--- a/src/gbproxy/gb_proxy_patch.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,482 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Gb-proxy message patching */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2014 by On-Waves</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gprs/gprs_msgb.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/gb_proxy.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/gprs_utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/gprs_gb_parse.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gprs/protocol/gsm_08_18.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/rate_ctr.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/apn.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-extern void *tall_sgsn_ctx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* patch RA identifier in place */</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                        int to_bss, const char *log_text)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_plmn_id old_plmn;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gprs_ra_id raid;</span><br><span style="color: hsl(0, 100%, 40%);">- enum gbproxy_bvc_ctr counter =</span><br><span style="color: hsl(0, 100%, 40%);">-          to_bss ?</span><br><span style="color: hsl(0, 100%, 40%);">-                GBPROX_PEER_CTR_RAID_PATCHED_SGSN :</span><br><span style="color: hsl(0, 100%, 40%);">-             GBPROX_PEER_CTR_RAID_PATCHED_BSS;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!state->local_plmn.mcc || !state->local_plmn.mnc)</span><br><span style="color: hsl(0, 100%, 40%);">-             return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- gsm48_parse_ra(&raid, (uint8_t *)raid_enc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- old_plmn = (struct osmo_plmn_id){</span><br><span style="color: hsl(0, 100%, 40%);">-               .mcc = raid.mcc,</span><br><span style="color: hsl(0, 100%, 40%);">-                .mnc = raid.mnc,</span><br><span style="color: hsl(0, 100%, 40%);">-                .mnc_3_digits = raid.mnc_3_digits,</span><br><span style="color: hsl(0, 100%, 40%);">-      };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!to_bss) {</span><br><span style="color: hsl(0, 100%, 40%);">-          /* BSS -> SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-            if (state->local_plmn.mcc)</span><br><span style="color: hsl(0, 100%, 40%);">-                   raid.mcc = cfg->core_plmn.mcc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (state->local_plmn.mnc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 raid.mnc = cfg->core_plmn.mnc;</span><br><span style="color: hsl(0, 100%, 40%);">-                       raid.mnc_3_digits = cfg->core_plmn.mnc_3_digits;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* SGSN -> BSS */</span><br><span style="color: hsl(0, 100%, 40%);">-            if (state->local_plmn.mcc)</span><br><span style="color: hsl(0, 100%, 40%);">-                   raid.mcc = state->local_plmn.mcc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            if (state->local_plmn.mnc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 raid.mnc = state->local_plmn.mnc;</span><br><span style="color: hsl(0, 100%, 40%);">-                    raid.mnc_3_digits = state->local_plmn.mnc_3_digits;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPBVC(bvc, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-             "Patching %s to %s: "</span><br><span style="color: hsl(0, 100%, 40%);">-         "%s-%d-%d -> %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-        log_text,</span><br><span style="color: hsl(0, 100%, 40%);">-       to_bss ? "BSS" : "SGSN",</span><br><span style="color: hsl(0, 100%, 40%);">-            osmo_plmn_name(&old_plmn), raid.lac, raid.rac,</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_rai_name(&raid));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- gsm48_encode_ra(raid_enc, &raid);</span><br><span style="color: hsl(0, 100%, 40%);">-   rate_ctr_inc(&bvc->ctrg->ctr[counter]);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_patch_apn_ie(struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                             uint8_t *apn_ie, size_t apn_ie_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                             struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                size_t *new_apn_ie_len, const char *log_text)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct apn_ie_hdr {</span><br><span style="color: hsl(0, 100%, 40%);">-             uint8_t iei;</span><br><span style="color: hsl(0, 100%, 40%);">-            uint8_t apn_len;</span><br><span style="color: hsl(0, 100%, 40%);">-                uint8_t apn[0];</span><br><span style="color: hsl(0, 100%, 40%);">- } *hdr = (void *)apn_ie;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        size_t apn_len = hdr->apn_len;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t *apn = hdr->apn;</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(apn_ie_len == apn_len + sizeof(struct apn_ie_hdr));</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(apn_ie_len > 2 && apn_ie_len <= 102);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (cfg->core_apn_size == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               char str1[110];</span><br><span style="color: hsl(0, 100%, 40%);">-         /* Remove the IE */</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPBVC(bvc, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "Patching %s to SGSN: Removing APN '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   log_text,</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_apn_to_str(str1, apn, apn_len));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              *new_apn_ie_len = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-            msgb_resize_area(msg, apn_ie, apn_ie_len, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Resize the IE */</span><br><span style="color: hsl(0, 100%, 40%);">-             char str1[110];</span><br><span style="color: hsl(0, 100%, 40%);">-         char str2[110];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         OSMO_ASSERT(cfg->core_apn_size <= 100);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGPBVC(bvc, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "Patching %s to SGSN: "</span><br><span style="color: hsl(0, 100%, 40%);">-               "Replacing APN '%s' -> '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    log_text,</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_apn_to_str(str1, apn, apn_len),</span><br><span style="color: hsl(0, 100%, 40%);">-                    osmo_apn_to_str(str2, cfg->core_apn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   cfg->core_apn_size));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         *new_apn_ie_len = cfg->core_apn_size + 2;</span><br><span style="color: hsl(0, 100%, 40%);">-            msgb_resize_area(msg, apn, apn_len, cfg->core_apn_size);</span><br><span style="color: hsl(0, 100%, 40%);">-             memcpy(apn, cfg->core_apn, cfg->core_apn_size);</span><br><span style="color: hsl(0, 100%, 40%);">-           hdr->apn_len = cfg->core_apn_size;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_APN_PATCHED]);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_patch_tlli(uint8_t *tlli_enc,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint32_t new_tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                              int to_bss, const char *log_text)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t tlli_be;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint32_t tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-  enum gbproxy_bvc_ctr counter =</span><br><span style="color: hsl(0, 100%, 40%);">-          to_bss ?</span><br><span style="color: hsl(0, 100%, 40%);">-                GBPROX_PEER_CTR_TLLI_PATCHED_SGSN :</span><br><span style="color: hsl(0, 100%, 40%);">-             GBPROX_PEER_CTR_TLLI_PATCHED_BSS;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(&tlli_be, tlli_enc, sizeof(tlli_be));</span><br><span style="color: hsl(0, 100%, 40%);">-        tlli = ntohl(tlli_be);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (tlli == new_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-           return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPBVC(bvc, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-             "Patching %ss: "</span><br><span style="color: hsl(0, 100%, 40%);">-      "Replacing %08x -> %08x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-        log_text, tlli, new_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tlli_be = htonl(new_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-      memcpy(tlli_enc, &tlli_be, sizeof(tlli_be));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        rate_ctr_inc(&bvc->ctrg->ctr[counter]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_patch_ptmsi(uint8_t *ptmsi_enc,</span><br><span style="color: hsl(0, 100%, 40%);">-                           struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint32_t new_ptmsi,</span><br><span style="color: hsl(0, 100%, 40%);">-                             int to_bss, const char *log_text)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       uint32_t ptmsi_be;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint32_t ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">- enum gbproxy_bvc_ctr counter =</span><br><span style="color: hsl(0, 100%, 40%);">-          to_bss ?</span><br><span style="color: hsl(0, 100%, 40%);">-                GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN :</span><br><span style="color: hsl(0, 100%, 40%);">-            GBPROX_PEER_CTR_PTMSI_PATCHED_BSS;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(&ptmsi_be, ptmsi_enc, sizeof(ptmsi_be));</span><br><span style="color: hsl(0, 100%, 40%);">-     ptmsi = ntohl(ptmsi_be);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ptmsi == new_ptmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-         return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPBVC(bvc, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-             "Patching %ss: "</span><br><span style="color: hsl(0, 100%, 40%);">-      "Replacing %08x -> %08x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-        log_text, ptmsi, new_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ptmsi_be = htonl(new_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(ptmsi_enc, &ptmsi_be, sizeof(ptmsi_be));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     rate_ctr_inc(&bvc->ctrg->ctr[counter]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,</span><br><span style="color: hsl(0, 100%, 40%);">-              struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                struct gbproxy_link_info *link_info, int *len_change,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;</span><br><span style="color: hsl(0, 100%, 40%);">-    int have_patched = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   int fcs;</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->ptmsi_enc && link_info &&</span><br><span style="color: hsl(0, 100%, 40%);">-         !parse_ctx->old_raid_is_foreign && cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-                uint32_t ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-         if (parse_ctx->to_bss)</span><br><span style="color: hsl(0, 100%, 40%);">-                       ptmsi = link_info->tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-               else</span><br><span style="color: hsl(0, 100%, 40%);">-                    ptmsi = link_info->sgsn_tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          if (ptmsi != GSM_RESERVED_TMSI) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (gbproxy_patch_ptmsi(parse_ctx->ptmsi_enc, bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           ptmsi, parse_ctx->to_bss, "P-TMSI"))</span><br><span style="color: hsl(0, 100%, 40%);">-                               have_patched = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-               } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* TODO: invalidate old RAI if present (see below) */</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->new_ptmsi_enc && link_info && cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-          uint32_t ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-         if (parse_ctx->to_bss)</span><br><span style="color: hsl(0, 100%, 40%);">-                       ptmsi = link_info->tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-               else</span><br><span style="color: hsl(0, 100%, 40%);">-                    ptmsi = link_info->sgsn_tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          OSMO_ASSERT(ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-             if (gbproxy_patch_ptmsi(parse_ctx->new_ptmsi_enc, bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       ptmsi, parse_ctx->to_bss, "new P-TMSI"))</span><br><span style="color: hsl(0, 100%, 40%);">-                   have_patched = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->raid_enc) {</span><br><span style="color: hsl(0, 100%, 40%);">-           gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->raid_enc, bvc, parse_ctx->to_bss,</span><br><span style="color: hsl(0, 100%, 40%);">-                                parse_ctx->llc_msg_name);</span><br><span style="color: hsl(0, 100%, 40%);">-         have_patched = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->old_raid_enc && !parse_ctx->old_raid_is_foreign) {</span><br><span style="color: hsl(0, 100%, 40%);">-         /* TODO: Patch to invalid if P-TMSI unknown. */</span><br><span style="color: hsl(0, 100%, 40%);">-         gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->old_raid_enc, bvc, parse_ctx->to_bss,</span><br><span style="color: hsl(0, 100%, 40%);">-                            parse_ctx->llc_msg_name);</span><br><span style="color: hsl(0, 100%, 40%);">-         have_patched = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->apn_ie &&</span><br><span style="color: hsl(0, 100%, 40%);">-         cfg->core_apn &&</span><br><span style="color: hsl(0, 100%, 40%);">-     !parse_ctx->to_bss &&</span><br><span style="color: hsl(0, 100%, 40%);">-        gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING, link_info) &&</span><br><span style="color: hsl(0, 100%, 40%);">-          cfg->core_apn) {</span><br><span style="color: hsl(0, 100%, 40%);">-         size_t new_len;</span><br><span style="color: hsl(0, 100%, 40%);">-         gbproxy_patch_apn_ie(msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    parse_ctx->apn_ie, parse_ctx->apn_ie_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 bvc, &new_len, parse_ctx->llc_msg_name);</span><br><span style="color: hsl(0, 100%, 40%);">-            *len_change += (int)new_len - (int)parse_ctx->apn_ie_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            have_patched = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (have_patched) {</span><br><span style="color: hsl(0, 100%, 40%);">-             llc_len += *len_change;</span><br><span style="color: hsl(0, 100%, 40%);">-         ghp->crc_length += *len_change;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Fix FCS */</span><br><span style="color: hsl(0, 100%, 40%);">-           fcs = gprs_llc_fcs(llc, ghp->crc_length);</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGPBVC_CAT(bvc, DLLC, LOGL_DEBUG, "Updated LLC message, CRC: %06x -> %06x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  ghp->fcs, fcs);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         llc[llc_len - 3] = fcs & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-              llc[llc_len - 2] = (fcs >> 8) & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-         llc[llc_len - 1] = (fcs >> 16) & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return have_patched;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* patch BSSGP message to use core_plmn.mcc/mnc on the SGSN side */</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gbproxy_link_info *link_info, int *len_change,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      const char *err_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    int err_ctr = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->bssgp_raid_enc)</span><br><span style="color: hsl(0, 100%, 40%);">-               gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->bssgp_raid_enc, bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                parse_ctx->to_bss, "BSSGP");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (parse_ctx->need_decryption &&</span><br><span style="color: hsl(0, 100%, 40%);">-        (cfg->patch_ptmsi || cfg->core_apn)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Patching LLC messages has been requested</span><br><span style="color: hsl(0, 100%, 40%);">-              * explicitly, but the message (including the</span><br><span style="color: hsl(0, 100%, 40%);">-            * type) is encrypted, so we possibly fail to</span><br><span style="color: hsl(0, 100%, 40%);">-            * patch the LLC part of the message. */</span><br><span style="color: hsl(0, 100%, 40%);">-                err_ctr = GBPROX_PEER_CTR_PATCH_CRYPT_ERR;</span><br><span style="color: hsl(0, 100%, 40%);">-              err_info = "GMM message is encrypted";</span><br><span style="color: hsl(0, 100%, 40%);">-                goto patch_error;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info && parse_ctx->tlli_enc && parse_ctx->to_bss) {</span><br><span style="color: hsl(0, 100%, 40%);">-             /* Happens with unknown (not cached) TLLI coming from</span><br><span style="color: hsl(0, 100%, 40%);">-            * the SGSN */</span><br><span style="color: hsl(0, 100%, 40%);">-          /* TODO: What shall be done with the message in this case? */</span><br><span style="color: hsl(0, 100%, 40%);">-           err_ctr = GBPROX_PEER_CTR_TLLI_UNKNOWN;</span><br><span style="color: hsl(0, 100%, 40%);">-         err_info = "TLLI sent by the SGSN is unknown";</span><br><span style="color: hsl(0, 100%, 40%);">-                goto patch_error;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (parse_ctx->tlli_enc && cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-            uint32_t tlli = gbproxy_map_tlli(parse_ctx->tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             link_info, parse_ctx->to_bss);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (tlli) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     gbproxy_patch_tlli(parse_ctx->tlli_enc, bvc, tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      parse_ctx->to_bss, "TLLI");</span><br><span style="color: hsl(0, 100%, 40%);">-                     parse_ctx->tlli = tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-              } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* Internal error */</span><br><span style="color: hsl(0, 100%, 40%);">-                    err_ctr = GBPROX_PEER_CTR_PATCH_ERR;</span><br><span style="color: hsl(0, 100%, 40%);">-                    err_info = "Replacement TLLI is 0";</span><br><span style="color: hsl(0, 100%, 40%);">-                   goto patch_error;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->bssgp_ptmsi_enc && cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-             uint32_t ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-         if (parse_ctx->to_bss)</span><br><span style="color: hsl(0, 100%, 40%);">-                       ptmsi = link_info->tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-               else</span><br><span style="color: hsl(0, 100%, 40%);">-                    ptmsi = link_info->sgsn_tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          if (ptmsi != GSM_RESERVED_TMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-                 gbproxy_patch_ptmsi(</span><br><span style="color: hsl(0, 100%, 40%);">-                            parse_ctx->bssgp_ptmsi_enc, bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                             ptmsi, parse_ctx->to_bss, "BSSGP P-TMSI");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->llc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                uint8_t *llc = parse_ctx->llc;</span><br><span style="color: hsl(0, 100%, 40%);">-               size_t llc_len = parse_ctx->llc_len;</span><br><span style="color: hsl(0, 100%, 40%);">-         int llc_len_change = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         gbproxy_patch_llc(msg, llc, llc_len, bvc, link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                              &llc_len_change, parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Note that the APN might have been resized here, but no</span><br><span style="color: hsl(0, 100%, 40%);">-                * pointer int the parse_ctx will refer to an adress after the</span><br><span style="color: hsl(0, 100%, 40%);">-           * APN. So it's possible to patch first and do the TLLI</span><br><span style="color: hsl(0, 100%, 40%);">-              * handling afterwards. */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (llc_len_change) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   llc_len += llc_len_change;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                      /* Fix LLC IE len */</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* TODO: This is a kludge, but the a pointer to the</span><br><span style="color: hsl(0, 100%, 40%);">-                      * start of the IE is not available here */</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (llc[-2] == BSSGP_IE_LLC_PDU && llc[-1] & 0x80) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                /* most probably a one byte length */</span><br><span style="color: hsl(0, 100%, 40%);">-                           if (llc_len > 127) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                 err_info = "Cannot increase size";</span><br><span style="color: hsl(0, 100%, 40%);">-                                    err_ctr = GBPROX_PEER_CTR_PATCH_ERR;</span><br><span style="color: hsl(0, 100%, 40%);">-                                    goto patch_error;</span><br><span style="color: hsl(0, 100%, 40%);">-                               }</span><br><span style="color: hsl(0, 100%, 40%);">-                               llc[-1] = llc_len | 0x80;</span><br><span style="color: hsl(0, 100%, 40%);">-                       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                llc[-2] = (llc_len >> 8) & 0x7f;</span><br><span style="color: hsl(0, 100%, 40%);">-                              llc[-1] = llc_len & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-                   }</span><br><span style="color: hsl(0, 100%, 40%);">-                       *len_change += llc_len_change;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Note that the tp struct might contain invalid pointers here</span><br><span style="color: hsl(0, 100%, 40%);">-           * if the LLC field has changed its size */</span><br><span style="color: hsl(0, 100%, 40%);">-             parse_ctx->llc_len = llc_len;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-       return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-patch_error:</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(err_ctr >= 0);</span><br><span style="color: hsl(0, 100%, 40%);">-   rate_ctr_inc(&bvc->ctrg->ctr[err_ctr]);</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPBVC(bvc, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-             "NSE(%05u/%s) failed to patch BSSGP message as requested: %s.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-             msgb_nsei(msg), parse_ctx->to_bss ? "SGSN" : "BSS",</span><br><span style="color: hsl(0, 100%, 40%);">-      err_info);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_clear_patch_filter(struct gbproxy_match *match)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (match->enable) {</span><br><span style="color: hsl(0, 100%, 40%);">-         regfree(&match->re_comp);</span><br><span style="color: hsl(0, 100%, 40%);">-                match->enable = false;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       talloc_free(match->re_str);</span><br><span style="color: hsl(0, 100%, 40%);">-  match->re_str = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_set_patch_filter(struct gbproxy_match *match, const char *filter,</span><br><span style="color: hsl(0, 100%, 40%);">-          const char **err_msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  static char err_buf[300];</span><br><span style="color: hsl(0, 100%, 40%);">-       int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- gbproxy_clear_patch_filter(match);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!filter)</span><br><span style="color: hsl(0, 100%, 40%);">-            return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = regcomp(&match->re_comp, filter,</span><br><span style="color: hsl(0, 100%, 40%);">-                 REG_EXTENDED | REG_NOSUB | REG_ICASE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (rc == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-          match->enable = true;</span><br><span style="color: hsl(0, 100%, 40%);">-                match->re_str = talloc_strdup(tall_sgsn_ctx, filter);</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (err_msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-          regerror(rc, &match->re_comp,</span><br><span style="color: hsl(0, 100%, 40%);">-                     err_buf, sizeof(err_buf));</span><br><span style="color: hsl(0, 100%, 40%);">-             *err_msg = err_buf;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_check_imsi(struct gbproxy_match *match,</span><br><span style="color: hsl(0, 100%, 40%);">-                 const uint8_t *imsi, size_t imsi_len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- struct osmo_mobile_identity mi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!match->enable)</span><br><span style="color: hsl(0, 100%, 40%);">-          return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = osmo_mobile_identity_decode(&mi, imsi, imsi_len, false);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc || mi.type != GSM_MI_TYPE_IMSI) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DGPRS, LOGL_NOTICE, "Invalid IMSI %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_hexdump(imsi, imsi_len));</span><br><span style="color: hsl(0, 100%, 40%);">-             return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGP(DGPRS, LOGL_DEBUG, "Checking IMSI '%s' (%d)\n", mi.imsi, rc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    rc = regexec(&match->re_comp, mi.imsi, 0, NULL, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (rc == REG_NOMATCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DGPRS, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                 "IMSI '%s' doesn't match pattern '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 mi.imsi, match->re_str);</span><br><span style="color: hsl(0, 100%, 40%);">-              return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/gbproxy/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c</span><br><span>index f5a4376..67f6841 100644</span><br><span>--- a/src/gbproxy/gb_proxy_peer.c</span><br><span>+++ b/src/gbproxy/gb_proxy_peer.c</span><br><span>@@ -41,34 +41,6 @@</span><br><span>     { "dropped",     "BVC blocked, dropped packet     " },</span><br><span>   { "inv-nsei",    "NSEI mismatch                   " },</span><br><span>   { "tx-err",      "NS Transmission error           " },</span><br><span style="color: hsl(0, 100%, 40%);">-      { "raid-mod:bss",  "RAID patched              (BSS )" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "raid-mod:sgsn", "RAID patched              (SGSN)" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "apn-mod:sgsn",  "APN patched                     " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "tlli-mod:bss",  "TLLI patched              (BSS )" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "tlli-mod:sgsn", "TLLI patched              (SGSN)" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "ptmsi-mod:bss", "P-TMSI patched            (BSS )" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "ptmsi-mod:sgsn","P-TMSI patched            (SGSN)" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "mod-crypt-err", "Patch error: encrypted          " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "mod-err",     "Patch error: other              " },</span><br><span style="color: hsl(0, 100%, 40%);">-      { "attach-reqs",   "Attach Request count            " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "attach-rejs",   "Attach Reject count             " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "attach-acks",   "Attach Accept count             " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "attach-cpls",   "Attach Completed count          " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "ra-upd-reqs",   "RoutingArea Update Request count" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "ra-upd-rejs",   "RoutingArea Update Reject count " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "ra-upd-acks",   "RoutingArea Update Accept count " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "ra-upd-cpls",   "RoutingArea Update Compltd count" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "gmm-status",    "GMM Status count           (BSS)" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "gmm-status",    "GMM Status count          (SGSN)" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "detach-reqs",   "Detach Request count            " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "detach-acks",   "Detach Accept count             " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "pdp-act-reqs",  "PDP Activation Request count    " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "pdp-act-rejs",  "PDP Activation Reject count     " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "pdp-act-acks",  "PDP Activation Accept count     " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "pdp-deact-reqs","PDP Deactivation Request count  " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "pdp-deact-acks","PDP Deactivation Accept count   " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "tlli-unknown",  "TLLI from SGSN unknown          " },</span><br><span style="color: hsl(0, 100%, 40%);">-    { "tlli-cache",    "TLLI cache size                 " },</span><br><span> };</span><br><span> </span><br><span> osmo_static_assert(ARRAY_SIZE(bvc_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);</span><br><span>@@ -201,24 +173,6 @@</span><br><span>  return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void clean_stale_timer_cb(void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      time_t now;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct timespec ts = {0,};</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_bvc *bvc = (struct gbproxy_bvc *) data;</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_clock_gettime(CLOCK_MONOTONIC, &ts);</span><br><span style="color: hsl(0, 100%, 40%);">-   now = ts.tv_sec;</span><br><span style="color: hsl(0, 100%, 40%);">-        gbproxy_remove_stale_link_infos(bvc, now);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (cfg->clean_stale_timer_freq != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                osmo_timer_schedule(&bvc->clean_stale_timer,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     cfg->clean_stale_timer_freq, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci)</span><br><span> {</span><br><span>   struct gbproxy_bvc *bvc;</span><br><span>@@ -240,13 +194,6 @@</span><br><span> </span><br><span>  hash_add(nse->bvcs, &bvc->list, bvc->bvci);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    INIT_LLIST_HEAD(&bvc->patch_state.logical_links);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_timer_setup(&bvc->clean_stale_timer, clean_stale_timer_cb, bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (cfg->clean_stale_timer_freq != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                osmo_timer_schedule(&bvc->clean_stale_timer,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     cfg->clean_stale_timer_freq, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>  return bvc;</span><br><span> }</span><br><span> </span><br><span>@@ -256,8 +203,6 @@</span><br><span>           return;</span><br><span> </span><br><span>  hash_del(&bvc->list);</span><br><span style="color: hsl(0, 100%, 40%);">-    osmo_timer_del(&bvc->clean_stale_timer);</span><br><span style="color: hsl(0, 100%, 40%);">- gbproxy_delete_link_infos(bvc);</span><br><span> </span><br><span>  rate_ctr_group_free(bvc->ctrg);</span><br><span>   bvc->ctrg = NULL;</span><br><span>diff --git a/src/gbproxy/gb_proxy_tlli.c b/src/gbproxy/gb_proxy_tlli.c</span><br><span>deleted file mode 100644</span><br><span>index 0ea3a93..0000000</span><br><span>--- a/src/gbproxy/gb_proxy_tlli.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,746 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Gb-proxy TLLI state handling */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2014 by On-Waves</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/gsm48.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/gb_proxy.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/gprs_utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/gprs_gb_parse.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/gsm_utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/rate_ctr.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/talloc.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_tlli(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      uint32_t tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-              return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_for_each_entry(link_info, &state->logical_links, list)</span><br><span style="color: hsl(0, 100%, 40%);">-             if (link_info->tlli.current == tlli ||</span><br><span style="color: hsl(0, 100%, 40%);">-                   link_info->tlli.assigned == tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-                        return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_ptmsi(</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t ptmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ptmsi == GSM_RESERVED_TMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-         return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_for_each_entry(link_info, &state->logical_links, list)</span><br><span style="color: hsl(0, 100%, 40%);">-             if (link_info->tlli.ptmsi == ptmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-                  return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-              return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Don't care about the NSEI */</span><br><span style="color: hsl(0, 100%, 40%);">-     llist_for_each_entry(link_info, &state->logical_links, list)</span><br><span style="color: hsl(0, 100%, 40%);">-             if (link_info->sgsn_tlli.current == tlli ||</span><br><span style="color: hsl(0, 100%, 40%);">-               link_info->sgsn_tlli.assigned == tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-                  return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli(</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t tlli, uint32_t sgsn_nsei)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-              return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_for_each_entry(link_info, &state->logical_links, list)</span><br><span style="color: hsl(0, 100%, 40%);">-             if ((link_info->sgsn_tlli.current == tlli ||</span><br><span style="color: hsl(0, 100%, 40%);">-              link_info->sgsn_tlli.assigned == tlli) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                   link_info->sgsn_nsei == sgsn_nsei)</span><br><span style="color: hsl(0, 100%, 40%);">-                       return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_by_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        const uint8_t *imsi,</span><br><span style="color: hsl(0, 100%, 40%);">-    size_t imsi_len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!gprs_is_mi_imsi(imsi, imsi_len))</span><br><span style="color: hsl(0, 100%, 40%);">-           return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_for_each_entry(link_info, &state->logical_links, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (link_info->imsi_len != imsi_len)</span><br><span style="color: hsl(0, 100%, 40%);">-                 continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               if (memcmp(link_info->imsi, imsi, imsi_len) != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                    continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct msgb *msg, *nxt;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each_entry_safe(msg, nxt, &link_info->stored_msgs, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-             llist_del(&msg->list);</span><br><span style="color: hsl(0, 100%, 40%);">-           msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_delete_link_info(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   gbproxy_link_info_discard_messages(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  llist_del(&link_info->list);</span><br><span style="color: hsl(0, 100%, 40%);">-     talloc_free(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">- state->logical_link_count -= 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bvc->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =</span><br><span style="color: hsl(0, 100%, 40%);">-         state->logical_link_count;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_delete_link_infos(struct gbproxy_bvc *bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_link_info *link_info, *nxt;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list)</span><br><span style="color: hsl(0, 100%, 40%);">-           gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(state->logical_link_count == 0);</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(llist_empty(&state->logical_links));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_attach_link_info(struct gbproxy_bvc *bvc, time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-                            struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   link_info->timestamp = now;</span><br><span style="color: hsl(0, 100%, 40%);">-  llist_add(&link_info->list, &state->logical_links);</span><br><span style="color: hsl(0, 100%, 40%);">-       state->logical_link_count += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bvc->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =</span><br><span style="color: hsl(0, 100%, 40%);">-         state->logical_link_count;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_remove_stale_link_infos(struct gbproxy_bvc *bvc, time_t now)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-   int exceeded_max_len = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       int deleted_count = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-  int check_for_age;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (cfg->tlli_max_len > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                exceeded_max_len =</span><br><span style="color: hsl(0, 100%, 40%);">-                      state->logical_link_count - cfg->tlli_max_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    check_for_age = cfg->tlli_max_age > 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    for (; exceeded_max_len > 0; exceeded_max_len--) {</span><br><span style="color: hsl(0, 100%, 40%);">-           struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-            OSMO_ASSERT(!llist_empty(&state->logical_links));</span><br><span style="color: hsl(0, 100%, 40%);">-                link_info = llist_entry(state->logical_links.prev,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   struct gbproxy_link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       list);</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Removing TLLI %08x from list "</span><br><span style="color: hsl(0, 100%, 40%);">-               "(stale, length %d, max_len exceeded)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     link_info->tlli.current, state->logical_link_count);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-               deleted_count += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       while (check_for_age && !llist_empty(&state->logical_links)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           time_t age;</span><br><span style="color: hsl(0, 100%, 40%);">-             struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-            link_info = llist_entry(state->logical_links.prev,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   struct gbproxy_link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       list);</span><br><span style="color: hsl(0, 100%, 40%);">-          age = now - link_info->timestamp;</span><br><span style="color: hsl(0, 100%, 40%);">-            /* age < 0 only happens after system time jumps, discard entry */</span><br><span style="color: hsl(0, 100%, 40%);">-            if (age <= cfg->tlli_max_age && age >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    check_for_age = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                      continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Removing TLLI %08x from list "</span><br><span style="color: hsl(0, 100%, 40%);">-               "(stale, age %d, max_age exceeded)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                link_info->tlli.current, (int)age);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-               deleted_count += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return deleted_count;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_bvc *bvc)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    link_info = talloc_zero(bvc, struct gbproxy_link_info);</span><br><span style="color: hsl(0, 100%, 40%);">- link_info->tlli.ptmsi = GSM_RESERVED_TMSI;</span><br><span style="color: hsl(0, 100%, 40%);">-   link_info->sgsn_tlli.ptmsi = GSM_RESERVED_TMSI;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   INIT_LLIST_HEAD(&link_info->stored_msgs);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_detach_link_info(</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   llist_del(&link_info->list);</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(state->logical_link_count > 0);</span><br><span style="color: hsl(0, 100%, 40%);">-       state->logical_link_count -= 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bvc->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =</span><br><span style="color: hsl(0, 100%, 40%);">-         state->logical_link_count;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_update_link_info(struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                              const uint8_t *imsi, size_t imsi_len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!gprs_is_mi_imsi(imsi, imsi_len))</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- link_info->imsi_len = imsi_len;</span><br><span style="color: hsl(0, 100%, 40%);">-      link_info->imsi =</span><br><span style="color: hsl(0, 100%, 40%);">-            talloc_realloc_size(link_info, link_info->imsi, imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_ASSERT(link_info->imsi != NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-        memcpy(link_info->imsi, imsi, imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void gbproxy_reassign_tlli(struct gbproxy_tlli_state *tlli_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                      struct gbproxy_bvc *bvc, uint32_t new_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (new_tlli == tlli_state->current)</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-      "The TLLI has been reassigned from %08x to %08x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-           tlli_state->current, new_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Remember assigned TLLI */</span><br><span style="color: hsl(0, 100%, 40%);">-    tlli_state->assigned = new_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-     tlli_state->bss_validated = false;</span><br><span style="color: hsl(0, 100%, 40%);">-   tlli_state->net_validated = false;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t gbproxy_map_tlli(uint32_t other_tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                      struct gbproxy_link_info *link_info, int to_bss)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     uint32_t tlli = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_tlli_state *src, *dst;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (to_bss) {</span><br><span style="color: hsl(0, 100%, 40%);">-           src = &link_info->sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-             dst = &link_info->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-  } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                src = &link_info->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-          dst = &link_info->sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (src->current == other_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-              tlli = dst->current;</span><br><span style="color: hsl(0, 100%, 40%);">- else if (src->assigned == other_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-                tlli = dst->assigned;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_validate_tlli(struct gbproxy_tlli_state *tlli_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                             uint32_t tlli, int to_bss)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   LOGP(DGPRS, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-      "%s({current = %08x, assigned = %08x, net_vld = %d, bss_vld = %d}, %08x)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-          __func__, tlli_state->current, tlli_state->assigned,</span><br><span style="color: hsl(0, 100%, 40%);">-      tlli_state->net_validated, tlli_state->bss_validated, tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!tlli_state->assigned || tlli_state->assigned != tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-                return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* TODO: Is this ok? Check spec */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (gprs_tlli_type(tlli) != TLLI_LOCAL)</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* See GSM 04.08, 4.7.1.5 */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (to_bss)</span><br><span style="color: hsl(0, 100%, 40%);">-             tlli_state->net_validated = true;</span><br><span style="color: hsl(0, 100%, 40%);">-    else</span><br><span style="color: hsl(0, 100%, 40%);">-            tlli_state->bss_validated = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!tlli_state->bss_validated || !tlli_state->net_validated)</span><br><span style="color: hsl(0, 100%, 40%);">-             return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DGPRS, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-       "The TLLI %08x has been validated (was %08x)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-      tlli_state->assigned, tlli_state->current);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  tlli_state->current = tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-  tlli_state->assigned = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_touch_link_info(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    time_t now)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        gbproxy_detach_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-       gbproxy_attach_link_info(bvc, now, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_unregister_link_info(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-         return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (link_info->tlli.ptmsi == GSM_RESERVED_TMSI && !link_info->imsi_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Removing TLLI %08x from list (P-TMSI or IMSI are not set)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                link_info->tlli.current);</span><br><span style="color: hsl(0, 100%, 40%);">-               gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-               return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       link_info->tlli.current = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- link_info->tlli.assigned = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        link_info->sgsn_tlli.current = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    link_info->sgsn_tlli.assigned = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   link_info->is_deregistered = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   gbproxy_reset_link(link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_imsi_matches(struct gbproxy_config *cfg,</span><br><span style="color: hsl(0, 100%, 40%);">-                   enum gbproxy_match_id match_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_match *match;</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(match_id >= 0 && match_id < ARRAY_SIZE(cfg->matches));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     match = &cfg->matches[match_id];</span><br><span style="color: hsl(0, 100%, 40%);">- if (!match->enable)</span><br><span style="color: hsl(0, 100%, 40%);">-          return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return link_info != NULL && link_info->is_matching[match_id];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_assign_imsi(struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                    struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int imsi_matches;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *other_link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-      enum gbproxy_match_id match_id;</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Make sure that there is a second entry with the same IMSI */</span><br><span style="color: hsl(0, 100%, 40%);">- other_link_info = gbproxy_link_info_by_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">-            bvc, parse_ctx->imsi, parse_ctx->imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (other_link_info && other_link_info != link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-          struct osmo_mobile_identity mi;</span><br><span style="color: hsl(0, 100%, 40%);">-         if (osmo_mobile_identity_decode(&mi, parse_ctx->imsi, parse_ctx->imsi_len, false)</span><br><span style="color: hsl(0, 100%, 40%);">-                 || mi.type != GSM_MI_TYPE_IMSI) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   LOGPBVC(bvc, LOGL_ERROR, "Failed to decode Mobile Identity\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                      "Removing TLLI %08x from list (IMSI %s re-used)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           other_link_info->tlli.current, mi.imsi);</span><br><span style="color: hsl(0, 100%, 40%);">-                        gbproxy_delete_link_info(bvc, other_link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Update the IMSI field */</span><br><span style="color: hsl(0, 100%, 40%);">-     gbproxy_update_link_info(link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                              parse_ctx->imsi, parse_ctx->imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Check, whether the IMSI matches */</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_ASSERT(ARRAY_SIZE(link_info->is_matching) ==</span><br><span style="color: hsl(0, 100%, 40%);">-                ARRAY_SIZE(cfg->matches));</span><br><span style="color: hsl(0, 100%, 40%);">-       for (match_id = 0; match_id < ARRAY_SIZE(link_info->is_matching);</span><br><span style="color: hsl(0, 100%, 40%);">-      ++match_id) {</span><br><span style="color: hsl(0, 100%, 40%);">-              imsi_matches = gbproxy_check_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">-                      &cfg->matches[match_id],</span><br><span style="color: hsl(0, 100%, 40%);">-                 parse_ctx->imsi, parse_ctx->imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (imsi_matches >= 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                       link_info->is_matching[match_id] = imsi_matches ? true : false;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a,</span><br><span style="color: hsl(0, 100%, 40%);">-                           const struct gbproxy_tlli_state *b)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      if (a->current && a->current == b->current)</span><br><span style="color: hsl(0, 100%, 40%);">-            return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (a->assigned && a->assigned == b->assigned)</span><br><span style="color: hsl(0, 100%, 40%);">-         return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (a->ptmsi != GSM_RESERVED_TMSI && a->ptmsi == b->ptmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-             return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void gbproxy_remove_matching_link_infos(</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *info, *nxt;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Make sure that there is no second entry with the same P-TMSI or TLLI */</span><br><span style="color: hsl(0, 100%, 40%);">-      llist_for_each_entry_safe(info, nxt, &state->logical_links, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (info == link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-                  continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!gbproxy_tlli_match(&link_info->tlli, &info->tlli) &&</span><br><span style="color: hsl(0, 100%, 40%);">-             (link_info->sgsn_nsei != info->sgsn_nsei ||</span><br><span style="color: hsl(0, 100%, 40%);">-                !gbproxy_tlli_match(&link_info->sgsn_tlli, &info->sgsn_tlli)))</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Removing TLLI %08x from list (P-TMSI/TLLI re-used)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-               info->tlli.current);</span><br><span style="color: hsl(0, 100%, 40%);">-            gbproxy_delete_link_info(bvc, info);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct gbproxy_link_info *gbproxy_get_link_info_ul(</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        int *tlli_is_valid,</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *link_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (parse_ctx->tlli_enc) {</span><br><span style="color: hsl(0, 100%, 40%);">-           link_info = gbproxy_link_info_by_tlli(bvc, parse_ctx->tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         if (link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        *tlli_is_valid = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                     return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       *tlli_is_valid = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!link_info && parse_ctx->imsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-         link_info = gbproxy_link_info_by_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">-                  bvc, parse_ctx->imsi, parse_ctx->imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info && parse_ctx->ptmsi_enc && !parse_ctx->old_raid_is_foreign) {</span><br><span style="color: hsl(0, 100%, 40%);">-              uint32_t bss_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-             gprs_parse_tmsi(parse_ctx->ptmsi_enc, &bss_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-               link_info = gbproxy_link_info_by_ptmsi(bvc, bss_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-         return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    link_info->is_deregistered = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_update_link_state_ul(</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-    int tlli_is_valid;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       link_info = gbproxy_get_link_info_ul(bvc, &tlli_is_valid, parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->tlli_enc && parse_ctx->llc) {</span><br><span style="color: hsl(0, 100%, 40%);">-              uint32_t sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             if (!link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGPBVC(bvc, LOGL_INFO, "Adding TLLI %08x to list\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     parse_ctx->tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-                        link_info = gbproxy_link_info_alloc(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-                       gbproxy_attach_link_info(bvc, now, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                  /* Setup TLLIs */</span><br><span style="color: hsl(0, 100%, 40%);">-                       sgsn_tlli = gbproxy_make_sgsn_tlli(bvc, link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                         parse_ctx->tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-                 link_info->sgsn_tlli.current = sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-                    link_info->tlli.current = parse_ctx->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-                } else if (!tlli_is_valid) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* New TLLI (info found by IMSI or P-TMSI) */</span><br><span style="color: hsl(0, 100%, 40%);">-                   link_info->tlli.current = parse_ctx->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-                        link_info->tlli.assigned = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                        link_info->sgsn_tlli.current =</span><br><span style="color: hsl(0, 100%, 40%);">-                               gbproxy_make_sgsn_tlli(bvc, link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                 parse_ctx->tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-                     link_info->sgsn_tlli.assigned = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                   gbproxy_touch_link_info(bvc, link_info, now);</span><br><span style="color: hsl(0, 100%, 40%);">-           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, link_info, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (!sgsn_tlli)</span><br><span style="color: hsl(0, 100%, 40%);">-                         sgsn_tlli = gbproxy_make_sgsn_tlli(bvc, link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                                 parse_ctx->tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                 gbproxy_validate_tlli(&link_info->tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                        parse_ctx->tlli, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                   gbproxy_validate_tlli(&link_info->sgsn_tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           sgsn_tlli, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                    gbproxy_touch_link_info(bvc, link_info, now);</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-         gbproxy_touch_link_info(bvc, link_info, now);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->imsi && link_info && link_info->imsi_len == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             gbproxy_assign_imsi(bvc, link_info, parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct gbproxy_link_info *gbproxy_get_link_info_dl(</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *link_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Which key to use depends on its availability only, if that fails, do</span><br><span style="color: hsl(0, 100%, 40%);">-  * not retry it with another key (e.g. IMSI). */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (parse_ctx->tlli_enc)</span><br><span style="color: hsl(0, 100%, 40%);">-             link_info = gbproxy_link_info_by_sgsn_tlli(bvc, parse_ctx->tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        parse_ctx->peer_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* TODO: Get link_info by (SGSN) P-TMSI if that is available (see</span><br><span style="color: hsl(0, 100%, 40%);">-        * GSM 08.18, 7.2) instead of using the IMSI as key. */</span><br><span style="color: hsl(0, 100%, 40%);">- else if (parse_ctx->imsi)</span><br><span style="color: hsl(0, 100%, 40%);">-            link_info = gbproxy_link_info_by_imsi(</span><br><span style="color: hsl(0, 100%, 40%);">-                  bvc, parse_ctx->imsi, parse_ctx->imsi_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (link_info)</span><br><span style="color: hsl(0, 100%, 40%);">-          link_info->is_deregistered = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gbproxy_link_info *gbproxy_update_link_state_dl(</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_link_info *link_info = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       link_info = gbproxy_get_link_info_dl(bvc, parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-               /* A new P-TMSI has been signalled in the message,</span><br><span style="color: hsl(0, 100%, 40%);">-               * register new TLLI */</span><br><span style="color: hsl(0, 100%, 40%);">-         uint32_t new_sgsn_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-                uint32_t new_bss_ptmsi = GSM_RESERVED_TMSI;</span><br><span style="color: hsl(0, 100%, 40%);">-             gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_sgsn_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (link_info->sgsn_tlli.ptmsi == new_sgsn_ptmsi)</span><br><span style="color: hsl(0, 100%, 40%);">-                    new_bss_ptmsi = link_info->tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (new_bss_ptmsi == GSM_RESERVED_TMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-                 new_bss_ptmsi = gbproxy_make_bss_ptmsi(bvc, new_sgsn_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Got new PTMSI %08x from SGSN, using %08x for BSS\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 new_sgsn_ptmsi, new_bss_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-            /* Setup PTMSIs */</span><br><span style="color: hsl(0, 100%, 40%);">-              link_info->sgsn_tlli.ptmsi = new_sgsn_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-         link_info->tlli.ptmsi = new_bss_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && !link_info &&</span><br><span style="color: hsl(0, 100%, 40%);">-                  !cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* A new P-TMSI has been signalled in the message with an unknown</span><br><span style="color: hsl(0, 100%, 40%);">-                * TLLI, create a new link_info */</span><br><span style="color: hsl(0, 100%, 40%);">-              /* TODO: Add a test case for this branch */</span><br><span style="color: hsl(0, 100%, 40%);">-             uint32_t new_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-             gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Adding TLLI %08x to list (SGSN, new P-TMSI is %08x)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              parse_ctx->tlli, new_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            link_info = gbproxy_link_info_alloc(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-               link_info->sgsn_tlli.current = parse_ctx->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-           link_info->tlli.current = parse_ctx->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-                link_info->sgsn_tlli.ptmsi = new_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-              link_info->tlli.ptmsi = new_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-           gbproxy_attach_link_info(bvc, now, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-  } else if (parse_ctx->tlli_enc && parse_ctx->llc && !link_info &&</span><br><span style="color: hsl(0, 100%, 40%);">-            !cfg->patch_ptmsi) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Unknown SGSN TLLI, create a new link_info */</span><br><span style="color: hsl(0, 100%, 40%);">-         uint32_t new_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-             link_info = gbproxy_link_info_alloc(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGPBVC(bvc, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-               parse_ctx->tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               gbproxy_attach_link_info(bvc, now, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Setup TLLIs */</span><br><span style="color: hsl(0, 100%, 40%);">-               link_info->sgsn_tlli.current = parse_ctx->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-           link_info->tlli.current = parse_ctx->tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!parse_ctx->new_ptmsi_enc)</span><br><span style="color: hsl(0, 100%, 40%);">-                       return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-               /* A new P-TMSI has been signalled in the message */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Assigning new P-TMSI %08x\n", new_ptmsi);</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Setup P-TMSIs */</span><br><span style="color: hsl(0, 100%, 40%);">-             link_info->sgsn_tlli.ptmsi = new_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-              link_info->tlli.ptmsi = new_ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-   } else if (parse_ctx->tlli_enc && parse_ctx->llc && link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-          uint32_t bss_tlli = gbproxy_map_tlli(parse_ctx->tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                     link_info, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-             gbproxy_validate_tlli(&link_info->sgsn_tlli, parse_ctx->tlli, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-             gbproxy_validate_tlli(&link_info->tlli, bss_tlli, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-            gbproxy_touch_link_info(bvc, link_info, now);</span><br><span style="color: hsl(0, 100%, 40%);">-   } else if (link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-         gbproxy_touch_link_info(bvc, link_info, now);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->imsi && link_info && link_info->imsi_len == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             gbproxy_assign_imsi(bvc, link_info, parse_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gbproxy_update_link_state_after(</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gbproxy_bvc *bvc,</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_link_info *link_info,</span><br><span style="color: hsl(0, 100%, 40%);">-    time_t now,</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gprs_gb_parse_context *parse_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(bvc->nse);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_config *cfg = bvc->nse->cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (parse_ctx->invalidate_tlli && link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-               int keep_info =</span><br><span style="color: hsl(0, 100%, 40%);">-                 cfg->keep_link_infos == GBPROX_KEEP_ALWAYS ||</span><br><span style="color: hsl(0, 100%, 40%);">-                        (cfg->keep_link_infos == GBPROX_KEEP_REATTACH &&</span><br><span style="color: hsl(0, 100%, 40%);">-                      parse_ctx->await_reattach) ||</span><br><span style="color: hsl(0, 100%, 40%);">-                       (cfg->keep_link_infos == GBPROX_KEEP_IDENTIFIED &&</span><br><span style="color: hsl(0, 100%, 40%);">-                    link_info->imsi_len > 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                if (keep_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGPBVC(bvc, LOGL_INFO, "Unregistering TLLI %08x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       link_info->tlli.current);</span><br><span style="color: hsl(0, 100%, 40%);">-                       rc = gbproxy_unregister_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-              } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGPBVC(bvc, LOGL_INFO, "Removing TLLI %08x from list\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                          link_info->tlli.current);</span><br><span style="color: hsl(0, 100%, 40%);">-                       gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-                       rc = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (parse_ctx->to_bss && parse_ctx->tlli_enc &&</span><br><span style="color: hsl(0, 100%, 40%);">-               parse_ctx->new_ptmsi_enc && link_info) {</span><br><span style="color: hsl(0, 100%, 40%);">-          /* A new PTMSI has been signaled in the message,</span><br><span style="color: hsl(0, 100%, 40%);">-                 * register new TLLI */</span><br><span style="color: hsl(0, 100%, 40%);">-         uint32_t new_sgsn_ptmsi = link_info->sgsn_tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-                uint32_t new_bss_ptmsi = link_info->tlli.ptmsi;</span><br><span style="color: hsl(0, 100%, 40%);">-              uint32_t new_sgsn_tlli;</span><br><span style="color: hsl(0, 100%, 40%);">-         uint32_t new_bss_tlli = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              new_sgsn_tlli = gprs_tmsi2tlli(new_sgsn_ptmsi, TLLI_LOCAL);</span><br><span style="color: hsl(0, 100%, 40%);">-             if (new_bss_ptmsi != GSM_RESERVED_TMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-                 new_bss_tlli = gprs_tmsi2tlli(new_bss_ptmsi, TLLI_LOCAL);</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGPBVC(bvc, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Assigning new TLLI %08x to SGSN, %08x to BSS\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     new_sgsn_tlli, new_bss_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              gbproxy_reassign_tlli(&link_info->sgsn_tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   bvc, new_sgsn_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-              gbproxy_reassign_tlli(&link_info->tlli,</span><br><span style="color: hsl(0, 100%, 40%);">-                                bvc, new_bss_tlli);</span><br><span style="color: hsl(0, 100%, 40%);">-               gbproxy_remove_matching_link_infos(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       gbproxy_remove_stale_link_infos(bvc, now);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 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 47ac9b9..da5710a 100644</span><br><span>--- a/src/gbproxy/gb_proxy_vty.c</span><br><span>+++ b/src/gbproxy/gb_proxy_vty.c</span><br><span>@@ -54,20 +54,6 @@</span><br><span>        1,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const struct value_string keep_modes[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-   {GBPROX_KEEP_NEVER, "never"},</span><br><span style="color: hsl(0, 100%, 40%);">- {GBPROX_KEEP_REATTACH, "re-attach"},</span><br><span style="color: hsl(0, 100%, 40%);">-  {GBPROX_KEEP_IDENTIFIED, "identified"},</span><br><span style="color: hsl(0, 100%, 40%);">-       {GBPROX_KEEP_ALWAYS, "always"},</span><br><span style="color: hsl(0, 100%, 40%);">-       {0, NULL}</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct value_string match_ids[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-     {GBPROX_MATCH_PATCHING, "patching"},</span><br><span style="color: hsl(0, 100%, 40%);">-  {GBPROX_MATCH_ROUTING, "routing"},</span><br><span style="color: hsl(0, 100%, 40%);">-    {0, NULL}</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void gbprox_vty_print_bvc(struct vty *vty, struct gbproxy_bvc *bvc)</span><br><span> {</span><br><span>       struct gprs_ra_id raid;</span><br><span>@@ -83,62 +69,11 @@</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%);">-      enum gbproxy_match_id match_id;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      vty_out(vty, "gbproxy%s", VTY_NEWLINE);</span><br><span> </span><br><span>        vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei,</span><br><span>          VTY_NEWLINE);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       if (g_cfg->core_plmn.mcc > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             vty_out(vty, " core-mobile-country-code %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                        osmo_mcc_name(g_cfg->core_plmn.mcc), VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (g_cfg->core_plmn.mnc > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             vty_out(vty, " core-mobile-network-code %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                        osmo_mnc_name(g_cfg->core_plmn.mnc, g_cfg->core_plmn.mnc_3_digits), VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) {</span><br><span style="color: hsl(0, 100%, 40%);">-           struct gbproxy_match *match = &g_cfg->matches[match_id];</span><br><span style="color: hsl(0, 100%, 40%);">-         if (match->re_str)</span><br><span style="color: hsl(0, 100%, 40%);">-                   vty_out(vty, " match-imsi %s %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                           get_value_string(match_ids, match_id),</span><br><span style="color: hsl(0, 100%, 40%);">-                          match->re_str, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (g_cfg->core_apn != NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (g_cfg->core_apn_size > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   char str[500] = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-                    vty_out(vty, " core-access-point-name %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                          osmo_apn_to_str(str, g_cfg->core_apn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          g_cfg->core_apn_size),</span><br><span style="color: hsl(0, 100%, 40%);">-                             VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                vty_out(vty, " core-access-point-name none%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                        VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (g_cfg->route_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-           vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei,</span><br><span style="color: hsl(0, 100%, 40%);">-                  VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (g_cfg->clean_stale_timer_freq > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-            vty_out(vty, " link-list clean-stale-timer %u%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                     g_cfg->clean_stale_timer_freq, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">- if (g_cfg->tlli_max_age > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-              vty_out(vty, " link-list max-age %d%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                       g_cfg->tlli_max_age, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (g_cfg->tlli_max_len > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-              vty_out(vty, " link-list max-length %d%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                    g_cfg->tlli_max_len, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-   vty_out(vty, " link-list keep-mode %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-             get_value_string(keep_modes, g_cfg->keep_link_infos),</span><br><span style="color: hsl(0, 100%, 40%);">-                VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (g_cfg->stored_msgs_max_len > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-               vty_out(vty, " link stored-msgs-max-length %"PRIu32"%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                    g_cfg->stored_msgs_max_len, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -160,387 +95,10 @@</span><br><span> {</span><br><span>    unsigned int nsei = atoi(argv[0]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  if (g_cfg->route_to_sgsn2 && g_cfg->nsip_sgsn2_nsei == nsei) {</span><br><span style="color: hsl(0, 100%, 40%);">-            vty_out(vty, "SGSN NSEI %d conflicts with secondary SGSN NSEI%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                     nsei, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-             return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    g_cfg->nsip_sgsn_nsei = nsei;</span><br><span>     return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_CORE_MNC_STR "Use this network code for the core network\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_core_mnc,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_core_mnc_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "core-mobile-network-code <1-999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_CORE_MNC_STR "NCC value\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        uint16_t mnc;</span><br><span style="color: hsl(0, 100%, 40%);">-   bool mnc_3_digits;</span><br><span style="color: hsl(0, 100%, 40%);">-      if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          vty_out(vty, "%% Invalid MNC: %s%s", argv[0], VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->core_plmn.mnc = mnc;</span><br><span style="color: hsl(0, 100%, 40%);">-  g_cfg->core_plmn.mnc_3_digits = mnc_3_digits;</span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_core_mnc,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_core_mnc_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no core-mobile-network-code",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_CORE_MNC_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   g_cfg->core_plmn.mnc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    g_cfg->core_plmn.mnc_3_digits = false;</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_CORE_MCC_STR "Use this country code for the core network\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_core_mcc,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_core_mcc_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "core-mobile-country-code <1-999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_CORE_MCC_STR "MCC value\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        g_cfg->core_plmn.mcc = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_core_mcc,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_core_mcc_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no core-mobile-country-code",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_CORE_MCC_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   g_cfg->core_plmn.mcc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_MATCH_IMSI_STR "Restrict actions to certain IMSIs\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_match_imsi,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_match_imsi_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "match-imsi (patching|routing) .REGEXP",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_MATCH_IMSI_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "Patch MS related information elements on match only\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Route to the secondary SGSN on match only\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Regular expression for the IMSI match\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     const char *filter = argv[1];</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *err_msg = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_match *match;</span><br><span style="color: hsl(0, 100%, 40%);">-    enum gbproxy_match_id match_id = get_string_value(match_ids, argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING &&</span><br><span style="color: hsl(0, 100%, 40%);">-                 match_id < GBPROX_MATCH_LAST);</span><br><span style="color: hsl(0, 100%, 40%);">-   match = &g_cfg->matches[match_id];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               vty_out(vty, "Match expression invalid: %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                        err_msg, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-          return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->acquire_imsi = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_match_imsi,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_match_imsi_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no match-imsi",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_MATCH_IMSI_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   enum gbproxy_match_id match_id;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id)</span><br><span style="color: hsl(0, 100%, 40%);">-             gbproxy_clear_patch_filter(&g_cfg->matches[match_id]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   g_cfg->acquire_imsi = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_CORE_APN_STR "Use this access point name (APN) for the backbone\n"</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_CORE_APN_ARG_STR "Replace APN by this string\n" "Remove APN\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int set_core_apn(struct vty *vty, const char *apn)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    int apn_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!apn) {</span><br><span style="color: hsl(0, 100%, 40%);">-             talloc_free(g_cfg->core_apn);</span><br><span style="color: hsl(0, 100%, 40%);">-                g_cfg->core_apn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-              g_cfg->core_apn_size = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-            return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       apn_len = strlen(apn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (apn_len >= 100) {</span><br><span style="color: hsl(0, 100%, 40%);">-                vty_out(vty, "APN string too long (max 99 chars)%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                  VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (apn_len == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             talloc_free(g_cfg->core_apn);</span><br><span style="color: hsl(0, 100%, 40%);">-                /* TODO: replace NULL */</span><br><span style="color: hsl(0, 100%, 40%);">-                g_cfg->core_apn = talloc_zero_size(NULL, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-         g_cfg->core_apn_size = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* TODO: replace NULL */</span><br><span style="color: hsl(0, 100%, 40%);">-                g_cfg->core_apn =</span><br><span style="color: hsl(0, 100%, 40%);">-                    talloc_realloc_size(NULL, g_cfg->core_apn, apn_len + 1);</span><br><span style="color: hsl(0, 100%, 40%);">-             g_cfg->core_apn_size =</span><br><span style="color: hsl(0, 100%, 40%);">-                       gprs_str_to_apn(g_cfg->core_apn, apn_len + 1, apn);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_core_apn,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_core_apn_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "core-access-point-name (APN|none)",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_CORE_APN_STR GBPROXY_CORE_APN_ARG_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (strcmp(argv[0], "none") == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             return set_core_apn(vty, "");</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">-            return set_core_apn(vty, argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_core_apn,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_core_apn_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no core-access-point-name",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_CORE_APN_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return set_core_apn(vty, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* TODO: Remove the patch-ptmsi command, since P-TMSI patching is enabled</span><br><span style="color: hsl(0, 100%, 40%);">- * automatically when needed. This command is only left for manual testing</span><br><span style="color: hsl(0, 100%, 40%);">- * (e.g. doing P-TMSI patching without using a secondary SGSN)</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_PATCH_PTMSI_STR "Patch P-TMSI/TLLI\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_patch_ptmsi,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_patch_ptmsi_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "patch-ptmsi",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_PATCH_PTMSI_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        g_cfg->patch_ptmsi = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_patch_ptmsi,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_patch_ptmsi_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no patch-ptmsi",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_PATCH_PTMSI_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->patch_ptmsi = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* TODO: Remove the acquire-imsi command, since that feature is enabled</span><br><span style="color: hsl(0, 100%, 40%);">- * automatically when IMSI matching is enabled. This command is only left for</span><br><span style="color: hsl(0, 100%, 40%);">- * manual testing (e.g. doing IMSI acquisition without IMSI based patching)</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_ACQUIRE_IMSI_STR "Acquire the IMSI before establishing a LLC connection (Experimental)\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_acquire_imsi,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_acquire_imsi_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "acquire-imsi",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_ACQUIRE_IMSI_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      g_cfg->acquire_imsi = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_acquire_imsi,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_acquire_imsi_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no acquire-imsi",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_ACQUIRE_IMSI_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   g_cfg->acquire_imsi = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_SECOND_SGSN_STR "Route matching LLC connections to a second SGSN (Experimental)\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_secondary_sgsn,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_secondary_sgsn_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "secondary-sgsn nsei <0-65534>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_SECOND_SGSN_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "NSEI to be used in the connection with the SGSN\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "The NSEI\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      unsigned int nsei = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (g_cfg->nsip_sgsn_nsei == nsei) {</span><br><span style="color: hsl(0, 100%, 40%);">-         vty_out(vty, "Secondary SGSN NSEI %d conflicts with primary SGSN NSEI%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                     nsei, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-             return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->route_to_sgsn2 = true;</span><br><span style="color: hsl(0, 100%, 40%);">-        g_cfg->nsip_sgsn2_nsei = nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->patch_ptmsi = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_no_secondary_sgsn,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_no_secondary_sgsn_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no secondary-sgsn",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_SECOND_SGSN_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      g_cfg->route_to_sgsn2 = false;</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->nsip_sgsn2_nsei = 0xFFFF;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     g_cfg->patch_ptmsi = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n"</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_LINK_STR "Set TLLI parameters\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_CLEAN_STALE_TIMER_STR "Periodic timer to clean stale links\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_clean_stale_timer,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_clean_stale_timer_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "link-list clean-stale-timer <1-999999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "Frequency at which the periodic timer is fired (in seconds)\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_nse *nse;</span><br><span style="color: hsl(0, 100%, 40%);">-        int i, j;</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Re-schedule running timers soon in case prev frequency was really big</span><br><span style="color: hsl(0, 100%, 40%);">-           and new frequency is desired to be lower. After initial run, periodic</span><br><span style="color: hsl(0, 100%, 40%);">-           time is used. Use random() to avoid firing timers for all bvcs at</span><br><span style="color: hsl(0, 100%, 40%);">-       the same time */</span><br><span style="color: hsl(0, 100%, 40%);">-     hash_for_each(g_cfg->bss_nses, i, nse, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-               struct gbproxy_bvc *bvc;</span><br><span style="color: hsl(0, 100%, 40%);">-                hash_for_each(nse->bvcs, j, bvc, list)</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_timer_schedule(&bvc->clean_stale_timer,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             random() % 5, random() % 1000000);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_no_clean_stale_timer_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no link-list clean-stale-timer",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gbproxy_nse *nse;</span><br><span style="color: hsl(0, 100%, 40%);">-        int i, j;</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->clean_stale_timer_freq = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   hash_for_each(g_cfg->bss_nses, i, nse, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-               struct gbproxy_bvc *bvc;</span><br><span style="color: hsl(0, 100%, 40%);">-                hash_for_each(nse->bvcs, j, bvc, list)</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_timer_del(&bvc->clean_stale_timer);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_MAX_AGE_STR "Limit maximum age\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_max_age,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_max_age_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "link-list max-age <1-999999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "Maximum age in seconds\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     g_cfg->tlli_max_age = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_no_max_age,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_no_max_age_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no link-list max-age",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   g_cfg->tlli_max_age = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_MAX_LEN_STR "Limit list length\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_max_len,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_max_len_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "link-list max-length <1-99999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "Maximum number of logical links in the list\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      g_cfg->tlli_max_len = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_no_max_len,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_no_max_len_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no link-list max-length",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        g_cfg->tlli_max_len = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_list_keep_mode,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_list_keep_mode_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "link-list keep-mode (never|re-attach|identified|always)",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_LINK_LIST_STR "How to keep entries for detached logical links\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Discard entry immediately after detachment\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Keep entry if a re-attachment has be requested\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Keep entry if it associated with an IMSI\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Don't discard entries after detachment\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int val = get_string_value(keep_modes, argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(val >= GBPROX_KEEP_NEVER && val <= GBPROX_KEEP_ALWAYS);</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->keep_link_infos = val;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_stored_msgs_max_len,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_stored_msgs_max_len_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "link stored-msgs-max-length <1-99999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "Maximum number of msgb stored in the logical link waiting to acquire its IMSI\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->stored_msgs_max_len = (uint32_t) atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(cfg_gbproxy_link_no_stored_msgs_max_len,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_link_no_stored_msgs_max_len_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "no link stored-msgs-max-length",</span><br><span style="color: hsl(0, 100%, 40%);">-      NO_STR GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        g_cfg->stored_msgs_max_len = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void log_set_bvc_filter(struct log_target *target,</span><br><span>                            const uint16_t *bvci)</span><br><span> {</span><br><span>@@ -603,52 +161,12 @@</span><br><span>        SHOW_STR "Display information about the Gb proxy\n" "Show logical links\n")</span><br><span> {</span><br><span>    struct gbproxy_nse *nse;</span><br><span style="color: hsl(0, 100%, 40%);">-        time_t now;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct timespec ts = {0,};</span><br><span>   int i, j;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_clock_gettime(CLOCK_MONOTONIC, &ts);</span><br><span style="color: hsl(0, 100%, 40%);">-   now = ts.tv_sec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>     hash_for_each(g_cfg->bss_nses, i, nse, list) {</span><br><span>            struct gbproxy_bvc *bvc;</span><br><span>             hash_for_each(nse->bvcs, j, bvc, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct gbproxy_link_info *link_info;</span><br><span style="color: hsl(0, 100%, 40%);">-                    struct gbproxy_patch_state *state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>                        gbprox_vty_print_bvc(vty, bvc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                 llist_for_each_entry(link_info, &state->logical_links, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           time_t age = now - link_info->timestamp;</span><br><span style="color: hsl(0, 100%, 40%);">-                             struct osmo_mobile_identity mi;</span><br><span style="color: hsl(0, 100%, 40%);">-                         const char *imsi_str;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                           if (link_info->imsi > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false)</span><br><span style="color: hsl(0, 100%, 40%);">-                                         || mi.type != GSM_MI_TYPE_IMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-                                             imsi_str = "(invalid)";</span><br><span style="color: hsl(0, 100%, 40%);">-                                       else</span><br><span style="color: hsl(0, 100%, 40%);">-                                            imsi_str = mi.imsi;</span><br><span style="color: hsl(0, 100%, 40%);">-                             } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        imsi_str = "(none)";</span><br><span style="color: hsl(0, 100%, 40%);">-                          }</span><br><span style="color: hsl(0, 100%, 40%);">-                               vty_out(vty, "  TLLI %08x, IMSI %s, AGE %d",</span><br><span style="color: hsl(0, 100%, 40%);">-                                  link_info->tlli.current, imsi_str, (int)age);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                                if (link_info->stored_msgs_len)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      vty_out(vty, ", STORED %"PRIu32"/%"PRIu32,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          link_info->stored_msgs_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          g_cfg->stored_msgs_max_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                         if (g_cfg->route_to_sgsn2)</span><br><span style="color: hsl(0, 100%, 40%);">-                                   vty_out(vty, ", SGSN NSEI %d",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                link_info->sgsn_nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                               if (link_info->is_deregistered)</span><br><span style="color: hsl(0, 100%, 40%);">-                                      vty_out(vty, ", DE-REGISTERED");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                              vty_out(vty, "%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                      }</span><br><span>            }</span><br><span>    }</span><br><span>    return CMD_SUCCESS;</span><br><span>@@ -744,182 +262,6 @@</span><br><span>  return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_DELETE_LINK_STR \</span><br><span style="color: hsl(0, 100%, 40%);">-   "Delete a GBProxy logical link entry by NSEI and identification\nNSEI number\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-  "delete-gbproxy-link <0-65534> (tlli|imsi|sgsn-nsei) IDENT",</span><br><span style="color: hsl(0, 100%, 40%);">-    GBPROXY_DELETE_LINK_STR</span><br><span style="color: hsl(0, 100%, 40%);">- "Delete entries with a matching TLLI (hex)\n"</span><br><span style="color: hsl(0, 100%, 40%);">- "Delete entries with a matching IMSI\n"</span><br><span style="color: hsl(0, 100%, 40%);">-       "Delete entries with a matching SGSN NSEI\n"</span><br><span style="color: hsl(0, 100%, 40%);">-  "Identification to match\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- const uint16_t nsei = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-    enum {MATCH_TLLI = 't', MATCH_IMSI = 'i', MATCH_SGSN = 's'} match;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint32_t ident = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     const char *imsi = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gbproxy_bvc *bvc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_link_info *link_info, *nxt;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_patch_state *state;</span><br><span style="color: hsl(0, 100%, 40%);">-      int found = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  match = argv[1][0];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     switch (match) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case MATCH_TLLI: ident = strtoll(argv[2], NULL, 16); break;</span><br><span style="color: hsl(0, 100%, 40%);">-     case MATCH_IMSI: imsi = argv[2]; break;</span><br><span style="color: hsl(0, 100%, 40%);">- case MATCH_SGSN: ident = strtoll(argv[2], NULL, 0); break;</span><br><span style="color: hsl(0, 100%, 40%);">-      };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bvc = gbproxy_bvc_by_nsei(g_cfg, nsei);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!bvc) {</span><br><span style="color: hsl(0, 100%, 40%);">-             vty_out(vty, "Didn't find bvc with NSEI %d%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                    nsei, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-             return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-         struct osmo_mobile_identity mi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         switch (match) {</span><br><span style="color: hsl(0, 100%, 40%);">-                case MATCH_TLLI:</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (link_info->tlli.current != ident)</span><br><span style="color: hsl(0, 100%, 40%);">-                                continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case MATCH_SGSN:</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (link_info->sgsn_nsei != ident)</span><br><span style="color: hsl(0, 100%, 40%);">-                           continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case MATCH_IMSI:</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!link_info->imsi)</span><br><span style="color: hsl(0, 100%, 40%);">-                                continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false)</span><br><span style="color: hsl(0, 100%, 40%);">-                         || mi.type != GSM_MI_TYPE_IMSI)</span><br><span style="color: hsl(0, 100%, 40%);">-                             continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (strcmp(mi.imsi, imsi) != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                         continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               vty_out(vty, "Deleting link with TLLI %08x%s", link_info->tlli.current,</span><br><span style="color: hsl(0, 100%, 40%);">-                    VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-               found += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!found && argc >= 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-           vty_out(vty, "Didn't find link entry with %s %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                       argv[1], argv[2], VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN(delete_gb_link, delete_gb_link_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-   "delete-gbproxy-link <0-65534> (stale|de-registered)",</span><br><span style="color: hsl(0, 100%, 40%);">-  GBPROXY_DELETE_LINK_STR</span><br><span style="color: hsl(0, 100%, 40%);">- "Delete stale entries\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Delete de-registered entries\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    const uint16_t nsei = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-    enum {MATCH_STALE = 's', MATCH_DEREGISTERED = 'd'} match;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gbproxy_bvc *bvc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gbproxy_link_info *link_info, *nxt;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gbproxy_patch_state *state;</span><br><span style="color: hsl(0, 100%, 40%);">-      time_t now;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct timespec ts = {0,};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      int found = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  match = argv[1][0];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bvc = gbproxy_bvc_by_nsei(g_cfg, nsei);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!bvc) {</span><br><span style="color: hsl(0, 100%, 40%);">-             vty_out(vty, "Didn't find bvc with NSEI %d%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                    nsei, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-             return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       state = &bvc->patch_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_clock_gettime(CLOCK_MONOTONIC, &ts);</span><br><span style="color: hsl(0, 100%, 40%);">-   now = ts.tv_sec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (match == MATCH_STALE) {</span><br><span style="color: hsl(0, 100%, 40%);">-             found = gbproxy_remove_stale_link_infos(bvc, now);</span><br><span style="color: hsl(0, 100%, 40%);">-              if (found)</span><br><span style="color: hsl(0, 100%, 40%);">-                      vty_out(vty, "Deleted %d stale logical link%s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                             found, found == 1 ? "" : "s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                llist_for_each_entry_safe(link_info, nxt,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         &state->logical_links, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (!link_info->is_deregistered)</span><br><span style="color: hsl(0, 100%, 40%);">-                             continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       gbproxy_delete_link_info(bvc, link_info);</span><br><span style="color: hsl(0, 100%, 40%);">-                       found += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (found)</span><br><span style="color: hsl(0, 100%, 40%);">-              vty_out(vty, "Deleted %d %s logical link%s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                        found, argv[1], found == 1 ? "" : "s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * legacy commands to provide an upgrade path from "broken" releases</span><br><span style="color: hsl(0, 100%, 40%);">- * or pre-releases</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_broken_apn_match_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "core-access-point-name none match-imsi .REGEXP",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_CORE_APN_STR GBPROXY_MATCH_IMSI_STR "Remove APN\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Patch MS related information elements on match only\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Route to the secondary SGSN on match only\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "Regular expression for the IMSI match\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        const char *filter = argv[0];</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *err_msg = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gbproxy_match *match;</span><br><span style="color: hsl(0, 100%, 40%);">-    enum gbproxy_match_id match_id = get_string_value(match_ids, "patching");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* apply APN none */</span><br><span style="color: hsl(0, 100%, 40%);">-    set_core_apn(vty, "");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* do the matching... with copy and paste */</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING &&</span><br><span style="color: hsl(0, 100%, 40%);">-                 match_id < GBPROX_MATCH_LAST);</span><br><span style="color: hsl(0, 100%, 40%);">-   match = &g_cfg->matches[match_id];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               vty_out(vty, "Match expression invalid: %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                        err_msg, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-          return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       g_cfg->acquire_imsi = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"</span><br><span style="color: hsl(0, 100%, 40%);">-#define GBPROXY_MAX_LEN_STR "Limit list length\n"</span><br><span style="color: hsl(0, 100%, 40%);">-DEFUN_DEPRECATED(cfg_gbproxy_depr_tlli_list_max_len,</span><br><span style="color: hsl(0, 100%, 40%);">-      cfg_gbproxy_depr_tlli_list_max_len_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "tlli-list max-length <1-99999>",</span><br><span style="color: hsl(0, 100%, 40%);">-      GBPROXY_TLLI_LIST_STR GBPROXY_MAX_LEN_STR</span><br><span style="color: hsl(0, 100%, 40%);">-      "Maximum number of TLLIs in the list\n")</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     g_cfg->tlli_max_len = atoi(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> int gbproxy_vty_init(void)</span><br><span> {</span><br><span>      install_element_ve(&show_gbproxy_cmd);</span><br><span>@@ -928,39 +270,10 @@</span><br><span> </span><br><span>       install_element(ENABLE_NODE, &delete_gb_bvci_cmd);</span><br><span>       install_element(ENABLE_NODE, &delete_gb_nsei_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-  install_element(ENABLE_NODE, &delete_gb_link_by_id_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-    install_element(ENABLE_NODE, &delete_gb_link_cmd);</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>       install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-     install_element(GBPROXY_NODE, &cfg_gbproxy_core_mcc_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-   install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-   install_element(GBPROXY_NODE, &cfg_gbproxy_match_imsi_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">- install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-   install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-     install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-       install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_clean_stale_timer_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-  install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-  install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(GBPROXY_NODE, &cfg_gbproxy_link_stored_msgs_max_len_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-   install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-      install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_apn_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-        install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-  install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-     install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-    install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_clean_stale_timer_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-     install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-       install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-       install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_max_len_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* broken or deprecated to allow an upgrade path */</span><br><span style="color: hsl(0, 100%, 40%);">-     install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd);</span><br><span style="color: hsl(0, 100%, 40%);">-   install_element(GBPROXY_NODE, &cfg_gbproxy_depr_tlli_list_max_len_cmd);</span><br><span> </span><br><span>      return 0;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-sgsn/+/21552">change 21552</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/+/21552"/><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: Id9cc2e1c63486491ac5bb68876088a615075fde6 </div>
<div style="display:none"> Gerrit-Change-Number: 21552 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>