gprs: Track IMSI/TLLI to control APN patching

This patch adds IMSI/TLLI connection tracking and uses it to control
APN patching based on the IMSI. TLLI entries can expire based on age
and/or by limiting the TLLI list size.

VTY config-gbproxy:
  no core-access-point-name                   disable APN patching
  core-access-point-name none                 remove APN if present
  core-access-point-name APN                  replace APN if present
  core-access-point-name none match-imsi RE   remove if IMSI matches
  core-access-point-name APN match-imsi RE    replace if IMSI matches
  tlli-list max-age SECONDS                   expire after SECONDS
  no tlli-list max-age                        don't expire by age
  tlli-list max-length N                      keep N entries only
  no tlli-list max-length                     don't limit list length

RE is an extended regular expression, e.g. ^12345|^23456

Ticket: OW#1192
Sponsored-by: On-Waves ehf
diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c
index fa7e0bb..a9d0655 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.c
+++ b/openbsc/tests/gbproxy/gbproxy_test.c
@@ -842,6 +842,7 @@
 		{.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
 	struct  gprs_ra_id rai_unknown =
 		{.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
+	const char *err_msg = NULL;
 
 	bssgp_nsi = nsi;
 	gbcfg.nsi = bssgp_nsi;
@@ -854,6 +855,14 @@
 	configure_sgsn_peer(&sgsn_peer);
 	configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
 
+	gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
+	if (gbprox_set_patch_filter(gbcfg.match_re, &err_msg) != 0) {
+		fprintf(stderr, "Failed to compile RE '%s': %s\n",
+			gbcfg.match_re, err_msg);
+		exit(1);
+	}
+
+
 	printf("=== %s ===\n", __func__);
 	printf("--- Initialise SGSN ---\n\n");
 
@@ -917,7 +926,7 @@
 
 	printf("--- Bad cases ---\n\n");
 
-	printf("Invalid BVCI, shouldn't patch\n");
+	printf("TLLI is already detached, shouldn't patch\n");
 	send_ns_unitdata(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
 			 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
 
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index da5cd41..fb8991c 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -1680,18 +1680,18 @@
     APN patched                     : 2
 --- Bad cases ---
 
-Invalid BVCI, shouldn't patch
+TLLI is already detached, shouldn't patch
 PROCESSING ACT PDP CTX REQ from 0x01020304:1111
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 
 
 CALLBACK, event 0, msg length 76, bvci 0x1002
 00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 
 
-NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 71 (gprs_ns_sendmsg)
-MESSAGE to SGSN at 0x05060708:32000, msg length 75
-00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 30 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 85 fa 60 
+NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 76 (gprs_ns_sendmsg)
+MESSAGE to SGSN at 0x05060708:32000, msg length 80
+00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 
 
-result (ACT PDP CTX REQ) = 75
+result (ACT PDP CTX REQ) = 80
 
 Invalid RAI, shouldn't patch
 PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000
@@ -1713,6 +1713,6 @@
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
     RAID patched              (BSS ): 10
     RAID patched              (SGSN): 3
-    APN patched                     : 3
+    APN patched                     : 2
 ===== GbProxy test END