diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-16 14:10:27 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-19 11:21:01 +0200 |
commit | 1a02442f664aa43c7182a0646d8ed958eeb45a50 (patch) | |
tree | ce84e7d85c513c888f733c22dbfe788d985f6a91 /openbsc/src/gprs/gb_proxy_tlli.c | |
parent | 04f679be734709de387087c7ef91d8010cff6a46 (diff) |
gbproxy: Check other tlli_infos for matching TLLI/P-TMSI
Currently it is possible to create serveral entries referring to the
same P-TMSI/TLLI by using P-TMSI assigment via Attach Accept or
RA Update Accept messages. This can lead to the use of the wrong
tlli_info.
This patch adds gbproxy_remove_matching_tllis() that removes all
conflicting entries. This function is called after the P-TMSIs and
the resulting TLLIs has been set up.
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 | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c index beab9bb19..c4140f7e8 100644 --- a/openbsc/src/gprs/gb_proxy_tlli.c +++ b/openbsc/src/gprs/gb_proxy_tlli.c @@ -382,6 +382,43 @@ void gbproxy_assign_imsi(struct gbproxy_peer *peer, tlli_info->enable_patching = enable_patching; } +static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a, + const struct gbproxy_tlli_state *b) +{ + if (a->current && a->current == b->current) + return 1; + + if (a->assigned && a->assigned == b->assigned) + return 1; + + if (a->ptmsi != GSM_RESERVED_TMSI && a->ptmsi == b->ptmsi) + return 1; + + return 0; +} + +static void gbproxy_remove_matching_tllis(struct gbproxy_peer *peer, + struct gbproxy_tlli_info *tlli_info) +{ + struct gbproxy_tlli_info *info, *nxt; + struct gbproxy_patch_state *state = &peer->patch_state; + + /* Make sure that there is no second entry with the same P-TMSI or TLLI */ + llist_for_each_entry_safe(info, nxt, &state->enabled_tllis, list) { + if (info == tlli_info) + continue; + + if (!gbproxy_tlli_match(&tlli_info->tlli, &info->tlli) && + !gbproxy_tlli_match(&tlli_info->sgsn_tlli, &info->sgsn_tlli)) + continue; + + LOGP(DGPRS, LOGL_INFO, + "Removing TLLI %08x from list (P-TMSI/TLLI re-used)\n", + info->tlli.current); + gbproxy_delete_tlli(peer, info); + } +} + struct gbproxy_tlli_info *gbproxy_get_tlli_info_ul( struct gbproxy_peer *peer, struct gprs_gb_parse_context *parse_ctx) @@ -605,6 +642,7 @@ void gbproxy_update_tlli_state_after( peer, new_sgsn_tlli); gbproxy_reassign_tlli(&tlli_info->tlli, peer, new_bss_tlli); + gbproxy_remove_matching_tllis(peer, tlli_info); } gbproxy_remove_stale_tllis(peer, now); |