<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/10244">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Harald Welte: Looks good to me, approved
Jenkins Builder: Verified
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">USSD: Add Core USSD handling + VTY routing config to HLR<br><br>Change-Id: I3cfd7cd401ea32b7e92f1124d129099d9f7dc6e6<br>---<br>M src/Makefile.am<br>M src/hlr.c<br>M src/hlr.h<br>A src/hlr_ussd.c<br>A src/hlr_ussd.h<br>M src/hlr_vty.c<br>M src/hlr_vty.h<br>M tests/test_nodes.vty<br>8 files changed, 288 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index e4506bb..c531ed3 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -32,6 +32,7 @@</span><br><span> ctrl.h \</span><br><span> hlr_vty.h \</span><br><span> hlr_vty_subscr.h \</span><br><span style="color: hsl(120, 100%, 40%);">+ hlr_ussd.h \</span><br><span> db_bootstrap.h \</span><br><span> $(NULL)</span><br><span> </span><br><span>@@ -55,6 +56,7 @@</span><br><span> hlr_vty.c \</span><br><span> hlr_vty_subscr.c \</span><br><span> gsup_send.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ hlr_ussd.c \</span><br><span> $(NULL)</span><br><span> </span><br><span> osmo_hlr_LDADD = \</span><br><span>diff --git a/src/hlr.c b/src/hlr.c</span><br><span>index c38f13f..4fece7a 100644</span><br><span>--- a/src/hlr.c</span><br><span>+++ b/src/hlr.c</span><br><span>@@ -559,6 +559,7 @@</span><br><span> vty_info.tall_ctx = hlr_ctx;</span><br><span> </span><br><span> g_hlr = talloc_zero(hlr_ctx, struct hlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&g_hlr->euse_list);</span><br><span> </span><br><span> rc = osmo_init_logging2(hlr_ctx, &hlr_log_info);</span><br><span> if (rc < 0) {</span><br><span>diff --git a/src/hlr.h b/src/hlr.h</span><br><span>index 8f73806..938f7f9 100644</span><br><span>--- a/src/hlr.h</span><br><span>+++ b/src/hlr.h</span><br><span>@@ -23,6 +23,9 @@</span><br><span> #pragma once</span><br><span> </span><br><span> #include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse;</span><br><span> </span><br><span> struct hlr {</span><br><span> /* GSUP server pointer */</span><br><span>@@ -37,6 +40,9 @@</span><br><span> </span><br><span> /* Local bind addr */</span><br><span> char *gsup_bind_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head euse_list;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse_default;</span><br><span> };</span><br><span> </span><br><span> extern struct hlr *g_hlr;</span><br><span>diff --git a/src/hlr_ussd.c b/src/hlr_ussd.c</span><br><span>new file mode 100644</span><br><span>index 0000000..785eafd</span><br><span>--- /dev/null</span><br><span>+++ b/src/hlr_ussd.c</span><br><span>@@ -0,0 +1,93 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* OsmoHLR VTY implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2018 Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "hlr.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "hlr_ussd.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse *euse_find(struct hlr *hlr, const char *name)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(euse, &hlr->euse_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(euse->name, name))</span><br><span style="color: hsl(120, 100%, 40%);">+ return euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse *euse_alloc(struct hlr *hlr, const char *name)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse = euse_find(hlr, name);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (euse)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ euse = talloc_zero(hlr, struct hlr_euse);</span><br><span style="color: hsl(120, 100%, 40%);">+ euse->name = talloc_strdup(euse, name);</span><br><span style="color: hsl(120, 100%, 40%);">+ euse->hlr = hlr;</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&euse->routes);</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add_tail(&euse->list, &hlr->euse_list);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return euse;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void euse_del(struct hlr_euse *euse)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_del(&euse->list);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(euse);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse_route *euse_route_find(struct hlr_euse *euse, const char *prefix)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse_route *rt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(rt, &euse->routes, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(rt->prefix, prefix))</span><br><span style="color: hsl(120, 100%, 40%);">+ return rt;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse_route *euse_route_prefix_alloc(struct hlr_euse *euse, const char *prefix)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse_route *rt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (euse_route_find(euse, prefix))</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rt = talloc_zero(euse, struct hlr_euse_route);</span><br><span style="color: hsl(120, 100%, 40%);">+ rt->prefix = talloc_strdup(rt, prefix);</span><br><span style="color: hsl(120, 100%, 40%);">+ rt->euse = euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add_tail(&rt->list, &euse->routes);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return rt;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void euse_route_del(struct hlr_euse_route *rt)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_del(&rt->list);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(rt);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/hlr_ussd.h b/src/hlr_ussd.h</span><br><span>new file mode 100644</span><br><span>index 0000000..05d2099</span><br><span>--- /dev/null</span><br><span>+++ b/src/hlr_ussd.h</span><br><span>@@ -0,0 +1,30 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse_route {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* hlr_euse.routes */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *prefix;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* list in the per-hlr list of EUSEs */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr *hlr;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* name (must match the IPA ID tag) */</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *name;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* human-readable description */</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *description;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* list of hlr_euse_route */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head routes;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse *euse_find(struct hlr *hlr, const char *name);</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse *euse_alloc(struct hlr *hlr, const char *name);</span><br><span style="color: hsl(120, 100%, 40%);">+void euse_del(struct hlr_euse *euse);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse_route *euse_route_find(struct hlr_euse *euse, const char *prefix);</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse_route *euse_route_prefix_alloc(struct hlr_euse *euse, const char *prefix);</span><br><span style="color: hsl(120, 100%, 40%);">+void euse_route_del(struct hlr_euse_route *rt);</span><br><span>diff --git a/src/hlr_vty.c b/src/hlr_vty.c</span><br><span>index ae27975..e1349e7 100644</span><br><span>--- a/src/hlr_vty.c</span><br><span>+++ b/src/hlr_vty.c</span><br><span>@@ -6,6 +6,10 @@</span><br><span> *</span><br><span> * All Rights Reserved</span><br><span> *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span> * This program is free software; you can redistribute it and/or modify</span><br><span> * it under the terms of the GNU Affero General Public License as published by</span><br><span> * the Free Software Foundation; either version 3 of the License, or</span><br><span>@@ -117,12 +121,153 @@</span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * External USSD Entity</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "hlr_ussd.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_euse_route_pfx, cfg_euse_route_pfx_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "route prefix PREFIX",</span><br><span style="color: hsl(120, 100%, 40%);">+ "")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse_route *rt = euse_route_find(euse, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rt) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ euse_route_prefix_alloc(euse, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_euse_no_route_pfx, cfg_euse_no_route_pfx_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "no route prefix PREFIX",</span><br><span style="color: hsl(120, 100%, 40%);">+ NO_STR "")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse_route *rt = euse_route_find(euse, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!rt) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "%% Cannot find route for prefix %s%s", argv[0], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ euse_route_del(rt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_euse_defaultroute, cfg_euse_defaultroute_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "default-route",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Set this EUSE as default-route for all USSD to unknown destinations\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (g_hlr->euse_default != euse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "Switching default route from %s to %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hlr->euse_default->name, euse->name, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hlr->euse_default = euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_euse_no_defaultroute, cfg_euse_no_defaultroute_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "no default-route",</span><br><span style="color: hsl(120, 100%, 40%);">+ NO_STR "Remove this EUSE as default-route for all USSD to unknown destinations\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (g_hlr->euse_default != euse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "%% Current EUSE is no default route, cannot delete it%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hlr->euse_default = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct cmd_node euse_node = {</span><br><span style="color: hsl(120, 100%, 40%);">+ EUSE_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+ "%s(config-hlr-euse)# ",</span><br><span style="color: hsl(120, 100%, 40%);">+ 1,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_euse, cfg_euse_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "euse NAME",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Configure a particular External USSD Entity\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Alphanumeric name of the External USSD Entity\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *id = argv[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ euse = euse_find(g_hlr, id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!euse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ euse = euse_alloc(g_hlr, id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!euse)</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ vty->index = euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ vty->index_sub = &euse->description;</span><br><span style="color: hsl(120, 100%, 40%);">+ vty->node = EUSE_NODE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_no_euse, cfg_no_euse_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "no euse NAME",</span><br><span style="color: hsl(120, 100%, 40%);">+ NO_STR "Remove a particular External USSD Entity\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Alphanumeric name of the External USSD Entity\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse = euse_find(g_hlr, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!euse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "%% Cannot remove non-existant EUSE %s%s", argv[0], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (g_hlr->euse_default == euse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, "%% Cannot remove EUSE %s, it is the default route%s", argv[0], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ euse_del(euse);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void dump_one_euse(struct vty *vty, struct hlr_euse *euse)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse_route *er;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " euse %s%s", euse->name, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(er, &euse->routes, list)</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " route prefix %s%s", er->prefix, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (g_hlr->euse_default == euse)</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " default-route%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int config_write_euse(struct vty *vty)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(euse, &g_hlr->euse_list, list)</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_one_euse(vty, euse);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * Common Code</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int hlr_vty_go_parent(struct vty *vty)</span><br><span> {</span><br><span> switch (vty->node) {</span><br><span> case GSUP_NODE:</span><br><span style="color: hsl(120, 100%, 40%);">+ case EUSE_NODE:</span><br><span> vty->node = HLR_NODE;</span><br><span> vty->index = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ vty->index_sub = NULL;</span><br><span> break;</span><br><span> default:</span><br><span> case HLR_NODE:</span><br><span>@@ -165,5 +310,13 @@</span><br><span> </span><br><span> install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(HLR_NODE, &cfg_euse_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(HLR_NODE, &cfg_no_euse_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_node(&euse_node, config_write_euse);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(EUSE_NODE, &cfg_euse_route_pfx_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(EUSE_NODE, &cfg_euse_no_route_pfx_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(EUSE_NODE, &cfg_euse_defaultroute_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(EUSE_NODE, &cfg_euse_no_defaultroute_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> hlr_vty_subscriber_init();</span><br><span> }</span><br><span>diff --git a/src/hlr_vty.h b/src/hlr_vty.h</span><br><span>index bc9c2e5..1f3b87f 100644</span><br><span>--- a/src/hlr_vty.h</span><br><span>+++ b/src/hlr_vty.h</span><br><span>@@ -30,6 +30,7 @@</span><br><span> enum hlr_vty_node {</span><br><span> HLR_NODE = _LAST_OSMOVTY_NODE + 1,</span><br><span> GSUP_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+ EUSE_NODE,</span><br><span> };</span><br><span> </span><br><span> int hlr_vty_is_config_node(struct vty *vty, int node);</span><br><span>diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty</span><br><span>index 21809c8..d499962 100644</span><br><span>--- a/tests/test_nodes.vty</span><br><span>+++ b/tests/test_nodes.vty</span><br><span>@@ -70,6 +70,8 @@</span><br><span> exit</span><br><span> end</span><br><span> gsup</span><br><span style="color: hsl(120, 100%, 40%);">+ euse NAME</span><br><span style="color: hsl(120, 100%, 40%);">+ no euse NAME</span><br><span> </span><br><span> OsmoHLR(config-hlr)# gsup</span><br><span> OsmoHLR(config-hlr-gsup)# list</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10244">change 10244</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10244"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-hlr </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I3cfd7cd401ea32b7e92f1124d129099d9f7dc6e6 </div>
<div style="display:none"> Gerrit-Change-Number: 10244 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>