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);