gbproxy: Implement IMSI acquisition

To modify or route messages based on the IMSI the latter must be known
when the action shall take place.

This patch modifies the gbproxy to optionally retain and enqueue
messages from the MS while initiating an identification procedure.
Further message processing of the LLC PTP link towards the SGSN will
be done, when the identity of the MS has been acquired.

Note that the N(U) of the LLC GMM SAPI are not adjusted, so it is
possible that adjacent messages of a single LLC link arriving either
at the BSS or the SGSN have the same N(U) and might get discarded,
leading to retransmissions and additional delay.

Note also that retransmissions and packet loss are not yet handled
explicitely. If for instance the generated IDENT REQ gets lost, the
gbproxy will not act on its own. In this case, the MS will time out
and eventually resend the Attach Request on which the gbproxy will
act exactly like before (thus having two Attach Req messages in its
queue, which will both be sent after the Ident Resp arrives).

This has been tested successfully with an E71, needing one
retransmission by the SGSN due to an N(U) collision.

Ticket: OW#1261
Sponsored-by: On-Waves ehf
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index dcdc06c..49c0020 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -295,6 +295,28 @@
 	return CMD_SUCCESS;
 }
 
+#define GBPROXY_ACQUIRE_IMSI_STR "Acquire the IMSI before establishing a LLC connection (Experimental)\n"
+
+DEFUN(cfg_gbproxy_acquire_imsi,
+      cfg_gbproxy_acquire_imsi_cmd,
+      "acquire-imsi",
+      GBPROXY_ACQUIRE_IMSI_STR)
+{
+	g_cfg->acquire_imsi = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_gbproxy_no_acquire_imsi,
+      cfg_gbproxy_no_acquire_imsi_cmd,
+      "no acquire-imsi",
+      NO_STR GBPROXY_ACQUIRE_IMSI_STR)
+{
+	g_cfg->acquire_imsi = 0;
+
+	return CMD_SUCCESS;
+}
+
 #define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"
 #define GBPROXY_MAX_AGE_STR "Limit maximum age\n"
 
@@ -604,12 +626,14 @@
 	install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_match_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);
+	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_no_core_mcc_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_apn_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);
+	install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_no_max_age_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_no_max_len_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_patch_mode_cmd);