Optionally Use the NS Sub-Network-Service (SNS) on Gb

This change add support for the recently-introduced GPRS Gb interface
auto-configuration using the NS IP Sub-Network Service (SNS) procedures.

It requires a Change-Id I84786c3b43a8ae34ef3b3ba84b33c90042d234ea of
libosmocore.

Related: OS#3372
Depends: I84786c3b43a8ae34ef3b3ba84b33c90042d234ea (libosmcore)
Change-Id: I256b40ac592d3b6e75dd581bf7b9512f69b11e83
This commit is contained in:
Harald Welte 2018-07-05 03:11:17 +02:00
parent 2a47c73217
commit 57d3515abd
3 changed files with 50 additions and 7 deletions

View File

@ -159,6 +159,9 @@ struct gprs_rlcmac_bts {
/* Path to be used for the pcu-bts socket */
char *pcu_sock_path;
/* Are we talking Gb with IP-SNS (true) or classic Gb? */
bool gb_dialect_sns;
};
#ifdef __cplusplus

View File

@ -541,12 +541,20 @@ static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
return -EINVAL;
nssd = (struct ns_signal_data *)signal_data;
if (nssd->nsvc != the_pcu.nsvc) {
if (signal != S_SNS_CONFIGURED && nssd->nsvc != the_pcu.nsvc) {
LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");
return -EINVAL;
}
switch (signal) {
case S_SNS_CONFIGURED:
the_pcu.bvc_sig_reset = 0;
the_pcu.bvc_reset = 0;
/* There's no NS-RESET / NS-UNBLOCK procedure on IP SNS based NS-VCs */
the_pcu.nsvc_unblocked = 1;
LOGP(DPCU, LOGL_NOTICE, "NS-VC %d is unblocked.\n", the_pcu.nsvc->nsvci);
bvc_timeout(NULL);
break;
case S_NS_UNBLOCK:
if (!the_pcu.nsvc_unblocked) {
the_pcu.nsvc_unblocked = 1;
@ -872,9 +880,10 @@ static int gprs_ns_reconnect(struct gprs_nsvc *nsvc)
return -EBADF;
}
nsvc2 = gprs_ns_nsip_connect(bssgp_nsi, &nsvc->ip.bts_addr,
nsvc->nsei, nsvc->nsvci);
if (the_pcu.bts->gb_dialect_sns)
nsvc2 = gprs_ns_nsip_connect_sns(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
else
nsvc2 = gprs_ns_nsip_connect(bssgp_nsi, &nsvc->ip.bts_addr, nsvc->nsei, nsvc->nsvci);
if (!nsvc2) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to reconnect NSVC\n");
return -EIO;
@ -905,8 +914,13 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts
return NULL;
}
gprs_ns_vty_init(bssgp_nsi);
bssgp_nsi->nsip.remote_port = sgsn_port;
bssgp_nsi->nsip.remote_ip = sgsn_ip;
/* don't specify remote IP/port if SNS dialect is in use; Doing so would
* issue a connect() on the socket, which prevents us to dynamically communicate
* with any number of IP-SNS endpoints on the SGSN side */
if (!bts->gb_dialect_sns) {
bssgp_nsi->nsip.remote_port = sgsn_port;
bssgp_nsi->nsip.remote_ip = sgsn_ip;
}
bssgp_nsi->nsip.local_port = local_port;
rc = gprs_ns_nsip_listen(bssgp_nsi);
if (rc < 0) {
@ -920,7 +934,10 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts
dest.sin_port = htons(sgsn_port);
dest.sin_addr.s_addr = htonl(sgsn_ip);
the_pcu.nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);
if (bts->gb_dialect_sns)
the_pcu.nsvc = gprs_ns_nsip_connect_sns(bssgp_nsi, &dest, nsei, nsvci);
else
the_pcu.nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);
if (!the_pcu.nsvc) {
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSVCt\n");
gprs_ns_destroy(bssgp_nsi);

View File

@ -265,6 +265,11 @@ static int config_write_pcu(struct vty *vty)
}
}
if (bts->gb_dialect_sns)
vty_out(vty, " gb-dialect ip-sns%s", VTY_NEWLINE);
else
vty_out(vty, " gb-dialect classic%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
@ -1059,6 +1064,23 @@ DEFUN(cfg_pcu_sock,
return CMD_SUCCESS;
}
DEFUN(cfg_pcu_gb_dialect,
cfg_pcu_gb_dialect_cmd,
"gb-dialect (classic|ip-sns)",
"Select which Gb interface dialect to use\n"
"Classic Gb interface with NS-{RESET,BLOCK,UNBLOCK} and static configuration\n"
"Modern Gb interface with IP-SNS (Sub Network Service) and dynamic configuration\n")
{
struct gprs_rlcmac_bts *bts = bts_main_data();
if (!strcmp(argv[0], "ip-sns"))
bts->gb_dialect_sns = true;
else
bts->gb_dialect_sns = false;
return CMD_SUCCESS;
}
DEFUN(show_tbf,
show_tbf_cmd,
"show tbf all",
@ -1189,6 +1211,7 @@ int pcu_vty_init(const struct log_info *cat)
install_element(PCU_NODE, &cfg_pcu_gsmtap_categ_cmd);
install_element(PCU_NODE, &cfg_pcu_no_gsmtap_categ_cmd);
install_element(PCU_NODE, &cfg_pcu_sock_cmd);
install_element(PCU_NODE, &cfg_pcu_gb_dialect_cmd);
install_element_ve(&show_bts_stats_cmd);
install_element_ve(&show_tbf_cmd);