aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2021-03-04 22:29:17 +0100
committerHarald Welte <laforge@osmocom.org>2021-03-24 00:30:23 +0100
commitd164ef80f93eb36ba35c20015148188a7b4cf1b3 (patch)
treea498d0848cd28d7818840d373bf21ec859efe50e /src
parentfe0266e8d83a7622d51714db9693726ec035bdc8 (diff)
gprs_ns2_sns: Allow VTY configuration of default binds for IP-SNS
In the IP-SNS SGSN role, we need to inform the BSS of our local IP endpoints. For statically configured NSEs, those are explicitly stated on a per-NSE level. For dynamically created IP-SNS NSEs, we are adding a new VTY command, using which the administrator can configure which binds should be advertised as IP endpoints to such BSS. Change-Id: Id01c29b07e9203c9305f2129361a4f5aaefa2c52 Related: OS#3373
Diffstat (limited to 'src')
-rw-r--r--src/gb/gprs_ns2.c5
-rw-r--r--src/gb/gprs_ns2_internal.h3
-rw-r--r--src/gb/gprs_ns2_vty.c100
3 files changed, 106 insertions, 2 deletions
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 21a2d22d..4d27333a 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -933,8 +933,9 @@ static enum ns2_cs ns2_create_vc_sns(struct gprs_ns2_vc_bind *bind,
LOGP(DLNS, LOGL_ERROR, "Failed to create NSE(%05u)\n", nsei);
return NS2_CS_ERROR;
}
- gprs_ns2_sns_add_bind(nse, bind);
- /* TODO: add (configured) list of other binds */
+ /* add configured list of default binds; if that fails, use only current bind */
+ if (!ns2_sns_add_sns_default_binds(nse))
+ gprs_ns2_sns_add_bind(nse, bind);
} else {
/* nsei already known */
if (nse->ll != bind->ll) {
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index 567e1c57..29717c63 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -388,3 +388,6 @@ void ns2_nse_notify_unblocked(struct gprs_ns2_vc *nsvc, bool unblocked);
enum gprs_ns2_vc_mode ns2_dialect_to_vc_mode(enum gprs_ns2_dialect dialect);
int ns2_count_transfer_cap(struct gprs_ns2_nse *nse,
uint16_t bvci);
+
+/* vty */
+int ns2_sns_add_sns_default_binds(struct gprs_ns2_nse *nse);
diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c
index 55509d28..681d1cbd 100644
--- a/src/gb/gprs_ns2_vty.c
+++ b/src/gb/gprs_ns2_vty.c
@@ -3,6 +3,7 @@
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Alexander Couzens <lynxis@fe80.eu>
+ * (C) 2021 by Harald Welte <laforge@osmocom.org>
*
* All Rights Reserved
*
@@ -59,6 +60,7 @@ static struct gprs_ns2_inst *vty_nsi = NULL;
static struct osmo_fr_network *vty_fr_network = NULL;
static struct llist_head binds;
static struct llist_head nses;
+static struct llist_head ip_sns_default_binds;
struct vty_bind {
struct llist_head list;
@@ -577,6 +579,7 @@ static int config_write_ns_bind(struct vty *vty)
static int config_write_ns(struct vty *vty)
{
+ struct vty_nse_bind *vbind;
unsigned int i;
int ret;
@@ -591,6 +594,10 @@ static int config_write_ns(struct vty *vty)
if (ret)
return ret;
+ llist_for_each_entry(vbind, &ip_sns_default_binds, list) {
+ vty_out(vty, " ip-sns-default bind %s%s", vbind->vbind->name, VTY_NEWLINE);
+ }
+
ret = config_write_ns_nse(vty);
if (ret)
return ret;
@@ -1584,6 +1591,95 @@ DEFUN(cfg_no_ns_nse_ip_sns_remote, cfg_no_ns_nse_ip_sns_remote_cmd,
return CMD_SUCCESS;
}
+/* add all IP-SNS default binds to the given NSE */
+int ns2_sns_add_sns_default_binds(struct gprs_ns2_nse *nse)
+{
+ struct vty_nse_bind *vnse_bind;
+ int count = 0;
+
+ OSMO_ASSERT(nse->ll == GPRS_NS2_LL_UDP);
+ OSMO_ASSERT(nse->dialect == GPRS_NS2_DIALECT_SNS);
+
+ llist_for_each_entry(vnse_bind, &ip_sns_default_binds, list) {
+ struct gprs_ns2_vc_bind *bind = gprs_ns2_bind_by_name(vty_nsi, vnse_bind->vbind->name);
+ /* the bind might not yet created because "listen" is missing. */
+ if (!bind)
+ continue;
+ gprs_ns2_sns_add_bind(nse, bind);
+ count++;
+ }
+ return count;
+}
+
+DEFUN(cfg_ns_ip_sns_default_bind, cfg_ns_ip_sns_default_bind_cmd,
+ "ip-sns-default bind ID",
+ "Defaults for dynamically created NSEs created by IP-SNS in SGSN role\n"
+ "IP SNS binds\n"
+ "Name of NS udp bind whose IP endpoint will be used as IP-SNS local endpoint. Can be given multiple times.\n")
+{
+ struct vty_bind *vbind;
+ struct vty_nse_bind *vnse_bind;
+ const char *name = argv[0];
+
+ vbind = vty_bind_by_name(name);
+ if (!vbind) {
+ vty_out(vty, "Can not find the given bind '%s'%s", name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (vbind->ll != GPRS_NS2_LL_UDP) {
+ vty_out(vty, "ip-sns-default bind can only be used with UDP bind%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ llist_for_each_entry(vnse_bind, &ip_sns_default_binds, list) {
+ if (vnse_bind->vbind == vbind)
+ return CMD_SUCCESS;
+ }
+
+ vnse_bind = talloc(vty_nsi, struct vty_nse_bind);
+ if (!vnse_bind)
+ return CMD_WARNING;
+ vnse_bind->vbind = vbind;
+
+ llist_add_tail(&vnse_bind->list, &ip_sns_default_binds);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_ns_ip_sns_default_bind, cfg_no_ns_ip_sns_default_bind_cmd,
+ "no ip-sns-default bind ID",
+ NO_STR "Defaults for dynamically created NSEs created by IP-SNS in SGSN role\n"
+ "IP SNS binds\n"
+ "Name of NS udp bind whose IP endpoint will be removed as IP-SNS local endpoint.\n")
+{
+ struct vty_bind *vbind;
+ struct vty_nse_bind *vnse_bind;
+ const char *name = argv[0];
+
+ vbind = vty_bind_by_name(name);
+ if (!vbind) {
+ vty_out(vty, "Can not find the given bind '%s'%s", name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (vbind->ll != GPRS_NS2_LL_UDP) {
+ vty_out(vty, "ip-sns-default bind can only be used with UDP bind%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ llist_for_each_entry(vnse_bind, &ip_sns_default_binds, list) {
+ if (vnse_bind->vbind == vbind) {
+ llist_del(&vnse_bind->list);
+ talloc_free(vnse_bind);
+ return CMD_SUCCESS;
+ }
+ }
+
+ vty_out(vty, "Bind '%s' was not an ip-sns-default bind%s", name, VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
DEFUN(cfg_ns_nse_ip_sns_bind, cfg_ns_nse_ip_sns_bind_cmd,
"ip-sns-bind BINDID",
"IP SNS binds\n"
@@ -2060,6 +2156,7 @@ int gprs_ns2_vty_init_reduced(struct gprs_ns2_inst *nsi)
vty_nsi = nsi;
INIT_LLIST_HEAD(&binds);
INIT_LLIST_HEAD(&nses);
+ INIT_LLIST_HEAD(&ip_sns_default_binds);
vty_fr_network = osmo_fr_network_alloc(nsi);
if (!vty_fr_network)
@@ -2099,6 +2196,9 @@ int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi)
install_lib_element(L_NS_NODE, &cfg_ns_bind_cmd);
install_lib_element(L_NS_NODE, &cfg_no_ns_bind_cmd);
+ install_lib_element(L_NS_NODE, &cfg_ns_ip_sns_default_bind_cmd);
+ install_lib_element(L_NS_NODE, &cfg_no_ns_ip_sns_default_bind_cmd);
+
install_node(&ns_bind_node, NULL);
install_lib_element(L_NS_BIND_NODE, &cfg_ns_bind_listen_cmd);
install_lib_element(L_NS_BIND_NODE, &cfg_no_ns_bind_listen_cmd);