blob: de372dcb51a5a85513205ba3a6cb04830e091cd7 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * RIPngd and zebra interface.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
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.
11 *
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.
16 *
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.
21 */
22
23#include <zebra.h>
24
25#include "command.h"
26#include "prefix.h"
27#include "stream.h"
28#include "routemap.h"
29#include "zclient.h"
30#include "log.h"
31
32#include "ripngd/ripngd.h"
33
34/* All information about zebra. */
35struct zclient *zclient = NULL;
36
37/* Callback prototypes for zebra client service. */
38int ripng_interface_up (int, struct zclient *, zebra_size_t);
39int ripng_interface_down (int, struct zclient *, zebra_size_t);
40int ripng_interface_add (int, struct zclient *, zebra_size_t);
41int ripng_interface_delete (int, struct zclient *, zebra_size_t);
42int ripng_interface_address_add (int, struct zclient *, zebra_size_t);
43int ripng_interface_address_delete (int, struct zclient *, zebra_size_t);
44
45void
46ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
47 unsigned int ifindex)
48{
49 struct zapi_ipv6 api;
50
51 if (zclient->redist[ZEBRA_ROUTE_RIPNG])
52 {
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
63 zapi_ipv6_add (zclient, p, &api);
64 }
65}
66
67void
68ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
69 unsigned int ifindex)
70{
71 struct zapi_ipv6 api;
72
73 if (zclient->redist[ZEBRA_ROUTE_RIPNG])
74 {
75 api.type = ZEBRA_ROUTE_RIPNG;
76 api.flags = 0;
77 api.message = 0;
78 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
79 api.nexthop_num = 1;
80 api.nexthop = &nexthop;
81 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
82 api.ifindex_num = 1;
83 api.ifindex = &ifindex;
84
85 zapi_ipv6_delete (zclient, p, &api);
86 }
87}
88
89/* Zebra route add and delete treatment. */
90int
91ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
92 zebra_size_t length)
93{
94 struct stream *s;
95 struct zapi_ipv6 api;
96 unsigned long ifindex;
97 struct in6_addr nexthop;
98 struct prefix_ipv6 p;
99
100 s = zclient->ibuf;
101 ifindex = 0;
102 memset (&nexthop, 0, sizeof (struct in6_addr));
103
104 /* Type, flags, message. */
105 api.type = stream_getc (s);
106 api.flags = stream_getc (s);
107 api.message = stream_getc (s);
108
109 /* IPv6 prefix. */
110 memset (&p, 0, sizeof (struct prefix_ipv6));
111 p.family = AF_INET6;
112 p.prefixlen = stream_getc (s);
113 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
114
115 /* Nexthop, ifindex, distance, metric. */
116 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
117 {
118 api.nexthop_num = stream_getc (s);
119 stream_get (&nexthop, s, 16);
120 }
121 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
122 {
123 api.ifindex_num = stream_getc (s);
124 ifindex = stream_getl (s);
125 }
126 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
127 api.distance = stream_getc (s);
128 else
129 api.distance = 0;
130 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
131 api.metric = stream_getl (s);
132 else
133 api.metric = 0;
134
135 if (command == ZEBRA_IPV6_ROUTE_ADD)
hassoa94434b2003-05-25 17:10:12 +0000136 ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
paul718e3742002-12-13 20:15:29 +0000137 else
hassoa94434b2003-05-25 17:10:12 +0000138 ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
paul718e3742002-12-13 20:15:29 +0000139
140 return 0;
141}
142
hassoa94434b2003-05-25 17:10:12 +0000143void
144ripng_zclient_reset ()
145{
146 zclient_reset (zclient);
147}
148
paul718e3742002-12-13 20:15:29 +0000149int
150ripng_redistribute_unset (int type)
151{
152 if (! zclient->redist[type])
153 return CMD_SUCCESS;
154
155 zclient->redist[type] = 0;
156
157 if (zclient->sock > 0)
158 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
159
160 ripng_redistribute_withdraw (type);
161
162 return CMD_SUCCESS;
163}
164
hassoa94434b2003-05-25 17:10:12 +0000165int
166ripng_redistribute_check (int type)
167{
168 return (zclient->redist[type]);
169}
170
paul718e3742002-12-13 20:15:29 +0000171void
172ripng_redistribute_metric_set (int type, int metric)
173{
174 ripng->route_map[type].metric_config = 1;
175 ripng->route_map[type].metric = metric;
176}
177
hassoa94434b2003-05-25 17:10:12 +0000178int
paul718e3742002-12-13 20:15:29 +0000179ripng_redistribute_metric_unset (int type)
180{
181 ripng->route_map[type].metric_config = 0;
182 ripng->route_map[type].metric = 0;
hassoa94434b2003-05-25 17:10:12 +0000183 return 0;
paul718e3742002-12-13 20:15:29 +0000184}
185
186void
187ripng_redistribute_routemap_set (int type, char *name)
188{
189 if (ripng->route_map[type].name)
190 free (ripng->route_map[type].name);
191
192 ripng->route_map[type].name = strdup (name);
193 ripng->route_map[type].map = route_map_lookup_by_name (name);
194}
195
196void
197ripng_redistribute_routemap_unset (int type)
198{
199 if (ripng->route_map[type].name)
200 free (ripng->route_map[type].name);
201
202 ripng->route_map[type].name = NULL;
203 ripng->route_map[type].map = NULL;
204}
paul718e3742002-12-13 20:15:29 +0000205
hassoa94434b2003-05-25 17:10:12 +0000206/* Redistribution types */
207static struct {
208 int type;
209 int str_min_len;
210 char *str;
211} redist_type[] = {
212 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
213 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
214 {ZEBRA_ROUTE_STATIC, 1, "static"},
215 {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
216 {ZEBRA_ROUTE_BGP, 1, "bgp"},
217 {0, 0, NULL}
218};
219
220void
221ripng_redistribute_clean ()
222{
223 int i;
224
225 for (i = 0; redist_type[i].str; i++)
226 {
227 if (zclient->redist[redist_type[i].type])
228 {
229 if (zclient->sock > 0)
230 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
231 zclient->sock, redist_type[i].type);
232
233 zclient->redist[redist_type[i].type] = 0;
234
235 /* Remove the routes from RIPng table. */
236 ripng_redistribute_withdraw (redist_type[i].type);
237 }
238 }
239}
240
paul718e3742002-12-13 20:15:29 +0000241DEFUN (router_zebra,
242 router_zebra_cmd,
243 "router zebra",
244 "Enable a routing process\n"
245 "Make connection to zebra daemon\n")
246{
247 vty->node = ZEBRA_NODE;
248 zclient->enable = 1;
249 zclient_start (zclient);
250 return CMD_SUCCESS;
251}
252
253DEFUN (no_router_zebra,
254 no_router_zebra_cmd,
255 "no router zebra",
256 NO_STR
257 "Disable a routing process\n"
258 "Stop connection to zebra daemon\n")
259{
260 zclient->enable = 0;
261 zclient_stop (zclient);
262 return CMD_SUCCESS;
263}
264
265DEFUN (ripng_redistribute_ripng,
266 ripng_redistribute_ripng_cmd,
267 "redistribute ripng",
268 "Redistribute information from another routing protocol\n"
269 "RIPng route\n")
270{
271 zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
272 return CMD_SUCCESS;
273}
274
275DEFUN (no_ripng_redistribute_ripng,
276 no_ripng_redistribute_ripng_cmd,
277 "no redistribute ripng",
278 NO_STR
279 "Redistribute information from another routing protocol\n"
280 "RIPng route\n")
281{
282 zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
283 return CMD_SUCCESS;
284}
285
hassoa94434b2003-05-25 17:10:12 +0000286DEFUN (ripng_redistribute_type,
287 ripng_redistribute_type_cmd,
288 "redistribute (kernel|connected|static|ospf6|bgp)",
paul718e3742002-12-13 20:15:29 +0000289 "Redistribute information from another routing protocol\n"
hassoa94434b2003-05-25 17:10:12 +0000290 "Kernel routes\n"
291 "Connected\n"
292 "Static routes\n"
293 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000294 "Border Gateway Protocol (BGP)\n")
295{
hassoa94434b2003-05-25 17:10:12 +0000296 int i;
297
298 for(i = 0; redist_type[i].str; i++)
299 {
300 if (strncmp (redist_type[i].str, argv[0],
301 redist_type[i].str_min_len) == 0)
302 {
303 zclient_redistribute_set (zclient, redist_type[i].type);
304 return CMD_SUCCESS;
305 }
306 }
307
308 vty_out(vty, "Invalid type %s%s", argv[0],
309 VTY_NEWLINE);
310
311 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000312}
313
hassoa94434b2003-05-25 17:10:12 +0000314DEFUN (no_ripng_redistribute_type,
315 no_ripng_redistribute_type_cmd,
316 "no redistribute (kernel|connected|static|ospf6|bgp)",
paul718e3742002-12-13 20:15:29 +0000317 NO_STR
318 "Redistribute information from another routing protocol\n"
hassoa94434b2003-05-25 17:10:12 +0000319 "Kernel routes\n"
320 "Connected\n"
321 "Static routes\n"
322 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000323 "Border Gateway Protocol (BGP)\n")
324{
hassoa94434b2003-05-25 17:10:12 +0000325 int i;
326
327 for (i = 0; redist_type[i].str; i++)
328 {
329 if (strncmp(redist_type[i].str, argv[0],
330 redist_type[i].str_min_len) == 0)
331 {
332 ripng_redistribute_metric_unset (redist_type[i].type);
333 ripng_redistribute_routemap_unset (redist_type[i].type);
334 return ripng_redistribute_unset (redist_type[i].type);
335 }
336 }
337
338 vty_out(vty, "Invalid type %s%s", argv[0],
339 VTY_NEWLINE);
340
341 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000342}
343
paul718e3742002-12-13 20:15:29 +0000344
hassoa94434b2003-05-25 17:10:12 +0000345DEFUN (ripng_redistribute_type_metric,
346 ripng_redistribute_type_metric_cmd,
347 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
paul718e3742002-12-13 20:15:29 +0000348 "Redistribute information from another routing protocol\n"
349 "Kernel routes\n"
paul718e3742002-12-13 20:15:29 +0000350 "Connected\n"
paul718e3742002-12-13 20:15:29 +0000351 "Static routes\n"
hassoa94434b2003-05-25 17:10:12 +0000352 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000353 "Border Gateway Protocol (BGP)\n"
354 "Metric\n"
355 "Metric value\n")
356{
hassoa94434b2003-05-25 17:10:12 +0000357 int i;
358 int metric;
359
360 metric = atoi (argv[1]);
361
362 for (i = 0; redist_type[i].str; i++) {
363 if (strncmp(redist_type[i].str, argv[0],
364 redist_type[i].str_min_len) == 0)
365 {
366 ripng_redistribute_metric_set (redist_type[i].type, metric);
367 zclient_redistribute_set (zclient, redist_type[i].type);
368 return CMD_SUCCESS;
369 }
370 }
371
372 vty_out(vty, "Invalid type %s%s", argv[0],
373 VTY_NEWLINE);
374
375 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000376}
377
hassoa94434b2003-05-25 17:10:12 +0000378ALIAS (no_ripng_redistribute_type,
379 no_ripng_redistribute_type_metric_cmd,
380 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
paul718e3742002-12-13 20:15:29 +0000381 NO_STR
382 "Redistribute information from another routing protocol\n"
hassoa94434b2003-05-25 17:10:12 +0000383 "Kernel routes\n"
384 "Connected\n"
385 "Static routes\n"
386 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000387 "Border Gateway Protocol (BGP)\n"
388 "Metric\n"
389 "Metric value\n")
390
hassoa94434b2003-05-25 17:10:12 +0000391DEFUN (ripng_redistribute_type_routemap,
392 ripng_redistribute_type_routemap_cmd,
393 "redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
paul718e3742002-12-13 20:15:29 +0000394 "Redistribute information from another routing protocol\n"
395 "Kernel routes\n"
paul718e3742002-12-13 20:15:29 +0000396 "Connected\n"
paul718e3742002-12-13 20:15:29 +0000397 "Static routes\n"
hassoa94434b2003-05-25 17:10:12 +0000398 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000399 "Border Gateway Protocol (BGP)\n"
400 "Route map reference\n"
401 "Pointer to route-map entries\n")
402{
hassoa94434b2003-05-25 17:10:12 +0000403 int i;
404
405 for (i = 0; redist_type[i].str; i++) {
406 if (strncmp(redist_type[i].str, argv[0],
407 redist_type[i].str_min_len) == 0)
408 {
409 ripng_redistribute_routemap_set (redist_type[i].type, argv[1]);
410 zclient_redistribute_set (zclient, redist_type[i].type);
411 return CMD_SUCCESS;
412 }
413 }
414
415 vty_out(vty, "Invalid type %s%s", argv[0],
416 VTY_NEWLINE);
417
418 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000419}
420
hassoa94434b2003-05-25 17:10:12 +0000421ALIAS (no_ripng_redistribute_type,
422 no_ripng_redistribute_type_routemap_cmd,
423 "no redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
paul718e3742002-12-13 20:15:29 +0000424 NO_STR
425 "Redistribute information from another routing protocol\n"
hassoa94434b2003-05-25 17:10:12 +0000426 "Kernel routes\n"
427 "Connected\n"
428 "Static routes\n"
429 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000430 "Border Gateway Protocol (BGP)\n"
431 "Route map reference\n"
432 "Pointer to route-map entries\n")
433
hassoa94434b2003-05-25 17:10:12 +0000434DEFUN (ripng_redistribute_type_metric_routemap,
435 ripng_redistribute_type_metric_routemap_cmd,
436 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
paul718e3742002-12-13 20:15:29 +0000437 "Redistribute information from another routing protocol\n"
438 "Kernel routes\n"
paul718e3742002-12-13 20:15:29 +0000439 "Connected\n"
paul718e3742002-12-13 20:15:29 +0000440 "Static routes\n"
hassoa94434b2003-05-25 17:10:12 +0000441 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000442 "Border Gateway Protocol (BGP)\n"
443 "Metric\n"
444 "Metric value\n"
445 "Route map reference\n"
446 "Pointer to route-map entries\n")
447{
hassoa94434b2003-05-25 17:10:12 +0000448 int i;
449 int metric;
450
451 metric = atoi (argv[1]);
452
453 for (i = 0; redist_type[i].str; i++) {
454 if (strncmp(redist_type[i].str, argv[0],
455 redist_type[i].str_min_len) == 0)
456 {
457 ripng_redistribute_metric_set (redist_type[i].type, metric);
458 ripng_redistribute_routemap_set (redist_type[i].type, argv[2]);
459 zclient_redistribute_set (zclient, redist_type[i].type);
460 return CMD_SUCCESS;
461 }
462 }
463
464 vty_out(vty, "Invalid type %s%s", argv[0],
465 VTY_NEWLINE);
466
467 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000468}
469
hassoa94434b2003-05-25 17:10:12 +0000470ALIAS (no_ripng_redistribute_type,
471 no_ripng_redistribute_type_metric_routemap_cmd,
472 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
paul718e3742002-12-13 20:15:29 +0000473 NO_STR
474 "Redistribute information from another routing protocol\n"
hassoa94434b2003-05-25 17:10:12 +0000475 "Kernel routes\n"
476 "Connected\n"
477 "Static routes\n"
478 "Open Shortest Path First (OSPFv3)\n"
paul718e3742002-12-13 20:15:29 +0000479 "Border Gateway Protocol (BGP)\n"
paul718e3742002-12-13 20:15:29 +0000480 "Route map reference\n"
481 "Pointer to route-map entries\n")
482
483void
hassoa94434b2003-05-25 17:10:12 +0000484ripng_redistribute_write (struct vty *vty, int config_mode)
paul718e3742002-12-13 20:15:29 +0000485{
486 int i;
487 char *str[] = { "system", "kernel", "connected", "static", "rip",
hasso66e31692004-03-20 19:33:06 +0000488 "ripng", "ospf", "ospf6", "isis", "bgp"};
paul718e3742002-12-13 20:15:29 +0000489
490 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
491 if (i != zclient->redist_default && zclient->redist[i])
492 {
hassoa94434b2003-05-25 17:10:12 +0000493 if (config_mode)
494 {
495 if (ripng->route_map[i].metric_config)
496 {
497 if (ripng->route_map[i].name)
498 vty_out (vty, " redistribute %s metric %d route-map %s%s",
499 str[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 str[i], ripng->route_map[i].metric, VTY_NEWLINE);
504 }
505 else
506 {
507 if (ripng->route_map[i].name)
508 vty_out (vty, " redistribute %s route-map %s%s",
509 str[i], ripng->route_map[i].name, VTY_NEWLINE);
510 else
511 vty_out (vty, " redistribute %s%s", str[i], VTY_NEWLINE);
512 }
513 }
514 else
515 vty_out (vty, " %s", str[i]);
paul718e3742002-12-13 20:15:29 +0000516 }
517}
518
519/* RIPng configuration write function. */
520int
521zebra_config_write (struct vty *vty)
522{
523 if (! zclient->enable)
524 {
525 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
526 return 1;
527 }
528 else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
529 {
530 vty_out (vty, "router zebra%s", VTY_NEWLINE);
531 vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
532 return 1;
533 }
534 return 0;
535}
536
537/* Zebra node structure. */
538struct cmd_node zebra_node =
539{
540 ZEBRA_NODE,
541 "%s(config-router)# ",
542};
543
544/* Initialize zebra structure and it's commands. */
545void
546zebra_init ()
547{
548 /* Allocate zebra structure. */
549 zclient = zclient_new ();
550 zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
551
552 zclient->interface_up = ripng_interface_up;
553 zclient->interface_down = ripng_interface_down;
554 zclient->interface_add = ripng_interface_add;
555 zclient->interface_delete = ripng_interface_delete;
556 zclient->interface_address_add = ripng_interface_address_add;
557 zclient->interface_address_delete = ripng_interface_address_delete;
558 zclient->ipv6_route_add = ripng_zebra_read_ipv6;
559 zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
560
561 /* Install zebra node. */
562 install_node (&zebra_node, zebra_config_write);
563
564 /* Install command element for zebra node. */
565 install_element (CONFIG_NODE, &router_zebra_cmd);
566 install_element (CONFIG_NODE, &no_router_zebra_cmd);
567 install_default (ZEBRA_NODE);
568 install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
569 install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
hassoa94434b2003-05-25 17:10:12 +0000570
571 /* Install command elements to ripng node */
572 install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
573 install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
574 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
575 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
576 install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
577 install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
578 install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
579 install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
paul718e3742002-12-13 20:15:29 +0000580}