diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-07 16:07:24 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-13 10:42:26 +0200 |
commit | c812882dbf9c55636c57f7b2e18314d11a94168b (patch) | |
tree | b66efe7acbcd4380df585e3ec37658a72dfe59c3 /openbsc | |
parent | 291f0508c52666d592ee111254364b0a6809d0ae (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
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/src/gprs/gb_proxy.c | 137 |
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) { |