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.deSponsored-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