summaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-11 17:26:21 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-24 16:16:39 +0200
commit59748e653b7d6ab7e8bb62bf55ca714958b356e2 (patch)
tree841ea1513bc814b07f601b3102ce322ed23ac0d3 /openbsc/src/gprs/gb_proxy.c
parent3c5b40fb759e07bba63b06b80560f1c59125c8e0 (diff)
gbproxy: Handle old and new P-TMSI/TLLI
Don't replace the current TLLI immediately, store it in an additional 'assigned_tlli' field and discard the old TLLI when both sides have used the new one (see GSM 04.08, 4.7.1.5). Add an Attach Complete message to test and check, whether the related field of the corresponding tlli_info struct are set as expected during the local TLLI validation cycle. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/gprs/gb_proxy.c')
-rw-r--r--openbsc/src/gprs/gb_proxy.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 5e19247..26f4c17 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -420,14 +420,14 @@ struct gbproxy_parse_context {
int pdu_type;
};
-static struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
- uint32_t tlli)
+struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
+ uint32_t tlli)
{
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->tlli == tlli)
+ if (tlli_info->tlli == tlli || tlli_info->assigned_tlli == tlli)
return tlli_info;
return NULL;
@@ -659,8 +659,41 @@ void gbprox_reassign_tlli(struct gbproxy_tlli_info *tlli_info,
"The TLLI has been reassigned from %08x to %08x\n",
tlli_info->tlli, new_tlli);
- /* TODO: Save old TLLI */
- tlli_info->tlli = new_tlli;
+ /* Remember assigned TLLI */
+ tlli_info->assigned_tlli = new_tlli;
+ tlli_info->bss_validated = 0;
+ tlli_info->net_validated = 0;
+}
+
+static void gbprox_validate_tlli(struct gbproxy_tlli_info *tlli_info,
+ uint32_t tlli, int to_bss)
+{
+ LOGP(DGPRS, LOGL_DEBUG,
+ "%s({tlli = %08x, assigned_tlli = %08x, net_vld = %d, bss_vld = %d}, %08x)\n",
+ __func__, tlli_info->tlli, tlli_info->assigned_tlli,
+ tlli_info->net_validated, tlli_info->bss_validated, tlli);
+
+ if (!tlli_info->assigned_tlli || tlli_info->assigned_tlli != tlli)
+ return;
+
+ if (gprs_tlli_type(tlli) != TLLI_LOCAL)
+ return;
+
+ /* See GSM 04.08, 4.7.1.5 */
+ if (to_bss)
+ tlli_info->net_validated = 1;
+ else
+ tlli_info->bss_validated = 1;
+
+ if (!tlli_info->bss_validated || !tlli_info->net_validated)
+ return;
+
+ LOGP(DGPRS, LOGL_INFO,
+ "The TLLI %08x has been validated (was %08x)\n",
+ tlli_info->assigned_tlli, tlli_info->tlli);
+
+ tlli_info->tlli = tlli;
+ tlli_info->assigned_tlli = 0;
}
void gbprox_touch_tlli(struct gbproxy_peer *peer,
@@ -1429,10 +1462,16 @@ static struct gbproxy_tlli_info *gbprox_update_state(
parse_ctx->imsi_len, now);
}
} else if (parse_ctx->tlli_enc && parse_ctx->llc) {
- tlli_info =
- gbprox_register_tlli(peer, parse_ctx->tlli,
- parse_ctx->imsi,
- parse_ctx->imsi_len, now);
+ if (!tlli_info) {
+ tlli_info =
+ gbprox_register_tlli(peer, parse_ctx->tlli,
+ parse_ctx->imsi,
+ parse_ctx->imsi_len, now);
+ } else {
+ gbprox_validate_tlli(tlli_info, parse_ctx->tlli,
+ parse_ctx->to_bss);
+ gbprox_touch_tlli(peer, tlli_info, now);
+ }
} else if (tlli_info) {
gbprox_touch_tlli(peer, tlli_info, now);
}