File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripngd / ripng_zebra.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:29 2012 UTC (11 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, HEAD
quagga

    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. */
   35: struct zclient *zclient = NULL;
   36: 
   37: /* Callback prototypes for zebra client service. */
   38: int ripng_interface_up (int, struct zclient *, zebra_size_t);
   39: int ripng_interface_down (int, struct zclient *, zebra_size_t);
   40: int ripng_interface_add (int, struct zclient *, zebra_size_t);
   41: int ripng_interface_delete (int, struct zclient *, zebra_size_t);
   42: int ripng_interface_address_add (int, struct zclient *, zebra_size_t);
   43: int ripng_interface_address_delete (int, struct zclient *, zebra_size_t);
   44: 
   45: void
   46: ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
   47: 		      unsigned int ifindex, u_char metric)
   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:       api.safi = SAFI_UNICAST;
   57:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
   58:       api.nexthop_num = 1;
   59:       api.nexthop = &nexthop;
   60:       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
   61:       api.ifindex_num = 1;
   62:       api.ifindex = &ifindex;
   63:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
   64:       api.metric = metric;
   65:       
   66:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
   67:     }
   68: }
   69: 
   70: void
   71: ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
   72: 			 unsigned int ifindex)
   73: {
   74:   struct zapi_ipv6 api;
   75: 
   76:   if (zclient->redist[ZEBRA_ROUTE_RIPNG])
   77:     {
   78:       api.type = ZEBRA_ROUTE_RIPNG;
   79:       api.flags = 0;
   80:       api.message = 0;
   81:       api.safi = SAFI_UNICAST;
   82:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
   83:       api.nexthop_num = 1;
   84:       api.nexthop = &nexthop;
   85:       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
   86:       api.ifindex_num = 1;
   87:       api.ifindex = &ifindex;
   88: 
   89:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
   90:     }
   91: }
   92: 
   93: /* Zebra route add and delete treatment. */
   94: static int
   95: ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
   96: 		       zebra_size_t length)
   97: {
   98:   struct stream *s;
   99:   struct zapi_ipv6 api;
  100:   unsigned long ifindex;
  101:   struct in6_addr nexthop;
  102:   struct prefix_ipv6 p;
  103: 
  104:   s = zclient->ibuf;
  105:   ifindex = 0;
  106:   memset (&nexthop, 0, sizeof (struct in6_addr));
  107: 
  108:   /* Type, flags, message. */
  109:   api.type = stream_getc (s);
  110:   api.flags = stream_getc (s);
  111:   api.message = stream_getc (s);
  112: 
  113:   /* IPv6 prefix. */
  114:   memset (&p, 0, sizeof (struct prefix_ipv6));
  115:   p.family = AF_INET6;
  116:   p.prefixlen = stream_getc (s);
  117:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  118: 
  119:   /* Nexthop, ifindex, distance, metric. */
  120:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  121:     {
  122:       api.nexthop_num = stream_getc (s);
  123:       stream_get (&nexthop, s, 16);
  124:     }
  125:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  126:     {
  127:       api.ifindex_num = stream_getc (s);
  128:       ifindex = stream_getl (s);
  129:     }
  130:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  131:     api.distance = stream_getc (s);
  132:   else
  133:     api.distance = 0;
  134:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  135:     api.metric = stream_getl (s);
  136:   else
  137:     api.metric = 0;
  138: 
  139:   if (command == ZEBRA_IPV6_ROUTE_ADD)
  140:     ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
  141:   else
  142:     ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
  143: 
  144:   return 0;
  145: }
  146: 
  147: void
  148: ripng_zclient_reset (void)
  149: {
  150:   zclient_reset (zclient);
  151: }
  152: 
  153: static int
  154: ripng_redistribute_unset (int type)
  155: {
  156:   if (! zclient->redist[type])
  157:     return CMD_SUCCESS;
  158: 
  159:   zclient->redist[type] = 0;
  160: 
  161:   if (zclient->sock > 0)
  162:     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
  163: 
  164:   ripng_redistribute_withdraw (type);
  165:   
  166:   return CMD_SUCCESS;
  167: }
  168: 
  169: int
  170: ripng_redistribute_check (int type)
  171: {
  172:   return (zclient->redist[type]);
  173: }
  174: 
  175: static void
  176: ripng_redistribute_metric_set (int type, int metric)
  177: {
  178:   ripng->route_map[type].metric_config = 1;
  179:   ripng->route_map[type].metric = metric;
  180: }
  181: 
  182: static int
  183: ripng_redistribute_metric_unset (int type)
  184: {
  185:   ripng->route_map[type].metric_config = 0;
  186:   ripng->route_map[type].metric = 0;
  187:   return 0;
  188: }
  189: 
  190: static void
  191: ripng_redistribute_routemap_set (int type, const char *name)
  192: {
  193:   if (ripng->route_map[type].name)
  194:     free (ripng->route_map[type].name);
  195: 
  196:   ripng->route_map[type].name = strdup (name);
  197:   ripng->route_map[type].map = route_map_lookup_by_name (name);
  198: }
  199: 
  200: static void
  201: ripng_redistribute_routemap_unset (int type)
  202: {
  203:   if (ripng->route_map[type].name)
  204:     free (ripng->route_map[type].name);
  205: 
  206:   ripng->route_map[type].name = NULL;
  207:   ripng->route_map[type].map = NULL;
  208: }
  209: 
  210: /* Redistribution types */
  211: static struct {
  212:   int type;
  213:   int str_min_len;
  214:   const char *str;
  215: } redist_type[] = {
  216:   {ZEBRA_ROUTE_KERNEL,  1, "kernel"},
  217:   {ZEBRA_ROUTE_CONNECT, 1, "connected"},
  218:   {ZEBRA_ROUTE_STATIC,  1, "static"},
  219:   {ZEBRA_ROUTE_OSPF6,   1, "ospf6"},
  220:   {ZEBRA_ROUTE_BGP,     2, "bgp"},
  221:   {ZEBRA_ROUTE_BABEL,   2, "babel"},
  222:   {0, 0, NULL}
  223: };
  224: 
  225: void
  226: ripng_redistribute_clean ()
  227: {
  228:   int i;
  229: 
  230:   for (i = 0; redist_type[i].str; i++)
  231:     {
  232:       if (zclient->redist[redist_type[i].type])
  233:         {
  234:           if (zclient->sock > 0)
  235:             zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
  236:                                      zclient, redist_type[i].type);
  237: 
  238:           zclient->redist[redist_type[i].type] = 0;
  239: 
  240:           /* Remove the routes from RIPng table. */
  241:           ripng_redistribute_withdraw (redist_type[i].type);
  242:         }
  243:     }
  244: }
  245: 
  246: DEFUN (router_zebra,
  247:        router_zebra_cmd,
  248:        "router zebra",
  249:        "Enable a routing process\n"
  250:        "Make connection to zebra daemon\n")
  251: {
  252:   vty->node = ZEBRA_NODE;
  253:   zclient->enable = 1;
  254:   zclient_start (zclient);
  255:   return CMD_SUCCESS;
  256: }
  257: 
  258: DEFUN (no_router_zebra,
  259:        no_router_zebra_cmd,
  260:        "no router zebra",
  261:        NO_STR
  262:        "Disable a routing process\n"
  263:        "Stop connection to zebra daemon\n")
  264: {
  265:   zclient->enable = 0;
  266:   zclient_stop (zclient);
  267:   return CMD_SUCCESS;
  268: }
  269: 
  270: DEFUN (ripng_redistribute_ripng,
  271:        ripng_redistribute_ripng_cmd,
  272:        "redistribute ripng",
  273:        "Redistribute information from another routing protocol\n"
  274:        "RIPng route\n")
  275: {
  276:   zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
  277:   return CMD_SUCCESS;
  278: }
  279: 
  280: DEFUN (no_ripng_redistribute_ripng,
  281:        no_ripng_redistribute_ripng_cmd,
  282:        "no redistribute ripng",
  283:        NO_STR
  284:        "Redistribute information from another routing protocol\n"
  285:        "RIPng route\n")
  286: {
  287:   zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
  288:   return CMD_SUCCESS;
  289: }
  290: 
  291: DEFUN (ripng_redistribute_type,
  292:        ripng_redistribute_type_cmd,
  293:        "redistribute " QUAGGA_REDIST_STR_RIPNGD,
  294:        "Redistribute\n"
  295:        QUAGGA_REDIST_HELP_STR_RIPNGD)
  296: {
  297:   int type;
  298: 
  299:   type = proto_redistnum(AFI_IP6, argv[0]);
  300: 
  301:   if (type < 0)
  302:     {
  303:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
  304:       return CMD_WARNING;
  305:     }
  306: 
  307:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  308:   return CMD_SUCCESS;
  309: }
  310: 
  311: DEFUN (no_ripng_redistribute_type,
  312:        no_ripng_redistribute_type_cmd,
  313:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD,
  314:        NO_STR
  315:        "Redistribute\n"
  316:        QUAGGA_REDIST_HELP_STR_RIPNGD)
  317: {
  318:   int type;
  319: 
  320:   type = proto_redistnum(AFI_IP6, argv[0]);
  321: 
  322:   if (type < 0)
  323:     {
  324:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
  325:       return CMD_WARNING;
  326:     }
  327: 
  328:   ripng_redistribute_metric_unset (type);
  329:   ripng_redistribute_routemap_unset (type);
  330:   return ripng_redistribute_unset (type);
  331: }
  332: 
  333: 
  334: DEFUN (ripng_redistribute_type_metric,
  335:        ripng_redistribute_type_metric_cmd,
  336:        "redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16>",
  337:        "Redistribute\n"
  338:        QUAGGA_REDIST_HELP_STR_RIPNGD
  339:        "Metric\n"
  340:        "Metric value\n")
  341: {
  342:   int type;
  343:   int metric;
  344: 
  345:   metric = atoi (argv[1]);
  346:   type = proto_redistnum(AFI_IP6, argv[0]);
  347: 
  348:   if (type < 0)
  349:     {
  350:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
  351:       return CMD_WARNING;
  352:     }
  353: 
  354:   ripng_redistribute_metric_set (type, metric);
  355:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  356:   return CMD_SUCCESS;
  357: }
  358: 
  359: ALIAS (no_ripng_redistribute_type,
  360:        no_ripng_redistribute_type_metric_cmd,
  361:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16>",
  362:        NO_STR
  363:        "Redistribute\n"
  364:        QUAGGA_REDIST_HELP_STR_RIPNGD
  365:        "Metric\n"
  366:        "Metric value\n")
  367: 
  368: DEFUN (ripng_redistribute_type_routemap,
  369:        ripng_redistribute_type_routemap_cmd,
  370:        "redistribute " QUAGGA_REDIST_STR_RIPNGD " route-map WORD",
  371:        "Redistribute\n"
  372:        QUAGGA_REDIST_HELP_STR_RIPNGD
  373:        "Route map reference\n"
  374:        "Pointer to route-map entries\n")
  375: {
  376:   int type;
  377: 
  378:   type = proto_redistnum(AFI_IP6, argv[0]);
  379: 
  380:   if (type < 0)
  381:     {
  382:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
  383:       return CMD_WARNING;
  384:     }
  385: 
  386:   ripng_redistribute_routemap_set (type, argv[1]);
  387:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  388:  return CMD_SUCCESS;
  389: }
  390: 
  391: ALIAS (no_ripng_redistribute_type,
  392:        no_ripng_redistribute_type_routemap_cmd,
  393:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD " route-map WORD",
  394:        NO_STR
  395:        "Redistribute\n"
  396:        QUAGGA_REDIST_HELP_STR_RIPNGD
  397:        "Route map reference\n"
  398:        "Pointer to route-map entries\n")
  399: 
  400: DEFUN (ripng_redistribute_type_metric_routemap,
  401:        ripng_redistribute_type_metric_routemap_cmd,
  402:        "redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16> route-map WORD",
  403:        "Redistribute\n"
  404:        QUAGGA_REDIST_HELP_STR_RIPNGD
  405:        "Metric\n"
  406:        "Metric value\n"
  407:        "Route map reference\n"
  408:        "Pointer to route-map entries\n")
  409: {
  410:   int type;
  411:   int metric;
  412: 
  413:   type = proto_redistnum(AFI_IP6, argv[0]);
  414:   metric = atoi (argv[1]);
  415: 
  416:   if (type < 0)
  417:     {
  418:       vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
  419:       return CMD_WARNING;
  420:     }
  421: 
  422:   ripng_redistribute_metric_set (type, metric);
  423:   ripng_redistribute_routemap_set (type, argv[2]);
  424:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  425:   return CMD_SUCCESS;
  426: }
  427: 
  428: ALIAS (no_ripng_redistribute_type,
  429:        no_ripng_redistribute_type_metric_routemap_cmd,
  430:        "no redistribute " QUAGGA_REDIST_STR_RIPNGD " metric <0-16> route-map WORD",
  431:        NO_STR
  432:        "Redistribute\n"
  433:        QUAGGA_REDIST_HELP_STR_RIPNGD
  434:        "Route map reference\n"
  435:        "Pointer to route-map entries\n")
  436: 
  437: void
  438: ripng_redistribute_write (struct vty *vty, int config_mode)
  439: {
  440:   int i;
  441: 
  442:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  443:     if (i != zclient->redist_default && zclient->redist[i])
  444:       {
  445:       if (config_mode)
  446: 	{
  447: 	  if (ripng->route_map[i].metric_config)
  448: 	    {
  449: 	      if (ripng->route_map[i].name)
  450: 		vty_out (vty, " redistribute %s metric %d route-map %s%s",
  451: 			 zebra_route_string(i), ripng->route_map[i].metric,
  452: 			ripng->route_map[i].name, VTY_NEWLINE);
  453: 	      else
  454: 		vty_out (vty, " redistribute %s metric %d%s",
  455: 			zebra_route_string(i), ripng->route_map[i].metric,
  456: 			VTY_NEWLINE);
  457: 	    }
  458: 	  else
  459: 	    {
  460: 	      if (ripng->route_map[i].name)
  461: 		vty_out (vty, " redistribute %s route-map %s%s",
  462: 			 zebra_route_string(i), ripng->route_map[i].name,
  463: 			 VTY_NEWLINE);
  464: 	      else
  465: 		vty_out (vty, " redistribute %s%s", zebra_route_string(i),
  466: 			 VTY_NEWLINE);
  467: 	    }
  468: 	}
  469:       else
  470: 	vty_out (vty, "    %s", zebra_route_string(i));
  471:       }
  472: }
  473: 
  474: /* RIPng configuration write function. */
  475: static int
  476: zebra_config_write (struct vty *vty)
  477: {
  478:   if (! zclient->enable)
  479:     {
  480:       vty_out (vty, "no router zebra%s", VTY_NEWLINE);
  481:       return 1;
  482:     }
  483:   else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
  484:     {
  485:       vty_out (vty, "router zebra%s", VTY_NEWLINE);
  486:       vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
  487:       return 1;
  488:     }
  489:   return 0;
  490: }
  491: 
  492: /* Zebra node structure. */
  493: static struct cmd_node zebra_node =
  494: {
  495:   ZEBRA_NODE,
  496:   "%s(config-router)# ",
  497: };
  498: 
  499: /* Initialize zebra structure and it's commands. */
  500: void
  501: zebra_init ()
  502: {
  503:   /* Allocate zebra structure. */
  504:   zclient = zclient_new ();
  505:   zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
  506: 
  507:   zclient->interface_up = ripng_interface_up;
  508:   zclient->interface_down = ripng_interface_down;
  509:   zclient->interface_add = ripng_interface_add;
  510:   zclient->interface_delete = ripng_interface_delete;
  511:   zclient->interface_address_add = ripng_interface_address_add;
  512:   zclient->interface_address_delete = ripng_interface_address_delete;
  513:   zclient->ipv6_route_add = ripng_zebra_read_ipv6;
  514:   zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
  515:   
  516:   /* Install zebra node. */
  517:   install_node (&zebra_node, zebra_config_write);
  518: 
  519:   /* Install command element for zebra node. */ 
  520:   install_element (CONFIG_NODE, &router_zebra_cmd);
  521:   install_element (CONFIG_NODE, &no_router_zebra_cmd);
  522:   install_default (ZEBRA_NODE);
  523:   install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
  524:   install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
  525: 
  526:   /* Install command elements to ripng node */
  527:   install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
  528:   install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
  529:   install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
  530:   install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
  531:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
  532:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
  533:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
  534:   install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
  535: }

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