From 46f1d6fddb422871eec22951dd04b936ffa79c3a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 21 Aug 2014 13:45:04 +0200 Subject: [PATCH] gbproxy: Move PTP message handling into separate functions This patch adds gbprox_rx_data_from_sgsn() and gbprox_rx_ptp_from_bss() which contain the PTP message processing of gbprox_rcvmsg(). The calls to gbprox_process_bssgp_ul() are moved from gbprox_relay2sgsn() to gbprox_rx_ptp_from_bss() and gbprox_rx_sig_from_bss(). The goal is, to do all patching (and calls to gbprox_process_bssgp_*) from within the gbprox_rx_* functions. Doing the patching from within gbprox_relay2sgsn has the drawback, that the patching code cannot call gbprox_relay2sgsn() which is needed if a single message shall trigger a sequence of messages. Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gb_proxy.c | 89 ++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 9a9967fce..dfceabea0 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -325,15 +325,13 @@ static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg, /* 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) + uint16_t ns_bvci) { /* create a copy of the message so the old one can * be free()d safely when we return from gbprox_rcvmsg() */ struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2sgsn"); int rc; - gbprox_process_bssgp_ul(cfg, msg, peer); - DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n", msgb_nsei(msg), ns_bvci, cfg->nsip_sgsn_nsei); @@ -424,6 +422,53 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) return 0; } +/* Receive an incoming PTP message from a BSS-side NS-VC */ +static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg, + struct msgb *msg, uint16_t nsei, + uint16_t nsvci, uint16_t ns_bvci) +{ + struct gbproxy_peer *peer; + + peer = gbproxy_peer_by_bvci(cfg, ns_bvci); + + if (peer) + check_peer_nsei(peer, nsei); + + gbprox_process_bssgp_ul(cfg, msg, peer); + + return gbprox_relay2sgsn(cfg, msg, ns_bvci); +} + +/* Receive an incoming PTP message from a SGSN-side NS-VC */ +static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg, + struct msgb *msg, uint16_t nsei, + uint16_t nsvci, uint16_t ns_bvci) +{ + struct gbproxy_peer *peer; + + peer = gbproxy_peer_by_bvci(cfg, ns_bvci); + + if (!peer) { + LOGP(DGPRS, LOGL_INFO, "Didn't find peer for " + "BVCI=%u for message from NSVC=%u/NSEI=%u (SGSN)\n", + ns_bvci, nsvci, nsei); + rate_ctr_inc(&cfg->ctrg-> + ctr[GBPROX_GLOB_CTR_INV_BVCI]); + return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, + &ns_bvci, msg); + } + + if (peer->blocked) { + LOGP(DGPRS, LOGL_NOTICE, "Dropping PDU for " + "blocked BVCI=%u via NSVC=%u/NSEI=%u\n", + ns_bvci, nsvci, nsei); + rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]); + return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, NULL, msg); + } + + return gbprox_relay2peer(msg, peer, ns_bvci); +} + /* Receive an incoming signalling message from a BSS-side NS-VC */ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, @@ -524,7 +569,8 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg, /* Normally, we can simply pass on all signalling messages from BSS to * SGSN */ - return gbprox_relay2sgsn(cfg, msg, from_peer, ns_bvci); + gbprox_process_bssgp_ul(cfg, msg, from_peer); + return gbprox_relay2sgsn(cfg, msg, ns_bvci); err_no_peer: LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) cannot find peer based on NSEI\n", nsei); @@ -746,7 +792,6 @@ int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, uint16_t ns_bvci, uint16_t nsvci) { int rc; - struct gbproxy_peer *peer; int remote_end_is_sgsn = nsei == cfg->nsip_sgsn_nsei; if (remote_end_is_sgsn) @@ -759,33 +804,13 @@ int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, else rc = gbprox_rx_sig_from_bss(cfg, msg, nsei, ns_bvci); } else { - peer = gbproxy_peer_by_bvci(cfg, ns_bvci); - - /* All other BVCI are PTP and thus can be simply forwarded */ - if (!remote_end_is_sgsn) { - if (peer) - check_peer_nsei(peer, nsei); - return gbprox_relay2sgsn(cfg, msg, peer, ns_bvci); - } - - /* else: SGSN -> BSS direction */ - if (!peer) { - LOGP(DGPRS, LOGL_INFO, "Didn't find peer for " - "BVCI=%u for message from NSVC=%u/NSEI=%u (SGSN)\n", - ns_bvci, nsvci, nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ns_bvci, msg); - } - if (peer->blocked) { - LOGP(DGPRS, LOGL_NOTICE, "Dropping PDU for " - "blocked BVCI=%u via NSVC=%u/NSEI=%u\n", - ns_bvci, nsvci, nsei); - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]); - return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, NULL, msg); - } - rc = gbprox_relay2peer(msg, peer, ns_bvci); + /* All other BVCI are PTP */ + if (remote_end_is_sgsn) + rc = gbprox_rx_ptp_from_sgsn(cfg, msg, nsei, nsvci, + ns_bvci); + else + rc = gbprox_rx_ptp_from_bss(cfg, msg, nsei, nsvci, + ns_bvci); } return rc;