]> git.proxmox.com Git - mirror_frr.git/blame - ripngd/ripng_zebra.c
Patch from Cougar - sort iflist by name.
[mirror_frr.git] / ripngd / ripng_zebra.c
CommitLineData
718e3744 1/*
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\f
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)
a94434b6 136 ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
718e3744 137 else
a94434b6 138 ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
718e3744 139
140 return 0;
141}
142
a94434b6 143void
144ripng_zclient_reset ()
145{
146 zclient_reset (zclient);
147}
148
718e3744 149int
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
a94434b6 165int
166ripng_redistribute_check (int type)
167{
168 return (zclient->redist[type]);
169}
170
718e3744 171void
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
a94434b6 178int
718e3744 179ripng_redistribute_metric_unset (int type)
180{
181 ripng->route_map[type].metric_config = 0;
182 ripng->route_map[type].metric = 0;
a94434b6 183 return 0;
718e3744 184}
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}
718e3744 205\f
a94434b6 206/* 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
718e3744 241DEFUN (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
a94434b6 286DEFUN (ripng_redistribute_type,
287 ripng_redistribute_type_cmd,
288 "redistribute (kernel|connected|static|ospf6|bgp)",
718e3744 289 "Redistribute information from another routing protocol\n"
a94434b6 290 "Kernel routes\n"
291 "Connected\n"
292 "Static routes\n"
293 "Open Shortest Path First (OSPFv3)\n"
294 "Border Gateway Protocol (BGP)\n")
718e3744 295{
a94434b6 296 int i;
718e3744 297
a94434b6 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 }
718e3744 307
a94434b6 308 vty_out(vty, "Invalid type %s%s", argv[0],
309 VTY_NEWLINE);
718e3744 310
a94434b6 311 return CMD_WARNING;
718e3744 312}
313
a94434b6 314DEFUN (no_ripng_redistribute_type,
315 no_ripng_redistribute_type_cmd,
316 "no redistribute (kernel|connected|static|ospf6|bgp)",
718e3744 317 NO_STR
318 "Redistribute information from another routing protocol\n"
a94434b6 319 "Kernel routes\n"
320 "Connected\n"
321 "Static routes\n"
322 "Open Shortest Path First (OSPFv3)\n"
718e3744 323 "Border Gateway Protocol (BGP)\n")
324{
a94434b6 325 int i;
718e3744 326
a94434b6 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 }
718e3744 337
a94434b6 338 vty_out(vty, "Invalid type %s%s", argv[0],
339 VTY_NEWLINE);
718e3744 340
a94434b6 341 return CMD_WARNING;
718e3744 342}
343
718e3744 344
a94434b6 345DEFUN (ripng_redistribute_type_metric,
346 ripng_redistribute_type_metric_cmd,
347 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
718e3744 348 "Redistribute information from another routing protocol\n"
349 "Kernel routes\n"
718e3744 350 "Connected\n"
718e3744 351 "Static routes\n"
a94434b6 352 "Open Shortest Path First (OSPFv3)\n"
353 "Border Gateway Protocol (BGP)\n"
718e3744 354 "Metric\n"
355 "Metric value\n")
356{
a94434b6 357 int i;
358 int metric;
718e3744 359
a94434b6 360 metric = atoi (argv[1]);
718e3744 361
a94434b6 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 }
718e3744 371
a94434b6 372 vty_out(vty, "Invalid type %s%s", argv[0],
373 VTY_NEWLINE);
718e3744 374
a94434b6 375 return CMD_WARNING;
718e3744 376}
377
a94434b6 378ALIAS (no_ripng_redistribute_type,
379 no_ripng_redistribute_type_metric_cmd,
380 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
718e3744 381 NO_STR
382 "Redistribute information from another routing protocol\n"
a94434b6 383 "Kernel routes\n"
384 "Connected\n"
385 "Static routes\n"
386 "Open Shortest Path First (OSPFv3)\n"
718e3744 387 "Border Gateway Protocol (BGP)\n"
388 "Metric\n"
389 "Metric value\n")
390
a94434b6 391DEFUN (ripng_redistribute_type_routemap,
392 ripng_redistribute_type_routemap_cmd,
393 "redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
718e3744 394 "Redistribute information from another routing protocol\n"
395 "Kernel routes\n"
718e3744 396 "Connected\n"
718e3744 397 "Static routes\n"
a94434b6 398 "Open Shortest Path First (OSPFv3)\n"
718e3744 399 "Border Gateway Protocol (BGP)\n"
400 "Route map reference\n"
401 "Pointer to route-map entries\n")
402{
a94434b6 403 int i;
718e3744 404
a94434b6 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 }
718e3744 414
a94434b6 415 vty_out(vty, "Invalid type %s%s", argv[0],
416 VTY_NEWLINE);
417
418 return CMD_WARNING;
718e3744 419}
420
a94434b6 421ALIAS (no_ripng_redistribute_type,
422 no_ripng_redistribute_type_routemap_cmd,
423 "no redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
718e3744 424 NO_STR
425 "Redistribute information from another routing protocol\n"
426 "Kernel routes\n"
718e3744 427 "Connected\n"
a94434b6 428 "Static routes\n"
429 "Open Shortest Path First (OSPFv3)\n"
430 "Border Gateway Protocol (BGP)\n"
718e3744 431 "Route map reference\n"
432 "Pointer to route-map entries\n")
718e3744 433
a94434b6 434DEFUN (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",
718e3744 437 "Redistribute information from another routing protocol\n"
a94434b6 438 "Kernel routes\n"
718e3744 439 "Connected\n"
718e3744 440 "Static routes\n"
a94434b6 441 "Open Shortest Path First (OSPFv3)\n"
442 "Border Gateway Protocol (BGP)\n"
718e3744 443 "Metric\n"
444 "Metric value\n"
445 "Route map reference\n"
446 "Pointer to route-map entries\n")
447{
a94434b6 448 int i;
449 int metric;
718e3744 450
a94434b6 451 metric = atoi (argv[1]);
718e3744 452
a94434b6 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 }
718e3744 463
a94434b6 464 vty_out(vty, "Invalid type %s%s", argv[0],
465 VTY_NEWLINE);
718e3744 466
a94434b6 467 return CMD_WARNING;
718e3744 468}
469
a94434b6 470ALIAS (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",
718e3744 473 NO_STR
474 "Redistribute information from another routing protocol\n"
a94434b6 475 "Kernel routes\n"
476 "Connected\n"
477 "Static routes\n"
478 "Open Shortest Path First (OSPFv3)\n"
718e3744 479 "Border Gateway Protocol (BGP)\n"
718e3744 480 "Route map reference\n"
481 "Pointer to route-map entries\n")
482
483void
a94434b6 484ripng_redistribute_write (struct vty *vty, int config_mode)
718e3744 485{
486 int i;
487 char *str[] = { "system", "kernel", "connected", "static", "rip",
488 "ripng", "ospf", "ospf6", "bgp"};
489
490 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
491 if (i != zclient->redist_default && zclient->redist[i])
492 {
a94434b6 493 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]);
718e3744 516 }
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);
a94434b6 570
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);
718e3744 580}