Change in osmo-sgsn[master]: WIP gbproxy: Implment TLLI cache and use it for SUSPEND/RESUME

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

daniel gerrit-no-reply at lists.osmocom.org
Tue Jan 5 14:58:08 UTC 2021


daniel has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sgsn/+/21960 )


Change subject: WIP gbproxy: Implment TLLI cache and use it for SUSPEND/RESUME
......................................................................

WIP gbproxy: Implment TLLI cache and use it for SUSPEND/RESUME

Deleting cache entries by timer or reception of NACK/ACK is missing

Related: SYS#4865, OS#4472
Change-Id: I42adf70f560d2bb358a9e1c7614281e8d2967568
---
M include/osmocom/sgsn/gb_proxy.h
M src/gbproxy/gb_proxy.c
M src/gbproxy/gb_proxy_peer.c
3 files changed, 90 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/60/21960/1

diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h
index ad5bb27..ea9e649 100644
--- a/include/osmocom/sgsn/gb_proxy.h
+++ b/include/osmocom/sgsn/gb_proxy.h
@@ -75,6 +75,9 @@
 	/* hash table of all gbproxy_cell */
 	DECLARE_HASHTABLE(cells, 8);
 
+	/* tlli<->sgsn cache */
+	DECLARE_HASHTABLE(tlli_cache, 10);
+
 	/* List of all SGSNs */
 	struct llist_head sgsns;
 
@@ -163,6 +166,19 @@
 	} pool;
 };
 
+/* TLLI cache */
+struct gbproxy_tlli_cache {
+	/* linked to gbproxy_config.tlli_cache */
+	struct hlist_node list;
+
+	/* TLLI of the entry */
+	uint32_t tlli;
+	/* When was this entry last seen */
+	struct timespec tstamp;
+	/* The Cell this TLLI was last seen */
+	struct gbproxy_nse *nse;
+};
+
 /* Convenience logging macros for NSE/BVC */
 #define LOGPNSE_CAT(NSE, SUBSYS, LEVEL, FMT, ARGS...) \
 	LOGP(SUBSYS, LEVEL, "NSE(%05u/%s) " FMT, (NSE)->nsei, \
@@ -229,6 +245,8 @@
 void gbproxy_nse_free(struct gbproxy_nse *nse);
 struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags);
 struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);
+void gbproxy_nse_cache_tlli(struct gbproxy_nse *nse, uint32_t tlli);
+struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli);
 
 /* SGSN handling */
 struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name);
diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c
index 34cff31..a260ec9 100644
--- a/src/gbproxy/gb_proxy.c
+++ b/src/gbproxy/gb_proxy.c
@@ -890,11 +890,26 @@
 		return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK, msg);
 	case BSSGP_PDUT_SUSPEND:
 	case BSSGP_PDUT_RESUME:
+	{
+		struct gbproxy_sgsn *sgsn;
+
 		/* FIXME: Implement TLLI Cache.  Every SUSPEND/RESUME we must
 		 * take record of the TLLI->BVC mapping so we can map
 		 * back from TLLI->BVC when the SUSPEND/RESUME-ACK
 		 * arrives.  Cache should have a timeout of 1-3 seconds
 		 * and the ACK should explicitly delete entries. */
+		tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+
+		sgsn = gbproxy_select_sgsn(nse->cfg, &tlli);
+		if (!sgsn) {
+			LOGP(DGPRS, LOGL_ERROR, "Could not find any SGSN for TLLI, dropping message!\n");
+			rc = -EINVAL;
+			break;
+		}
+
+		gbproxy_nse_cache_tlli(nse, tlli);
+
+		rc = gbprox_relay2nse(msg, sgsn->nse, 0);
 #if 0
 		/* TODO: Validate the RAI for consistency with the RAI
 		 * we expect for any of the BVC within this BSS side NSE */
@@ -902,6 +917,7 @@
 		gsm48_parse_ra(&raid, from_bvc->ra);
 #endif
 		break;
+	}
 	case BSSGP_PDUT_STATUS:
 		/* FIXME: inspect the erroneous PDU IE (if any) and check
 		 * if we can extract a TLLI/RNI to route it to the correct SGSN */
@@ -1149,11 +1165,26 @@
 	case BSSGP_PDUT_SUSPEND_NACK:
 	case BSSGP_PDUT_RESUME_ACK:
 	case BSSGP_PDUT_RESUME_NACK:
+	{
+		struct gbproxy_nse *nse_peer;
+		uint32_t tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+
 		/* FIXME: handle based on TLLI cache. The RA-ID is not a unique
 		 * criterion, so we have to rely on the TLLI->BVC state created
 		 * while processing the SUSPEND/RESUME in uplink */
 		/* FIXME: route to SGSN baed on NRI derived from TLLI */
+		nse_peer = gbproxy_nse_by_tlli(cfg, tlli);
+		if (!nse_peer) {
+			LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find NSE\n", pdut_name);
+			//rate_ctr_inc(&cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_RAI]);
+			// FIXME
+			return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
+		}
+
+		LOGPNSE(nse_peer, LOGL_DEBUG, "Rx %s: forwarding\n", pdut_name);
+		gbprox_relay2nse(msg, nse_peer, ns_bvci);
 		break;
+	}
 	case BSSGP_PDUT_SGSN_INVOKE_TRACE:
 	case BSSGP_PDUT_OVERLOAD:
 		LOGPNSE(nse, LOGL_DEBUG, "Rx %s: broadcasting\n", pdut_name);
@@ -1386,6 +1417,7 @@
 	hash_init(cfg->bss_nses);
 	hash_init(cfg->sgsn_nses);
 	hash_init(cfg->cells);
+	hash_init(cfg->tlli_cache);
 	INIT_LLIST_HEAD(&cfg->sgsns);
 
 	cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
diff --git a/src/gbproxy/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c
index 7c00fc7..95ec68a 100644
--- a/src/gbproxy/gb_proxy_peer.c
+++ b/src/gbproxy/gb_proxy_peer.c
@@ -192,6 +192,46 @@
 	return NULL;
 }
 
+static inline struct gbproxy_tlli_cache *_get_tlli_entry(struct gbproxy_config *cfg, uint32_t tlli)
+{
+	struct gbproxy_tlli_cache *cache_entry;
+
+	hash_for_each_possible(cfg->tlli_cache, cache_entry, list, tlli) {
+		if (cache_entry->tlli == tlli)
+			return cache_entry;
+	}
+	return NULL;
+}
+
+void gbproxy_nse_cache_tlli(struct gbproxy_nse *nse, uint32_t tlli)
+{
+	struct gbproxy_config *cfg = nse->cfg;
+	struct gbproxy_tlli_cache *cache_entry = _get_tlli_entry(cfg, tlli);
+
+	if (cache_entry) {
+		// Update the entry if it already exists
+		cache_entry->nse = nse;
+		osmo_clock_gettime(CLOCK_MONOTONIC, &cache_entry->tstamp);
+	}
+
+	cache_entry = talloc_zero(cfg, struct gbproxy_tlli_cache);
+	cache_entry->tlli = tlli;
+	cache_entry->nse = nse;
+	osmo_clock_gettime(CLOCK_MONOTONIC, &cache_entry->tstamp);
+	hash_add(cfg->tlli_cache, &cache_entry->list, cache_entry->tlli);
+}
+
+struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli)
+{
+	struct gbproxy_tlli_cache *tlli_cache;
+
+	hash_for_each_possible(cfg->tlli_cache, tlli_cache, list, tlli) {
+		if (tlli_cache->tlli == tlli)
+			return tlli_cache->nse;
+	}
+	return NULL;
+}
+
 struct gbproxy_cell *gbproxy_cell_by_bvci_or_new(struct gbproxy_config *cfg, uint16_t bvci)
 {
 	struct gbproxy_cell *cell;

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-sgsn/+/21960
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: I42adf70f560d2bb358a9e1c7614281e8d2967568
Gerrit-Change-Number: 21960
Gerrit-PatchSet: 1
Gerrit-Owner: daniel <dwillmann at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210105/032fa32b/attachment.htm>


More information about the gerrit-log mailing list