]> git.proxmox.com Git - mirror_frr.git/blob - babeld/babel_zebra.c
vtysh: return non-zero for configuration failures
[mirror_frr.git] / babeld / babel_zebra.c
1 /*
2 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22
23 /* FRR's includes */
24 #include <zebra.h>
25 #include "command.h"
26 #include "zclient.h"
27 #include "stream.h"
28
29 /* babel's includes*/
30 #include "babel_zebra.h"
31 #include "babel_interface.h"
32 #include "xroute.h"
33 #include "util.h"
34
35 void babelz_zebra_init(void);
36
37
38 /* we must use a pointer because of zclient.c's functions (new, free). */
39 struct zclient *zclient;
40 static int zebra_config_write (struct vty *vty);
41
42 /* Debug types */
43 static struct {
44 int type;
45 int str_min_len;
46 const char *str;
47 } debug_type[] = {
48 {BABEL_DEBUG_COMMON, 1, "common"},
49 {BABEL_DEBUG_KERNEL, 1, "kernel"},
50 {BABEL_DEBUG_FILTER, 1, "filter"},
51 {BABEL_DEBUG_TIMEOUT, 1, "timeout"},
52 {BABEL_DEBUG_IF, 1, "interface"},
53 {BABEL_DEBUG_ROUTE, 1, "route"},
54 {BABEL_DEBUG_ALL, 1, "all"},
55 {0, 0, NULL}
56 };
57
58 static struct {
59 int str_min_len;
60 const char *str;
61 } proto_redistnum_type[ZEBRA_ROUTE_MAX] = {
62 [ZEBRA_ROUTE_BABEL] = {2, "babel"},
63 [ZEBRA_ROUTE_BGP] = {2, "bgp"},
64 [ZEBRA_ROUTE_CONNECT] = {1, "connected"},
65 [ZEBRA_ROUTE_HSLS] = {1, "hsls"},
66 [ZEBRA_ROUTE_ISIS] = {1, "isis"},
67 [ZEBRA_ROUTE_KERNEL] = {1, "kernel"},
68 [ZEBRA_ROUTE_OLSR] = {2, "olsr"},
69 [ZEBRA_ROUTE_OSPF] = {2, "ospf"},
70 [ZEBRA_ROUTE_OSPF6] = {5, "ospf6"},
71 [ZEBRA_ROUTE_RIP] = {1, "rip"},
72 [ZEBRA_ROUTE_RIPNG] = {4, "ripng"},
73 [ZEBRA_ROUTE_STATIC] = {2, "static"},
74 [ZEBRA_ROUTE_SYSTEM] = {2, "system"},
75 };
76
77 /* Zebra node structure. */
78 struct cmd_node zebra_node =
79 {
80 ZEBRA_NODE,
81 "%s(config-router)# ",
82 1 /* vtysh? yes */
83 };
84
85
86 /* Zebra route add and delete treatment (ipv6). */
87 static int
88 babel_zebra_read_ipv6 (int command, struct zclient *zclient,
89 zebra_size_t length, vrf_id_t vrf)
90 {
91 struct stream *s;
92 struct zapi_ipv6 api;
93 unsigned long ifindex = -1;
94 struct in6_addr nexthop;
95 struct prefix_ipv6 prefix;
96
97 s = zclient->ibuf;
98 ifindex = 0;
99 memset (&nexthop, 0, sizeof (struct in6_addr));
100 memset (&api, 0, sizeof(struct zapi_ipv6));
101 memset (&prefix, 0, sizeof (struct prefix_ipv6));
102
103 /* Type, flags, message. */
104 api.type = stream_getc (s);
105 api.instance = stream_getw (s);
106 api.flags = stream_getl (s);
107 api.message = stream_getc (s);
108
109 /* IPv6 prefix. */
110 prefix.family = AF_INET6;
111 prefix.prefixlen = stream_getc (s);
112 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
113
114 /* Nexthop, ifindex, distance, metric. */
115 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
116 api.nexthop_num = stream_getc (s);
117 stream_get (&nexthop, s, sizeof(nexthop));
118 }
119 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
120 api.ifindex_num = stream_getc (s);
121 ifindex = stream_getl (s);
122 }
123 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
124 api.distance = stream_getc (s);
125 else
126 api.distance = 0;
127 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
128 api.metric = stream_getl (s);
129 else
130 api.metric = 0;
131
132 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
133 babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop);
134 else
135 babel_ipv6_route_delete(&api, &prefix, ifindex);
136
137 return 0;
138 }
139
140 static int
141 babel_zebra_read_ipv4 (int command, struct zclient *zclient,
142 zebra_size_t length, vrf_id_t vrf)
143 {
144 struct stream *s;
145 struct zapi_ipv4 api;
146 unsigned long ifindex = -1;
147 struct in_addr nexthop;
148 struct prefix_ipv4 prefix;
149
150 s = zclient->ibuf;
151 ifindex = 0;
152 memset (&nexthop, 0, sizeof (struct in_addr));
153 memset (&api, 0, sizeof(struct zapi_ipv4));
154 memset (&prefix, 0, sizeof (struct prefix_ipv4));
155
156 /* Type, flags, message. */
157 api.type = stream_getc (s);
158 api.instance = stream_getw (s);
159 api.flags = stream_getl (s);
160 api.message = stream_getc (s);
161
162 /* IPv6 prefix. */
163 prefix.family = AF_INET;
164 prefix.prefixlen = stream_getc (s);
165 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
166
167 /* Nexthop, ifindex, distance, metric. */
168 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
169 api.nexthop_num = stream_getc (s);
170 stream_get (&nexthop, s, sizeof(nexthop));
171 }
172 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
173 api.ifindex_num = stream_getc (s);
174 ifindex = stream_getl (s);
175 }
176 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
177 api.distance = stream_getc (s);
178 else
179 api.distance = 0;
180 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
181 api.metric = stream_getl (s);
182 else
183 api.metric = 0;
184
185 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) {
186 babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop);
187 } else {
188 babel_ipv4_route_delete(&api, &prefix, ifindex);
189 }
190
191 return 0;
192 }
193
194 static int
195 babel_proto_redistnum(const char *s)
196 {
197 int i;
198 if (! s)
199 return -1;
200 int len = strlen(s);
201
202 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
203 if (len <= (int)strlen(proto_redistnum_type[i].str) &&
204 strncmp(proto_redistnum_type[i].str, s,
205 proto_redistnum_type[i].str_min_len) == 0) {
206 return i;
207 }
208 }
209
210 return -1;
211 }
212
213 /* [Babel Command] */
214 DEFUN (babel_redistribute_type,
215 babel_redistribute_type_cmd,
216 "redistribute " FRR_REDIST_STR_BABELD,
217 "Redistribute\n"
218 FRR_REDIST_HELP_STR_BABELD)
219 {
220 int type;
221
222 type = babel_proto_redistnum(argv[1]->arg);
223
224 if (type < 0) {
225 vty_outln (vty, "Invalid type %s", argv[1]->arg);
226 return CMD_WARNING_CONFIG_FAILED;
227 }
228
229 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, VRF_DEFAULT);
230 return CMD_SUCCESS;
231 }
232
233 /* [Babel Command] */
234 DEFUN (no_babel_redistribute_type,
235 no_babel_redistribute_type_cmd,
236 "no redistribute " FRR_REDIST_STR_BABELD,
237 NO_STR
238 "Redistribute\n"
239 FRR_REDIST_HELP_STR_BABELD)
240 {
241 int type;
242
243 type = babel_proto_redistnum(argv[2]->arg);
244
245 if (type < 0) {
246 vty_outln (vty, "Invalid type %s", argv[2]->arg);
247 return CMD_WARNING_CONFIG_FAILED;
248 }
249
250 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
251 /* perhaps should we remove xroutes having the same type... */
252 return CMD_SUCCESS;
253 }
254
255 #ifndef NO_DEBUG
256 /* [Babel Command] */
257 DEFUN (debug_babel,
258 debug_babel_cmd,
259 "debug babel <common|kernel|filter|timeout|interface|route|all>",
260 "Enable debug messages for specific or all part.\n"
261 "Babel information\n"
262 "Common messages (default)\n"
263 "Kernel messages\n"
264 "Filter messages\n"
265 "Timeout messages\n"
266 "Interface messages\n"
267 "Route messages\n"
268 "All messages\n")
269 {
270 int i;
271
272 for(i = 0; debug_type[i].str != NULL; i++) {
273 if (strncmp (debug_type[i].str, argv[2]->arg,
274 debug_type[i].str_min_len) == 0) {
275 debug |= debug_type[i].type;
276 return CMD_SUCCESS;
277 }
278 }
279
280 vty_outln (vty, "Invalid type %s", argv[2]->arg);
281
282 return CMD_WARNING_CONFIG_FAILED;
283 }
284
285 /* [Babel Command] */
286 DEFUN (no_debug_babel,
287 no_debug_babel_cmd,
288 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
289 NO_STR
290 "Disable debug messages for specific or all part.\n"
291 "Babel information\n"
292 "Common messages (default)\n"
293 "Kernel messages\n"
294 "Filter messages\n"
295 "Timeout messages\n"
296 "Interface messages\n"
297 "Route messages\n"
298 "All messages\n")
299 {
300 int i;
301
302 for (i = 0; debug_type[i].str; i++) {
303 if (strncmp(debug_type[i].str, argv[3]->arg,
304 debug_type[i].str_min_len) == 0) {
305 debug &= ~debug_type[i].type;
306 return CMD_SUCCESS;
307 }
308 }
309
310 vty_outln (vty, "Invalid type %s", argv[3]->arg);
311
312 return CMD_WARNING_CONFIG_FAILED;
313 }
314 #endif /* NO_DEBUG */
315
316 /* Output "debug" statement lines, if necessary. */
317 int
318 debug_babel_config_write (struct vty * vty)
319 {
320 #ifdef NO_DEBUG
321 return 0;
322 #else
323 int i, lines = 0;
324
325 if (debug == BABEL_DEBUG_ALL)
326 {
327 vty_outln (vty, "debug babel all");
328 lines++;
329 }
330 else
331 for (i = 0; debug_type[i].str != NULL; i++)
332 if
333 (
334 debug_type[i].type != BABEL_DEBUG_ALL
335 && CHECK_FLAG (debug, debug_type[i].type)
336 )
337 {
338 vty_outln (vty, "debug babel %s", debug_type[i].str);
339 lines++;
340 }
341 if (lines)
342 {
343 vty_outln (vty, "!");
344 lines++;
345 }
346 return lines;
347 #endif /* NO_DEBUG */
348 }
349
350 static void
351 babel_zebra_connected (struct zclient *zclient)
352 {
353 zclient_send_reg_requests (zclient, VRF_DEFAULT);
354 }
355
356 void babelz_zebra_init(void)
357 {
358 zclient = zclient_new(master);
359 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
360
361 zclient->zebra_connected = babel_zebra_connected;
362 zclient->interface_add = babel_interface_add;
363 zclient->interface_delete = babel_interface_delete;
364 zclient->interface_up = babel_interface_up;
365 zclient->interface_down = babel_interface_down;
366 zclient->interface_address_add = babel_interface_address_add;
367 zclient->interface_address_delete = babel_interface_address_delete;
368 zclient->redistribute_route_ipv4_add = babel_zebra_read_ipv4;
369 zclient->redistribute_route_ipv4_del = babel_zebra_read_ipv4;
370 zclient->redistribute_route_ipv6_add = babel_zebra_read_ipv6;
371 zclient->redistribute_route_ipv6_del = babel_zebra_read_ipv6;
372
373 install_node (&zebra_node, zebra_config_write);
374 install_element(BABEL_NODE, &babel_redistribute_type_cmd);
375 install_element(BABEL_NODE, &no_babel_redistribute_type_cmd);
376 install_element(ENABLE_NODE, &debug_babel_cmd);
377 install_element(ENABLE_NODE, &no_debug_babel_cmd);
378 install_element(CONFIG_NODE, &debug_babel_cmd);
379 install_element(CONFIG_NODE, &no_debug_babel_cmd);
380 }
381
382 static int
383 zebra_config_write (struct vty *vty)
384 {
385 if (! zclient->enable)
386 {
387 vty_outln (vty, "no router zebra");
388 return 1;
389 }
390 else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT))
391 {
392 vty_outln (vty, "router zebra");
393 vty_outln (vty, " no redistribute babel");
394 return 1;
395 }
396 return 0;
397 }
398
399 void
400 babel_zebra_close_connexion(void)
401 {
402 zclient_stop(zclient);
403 zclient_free(zclient);
404 }