blob: 6e98e44d6acdd41f57cdccc942911692f9050847 [file] [log] [blame]
Harald Weltef2b4cd72010-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
107DEFUN(show_ns, show_ns_cmd, "show ns",
108 SHOW_STR "Display information about the NS protocol")
109{
110 struct gprs_ns_inst *nsi = vty_nsi;
111 struct gprs_nsvc *nsvc;
112
113 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
114 vty_out(vty, "NSEI %5u, NS-VC %5u, Remote: %-4s, %5s %9s",
115 nsvc->nsei, nsvc->nsvci,
116 nsvc->remote_end_is_sgsn ? "SGSN" : "BSS",
117 nsvc->state & NSE_S_ALIVE ? "ALIVE" : "DEAD",
118 nsvc->state & NSE_S_BLOCKED ? "BLOCKED" : "UNBLOCKED");
119 if (nsvc->nsi->ll == GPRS_NS_LL_UDP)
120 vty_out(vty, ", %15s:%u",
121 inet_ntoa(nsvc->ip.bts_addr.sin_addr),
122 ntohs(nsvc->ip.bts_addr.sin_port));
123 vty_out(vty, "%s", VTY_NEWLINE);
124 vty_out_rate_ctr_group(vty, " ", nsvc->ctrg);
125 }
126
127 return CMD_SUCCESS;
128}
129
130
131#define NSE_CMD_STR "NS Entity\n" "NS Entity ID (NSEI)\n"
132
133DEFUN(cfg_nse_nsvc, cfg_nse_nsvci_cmd,
134 "nse <0-65535> nsvci <0-65534>",
135 NSE_CMD_STR
136 "NS Virtual Connection\n"
137 "NS Virtual Connection ID (NSVCI)\n"
138 )
139{
140 uint16_t nsei = atoi(argv[0]);
141 uint16_t nsvci = atoi(argv[1]);
142 struct gprs_nsvc *nsvc;
143
144 nsvc = nsvc_by_nsei(vty_nsi, nsei);
145 if (!nsvc) {
146 nsvc = nsvc_create(vty_nsi, nsvci);
147 nsvc->nsei = nsei;
148 }
149 nsvc->nsvci = nsvci;
150 /* All NSVCs that are explicitly configured by VTY are
151 * marked as persistent so we can write them to the config
152 * file at some later point */
153 nsvc->persistent = 1;
154
155 return CMD_SUCCESS;
156}
157
158DEFUN(cfg_nse_remoteip, cfg_nse_remoteip_cmd,
159 "nse <0-65535> remote-ip A.B.C.D",
160 NSE_CMD_STR
161 "Remote IP Address\n"
162 "Remote IP Address\n")
163{
164 uint16_t nsei = atoi(argv[0]);
165 struct gprs_nsvc *nsvc;
166
167 nsvc = nsvc_by_nsei(vty_nsi, nsei);
168 if (!nsvc) {
169 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
170 return CMD_WARNING;
171 }
172 inet_aton(argv[1], &nsvc->ip.bts_addr.sin_addr);
173
174 return CMD_SUCCESS;
175
176}
177
178DEFUN(cfg_nse_remoteport, cfg_nse_remoteport_cmd,
179 "nse <0-65535> remote-port <0-65535>",
180 NSE_CMD_STR
181 "Remote UDP Port\n"
182 "Remote UDP Port Number\n")
183{
184 uint16_t nsei = atoi(argv[0]);
185 uint16_t port = atoi(argv[1]);
186 struct gprs_nsvc *nsvc;
187
188 nsvc = nsvc_by_nsei(vty_nsi, nsei);
189 if (!nsvc) {
190 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
191 return CMD_WARNING;
192 }
193
194 nsvc->ip.bts_addr.sin_port = htons(port);
195
196 return CMD_SUCCESS;
197}
198
199DEFUN(cfg_nse_remoterole, cfg_nse_remoterole_cmd,
200 "nse <0-65535> remote-role (sgsn|bss)",
201 NSE_CMD_STR
202 "Remote NSE Role\n"
203 "Remote Peer is SGSN\n"
204 "Remote Peer is BSS\n")
205{
206 uint16_t nsei = atoi(argv[0]);
207 struct gprs_nsvc *nsvc;
208
209 nsvc = nsvc_by_nsei(vty_nsi, nsei);
210 if (!nsvc) {
211 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
212 return CMD_WARNING;
213 }
214
215 if (!strcmp(argv[1], "sgsn"))
216 nsvc->remote_end_is_sgsn = 1;
217 else
218 nsvc->remote_end_is_sgsn = 0;
219
220 return CMD_SUCCESS;
221}
222
223DEFUN(cfg_no_nse, cfg_no_nse_cmd,
224 "no nse <0-65535>",
225 "Delete NS Entity\n"
226 "Delete " NSE_CMD_STR)
227{
228 uint16_t nsei = atoi(argv[0]);
229 struct gprs_nsvc *nsvc;
230
231 nsvc = nsvc_by_nsei(vty_nsi, nsei);
232 if (!nsvc) {
233 vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
234 return CMD_WARNING;
235 }
236
237 nsvc_delete(nsvc);
238
239 return CMD_SUCCESS;
240}
241
242DEFUN(cfg_ns_timer, cfg_ns_timer_cmd,
243 "timer " NS_TIMERS " <0-65535>",
244 "Network Service Timer\n"
245 NS_TIMERS_HELP "Timer Value\n")
246{
247 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
248 int val = atoi(argv[1]);
249
250 if (idx < 0 || idx >= ARRAY_SIZE(vty_nsi->timeout))
251 return CMD_WARNING;
252
253 vty_nsi->timeout[idx] = val;
254
255 return CMD_SUCCESS;
256}
257
258int gprs_ns_vty_init(struct gprs_ns_inst *nsi)
259{
260 vty_nsi = nsi;
261
262 install_element_ve(&show_ns_cmd);
263
264 install_element(CONFIG_NODE, &cfg_ns_cmd);
265 install_node(&ns_node, config_write_ns);
266 install_default(NS_NODE);
267 install_element(NS_NODE, &cfg_nse_nsvci_cmd);
268 install_element(NS_NODE, &cfg_nse_remoteip_cmd);
269 install_element(NS_NODE, &cfg_nse_remoteport_cmd);
270 install_element(NS_NODE, &cfg_nse_remoterole_cmd);
271 install_element(NS_NODE, &cfg_no_nse_cmd);
272 install_element(NS_NODE, &cfg_ns_timer_cmd);
273
274 return 0;
275}