[lib] CID #39, fix leak in error path, vty_describe_command
[jleu-quagga.git] / ripngd / ripng_zebra.c
blob1f9bee0c87831611b475f8572e9307923b422d75
1 /*
2 * RIPngd and zebra interface.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
23 #include <zebra.h>
25 #include "command.h"
26 #include "prefix.h"
27 #include "stream.h"
28 #include "routemap.h"
29 #include "zclient.h"
30 #include "log.h"
32 #include "ripngd/ripngd.h"
34 /* All information about zebra. */
35 struct zclient *zclient = NULL;
37 /* Callback prototypes for zebra client service. */
38 int ripng_interface_up (int, struct zclient *, zebra_size_t);
39 int ripng_interface_down (int, struct zclient *, zebra_size_t);
40 int ripng_interface_add (int, struct zclient *, zebra_size_t);
41 int ripng_interface_delete (int, struct zclient *, zebra_size_t);
42 int ripng_interface_address_add (int, struct zclient *, zebra_size_t);
43 int ripng_interface_address_delete (int, struct zclient *, zebra_size_t);
45 void
46 ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
47 unsigned int ifindex, u_char metric)
49 struct zapi_ipv6 api;
51 if (zclient->redist[ZEBRA_ROUTE_RIPNG])
53 api.type = ZEBRA_ROUTE_RIPNG;
54 api.flags = 0;
55 api.message = 0;
56 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
57 api.nexthop_num = 1;
58 api.nexthop = &nexthop;
59 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
60 api.ifindex_num = 1;
61 api.ifindex = &ifindex;
62 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
63 api.metric = metric;
65 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
69 void
70 ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
71 unsigned int ifindex)
73 struct zapi_ipv6 api;
75 if (zclient->redist[ZEBRA_ROUTE_RIPNG])
77 api.type = ZEBRA_ROUTE_RIPNG;
78 api.flags = 0;
79 api.message = 0;
80 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
81 api.nexthop_num = 1;
82 api.nexthop = &nexthop;
83 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
84 api.ifindex_num = 1;
85 api.ifindex = &ifindex;
87 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
91 /* Zebra route add and delete treatment. */
92 int
93 ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
94 zebra_size_t length)
96 struct stream *s;
97 struct zapi_ipv6 api;
98 unsigned long ifindex;
99 struct in6_addr nexthop;
100 struct prefix_ipv6 p;
102 s = zclient->ibuf;
103 ifindex = 0;
104 memset (&nexthop, 0, sizeof (struct in6_addr));
106 /* Type, flags, message. */
107 api.type = stream_getc (s);
108 api.flags = stream_getc (s);
109 api.message = stream_getc (s);
111 /* IPv6 prefix. */
112 memset (&p, 0, sizeof (struct prefix_ipv6));
113 p.family = AF_INET6;
114 p.prefixlen = stream_getc (s);
115 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
117 /* Nexthop, ifindex, distance, metric. */
118 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
120 api.nexthop_num = stream_getc (s);
121 stream_get (&nexthop, s, 16);
123 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
125 api.ifindex_num = stream_getc (s);
126 ifindex = stream_getl (s);
128 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
129 api.distance = stream_getc (s);
130 else
131 api.distance = 0;
132 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
133 api.metric = stream_getl (s);
134 else
135 api.metric = 0;
137 if (command == ZEBRA_IPV6_ROUTE_ADD)
138 ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
139 else
140 ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
142 return 0;
145 void
146 ripng_zclient_reset ()
148 zclient_reset (zclient);
152 ripng_redistribute_unset (int type)
154 if (! zclient->redist[type])
155 return CMD_SUCCESS;
157 zclient->redist[type] = 0;
159 if (zclient->sock > 0)
160 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
162 ripng_redistribute_withdraw (type);
164 return CMD_SUCCESS;
168 ripng_redistribute_check (int type)
170 return (zclient->redist[type]);
173 void
174 ripng_redistribute_metric_set (int type, int metric)
176 ripng->route_map[type].metric_config = 1;
177 ripng->route_map[type].metric = metric;
181 ripng_redistribute_metric_unset (int type)
183 ripng->route_map[type].metric_config = 0;
184 ripng->route_map[type].metric = 0;
185 return 0;
188 void
189 ripng_redistribute_routemap_set (int type, const char *name)
191 if (ripng->route_map[type].name)
192 free (ripng->route_map[type].name);
194 ripng->route_map[type].name = strdup (name);
195 ripng->route_map[type].map = route_map_lookup_by_name (name);
198 void
199 ripng_redistribute_routemap_unset (int type)
201 if (ripng->route_map[type].name)
202 free (ripng->route_map[type].name);
204 ripng->route_map[type].name = NULL;
205 ripng->route_map[type].map = NULL;
208 /* Redistribution types */
209 static struct {
210 int type;
211 int str_min_len;
212 const char *str;
213 } redist_type[] = {
214 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
215 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
216 {ZEBRA_ROUTE_STATIC, 1, "static"},
217 {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
218 {ZEBRA_ROUTE_BGP, 1, "bgp"},
219 {0, 0, NULL}
222 void
223 ripng_redistribute_clean ()
225 int i;
227 for (i = 0; redist_type[i].str; i++)
229 if (zclient->redist[redist_type[i].type])
231 if (zclient->sock > 0)
232 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
233 zclient, redist_type[i].type);
235 zclient->redist[redist_type[i].type] = 0;
237 /* Remove the routes from RIPng table. */
238 ripng_redistribute_withdraw (redist_type[i].type);
243 DEFUN (router_zebra,
244 router_zebra_cmd,
245 "router zebra",
246 "Enable a routing process\n"
247 "Make connection to zebra daemon\n")
249 vty->node = ZEBRA_NODE;
250 zclient->enable = 1;
251 zclient_start (zclient);
252 return CMD_SUCCESS;
255 DEFUN (no_router_zebra,
256 no_router_zebra_cmd,
257 "no router zebra",
258 NO_STR
259 "Disable a routing process\n"
260 "Stop connection to zebra daemon\n")
262 zclient->enable = 0;
263 zclient_stop (zclient);
264 return CMD_SUCCESS;
267 DEFUN (ripng_redistribute_ripng,
268 ripng_redistribute_ripng_cmd,
269 "redistribute ripng",
270 "Redistribute information from another routing protocol\n"
271 "RIPng route\n")
273 zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
274 return CMD_SUCCESS;
277 DEFUN (no_ripng_redistribute_ripng,
278 no_ripng_redistribute_ripng_cmd,
279 "no redistribute ripng",
280 NO_STR
281 "Redistribute information from another routing protocol\n"
282 "RIPng route\n")
284 zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
285 return CMD_SUCCESS;
288 DEFUN (ripng_redistribute_type,
289 ripng_redistribute_type_cmd,
290 "redistribute (kernel|connected|static|ospf6|bgp)",
291 "Redistribute information from another routing protocol\n"
292 "Kernel routes\n"
293 "Connected\n"
294 "Static routes\n"
295 "Open Shortest Path First (OSPFv3)\n"
296 "Border Gateway Protocol (BGP)\n")
298 int i;
300 for(i = 0; redist_type[i].str; i++)
302 if (strncmp (redist_type[i].str, argv[0],
303 redist_type[i].str_min_len) == 0)
305 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
306 return CMD_SUCCESS;
310 vty_out(vty, "Invalid type %s%s", argv[0],
311 VTY_NEWLINE);
313 return CMD_WARNING;
316 DEFUN (no_ripng_redistribute_type,
317 no_ripng_redistribute_type_cmd,
318 "no redistribute (kernel|connected|static|ospf6|bgp)",
319 NO_STR
320 "Redistribute information from another routing protocol\n"
321 "Kernel routes\n"
322 "Connected\n"
323 "Static routes\n"
324 "Open Shortest Path First (OSPFv3)\n"
325 "Border Gateway Protocol (BGP)\n")
327 int i;
329 for (i = 0; redist_type[i].str; i++)
331 if (strncmp(redist_type[i].str, argv[0],
332 redist_type[i].str_min_len) == 0)
334 ripng_redistribute_metric_unset (redist_type[i].type);
335 ripng_redistribute_routemap_unset (redist_type[i].type);
336 return ripng_redistribute_unset (redist_type[i].type);
340 vty_out(vty, "Invalid type %s%s", argv[0],
341 VTY_NEWLINE);
343 return CMD_WARNING;
347 DEFUN (ripng_redistribute_type_metric,
348 ripng_redistribute_type_metric_cmd,
349 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
350 "Redistribute information from another routing protocol\n"
351 "Kernel routes\n"
352 "Connected\n"
353 "Static routes\n"
354 "Open Shortest Path First (OSPFv3)\n"
355 "Border Gateway Protocol (BGP)\n"
356 "Metric\n"
357 "Metric value\n")
359 int i;
360 int metric;
362 metric = atoi (argv[1]);
364 for (i = 0; redist_type[i].str; i++) {
365 if (strncmp(redist_type[i].str, argv[0],
366 redist_type[i].str_min_len) == 0)
368 ripng_redistribute_metric_set (redist_type[i].type, metric);
369 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
370 return CMD_SUCCESS;
374 vty_out(vty, "Invalid type %s%s", argv[0],
375 VTY_NEWLINE);
377 return CMD_WARNING;
380 ALIAS (no_ripng_redistribute_type,
381 no_ripng_redistribute_type_metric_cmd,
382 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
383 NO_STR
384 "Redistribute information from another routing protocol\n"
385 "Kernel routes\n"
386 "Connected\n"
387 "Static routes\n"
388 "Open Shortest Path First (OSPFv3)\n"
389 "Border Gateway Protocol (BGP)\n"
390 "Metric\n"
391 "Metric value\n")
393 DEFUN (ripng_redistribute_type_routemap,
394 ripng_redistribute_type_routemap_cmd,
395 "redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
396 "Redistribute information from another routing protocol\n"
397 "Kernel routes\n"
398 "Connected\n"
399 "Static routes\n"
400 "Open Shortest Path First (OSPFv3)\n"
401 "Border Gateway Protocol (BGP)\n"
402 "Route map reference\n"
403 "Pointer to route-map entries\n")
405 int i;
407 for (i = 0; redist_type[i].str; i++) {
408 if (strncmp(redist_type[i].str, argv[0],
409 redist_type[i].str_min_len) == 0)
411 ripng_redistribute_routemap_set (redist_type[i].type, argv[1]);
412 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
413 return CMD_SUCCESS;
417 vty_out(vty, "Invalid type %s%s", argv[0],
418 VTY_NEWLINE);
420 return CMD_WARNING;
423 ALIAS (no_ripng_redistribute_type,
424 no_ripng_redistribute_type_routemap_cmd,
425 "no redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
426 NO_STR
427 "Redistribute information from another routing protocol\n"
428 "Kernel routes\n"
429 "Connected\n"
430 "Static routes\n"
431 "Open Shortest Path First (OSPFv3)\n"
432 "Border Gateway Protocol (BGP)\n"
433 "Route map reference\n"
434 "Pointer to route-map entries\n")
436 DEFUN (ripng_redistribute_type_metric_routemap,
437 ripng_redistribute_type_metric_routemap_cmd,
438 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
439 "Redistribute information from another routing protocol\n"
440 "Kernel routes\n"
441 "Connected\n"
442 "Static routes\n"
443 "Open Shortest Path First (OSPFv3)\n"
444 "Border Gateway Protocol (BGP)\n"
445 "Metric\n"
446 "Metric value\n"
447 "Route map reference\n"
448 "Pointer to route-map entries\n")
450 int i;
451 int metric;
453 metric = atoi (argv[1]);
455 for (i = 0; redist_type[i].str; i++) {
456 if (strncmp(redist_type[i].str, argv[0],
457 redist_type[i].str_min_len) == 0)
459 ripng_redistribute_metric_set (redist_type[i].type, metric);
460 ripng_redistribute_routemap_set (redist_type[i].type, argv[2]);
461 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
462 return CMD_SUCCESS;
466 vty_out(vty, "Invalid type %s%s", argv[0],
467 VTY_NEWLINE);
469 return CMD_WARNING;
472 ALIAS (no_ripng_redistribute_type,
473 no_ripng_redistribute_type_metric_routemap_cmd,
474 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
475 NO_STR
476 "Redistribute information from another routing protocol\n"
477 "Kernel routes\n"
478 "Connected\n"
479 "Static routes\n"
480 "Open Shortest Path First (OSPFv3)\n"
481 "Border Gateway Protocol (BGP)\n"
482 "Route map reference\n"
483 "Pointer to route-map entries\n")
485 void
486 ripng_redistribute_write (struct vty *vty, int config_mode)
488 int i;
490 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
491 if (i != zclient->redist_default && zclient->redist[i])
493 if (config_mode)
495 if (ripng->route_map[i].metric_config)
497 if (ripng->route_map[i].name)
498 vty_out (vty, " redistribute %s metric %d route-map %s%s",
499 zebra_route_string(i), ripng->route_map[i].metric,
500 ripng->route_map[i].name, VTY_NEWLINE);
501 else
502 vty_out (vty, " redistribute %s metric %d%s",
503 zebra_route_string(i), ripng->route_map[i].metric,
504 VTY_NEWLINE);
506 else
508 if (ripng->route_map[i].name)
509 vty_out (vty, " redistribute %s route-map %s%s",
510 zebra_route_string(i), ripng->route_map[i].name,
511 VTY_NEWLINE);
512 else
513 vty_out (vty, " redistribute %s%s", zebra_route_string(i),
514 VTY_NEWLINE);
517 else
518 vty_out (vty, " %s", zebra_route_string(i));
522 /* RIPng configuration write function. */
524 zebra_config_write (struct vty *vty)
526 if (! zclient->enable)
528 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
529 return 1;
531 else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
533 vty_out (vty, "router zebra%s", VTY_NEWLINE);
534 vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
535 return 1;
537 return 0;
540 /* Zebra node structure. */
541 struct cmd_node zebra_node =
543 ZEBRA_NODE,
544 "%s(config-router)# ",
547 /* Initialize zebra structure and it's commands. */
548 void
549 zebra_init ()
551 /* Allocate zebra structure. */
552 zclient = zclient_new ();
553 zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
555 zclient->interface_up = ripng_interface_up;
556 zclient->interface_down = ripng_interface_down;
557 zclient->interface_add = ripng_interface_add;
558 zclient->interface_delete = ripng_interface_delete;
559 zclient->interface_address_add = ripng_interface_address_add;
560 zclient->interface_address_delete = ripng_interface_address_delete;
561 zclient->ipv6_route_add = ripng_zebra_read_ipv6;
562 zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
564 /* Install zebra node. */
565 install_node (&zebra_node, zebra_config_write);
567 /* Install command element for zebra node. */
568 install_element (CONFIG_NODE, &router_zebra_cmd);
569 install_element (CONFIG_NODE, &no_router_zebra_cmd);
570 install_default (ZEBRA_NODE);
571 install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
572 install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
574 /* Install command elements to ripng node */
575 install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
576 install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
577 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
578 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
579 install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
580 install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
581 install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
582 install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);