File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / redistribute.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, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, HEAD
quagga

    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:   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
  249:     return;
  250: 
  251:   if (! client->redist[type])
  252:     {
  253:       client->redist[type] = 1;
  254:       zebra_redistribute (client, type);
  255:     }
  256: }
  257: 
  258: void
  259: zebra_redistribute_delete (int command, struct zserv *client, int length)
  260: {
  261:   int type;
  262: 
  263:   type = stream_getc (client->ibuf);
  264: 
  265:   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
  266:     return;
  267: 
  268:   client->redist[type] = 0;
  269: }
  270: 
  271: void
  272: zebra_redistribute_default_add (int command, struct zserv *client, int length)
  273: {
  274:   client->redist_default = 1;
  275:   zebra_redistribute_default (client);
  276: }     
  277: 
  278: void
  279: zebra_redistribute_default_delete (int command, struct zserv *client,
  280: 				   int length)
  281: {
  282:   client->redist_default = 0;;
  283: }     
  284: 
  285: /* Interface up information. */
  286: void
  287: zebra_interface_up_update (struct interface *ifp)
  288: {
  289:   struct listnode *node, *nnode;
  290:   struct zserv *client;
  291: 
  292:   if (IS_ZEBRA_DEBUG_EVENT)
  293:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
  294: 
  295:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  296:     zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
  297: }
  298: 
  299: /* Interface down information. */
  300: void
  301: zebra_interface_down_update (struct interface *ifp)
  302: {
  303:   struct listnode *node, *nnode;
  304:   struct zserv *client;
  305: 
  306:   if (IS_ZEBRA_DEBUG_EVENT)
  307:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
  308: 
  309:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  310:     zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
  311: }
  312: 
  313: /* Interface information update. */
  314: void
  315: zebra_interface_add_update (struct interface *ifp)
  316: {
  317:   struct listnode *node, *nnode;
  318:   struct zserv *client;
  319: 
  320:   if (IS_ZEBRA_DEBUG_EVENT)
  321:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
  322:     
  323:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  324:     if (client->ifinfo)
  325:       zsend_interface_add (client, ifp);
  326: }
  327: 
  328: void
  329: zebra_interface_delete_update (struct interface *ifp)
  330: {
  331:   struct listnode *node, *nnode;
  332:   struct zserv *client;
  333: 
  334:   if (IS_ZEBRA_DEBUG_EVENT)
  335:     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
  336: 
  337:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  338:     if (client->ifinfo)
  339:       zsend_interface_delete (client, ifp);
  340: }
  341: 
  342: /* Interface address addition. */
  343: void
  344: zebra_interface_address_add_update (struct interface *ifp,
  345: 				    struct connected *ifc)
  346: {
  347:   struct listnode *node, *nnode;
  348:   struct zserv *client;
  349:   struct prefix *p;
  350: 
  351:   if (IS_ZEBRA_DEBUG_EVENT)
  352:     {
  353:       char buf[INET6_ADDRSTRLEN];
  354: 
  355:       p = ifc->address;
  356:       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
  357: 		  inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
  358: 		  p->prefixlen, ifc->ifp->name);
  359:     }
  360: 
  361:   router_id_add_address(ifc);
  362: 
  363:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  364:     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  365:       zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
  366: }
  367: 
  368: /* Interface address deletion. */
  369: void
  370: zebra_interface_address_delete_update (struct interface *ifp,
  371: 				       struct connected *ifc)
  372: {
  373:   struct listnode *node, *nnode;
  374:   struct zserv *client;
  375:   struct prefix *p;
  376: 
  377:   if (IS_ZEBRA_DEBUG_EVENT)
  378:     {
  379:       char buf[INET6_ADDRSTRLEN];
  380: 
  381:       p = ifc->address;
  382:       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
  383: 		  inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
  384: 		 p->prefixlen, ifc->ifp->name);
  385:     }
  386: 
  387:   router_id_del_address(ifc);
  388: 
  389:   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
  390:     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  391:       zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
  392: }

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