diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-11 17:26:21 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-08-24 16:16:39 +0200 |
commit | 59748e653b7d6ab7e8bb62bf55ca714958b356e2 (patch) | |
tree | 841ea1513bc814b07f601b3102ce322ed23ac0d3 /openbsc/src/gprs/gb_proxy.c | |
parent | 3c5b40fb759e07bba63b06b80560f1c59125c8e0 (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.c | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 5e19247a2..26f4c1755 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); } |