diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-17 10:56:38 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-19 11:21:35 +0200 |
commit | 91a0e8639a74231f41d14ca7cc952079cc541755 (patch) | |
tree | f908e1752528fc985f953f25f2c9e06b774d209e /openbsc/src/gprs/gb_proxy_tlli.c | |
parent | af952baffc73dae23d9498518ec26a30f50f07f0 (diff) |
gbproxy: Separate SGSN numeric namespaces
Currently the SGSN side message's TLLI are searched without checking
the originating SGSN. This leads to collisions if both SGSN use the
same P-TMSI for different MS.
With this patch, the SGSN NSEI is stored within the tlli_info and is
used in comparisons to separate the namespaces.
Note that this type of collision cannot happen with BSS numbers,
since the tlli_info are already separated and stored per (BSS) peer.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/gprs/gb_proxy_tlli.c')
-rw-r--r-- | openbsc/src/gprs/gb_proxy_tlli.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c index c4140f7e8..8aadd2f44 100644 --- a/openbsc/src/gprs/gb_proxy_tlli.c +++ b/openbsc/src/gprs/gb_proxy_tlli.c @@ -60,16 +60,33 @@ struct gbproxy_tlli_info *gbproxy_find_tlli_by_ptmsi( return NULL; } -struct gbproxy_tlli_info *gbproxy_find_tlli_by_sgsn_tlli( +struct gbproxy_tlli_info *gbproxy_find_tlli_by_any_sgsn_tlli( struct gbproxy_peer *peer, uint32_t tlli) { struct gbproxy_tlli_info *tlli_info; struct gbproxy_patch_state *state = &peer->patch_state; + /* Don't care about the NSEI */ llist_for_each_entry(tlli_info, &state->enabled_tllis, list) if (tlli_info->sgsn_tlli.current == tlli || - tlli_info->sgsn_tlli.assigned == tlli) + tlli_info->sgsn_tlli.assigned == tlli) + return tlli_info; + + return NULL; +} + +struct gbproxy_tlli_info *gbproxy_find_tlli_by_sgsn_tlli( + struct gbproxy_peer *peer, + uint32_t tlli, uint32_t sgsn_nsei) +{ + struct gbproxy_tlli_info *tlli_info; + struct gbproxy_patch_state *state = &peer->patch_state; + + llist_for_each_entry(tlli_info, &state->enabled_tllis, list) + if ((tlli_info->sgsn_tlli.current == tlli || + tlli_info->sgsn_tlli.assigned == tlli) && + tlli_info->sgsn_nsei == sgsn_nsei) return tlli_info; return NULL; @@ -409,7 +426,8 @@ static void gbproxy_remove_matching_tllis(struct gbproxy_peer *peer, continue; if (!gbproxy_tlli_match(&tlli_info->tlli, &info->tlli) && - !gbproxy_tlli_match(&tlli_info->sgsn_tlli, &info->sgsn_tlli)) + (tlli_info->sgsn_nsei != info->sgsn_nsei || + !gbproxy_tlli_match(&tlli_info->sgsn_tlli, &info->sgsn_tlli))) continue; LOGP(DGPRS, LOGL_INFO, @@ -508,7 +526,8 @@ struct gbproxy_tlli_info *gbproxy_update_tlli_state_dl( struct gbproxy_tlli_info *tlli_info = NULL; if (parse_ctx->tlli_enc) - tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, parse_ctx->tlli); + tlli_info = gbproxy_find_tlli_by_sgsn_tlli( + peer, parse_ctx->tlli, parse_ctx->peer_nsei); if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && tlli_info) { /* A new P-TMSI has been signalled in the message, |