blob: 86d65a8e343cf872aa616393ac714fe80b0f17ff [file] [log] [blame]
Harald Welte799e0c92010-04-30 21:49:24 +02001/*
2 * (C) 2010 by Harald Welte <laforge@gnumonks.org>
3 * (C) 2010 by On-Waves
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01007 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
Harald Welte799e0c92010-04-30 21:49:24 +02009 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010014 * GNU Affero General Public License for more details.
Harald Welte799e0c92010-04-30 21:49:24 +020015 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010016 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte799e0c92010-04-30 21:49:24 +020018 *
19 */
20
Harald Welte799e0c92010-04-30 21:49:24 +020021#include <sys/socket.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
Jacob Erlbeck73685282014-05-23 20:48:07 +020024#include <string.h>
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +020025#include <time.h>
Harald Welte799e0c92010-04-30 21:49:24 +020026
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010027#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +020028#include <osmocom/core/rate_ctr.h>
Harald Welte799e0c92010-04-30 21:49:24 +020029
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +020030#include <openbsc/gsm_04_08.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080031#include <osmocom/gprs/gprs_ns.h>
Harald Welted0d62492017-08-12 13:43:54 +020032#include <osmocom/gsm/apn.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080033
Harald Welte799e0c92010-04-30 21:49:24 +020034#include <openbsc/debug.h>
Harald Welteb77c6972010-05-01 11:28:43 +020035#include <openbsc/gb_proxy.h>
Holger Hans Peter Freyther7127b022014-08-04 11:52:52 +020036#include <openbsc/gprs_utils.h>
Harald Welte62ab20c2010-05-14 18:59:17 +020037#include <openbsc/vty.h>
Harald Welte799e0c92010-04-30 21:49:24 +020038
Harald Welte4b037e42010-05-19 19:45:32 +020039#include <osmocom/vty/command.h>
40#include <osmocom/vty/vty.h>
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +020041#include <osmocom/vty/misc.h>
Harald Welte799e0c92010-04-30 21:49:24 +020042
Harald Welte799e0c92010-04-30 21:49:24 +020043static struct gbproxy_config *g_cfg = NULL;
44
45/*
46 * vty code for mgcp below
47 */
Harald Welteb77c6972010-05-01 11:28:43 +020048static struct cmd_node gbproxy_node = {
Harald Welte799e0c92010-04-30 21:49:24 +020049 GBPROXY_NODE,
Harald Welte570ce242012-08-17 13:16:10 +020050 "%s(config-gbproxy)# ",
Harald Welte799e0c92010-04-30 21:49:24 +020051 1,
52};
53
Jacob Erlbeck7430da62014-09-12 15:09:56 +020054static const struct value_string keep_modes[] = {
55 {GBPROX_KEEP_NEVER, "never"},
56 {GBPROX_KEEP_REATTACH, "re-attach"},
57 {GBPROX_KEEP_IDENTIFIED, "identified"},
58 {GBPROX_KEEP_ALWAYS, "always"},
59 {0, NULL}
60};
61
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +020062static const struct value_string match_ids[] = {
63 {GBPROX_MATCH_PATCHING, "patching"},
Jacob Erlbeckb36032c2014-09-25 13:21:48 +020064 {GBPROX_MATCH_ROUTING, "routing"},
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +020065 {0, NULL}
66};
67
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020068static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +020069{
70 struct gprs_ra_id raid;
71 gsm48_parse_ra(&raid, peer->ra);
72
73 vty_out(vty, "NSEI %5u, PTP-BVCI %5u, "
74 "RAI %u-%u-%u-%u",
75 peer->nsei, peer->bvci,
76 raid.mcc, raid.mnc, raid.lac, raid.rac);
77 if (peer->blocked)
78 vty_out(vty, " [BVC-BLOCKED]");
79
80 vty_out(vty, "%s", VTY_NEWLINE);
81}
82
Harald Welte799e0c92010-04-30 21:49:24 +020083static int config_write_gbproxy(struct vty *vty)
84{
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +020085 enum gbproxy_match_id match_id;
86
Harald Welte799e0c92010-04-30 21:49:24 +020087 vty_out(vty, "gbproxy%s", VTY_NEWLINE);
88
Harald Welteff3bde82010-05-19 15:09:09 +020089 vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei,
Harald Welte799e0c92010-04-30 21:49:24 +020090 VTY_NEWLINE);
Harald Welte799e0c92010-04-30 21:49:24 +020091
Jacob Erlbeck67a44452014-05-19 10:14:58 +020092 if (g_cfg->core_mcc > 0)
93 vty_out(vty, " core-mobile-country-code %d%s",
94 g_cfg->core_mcc, VTY_NEWLINE);
95 if (g_cfg->core_mnc > 0)
96 vty_out(vty, " core-mobile-network-code %d%s",
97 g_cfg->core_mnc, VTY_NEWLINE);
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +020098
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +020099 for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) {
100 struct gbproxy_match *match = &g_cfg->matches[match_id];
101 if (match->re_str)
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200102 vty_out(vty, " match-imsi %s %s%s",
103 get_value_string(match_ids, match_id),
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200104 match->re_str, VTY_NEWLINE);
105 }
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200106
Jacob Erlbeck73685282014-05-23 20:48:07 +0200107 if (g_cfg->core_apn != NULL) {
108 if (g_cfg->core_apn_size > 0) {
109 char str[500] = {0};
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200110 vty_out(vty, " core-access-point-name %s%s",
Harald Welted0d62492017-08-12 13:43:54 +0200111 osmo_apn_to_str(str, g_cfg->core_apn,
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200112 g_cfg->core_apn_size),
113 VTY_NEWLINE);
Jacob Erlbeck73685282014-05-23 20:48:07 +0200114 } else {
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200115 vty_out(vty, " core-access-point-name none%s",
116 VTY_NEWLINE);
Jacob Erlbeck73685282014-05-23 20:48:07 +0200117 }
118 }
Jacob Erlbeck0d4236b2014-08-18 14:54:37 +0200119
Jacob Erlbeck25f98e62014-08-28 13:47:53 +0200120 if (g_cfg->route_to_sgsn2)
121 vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei,
122 VTY_NEWLINE);
123
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200124 if (g_cfg->tlli_max_age > 0)
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200125 vty_out(vty, " link-list max-age %d%s",
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200126 g_cfg->tlli_max_age, VTY_NEWLINE);
127 if (g_cfg->tlli_max_len > 0)
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200128 vty_out(vty, " link-list max-length %d%s",
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200129 g_cfg->tlli_max_len, VTY_NEWLINE);
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200130 vty_out(vty, " link-list keep-mode %s%s",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200131 get_value_string(keep_modes, g_cfg->keep_link_infos),
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200132 VTY_NEWLINE);
133
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200134
Harald Welte799e0c92010-04-30 21:49:24 +0200135 return CMD_SUCCESS;
136}
137
Harald Welte799e0c92010-04-30 21:49:24 +0200138DEFUN(cfg_gbproxy,
139 cfg_gbproxy_cmd,
140 "gbproxy",
141 "Configure the Gb proxy")
142{
143 vty->node = GBPROXY_NODE;
144 return CMD_SUCCESS;
145}
146
Harald Welte799e0c92010-04-30 21:49:24 +0200147DEFUN(cfg_nsip_sgsn_nsei,
148 cfg_nsip_sgsn_nsei_cmd,
Harald Welteff3bde82010-05-19 15:09:09 +0200149 "sgsn nsei <0-65534>",
Holger Hans Peter Freyther2eb6e2c2011-11-05 15:14:59 +0100150 "SGSN information\n"
151 "NSEI to be used in the connection with the SGSN\n"
152 "The NSEI\n")
Harald Welte799e0c92010-04-30 21:49:24 +0200153{
Jacob Erlbeckcc8856f2014-10-08 13:37:28 +0200154 unsigned int nsei = atoi(argv[0]);
Harald Welte799e0c92010-04-30 21:49:24 +0200155
Jacob Erlbeckcc8856f2014-10-08 13:37:28 +0200156 if (g_cfg->route_to_sgsn2 && g_cfg->nsip_sgsn2_nsei == nsei) {
157 vty_out(vty, "SGSN NSEI %d conflicts with secondary SGSN NSEI%s",
158 nsei, VTY_NEWLINE);
159 return CMD_WARNING;
160 }
161
162 g_cfg->nsip_sgsn_nsei = nsei;
Harald Welte799e0c92010-04-30 21:49:24 +0200163 return CMD_SUCCESS;
164}
165
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200166#define GBPROXY_CORE_MNC_STR "Use this network code for the core network\n"
167
168DEFUN(cfg_gbproxy_core_mnc,
169 cfg_gbproxy_core_mnc_cmd,
170 "core-mobile-network-code <1-999>",
171 GBPROXY_CORE_MNC_STR "NCC value\n")
172{
173 g_cfg->core_mnc = atoi(argv[0]);
174 return CMD_SUCCESS;
175}
176
177DEFUN(cfg_gbproxy_no_core_mnc,
178 cfg_gbproxy_no_core_mnc_cmd,
179 "no core-mobile-network-code",
180 NO_STR GBPROXY_CORE_MNC_STR)
181{
182 g_cfg->core_mnc = 0;
183 return CMD_SUCCESS;
184}
185
186#define GBPROXY_CORE_MCC_STR "Use this country code for the core network\n"
187
188DEFUN(cfg_gbproxy_core_mcc,
189 cfg_gbproxy_core_mcc_cmd,
190 "core-mobile-country-code <1-999>",
191 GBPROXY_CORE_MCC_STR "MCC value\n")
192{
193 g_cfg->core_mcc = atoi(argv[0]);
194 return CMD_SUCCESS;
195}
196
197DEFUN(cfg_gbproxy_no_core_mcc,
198 cfg_gbproxy_no_core_mcc_cmd,
199 "no core-mobile-country-code",
200 NO_STR GBPROXY_CORE_MCC_STR)
201{
202 g_cfg->core_mcc = 0;
203 return CMD_SUCCESS;
204}
205
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200206#define GBPROXY_MATCH_IMSI_STR "Restrict actions to certain IMSIs\n"
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200207
208DEFUN(cfg_gbproxy_match_imsi,
209 cfg_gbproxy_match_imsi_cmd,
Jacob Erlbeckb36032c2014-09-25 13:21:48 +0200210 "match-imsi (patching|routing) .REGEXP",
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200211 GBPROXY_MATCH_IMSI_STR
Jacob Erlbeckb36032c2014-09-25 13:21:48 +0200212 "Patch MS related information elements on match only\n"
213 "Route to the secondary SGSN on match only\n"
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200214 "Regular expression for the IMSI match\n")
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200215{
Jacob Erlbeckb36032c2014-09-25 13:21:48 +0200216 const char *filter = argv[1];
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200217 const char *err_msg = NULL;
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200218 struct gbproxy_match *match;
Jacob Erlbeckb36032c2014-09-25 13:21:48 +0200219 enum gbproxy_match_id match_id = get_string_value(match_ids, argv[0]);
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200220
221 OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING &&
222 match_id < GBPROX_MATCH_LAST);
223 match = &g_cfg->matches[match_id];
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200224
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200225 if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200226 vty_out(vty, "Match expression invalid: %s%s",
227 err_msg, VTY_NEWLINE);
228 return CMD_WARNING;
229 }
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200230
231 g_cfg->acquire_imsi = 1;
232
233 return CMD_SUCCESS;
234}
235
236DEFUN(cfg_gbproxy_no_match_imsi,
237 cfg_gbproxy_no_match_imsi_cmd,
238 "no match-imsi",
239 NO_STR GBPROXY_MATCH_IMSI_STR)
240{
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200241 enum gbproxy_match_id match_id;
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200242
Jacob Erlbeck6c3fdc12014-09-25 13:39:06 +0200243 for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id)
244 gbproxy_clear_patch_filter(&g_cfg->matches[match_id]);
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200245
246 g_cfg->acquire_imsi = 0;
247
248 return CMD_SUCCESS;
249}
250
Jacob Erlbeck73685282014-05-23 20:48:07 +0200251#define GBPROXY_CORE_APN_STR "Use this access point name (APN) for the backbone\n"
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200252#define GBPROXY_CORE_APN_ARG_STR "Replace APN by this string\n" "Remove APN\n"
Jacob Erlbeck73685282014-05-23 20:48:07 +0200253
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200254static int set_core_apn(struct vty *vty, const char *apn)
Jacob Erlbeck73685282014-05-23 20:48:07 +0200255{
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200256 int apn_len;
Jacob Erlbeck73685282014-05-23 20:48:07 +0200257
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200258 if (!apn) {
259 talloc_free(g_cfg->core_apn);
260 g_cfg->core_apn = NULL;
261 g_cfg->core_apn_size = 0;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200262 return CMD_SUCCESS;
263 }
Jacob Erlbeck73685282014-05-23 20:48:07 +0200264
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200265 apn_len = strlen(apn);
266
267 if (apn_len >= 100) {
Jacob Erlbeck73685282014-05-23 20:48:07 +0200268 vty_out(vty, "APN string too long (max 99 chars)%s",
269 VTY_NEWLINE);
270 return CMD_WARNING;
271 }
272
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200273 if (apn_len == 0) {
274 talloc_free(g_cfg->core_apn);
275 /* TODO: replace NULL */
276 g_cfg->core_apn = talloc_zero_size(NULL, 2);
277 g_cfg->core_apn_size = 0;
278 } else {
279 /* TODO: replace NULL */
280 g_cfg->core_apn =
281 talloc_realloc_size(NULL, g_cfg->core_apn, apn_len + 1);
282 g_cfg->core_apn_size =
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +0200283 gprs_str_to_apn(g_cfg->core_apn, apn_len + 1, apn);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200284 }
Jacob Erlbeck73685282014-05-23 20:48:07 +0200285
286 return CMD_SUCCESS;
287}
288
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200289DEFUN(cfg_gbproxy_core_apn,
290 cfg_gbproxy_core_apn_cmd,
291 "core-access-point-name (APN|none)",
292 GBPROXY_CORE_APN_STR GBPROXY_CORE_APN_ARG_STR)
293{
294 if (strcmp(argv[0], "none") == 0)
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200295 return set_core_apn(vty, "");
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200296 else
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200297 return set_core_apn(vty, argv[0]);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200298}
299
Jacob Erlbeck73685282014-05-23 20:48:07 +0200300DEFUN(cfg_gbproxy_no_core_apn,
301 cfg_gbproxy_no_core_apn_cmd,
302 "no core-access-point-name",
303 NO_STR GBPROXY_CORE_APN_STR)
304{
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200305 return set_core_apn(vty, NULL);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200306}
307
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200308/* TODO: Remove the patch-ptmsi command, since P-TMSI patching is enabled
309 * automatically when needed. This command is only left for manual testing
310 * (e.g. doing P-TMSI patching without using a secondary SGSN)
311 */
Jacob Erlbeck0d4236b2014-08-18 14:54:37 +0200312#define GBPROXY_PATCH_PTMSI_STR "Patch P-TMSI/TLLI\n"
313
314DEFUN(cfg_gbproxy_patch_ptmsi,
315 cfg_gbproxy_patch_ptmsi_cmd,
316 "patch-ptmsi",
317 GBPROXY_PATCH_PTMSI_STR)
318{
319 g_cfg->patch_ptmsi = 1;
320
321 return CMD_SUCCESS;
322}
323
324DEFUN(cfg_gbproxy_no_patch_ptmsi,
325 cfg_gbproxy_no_patch_ptmsi_cmd,
326 "no patch-ptmsi",
327 NO_STR GBPROXY_PATCH_PTMSI_STR)
328{
329 g_cfg->patch_ptmsi = 0;
330
331 return CMD_SUCCESS;
332}
333
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200334/* TODO: Remove the acquire-imsi command, since that feature is enabled
335 * automatically when IMSI matching is enabled. This command is only left for
336 * manual testing (e.g. doing IMSI acquisition without IMSI based patching)
337 */
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200338#define GBPROXY_ACQUIRE_IMSI_STR "Acquire the IMSI before establishing a LLC connection (Experimental)\n"
339
340DEFUN(cfg_gbproxy_acquire_imsi,
341 cfg_gbproxy_acquire_imsi_cmd,
342 "acquire-imsi",
343 GBPROXY_ACQUIRE_IMSI_STR)
344{
345 g_cfg->acquire_imsi = 1;
346
347 return CMD_SUCCESS;
348}
349
350DEFUN(cfg_gbproxy_no_acquire_imsi,
351 cfg_gbproxy_no_acquire_imsi_cmd,
352 "no acquire-imsi",
353 NO_STR GBPROXY_ACQUIRE_IMSI_STR)
354{
355 g_cfg->acquire_imsi = 0;
356
357 return CMD_SUCCESS;
358}
359
Jacob Erlbeckf4d60c82014-08-26 14:47:15 +0200360#define GBPROXY_SECOND_SGSN_STR "Route matching LLC connections to a second SGSN (Experimental)\n"
361
362DEFUN(cfg_gbproxy_secondary_sgsn,
363 cfg_gbproxy_secondary_sgsn_cmd,
364 "secondary-sgsn nsei <0-65534>",
365 GBPROXY_SECOND_SGSN_STR
366 "NSEI to be used in the connection with the SGSN\n"
367 "The NSEI\n")
368{
Jacob Erlbeckcc8856f2014-10-08 13:37:28 +0200369 unsigned int nsei = atoi(argv[0]);
370
371 if (g_cfg->nsip_sgsn_nsei == nsei) {
372 vty_out(vty, "Secondary SGSN NSEI %d conflicts with primary SGSN NSEI%s",
373 nsei, VTY_NEWLINE);
374 return CMD_WARNING;
375 }
376
Jacob Erlbeckf4d60c82014-08-26 14:47:15 +0200377 g_cfg->route_to_sgsn2 = 1;
Jacob Erlbeckcc8856f2014-10-08 13:37:28 +0200378 g_cfg->nsip_sgsn2_nsei = nsei;
Jacob Erlbeckf4d60c82014-08-26 14:47:15 +0200379
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200380 g_cfg->patch_ptmsi = 1;
381
Jacob Erlbeckf4d60c82014-08-26 14:47:15 +0200382 return CMD_SUCCESS;
383}
384
385DEFUN(cfg_gbproxy_no_secondary_sgsn,
386 cfg_gbproxy_no_secondary_sgsn_cmd,
387 "no secondary-sgsn",
388 NO_STR GBPROXY_SECOND_SGSN_STR)
389{
390 g_cfg->route_to_sgsn2 = 0;
391 g_cfg->nsip_sgsn2_nsei = 0xFFFF;
392
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200393 g_cfg->patch_ptmsi = 0;
394
Jacob Erlbeckf4d60c82014-08-26 14:47:15 +0200395 return CMD_SUCCESS;
396}
397
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200398#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n"
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200399#define GBPROXY_MAX_AGE_STR "Limit maximum age\n"
400
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200401DEFUN(cfg_gbproxy_link_list_max_age,
402 cfg_gbproxy_link_list_max_age_cmd,
403 "link-list max-age <1-999999>",
404 GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200405 "Maximum age in seconds\n")
406{
407 g_cfg->tlli_max_age = atoi(argv[0]);
408
Jacob Erlbeck73685282014-05-23 20:48:07 +0200409 return CMD_SUCCESS;
410}
411
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200412DEFUN(cfg_gbproxy_link_list_no_max_age,
413 cfg_gbproxy_link_list_no_max_age_cmd,
414 "no link-list max-age",
415 NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR)
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200416{
417 g_cfg->tlli_max_age = 0;
418
419 return CMD_SUCCESS;
420}
421
422#define GBPROXY_MAX_LEN_STR "Limit list length\n"
423
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200424DEFUN(cfg_gbproxy_link_list_max_len,
425 cfg_gbproxy_link_list_max_len_cmd,
426 "link-list max-length <1-99999>",
427 GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR
428 "Maximum number of logical links in the list\n")
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200429{
430 g_cfg->tlli_max_len = atoi(argv[0]);
431
432 return CMD_SUCCESS;
433}
434
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200435DEFUN(cfg_gbproxy_link_list_no_max_len,
436 cfg_gbproxy_link_list_no_max_len_cmd,
437 "no link-list max-length",
438 NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR)
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200439{
440 g_cfg->tlli_max_len = 0;
441
442 return CMD_SUCCESS;
443}
444
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200445DEFUN(cfg_gbproxy_link_list_keep_mode,
446 cfg_gbproxy_link_list_keep_mode_cmd,
447 "link-list keep-mode (never|re-attach|identified|always)",
448 GBPROXY_LINK_LIST_STR "How to keep entries for detached logical links\n"
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200449 "Discard entry immediately after detachment\n"
450 "Keep entry if a re-attachment has be requested\n"
451 "Keep entry if it associated with an IMSI\n"
452 "Don't discard entries after detachment\n")
453{
454 int val = get_string_value(keep_modes, argv[0]);
455 OSMO_ASSERT(val >= GBPROX_KEEP_NEVER && val <= GBPROX_KEEP_ALWAYS);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200456 g_cfg->keep_link_infos = val;
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200457
458 return CMD_SUCCESS;
459}
460
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200461
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200462DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
463 SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n")
464{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +0200465 struct gbproxy_peer *peer;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200466 int show_stats = argc >= 1;
Jacob Erlbeck91fb6802014-05-28 10:59:10 +0200467
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200468 if (show_stats)
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200469 vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200470
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200471 llist_for_each_entry(peer, &g_cfg->bts_peers, list) {
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200472 gbprox_vty_print_peer(vty, peer);
473
474 if (show_stats)
475 vty_out_rate_ctr_group(vty, " ", peer->ctrg);
476 }
477 return CMD_SUCCESS;
478}
479
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200480DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
481 SHOW_STR "Display information about the Gb proxy\n" "Show logical links\n")
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200482{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +0200483 struct gbproxy_peer *peer;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200484 char mi_buf[200];
Jacob Erlbeckc6807c42014-09-19 16:34:01 +0200485 time_t now;
486 struct timespec ts = {0,};
487
488 clock_gettime(CLOCK_MONOTONIC, &ts);
489 now = ts.tv_sec;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200490
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200491 llist_for_each_entry(peer, &g_cfg->bts_peers, list) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200492 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +0200493 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200494
495 gbprox_vty_print_peer(vty, peer);
496
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200497 llist_for_each_entry(link_info, &state->logical_links, list) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200498 time_t age = now - link_info->timestamp;
Jacob Erlbeck146e3072014-09-02 14:09:01 +0200499 int stored_msgs = 0;
500 struct llist_head *iter;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200501 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeck146e3072014-09-02 14:09:01 +0200502 stored_msgs++;
503
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200504 if (link_info->imsi > 0) {
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200505 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
506 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200507 link_info->imsi,
508 link_info->imsi_len);
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200509 } else {
510 snprintf(mi_buf, sizeof(mi_buf), "(none)");
511 }
Jacob Erlbeck146e3072014-09-02 14:09:01 +0200512 vty_out(vty, " TLLI %08x, IMSI %s, AGE %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200513 link_info->tlli.current, mi_buf, (int)age);
Jacob Erlbeck146e3072014-09-02 14:09:01 +0200514
515 if (stored_msgs)
516 vty_out(vty, ", STORED %d", stored_msgs);
517
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200518 if (g_cfg->route_to_sgsn2)
519 vty_out(vty, ", SGSN NSEI %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200520 link_info->sgsn_nsei);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200521
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200522 if (link_info->is_deregistered)
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200523 vty_out(vty, ", DE-REGISTERED");
524
Jacob Erlbeck146e3072014-09-02 14:09:01 +0200525 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200526 }
527 }
528 return CMD_SUCCESS;
529}
530
531DEFUN(delete_gb_bvci, delete_gb_bvci_cmd,
532 "delete-gbproxy-peer <0-65534> bvci <2-65534>",
533 "Delete a GBProxy peer by NSEI and optionally BVCI\n"
534 "NSEI number\n"
535 "Only delete peer with a matching BVCI\n"
536 "BVCI number\n")
537{
538 const uint16_t nsei = atoi(argv[0]);
539 const uint16_t bvci = atoi(argv[1]);
540 int counter;
541
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +0200542 counter = gbproxy_cleanup_peers(g_cfg, nsei, bvci);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200543
544 if (counter == 0) {
545 vty_out(vty, "BVC not found%s", VTY_NEWLINE);
546 return CMD_WARNING;
547 }
548
549 return CMD_SUCCESS;
550}
551
552DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
553 "delete-gbproxy-peer <0-65534> (only-bvc|only-nsvc|all) [dry-run]",
554 "Delete a GBProxy peer by NSEI and optionally BVCI\n"
555 "NSEI number\n"
556 "Only delete BSSGP connections (BVC)\n"
557 "Only delete dynamic NS connections (NS-VC)\n"
558 "Delete BVC and dynamic NS connections\n"
559 "Show what would be deleted instead of actually deleting\n"
560 )
561{
562 const uint16_t nsei = atoi(argv[0]);
563 const char *mode = argv[1];
564 int dry_run = argc > 2;
565 int delete_bvc = 0;
566 int delete_nsvc = 0;
567 int counter;
568
569 if (strcmp(mode, "only-bvc") == 0)
570 delete_bvc = 1;
571 else if (strcmp(mode, "only-nsvc") == 0)
572 delete_nsvc = 1;
573 else
574 delete_bvc = delete_nsvc = 1;
575
576 if (delete_bvc) {
577 if (!dry_run)
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +0200578 counter = gbproxy_cleanup_peers(g_cfg, nsei, 0);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200579 else {
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +0200580 struct gbproxy_peer *peer;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200581 counter = 0;
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200582 llist_for_each_entry(peer, &g_cfg->bts_peers, list) {
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200583 if (peer->nsei != nsei)
584 continue;
585
586 vty_out(vty, "BVC: ");
587 gbprox_vty_print_peer(vty, peer);
588 counter += 1;
589 }
590 }
591 vty_out(vty, "%sDeleted %d BVC%s",
592 dry_run ? "Not " : "", counter, VTY_NEWLINE);
593 }
594
595 if (delete_nsvc) {
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200596 struct gprs_ns_inst *nsi = g_cfg->nsi;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200597 struct gprs_nsvc *nsvc, *nsvc2;
598
599 counter = 0;
600 llist_for_each_entry_safe(nsvc, nsvc2, &nsi->gprs_nsvcs, list) {
601 if (nsvc->nsei != nsei)
602 continue;
603 if (nsvc->persistent)
604 continue;
605
606 if (!dry_run)
607 gprs_nsvc_delete(nsvc);
608 else
609 vty_out(vty, "NS-VC: NSEI %5u, NS-VCI %5u, "
610 "remote %s%s",
611 nsvc->nsei, nsvc->nsvci,
612 gprs_ns_ll_str(nsvc), VTY_NEWLINE);
613 counter += 1;
614 }
615 vty_out(vty, "%sDeleted %d NS-VC%s",
616 dry_run ? "Not " : "", counter, VTY_NEWLINE);
617 }
618
619 return CMD_SUCCESS;
620}
621
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200622#define GBPROXY_DELETE_LINK_STR \
623 "Delete a GBProxy logical link entry by NSEI and identification\nNSEI number\n"
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200624
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200625DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd,
626 "delete-gbproxy-link <0-65534> (tlli|imsi|sgsn-nsei) IDENT",
627 GBPROXY_DELETE_LINK_STR
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200628 "Delete entries with a matching TLLI (hex)\n"
629 "Delete entries with a matching IMSI\n"
Jacob Erlbeckde74e722014-10-28 11:29:43 +0100630 "Delete entries with a matching SGSN NSEI\n"
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200631 "Identification to match\n")
632{
633 const uint16_t nsei = atoi(argv[0]);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200634 enum {MATCH_TLLI = 't', MATCH_IMSI = 'i', MATCH_SGSN = 's'} match;
635 uint32_t ident = 0;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200636 const char *imsi = NULL;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +0200637 struct gbproxy_peer *peer = 0;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200638 struct gbproxy_link_info *link_info, *nxt;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +0200639 struct gbproxy_patch_state *state;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200640 char mi_buf[200];
641 int found = 0;
642
643 match = argv[1][0];
644
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200645 switch (match) {
646 case MATCH_TLLI: ident = strtoll(argv[2], NULL, 16); break;
647 case MATCH_IMSI: imsi = argv[2]; break;
648 case MATCH_SGSN: ident = strtoll(argv[2], NULL, 0); break;
649 };
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200650
651 peer = gbproxy_peer_by_nsei(g_cfg, nsei);
652 if (!peer) {
653 vty_out(vty, "Didn't find peer with NSEI %d%s",
654 nsei, VTY_NEWLINE);
655 return CMD_WARNING;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200656 }
657
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200658 state = &peer->patch_state;
659
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200660 llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) {
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200661 switch (match) {
662 case MATCH_TLLI:
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200663 if (link_info->tlli.current != ident)
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200664 continue;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200665 break;
666 case MATCH_SGSN:
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200667 if (link_info->sgsn_nsei != ident)
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200668 continue;
669 break;
670 case MATCH_IMSI:
Jacob Erlbeck6a1d4282014-10-20 17:22:36 +0200671 if (!link_info->imsi)
672 continue;
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200673 mi_buf[0] = '\0';
674 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200675 link_info->imsi,
676 link_info->imsi_len);
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200677
678 if (strcmp(mi_buf, imsi) != 0)
679 continue;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200680 break;
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200681 }
682
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200683 vty_out(vty, "Deleting link with TLLI %08x%s", link_info->tlli.current,
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200684 VTY_NEWLINE);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200685 gbproxy_delete_link_info(peer, link_info);
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200686 found += 1;
687 }
688
689 if (!found && argc >= 2) {
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200690 vty_out(vty, "Didn't find link entry with %s %s%s",
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200691 argv[1], argv[2], VTY_NEWLINE);
692 }
693
694 return CMD_SUCCESS;
695}
696
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200697DEFUN(delete_gb_link, delete_gb_link_cmd,
698 "delete-gbproxy-link <0-65534> (stale|de-registered)",
699 GBPROXY_DELETE_LINK_STR
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200700 "Delete stale entries\n"
701 "Delete de-registered entries\n")
702{
703 const uint16_t nsei = atoi(argv[0]);
704 enum {MATCH_STALE = 's', MATCH_DEREGISTERED = 'd'} match;
705 struct gbproxy_peer *peer = 0;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200706 struct gbproxy_link_info *link_info, *nxt;
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200707 struct gbproxy_patch_state *state;
Jacob Erlbeckc6807c42014-09-19 16:34:01 +0200708 time_t now;
709 struct timespec ts = {0,};
710
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200711 int found = 0;
712
713 match = argv[1][0];
714
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +0200715 peer = gbproxy_peer_by_nsei(g_cfg, nsei);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200716 if (!peer) {
717 vty_out(vty, "Didn't find peer with NSEI %d%s",
718 nsei, VTY_NEWLINE);
719 return CMD_WARNING;
720 }
721
722 state = &peer->patch_state;
723
Jacob Erlbeckc6807c42014-09-19 16:34:01 +0200724 clock_gettime(CLOCK_MONOTONIC, &ts);
725 now = ts.tv_sec;
726
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200727 if (match == MATCH_STALE) {
Jacob Erlbeckc6807c42014-09-19 16:34:01 +0200728 found = gbproxy_remove_stale_link_infos(peer, now);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200729 if (found)
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200730 vty_out(vty, "Deleted %d stale logical link%s%s",
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200731 found, found == 1 ? "" : "s", VTY_NEWLINE);
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200732 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200733 llist_for_each_entry_safe(link_info, nxt,
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200734 &state->logical_links, list) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200735 if (!link_info->is_deregistered)
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200736 continue;
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200737
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200738 gbproxy_delete_link_info(peer, link_info);
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200739 found += 1;
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200740 }
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200741 }
742
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200743 if (found)
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200744 vty_out(vty, "Deleted %d %s logical link%s%s",
Jacob Erlbeckcdd37832014-09-16 08:56:26 +0200745 found, argv[1], found == 1 ? "" : "s", VTY_NEWLINE);
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +0200746
747 return CMD_SUCCESS;
748}
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200749
Holger Hans Peter Freyther925504b2015-09-24 10:21:40 +0200750/*
751 * legacy commands to provide an upgrade path from "broken" releases
752 * or pre-releases
753 */
754DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match,
755 cfg_gbproxy_broken_apn_match_cmd,
756 "core-access-point-name none match-imsi .REGEXP",
757 GBPROXY_CORE_APN_STR GBPROXY_MATCH_IMSI_STR "Remove APN\n"
758 "Patch MS related information elements on match only\n"
759 "Route to the secondary SGSN on match only\n"
760 "Regular expression for the IMSI match\n")
761{
762 const char *filter = argv[0];
763 const char *err_msg = NULL;
764 struct gbproxy_match *match;
765 enum gbproxy_match_id match_id = get_string_value(match_ids, "patching");
766
767 /* apply APN none */
768 set_core_apn(vty, "");
769
770 /* do the matching... with copy and paste */
771 OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING &&
772 match_id < GBPROX_MATCH_LAST);
773 match = &g_cfg->matches[match_id];
774
775 if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {
776 vty_out(vty, "Match expression invalid: %s%s",
777 err_msg, VTY_NEWLINE);
778 return CMD_WARNING;
779 }
780
781 g_cfg->acquire_imsi = 1;
782
783 return CMD_SUCCESS;
784}
785
786#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"
787#define GBPROXY_MAX_LEN_STR "Limit list length\n"
788DEFUN_DEPRECATED(cfg_gbproxy_depr_tlli_list_max_len,
789 cfg_gbproxy_depr_tlli_list_max_len_cmd,
790 "tlli-list max-length <1-99999>",
791 GBPROXY_TLLI_LIST_STR GBPROXY_MAX_LEN_STR
792 "Maximum number of TLLIs in the list\n")
793{
794 g_cfg->tlli_max_len = atoi(argv[0]);
795
796 return CMD_SUCCESS;
797}
798
Harald Welte799e0c92010-04-30 21:49:24 +0200799int gbproxy_vty_init(void)
800{
Harald Welte995a2d32010-05-12 16:50:52 +0000801 install_element_ve(&show_gbproxy_cmd);
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200802 install_element_ve(&show_gbproxy_links_cmd);
Harald Welte799e0c92010-04-30 21:49:24 +0200803
Jacob Erlbeck4211d792013-10-24 12:48:23 +0200804 install_element(ENABLE_NODE, &delete_gb_bvci_cmd);
805 install_element(ENABLE_NODE, &delete_gb_nsei_cmd);
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200806 install_element(ENABLE_NODE, &delete_gb_link_by_id_cmd);
807 install_element(ENABLE_NODE, &delete_gb_link_cmd);
Holger Hans Peter Freyther90267a92013-10-23 11:24:17 +0200808
Harald Welte799e0c92010-04-30 21:49:24 +0200809 install_element(CONFIG_NODE, &cfg_gbproxy_cmd);
810 install_node(&gbproxy_node, config_write_gbproxy);
Jacob Erlbeck36722e12013-10-29 09:30:30 +0100811 vty_install_default(GBPROXY_NODE);
Harald Welte799e0c92010-04-30 21:49:24 +0200812 install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd);
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200813 install_element(GBPROXY_NODE, &cfg_gbproxy_core_mcc_cmd);
814 install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd);
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200815 install_element(GBPROXY_NODE, &cfg_gbproxy_match_imsi_cmd);
Jacob Erlbeck73685282014-05-23 20:48:07 +0200816 install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_cmd);
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200817 install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd);
Jacob Erlbeck0d4236b2014-08-18 14:54:37 +0200818 install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200819 install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd);
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200820 install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd);
821 install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd);
822 install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd);
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200823 install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);
824 install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200825 install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd);
Jacob Erlbeck73685282014-05-23 20:48:07 +0200826 install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_apn_cmd);
Jacob Erlbeckcd9e1c92014-09-02 13:57:19 +0200827 install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd);
Jacob Erlbeck0d4236b2014-08-18 14:54:37 +0200828 install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200829 install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);
Jacob Erlbeckd4c79a42014-09-19 15:36:44 +0200830 install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);
831 install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);
Harald Welte799e0c92010-04-30 21:49:24 +0200832
Holger Hans Peter Freyther925504b2015-09-24 10:21:40 +0200833 /* broken or deprecated to allow an upgrade path */
834 install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd);
835 install_element(GBPROXY_NODE, &cfg_gbproxy_depr_tlli_list_max_len_cmd);
836
Harald Welte799e0c92010-04-30 21:49:24 +0200837 return 0;
838}
839
840int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg)
841{
842 int rc;
843
844 g_cfg = cfg;
Harald Weltedcccb182010-05-16 20:52:23 +0200845 rc = vty_read_config_file(config_file, NULL);
Harald Welte799e0c92010-04-30 21:49:24 +0200846 if (rc < 0) {
847 fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
848 return rc;
849 }
850
851 return 0;
852}
853