File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / rip_zebra.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /* RIPd and zebra interface.
    2:  * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    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
    9:  * later version.
   10:  *
   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.
   15:  *
   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
   19:  * 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: 
   24: #include "command.h"
   25: #include "prefix.h"
   26: #include "table.h"
   27: #include "stream.h"
   28: #include "memory.h"
   29: #include "routemap.h"
   30: #include "zclient.h"
   31: #include "log.h"
   32: #include "vrf.h"
   33: #include "ripd/ripd.h"
   34: #include "ripd/rip_debug.h"
   35: #include "ripd/rip_interface.h"
   36: 
   37: /* All information about zebra. */
   38: struct zclient *zclient = NULL;
   39: 
   40: /* Send ECMP routes to zebra. */
   41: static void
   42: rip_zebra_ipv4_send (struct route_node *rp, u_char cmd)
   43: {
   44:   static struct in_addr **nexthops = NULL;
   45:   static unsigned int nexthops_len = 0;
   46: 
   47:   struct list *list = (struct list *)rp->info;
   48:   struct zapi_ipv4 api;
   49:   struct listnode *listnode = NULL;
   50:   struct rip_info *rinfo = NULL;
   51:   int count = 0;
   52: 
   53:   if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
   54:     {
   55:       api.vrf_id = VRF_DEFAULT;
   56:       api.type = ZEBRA_ROUTE_RIP;
   57:       api.flags = 0;
   58:       api.message = 0;
   59:       api.safi = SAFI_UNICAST;
   60: 
   61:       if (nexthops_len < listcount (list))
   62:         {
   63:           nexthops_len = listcount (list);
   64:           nexthops = XREALLOC (MTYPE_TMP, nexthops,
   65:                                nexthops_len * sizeof (struct in_addr *));
   66:         }
   67: 
   68:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
   69:       for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
   70:         {
   71:           nexthops[count++] = &rinfo->nexthop;
   72:           if (cmd == ZEBRA_IPV4_ROUTE_ADD)
   73:             SET_FLAG (rinfo->flags, RIP_RTF_FIB);
   74:           else
   75:             UNSET_FLAG (rinfo->flags, RIP_RTF_FIB);
   76:         }
   77: 
   78:       api.nexthop = nexthops;
   79:       api.nexthop_num = count;
   80:       api.ifindex_num = 0;
   81: 
   82:       rinfo = listgetdata (listhead (list));
   83: 
   84:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
   85:       api.metric = rinfo->metric;
   86: 
   87:       if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT)
   88:         {
   89:           SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
   90:           api.distance = rinfo->distance;
   91:         }
   92: 
   93:       zapi_ipv4_route (cmd, zclient,
   94:                        (struct prefix_ipv4 *)&rp->p, &api);
   95: 
   96:       if (IS_RIP_DEBUG_ZEBRA)
   97:         {
   98:           if (rip->ecmp)
   99:             zlog_debug ("%s: %s/%d nexthops %d",
  100:                         (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
  101:                             "Install into zebra" : "Delete from zebra",
  102:                         inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen, count);
  103:           else
  104:             zlog_debug ("%s: %s/%d",
  105:                         (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
  106:                             "Install into zebra" : "Delete from zebra",
  107:                         inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
  108:         }
  109: 
  110:       rip_global_route_changes++;
  111:     }
  112: }
  113: 
  114: /* Add/update ECMP routes to zebra. */
  115: void
  116: rip_zebra_ipv4_add (struct route_node *rp)
  117: {
  118:   rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_ADD);
  119: }
  120: 
  121: /* Delete ECMP routes from zebra. */
  122: void
  123: rip_zebra_ipv4_delete (struct route_node *rp)
  124: {
  125:   rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_DELETE);
  126: }
  127: 
  128: /* Zebra route add and delete treatment. */
  129: static int
  130: rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
  131:     vrf_id_t vrf_id)
  132: {
  133:   struct stream *s;
  134:   struct zapi_ipv4 api;
  135:   unsigned long ifindex;
  136:   struct in_addr nexthop;
  137:   struct prefix_ipv4 p;
  138:   unsigned char plength = 0;
  139: 
  140:   s = zclient->ibuf;
  141:   ifindex = 0;
  142:   nexthop.s_addr = 0;
  143: 
  144:   /* Type, flags, message. */
  145:   api.type = stream_getc (s);
  146:   api.flags = stream_getc (s);
  147:   api.message = stream_getc (s);
  148: 
  149:   /* IPv4 prefix. */
  150:   memset (&p, 0, sizeof (struct prefix_ipv4));
  151:   p.family = AF_INET;
  152:   plength = stream_getc (s);
  153:   p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
  154:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  155: 
  156:   /* Nexthop, ifindex, distance, metric. */
  157:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  158:     {
  159:       api.nexthop_num = stream_getc (s);
  160:       nexthop.s_addr = stream_get_ipv4 (s);
  161:     }
  162:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  163:     {
  164:       api.ifindex_num = stream_getc (s);
  165:       ifindex = stream_getl (s);
  166:     }
  167:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  168:     api.distance = stream_getc (s);
  169:   else
  170:     api.distance = 255;
  171:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  172:     api.metric = stream_getl (s);
  173:   else
  174:     api.metric = 0;
  175: 
  176:   /* Then fetch IPv4 prefixes. */
  177:   if (command == ZEBRA_IPV4_ROUTE_ADD)
  178:     rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, 
  179:                           &nexthop, api.metric, api.distance);
  180:   else 
  181:     rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
  182: 
  183:   return 0;
  184: }
  185: 
  186: void
  187: rip_zclient_reset (void)
  188: {
  189:   zclient_reset (zclient);
  190: }
  191: 
  192: /* RIP route-map set for redistribution */
  193: static void
  194: rip_routemap_set (int type, const char *name)
  195: {
  196:   if (rip->route_map[type].name)
  197:     free(rip->route_map[type].name);
  198: 
  199:   rip->route_map[type].name = strdup (name);
  200:   rip->route_map[type].map = route_map_lookup_by_name (name);
  201: }
  202: 
  203: static void
  204: rip_redistribute_metric_set (int type, unsigned int metric)
  205: {
  206:   rip->route_map[type].metric_config = 1;
  207:   rip->route_map[type].metric = metric;
  208: }
  209: 
  210: static int
  211: rip_metric_unset (int type, unsigned int metric)
  212: {
  213: #define DONT_CARE_METRIC_RIP 17  
  214:   if (metric != DONT_CARE_METRIC_RIP &&
  215:       rip->route_map[type].metric != metric)
  216:     return 1;
  217:   rip->route_map[type].metric_config = 0;
  218:   rip->route_map[type].metric = 0;
  219:   return 0;
  220: }
  221: 
  222: /* RIP route-map unset for redistribution */
  223: static int
  224: rip_routemap_unset (int type, const char *name)
  225: {
  226:   if (! rip->route_map[type].name ||
  227:       (name != NULL && strcmp(rip->route_map[type].name,name)))
  228:     return 1;
  229: 
  230:   free (rip->route_map[type].name);
  231:   rip->route_map[type].name = NULL;
  232:   rip->route_map[type].map = NULL;
  233: 
  234:   return 0;
  235: }
  236: 
  237: /* Redistribution types */
  238: static struct {
  239:   int type;
  240:   int str_min_len;
  241:   const char *str;
  242: } redist_type[] = {
  243:   {ZEBRA_ROUTE_KERNEL,  1, "kernel"},
  244:   {ZEBRA_ROUTE_CONNECT, 1, "connected"},
  245:   {ZEBRA_ROUTE_STATIC,  1, "static"},
  246:   {ZEBRA_ROUTE_OSPF,    1, "ospf"},
  247:   {ZEBRA_ROUTE_BGP,     2, "bgp"},
  248:   {ZEBRA_ROUTE_BABEL,   2, "babel"},
  249:   {0, 0, NULL}
  250: };
  251: 
  252: DEFUN (router_zebra,
  253:        router_zebra_cmd,
  254:        "router zebra",
  255:        "Enable a routing process\n"
  256:        "Make connection to zebra daemon\n")
  257: {
  258:   vty->node = ZEBRA_NODE;
  259:   zclient->enable = 1;
  260:   zclient_start (zclient);
  261:   return CMD_SUCCESS;
  262: }
  263: 
  264: DEFUN (no_router_zebra,
  265:        no_router_zebra_cmd,
  266:        "no router zebra",
  267:        NO_STR
  268:        "Enable a routing process\n"
  269:        "Make connection to zebra daemon\n")
  270: {
  271:   zclient->enable = 0;
  272:   zclient_stop (zclient);
  273:   return CMD_SUCCESS;
  274: }
  275: 
  276: #if 0
  277: static int
  278: rip_redistribute_set (int type)
  279: {
  280:   if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
  281:     return CMD_SUCCESS;
  282: 
  283:   vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
  284: 
  285:   if (zclient->sock > 0)
  286:     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  287: 
  288:   return CMD_SUCCESS;
  289: }
  290: #endif
  291: 
  292: static int
  293: rip_redistribute_unset (int type)
  294: {
  295:   if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
  296:     return CMD_SUCCESS;
  297: 
  298:   vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
  299: 
  300:   if (zclient->sock > 0)
  301:     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
  302:                              VRF_DEFAULT);
  303: 
  304:   /* Remove the routes from RIP table. */
  305:   rip_redistribute_withdraw (type);
  306: 
  307:   return CMD_SUCCESS;
  308: }
  309: 
  310: int
  311: rip_redistribute_check (int type)
  312: {
  313:   return vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT);
  314: }
  315: 
  316: void
  317: rip_redistribute_clean (void)
  318: {
  319:   int i;
  320: 
  321:   for (i = 0; redist_type[i].str; i++)
  322:     {
  323:       if (vrf_bitmap_check (zclient->redist[redist_type[i].type], VRF_DEFAULT))
  324: 	{
  325: 	  if (zclient->sock > 0)
  326: 	    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
  327: 				     zclient, redist_type[i].type,
  328: 				     VRF_DEFAULT);
  329: 
  330: 	  vrf_bitmap_unset (zclient->redist[redist_type[i].type], VRF_DEFAULT);
  331: 
  332: 	  /* Remove the routes from RIP table. */
  333: 	  rip_redistribute_withdraw (redist_type[i].type);
  334: 	}
  335:     }
  336: }
  337: 
  338: DEFUN (rip_redistribute_rip,
  339:        rip_redistribute_rip_cmd,
  340:        "redistribute rip",
  341:        "Redistribute information from another routing protocol\n"
  342:        "Routing Information Protocol (RIP)\n")
  343: {
  344:   vrf_bitmap_set (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
  345:   return CMD_SUCCESS;
  346: }
  347: 
  348: DEFUN (no_rip_redistribute_rip,
  349:        no_rip_redistribute_rip_cmd,
  350:        "no redistribute rip",
  351:        NO_STR
  352:        "Redistribute information from another routing protocol\n"
  353:        "Routing Information Protocol (RIP)\n")
  354: {
  355:   vrf_bitmap_unset (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
  356:   return CMD_SUCCESS;
  357: }
  358: 
  359: DEFUN (rip_redistribute_type,
  360:        rip_redistribute_type_cmd,
  361:        "redistribute " QUAGGA_REDIST_STR_RIPD,
  362:        REDIST_STR
  363:        QUAGGA_REDIST_HELP_STR_RIPD)
  364: {
  365:   int i;
  366: 
  367:   for(i = 0; redist_type[i].str; i++) 
  368:     {
  369:       if (strncmp (redist_type[i].str, argv[0], 
  370: 		   redist_type[i].str_min_len) == 0) 
  371: 	{
  372: 	  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, 
  373: 	                        redist_type[i].type, VRF_DEFAULT);
  374: 	  return CMD_SUCCESS;
  375: 	}
  376:     }
  377: 
  378:   vty_out(vty, "Invalid type %s%s", argv[0],
  379: 	  VTY_NEWLINE);
  380: 
  381:   return CMD_WARNING;
  382: }
  383: 
  384: DEFUN (no_rip_redistribute_type,
  385:        no_rip_redistribute_type_cmd,
  386:        "no redistribute " QUAGGA_REDIST_STR_RIPD,
  387:        NO_STR
  388:        REDIST_STR
  389:        QUAGGA_REDIST_HELP_STR_RIPD)
  390: {
  391:   int i;
  392: 
  393:   for (i = 0; redist_type[i].str; i++) 
  394:     {
  395:       if (strncmp(redist_type[i].str, argv[0], 
  396: 		  redist_type[i].str_min_len) == 0) 
  397: 	{
  398: 	  rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
  399: 	  rip_routemap_unset (redist_type[i].type,NULL);
  400: 	  rip_redistribute_unset (redist_type[i].type);
  401: 	  return CMD_SUCCESS;
  402:         }
  403:     }
  404: 
  405:   vty_out(vty, "Invalid type %s%s", argv[0],
  406: 	  VTY_NEWLINE);
  407: 
  408:   return CMD_WARNING;
  409: }
  410: 
  411: DEFUN (rip_redistribute_type_routemap,
  412:        rip_redistribute_type_routemap_cmd,
  413:        "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
  414:        REDIST_STR
  415:        QUAGGA_REDIST_HELP_STR_RIPD
  416:        "Route map reference\n"
  417:        "Pointer to route-map entries\n")
  418: {
  419:   int i;
  420: 
  421:   for (i = 0; redist_type[i].str; i++) {
  422:     if (strncmp(redist_type[i].str, argv[0],
  423: 		redist_type[i].str_min_len) == 0) 
  424:       {
  425: 	rip_routemap_set (redist_type[i].type, argv[1]);
  426: 	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
  427: 	                      VRF_DEFAULT);
  428: 	return CMD_SUCCESS;
  429:       }
  430:   }
  431: 
  432:   vty_out(vty, "Invalid type %s%s", argv[0],
  433: 	  VTY_NEWLINE);
  434: 
  435:   return CMD_WARNING;
  436: }
  437: 
  438: DEFUN (no_rip_redistribute_type_routemap,
  439:        no_rip_redistribute_type_routemap_cmd,
  440:        "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
  441:        NO_STR
  442:        REDIST_STR
  443:        QUAGGA_REDIST_HELP_STR_RIPD
  444:        "Route map reference\n"
  445:        "Pointer to route-map entries\n")
  446: {
  447:   int i;
  448: 
  449:   for (i = 0; redist_type[i].str; i++) 
  450:     {
  451:       if (strncmp(redist_type[i].str, argv[0], 
  452: 		  redist_type[i].str_min_len) == 0) 
  453: 	{
  454: 	  if (rip_routemap_unset (redist_type[i].type,argv[1]))
  455: 	    return CMD_WARNING;
  456: 	  rip_redistribute_unset (redist_type[i].type);
  457: 	  return CMD_SUCCESS;
  458:         }
  459:     }
  460: 
  461:   vty_out(vty, "Invalid type %s%s", argv[0],
  462: 	  VTY_NEWLINE);
  463: 
  464:   return CMD_WARNING;
  465: }
  466: 
  467: DEFUN (rip_redistribute_type_metric,
  468:        rip_redistribute_type_metric_cmd,
  469:        "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
  470:        REDIST_STR
  471:        QUAGGA_REDIST_HELP_STR_RIPD
  472:        "Metric\n"
  473:        "Metric value\n")
  474: {
  475:   int i;
  476:   int metric;
  477: 
  478:   metric = atoi (argv[1]);
  479: 
  480:   for (i = 0; redist_type[i].str; i++) {
  481:     if (strncmp(redist_type[i].str, argv[0],
  482: 		redist_type[i].str_min_len) == 0) 
  483:       {
  484: 	rip_redistribute_metric_set (redist_type[i].type, metric);
  485: 	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
  486: 	                      VRF_DEFAULT);
  487: 	return CMD_SUCCESS;
  488:       }
  489:   }
  490: 
  491:   vty_out(vty, "Invalid type %s%s", argv[0],
  492: 	  VTY_NEWLINE);
  493: 
  494:   return CMD_WARNING;
  495: }
  496: 
  497: DEFUN (no_rip_redistribute_type_metric,
  498:        no_rip_redistribute_type_metric_cmd,
  499:        "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
  500:        NO_STR
  501:        REDIST_STR
  502:        QUAGGA_REDIST_HELP_STR_RIPD
  503:        "Metric\n"
  504:        "Metric value\n")
  505: {
  506:   int i;
  507: 
  508:   for (i = 0; redist_type[i].str; i++) 
  509:     {
  510:       if (strncmp(redist_type[i].str, argv[0], 
  511: 		  redist_type[i].str_min_len) == 0) 
  512: 	{
  513: 	  if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
  514: 	    return CMD_WARNING;
  515: 	  rip_redistribute_unset (redist_type[i].type);
  516: 	  return CMD_SUCCESS;
  517:         }
  518:     }
  519: 
  520:   vty_out(vty, "Invalid type %s%s", argv[0],
  521: 	  VTY_NEWLINE);
  522: 
  523:   return CMD_WARNING;
  524: }
  525: 
  526: DEFUN (rip_redistribute_type_metric_routemap,
  527:        rip_redistribute_type_metric_routemap_cmd,
  528:        "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
  529:        REDIST_STR
  530:        QUAGGA_REDIST_HELP_STR_RIPD
  531:        "Metric\n"
  532:        "Metric value\n"
  533:        "Route map reference\n"
  534:        "Pointer to route-map entries\n")
  535: {
  536:   int i;
  537:   int metric;
  538: 
  539:   metric = atoi (argv[1]);
  540: 
  541:   for (i = 0; redist_type[i].str; i++) {
  542:     if (strncmp(redist_type[i].str, argv[0],
  543: 		redist_type[i].str_min_len) == 0) 
  544:       {
  545: 	rip_redistribute_metric_set (redist_type[i].type, metric);
  546: 	rip_routemap_set (redist_type[i].type, argv[2]);
  547: 	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
  548: 	                      VRF_DEFAULT);
  549: 	return CMD_SUCCESS;
  550:       }
  551:   }
  552: 
  553:   vty_out(vty, "Invalid type %s%s", argv[0],
  554: 	  VTY_NEWLINE);
  555: 
  556:   return CMD_WARNING;
  557: }
  558: 
  559: 
  560: DEFUN (no_rip_redistribute_type_metric_routemap,
  561:        no_rip_redistribute_type_metric_routemap_cmd,
  562:        "no redistribute " QUAGGA_REDIST_STR_RIPD
  563:        " metric <0-16> route-map WORD",
  564:        NO_STR
  565:        REDIST_STR
  566:        QUAGGA_REDIST_HELP_STR_RIPD
  567:        "Metric\n"
  568:        "Metric value\n"
  569:        "Route map reference\n"
  570:        "Pointer to route-map entries\n")
  571: {
  572:   int i;
  573: 
  574:   for (i = 0; redist_type[i].str; i++) 
  575:     {
  576:       if (strncmp(redist_type[i].str, argv[0], 
  577: 		  redist_type[i].str_min_len) == 0) 
  578: 	{
  579: 	  if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
  580: 	    return CMD_WARNING;
  581: 	  if (rip_routemap_unset (redist_type[i].type, argv[2]))
  582: 	    {
  583: 	      rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));   
  584: 	      return CMD_WARNING;
  585: 	    }
  586: 	  rip_redistribute_unset (redist_type[i].type);
  587: 	  return CMD_SUCCESS;
  588:         }
  589:     }
  590: 
  591:   vty_out(vty, "Invalid type %s%s", argv[0],
  592: 	  VTY_NEWLINE);
  593: 
  594:   return CMD_WARNING;
  595: }
  596: 
  597: /* Default information originate. */
  598: 
  599: DEFUN (rip_default_information_originate,
  600:        rip_default_information_originate_cmd,
  601:        "default-information originate",
  602:        "Control distribution of default route\n"
  603:        "Distribute a default route\n")
  604: {
  605:   struct prefix_ipv4 p;
  606: 
  607:   if (! rip->default_information)
  608:     {
  609:       memset (&p, 0, sizeof (struct prefix_ipv4));
  610:       p.family = AF_INET;
  611: 
  612:       rip->default_information = 1;
  613:   
  614:       rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0, 
  615:                             NULL, 0, 0);
  616:     }
  617: 
  618:   return CMD_SUCCESS;
  619: }
  620: 
  621: DEFUN (no_rip_default_information_originate,
  622:        no_rip_default_information_originate_cmd,
  623:        "no default-information originate",
  624:        NO_STR
  625:        "Control distribution of default route\n"
  626:        "Distribute a default route\n")
  627: {
  628:   struct prefix_ipv4 p;
  629: 
  630:   if (rip->default_information)
  631:     {
  632:       memset (&p, 0, sizeof (struct prefix_ipv4));
  633:       p.family = AF_INET;
  634: 
  635:       rip->default_information = 0;
  636:   
  637:       rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
  638:     }
  639: 
  640:   return CMD_SUCCESS;
  641: }
  642: 
  643: /* RIP configuration write function. */
  644: static int
  645: config_write_zebra (struct vty *vty)
  646: {
  647:   if (! zclient->enable)
  648:     {
  649:       vty_out (vty, "no router zebra%s", VTY_NEWLINE);
  650:       return 1;
  651:     }
  652:   else if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
  653:     {
  654:       vty_out (vty, "router zebra%s", VTY_NEWLINE);
  655:       vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
  656:       return 1;
  657:     }
  658:   return 0;
  659: }
  660: 
  661: int
  662: config_write_rip_redistribute (struct vty *vty, int config_mode)
  663: {
  664:   int i;
  665: 
  666:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  667:     if (i != zclient->redist_default &&
  668:         vrf_bitmap_check (zclient->redist[i], VRF_DEFAULT))
  669:       {
  670: 	if (config_mode)
  671: 	  {
  672: 	    if (rip->route_map[i].metric_config)
  673: 	      {
  674: 		if (rip->route_map[i].name)
  675: 		  vty_out (vty, " redistribute %s metric %d route-map %s%s",
  676: 			   zebra_route_string(i), rip->route_map[i].metric,
  677: 			   rip->route_map[i].name,
  678: 			   VTY_NEWLINE);
  679: 		else
  680: 		  vty_out (vty, " redistribute %s metric %d%s",
  681: 			   zebra_route_string(i), rip->route_map[i].metric,
  682: 			   VTY_NEWLINE);
  683: 	      }
  684: 	    else
  685: 	      {
  686: 		if (rip->route_map[i].name)
  687: 		  vty_out (vty, " redistribute %s route-map %s%s",
  688: 			   zebra_route_string(i), rip->route_map[i].name,
  689: 			   VTY_NEWLINE);
  690: 		else
  691: 		  vty_out (vty, " redistribute %s%s", zebra_route_string(i),
  692: 			   VTY_NEWLINE);
  693: 	      }
  694: 	  }
  695: 	else
  696: 	  vty_out (vty, " %s", zebra_route_string(i));
  697:       }
  698:   return 0;
  699: }
  700: 
  701: /* Zebra node structure. */
  702: static struct cmd_node zebra_node =
  703: {
  704:   ZEBRA_NODE,
  705:   "%s(config-router)# ",
  706: };
  707: 
  708: static void
  709: rip_zebra_connected (struct zclient *zclient)
  710: {
  711:   zclient_send_requests (zclient, VRF_DEFAULT);
  712: }
  713: 
  714: void
  715: rip_zclient_init (struct thread_master *master)
  716: {
  717:   /* Set default value to the zebra client structure. */
  718:   zclient = zclient_new (master);
  719:   zclient_init (zclient, ZEBRA_ROUTE_RIP);
  720:   zclient->zebra_connected = rip_zebra_connected;
  721:   zclient->interface_add = rip_interface_add;
  722:   zclient->interface_delete = rip_interface_delete;
  723:   zclient->interface_address_add = rip_interface_address_add;
  724:   zclient->interface_address_delete = rip_interface_address_delete;
  725:   zclient->ipv4_route_add = rip_zebra_read_ipv4;
  726:   zclient->ipv4_route_delete = rip_zebra_read_ipv4;
  727:   zclient->interface_up = rip_interface_up;
  728:   zclient->interface_down = rip_interface_down;
  729:   
  730:   /* Install zebra node. */
  731:   install_node (&zebra_node, config_write_zebra);
  732: 
  733:   /* Install command elements to zebra node. */ 
  734:   install_element (CONFIG_NODE, &router_zebra_cmd);
  735:   install_element (CONFIG_NODE, &no_router_zebra_cmd);
  736:   install_default (ZEBRA_NODE);
  737:   install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
  738:   install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
  739: 
  740:   /* Install command elements to rip node. */
  741:   install_element (RIP_NODE, &rip_redistribute_type_cmd);
  742:   install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
  743:   install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
  744:   install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
  745:   install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
  746:   install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
  747:   install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
  748:   install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
  749:   install_element (RIP_NODE, &rip_default_information_originate_cmd);
  750:   install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
  751: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>