blob: 2fd4783f8a76f03d03021ca70f2d26d2c72f4e2e [file] [log] [blame]
Neels Hofmeyr7685a782017-01-30 23:30:26 +01001/* OsmoHLR VTY implementation */
2
3/* (C) 2016 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
Neels Hofmeyr7685a782017-01-30 23:30:26 +01004 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
Harald Weltefa7ee332018-06-24 13:20:32 +02005 * (C) 2018 Harald Welte <laforge@gnumonks.org>
6 *
7 * All Rights Reserved
Neels Hofmeyr7685a782017-01-30 23:30:26 +01008 *
Harald Welte4956ae12018-06-15 22:04:28 +02009 * (C) 2018 Harald Welte <laforge@gnumonks.org>
10 *
11 * All Rights Reserved
12 *
Neels Hofmeyr7685a782017-01-30 23:30:26 +010013 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Affero General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
22 *
23 * You should have received a copy of the GNU Affero General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 *
26 */
27
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020028#include <osmocom/core/talloc.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010029#include <osmocom/vty/vty.h>
Max20ddfdb2019-02-18 13:12:27 +010030#include <osmocom/vty/stats.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010031#include <osmocom/vty/command.h>
32#include <osmocom/vty/logging.h>
Harald Welte7ee6e552018-02-14 00:52:05 +010033#include <osmocom/vty/misc.h>
Harald Weltefa7ee332018-06-24 13:20:32 +020034#include <osmocom/abis/ipa.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010035
Neels Hofmeyr2f758032019-11-20 00:37:07 +010036#include <osmocom/hlr/db.h>
37#include <osmocom/hlr/hlr.h>
38#include <osmocom/hlr/hlr_vty.h>
39#include <osmocom/hlr/hlr_vty_subscr.h>
40#include <osmocom/hlr/hlr_ussd.h>
41#include <osmocom/hlr/gsup_server.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010042
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020043struct cmd_node hlr_node = {
44 HLR_NODE,
45 "%s(config-hlr)# ",
46 1,
47};
48
49DEFUN(cfg_hlr,
50 cfg_hlr_cmd,
51 "hlr",
52 "Configure the HLR")
53{
54 vty->node = HLR_NODE;
55 return CMD_SUCCESS;
56}
57
58struct cmd_node gsup_node = {
59 GSUP_NODE,
60 "%s(config-hlr-gsup)# ",
61 1,
62};
63
64DEFUN(cfg_gsup,
65 cfg_gsup_cmd,
66 "gsup",
67 "Configure GSUP options")
68{
69 vty->node = GSUP_NODE;
70 return CMD_SUCCESS;
71}
72
73static int config_write_hlr(struct vty *vty)
74{
75 vty_out(vty, "hlr%s", VTY_NEWLINE);
Oliver Smith851814a2019-01-11 15:30:21 +010076 if (g_hlr->store_imei)
77 vty_out(vty, " store-imei%s", VTY_NEWLINE);
Neels Hofmeyr5857c592019-04-02 04:24:49 +020078 if (g_hlr->db_file_path && strcmp(g_hlr->db_file_path, HLR_DEFAULT_DB_FILE_PATH))
79 vty_out(vty, " database %s%s", g_hlr->db_file_path, VTY_NEWLINE);
Oliver Smithc7f17872019-03-04 15:10:44 +010080 if (g_hlr->subscr_create_on_demand) {
81 const char *flags_str = "none";
82 uint8_t flags = g_hlr->subscr_create_on_demand_flags;
83 unsigned int rand_msisdn_len = g_hlr->subscr_create_on_demand_rand_msisdn_len;
84
85 if ((flags & DB_SUBSCR_FLAG_NAM_CS) && (flags & DB_SUBSCR_FLAG_NAM_PS))
86 flags_str = "cs+ps";
87 else if (flags & DB_SUBSCR_FLAG_NAM_CS)
88 flags_str = "cs";
89 else if (flags & DB_SUBSCR_FLAG_NAM_PS)
90 flags_str = "ps";
91
92 if (rand_msisdn_len)
93 vty_out(vty, " subscriber-create-on-demand %i %s%s", rand_msisdn_len, flags_str, VTY_NEWLINE);
94 else
95 vty_out(vty, " subscriber-create-on-demand no-msisdn %s%s", flags_str, VTY_NEWLINE);
96 }
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020097 return CMD_SUCCESS;
98}
99
100static int config_write_hlr_gsup(struct vty *vty)
101{
102 vty_out(vty, " gsup%s", VTY_NEWLINE);
103 if (g_hlr->gsup_bind_addr)
104 vty_out(vty, " bind ip %s%s", g_hlr->gsup_bind_addr, VTY_NEWLINE);
Keith649c3352021-02-26 01:05:31 +0100105 if (g_hlr->gsup_unit_name.serno)
106 vty_out(vty, " ipa-name %s%s", g_hlr->gsup_unit_name.serno, VTY_NEWLINE);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200107 return CMD_SUCCESS;
108}
109
Harald Weltefa7ee332018-06-24 13:20:32 +0200110static void show_one_conn(struct vty *vty, const struct osmo_gsup_conn *conn)
111{
112 const struct ipa_server_conn *isc = conn->conn;
113 char *name;
114 int rc;
115
116 rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &name, IPAC_IDTAG_SERNR);
117 OSMO_ASSERT(rc);
118
Neels Hofmeyr3f9d1972019-12-12 04:04:53 +0100119 vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u%s",
120 name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps,
Harald Weltefa7ee332018-06-24 13:20:32 +0200121 VTY_NEWLINE);
122}
123
124DEFUN(show_gsup_conn, show_gsup_conn_cmd,
125 "show gsup-connections",
126 SHOW_STR "GSUP Connections from VLRs, SGSNs, EUSEs\n")
127{
128 struct osmo_gsup_server *gs = g_hlr->gs;
129 struct osmo_gsup_conn *conn;
130
131 llist_for_each_entry(conn, &gs->clients, list)
132 show_one_conn(vty, conn);
133
134 return CMD_SUCCESS;
135}
136
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200137DEFUN(cfg_hlr_gsup_bind_ip,
138 cfg_hlr_gsup_bind_ip_cmd,
139 "bind ip A.B.C.D",
140 "Listen/Bind related socket option\n"
141 IP_STR
142 "IPv4 Address to bind the GSUP interface to\n")
143{
144 if(g_hlr->gsup_bind_addr)
145 talloc_free(g_hlr->gsup_bind_addr);
146 g_hlr->gsup_bind_addr = talloc_strdup(g_hlr, argv[0]);
147
148 return CMD_SUCCESS;
149}
150
Neels Hofmeyr76328bd2019-11-20 03:35:37 +0100151DEFUN(cfg_hlr_gsup_ipa_name,
152 cfg_hlr_gsup_ipa_name_cmd,
153 "ipa-name NAME",
154 "Set the IPA name of this HLR, for proxying to remote HLRs\n"
155 "A globally unique name for this HLR. For example: PLMN + redundancy server number: HLR-901-70-0. "
156 "This name is used for GSUP routing and must be set if multiple HLRs interconnect (e.g. mslookup "
157 "for Distributed GSM).\n")
158{
159 if (vty->type != VTY_FILE) {
160 vty_out(vty, "gsup/ipa-name: The GSUP IPA name cannot be changed at run-time; "
161 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
162 return CMD_WARNING;
163 }
164
165 g_hlr->gsup_unit_name.serno = talloc_strdup(g_hlr, argv[0]);
166 return CMD_SUCCESS;
167}
168
Harald Welte4956ae12018-06-15 22:04:28 +0200169/***********************************************************************
Harald Weltedab544e2018-07-29 16:14:48 +0200170 * USSD Entity
Harald Welte4956ae12018-06-15 22:04:28 +0200171 ***********************************************************************/
172
Neels Hofmeyr2f758032019-11-20 00:37:07 +0100173#include <osmocom/hlr/hlr_ussd.h>
Harald Welte4956ae12018-06-15 22:04:28 +0200174
Harald Weltedab544e2018-07-29 16:14:48 +0200175#define USSD_STR "USSD Configuration\n"
176#define UROUTE_STR "Routing Configuration\n"
177#define PREFIX_STR "Prefix-Matching Route\n" "USSD Prefix\n"
Harald Welte4956ae12018-06-15 22:04:28 +0200178
Vadim Yanitskiydac855e2020-11-17 04:17:46 +0700179#define INT_CHOICE "(own-msisdn|own-imsi|test-idle)"
Harald Weltedab544e2018-07-29 16:14:48 +0200180#define INT_STR "Internal USSD Handler\n" \
181 "Respond with subscribers' own MSISDN\n" \
Vadim Yanitskiydac855e2020-11-17 04:17:46 +0700182 "Respond with subscribers' own IMSI\n" \
183 "Keep the session idle (useful for testing)\n"
Harald Weltedab544e2018-07-29 16:14:48 +0200184
185#define EXT_STR "External USSD Handler\n" \
186 "Name of External USSD Handler (IPA CCM ID)\n"
187
188DEFUN(cfg_ussd_route_pfx_int, cfg_ussd_route_pfx_int_cmd,
189 "ussd route prefix PREFIX internal " INT_CHOICE,
190 USSD_STR UROUTE_STR PREFIX_STR INT_STR)
191{
192 const struct hlr_iuse *iuse = iuse_find(argv[1]);
193 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
Harald Welte4956ae12018-06-15 22:04:28 +0200194 if (rt) {
195 vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);
196 return CMD_WARNING;
197 }
Harald Weltedab544e2018-07-29 16:14:48 +0200198 ussd_route_prefix_alloc_int(g_hlr, argv[0], iuse);
Harald Welte4956ae12018-06-15 22:04:28 +0200199
200 return CMD_SUCCESS;
201}
202
Harald Weltedab544e2018-07-29 16:14:48 +0200203DEFUN(cfg_ussd_route_pfx_ext, cfg_ussd_route_pfx_ext_cmd,
204 "ussd route prefix PREFIX external EUSE",
205 USSD_STR UROUTE_STR PREFIX_STR EXT_STR)
Harald Welte4956ae12018-06-15 22:04:28 +0200206{
Harald Weltedab544e2018-07-29 16:14:48 +0200207 struct hlr_euse *euse = euse_find(g_hlr, argv[1]);
208 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
209 if (rt) {
210 vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);
211 return CMD_WARNING;
212 }
213 if (!euse) {
214 vty_out(vty, "%% Cannot find euse '%s'%s", argv[1], VTY_NEWLINE);
215 return CMD_WARNING;
216 }
217 ussd_route_prefix_alloc_ext(g_hlr, argv[0], euse);
218
219 return CMD_SUCCESS;
220}
221
222DEFUN(cfg_ussd_no_route_pfx, cfg_ussd_no_route_pfx_cmd,
223 "no ussd route prefix PREFIX",
224 NO_STR USSD_STR UROUTE_STR PREFIX_STR)
225{
226 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
Harald Welte4956ae12018-06-15 22:04:28 +0200227 if (!rt) {
228 vty_out(vty, "%% Cannot find route for prefix %s%s", argv[0], VTY_NEWLINE);
229 return CMD_WARNING;
230 }
Harald Weltedab544e2018-07-29 16:14:48 +0200231 ussd_route_del(rt);
Harald Welte4956ae12018-06-15 22:04:28 +0200232
233 return CMD_SUCCESS;
234}
235
Harald Weltedab544e2018-07-29 16:14:48 +0200236DEFUN(cfg_ussd_defaultroute, cfg_ussd_defaultroute_cmd,
237 "ussd default-route external EUSE",
238 USSD_STR "Configure default-route for all USSD to unknown destinations\n"
239 EXT_STR)
Harald Welte4956ae12018-06-15 22:04:28 +0200240{
Vadim Yanitskiyb93c44f2018-08-02 23:37:51 +0700241 struct hlr_euse *euse;
242
243 euse = euse_find(g_hlr, argv[0]);
244 if (!euse) {
245 vty_out(vty, "%% Cannot find EUSE %s%s", argv[0], VTY_NEWLINE);
246 return CMD_WARNING;
247 }
Harald Welte4956ae12018-06-15 22:04:28 +0200248
249 if (g_hlr->euse_default != euse) {
250 vty_out(vty, "Switching default route from %s to %s%s",
Harald Welte55d32a12018-07-30 17:26:35 +0200251 g_hlr->euse_default ? g_hlr->euse_default->name : "<none>",
252 euse->name, VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200253 g_hlr->euse_default = euse;
254 }
255
256 return CMD_SUCCESS;
257}
258
Harald Weltedab544e2018-07-29 16:14:48 +0200259DEFUN(cfg_ussd_no_defaultroute, cfg_ussd_no_defaultroute_cmd,
260 "no ussd default-route",
261 NO_STR USSD_STR "Remove the default-route for all USSD to unknown destinations\n")
Harald Welte4956ae12018-06-15 22:04:28 +0200262{
Harald Welte4956ae12018-06-15 22:04:28 +0200263 g_hlr->euse_default = NULL;
264
265 return CMD_SUCCESS;
266}
267
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200268DEFUN(cfg_database, cfg_database_cmd,
269 "database PATH",
270 "Set the path to the HLR database file\n"
271 "Relative or absolute file system path to the database file (default is '" HLR_DEFAULT_DB_FILE_PATH "')\n")
272{
273 osmo_talloc_replace_string(g_hlr, &g_hlr->db_file_path, argv[0]);
274 return CMD_SUCCESS;
275}
276
Harald Welte4956ae12018-06-15 22:04:28 +0200277struct cmd_node euse_node = {
278 EUSE_NODE,
279 "%s(config-hlr-euse)# ",
280 1,
281};
282
283DEFUN(cfg_euse, cfg_euse_cmd,
284 "euse NAME",
285 "Configure a particular External USSD Entity\n"
286 "Alphanumeric name of the External USSD Entity\n")
287{
288 struct hlr_euse *euse;
289 const char *id = argv[0];
290
291 euse = euse_find(g_hlr, id);
292 if (!euse) {
293 euse = euse_alloc(g_hlr, id);
294 if (!euse)
295 return CMD_WARNING;
296 }
297 vty->index = euse;
298 vty->index_sub = &euse->description;
299 vty->node = EUSE_NODE;
300
301 return CMD_SUCCESS;
302}
303
304DEFUN(cfg_no_euse, cfg_no_euse_cmd,
305 "no euse NAME",
306 NO_STR "Remove a particular External USSD Entity\n"
307 "Alphanumeric name of the External USSD Entity\n")
308{
309 struct hlr_euse *euse = euse_find(g_hlr, argv[0]);
310 if (!euse) {
Vadim Yanitskiyc47d5c02020-10-29 18:05:22 +0700311 vty_out(vty, "%% Cannot remove non-existent EUSE %s%s", argv[0], VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200312 return CMD_WARNING;
313 }
314 if (g_hlr->euse_default == euse) {
315 vty_out(vty, "%% Cannot remove EUSE %s, it is the default route%s", argv[0], VTY_NEWLINE);
316 return CMD_WARNING;
317 }
318 euse_del(euse);
319 return CMD_SUCCESS;
320}
321
322static void dump_one_euse(struct vty *vty, struct hlr_euse *euse)
323{
Harald Welte4956ae12018-06-15 22:04:28 +0200324 vty_out(vty, " euse %s%s", euse->name, VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200325}
326
327static int config_write_euse(struct vty *vty)
328{
329 struct hlr_euse *euse;
Harald Weltedab544e2018-07-29 16:14:48 +0200330 struct hlr_ussd_route *rt;
Harald Welte4956ae12018-06-15 22:04:28 +0200331
332 llist_for_each_entry(euse, &g_hlr->euse_list, list)
333 dump_one_euse(vty, euse);
334
Harald Weltedab544e2018-07-29 16:14:48 +0200335 llist_for_each_entry(rt, &g_hlr->ussd_routes, list) {
336 vty_out(vty, " ussd route prefix %s %s %s%s", rt->prefix,
337 rt->is_external ? "external" : "internal",
338 rt->is_external ? rt->u.euse->name : rt->u.iuse->name,
339 VTY_NEWLINE);
340 }
341
342 if (g_hlr->euse_default)
343 vty_out(vty, " ussd default-route external %s%s", g_hlr->euse_default->name, VTY_NEWLINE);
344
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700345 if (g_hlr->ncss_guard_timeout != NCSS_GUARD_TIMEOUT_DEFAULT)
346 vty_out(vty, " ncss-guard-timeout %i%s",
347 g_hlr->ncss_guard_timeout, VTY_NEWLINE);
348
Harald Welte4956ae12018-06-15 22:04:28 +0200349 return 0;
350}
351
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700352DEFUN(cfg_ncss_guard_timeout, cfg_ncss_guard_timeout_cmd,
353 "ncss-guard-timeout <0-255>",
354 "Set guard timer for NCSS (call independent SS) session activity\n"
355 "Guard timer value (sec.), or 0 to disable")
356{
357 g_hlr->ncss_guard_timeout = atoi(argv[0]);
358 return CMD_SUCCESS;
359}
360
Oliver Smith851814a2019-01-11 15:30:21 +0100361DEFUN(cfg_store_imei, cfg_store_imei_cmd,
362 "store-imei",
363 "Save the IMEI in the database when receiving Check IMEI requests. Note that an MSC does not necessarily send"
364 " Check IMEI requests (for OsmoMSC, you may want to set 'check-imei-rqd 1').")
365{
366 g_hlr->store_imei = true;
367 return CMD_SUCCESS;
368}
369
370DEFUN(cfg_no_store_imei, cfg_no_store_imei_cmd,
371 "no store-imei",
372 "Do not save the IMEI in the database, when receiving Check IMEI requests.")
373{
374 g_hlr->store_imei = false;
375 return CMD_SUCCESS;
376}
377
Oliver Smithc7f17872019-03-04 15:10:44 +0100378DEFUN(cfg_subscr_create_on_demand, cfg_subscr_create_on_demand_cmd,
379 "subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|cs+ps)",
380 "Make a new record when a subscriber is first seen.\n"
381 "Do not automatically assign MSISDN.\n"
382 "Length of an automatically assigned MSISDN.\n"
383 "Do not allow any NAM (Network Access Mode) by default.\n"
384 "Allow access to circuit switched NAM by default.\n"
385 "Allow access to packet switched NAM by default.\n"
386 "Allow access to circuit and packet switched NAM by default.\n")
387{
388 unsigned int rand_msisdn_len = 0;
389 uint8_t flags = 0x00;
390
391 if (strcmp(argv[0], "no-msisdn") != 0)
392 rand_msisdn_len = atoi(argv[0]);
393
394 if (strstr(argv[1], "cs"))
395 flags |= DB_SUBSCR_FLAG_NAM_CS;
396 if (strstr(argv[1], "ps"))
397 flags |= DB_SUBSCR_FLAG_NAM_PS;
398
399 g_hlr->subscr_create_on_demand = true;
400 g_hlr->subscr_create_on_demand_rand_msisdn_len = rand_msisdn_len;
401 g_hlr->subscr_create_on_demand_flags = flags;
402
403 return CMD_SUCCESS;
404}
405
406DEFUN(cfg_no_subscr_create_on_demand, cfg_no_subscr_create_on_demand_cmd,
407 "no subscriber-create-on-demand",
408 "Do not make a new record when a subscriber is first seen.\n")
409{
410 g_hlr->subscr_create_on_demand = false;
411 return CMD_SUCCESS;
412}
413
Harald Welte4956ae12018-06-15 22:04:28 +0200414/***********************************************************************
415 * Common Code
416 ***********************************************************************/
417
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200418int hlr_vty_go_parent(struct vty *vty)
419{
420 switch (vty->node) {
421 case GSUP_NODE:
Harald Welte4956ae12018-06-15 22:04:28 +0200422 case EUSE_NODE:
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200423 vty->node = HLR_NODE;
424 vty->index = NULL;
Harald Welte4956ae12018-06-15 22:04:28 +0200425 vty->index_sub = NULL;
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200426 break;
427 default:
428 case HLR_NODE:
429 vty->node = CONFIG_NODE;
430 vty->index = NULL;
431 break;
432 case CONFIG_NODE:
433 vty->node = ENABLE_NODE;
434 vty->index = NULL;
435 break;
436 }
437
438 return vty->node;
439}
440
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100441int hlr_vty_is_config_node(struct vty *vty, int node)
442{
443 switch (node) {
444 /* add items that are not config */
445 case CONFIG_NODE:
446 return 0;
447
448 default:
449 return 1;
450 }
451}
452
Pau Espin Pedrole49391b2019-08-05 15:57:10 +0200453void hlr_vty_init(void)
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100454{
Pau Espin Pedrole49391b2019-08-05 15:57:10 +0200455 logging_vty_add_cmds();
Harald Welte7ee6e552018-02-14 00:52:05 +0100456 osmo_talloc_vty_add_cmds();
Max20ddfdb2019-02-18 13:12:27 +0100457 osmo_stats_vty_add_cmds();
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200458
Harald Weltefa7ee332018-06-24 13:20:32 +0200459 install_element_ve(&show_gsup_conn_cmd);
460
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200461 install_element(CONFIG_NODE, &cfg_hlr_cmd);
462 install_node(&hlr_node, config_write_hlr);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200463
464 install_element(HLR_NODE, &cfg_gsup_cmd);
465 install_node(&gsup_node, config_write_hlr_gsup);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200466
467 install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd);
Neels Hofmeyr76328bd2019-11-20 03:35:37 +0100468 install_element(GSUP_NODE, &cfg_hlr_gsup_ipa_name_cmd);
Neels Hofmeyr183e7002017-10-06 02:59:54 +0200469
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200470 install_element(HLR_NODE, &cfg_database_cmd);
471
Harald Welte4956ae12018-06-15 22:04:28 +0200472 install_element(HLR_NODE, &cfg_euse_cmd);
473 install_element(HLR_NODE, &cfg_no_euse_cmd);
474 install_node(&euse_node, config_write_euse);
Harald Weltedab544e2018-07-29 16:14:48 +0200475 install_element(HLR_NODE, &cfg_ussd_route_pfx_int_cmd);
476 install_element(HLR_NODE, &cfg_ussd_route_pfx_ext_cmd);
477 install_element(HLR_NODE, &cfg_ussd_no_route_pfx_cmd);
478 install_element(HLR_NODE, &cfg_ussd_defaultroute_cmd);
479 install_element(HLR_NODE, &cfg_ussd_no_defaultroute_cmd);
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700480 install_element(HLR_NODE, &cfg_ncss_guard_timeout_cmd);
Oliver Smith851814a2019-01-11 15:30:21 +0100481 install_element(HLR_NODE, &cfg_store_imei_cmd);
482 install_element(HLR_NODE, &cfg_no_store_imei_cmd);
Oliver Smithc7f17872019-03-04 15:10:44 +0100483 install_element(HLR_NODE, &cfg_subscr_create_on_demand_cmd);
484 install_element(HLR_NODE, &cfg_no_subscr_create_on_demand_cmd);
Harald Welte4956ae12018-06-15 22:04:28 +0200485
Harald Welted5807b82018-07-29 12:27:41 +0200486 hlr_vty_subscriber_init();
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100487}