diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-26 14:47:15 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-09-08 09:11:59 +0200 |
commit | f4d60c8788c16ee55f827a828c5618b4bd8c4a46 (patch) | |
tree | 0e5ec54087680c1d7b707602aecf206dbdc822fe /openbsc/src/gprs/gb_proxy.c | |
parent | 593006470075419ab10715e3a7e23332b6a136a4 (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.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index f0375ee44..539e3aef9 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 |