File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / redistribute.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:11 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /* Redistribution Handler
    2:  * Copyright (C) 1998 Kunihiro Ishiguro
    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 "vector.h"
   25: #include "vty.h"
   26: #include "command.h"
   27: #include "prefix.h"
   28: #include "table.h"
   29: #include "stream.h"
   30: #include "zclient.h"
   31: #include "linklist.h"
   32: #include "log.h"
   33: 
   34: #include "zebra/rib.h"
   35: #include "zebra/zserv.h"
   36: #include "zebra/redistribute.h"
   37: #include "zebra/debug.h"
   38: #include "zebra/router-id.h"
   39: 
   40: /* master zebra server structure */
   41: extern struct zebra_t zebrad;
   42: 
   43: int
   44: zebra_check_addr (struct prefix *p)
   45: {
   46:   if (p->family == AF_INET)
   47:     {
   48:       u_int32_t addr;
   49: 
   50:       addr = p->u.prefix4.s_addr;
   51:       addr = ntohl (addr);
   52: 
   53:       if (IPV4_NET127 (addr)
   54:           || IN_CLASSD (addr)
   55:           || IPV4_LINKLOCAL(addr))
   56: 	return 0;
   57:     }
   58: #ifdef HAVE_IPV6
   59:   if (p->family == AF_INET6)
   60:     {
   61:       if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
   62: 	return 0;
   63:       if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
   64: 	return 0;
   65:     }
   66: #endif /* HAVE_IPV6 */
   67:   return 1;
   68: }
   69: 
   70: static int
   71: is_default (struct prefix *p)
   72: {
   73:   if (p->family == AF_INET)
   74:     if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
   75:       return 1;
   76: #ifdef HAVE_IPV6
   77: #if 0  /* IPv6 default separation is now pending until protocol daemon
   78:           can handle that. */
   79:   if (p->family == AF_INET6)
   80:     if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
   81:       return 1;
   82: #endif /* 0 */
   83: #endif /* HAVE_IPV6 */
   84:   return 0;
   85: }
   86: 
   87: static void
   88: zebra_redistribute_default (struct zserv *client)
   89: {
   90:   struct prefix_ipv4 p;
   91:   struct route_table *table;
   92:   struct route_node *rn;
   93:   struct rib *newrib;
   94: #ifdef HAVE_IPV6
   95:   struct prefix_ipv6 p6;
   96: #endif /* HAVE_IPV6 */
   97: 
   98: 
   99:   /* Lookup default route. */
  100:   memset (&p, 0, sizeof (struct prefix_ipv4));
  101:   p.family = AF_INET;
  102: 
  103:   /* Lookup table.  */
  104:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  105:   if (table)
  106:     {
  107:       rn = route_node_lookup (table, (struct prefix *)&p);
  108:       if (rn)
  109: 	{
  110: 	  for (newrib = rn->info; newrib; newrib = newrib->next)
  111: 	    if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
  112: 		&& newrib->distance != DISTANCE_INFINITY)
  113: 	      zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
  114: 	  route_unlock_node (rn);
  115: 	}
  116:     }
  117: 
  118: #ifdef HAVE_IPV6
  119:   /* Lookup default route. */
  120:   memset (&p6, 0, sizeof (struct prefix_ipv6));
  121:   p6.family = AF_INET6;
  122: 
  123:   /* Lookup table.  */
  124:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  125:   if (table)
  126:     {
  127:       rn = route_node_lookup (table, (struct prefix *)&p6);
  128:       if (rn)
  129: 	{
  130: 	  for (newrib = rn->info; newrib; newrib = newrib->next)
  131: 	    if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
  132: 		&& newrib->distance != DISTANCE_INFINITY)
  133: 	      zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
  134: 	  route_unlock_node (rn);
  135: 	}
  136:     }
  137: #endif /* HAVE_IPV6 */
  138: }
  139: 
  140: /* Redistribute routes. */
  141: static void
  142: zebra_redistribute (struct zserv *client, int type)
  143: {
  144:   struct rib *newrib;
  145:   struct route_table *table;
  146:   struct route_node *rn;
  147: 
  148:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  149:   if (table)
  150:     for (rn = route_top (table); rn; rn = route_next (rn))
  151:       for (newrib = rn->info; newrib; newrib = newrib->next)
  152: 	if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) 
  153: 	    && newrib->type == type 
  154: 	    && newrib->distance != DISTANCE_INFINITY
  155: 	    && zebra_check_addr (&rn->p))
  156: 	  zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
  157:   
  158: #ifdef HAVE_IPV6
  159:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  160:   if (table)
  161:     for (rn = route_top (table); rn; rn = route_next (rn))
  162:       for (newrib = rn->info; newrib; newrib = newrib->next)
  163: 	if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
  164: 	    && newrib->type == type 
  165: 	    && newrib->distance != DISTANCE_INFINITY
  166: 	    && zebra_check_addr (&rn->p))
  167: 	  zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
  168: #endif /* HAVE_IPV6 */
  169: }
  170: 
  171: void
  172: redistribute_add (struct prefix *p, struct rib *rib)
  173: {
  174:   struct listnode *node, *nnode;
  175:   struct zserv *client;
  176: 
  177:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  178:     {
  179:       if (is_default (p))
  180:         {
  181:           if (client->redist_default || client->redist[rib->type])
  182:             {
  183:               if (p->family == AF_INET)
  184:                 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
  185: #ifdef HAVE_IPV6
  186:               if (p->family == AF_INET6)
  187:                 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
  188: #endif /* HAVE_IPV6 */	  
  189: 	    }
  190:         }
  191:       else if (client->redist[rib->type])
  192:         {
  193:           if (p->family == AF_INET)
  194:             zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
  195: #ifdef HAVE_IPV6
  196:           if (p->family == AF_INET6)
  197:             zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
  198: #endif /* HAVE_IPV6 */	  
  199:         }
  200:     }
  201: }
  202: 
  203: void
  204: redistribute_delete (struct prefix *p, struct rib *rib)
  205: {
  206:   struct listnode *node, *nnode;
  207:   struct zserv *client;
  208: 
  209:   /* Add DISTANCE_INFINITY check. */
  210:   if (rib->distance == DISTANCE_INFINITY)
  211:     return;
  212: 
  213:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  214:     {
  215:       if (is_default (p))
  216: 	{
  217: 	  if (client->redist_default || client->redist[rib->type])
  218: 	    {
  219: 	      if (p->family == AF_INET)
  220: 		zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
  221: 				       rib);
  222: #ifdef HAVE_IPV6
  223: 	      if (p->family == AF_INET6)
  224: 		zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
  225: 				       rib);
  226: #endif /* HAVE_IPV6 */
  227: 	    }
  228: 	}
  229:       else if (client->redist[rib->type])
  230: 	{
  231: 	  if (p->family == AF_INET)
  232: 	    zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
  233: #ifdef HAVE_IPV6
  234: 	  if (p->family == AF_INET6)
  235: 	    zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
  236: #endif /* HAVE_IPV6 */
  237: 	}
  238:     }
  239: }
  240: 
  241: void
  242: zebra_redistribute_add (int command, struct zserv *client, int length)
  243: {
  244:   int type;
  245: 
  246:   type = stream_getc (client->ibuf);
  247: 
  248:   switch (type)
  249:     {
  250:     case ZEBRA_ROUTE_KERNEL:
  251:     case ZEBRA_ROUTE_CONNECT:
  252:     case ZEBRA_ROUTE_STATIC:
  253:     case ZEBRA_ROUTE_RIP:
  254:     case ZEBRA_ROUTE_RIPNG:
  255:     case ZEBRA_ROUTE_OSPF:
  256:     case ZEBRA_ROUTE_OSPF6:
  257:     case ZEBRA_ROUTE_BGP:
  258:       if (! client->redist[type])
  259: 	{
  260: 	  client->redist[type] = 1;
  261: 	  zebra_redistribute (client, type);
  262: 	}
  263:       break;
  264:     default:
  265:       break;
  266:     }
  267: }     
  268: 
  269: void
  270: zebra_redistribute_delete (int command, struct zserv *client, int length)
  271: {
  272:   int type;
  273: 
  274:   type = stream_getc (client->ibuf);
  275: 
  276:   switch (type)
  277:     {
  278:     case ZEBRA_ROUTE_KERNEL:
  279:     case ZEBRA_ROUTE_CONNECT:
  280:     case ZEBRA_ROUTE_STATIC:
  281:     case ZEBRA_ROUTE_RIP:
  282:     case ZEBRA_ROUTE_RIPNG:
  283:     case ZEBRA_ROUTE_OSPF:
  284:     case ZEBRA_ROUTE_OSPF6:
  285:     case ZEBRA_ROUTE_BGP:
  286:       client->redist[type] = 0;
  287:       break;
  288:     default:
  289:       break;
  290:     }
  291: }     
  292: 
  293: void
  294: zebra_redistribute_default_add (int command, struct zserv *client, int length)
  295: {
  296:   client->redist_default = 1;
  297:   zebra_redistribute_default (client);
  298: }     
  299: 
  300: void
  301: zebra_redistribute_default_delete (int command, struct zserv *client,
  302: 				   int length)
  303: {
  304:   client->redist_default = 0;;
  305: }     
  306: 
  307: /* Interface up information. */
  308: void
  309: zebra_interface_up_update (struct interface *ifp)
  310: {
  311:   struct listnode *node, *nnode;
  312:   struct zserv *client;
  313: 
  314:   if (IS_ZEBRA_DEBUG_EVENT)
  315:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
  316: 
  317:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  318:     zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
  319: }
  320: 
  321: /* Interface down information. */
  322: void
  323: zebra_interface_down_update (struct interface *ifp)
  324: {
  325:   struct listnode *node, *nnode;
  326:   struct zserv *client;
  327: 
  328:   if (IS_ZEBRA_DEBUG_EVENT)
  329:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
  330: 
  331:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  332:     zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
  333: }
  334: 
  335: /* Interface information update. */
  336: void
  337: zebra_interface_add_update (struct interface *ifp)
  338: {
  339:   struct listnode *node, *nnode;
  340:   struct zserv *client;
  341: 
  342:   if (IS_ZEBRA_DEBUG_EVENT)
  343:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
  344:     
  345:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  346:     if (client->ifinfo)
  347:       zsend_interface_add (client, ifp);
  348: }
  349: 
  350: void
  351: zebra_interface_delete_update (struct interface *ifp)
  352: {
  353:   struct listnode *node, *nnode;
  354:   struct zserv *client;
  355: 
  356:   if (IS_ZEBRA_DEBUG_EVENT)
  357:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
  358: 
  359:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  360:     if (client->ifinfo)
  361:       zsend_interface_delete (client, ifp);
  362: }
  363: 
  364: /* Interface address addition. */
  365: void
  366: zebra_interface_address_add_update (struct interface *ifp,
  367: 				    struct connected *ifc)
  368: {
  369:   struct listnode *node, *nnode;
  370:   struct zserv *client;
  371:   struct prefix *p;
  372: 
  373:   if (IS_ZEBRA_DEBUG_EVENT)
  374:     {
  375:       char buf[INET6_ADDRSTRLEN];
  376: 
  377:       p = ifc->address;
  378:       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
  379: 		  inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
  380: 		  p->prefixlen, ifc->ifp->name);
  381:     }
  382: 
  383:   router_id_add_address(ifc);
  384: 
  385:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  386:     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  387:       zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
  388: }
  389: 
  390: /* Interface address deletion. */
  391: void
  392: zebra_interface_address_delete_update (struct interface *ifp,
  393: 				       struct connected *ifc)
  394: {
  395:   struct listnode *node, *nnode;
  396:   struct zserv *client;
  397:   struct prefix *p;
  398: 
  399:   if (IS_ZEBRA_DEBUG_EVENT)
  400:     {
  401:       char buf[INET6_ADDRSTRLEN];
  402: 
  403:       p = ifc->address;
  404:       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
  405: 		  inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
  406: 		 p->prefixlen, ifc->ifp->name);
  407:     }
  408: 
  409:   router_id_del_address(ifc);
  410: 
  411:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  412:     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  413:       zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
  414: }

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