1 /* RIPd and zebra interface.
2 * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "ripd/ripd.h"
34 #include "ripd/rip_debug.h"
35 #include "ripd/rip_interface.h"
37 /* All information about zebra. */
38 struct zclient *zclient = NULL;
40 /* Send ECMP routes to zebra. */
42 rip_zebra_ipv4_send (struct route_node *rp, u_char cmd)
44 static struct in_addr **nexthops = NULL;
45 static unsigned int nexthops_len = 0;
47 struct list *list = (struct list *)rp->info;
49 struct listnode *listnode = NULL;
50 struct rip_info *rinfo = NULL;
53 if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
55 api.vrf_id = VRF_DEFAULT;
56 api.type = ZEBRA_ROUTE_RIP;
59 api.safi = SAFI_UNICAST;
61 if (nexthops_len < listcount (list))
63 nexthops_len = listcount (list);
64 nexthops = XREALLOC (MTYPE_TMP, nexthops,
65 nexthops_len * sizeof (struct in_addr *));
68 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
69 for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
71 nexthops[count++] = &rinfo->nexthop;
72 if (cmd == ZEBRA_IPV4_ROUTE_ADD)
73 SET_FLAG (rinfo->flags, RIP_RTF_FIB);
75 UNSET_FLAG (rinfo->flags, RIP_RTF_FIB);
78 api.nexthop = nexthops;
79 api.nexthop_num = count;
82 rinfo = listgetdata (listhead (list));
84 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
85 api.metric = rinfo->metric;
87 if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT)
89 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
90 api.distance = rinfo->distance;
95 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
99 zapi_ipv4_route (cmd, zclient,
100 (struct prefix_ipv4 *)&rp->p, &api);
102 if (IS_RIP_DEBUG_ZEBRA)
105 zlog_debug ("%s: %s/%d nexthops %d",
106 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
107 "Install into zebra" : "Delete from zebra",
108 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen, count);
110 zlog_debug ("%s: %s/%d",
111 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
112 "Install into zebra" : "Delete from zebra",
113 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
116 rip_global_route_changes++;
120 /* Add/update ECMP routes to zebra. */
122 rip_zebra_ipv4_add (struct route_node *rp)
124 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_ADD);
127 /* Delete ECMP routes from zebra. */
129 rip_zebra_ipv4_delete (struct route_node *rp)
131 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_DELETE);
134 /* Zebra route add and delete treatment. */
136 rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
140 struct zapi_ipv4 api;
141 unsigned long ifindex;
142 struct in_addr nexthop;
143 struct prefix_ipv4 p;
144 unsigned char plength = 0;
150 /* Type, flags, message. */
151 api.type = stream_getc (s);
152 api.flags = stream_getc (s);
153 api.message = stream_getc (s);
156 memset (&p, 0, sizeof (struct prefix_ipv4));
158 plength = stream_getc (s);
159 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
160 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
162 /* Nexthop, ifindex, distance, metric. */
163 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
165 api.nexthop_num = stream_getc (s);
166 nexthop.s_addr = stream_get_ipv4 (s);
168 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
170 api.ifindex_num = stream_getc (s);
171 ifindex = stream_getl (s);
173 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
174 api.distance = stream_getc (s);
177 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
178 api.metric = stream_getl (s);
182 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
183 api.tag = stream_getl (s);
187 /* Then fetch IPv4 prefixes. */
188 if (command == ZEBRA_IPV4_ROUTE_ADD)
189 rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
190 &nexthop, api.metric, api.distance, api.tag);
192 rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
198 rip_zclient_reset (void)
200 zclient_reset (zclient);
203 /* RIP route-map set for redistribution */
205 rip_routemap_set (int type, const char *name)
207 if (rip->route_map[type].name)
208 free(rip->route_map[type].name);
210 rip->route_map[type].name = strdup (name);
211 rip->route_map[type].map = route_map_lookup_by_name (name);
215 rip_redistribute_metric_set (int type, unsigned int metric)
217 rip->route_map[type].metric_config = 1;
218 rip->route_map[type].metric = metric;
222 rip_metric_unset (int type, unsigned int metric)
224 #define DONT_CARE_METRIC_RIP 17
225 if (metric != DONT_CARE_METRIC_RIP &&
226 rip->route_map[type].metric != metric)
228 rip->route_map[type].metric_config = 0;
229 rip->route_map[type].metric = 0;
233 /* RIP route-map unset for redistribution */
235 rip_routemap_unset (int type, const char *name)
237 if (! rip->route_map[type].name ||
238 (name != NULL && strcmp(rip->route_map[type].name,name)))
241 free (rip->route_map[type].name);
242 rip->route_map[type].name = NULL;
243 rip->route_map[type].map = NULL;
248 /* Redistribution types */
254 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
255 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
256 {ZEBRA_ROUTE_STATIC, 1, "static"},
257 {ZEBRA_ROUTE_OSPF, 1, "ospf"},
258 {ZEBRA_ROUTE_BGP, 2, "bgp"},
259 {ZEBRA_ROUTE_BABEL, 2, "babel"},
266 "Enable a routing process\n"
267 "Make connection to zebra daemon\n")
269 vty->node = ZEBRA_NODE;
271 zclient_start (zclient);
275 DEFUN (no_router_zebra,
279 "Enable a routing process\n"
280 "Make connection to zebra daemon\n")
283 zclient_stop (zclient);
289 rip_redistribute_set (int type)
291 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
294 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
296 if (zclient->sock > 0)
297 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
304 rip_redistribute_unset (int type)
306 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
309 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
311 if (zclient->sock > 0)
312 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
315 /* Remove the routes from RIP table. */
316 rip_redistribute_withdraw (type);
322 rip_redistribute_check (int type)
324 return vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT);
328 rip_redistribute_clean (void)
332 for (i = 0; redist_type[i].str; i++)
334 if (vrf_bitmap_check (zclient->redist[redist_type[i].type], VRF_DEFAULT))
336 if (zclient->sock > 0)
337 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
338 zclient, redist_type[i].type,
341 vrf_bitmap_unset (zclient->redist[redist_type[i].type], VRF_DEFAULT);
343 /* Remove the routes from RIP table. */
344 rip_redistribute_withdraw (redist_type[i].type);
349 DEFUN (rip_redistribute_rip,
350 rip_redistribute_rip_cmd,
352 "Redistribute information from another routing protocol\n"
353 "Routing Information Protocol (RIP)\n")
355 vrf_bitmap_set (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
359 DEFUN (no_rip_redistribute_rip,
360 no_rip_redistribute_rip_cmd,
361 "no redistribute rip",
363 "Redistribute information from another routing protocol\n"
364 "Routing Information Protocol (RIP)\n")
366 vrf_bitmap_unset (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
370 DEFUN (rip_redistribute_type,
371 rip_redistribute_type_cmd,
372 "redistribute " QUAGGA_REDIST_STR_RIPD,
374 QUAGGA_REDIST_HELP_STR_RIPD)
378 for(i = 0; redist_type[i].str; i++)
380 if (strncmp (redist_type[i].str, argv[0],
381 redist_type[i].str_min_len) == 0)
383 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
384 redist_type[i].type, VRF_DEFAULT);
389 vty_out(vty, "Invalid type %s%s", argv[0],
395 DEFUN (no_rip_redistribute_type,
396 no_rip_redistribute_type_cmd,
397 "no redistribute " QUAGGA_REDIST_STR_RIPD,
400 QUAGGA_REDIST_HELP_STR_RIPD)
404 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)
409 rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
410 rip_routemap_unset (redist_type[i].type,NULL);
411 rip_redistribute_unset (redist_type[i].type);
416 vty_out(vty, "Invalid type %s%s", argv[0],
422 DEFUN (rip_redistribute_type_routemap,
423 rip_redistribute_type_routemap_cmd,
424 "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
426 QUAGGA_REDIST_HELP_STR_RIPD
427 "Route map reference\n"
428 "Pointer to route-map entries\n")
432 for (i = 0; redist_type[i].str; i++) {
433 if (strncmp(redist_type[i].str, argv[0],
434 redist_type[i].str_min_len) == 0)
436 rip_routemap_set (redist_type[i].type, argv[1]);
437 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
443 vty_out(vty, "Invalid type %s%s", argv[0],
449 DEFUN (no_rip_redistribute_type_routemap,
450 no_rip_redistribute_type_routemap_cmd,
451 "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
454 QUAGGA_REDIST_HELP_STR_RIPD
455 "Route map reference\n"
456 "Pointer to route-map entries\n")
460 for (i = 0; redist_type[i].str; i++)
462 if (strncmp(redist_type[i].str, argv[0],
463 redist_type[i].str_min_len) == 0)
465 if (rip_routemap_unset (redist_type[i].type,argv[1]))
467 rip_redistribute_unset (redist_type[i].type);
472 vty_out(vty, "Invalid type %s%s", argv[0],
478 DEFUN (rip_redistribute_type_metric,
479 rip_redistribute_type_metric_cmd,
480 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
482 QUAGGA_REDIST_HELP_STR_RIPD
489 metric = atoi (argv[1]);
491 for (i = 0; redist_type[i].str; i++) {
492 if (strncmp(redist_type[i].str, argv[0],
493 redist_type[i].str_min_len) == 0)
495 rip_redistribute_metric_set (redist_type[i].type, metric);
496 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
502 vty_out(vty, "Invalid type %s%s", argv[0],
508 DEFUN (no_rip_redistribute_type_metric,
509 no_rip_redistribute_type_metric_cmd,
510 "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
513 QUAGGA_REDIST_HELP_STR_RIPD
519 for (i = 0; redist_type[i].str; i++)
521 if (strncmp(redist_type[i].str, argv[0],
522 redist_type[i].str_min_len) == 0)
524 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
526 rip_redistribute_unset (redist_type[i].type);
531 vty_out(vty, "Invalid type %s%s", argv[0],
537 DEFUN (rip_redistribute_type_metric_routemap,
538 rip_redistribute_type_metric_routemap_cmd,
539 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
541 QUAGGA_REDIST_HELP_STR_RIPD
544 "Route map reference\n"
545 "Pointer to route-map entries\n")
550 metric = atoi (argv[1]);
552 for (i = 0; redist_type[i].str; i++) {
553 if (strncmp(redist_type[i].str, argv[0],
554 redist_type[i].str_min_len) == 0)
556 rip_redistribute_metric_set (redist_type[i].type, metric);
557 rip_routemap_set (redist_type[i].type, argv[2]);
558 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
564 vty_out(vty, "Invalid type %s%s", argv[0],
571 DEFUN (no_rip_redistribute_type_metric_routemap,
572 no_rip_redistribute_type_metric_routemap_cmd,
573 "no redistribute " QUAGGA_REDIST_STR_RIPD
574 " metric <0-16> route-map WORD",
577 QUAGGA_REDIST_HELP_STR_RIPD
580 "Route map reference\n"
581 "Pointer to route-map entries\n")
585 for (i = 0; redist_type[i].str; i++)
587 if (strncmp(redist_type[i].str, argv[0],
588 redist_type[i].str_min_len) == 0)
590 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
592 if (rip_routemap_unset (redist_type[i].type, argv[2]))
594 rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
597 rip_redistribute_unset (redist_type[i].type);
602 vty_out(vty, "Invalid type %s%s", argv[0],
608 /* Default information originate. */
610 DEFUN (rip_default_information_originate,
611 rip_default_information_originate_cmd,
612 "default-information originate",
613 "Control distribution of default route\n"
614 "Distribute a default route\n")
616 struct prefix_ipv4 p;
618 if (! rip->default_information)
620 memset (&p, 0, sizeof (struct prefix_ipv4));
623 rip->default_information = 1;
625 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
632 DEFUN (no_rip_default_information_originate,
633 no_rip_default_information_originate_cmd,
634 "no default-information originate",
636 "Control distribution of default route\n"
637 "Distribute a default route\n")
639 struct prefix_ipv4 p;
641 if (rip->default_information)
643 memset (&p, 0, sizeof (struct prefix_ipv4));
646 rip->default_information = 0;
648 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
654 /* RIP configuration write function. */
656 config_write_zebra (struct vty *vty)
658 if (! zclient->enable)
660 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
663 else if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
665 vty_out (vty, "router zebra%s", VTY_NEWLINE);
666 vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
673 config_write_rip_redistribute (struct vty *vty, int config_mode)
677 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
678 if (i != zclient->redist_default &&
679 vrf_bitmap_check (zclient->redist[i], VRF_DEFAULT))
683 if (rip->route_map[i].metric_config)
685 if (rip->route_map[i].name)
686 vty_out (vty, " redistribute %s metric %d route-map %s%s",
687 zebra_route_string(i), rip->route_map[i].metric,
688 rip->route_map[i].name,
691 vty_out (vty, " redistribute %s metric %d%s",
692 zebra_route_string(i), rip->route_map[i].metric,
697 if (rip->route_map[i].name)
698 vty_out (vty, " redistribute %s route-map %s%s",
699 zebra_route_string(i), rip->route_map[i].name,
702 vty_out (vty, " redistribute %s%s", zebra_route_string(i),
707 vty_out (vty, " %s", zebra_route_string(i));
712 /* Zebra node structure. */
713 static struct cmd_node zebra_node =
716 "%s(config-router)# ",
720 rip_zebra_connected (struct zclient *zclient)
722 zclient_send_requests (zclient, VRF_DEFAULT);
726 rip_zclient_init (struct thread_master *master)
728 /* Set default value to the zebra client structure. */
729 zclient = zclient_new (master);
730 zclient_init (zclient, ZEBRA_ROUTE_RIP);
731 zclient->zebra_connected = rip_zebra_connected;
732 zclient->interface_add = rip_interface_add;
733 zclient->interface_delete = rip_interface_delete;
734 zclient->interface_address_add = rip_interface_address_add;
735 zclient->interface_address_delete = rip_interface_address_delete;
736 zclient->ipv4_route_add = rip_zebra_read_ipv4;
737 zclient->ipv4_route_delete = rip_zebra_read_ipv4;
738 zclient->interface_up = rip_interface_up;
739 zclient->interface_down = rip_interface_down;
741 /* Install zebra node. */
742 install_node (&zebra_node, config_write_zebra);
744 /* Install command elements to zebra node. */
745 install_element (CONFIG_NODE, &router_zebra_cmd);
746 install_element (CONFIG_NODE, &no_router_zebra_cmd);
747 install_default (ZEBRA_NODE);
748 install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
749 install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
751 /* Install command elements to rip node. */
752 install_element (RIP_NODE, &rip_redistribute_type_cmd);
753 install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
754 install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
755 install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
756 install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
757 install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
758 install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
759 install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
760 install_element (RIP_NODE, &rip_default_information_originate_cmd);
761 install_element (RIP_NODE, &no_rip_default_information_originate_cmd);