blob: 1126c5cd8c1b2bc6492d8984cd8780cbf2fa61c9 [file] [log] [blame]
Neels Hofmeyr87203f22017-10-31 01:15:45 +01001/* MGCP client interface to quagga VTY */
Neels Hofmeyre9920f22017-07-10 15:07:22 +02002/* (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
3 * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
4 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
5 * (C) 2009-2011 by Holger Hans Peter Freyther
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
Harald Welte220f4872018-02-04 09:04:16 +01009 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
Neels Hofmeyre9920f22017-07-10 15:07:22 +020011 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte220f4872018-02-04 09:04:16 +010016 * GNU General Public License for more details.
Neels Hofmeyre9920f22017-07-10 15:07:22 +020017 *
Harald Welte220f4872018-02-04 09:04:16 +010018 * You should have received a copy of the GNU General Public License
Neels Hofmeyre9920f22017-07-10 15:07:22 +020019 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include <inttypes.h>
24#include <stdlib.h>
25#include <talloc.h>
26
27#include <osmocom/vty/command.h>
Stefan Sperling29248252018-02-22 18:09:28 +010028#include <osmocom/vty/misc.h>
Neels Hofmeyre9920f22017-07-10 15:07:22 +020029#include <osmocom/core/utils.h>
30
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020031#include <osmocom/mgcp_client/mgcp_client.h>
Philipp Maier3f2c15f2021-07-22 11:53:07 +020032#include <osmocom/mgcp_client/mgcp_client_internal.h>
Neels Hofmeyre9920f22017-07-10 15:07:22 +020033
Neels Hofmeyre6d8e912018-08-23 16:36:48 +020034#define MGW_STR MGCP_CLIENT_MGW_STR
Neels Hofmeyre9920f22017-07-10 15:07:22 +020035
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020036void *global_mgcp_client_ctx = NULL;
37struct mgcp_client_conf *global_mgcp_client_conf = NULL;
Neels Hofmeyre9920f22017-07-10 15:07:22 +020038
Neels Hofmeyr87203f22017-10-31 01:15:45 +010039DEFUN(cfg_mgw_local_ip, cfg_mgw_local_ip_cmd,
Pau Espin Pedrol531470a2020-08-31 17:06:55 +020040 "mgw local-ip " VTY_IPV46_CMD,
Neels Hofmeyr54dd4b32017-10-31 01:18:33 +010041 MGW_STR "local bind to connect to MGW from\n"
Pau Espin Pedrol531470a2020-08-31 17:06:55 +020042 "local bind IPv4 address\n"
43 "local bind IPv6 address\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +020044{
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020045 if (!global_mgcp_client_conf)
Neels Hofmeyre9920f22017-07-10 15:07:22 +020046 return CMD_ERR_NOTHING_TODO;
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020047 OSMO_ASSERT(global_mgcp_client_ctx);
Neels Hofmeyrc3132fd2018-12-19 00:30:34 +010048 osmo_talloc_replace_string(global_mgcp_client_ctx,
49 (char**)&global_mgcp_client_conf->local_addr,
50 argv[0]);
Neels Hofmeyre9920f22017-07-10 15:07:22 +020051 return CMD_SUCCESS;
52}
Neels Hofmeyr87203f22017-10-31 01:15:45 +010053ALIAS_DEPRECATED(cfg_mgw_local_ip, cfg_mgcpgw_local_ip_cmd,
54 "mgcpgw local-ip A.B.C.D",
55 MGW_STR "local bind to connect to MGCP gateway with\n"
56 "local bind IP address\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +020057
Neels Hofmeyr87203f22017-10-31 01:15:45 +010058DEFUN(cfg_mgw_local_port, cfg_mgw_local_port_cmd,
59 "mgw local-port <0-65535>",
Neels Hofmeyr54dd4b32017-10-31 01:18:33 +010060 MGW_STR "local port to connect to MGW from\n"
Neels Hofmeyre9920f22017-07-10 15:07:22 +020061 "local bind port\n")
62{
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020063 if (!global_mgcp_client_conf)
Neels Hofmeyre9920f22017-07-10 15:07:22 +020064 return CMD_ERR_NOTHING_TODO;
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020065 global_mgcp_client_conf->local_port = atoi(argv[0]);
Neels Hofmeyre9920f22017-07-10 15:07:22 +020066 return CMD_SUCCESS;
67}
Neels Hofmeyr87203f22017-10-31 01:15:45 +010068ALIAS_DEPRECATED(cfg_mgw_local_port, cfg_mgcpgw_local_port_cmd,
69 "mgcpgw local-port <0-65535>",
70 MGW_STR "local bind to connect to MGCP gateway with\n"
71 "local bind port\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +020072
Neels Hofmeyr87203f22017-10-31 01:15:45 +010073DEFUN(cfg_mgw_remote_ip, cfg_mgw_remote_ip_cmd,
Pau Espin Pedrol531470a2020-08-31 17:06:55 +020074 "mgw remote-ip " VTY_IPV46_CMD,
Neels Hofmeyr54dd4b32017-10-31 01:18:33 +010075 MGW_STR "remote IP address to reach the MGW at\n"
Pau Espin Pedrol531470a2020-08-31 17:06:55 +020076 "remote IPv4 address\n"
77 "remote IPv6 address\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +020078{
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020079 if (!global_mgcp_client_conf)
Neels Hofmeyre9920f22017-07-10 15:07:22 +020080 return CMD_ERR_NOTHING_TODO;
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020081 OSMO_ASSERT(global_mgcp_client_ctx);
Neels Hofmeyrc3132fd2018-12-19 00:30:34 +010082 osmo_talloc_replace_string(global_mgcp_client_ctx,
83 (char**)&global_mgcp_client_conf->remote_addr,
84 argv[0]);
Neels Hofmeyre9920f22017-07-10 15:07:22 +020085 return CMD_SUCCESS;
86}
Neels Hofmeyr87203f22017-10-31 01:15:45 +010087ALIAS_DEPRECATED(cfg_mgw_remote_ip, cfg_mgcpgw_remote_ip_cmd,
88 "mgcpgw remote-ip A.B.C.D",
89 MGW_STR "remote bind to connect to MGCP gateway with\n"
90 "remote bind IP address\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +020091
Neels Hofmeyr87203f22017-10-31 01:15:45 +010092DEFUN(cfg_mgw_remote_port, cfg_mgw_remote_port_cmd,
93 "mgw remote-port <0-65535>",
Neels Hofmeyr54dd4b32017-10-31 01:18:33 +010094 MGW_STR "remote port to reach the MGW at\n"
95 "remote port\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +020096{
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020097 if (!global_mgcp_client_conf)
Neels Hofmeyre9920f22017-07-10 15:07:22 +020098 return CMD_ERR_NOTHING_TODO;
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +020099 global_mgcp_client_conf->remote_port = atoi(argv[0]);
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200100 return CMD_SUCCESS;
101}
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100102ALIAS_DEPRECATED(cfg_mgw_remote_port, cfg_mgcpgw_remote_port_cmd,
103 "mgcpgw remote-port <0-65535>",
104 MGW_STR "remote bind to connect to MGCP gateway with\n"
105 "remote bind port\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200106
Neels Hofmeyr72bc8da2018-12-19 00:44:37 +0100107DEFUN_DEPRECATED(cfg_mgw_endpoint_range, cfg_mgw_endpoint_range_cmd,
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100108 "mgw endpoint-range <1-65534> <1-65534>",
Neels Hofmeyr72bc8da2018-12-19 00:44:37 +0100109 MGW_STR "DEPRECATED: the endpoint range cannot be defined by the client\n"
110 "-\n" "-\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200111{
Neels Hofmeyr72bc8da2018-12-19 00:44:37 +0100112 vty_out(vty, "Please do not use legacy config 'mgw endpoint-range'"
113 " (the range can no longer be defined by the MGCP client)%s",
114 VTY_NEWLINE);
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200115 return CMD_SUCCESS;
116}
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100117ALIAS_DEPRECATED(cfg_mgw_endpoint_range, cfg_mgcpgw_endpoint_range_cmd,
118 "mgcpgw endpoint-range <1-65534> <1-65534>",
119 MGW_STR "usable range of endpoint identifiers\n"
120 "set first useable endpoint identifier\n"
121 "set the last useable endpoint identifier\n")
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200122
Neels Hofmeyrc0dcc3c2017-12-02 18:31:34 +0000123#define BTS_START_STR "First UDP port allocated for the BTS side\n"
124#define UDP_PORT_STR "UDP Port number\n"
Neels Hofmeyr72bc8da2018-12-19 00:44:37 +0100125DEFUN_DEPRECATED(cfg_mgw_rtp_bts_base_port,
Neels Hofmeyrc0dcc3c2017-12-02 18:31:34 +0000126 cfg_mgw_rtp_bts_base_port_cmd,
127 "mgw bts-base <0-65534>",
128 MGW_STR
Neels Hofmeyr72bc8da2018-12-19 00:44:37 +0100129 "DEPRECATED: there is no explicit BTS side in current osmo-mgw\n" "-\n")
Neels Hofmeyrc0dcc3c2017-12-02 18:31:34 +0000130{
Neels Hofmeyr72bc8da2018-12-19 00:44:37 +0100131 vty_out(vty, "Please do not use legacy config 'mgw bts-base'"
132 " (there is no explicit BTS side in an MGW anymore)%s",
133 VTY_NEWLINE);
Neels Hofmeyrc0dcc3c2017-12-02 18:31:34 +0000134 return CMD_SUCCESS;
135}
136ALIAS_DEPRECATED(cfg_mgw_rtp_bts_base_port,
137 cfg_mgcpgw_rtp_bts_base_port_cmd,
138 "mgcpgw bts-base <0-65534>",
139 MGW_STR
140 BTS_START_STR
141 UDP_PORT_STR)
142
Neels Hofmeyrac69ea92018-12-19 00:27:50 +0100143DEFUN(cfg_mgw_endpoint_domain_name,
144 cfg_mgw_endpoint_domain_name_cmd,
145 "mgw endpoint-domain NAME",
146 MGW_STR "Set the domain name to send in MGCP messages, e.g. the part 'foo' in 'rtpbridge/*@foo'.\n"
147 "Domain name, should be alphanumeric.\n")
148{
149 if (osmo_strlcpy(global_mgcp_client_conf->endpoint_domain_name, argv[0],
150 sizeof(global_mgcp_client_conf->endpoint_domain_name))
151 >= sizeof(global_mgcp_client_conf->endpoint_domain_name)) {
152 vty_out(vty, "%% Error: 'mgw endpoint-domain' name too long, max length is %zu: '%s'%s",
153 sizeof(global_mgcp_client_conf->endpoint_domain_name) - 1, argv[0], VTY_NEWLINE);
154 return CMD_WARNING;
155 }
156 return CMD_SUCCESS;
157}
158
Philipp Maier3f2c15f2021-07-22 11:53:07 +0200159DEFUN(cfg_mgw_reset_ep_name,
160 cfg_mgw_reset_ep_name_cmd,
161 "mgw reset-endpoint NAME",
162 MGW_STR "Add an endpoint name that should be reset (DLCX) on connect to the reset-endpoint list,"
163 "e.g. 'rtpbridge/*'\n"
164 "Endpoint name, e.g. 'rtpbridge/*' or 'ds/e1-0/s-3/su16-4'.\n")
165{
166 int rc;
167 struct reset_ep *reset_ep;
168
169 /* stop when the address is already in the list */
170 llist_for_each_entry(reset_ep, &global_mgcp_client_conf->reset_epnames, list) {
171 if (strcmp(argv[0], reset_ep->name) == 0) {
172 vty_out(vty, "%% duplicate endpoint name configured ('%s')%s", argv[0], VTY_NEWLINE);
173 return CMD_WARNING;
174 }
175 }
176
177 /* the domain name is not part of the actual endpoint name */
178 if (strchr(argv[0], '@')) {
179 vty_out(vty, "%% the endpoint name must be given without domain name ('%s')%s",
180 argv[0], VTY_NEWLINE);
181 return CMD_WARNING;
182 }
183
184 reset_ep = talloc_zero(global_mgcp_client_ctx, struct reset_ep);
185 OSMO_ASSERT(reset_ep);
186
187 rc = osmo_strlcpy(reset_ep->name, argv[0], sizeof(reset_ep->name));
188 if (rc >= sizeof(reset_ep->name)) {
189 vty_out(vty, "%% Error: 'mgw reset-endpoint' name too long, max length is %zu: '%s'%s",
190 sizeof(reset_ep->name) - 1, argv[0], VTY_NEWLINE);
191 talloc_free(reset_ep);
192 return CMD_WARNING;
193 }
194
195 llist_add_tail(&reset_ep->list, &global_mgcp_client_conf->reset_epnames);
196
197 return CMD_SUCCESS;
198}
199
200DEFUN(cfg_mgw_no_reset_ep_name,
201 cfg_mgw_no_reset_ep_name_cmd,
202 "no mgw reset-endpoint NAME",
203 MGW_STR "remove an endpoint name from the reset-endpoint list, e.g. 'rtpbridge/*'\n"
204 "Endpoint name, e.g. 'rtpbridge/*' or 'ds/e1-0/s-3/su16-4'.\n")
205{
206 struct reset_ep *reset_ep;
207
208 llist_for_each_entry(reset_ep, &global_mgcp_client_conf->reset_epnames, list) {
209 if (strcmp(argv[0], reset_ep->name) == 0) {
210 llist_del(&reset_ep->list);
211 talloc_free(reset_ep);
212 return CMD_SUCCESS;
213 }
214 }
215
216 vty_out(vty, "%% no such endpoint name configured ('%s')%s", argv[0], VTY_NEWLINE);
217 return CMD_WARNING;
218}
219
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200220int mgcp_client_config_write(struct vty *vty, const char *indent)
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200221{
222 const char *addr;
223 int port;
Philipp Maier3f2c15f2021-07-22 11:53:07 +0200224 struct reset_ep *reset_ep;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200225
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200226 addr = global_mgcp_client_conf->local_addr;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200227 if (addr)
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100228 vty_out(vty, "%smgw local-ip %s%s", indent, addr,
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200229 VTY_NEWLINE);
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200230 port = global_mgcp_client_conf->local_port;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200231 if (port >= 0)
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100232 vty_out(vty, "%smgw local-port %u%s", indent,
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200233 (uint16_t)port, VTY_NEWLINE);
234
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200235 addr = global_mgcp_client_conf->remote_addr;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200236 if (addr)
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100237 vty_out(vty, "%smgw remote-ip %s%s", indent, addr,
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200238 VTY_NEWLINE);
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200239 port = global_mgcp_client_conf->remote_port;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200240 if (port >= 0)
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100241 vty_out(vty, "%smgw remote-port %u%s", indent,
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200242 (uint16_t)port, VTY_NEWLINE);
243
Neels Hofmeyrac69ea92018-12-19 00:27:50 +0100244 if (global_mgcp_client_conf->endpoint_domain_name[0])
245 vty_out(vty, "%smgw endpoint-domain %s%s", indent,
246 global_mgcp_client_conf->endpoint_domain_name, VTY_NEWLINE);
247
Philipp Maier3f2c15f2021-07-22 11:53:07 +0200248 llist_for_each_entry(reset_ep, &global_mgcp_client_conf->reset_epnames, list)
249 vty_out(vty, "%smgw reset-endpoint %s%s", indent, reset_ep->name, VTY_NEWLINE);
250
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200251 return CMD_SUCCESS;
252}
253
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200254void mgcp_client_vty_init(void *talloc_ctx, int node, struct mgcp_client_conf *conf)
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200255{
Neels Hofmeyr3a8e7232017-09-04 01:02:56 +0200256 global_mgcp_client_ctx = talloc_ctx;
257 global_mgcp_client_conf = conf;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200258
Vadim Yanitskiy3ba40952020-10-04 16:42:04 +0700259 install_lib_element(node, &cfg_mgw_local_ip_cmd);
260 install_lib_element(node, &cfg_mgw_local_port_cmd);
261 install_lib_element(node, &cfg_mgw_remote_ip_cmd);
262 install_lib_element(node, &cfg_mgw_remote_port_cmd);
263 install_lib_element(node, &cfg_mgw_endpoint_range_cmd);
264 install_lib_element(node, &cfg_mgw_rtp_bts_base_port_cmd);
265 install_lib_element(node, &cfg_mgw_endpoint_domain_name_cmd);
Philipp Maier3f2c15f2021-07-22 11:53:07 +0200266 install_lib_element(node, &cfg_mgw_reset_ep_name_cmd);
267 install_lib_element(node, &cfg_mgw_no_reset_ep_name_cmd);
Neels Hofmeyr87203f22017-10-31 01:15:45 +0100268
269 /* deprecated 'mgcpgw' commands */
Vadim Yanitskiy3ba40952020-10-04 16:42:04 +0700270 install_lib_element(node, &cfg_mgcpgw_local_ip_cmd);
271 install_lib_element(node, &cfg_mgcpgw_local_port_cmd);
272 install_lib_element(node, &cfg_mgcpgw_remote_ip_cmd);
273 install_lib_element(node, &cfg_mgcpgw_remote_port_cmd);
274 install_lib_element(node, &cfg_mgcpgw_endpoint_range_cmd);
275 install_lib_element(node, &cfg_mgcpgw_rtp_bts_base_port_cmd);
Stefan Sperling29248252018-02-22 18:09:28 +0100276
277 osmo_fsm_vty_add_cmds();
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200278}