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
This commit is contained in:
Jacob Erlbeck 2014-08-21 13:45:04 +02:00
parent 48bb3a37da
commit 46f1d6fddb
1 changed files with 57 additions and 32 deletions

View File

@ -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;