blob: aead178789efbe9fffa8bda6f1bcd5092c874761 [file] [log] [blame]
Neels Hofmeyrc8a614d2015-09-24 17:32:30 +02001/* (C) 2015 by sysmocom s.f.m.c. GmbH
2 * All Rights Reserved
3 *
4 * Author: Neels Hofmeyr
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * 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
9 * (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
14 * GNU Affero General Public License for more details.
15 *
16 * 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/>.
18 *
19 */
20
21#include <string.h>
22
23#include <osmocom/core/talloc.h>
24#include <osmocom/vty/command.h>
25
26#include <openbsc/vty.h>
27#include <openbsc/gtphub.h>
28
29static struct gtphub_cfg *g_cfg = 0;
30
31static struct cmd_node gtphub_node = {
32 GTPHUB_NODE,
33 "%s(config-gtphub)# ",
34 1,
35};
36
37#define GTPH_DEFAULT_CONTROL_PORT 2123
38#define GTPH_DEFAULT_USER_PORT 2152
39
40static void write_addrs(struct vty *vty, const char *name,
41 struct gtphub_cfg_addr *c, struct gtphub_cfg_addr *u)
42{
43 if ((c->port == GTPH_DEFAULT_CONTROL_PORT)
44 && (u->port == GTPH_DEFAULT_USER_PORT)
45 && (strcmp(c->addr_str, u->addr_str) == 0)) {
46 /* Default port numbers and same IP address: write "short"
47 * variant. */
48 vty_out(vty, " %s %s%s",
49 name,
50 c->addr_str,
51 VTY_NEWLINE);
52 return;
53 }
54
55 vty_out(vty, " %s ctrl %s %d user %s %d%s",
56 name,
57 c->addr_str, (int)c->port,
58 u->addr_str, (int)u->port,
59 VTY_NEWLINE);
60}
61
62static int config_write_gtphub(struct vty *vty)
63{
64 vty_out(vty, "gtphub%s", VTY_NEWLINE);
65
66 write_addrs(vty, "bind-to-sgsns",
67 &g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind,
68 &g_cfg->to_sgsns[GTPH_PLANE_USER].bind);
69
70 write_addrs(vty, "bind-to-ggsns",
71 &g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind,
72 &g_cfg->to_ggsns[GTPH_PLANE_USER].bind);
73
74 if (g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str) {
75 write_addrs(vty, "ggsn-proxy",
76 &g_cfg->ggsn_proxy[GTPH_PLANE_CTRL],
77 &g_cfg->ggsn_proxy[GTPH_PLANE_USER]);
78 }
79
80 return CMD_SUCCESS;
81}
82
83DEFUN(cfg_gtphub, cfg_gtphub_cmd,
84 "gtphub",
85 "Configure the GTP hub")
86{
87 vty->node = GTPHUB_NODE;
88 return CMD_SUCCESS;
89}
90
91#define BIND_ARGS "ctrl ADDR <0-65535> user ADDR <0-65535>"
92#define BIND_DOCS \
93 "Set GTP-C bind\n" \
94 "GTP-C local IP address (v4 or v6)\n" \
95 "GTP-C local port\n" \
96 "Set GTP-U bind\n" \
97 "GTP-U local IP address (v4 or v6)\n" \
98 "GTP-U local port\n"
99
100
101DEFUN(cfg_gtphub_bind_to_sgsns_short, cfg_gtphub_bind_to_sgsns_short_cmd,
102 "bind-to-sgsns ADDR",
103 "GTP Hub Parameters\n"
104 "Set the local bind address to listen for SGSNs, for both GTP-C and GTP-U\n"
105 "Local IP address (v4 or v6)\n"
106 )
107{
108 int i;
109 for (i = 0; i < GTPH_PLANE_N; i++)
110 g_cfg->to_sgsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
111 g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT;
112 g_cfg->to_sgsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT;
113 return CMD_SUCCESS;
114}
115
116DEFUN(cfg_gtphub_bind_to_ggsns_short, cfg_gtphub_bind_to_ggsns_short_cmd,
117 "bind-to-ggsns ADDR",
118 "GTP Hub Parameters\n"
119 "Set the local bind address to listen for GGSNs, for both GTP-C and GTP-U\n"
120 "Local IP address (v4 or v6)\n"
121 )
122{
123 int i;
124 for (i = 0; i < GTPH_PLANE_N; i++)
125 g_cfg->to_ggsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
126 g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT;
127 g_cfg->to_ggsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT;
128 return CMD_SUCCESS;
129}
130
131
132static int handle_binds(struct gtphub_cfg_bind *b, const char **argv)
133{
134 b[GTPH_PLANE_CTRL].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
135 b[GTPH_PLANE_CTRL].bind.port = atoi(argv[1]);
136 b[GTPH_PLANE_USER].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[2]);
137 b[GTPH_PLANE_USER].bind.port = atoi(argv[3]);
138 return CMD_SUCCESS;
139}
140
141DEFUN(cfg_gtphub_bind_to_sgsns, cfg_gtphub_bind_to_sgsns_cmd,
142 "bind-to-sgsns " BIND_ARGS,
143 "GTP Hub Parameters\n"
144 "Set the local bind addresses and ports to listen for SGSNs\n"
145 BIND_DOCS
146 )
147{
148 return handle_binds(g_cfg->to_sgsns, argv);
149}
150
151DEFUN(cfg_gtphub_bind_to_ggsns, cfg_gtphub_bind_to_ggsns_cmd,
152 "bind-to-ggsns " BIND_ARGS,
153 "GTP Hub Parameters\n"
154 "Set the local bind addresses and ports to listen for GGSNs\n"
155 BIND_DOCS
156 )
157{
158 return handle_binds(g_cfg->to_ggsns, argv);
159}
160
161DEFUN(cfg_gtphub_ggsn_proxy_short, cfg_gtphub_ggsn_proxy_short_cmd,
162 "ggsn-proxy ADDR",
163 "GTP Hub Parameters\n"
164 "Redirect all GGSN bound traffic to default ports on this address (another gtphub)\n"
165 "Remote IP address (v4 or v6)\n"
166 )
167{
168 g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
169 g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT;
170 g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
171 g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT;
172 return CMD_SUCCESS;
173}
174
175DEFUN(cfg_gtphub_ggsn_proxy, cfg_gtphub_ggsn_proxy_cmd,
176 "ggsn-proxy " BIND_ARGS,
177 "GTP Hub Parameters\n"
178 "Redirect all GGSN bound traffic to these addresses and ports (another gtphub)\n"
179 BIND_DOCS
180 )
181{
182 g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
183 g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]);
184 g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]);
185 g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]);
186 return CMD_SUCCESS;
187}
188
189DEFUN(cfg_gtphub_sgsn_proxy_short, cfg_gtphub_sgsn_proxy_short_cmd,
190 "sgsn-proxy ADDR",
191 "GTP Hub Parameters\n"
192 "Redirect all SGSN bound traffic to default ports on this address (another gtphub)\n"
193 "Remote IP address (v4 or v6)\n"
194 )
195{
196 g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
197 g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT;
198 g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
199 g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT;
200 return CMD_SUCCESS;
201}
202
203DEFUN(cfg_gtphub_sgsn_proxy, cfg_gtphub_sgsn_proxy_cmd,
204 "sgsn-proxy " BIND_ARGS,
205 "GTP Hub Parameters\n"
206 "Redirect all SGSN bound traffic to these addresses and ports (another gtphub)\n"
207 BIND_DOCS
208 )
209{
210 g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
211 g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]);
212 g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]);
213 g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]);
214 return CMD_SUCCESS;
215}
216
217DEFUN(show_gtphub, show_gtphub_cmd, "show gtphub",
218 SHOW_STR "Display information about the GTP hub")
219{
220 vty_out(vty, "gtphub has nothing to say yet%s", VTY_NEWLINE);
221 return CMD_SUCCESS;
222}
223
224
225int gtphub_vty_init(void)
226{
227 install_element_ve(&show_gtphub_cmd);
228
229 install_element(CONFIG_NODE, &cfg_gtphub_cmd);
230 install_node(&gtphub_node, config_write_gtphub);
231 vty_install_default(GTPHUB_NODE);
232
233 install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_short_cmd);
234 install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_cmd);
235 install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_short_cmd);
236 install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_cmd);
237 install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_short_cmd);
238 install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_cmd);
239 install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_short_cmd);
240 install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_cmd);
241
242 return 0;
243}
244
245int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file)
246{
247 int rc;
248
249 g_cfg = cfg;
250
251 rc = vty_read_config_file(config_file, NULL);
252 if (rc < 0) {
253 fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
254 return rc;
255 }
256
257 return 0;
258}