Annotation of embedaddon/quagga/zebra/redistribute.c, revision 1.1.1.4

1.1       misho       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"
1.1.1.4 ! misho      33: #include "vrf.h"
1.1       misho      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: 
1.1.1.4 ! misho      71: int
1.1       misho      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
1.1.1.4 ! misho      89: zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
1.1       misho      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.  */
1.1.1.4 ! misho     105:   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1.1       misho     106:   if (table)
                    107:     {
                    108:       rn = route_node_lookup (table, (struct prefix *)&p);
                    109:       if (rn)
                    110:        {
1.1.1.3   misho     111:          RNODE_FOREACH_RIB (rn, newrib)
1.1       misho     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.  */
1.1.1.4 ! misho     125:   table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
1.1       misho     126:   if (table)
                    127:     {
                    128:       rn = route_node_lookup (table, (struct prefix *)&p6);
                    129:       if (rn)
                    130:        {
1.1.1.3   misho     131:          RNODE_FOREACH_RIB (rn, newrib)
1.1       misho     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
1.1.1.4 ! misho     143: zebra_redistribute (struct zserv *client, int type, vrf_id_t vrf_id)
1.1       misho     144: {
                    145:   struct rib *newrib;
                    146:   struct route_table *table;
                    147:   struct route_node *rn;
                    148: 
1.1.1.4 ! misho     149:   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1.1       misho     150:   if (table)
                    151:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3   misho     152:       RNODE_FOREACH_RIB (rn, newrib)
1.1.1.4 ! misho     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: 
1.1       misho     165: #ifdef HAVE_IPV6
1.1.1.4 ! misho     166:   table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
1.1       misho     167:   if (table)
                    168:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3   misho     169:       RNODE_FOREACH_RIB (rn, newrib)
1.1       misho     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:     {
1.1.1.4 ! misho     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))
1.1       misho     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:     {
1.1.1.4 ! misho     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))
1.1       misho     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
1.1.1.4 ! misho     227: zebra_redistribute_add (int command, struct zserv *client, int length,
        !           228:     vrf_id_t vrf_id)
1.1       misho     229: {
                    230:   int type;
                    231: 
                    232:   type = stream_getc (client->ibuf);
                    233: 
1.1.1.2   misho     234:   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
                    235:     return;
                    236: 
1.1.1.4 ! misho     237:   if (! vrf_bitmap_check (client->redist[type], vrf_id))
1.1       misho     238:     {
1.1.1.4 ! misho     239:       vrf_bitmap_set (client->redist[type], vrf_id);
        !           240:       zebra_redistribute (client, type, vrf_id);
1.1       misho     241:     }
1.1.1.2   misho     242: }
1.1       misho     243: 
                    244: void
1.1.1.4 ! misho     245: zebra_redistribute_delete (int command, struct zserv *client, int length,
        !           246:     vrf_id_t vrf_id)
1.1       misho     247: {
                    248:   int type;
                    249: 
                    250:   type = stream_getc (client->ibuf);
                    251: 
1.1.1.2   misho     252:   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
                    253:     return;
                    254: 
1.1.1.4 ! misho     255:   vrf_bitmap_unset (client->redist[type], vrf_id);
1.1.1.2   misho     256: }
1.1       misho     257: 
                    258: void
1.1.1.4 ! misho     259: zebra_redistribute_default_add (int command, struct zserv *client, int length,
        !           260:     vrf_id_t vrf_id)
1.1       misho     261: {
1.1.1.4 ! misho     262:   vrf_bitmap_set (client->redist_default, vrf_id);
        !           263:   zebra_redistribute_default (client, vrf_id);
1.1       misho     264: }     
                    265: 
                    266: void
                    267: zebra_redistribute_default_delete (int command, struct zserv *client,
1.1.1.4 ! misho     268:     int length, vrf_id_t vrf_id)
1.1       misho     269: {
1.1.1.4 ! misho     270:   vrf_bitmap_unset (client->redist_default, vrf_id);
1.1       misho     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:     {
1.1.1.4 ! misho     341:       char buf[PREFIX_STRLEN];
1.1       misho     342: 
                    343:       p = ifc->address;
1.1.1.4 ! misho     344:       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
        !           345:                  prefix2str (p, buf, sizeof(buf)),
        !           346:                  ifc->ifp->name);
1.1       misho     347:     }
                    348: 
1.1.1.4 ! misho     349:   if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
        !           350:     zlog_warn("WARNING: advertising address to clients that is not yet usable.");
        !           351: 
1.1       misho     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:     {
1.1.1.4 ! misho     370:       char buf[PREFIX_STRLEN];
1.1       misho     371: 
                    372:       p = ifc->address;
1.1.1.4 ! misho     373:       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
        !           374:                  prefix2str (p, buf, sizeof(buf)),
        !           375:                  ifc->ifp->name);
1.1       misho     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>