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
This commit is contained in:
parent
5930064700
commit
f4d60c8788
|
@ -86,6 +86,8 @@ struct gbproxy_config {
|
|||
/* Experimental config */
|
||||
int patch_ptmsi;
|
||||
int acquire_imsi;
|
||||
int route_to_sgsn2;
|
||||
uint16_t nsip_sgsn2_nsei;
|
||||
|
||||
/* IMSI checking/matching */
|
||||
int check_imsi;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -317,6 +317,32 @@ DEFUN(cfg_gbproxy_no_acquire_imsi,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define GBPROXY_SECOND_SGSN_STR "Route matching LLC connections to a second SGSN (Experimental)\n"
|
||||
|
||||
DEFUN(cfg_gbproxy_secondary_sgsn,
|
||||
cfg_gbproxy_secondary_sgsn_cmd,
|
||||
"secondary-sgsn nsei <0-65534>",
|
||||
GBPROXY_SECOND_SGSN_STR
|
||||
"NSEI to be used in the connection with the SGSN\n"
|
||||
"The NSEI\n")
|
||||
{
|
||||
g_cfg->route_to_sgsn2 = 1;
|
||||
g_cfg->nsip_sgsn2_nsei = atoi(argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_gbproxy_no_secondary_sgsn,
|
||||
cfg_gbproxy_no_secondary_sgsn_cmd,
|
||||
"no secondary-sgsn",
|
||||
NO_STR GBPROXY_SECOND_SGSN_STR)
|
||||
{
|
||||
g_cfg->route_to_sgsn2 = 0;
|
||||
g_cfg->nsip_sgsn2_nsei = 0xFFFF;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"
|
||||
#define GBPROXY_MAX_AGE_STR "Limit maximum age\n"
|
||||
|
||||
|
@ -627,6 +653,7 @@ int gbproxy_vty_init(void)
|
|||
install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_match_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_max_age_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_max_len_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);
|
||||
|
@ -634,6 +661,7 @@ int gbproxy_vty_init(void)
|
|||
install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_apn_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_no_max_age_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_no_max_len_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_patch_mode_cmd);
|
||||
|
|
Loading…
Reference in New Issue