aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy.c
diff options
context:
space:
mode:
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 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);
}