gbproxy: Add usage flag to the imsi_cache

This is only used for the imsi cache entries for now. Further uses will
be added in subsequent commits.

Related: OS#4472
Change-Id: I4a4b8c99eb97f6bb5387d0f26aecd861e07d9914
This commit is contained in:
Daniel Willmann 2021-07-09 17:44:30 +02:00
parent f50aa80054
commit 361d0b566a
3 changed files with 24 additions and 15 deletions

View File

@ -192,6 +192,10 @@ struct gbproxy_sgsn {
} pool; } pool;
}; };
enum cache_usage_type {
CACHE_USAGE_PAGING,
};
/* TLLI cache */ /* TLLI cache */
struct gbproxy_tlli_cache_entry { struct gbproxy_tlli_cache_entry {
/* linked to gbproxy_config.tlli_cache.entries */ /* linked to gbproxy_config.tlli_cache.entries */
@ -199,6 +203,8 @@ struct gbproxy_tlli_cache_entry {
/* TLLI of the entry */ /* TLLI of the entry */
uint32_t tlli; uint32_t tlli;
enum cache_usage_type usage;
/* When was this entry last seen */ /* When was this entry last seen */
time_t tstamp; time_t tstamp;
/* The Cell this TLLI was last seen */ /* The Cell this TLLI was last seen */
@ -212,6 +218,8 @@ struct gbproxy_imsi_cache_entry {
/* IMSI of the entry */ /* IMSI of the entry */
char imsi[OSMO_IMSI_BUF_SIZE]; char imsi[OSMO_IMSI_BUF_SIZE];
enum cache_usage_type usage;
/* When was this entry last seen */ /* When was this entry last seen */
time_t tstamp; time_t tstamp;
/* The SGSN where the request came from */ /* The SGSN where the request came from */
@ -286,7 +294,7 @@ 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(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); struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);
struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli); struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli);
struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi); struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi, enum cache_usage_type usage);
/* TLLI cache */ /* TLLI cache */
void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli); void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli);
@ -294,8 +302,8 @@ void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli);
int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg); int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg);
/* IMSI cache */ /* IMSI cache */
void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi); void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi, enum cache_usage_type usage);
void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi); void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi, enum cache_usage_type usage);
int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg); int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg);
/* SGSN handling */ /* SGSN handling */

View File

@ -484,7 +484,7 @@ static int gbprox_rx_ptp_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uin
const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI); const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI); uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi); nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi, CACHE_USAGE_PAGING);
if (nse) { if (nse) {
OSMO_ASSERT(nse->sgsn_facing); OSMO_ASSERT(nse->sgsn_facing);
rc = gbprox_relay2nse(msg, nse, ns_bvci); rc = gbprox_relay2nse(msg, nse, ns_bvci);
@ -586,7 +586,7 @@ static int gbprox_rx_ptp_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, ui
const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI); const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI); uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
gbproxy_imsi_cache_update(nse, mi.imsi); gbproxy_imsi_cache_update(nse, mi.imsi, CACHE_USAGE_PAGING);
break; break;
} }
default: default:
@ -1106,7 +1106,7 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uin
const uint8_t *mi_data = TLVP_VAL(&tp[0], BSSGP_IE_IMSI); const uint8_t *mi_data = TLVP_VAL(&tp[0], BSSGP_IE_IMSI);
uint8_t mi_len = TLVP_LEN(&tp[0], BSSGP_IE_IMSI); uint8_t mi_len = TLVP_LEN(&tp[0], BSSGP_IE_IMSI);
osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi); nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi, CACHE_USAGE_PAGING);
if (!nse) { if (!nse) {
return tx_status(nse, ns_bvci, BSSGP_CAUSE_INV_MAND_INF, NULL, msg); return tx_status(nse, ns_bvci, BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
} }
@ -1386,7 +1386,7 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, ui
const uint8_t *mi_data = TLVP_VAL(&tp[0], BSSGP_IE_IMSI); const uint8_t *mi_data = TLVP_VAL(&tp[0], BSSGP_IE_IMSI);
uint8_t mi_len = TLVP_LEN(&tp[0], BSSGP_IE_IMSI); uint8_t mi_len = TLVP_LEN(&tp[0], BSSGP_IE_IMSI);
osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
gbproxy_imsi_cache_update(nse, mi.imsi); gbproxy_imsi_cache_update(nse, mi.imsi, CACHE_USAGE_PAGING);
/* fall through */ /* fall through */
} }
case BSSGP_PDUT_PAGING_CS: case BSSGP_PDUT_PAGING_CS:

View File

@ -347,23 +347,23 @@ static inline uint16_t _checksum_imsi(const char *imsi)
return osmo_crc16(0, (const uint8_t *)imsi, len); return osmo_crc16(0, (const uint8_t *)imsi, len);
} }
static inline struct gbproxy_imsi_cache_entry *_get_imsi_entry(struct gbproxy_config *cfg, const char *imsi) static inline struct gbproxy_imsi_cache_entry *_get_imsi_entry(struct gbproxy_config *cfg, const char *imsi, enum cache_usage_type usage)
{ {
struct gbproxy_imsi_cache_entry *cache_entry; struct gbproxy_imsi_cache_entry *cache_entry;
uint16_t imsi_hash = _checksum_imsi(imsi); uint16_t imsi_hash = _checksum_imsi(imsi);
hash_for_each_possible(cfg->imsi_cache.entries, cache_entry, list, imsi_hash) { hash_for_each_possible(cfg->imsi_cache.entries, cache_entry, list, imsi_hash) {
if (!strncmp(cache_entry->imsi, imsi, sizeof(cache_entry->imsi))) if (!strncmp(cache_entry->imsi, imsi, sizeof(cache_entry->imsi)) && cache_entry->usage == usage)
return cache_entry; return cache_entry;
} }
return NULL; return NULL;
} }
void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi) void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi, enum cache_usage_type usage)
{ {
struct gbproxy_config *cfg = nse->cfg; struct gbproxy_config *cfg = nse->cfg;
struct timespec now; struct timespec now;
struct gbproxy_imsi_cache_entry *cache_entry = _get_imsi_entry(cfg, imsi); struct gbproxy_imsi_cache_entry *cache_entry = _get_imsi_entry(cfg, imsi, usage);
uint16_t imsi_hash = _checksum_imsi(imsi); uint16_t imsi_hash = _checksum_imsi(imsi);
osmo_clock_gettime(CLOCK_MONOTONIC, &now); osmo_clock_gettime(CLOCK_MONOTONIC, &now);
@ -378,6 +378,7 @@ void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi)
cache_entry = talloc_zero(cfg, struct gbproxy_imsi_cache_entry); cache_entry = talloc_zero(cfg, struct gbproxy_imsi_cache_entry);
OSMO_STRLCPY_ARRAY(cache_entry->imsi, imsi); OSMO_STRLCPY_ARRAY(cache_entry->imsi, imsi);
cache_entry->nse = nse; cache_entry->nse = nse;
cache_entry->usage = usage;
cache_entry->tstamp = now.tv_sec; cache_entry->tstamp = now.tv_sec;
hash_add(cfg->imsi_cache.entries, &cache_entry->list, imsi_hash); hash_add(cfg->imsi_cache.entries, &cache_entry->list, imsi_hash);
} }
@ -396,14 +397,14 @@ static void _imsi_cache_remove_nse(struct gbproxy_nse *nse) {
} }
} }
void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi) void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi, enum cache_usage_type usage)
{ {
struct gbproxy_imsi_cache_entry *imsi_cache; struct gbproxy_imsi_cache_entry *imsi_cache;
struct hlist_node *tmp; struct hlist_node *tmp;
uint16_t imsi_hash = _checksum_imsi(imsi); uint16_t imsi_hash = _checksum_imsi(imsi);
hash_for_each_possible_safe(cfg->imsi_cache.entries, imsi_cache, tmp, list, imsi_hash) { hash_for_each_possible_safe(cfg->imsi_cache.entries, imsi_cache, tmp, list, imsi_hash) {
if (!(strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)))) { if (!(strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi))) && imsi_cache->usage == usage) {
hash_del(&imsi_cache->list); hash_del(&imsi_cache->list);
talloc_free(imsi_cache); talloc_free(imsi_cache);
return; return;
@ -546,13 +547,13 @@ struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tll
return NULL; return NULL;
} }
struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi) struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi, enum cache_usage_type usage)
{ {
struct gbproxy_imsi_cache_entry *imsi_cache; struct gbproxy_imsi_cache_entry *imsi_cache;
uint16_t imsi_hash = _checksum_imsi(imsi); uint16_t imsi_hash = _checksum_imsi(imsi);
hash_for_each_possible(cfg->imsi_cache.entries, imsi_cache, list, imsi_hash) { hash_for_each_possible(cfg->imsi_cache.entries, imsi_cache, list, imsi_hash) {
if (!strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi))) if (!strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)) && imsi_cache->usage == usage)
return imsi_cache->nse; return imsi_cache->nse;
} }
return NULL; return NULL;