aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-18 17:01:32 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-24 16:16:39 +0200
commite37487e0838a03ebc5cb06cf980278d7196bc5df (patch)
treee286b2d1fadb0c504bf337b4e46f001a7e1f8191
parent3b23d639ab667de85dd18ac89f8e9315cb43710f (diff)
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
-rw-r--r--openbsc/src/gprs/gb_proxy.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index cbf2e9075..ef2f0d417 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -687,6 +687,26 @@ void gbprox_reassign_tlli(struct gbproxy_tlli_state *tlli_state,
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_bss_ptmsi(struct gbproxy_peer *peer,
}
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 @@ static struct gbproxy_tlli_info *gbprox_update_state_ul(
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 @@ static struct gbproxy_tlli_info *gbprox_update_state_dl(
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 @@ static struct gbproxy_tlli_info *gbprox_update_state_dl(
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 @@ static struct gbproxy_tlli_info *gbprox_update_state_dl(
* 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 @@ static int gbprox_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
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)