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

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: 
                    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>