gbproxy: Refactor gbproxy_patch_bssgp_message

This patch refactors that function by separating the actual patch
code into a new function gbproxy_patch_bssgp(), similar to
gbproxy_patch_llc(). The remaining function is renamed to
gbproxy_process_bssgp_message. The existing function
gbproxy_parse_bssgp_message() is renamed to
gbproxy_process_bssgp_message to match gbproxy_parse_llc.

Sponsored-by: On-Waves ehf
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index e797549..d36ff5b 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -1347,8 +1347,8 @@
 		gbprox_unregister_tlli(peer, parse_ctx->tlli);
 }
 
-static int gbprox_parse_bssgp_message(uint8_t *bssgp, size_t bssgp_len,
-				       struct gbproxy_parse_context *parse_ctx)
+static int gbprox_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
+			      struct gbproxy_parse_context *parse_ctx)
 {
 	struct bssgp_normal_hdr *bgph;
 	struct bssgp_ud_hdr *budh = NULL;
@@ -1428,21 +1428,99 @@
 }
 
 /* patch BSSGP message to use core_mcc/mnc on the SGSN side */
-static void gbprox_patch_bssgp_message(struct gbproxy_config *cfg, struct msgb *msg,
-				       struct gbproxy_peer *peer, int to_bss)
+static void gbprox_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
+			       struct gbproxy_peer *peer, int *len_change,
+			       struct gbproxy_parse_context *parse_ctx)
+	__attribute__((nonnull));
+static void gbprox_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
+			       struct gbproxy_peer *peer, int *len_change,
+			       struct gbproxy_parse_context *parse_ctx)
 {
-	struct gbproxy_parse_context parse_ctx = {0};
 	const char *err_info = NULL;
 	int err_ctr = -1;
+
+	if (!patching_is_enabled(peer, GBPROX_PATCH_BSSGP))
+		return;
+
+	if (parse_ctx->bssgp_raid_enc)
+		gbprox_patch_raid(parse_ctx->bssgp_raid_enc, peer,
+				  parse_ctx->to_bss, "BSSGP");
+
+	if (!patching_is_enabled(peer, GBPROX_PATCH_LLC_ATTACH_REQ))
+		return;
+
+	if (parse_ctx->need_decryption &&
+	    patching_is_required(peer, GBPROX_PATCH_LLC_ATTACH)) {
+		/* Patching LLC messages has been requested
+		 * explicitly, but the message (including the
+		 * type) is encrypted, so we possibly fail to
+		 * patch the LLC part of the message. */
+		err_ctr = GBPROX_PEER_CTR_PATCH_CRYPT_ERR;
+		err_info = "GMM message is encrypted";
+		goto patch_error;
+	}
+
+	if (parse_ctx->llc) {
+		uint8_t *llc = parse_ctx->llc;
+		size_t llc_len = parse_ctx->llc_len;
+		int llc_len_change = 0;
+
+		gbprox_patch_llc(msg, llc, llc_len, peer, &llc_len_change,
+				 parse_ctx);
+		/* Note that the APN might have been resized here, but no
+		 * pointer int the parse_ctx will refer to an adress after the
+		 * APN. So it's possible to patch first and do the TLLI
+		 * handling afterwards. */
+
+		if (llc_len_change) {
+			llc_len += llc_len_change;
+
+			/* Fix LLC IE len */
+			/* TODO: This is a kludge, but the a pointer to the
+			 * start of the IE is not available here */
+			if (llc[-2] == BSSGP_IE_LLC_PDU && llc[-1] & 0x80) {
+				/* most probably a one byte length */
+				if (llc_len > 127) {
+					err_info = "Cannot increase size";
+					err_ctr = GBPROX_PEER_CTR_PATCH_ERR;
+					goto patch_error;
+				}
+				llc[-1] = llc_len | 0x80;
+			} else {
+				llc[-2] = (llc_len >> 8) & 0x7f;
+				llc[-1] = llc_len & 0xff;
+			}
+			*len_change += llc_len_change;
+		}
+		/* Note that the tp struct might contain invalid pointers here
+		 * if the LLC field has changed its size */
+		parse_ctx->llc_len = llc_len;
+	}
+	return;
+
+patch_error:
+	OSMO_ASSERT(err_ctr >= 0);
+	rate_ctr_inc(&peer->ctrg->ctr[err_ctr]);
+	LOGP(DGPRS, LOGL_ERROR,
+	     "Failed to patch BSSGP message as requested: %s.\n", err_info);
+}
+
+/* patch BSSGP message to use core_mcc/mnc on the SGSN side */
+static void gbprox_process_bssgp_message(struct gbproxy_config *cfg,
+					 struct msgb *msg,
+					 struct gbproxy_peer *peer, int to_bss)
+{
+	struct gbproxy_parse_context parse_ctx = {0};
 	int rc;
+	int len_change = 0;
 
 	if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn)
 		return;
 
 	parse_ctx.to_bss = to_bss;
 
-	rc = gbprox_parse_bssgp_message(msgb_bssgph(msg), msgb_bssgp_len(msg),
-					&parse_ctx);
+	rc = gbprox_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
+				&parse_ctx);
 
 	if (!rc) {
 		if (!parse_ctx.need_decryption) {
@@ -1471,67 +1549,14 @@
 		return;
 	}
 
-	if (parse_ctx.need_decryption &&
-	    patching_is_required(peer, GBPROX_PATCH_LLC_ATTACH)) {
-		/* Patching LLC messages has been requested
-		 * explicitly, but the message (including the
-		 * type) is encrypted, so we possibly fail to
-		 * patch the LLC part of the message. */
-		err_ctr = GBPROX_PEER_CTR_PATCH_CRYPT_ERR;
-		err_info = "GMM message is encrypted";
-		goto patch_error;
-	}
-
 	gbprox_update_state(peer, &parse_ctx);
 
-	if (parse_ctx.bssgp_raid_enc)
-		gbprox_patch_raid(parse_ctx.bssgp_raid_enc, peer, to_bss, "BSSGP");
-
-	if (parse_ctx.llc &&
-	    patching_is_enabled(peer, GBPROX_PATCH_LLC_ATTACH_REQ)) {
-		uint8_t *llc = parse_ctx.llc;
-		size_t llc_len = parse_ctx.llc_len;
-		int len_change = 0;
-
-		gbprox_patch_llc(msg, llc, llc_len, peer, &len_change, &parse_ctx);
-		/* Note that the APN might have been resized here, but no
-		 * pointer int the parse_ctx will refer to an adress after the
-		 * APN. So it's possible to patch first and do the TLLI
-		 * handling afterwards. */
-
-		if (len_change) {
-			llc_len += len_change;
-
-			/* Fix LLC IE len */
-			/* TODO: This is a kludge, but the a pointer to the
-			 * start of the IE is not available here */
-			if (llc[-2] == BSSGP_IE_LLC_PDU && llc[-1] & 0x80) {
-				/* most probably a one byte length */
-				if (llc_len > 127) {
-					err_info = "Cannot increase size";
-					err_ctr = GBPROX_PEER_CTR_PATCH_ERR;
-					goto patch_error;
-				}
-				llc[-1] = llc_len | 0x80;
-			} else {
-				llc[-2] = (llc_len >> 8) & 0x7f;
-				llc[-1] = llc_len & 0xff;
-			}
-		}
-		/* Note that the tp struct might contain invalid pointers here
-		 * if the LLC field has changed its size */
-		parse_ctx.llc_len = llc_len;
-	}
+	gbprox_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),
+			   peer, &len_change, &parse_ctx);
 
 	gbprox_update_state_after(peer, &parse_ctx);
 
 	return;
-
-patch_error:
-	OSMO_ASSERT(err_ctr >= 0);
-	rate_ctr_inc(&peer->ctrg->ctr[err_ctr]);
-	LOGP(DGPRS, LOGL_ERROR,
-	     "Failed to patch BSSGP message as requested: %s.\n", err_info);
 }
 
 /* feed a message down the NS-VC associated with the specified peer */
@@ -1543,7 +1568,7 @@
 	struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2sgsn");
 	int rc;
 
-	gbprox_patch_bssgp_message(cfg, msg, peer, 0);
+	gbprox_process_bssgp_message(cfg, msg, peer, 0);
 
 	DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n",
 		msgb_nsei(msg), ns_bvci, cfg->nsip_sgsn_nsei);
@@ -1961,7 +1986,7 @@
 	int remote_end_is_sgsn = nsei == cfg->nsip_sgsn_nsei;
 
 	if (remote_end_is_sgsn)
-		gbprox_patch_bssgp_message(cfg, msg, NULL, 1);
+		gbprox_process_bssgp_message(cfg, msg, NULL, 1);
 
 	/* Only BVCI=0 messages need special treatment */
 	if (ns_bvci == 0 || ns_bvci == 1) {