aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-07 16:07:24 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-13 10:42:26 +0200
commitc812882dbf9c55636c57f7b2e18314d11a94168b (patch)
treeb66efe7acbcd4380df585e3ec37658a72dfe59c3
parent291f0508c52666d592ee111254364b0a6809d0ae (diff)
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
-rw-r--r--openbsc/src/gprs/gb_proxy.c137
1 files changed, 81 insertions, 56 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index e7975497a..d36ff5bc6 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -1347,8 +1347,8 @@ static void gbprox_update_state_after(struct gbproxy_peer *peer,
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,50 +1428,28 @@ static int gbprox_parse_bssgp_message(uint8_t *bssgp, size_t bssgp_len,
}
/* 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;
- int rc;
- if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn)
+ if (!patching_is_enabled(peer, GBPROX_PATCH_BSSGP))
return;
- parse_ctx.to_bss = to_bss;
-
- rc = gbprox_parse_bssgp_message(msgb_bssgph(msg), msgb_bssgp_len(msg),
- &parse_ctx);
-
- if (!rc) {
- if (!parse_ctx.need_decryption) {
- LOGP(DGPRS, LOGL_ERROR,
- "Failed to parse BSSGP/GMM message\n");
- return;
- }
- }
-
- if (!peer && msgb_bvci(msg) >= 2)
- peer = peer_by_bvci(cfg, msgb_bvci(msg));
-
- if (!peer && !to_bss)
- peer = gbprox_peer_by_nsei(cfg, msgb_nsei(msg));
-
- if (!peer)
- peer = peer_by_bssgp_tlv(cfg, &parse_ctx.bssgp_tp);
+ if (parse_ctx->bssgp_raid_enc)
+ gbprox_patch_raid(parse_ctx->bssgp_raid_enc, peer,
+ parse_ctx->to_bss, "BSSGP");
- if (!peer) {
- LOGP(DLLC, LOGL_INFO,
- "NSEI=%d(%s) patching: didn't find peer for message, "
- "PDU %d\n",
- msgb_nsei(msg), to_bss ? "SGSN" : "BSS", parse_ctx.pdu_type);
- /* Increment counter */
- rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PATCH_PEER_ERR]);
+ if (!patching_is_enabled(peer, GBPROX_PATCH_LLC_ATTACH_REQ))
return;
- }
- if (parse_ctx.need_decryption &&
+ 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
@@ -1482,25 +1460,20 @@ static void gbprox_patch_bssgp_message(struct gbproxy_config *cfg, struct msgb *
goto patch_error;
}
- gbprox_update_state(peer, &parse_ctx);
+ if (parse_ctx->llc) {
+ uint8_t *llc = parse_ctx->llc;
+ size_t llc_len = parse_ctx->llc_len;
+ int llc_len_change = 0;
- 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);
+ 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 (len_change) {
- llc_len += len_change;
+ if (llc_len_change) {
+ llc_len += llc_len_change;
/* Fix LLC IE len */
/* TODO: This is a kludge, but the a pointer to the
@@ -1517,14 +1490,12 @@ static void gbprox_patch_bssgp_message(struct gbproxy_config *cfg, struct msgb *
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;
+ parse_ctx->llc_len = llc_len;
}
-
- gbprox_update_state_after(peer, &parse_ctx);
-
return;
patch_error:
@@ -1534,6 +1505,60 @@ patch_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(msgb_bssgph(msg), msgb_bssgp_len(msg),
+ &parse_ctx);
+
+ if (!rc) {
+ if (!parse_ctx.need_decryption) {
+ LOGP(DGPRS, LOGL_ERROR,
+ "Failed to parse BSSGP/GMM message\n");
+ return;
+ }
+ }
+
+ if (!peer && msgb_bvci(msg) >= 2)
+ peer = peer_by_bvci(cfg, msgb_bvci(msg));
+
+ if (!peer && !to_bss)
+ peer = gbprox_peer_by_nsei(cfg, msgb_nsei(msg));
+
+ if (!peer)
+ peer = peer_by_bssgp_tlv(cfg, &parse_ctx.bssgp_tp);
+
+ if (!peer) {
+ LOGP(DLLC, LOGL_INFO,
+ "NSEI=%d(%s) patching: didn't find peer for message, "
+ "PDU %d\n",
+ msgb_nsei(msg), to_bss ? "SGSN" : "BSS", parse_ctx.pdu_type);
+ /* Increment counter */
+ rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PATCH_PEER_ERR]);
+ return;
+ }
+
+ gbprox_update_state(peer, &parse_ctx);
+
+ gbprox_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),
+ peer, &len_change, &parse_ctx);
+
+ gbprox_update_state_after(peer, &parse_ctx);
+
+ return;
+}
+
/* feed a message down the NS-VC associated with the specified peer */
static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
struct gbproxy_peer *peer, uint16_t ns_bvci)
@@ -1543,7 +1568,7 @@ static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
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 gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei,
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) {