summaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-26 14:47:15 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2014-09-08 09:11:59 +0200
commitf4d60c8788c16ee55f827a828c5618b4bd8c4a46 (patch)
tree0e5ec54087680c1d7b707602aecf206dbdc822fe /openbsc/src/gprs/gb_proxy.c
parent593006470075419ab10715e3a7e23332b6a136a4 (diff)
gbproxy: Support a secondary SGSN
This patch refactors SGSN NSEI handling to support a secondary SGSN. It adds the following VTY commands: - secondary-sgsn nsei <0-65534> - no secondary-sgsn Sending messages to the secondary SGSN is not yet implemented, but received messages from such a SGSN would be forwarded to the BSS peers. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/gprs/gb_proxy.c')
-rw-r--r--openbsc/src/gprs/gb_proxy.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index f0375ee..539e3ae 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -75,7 +75,7 @@ static const struct rate_ctr_group_desc global_ctrg_desc = {
static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer,
uint16_t ns_bvci);
static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
- uint16_t ns_bvci);
+ uint16_t ns_bvci, uint16_t sgsn_nsei);
static int check_peer_nsei(struct gbproxy_peer *peer, uint16_t nsei)
{
@@ -358,7 +358,8 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
gbproxy_update_tlli_state_after(peer, tlli_info, now,
&tmp_parse_ctx);
- rc = gbprox_relay2sgsn(cfg, stored_msg, msgb_bvci(msg));
+ rc = gbprox_relay2sgsn(cfg, stored_msg, msgb_bvci(msg),
+ cfg->nsip_sgsn_nsei);
if (rc < 0)
LOGP(DLLC, LOGL_ERROR,
@@ -496,7 +497,7 @@ 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,
- uint16_t ns_bvci)
+ uint16_t ns_bvci, uint16_t sgsn_nsei)
{
/* create a copy of the message so the old one can
* be free()d safely when we return from gbprox_rcvmsg() */
@@ -504,10 +505,10 @@ static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
int rc;
DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n",
- msgb_nsei(msg), ns_bvci, cfg->nsip_sgsn_nsei);
+ msgb_nsei(msg), ns_bvci, sgsn_nsei);
msgb_bvci(msg) = ns_bvci;
- msgb_nsei(msg) = cfg->nsip_sgsn_nsei;
+ msgb_nsei(msg) = sgsn_nsei;
strip_ns_hdr(msg);
@@ -610,7 +611,7 @@ static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg,
if (!rc)
return 0;
- return gbprox_relay2sgsn(cfg, msg, ns_bvci);
+ return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);
}
/* Receive an incoming PTP message from a SGSN-side NS-VC */
@@ -752,7 +753,7 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
rc = gbprox_process_bssgp_ul(cfg, msg, from_peer);
if (!rc)
return 0;
- return gbprox_relay2sgsn(cfg, msg, ns_bvci);
+ return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);
err_no_peer:
LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) cannot find peer based on NSEI\n",
nsei);
@@ -981,12 +982,18 @@ err_no_peer:
return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, NULL, orig_msg);
}
+static int gbproxy_is_sgsn_nsei(struct gbproxy_config *cfg, uint16_t nsei)
+{
+ return nsei == cfg->nsip_sgsn_nsei ||
+ (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei);
+}
+
/* Main input function for Gb proxy */
int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei,
uint16_t ns_bvci, uint16_t nsvci)
{
int rc;
- int remote_end_is_sgsn = nsei == cfg->nsip_sgsn_nsei;
+ int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsei);
/* Only BVCI=0 messages need special treatment */
if (ns_bvci == 0 || ns_bvci == 1) {
@@ -1027,11 +1034,12 @@ int gbprox_signal(unsigned int subsys, unsigned int signal,
struct ns_signal_data *nssd = signal_data;
struct gprs_nsvc *nsvc = nssd->nsvc;
struct gbproxy_peer *peer;
+ int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsvc->nsei);
if (subsys != SS_L_NS)
return 0;
- if (signal == S_NS_RESET && nsvc->nsei == cfg->nsip_sgsn_nsei) {
+ if (signal == S_NS_RESET && remote_end_is_sgsn) {
/* We have received a NS-RESET from the NSEI and NSVC
* of the SGSN. This might happen with SGSN that start
* their own NS-RESET procedure without waiting for our