blob: 08b0076c1f7c04323556cf30643c3c04fa4ddf0c [file] [log] [blame]
Harald Welte144e0292010-05-13 11:45:07 +02001/* VTY interface for our GPRS Networks Service (NS) implementation */
2
3/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <stdlib.h>
24#include <unistd.h>
25#include <errno.h>
26#include <stdint.h>
27
28#include <arpa/inet.h>
29
30#include <openbsc/gsm_data.h>
31#include <osmocore/msgb.h>
32#include <osmocore/tlv.h>
33#include <osmocore/talloc.h>
34#include <osmocore/select.h>
35#include <osmocore/rate_ctr.h>
36#include <openbsc/debug.h>
37#include <openbsc/signal.h>
38#include <openbsc/gprs_ns.h>
39#include <openbsc/gprs_bssgp.h>
40
41#include <vty/vty.h>
42#include <vty/command.h>
43
44static struct gprs_ns_inst *vty_nsi = NULL;
45
46/* FIXME: this should go to some common file as it is copied
47 * in vty_interface.c of the BSC */
48static const struct value_string gprs_ns_timer_strs[] = {
49 { 0, "tns-block" },
50 { 1, "tns-block-retries" },
51 { 2, "tns-reset" },
52 { 3, "tns-reset-retries" },
53 { 4, "tns-test" },
54 { 5, "tns-alive" },
55 { 6, "tns-alive-retries" },
56 { 0, NULL }
57};
58
59static struct cmd_node ns_node = {
60 NS_NODE,
61 "%s(ns)#",
62 1,
63};
64
65static int config_write_ns(struct vty *vty)
66{
67 struct gprs_nsvc *nsvc;
68 unsigned int i;
69
70 vty_out(vty, "ns%s", VTY_NEWLINE);
71
72 llist_for_each_entry(nsvc, &vty_nsi->gprs_nsvcs, list) {
73 if (!nsvc->persistent)
74 continue;
75 vty_out(vty, " nse %u nsvci %u%s",
76 nsvc->nsei, nsvc->nsvci, VTY_NEWLINE);
77 vty_out(vty, " nse %u remote-role %s%s",
78 nsvc->nsei, nsvc->remote_end_is_sgsn ? "sgsn" : "bss",
79 VTY_NEWLINE);
80 if (nsvc->nsi->ll == GPRS_NS_LL_UDP) {
81 vty_out(vty, " nse %u remote-ip %s%s",
82 nsvc->nsei,
83 inet_ntoa(nsvc->ip.bts_addr.sin_addr),
84 VTY_NEWLINE);
85 vty_out(vty, " nse %u remote-port %u%s",
86 nsvc->nsei, ntohs(nsvc->ip.bts_addr.sin_port),
87 VTY_NEWLINE);
88 }
89 }
90
91 for (i = 0; i < ARRAY_SIZE(vty_nsi->timeout); i++)
92 vty_out(vty, " timer %s %u%s",
93 get_value_string(gprs_ns_timer_strs, i),
94 vty_nsi->timeout[i], VTY_NEWLINE);
95
96 return CMD_SUCCESS;
97}
98
99DEFUN(cfg_ns, cfg_ns_cmd,
100 "ns",
101 "Configure the GPRS Network Service")
102{
103 vty->node = NS_NODE;
104 return CMD_SUCCESS;
105}
106
Harald Welteaf1d4cb2010-05-13 12:32:30 +0200107static void dump_ns(struct vty *vty, struct gprs_ns_inst *nsi, int stats)
Harald Welte144e0292010-05-13 11:45:07 +0200108{
Harald Welte144e0292010-05-13 11:45:07 +0200109 struct gprs_nsvc *nsvc;
110
111 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
112 vty_out(vty, "NSEI %5u, NS-VC %5u, Remote: %-4s, %5s %9s",
113 nsvc->nsei, nsvc->nsvci,
114 nsvc->remote_end_is_sgsn ? "SGSN" : "BSS",
115 nsvc->state & NSE_S_ALIVE ? "ALIVE" : "DEAD",
116 nsvc->state & NSE_S_BLOCKED ? "BLOCKED" : "UNBLOCKED");
117 if (nsvc->nsi->ll == GPRS_NS_LL_UDP)
118 vty_out(vty, ", %15s:%u",
119 inet_ntoa(nsvc->ip.bts_addr.sin_addr),
120 ntohs(nsvc->ip.bts_addr.sin_port));
121 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welteaf1d4cb2010-05-13 12:32:30 +0200122 if (stats)
123 vty_out_rate_ctr_group(vty, " ", nsvc->ctrg);
Harald Welte144e0292010-05-13 11:45:07 +0200124 }
Harald Welteaf1d4cb2010-05-13 12:32:30 +0200125}
Harald Welte144e0292010-05-13 11:45:07 +0200126
Harald Welteaf1d4cb2010-05-13 12:32:30 +0200127DEFUN(show_ns, show_ns_cmd, "show ns",
128 SHOW_STR "Display information about the NS protocol")
129{
130 struct gprs_ns_inst *nsi = vty_nsi;
131 dump_ns(vty, nsi, 0);
Harald Welte144e0292010-05-13 11:45:07 +0200132 return CMD_SUCCESS;
133}
134
Harald Welteaf1d4cb2010-05-13 12:32:30 +0200135DEFUN(show_ns_stats, show_ns_stats_cmd, "show ns stats",
136 SHOW_STR
137 "Display information about the NS protocol\n"
138 "Include statistics\n")
139{
140 struct gprs_ns_inst *nsi = vty_nsi;
141 dump_ns(vty, nsi, 1);
142 return CMD_SUCCESS;
143}
Harald Welte144e0292010-05-13 11:45:07 +0200144
145#define NSE_CMD_STR "NS Entity\n" "NS Entity ID (NSEI)\n"
146
147DEFUN(cfg_nse_nsvc, cfg_nse_nsvci_cmd,
148 "nse <0-65535> nsvci <0-65534>",
149 NSE_CMD_STR
150 "NS Virtual Connection\n"
151 "NS Virtual Connection ID (NSVCI)\n"
152 )
153{
154 uint16_t nsei = atoi(argv[0]);
155 uint16_t nsvci = atoi(argv[1]);
156 struct gprs_nsvc *nsvc;
157
158 nsvc = nsvc_by_nsei(vty_nsi, nsei);
159 if (!nsvc) {
160 nsvc = nsvc_create(vty_nsi, nsvci);
161 nsvc->nsei = nsei;
162 }
163 nsvc->nsvci = nsvci;
164 /* All NSVCs that are explicitly configured by VTY are
165 * marked as persistent so we can write them to the config
166 * file at some later point */
167 nsvc->persistent = 1;
168
169 return CMD_SUCCESS;
170}
171
172DEFUN(cfg_nse_remoteip, cfg_nse_remoteip_cmd,
173 "nse <0-65535> remote-ip A.B.C.D",
174 NSE_CMD_STR
175 "Remote IP Address\n"
176 "Remote IP Address\n")
177{
178 uint16_t nsei = atoi(argv[0]);
179 struct gprs_nsvc *nsvc;
180
181 nsvc = nsvc_by_nsei(vty_nsi, nsei);
182 if (!nsvc) {
183 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
184 return CMD_WARNING;
185 }
186 inet_aton(argv[1], &nsvc->ip.bts_addr.sin_addr);
187
188 return CMD_SUCCESS;
189
190}
191
192DEFUN(cfg_nse_remoteport, cfg_nse_remoteport_cmd,
193 "nse <0-65535> remote-port <0-65535>",
194 NSE_CMD_STR
195 "Remote UDP Port\n"
196 "Remote UDP Port Number\n")
197{
198 uint16_t nsei = atoi(argv[0]);
199 uint16_t port = atoi(argv[1]);
200 struct gprs_nsvc *nsvc;
201
202 nsvc = nsvc_by_nsei(vty_nsi, nsei);
203 if (!nsvc) {
204 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
205 return CMD_WARNING;
206 }
207
208 nsvc->ip.bts_addr.sin_port = htons(port);
209
210 return CMD_SUCCESS;
211}
212
213DEFUN(cfg_nse_remoterole, cfg_nse_remoterole_cmd,
214 "nse <0-65535> remote-role (sgsn|bss)",
215 NSE_CMD_STR
216 "Remote NSE Role\n"
217 "Remote Peer is SGSN\n"
218 "Remote Peer is BSS\n")
219{
220 uint16_t nsei = atoi(argv[0]);
221 struct gprs_nsvc *nsvc;
222
223 nsvc = nsvc_by_nsei(vty_nsi, nsei);
224 if (!nsvc) {
225 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
226 return CMD_WARNING;
227 }
228
229 if (!strcmp(argv[1], "sgsn"))
230 nsvc->remote_end_is_sgsn = 1;
231 else
232 nsvc->remote_end_is_sgsn = 0;
233
234 return CMD_SUCCESS;
235}
236
237DEFUN(cfg_no_nse, cfg_no_nse_cmd,
238 "no nse <0-65535>",
239 "Delete NS Entity\n"
240 "Delete " NSE_CMD_STR)
241{
242 uint16_t nsei = atoi(argv[0]);
243 struct gprs_nsvc *nsvc;
244
245 nsvc = nsvc_by_nsei(vty_nsi, nsei);
246 if (!nsvc) {
247 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
248 return CMD_WARNING;
249 }
250
251 nsvc_delete(nsvc);
252
253 return CMD_SUCCESS;
254}
255
256DEFUN(cfg_ns_timer, cfg_ns_timer_cmd,
257 "timer " NS_TIMERS " <0-65535>",
258 "Network Service Timer\n"
259 NS_TIMERS_HELP "Timer Value\n")
260{
261 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
262 int val = atoi(argv[1]);
263
264 if (idx < 0 || idx >= ARRAY_SIZE(vty_nsi->timeout))
265 return CMD_WARNING;
266
267 vty_nsi->timeout[idx] = val;
268
269 return CMD_SUCCESS;
270}
271
272int gprs_ns_vty_init(struct gprs_ns_inst *nsi)
273{
274 vty_nsi = nsi;
275
276 install_element_ve(&show_ns_cmd);
Harald Welteaf1d4cb2010-05-13 12:32:30 +0200277 install_element_ve(&show_ns_stats_cmd);
Harald Welte144e0292010-05-13 11:45:07 +0200278
279 install_element(CONFIG_NODE, &cfg_ns_cmd);
280 install_node(&ns_node, config_write_ns);
281 install_default(NS_NODE);
282 install_element(NS_NODE, &cfg_nse_nsvci_cmd);
283 install_element(NS_NODE, &cfg_nse_remoteip_cmd);
284 install_element(NS_NODE, &cfg_nse_remoteport_cmd);
285 install_element(NS_NODE, &cfg_nse_remoterole_cmd);
286 install_element(NS_NODE, &cfg_no_nse_cmd);
287 install_element(NS_NODE, &cfg_ns_timer_cmd);
288
289 return 0;
290}