gbproxy: Fixed RAI patching in Attach Request messages

Currently the RAI in the LLC part of the message is not updated if
the message has been taken from the list of stored messages. The
reason is, that old_raid_matches is update in
gbprox_process_bssgp_ul() but not in gbproxy_flush_stored_messages().

This patch moves the check to gprs_gb_parse_bssgp() which is called
at both places and where other fields like parse_ctx->tlli are set,
too.

In addition, old_raid_matches is replaced by old_raid_is_foreign
since this is clearer in the case when there is no old RAI at all.

Several RAI patch counter assertions are also added to
test_gbproxy_ra_patching().

Sponsored-by: On-Waves ehf
diff --git a/openbsc/include/openbsc/gprs_gb_parse.h b/openbsc/include/openbsc/gprs_gb_parse.h
index eaf42d3..eb97763 100644
--- a/openbsc/include/openbsc/gprs_gb_parse.h
+++ b/openbsc/include/openbsc/gprs_gb_parse.h
@@ -37,7 +37,7 @@
 	int need_decryption;
 	uint32_t tlli;
 	int pdu_type;
-	int old_raid_matches;
+	int old_raid_is_foreign;
 };
 
 int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 2dfb4d8..344e164 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -494,10 +494,6 @@
 
 	now = time(NULL);
 
-	if (parse_ctx.bssgp_raid_enc && parse_ctx.old_raid_enc &&
-	    memcmp(parse_ctx.bssgp_raid_enc, parse_ctx.old_raid_enc, 6) == 0)
-		parse_ctx.old_raid_matches = 1;
-
 	gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer,
 				   parse_ctx.llc_msg_name);
 
diff --git a/openbsc/src/gprs/gb_proxy_patch.c b/openbsc/src/gprs/gb_proxy_patch.c
index be3ebd9..caedf89 100644
--- a/openbsc/src/gprs/gb_proxy_patch.c
+++ b/openbsc/src/gprs/gb_proxy_patch.c
@@ -199,7 +199,8 @@
 	int have_patched = 0;
 	int fcs;
 
-	if (parse_ctx->ptmsi_enc && tlli_info) {
+	if (parse_ctx->ptmsi_enc && tlli_info &&
+	    !parse_ctx->old_raid_is_foreign) {
 		uint32_t ptmsi;
 		if (parse_ctx->to_bss)
 			ptmsi = tlli_info->tlli.ptmsi;
@@ -234,7 +235,7 @@
 		have_patched = 1;
 	}
 
-	if (parse_ctx->old_raid_enc && parse_ctx->old_raid_matches) {
+	if (parse_ctx->old_raid_enc && !parse_ctx->old_raid_is_foreign) {
 		/* TODO: Patch to invalid if P-TMSI unknown. */
 		gbproxy_patch_raid(parse_ctx->old_raid_enc, peer, parse_ctx->to_bss,
 				   parse_ctx->llc_msg_name);
diff --git a/openbsc/src/gprs/gprs_gb_parse.c b/openbsc/src/gprs/gprs_gb_parse.c
index fe08817..f361951 100644
--- a/openbsc/src/gprs/gprs_gb_parse.c
+++ b/openbsc/src/gprs/gprs_gb_parse.c
@@ -557,6 +557,10 @@
 		parse_ctx->tlli = ntohl(tmp_tlli);
 	}
 
+	if (parse_ctx->bssgp_raid_enc && parse_ctx->old_raid_enc &&
+	    memcmp(parse_ctx->bssgp_raid_enc, parse_ctx->old_raid_enc, 6) != 0)
+		parse_ctx->old_raid_is_foreign = 1;
+
 	return 1;
 }
 
diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c
index 1521c5f..f2f8546 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.c
+++ b/openbsc/tests/gbproxy/gbproxy_test.c
@@ -1390,6 +1390,9 @@
 	dump_global(stdout, 0);
 	dump_peers(stdout, 0, 0, &gbcfg);
 
+	OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+	OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
+
 	printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
 
 	send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
@@ -1397,6 +1400,8 @@
 		       GPRS_SAPI_GMM, 0,
 		       dtap_attach_req, sizeof(dtap_attach_req));
 
+	OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
 		       foreign_tlli, 0, NULL, 0,
 		       GPRS_SAPI_GMM, 0,
@@ -1407,11 +1412,16 @@
 		       GPRS_SAPI_GMM, 3,
 		       dtap_identity_resp, sizeof(dtap_identity_resp));
 
+	OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+	OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
+
 	send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
 		       foreign_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, 1,
 		       dtap_attach_acc, sizeof(dtap_attach_acc));
 
+	OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
+
 	OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
 	OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
 	OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
@@ -1440,6 +1450,8 @@
 		       GPRS_SAPI_GMM, 4,
 		       dtap_attach_complete, sizeof(dtap_attach_complete));
 
+	OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
 	OSMO_ASSERT(tlli_info);
 	OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
@@ -1457,6 +1469,8 @@
 		       GPRS_SAPI_GMM, 3,
 		       dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
 
+	OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
 	OSMO_ASSERT(tlli_info);
 	OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
@@ -1473,6 +1487,8 @@
 		       GPRS_SAPI_GMM, 2,
 		       dtap_gmm_information, sizeof(dtap_gmm_information));
 
+	OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
+
 	tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
 	OSMO_ASSERT(tlli_info);
 	OSMO_ASSERT(tlli_info->tlli.assigned == 0);
@@ -1486,6 +1502,8 @@
 		       GPRS_SAPI_GMM, 3,
 		       dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
 
+	OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	gbcfg.core_apn[0] = 0;
 	gbcfg.core_apn_size = 0;
 
@@ -1495,6 +1513,8 @@
 		       GPRS_SAPI_GMM, 3,
 		       dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
 
+	OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	dump_peers(stdout, 0, 0, &gbcfg);
 
 	/* Detach */
@@ -1503,6 +1523,9 @@
 		       GPRS_SAPI_GMM, 6,
 		       dtap_detach_req, sizeof(dtap_detach_req));
 
+	OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+	OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
+
 	send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
 		       local_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, 5,
@@ -1517,17 +1540,23 @@
 		       GPRS_SAPI_GMM, 5,
 		       dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
 
+	OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
 		       foreign_tlli, 1, imsi, sizeof(imsi),
 		       GPRS_SAPI_GMM, 6,
 		       dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
 
+	OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
+
 	/* Remove APN */
 	send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
 		       local_tlli, &rai_bss, cell_id,
 		       GPRS_SAPI_GMM, 3,
 		       dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
 
+	OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	dump_peers(stdout, 0, 0, &gbcfg);
 
 	/* Detach (power off -> no Detach Accept) */
@@ -1536,6 +1565,8 @@
 		       GPRS_SAPI_GMM, 6,
 		       dtap_detach_po_req, sizeof(dtap_detach_po_req));
 
+	OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	dump_global(stdout, 0);
 	dump_peers(stdout, 0, 0, &gbcfg);
 
@@ -1549,6 +1580,8 @@
 		       GPRS_SAPI_GMM, 0,
 		       dtap_attach_req2, sizeof(dtap_attach_req2));
 
+	OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
+
 	printf("TLLI is already detached, shouldn't patch\n");
 	send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
 		       local_tlli, &rai_bss, cell_id,
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index 4a09561..0711292 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -2682,13 +2682,13 @@
 
 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 7c 69 fb 81 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 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 16 6d 01 
+00 00 10 02 01 7c 69 fb 81 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 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 8e cd 32 
 
 result (IDENT RESPONSE) = 0
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 2
+    RAID patched              (BSS ): 3
     TLLI patched              (BSS ): 1
     Attach Request count            : 1
     TLLI cache size                 : 1
@@ -2708,7 +2708,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 2
+    RAID patched              (BSS ): 3
     TLLI patched              (BSS ): 1
     TLLI patched              (SGSN): 1
     Attach Request count            : 1
@@ -2729,7 +2729,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 3
+    RAID patched              (BSS ): 4
     TLLI patched              (BSS ): 2
     TLLI patched              (SGSN): 1
     Attach Request count            : 1
@@ -2750,7 +2750,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 3
+    RAID patched              (BSS ): 4
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 2
     TLLI patched              (SGSN): 2
@@ -2773,7 +2773,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 4
+    RAID patched              (BSS ): 5
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 3
     TLLI patched              (SGSN): 2
@@ -2796,7 +2796,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 4
+    RAID patched              (BSS ): 5
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 3
     TLLI patched              (SGSN): 3
@@ -2855,7 +2855,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 6
+    RAID patched              (BSS ): 7
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 5
     TLLI patched              (SGSN): 5
@@ -2878,7 +2878,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 6
+    RAID patched              (BSS ): 7
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 6
     TLLI patched              (SGSN): 5
@@ -2901,7 +2901,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 6
+    RAID patched              (BSS ): 7
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 6
     TLLI patched              (SGSN): 6
@@ -2924,7 +2924,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 7
+    RAID patched              (BSS ): 8
     RAID patched              (SGSN): 1
     TLLI patched              (BSS ): 7
     TLLI patched              (SGSN): 6
@@ -2947,7 +2947,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 7
+    RAID patched              (BSS ): 8
     RAID patched              (SGSN): 2
     TLLI patched              (BSS ): 7
     TLLI patched              (SGSN): 7
@@ -3016,7 +3016,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 8
+    RAID patched              (BSS ): 9
     RAID patched              (SGSN): 3
     TLLI patched              (BSS ): 9
     TLLI patched              (SGSN): 8
@@ -3039,7 +3039,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 8
+    RAID patched              (BSS ): 9
     RAID patched              (SGSN): 3
     TLLI patched              (BSS ): 9
     TLLI patched              (SGSN): 9
@@ -3080,7 +3080,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 8
+    RAID patched              (BSS ): 9
     RAID patched              (SGSN): 3
     TLLI patched              (BSS ): 9
     TLLI patched              (SGSN): 9
@@ -3103,7 +3103,7 @@
 
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
-    RAID patched              (BSS ): 8
+    RAID patched              (BSS ): 9
     RAID patched              (SGSN): 3
     TLLI patched              (BSS ): 9
     TLLI patched              (SGSN): 9