[PATCH 06/15] gtphub: add TEI map API.

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/OpenBSC@lists.osmocom.org/.

Neels Hofmeyr nhofmeyr at sysmocom.de
Thu Oct 15 22:13:50 UTC 2015


Sponsored-by: On-Waves ehi

diff --git a/openbsc/include/openbsc/gtphub.h b/openbsc/include/openbsc/gtphub.h
index 7c89db1..7354786 100644
--- a/openbsc/include/openbsc/gtphub.h
+++ b/openbsc/include/openbsc/gtphub.h
@@ -38,6 +38,46 @@ enum gtphub_port_idx {
 extern const char* const gtphub_port_idx_names[GTPH_PORT_N];
 
 
+/* Generator for unused TEI IDs. So far this counts upwards from zero, but the
+ * implementation may change in the future. Treat this like an opaque struct. */
+struct tei_pool {
+	uint32_t last_tei;
+};
+
+void tei_pool_init(struct tei_pool *pool);
+
+/* Return the next unused TEI from the tei_pool. */
+uint32_t tei_pool_next(struct tei_pool *pool);
+
+
+struct tei_mapping {
+	struct llist_head entry;
+
+	uint32_t orig;
+	uint32_t repl;
+};
+
+struct tei_map {
+	struct tei_pool *pool;
+	struct llist_head mappings;
+};
+
+/* Initialize an (already allocated) tei_map, and set the map's TEI pool.
+ * Multiple tei_map instances may use the same tei_pool. */
+void tei_map_init(struct tei_map *map, struct tei_pool *pool);
+
+/* Return a replacement TEI for tei_orig. If tei_orig is unknown, create a new
+ * mapping using a so far unused TEI to map tei_orig to. Return 0 on error. */
+uint32_t tei_map_get(struct tei_map *map, uint32_t tei_orig);
+
+/* Return the original TEI for a replacement TEI. If no mapping exists to
+ * tei_repl, return 0. */
+uint32_t tei_map_get_rev(struct tei_map *map, uint32_t tei_repl);
+
+/* Remove the mapping for tei_orig, if it exists. */
+void tei_map_del(struct tei_map *map, uint32_t tei_orig);
+
+
 /* config */
 
 struct gtphub_cfg_addr {
@@ -66,10 +106,12 @@ struct gtphub_peer {
 	struct llist_head entry;
 
 	struct gtphub_addr addr;
+	struct tei_map teim;
 };
 
 struct gtphub_bind {
 	struct osmo_fd ofd;
+	struct tei_pool teip;
 
 	/* list of struct gtphub_peer */
 	struct llist_head peers;
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index 577a2d0..a80243c 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -21,6 +21,7 @@
 
 #include <string.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <netinet/in.h>
 
 #include <openbsc/gtphub.h>
@@ -54,6 +55,82 @@ const char* const gtphub_port_idx_names[GTPH_PORT_N] = {
 };
 
 
+void tei_pool_init(struct tei_pool *pool)
+{
+	*pool = (struct tei_pool){};
+}
+
+uint32_t tei_pool_next(struct tei_pool *pool)
+{
+	pool->last_tei ++;
+
+	OSMO_ASSERT(pool->last_tei > 0);
+	/* TODO: gracefully handle running out of TEIs. */
+	/* TODO: random TEIs. */
+
+	return pool->last_tei;
+}
+
+void tei_map_init(struct tei_map *map, struct tei_pool *pool)
+{
+	*map = (struct tei_map){};
+	map->pool = pool;
+	INIT_LLIST_HEAD(&map->mappings);
+}
+
+static uint32_t tei_map_new(struct tei_map *map, uint32_t tei_orig)
+{
+	struct tei_mapping *mapping;
+	mapping = talloc_zero(osmo_gtphub_ctx, struct tei_mapping);
+	OSMO_ASSERT(mapping);
+	mapping->orig = tei_orig;
+	mapping->repl = tei_pool_next(map->pool);
+	llist_add(&mapping->entry, &map->mappings);
+	return mapping->repl;
+}
+
+uint32_t tei_map_get(struct tei_map *map, uint32_t tei_orig)
+{
+	OSMO_ASSERT(tei_orig != 0);
+
+	struct tei_mapping *mapping;
+	llist_for_each_entry(mapping, &map->mappings, entry) {
+		if (mapping->orig == tei_orig)
+			return mapping->repl;
+	}
+	/* Not found. */
+
+	return tei_map_new(map, tei_orig);
+}
+
+uint32_t tei_map_get_rev(struct tei_map *map, uint32_t tei_repl)
+{
+	OSMO_ASSERT(tei_repl != 0);
+
+	struct tei_mapping *pos;
+	llist_for_each_entry(pos, &map->mappings, entry) {
+		if (pos->repl == tei_repl) {
+			OSMO_ASSERT(pos->orig);
+			return pos->orig;
+		}
+	}
+	return 0;
+}
+
+void tei_map_del(struct tei_map *map, uint32_t tei_orig)
+{
+	struct tei_mapping *mapping;
+	llist_for_each_entry(mapping, &map->mappings, entry) {
+		if (mapping->orig == tei_orig) {
+			llist_del(&mapping->entry);
+			talloc_free(mapping);
+			return;
+		}
+	}
+	LOGERR("No mapping exists for TEI %" PRIu32 ".\n", tei_orig);
+}
+
+
 /* gtphub */
 
 void gtphub_zero(struct gtphub *hub)
@@ -93,6 +170,7 @@ static int gtphub_gtp_bind_init(struct gtphub_bind *b,
 {
 	memset(b, '\0', sizeof(*b));
 
+	tei_pool_init(&b->teip);
 	INIT_LLIST_HEAD(&b->peers);
 
 	if (gtphub_sock_init(&b->ofd, &cfg->bind, cb, cb_data, ofd_id) != 0)
@@ -240,6 +318,9 @@ int gtphub_init(struct gtphub *hub, struct gtphub_cfg *cfg)
 struct gtphub_peer *gtphub_peer_new(struct gtphub_bind *bind)
 {
 	struct gtphub_peer *n = talloc_zero(osmo_gtphub_ctx, struct gtphub_peer);
+
+	tei_map_init(&n->teim, &bind->teip);
+
 	llist_add(&n->entry, &bind->peers);
 	return n;
 }
-- 
2.1.4




More information about the OpenBSC mailing list