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

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"
                     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: 
1.1.1.2 ! misho     248:   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
        !           249:     return;
        !           250: 
        !           251:   if (! client->redist[type])
1.1       misho     252:     {
1.1.1.2 ! misho     253:       client->redist[type] = 1;
        !           254:       zebra_redistribute (client, type);
1.1       misho     255:     }
1.1.1.2 ! misho     256: }
1.1       misho     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: 
1.1.1.2 ! misho     265:   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
        !           266:     return;
        !           267: 
        !           268:   client->redist[type] = 0;
        !           269: }
1.1       misho     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>