gbproxy: Keep tlli_info after detach

Currently a tlli_info entry is deleted when the TLLI gets invalidated
by a Detach message.

This patch introduces the possibility to keep tlli_info entries in
the list. Those entries then have cleared TLLI fields, are marked as
de-registered, and can only be retrieved by a message containing an
IMSI or a P-TMSI.

The following VTY configuration commands are added to the gbproxy
node:
  - tlli-list keep-mode never : Don't keep the entries (default)
  - tlli-list keep-mode re-attach : Only keep them, when a Detach
    message with re-attach required has been received
  - tlli-list keep-mode identified : Only keep entries which are
    associated with an IMSI
  - tlli-list keep-mode always : Keep all entries

Note that at least one of max-length or max-age should be set when
this feature is used to limit the number of entries.

Sponsored-by: On-Waves ehf
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
index 4a20bfb..d9731a7 100644
--- a/openbsc/include/openbsc/gb_proxy.h
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -50,6 +50,13 @@
 	GBPROX_PEER_CTR_TLLI_CACHE_SIZE,
 };
 
+enum gbproxy_keep_mode {
+	GBPROX_KEEP_NEVER,
+	GBPROX_KEEP_REATTACH,
+	GBPROX_KEEP_IDENTIFIED,
+	GBPROX_KEEP_ALWAYS,
+};
+
 struct gbproxy_config {
 	/* parsed from config file */
 	uint16_t nsip_sgsn_nsei;
@@ -77,6 +84,7 @@
 	int acquire_imsi;
 	int route_to_sgsn2;
 	uint16_t nsip_sgsn2_nsei;
+	enum gbproxy_keep_mode keep_tlli_infos;
 
 	/* IMSI checking/matching */
 	int check_imsi;
@@ -141,6 +149,8 @@
 	struct llist_head stored_msgs;
 	int imsi_acq_retries;
 
+	int is_deregistered;
+
 	int enable_patching;
 };
 
diff --git a/openbsc/include/openbsc/gprs_gb_parse.h b/openbsc/include/openbsc/gprs_gb_parse.h
index eb97763..3aa17fd 100644
--- a/openbsc/include/openbsc/gprs_gb_parse.h
+++ b/openbsc/include/openbsc/gprs_gb_parse.h
@@ -34,6 +34,7 @@
 	/* General info */
 	const char *llc_msg_name;
 	int invalidate_tlli;
+	int await_reattach;
 	int need_decryption;
 	uint32_t tlli;
 	int pdu_type;
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c
index 78459b7..509e489 100644
--- a/openbsc/src/gprs/gb_proxy_tlli.c
+++ b/openbsc/src/gprs/gb_proxy_tlli.c
@@ -316,17 +316,28 @@
 	gbproxy_attach_tlli_info(peer, now, tlli_info);
 }
 
-static void gbproxy_unregister_tlli(struct gbproxy_peer *peer, uint32_t tlli)
+static void gbproxy_unregister_tlli(struct gbproxy_peer *peer,
+				    struct gbproxy_tlli_info *tlli_info)
 {
-	struct gbproxy_tlli_info *tlli_info;
+	if (!tlli_info)
+		return;
 
-	tlli_info = gbproxy_find_tlli(peer, tlli);
-	if (tlli_info) {
+	if (tlli_info->tlli.ptmsi == GSM_RESERVED_TMSI && !tlli_info->imsi_len) {
 		LOGP(DGPRS, LOGL_INFO,
-		     "Removing TLLI %08x from list\n",
-		     tlli);
+		     "Removing TLLI %08x from list (P-TMSI or IMSI are not set)\n",
+		     tlli_info->tlli.current);
 		gbproxy_delete_tlli(peer, tlli_info);
+		return;
 	}
+
+	tlli_info->tlli.current = 0;
+	tlli_info->tlli.assigned = 0;
+	tlli_info->sgsn_tlli.current = 0;
+	tlli_info->sgsn_tlli.assigned = 0;
+
+	tlli_info->is_deregistered = 1;
+
+	return;
 }
 
 int gbproxy_check_tlli(struct gbproxy_peer *peer,
@@ -338,20 +349,44 @@
 	return tlli_info != NULL && tlli_info->enable_patching;
 }
 
+struct gbproxy_tlli_info *gbproxy_get_tlli_info_ul(
+	struct gbproxy_peer *peer,
+	struct gprs_gb_parse_context *parse_ctx)
+{
+	struct gbproxy_tlli_info *tlli_info = NULL;
+
+	if (parse_ctx->tlli_enc)
+		tlli_info = gbproxy_find_tlli(peer, parse_ctx->tlli);
+
+	if (!tlli_info && parse_ctx->imsi)
+		tlli_info = gbproxy_find_tlli_by_imsi(
+			peer, parse_ctx->imsi, parse_ctx->imsi_len);
+
+	if (!tlli_info && parse_ctx->ptmsi_enc && !parse_ctx->old_raid_is_foreign) {
+		uint32_t bss_ptmsi;
+		if (!gprs_parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN,
+					&bss_ptmsi))
+			LOGP(DGPRS, LOGL_ERROR,
+			     "Failed to parse P-TMSI (TLLI is %08x)\n",
+			     parse_ctx->tlli);
+		else
+			tlli_info = gbproxy_find_tlli_by_ptmsi(peer, bss_ptmsi);
+	}
+
+	if (tlli_info)
+		tlli_info->is_deregistered = 0;
+
+	return tlli_info;
+}
+
 struct gbproxy_tlli_info *gbproxy_update_tlli_state_ul(
 	struct gbproxy_peer *peer,
 	time_t now,
 	struct gprs_gb_parse_context *parse_ctx)
 {
-	struct gbproxy_tlli_info *tlli_info = NULL;
+	struct gbproxy_tlli_info *tlli_info;
 
-	if (parse_ctx->tlli_enc) {
-		tlli_info = gbproxy_find_tlli(peer, parse_ctx->tlli);
-
-		if (!tlli_info && parse_ctx->imsi)
-			tlli_info = gbproxy_find_tlli_by_imsi(
-				peer, parse_ctx->imsi, parse_ctx->imsi_len);
-	}
+	tlli_info = gbproxy_get_tlli_info_ul(peer, parse_ctx);
 
 	if (parse_ctx->tlli_enc && parse_ctx->llc) {
 		uint32_t sgsn_tlli;
@@ -366,6 +401,13 @@
 							   parse_ctx->tlli);
 			tlli_info->sgsn_tlli.current = sgsn_tlli;
 			tlli_info->tlli.current = parse_ctx->tlli;;
+		} else if (!tlli_info->tlli.current) {
+			/* New TLLI (info found by IMSI or P-TMSI) */
+			tlli_info->tlli.current = parse_ctx->tlli;
+			tlli_info->sgsn_tlli.current =
+				gbproxy_make_sgsn_tlli(peer, tlli_info,
+						       parse_ctx->tlli);
+			gbproxy_touch_tlli(peer, tlli_info, now);
 		} else {
 			sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, tlli_info, 0);
 			if (!sgsn_tlli)
@@ -512,8 +554,22 @@
 	time_t now,
 	struct gprs_gb_parse_context *parse_ctx)
 {
-	if (parse_ctx->invalidate_tlli) {
-		gbproxy_unregister_tlli(peer, parse_ctx->tlli);
+	if (parse_ctx->invalidate_tlli && tlli_info) {
+		int keep_info =
+			peer->cfg->keep_tlli_infos == GBPROX_KEEP_ALWAYS ||
+			(peer->cfg->keep_tlli_infos == GBPROX_KEEP_REATTACH &&
+			 parse_ctx->await_reattach) ||
+			(peer->cfg->keep_tlli_infos == GBPROX_KEEP_IDENTIFIED &&
+			 tlli_info->imsi_len > 0);
+		if (keep_info) {
+			LOGP(DGPRS, LOGL_INFO, "Unregistering TLLI %08x\n",
+			     tlli_info->tlli.current);
+			gbproxy_unregister_tlli(peer, tlli_info);
+		} else {
+			LOGP(DGPRS, LOGL_INFO, "Removing TLLI %08x from list\n",
+			     tlli_info->tlli.current);
+			gbproxy_delete_tlli(peer, tlli_info);
+		}
 	} else if (parse_ctx->to_bss && parse_ctx->tlli_enc &&
 		   parse_ctx->new_ptmsi_enc && tlli_info) {
 		/* A new PTMSI has been signaled in the message,
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index efdf751..ee39289 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -50,6 +50,14 @@
 	1,
 };
 
+static const struct value_string keep_modes[] = {
+	{GBPROX_KEEP_NEVER, "never"},
+	{GBPROX_KEEP_REATTACH, "re-attach"},
+	{GBPROX_KEEP_IDENTIFIED, "identified"},
+	{GBPROX_KEEP_ALWAYS, "always"},
+	{0, NULL}
+};
+
 static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
 {
 	struct gprs_ra_id raid;
@@ -106,6 +114,10 @@
 	if (g_cfg->tlli_max_len > 0)
 		vty_out(vty, " tlli-list max-length %d%s",
 			g_cfg->tlli_max_len, VTY_NEWLINE);
+	vty_out(vty, " tlli-list keep-mode %s%s",
+		get_value_string(keep_modes, g_cfg->keep_tlli_infos),
+		VTY_NEWLINE);
+
 
 	return CMD_SUCCESS;
 }
@@ -398,6 +410,22 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_gbproxy_tlli_list_keep_mode,
+      cfg_gbproxy_tlli_list_keep_mode_cmd,
+      "tlli-list keep-mode (never|re-attach|identified|always)",
+      GBPROXY_TLLI_LIST_STR "How to keep entries for detached TLLIs\n"
+      "Discard entry immediately after detachment\n"
+      "Keep entry if a re-attachment has be requested\n"
+      "Keep entry if it associated with an IMSI\n"
+      "Don't discard entries after detachment\n")
+{
+	int val = get_string_value(keep_modes, argv[0]);
+	OSMO_ASSERT(val >= GBPROX_KEEP_NEVER && val <= GBPROX_KEEP_ALWAYS);
+	g_cfg->keep_tlli_infos = val;
+
+	return CMD_SUCCESS;
+}
+
 
 DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
        SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n")
@@ -654,6 +682,7 @@
 	install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_max_age_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_max_len_cmd);
+	install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_keep_mode_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd);
diff --git a/openbsc/src/gprs/gprs_gb_parse.c b/openbsc/src/gprs/gprs_gb_parse.c
index f361951..7ae792a 100644
--- a/openbsc/src/gprs/gprs_gb_parse.c
+++ b/openbsc/src/gprs/gprs_gb_parse.c
@@ -224,6 +224,7 @@
 {
 	uint8_t *value;
 	size_t value_len;
+	int detach_type;
 	int power_off;
 
 	parse_ctx->llc_msg_name = "DETACH_REQ";
@@ -234,9 +235,14 @@
 		/* invalid */
 		return 0;
 
+	detach_type = *value & 0x07;
 	power_off = *value & 0x08 ? 1 : 0;
 
-	if (!parse_ctx->to_bss) {
+	if (parse_ctx->to_bss) {
+		/* Network originated */
+		if (detach_type == GPRS_DET_T_MT_REATT_REQ)
+			parse_ctx->await_reattach = 1;
+	} else {
 		/* Mobile originated */
 
 		if (power_off)
@@ -651,6 +657,10 @@
 		LOGP(DGPRS, LOGL_DEBUG, "%s invalidate", sep);
 		sep = ",";
 	}
+	if (parse_ctx->await_reattach) {
+		LOGP(DGPRS, LOGL_DEBUG, "%s re-attach", sep);
+		sep = ",";
+	}
 
 	LOGP(DGPRS, LOGL_DEBUG, "\n");
 }
diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c
index 06fea69..c4ebc73 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.c
+++ b/openbsc/tests/gbproxy/gbproxy_test.c
@@ -157,6 +157,9 @@
 			if (tlli_info->imsi_acq_pending)
 				fprintf(stream, ", IMSI acquisition in progress");
 
+			if (tlli_info->is_deregistered)
+				fprintf(stream, ", DE-REGISTERED");
+
 			rc = fprintf(stream, "\n");
 			if (rc < 0)
 				return rc;
@@ -2606,7 +2609,7 @@
 	const uint32_t foreign_tlli = 0xafe2b700;
 
 	const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
-	struct gbproxy_tlli_info *tlli_info;
+	struct gbproxy_tlli_info *tlli_info, *tlli_info2;
 	struct gbproxy_peer *peer;
 	unsigned bss_nu = 0;
 	unsigned sgsn_nu = 0;
@@ -2626,6 +2629,7 @@
 	gbcfg.core_apn_size = 0;
 	gbcfg.route_to_sgsn2 = 0;
 	gbcfg.nsip_sgsn2_nsei = 0xffff;
+	gbcfg.keep_tlli_infos = GBPROX_KEEP_ALWAYS;
 
 	configure_sgsn_peer(&sgsn_peer);
 	configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
@@ -2661,6 +2665,8 @@
 	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
 	OSMO_ASSERT(tlli_info);
 	OSMO_ASSERT(tlli_info->imsi_len == 0);
+	OSMO_ASSERT(!tlli_info->is_deregistered);
+	OSMO_ASSERT(tlli_info->imsi_acq_pending);
 
 	send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
 		       foreign_tlli, &rai_bss, cell_id,
@@ -2669,6 +2675,11 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info->imsi_len > 0);
+	OSMO_ASSERT(!tlli_info->imsi_acq_pending);
+
 	send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
 		       foreign_tlli, 0, NULL, 0,
 		       GPRS_SAPI_GMM, sgsn_nu++,
@@ -2730,8 +2741,10 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
-	tlli_info = gbproxy_find_tlli(peer, local_tlli);
-	OSMO_ASSERT(tlli_info == NULL);
+	OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
+	tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info->is_deregistered);
 
 	/* Re-Attach */
 	send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
@@ -2741,6 +2754,14 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info == tlli_info2);
+	OSMO_ASSERT(tlli_info->imsi_len != 0);
+	OSMO_ASSERT(!tlli_info->is_deregistered);
+	OSMO_ASSERT(!tlli_info->imsi_acq_pending);
+
 	send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
 		       foreign_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, sgsn_nu++,
@@ -2774,6 +2795,9 @@
 	dump_peers(stdout, 0, 0, &gbcfg);
 
 	OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
+	tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info->is_deregistered);
 
 	/* Re-Attach */
 	send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
@@ -2783,6 +2807,14 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info == tlli_info2);
+	OSMO_ASSERT(tlli_info->imsi_len != 0);
+	OSMO_ASSERT(!tlli_info->is_deregistered);
+	OSMO_ASSERT(!tlli_info->imsi_acq_pending);
+
 	send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
 		       foreign_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, sgsn_nu++,
@@ -2816,6 +2848,9 @@
 	dump_peers(stdout, 0, 0, &gbcfg);
 
 	OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
+	tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info->is_deregistered);
 
 	/* Re-Attach */
 	send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
@@ -2825,6 +2860,14 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info == tlli_info2);
+	OSMO_ASSERT(tlli_info->imsi_len != 0);
+	OSMO_ASSERT(!tlli_info->is_deregistered);
+	OSMO_ASSERT(!tlli_info->imsi_acq_pending);
+
 	send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
 		       foreign_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, sgsn_nu++,
@@ -2852,6 +2895,10 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	/* TODO: This should have de-registered the TLLI which it did not. Add
+	 *       assertions when this is fixed.
+	 */
+
 	/* Bad case: Re-Attach with wrong (initial) P-TMSI */
 	send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
 		       foreign_tlli, &rai_bss, cell_id,
@@ -2860,6 +2907,18 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info != tlli_info2);
+	OSMO_ASSERT(tlli_info->imsi_len == 0);
+	OSMO_ASSERT(!tlli_info->is_deregistered);
+	OSMO_ASSERT(tlli_info->imsi_acq_pending);
+
+	/* This wouldn't happen in reality, since the Attach Request hadn't
+	 * been forwarded to the SGSN.
+	 * TODO: Add the missing messages.
+	 */
 	send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
 		       foreign_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, sgsn_nu++,
@@ -2867,6 +2926,14 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
+	tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
+	OSMO_ASSERT(tlli_info);
+	OSMO_ASSERT(tlli_info == tlli_info2);
+	OSMO_ASSERT(tlli_info->imsi_len >= 0);
+	OSMO_ASSERT(!tlli_info->is_deregistered);
+	OSMO_ASSERT(tlli_info->imsi_acq_pending);
+
 	send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
 		       local_tlli, &rai_bss, cell_id,
 		       GPRS_SAPI_GMM, bss_nu++,
@@ -2892,6 +2959,11 @@
 
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	/* TODO: There is one entry with this TLLI left (since there were 2
+	 *       before the detach precedure started. Add assertions when
+	 *       this is fixed.
+	 */
+
 	dump_global(stdout, 0);
 
 	gbprox_reset(&gbcfg);
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index 80a691e..49ab7e3 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -4344,25 +4344,27 @@
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 1
-    TLLI-Cache: 0
+    TLLI cache size                 : 1
+    TLLI-Cache: 1
+      TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED
 PROCESSING ATTACH REQUEST from 0x01020304:1111
 00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 
 
 CALLBACK, event 0, msg length 75, bvci 0x1002
 00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 
 
-NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
-MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 
+NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
+MESSAGE to SGSN at 0x05060708:32000, msg length 79
+00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 
 
-result (ATTACH REQUEST) = 0
+result (ATTACH REQUEST) = 79
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 2
     TLLI cache size                 : 1
     TLLI-Cache: 1
-      TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress
+      TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0
 PROCESSING ATTACH ACCEPT from 0x05060708:32000
 00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 
 
@@ -4380,17 +4382,13 @@
     Attach Request count            : 2
     TLLI cache size                 : 1
     TLLI-Cache: 1
-      TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0, STORED 1, IMSI acquisition in progress
+      TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0
 PROCESSING ATTACH COMPLETE from 0x01020304:1111
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc 
 
 CALLBACK, event 0, msg length 31, bvci 0x1002
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc 
 
-NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
-MESSAGE to SGSN at 0x05060708:32000, msg length 79
-00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 
-
 NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
 MESSAGE to SGSN at 0x05060708:32000, msg length 35
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc 
@@ -4436,25 +4434,27 @@
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 2
-    TLLI-Cache: 0
+    TLLI cache size                 : 1
+    TLLI-Cache: 1
+      TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED
 PROCESSING ATTACH REQUEST from 0x01020304:1111
 00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc 
 
 CALLBACK, event 0, msg length 75, bvci 0x1002
 00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc 
 
-NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
-MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 
+NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
+MESSAGE to SGSN at 0x05060708:32000, msg length 79
+00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc 
 
-result (ATTACH REQUEST) = 0
+result (ATTACH REQUEST) = 79
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 3
     TLLI cache size                 : 1
     TLLI-Cache: 1
-      TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress
+      TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0
 PROCESSING ATTACH ACCEPT from 0x05060708:32000
 00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 19 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 27 3c 84 
 
@@ -4472,17 +4472,13 @@
     Attach Request count            : 3
     TLLI cache size                 : 1
     TLLI-Cache: 1
-      TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0, STORED 1, IMSI acquisition in progress
+      TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0
 PROCESSING ATTACH COMPLETE from 0x01020304:1111
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47 
 
 CALLBACK, event 0, msg length 31, bvci 0x1002
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47 
 
-NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
-MESSAGE to SGSN at 0x05060708:32000, msg length 79
-00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc 
-
 NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
 MESSAGE to SGSN at 0x05060708:32000, msg length 35
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47 
@@ -4528,25 +4524,27 @@
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 3
-    TLLI-Cache: 0
+    TLLI cache size                 : 1
+    TLLI-Cache: 1
+      TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED
 PROCESSING ATTACH REQUEST from 0x01020304:1111
 00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 2d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 14 f4 a3 
 
 CALLBACK, event 0, msg length 75, bvci 0x1002
 00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 2d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 14 f4 a3 
 
-NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
-MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 
+NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
+MESSAGE to SGSN at 0x05060708:32000, msg length 79
+00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 2d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 14 f4 a3 
 
-result (ATTACH REQUEST) = 0
+result (ATTACH REQUEST) = 79
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 4
     TLLI cache size                 : 1
     TLLI-Cache: 1
-      TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress
+      TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0
 PROCESSING ATTACH ACCEPT from 0x05060708:32000
 00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 21 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 cf 80 6e 
 
@@ -4564,17 +4562,13 @@
     Attach Request count            : 4
     TLLI cache size                 : 1
     TLLI-Cache: 1
-      TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0, STORED 1, IMSI acquisition in progress
+      TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0
 PROCESSING ATTACH COMPLETE from 0x01020304:1111
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11 
 
 CALLBACK, event 0, msg length 31, bvci 0x1002
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11 
 
-NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
-MESSAGE to SGSN at 0x05060708:32000, msg length 79
-00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 2d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 14 f4 a3 
-
 NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
 MESSAGE to SGSN at 0x05060708:32000, msg length 35
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11 
@@ -4712,8 +4706,9 @@
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     Attach Request count            : 5
-    TLLI cache size                 : 1
-    TLLI-Cache: 1
+    TLLI cache size                 : 2
+    TLLI-Cache: 2
+      TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED
       TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0
 Gbproxy global:
 Test TLLI info expiry