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

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

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