diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-21 13:45:04 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-02 09:53:30 +0200 |
commit | 46f1d6fddb422871eec22951dd04b936ffa79c3a (patch) | |
tree | cf6386d8031b2dd263f6e598061d780591af6e9c /openbsc/src | |
parent | 48bb3a37da6d0c9257b5cbb7bd2c6816b4ec5ab0 (diff) |
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
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/gprs/gb_proxy.c | 89 |
1 files 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; |