aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy_tlli.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-09-16 14:10:27 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2014-09-19 11:21:01 +0200
commit1a02442f664aa43c7182a0646d8ed958eeb45a50 (patch)
treece84e7d85c513c888f733c22dbfe788d985f6a91 /openbsc/src/gprs/gb_proxy_tlli.c
parent04f679be734709de387087c7ef91d8010cff6a46 (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.c38
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);