gbproxy: Fix TLLI state handling
This patch contains fixes for the TLLI tracking and handling.
It adds and uses gbprox_map_tlli() the map the source TLLI to the
destination TLLI while respecting whether it is current or assigned.
It removes gbprox_register_tlli() from the downlink path. It fixes
TLLI validation and disables the use of the BSSGP TLLI IE.
Sponsored-by: On-Waves ehf
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index cbf2e90..ef2f0d4 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -687,6 +687,26 @@
tlli_state->net_validated = 0;
}
+static uint32_t gbprox_map_tlli(uint32_t other_tlli,
+ struct gbproxy_tlli_info *tlli_info, int to_bss)
+{
+ uint32_t tlli = 0;
+ struct gbproxy_tlli_state *src, *dst;
+ if (to_bss) {
+ src = &tlli_info->sgsn_tlli;
+ dst = &tlli_info->tlli;
+ } else {
+ src = &tlli_info->tlli;
+ dst = &tlli_info->sgsn_tlli;
+ }
+ if (src->current == other_tlli)
+ tlli = dst->current;
+ else if (src->assigned == other_tlli)
+ tlli = dst->assigned;
+
+ return tlli;
+}
+
static void gbprox_validate_tlli(struct gbproxy_tlli_state *tlli_state,
uint32_t tlli, int to_bss)
{
@@ -1489,6 +1509,7 @@
}
static uint32_t gbprox_make_sgsn_tlli(struct gbproxy_peer *peer,
+ struct gbproxy_tlli_info *tlli_info,
uint32_t bss_tlli)
{
return bss_tlli;
@@ -1525,16 +1546,14 @@
parse_ctx->imsi,
parse_ctx->imsi_len, now);
/* Setup TLLIs */
- sgsn_tlli = gbprox_make_sgsn_tlli(peer, parse_ctx->tlli);
+ sgsn_tlli = gbprox_make_sgsn_tlli(peer, tlli_info,
+ parse_ctx->tlli);
tlli_info->sgsn_tlli.current = sgsn_tlli;
} else {
- sgsn_tlli = tlli_info->sgsn_tlli.assigned;
+ sgsn_tlli = gbprox_map_tlli(parse_ctx->tlli, tlli_info, 0);
if (!sgsn_tlli)
- sgsn_tlli = tlli_info->sgsn_tlli.current;
- if (!sgsn_tlli) {
- sgsn_tlli = gbprox_make_sgsn_tlli(peer,
+ sgsn_tlli = gbprox_make_sgsn_tlli(peer, tlli_info,
parse_ctx->tlli);
- }
gbprox_validate_tlli(&tlli_info->tlli,
parse_ctx->tlli, 0);
@@ -1612,10 +1631,12 @@
peer, new_bss_tlli);
gbprox_touch_tlli(peer, tlli_info, now);
} else {
- tlli_info =
- gbprox_register_tlli(peer, new_bss_tlli,
- parse_ctx->imsi,
- parse_ctx->imsi_len, now);
+ tlli_info = gbprox_tlli_info_alloc(peer);
+ LOGP(DGPRS, LOGL_INFO,
+ "Adding TLLI %08x to list (SGSN, new P-TMSI)\n",
+ new_sgsn_tlli);
+
+ gbprox_attach_tlli_info(peer, now, tlli_info);
/* Setup TLLIs */
tlli_info->sgsn_tlli.current = new_sgsn_tlli;
}
@@ -1624,13 +1645,13 @@
tlli_info->tlli.ptmsi = new_bss_ptmsi;
} else if (parse_ctx->tlli_enc && parse_ctx->llc && !tlli_info) {
/* Unknown SGSN TLLI */
- tlli_info =
- gbprox_register_tlli(peer, parse_ctx->tlli,
- parse_ctx->imsi,
- parse_ctx->imsi_len, now);
+ tlli_info = gbprox_tlli_info_alloc(peer);
+ LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n",
+ parse_ctx->tlli);
+ gbprox_attach_tlli_info(peer, now, tlli_info);
/* Setup TLLIs */
- tlli_info->sgsn_tlli.current = tlli_info->tlli.current;
+ tlli_info->sgsn_tlli.current = parse_ctx->tlli;
if (peer->cfg->patch_ptmsi) {
/* TODO: We don't know the local TLLI here, perhaps add
* a workaround that derives a PTMSI from the SGSN TLLI
@@ -1640,12 +1661,14 @@
* length.
*/
tlli_info->tlli.current = 0;
+ } else {
+ tlli_info->tlli.current = tlli_info->sgsn_tlli.current;
}
} else if (parse_ctx->tlli_enc && parse_ctx->llc && tlli_info) {
+ uint32_t bss_tlli = gbprox_map_tlli(parse_ctx->tlli,
+ tlli_info, 1);
gbprox_validate_tlli(&tlli_info->sgsn_tlli, parse_ctx->tlli, 1);
- if (!peer->cfg->patch_ptmsi)
- gbprox_validate_tlli(&tlli_info->tlli,
- parse_ctx->tlli, 1);
+ gbprox_validate_tlli(&tlli_info->tlli, bss_tlli, 1);
gbprox_touch_tlli(peer, tlli_info, now);
} else if (tlli_info) {
gbprox_touch_tlli(peer, tlli_info, now);
@@ -1730,7 +1753,9 @@
parse_ctx->imsi_len = TLVP_LEN(tp, BSSGP_IE_IMSI);
}
- if (TLVP_PRESENT(tp, BSSGP_IE_TLLI))
+ /* TODO: This is TLLI old, don't confuse with TLLI current, add
+ * and use tlli_old_enc instead */
+ if (0 && TLVP_PRESENT(tp, BSSGP_IE_TLLI))
parse_ctx->tlli_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TLLI);
if (TLVP_PRESENT(tp, BSSGP_IE_TMSI) && pdu_type == BSSGP_PDUT_PAGING_PS)