Annotation of embedaddon/quagga/zebra/zebra_rib.c, revision 1.1.1.3

1.1       misho       1: /* Routing Information Base.
                      2:  * Copyright (C) 1997, 98, 99, 2001 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 "prefix.h"
                     25: #include "table.h"
                     26: #include "memory.h"
                     27: #include "str.h"
                     28: #include "command.h"
                     29: #include "if.h"
                     30: #include "log.h"
                     31: #include "sockunion.h"
                     32: #include "linklist.h"
                     33: #include "thread.h"
                     34: #include "workqueue.h"
                     35: #include "prefix.h"
                     36: #include "routemap.h"
                     37: 
                     38: #include "zebra/rib.h"
                     39: #include "zebra/rt.h"
                     40: #include "zebra/zserv.h"
                     41: #include "zebra/redistribute.h"
                     42: #include "zebra/debug.h"
1.1.1.3 ! misho      43: #include "zebra/zebra_fpm.h"
1.1       misho      44: 
                     45: /* Default rtm_table for all clients */
                     46: extern struct zebra_t zebrad;
                     47: 
                     48: /* Hold time for RIB process, should be very minimal.
                     49:  * it is useful to able to set it otherwise for testing, hence exported
                     50:  * as global here for test-rig code.
                     51:  */
                     52: int rib_process_hold_time = 10;
                     53: 
                     54: /* Each route type's string and default distance value. */
                     55: static const struct
                     56: {  
                     57:   int key;
                     58:   int distance;
1.1.1.2   misho      59: } route_info[ZEBRA_ROUTE_MAX] =
1.1       misho      60: {
1.1.1.2   misho      61:   [ZEBRA_ROUTE_SYSTEM]  = {ZEBRA_ROUTE_SYSTEM,    0},
                     62:   [ZEBRA_ROUTE_KERNEL]  = {ZEBRA_ROUTE_KERNEL,    0},
                     63:   [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT,   0},
                     64:   [ZEBRA_ROUTE_STATIC]  = {ZEBRA_ROUTE_STATIC,    1},
                     65:   [ZEBRA_ROUTE_RIP]     = {ZEBRA_ROUTE_RIP,     120},
                     66:   [ZEBRA_ROUTE_RIPNG]   = {ZEBRA_ROUTE_RIPNG,   120},
                     67:   [ZEBRA_ROUTE_OSPF]    = {ZEBRA_ROUTE_OSPF,    110},
                     68:   [ZEBRA_ROUTE_OSPF6]   = {ZEBRA_ROUTE_OSPF6,   110},
                     69:   [ZEBRA_ROUTE_ISIS]    = {ZEBRA_ROUTE_ISIS,    115},
                     70:   [ZEBRA_ROUTE_BGP]     = {ZEBRA_ROUTE_BGP,      20  /* IBGP is 200. */},
                     71:   [ZEBRA_ROUTE_BABEL]   = {ZEBRA_ROUTE_BABEL,    95},
                     72:   /* no entry/default: 150 */
1.1       misho      73: };
                     74: 
                     75: /* Vector for routing table.  */
                     76: static vector vrf_vector;
                     77: 
1.1.1.3 ! misho      78: /*
        !            79:  * vrf_table_create
        !            80:  */
        !            81: static void
        !            82: vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
        !            83: {
        !            84:   rib_table_info_t *info;
        !            85:   struct route_table *table;
        !            86: 
        !            87:   assert (!vrf->table[afi][safi]);
        !            88: 
        !            89:   table = route_table_init ();
        !            90:   vrf->table[afi][safi] = table;
        !            91: 
        !            92:   info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
        !            93:   info->vrf = vrf;
        !            94:   info->afi = afi;
        !            95:   info->safi = safi;
        !            96:   table->info = info;
        !            97: }
        !            98: 
1.1       misho      99: /* Allocate new VRF.  */
                    100: static struct vrf *
                    101: vrf_alloc (const char *name)
                    102: {
                    103:   struct vrf *vrf;
                    104: 
                    105:   vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
                    106: 
                    107:   /* Put name.  */
                    108:   if (name)
                    109:     vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
                    110: 
                    111:   /* Allocate routing table and static table.  */
1.1.1.3 ! misho     112:   vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
        !           113:   vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
1.1       misho     114:   vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
                    115:   vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
1.1.1.3 ! misho     116:   vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
        !           117:   vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
1.1.1.2   misho     118:   vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
                    119:   vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
                    120: 
1.1       misho     121: 
                    122:   return vrf;
                    123: }
                    124: 
                    125: /* Lookup VRF by identifier.  */
                    126: struct vrf *
                    127: vrf_lookup (u_int32_t id)
                    128: {
                    129:   return vector_lookup (vrf_vector, id);
                    130: }
                    131: 
                    132: /* Initialize VRF.  */
                    133: static void
                    134: vrf_init (void)
                    135: {
                    136:   struct vrf *default_table;
                    137: 
                    138:   /* Allocate VRF vector.  */
                    139:   vrf_vector = vector_init (1);
                    140: 
                    141:   /* Allocate default main table.  */
                    142:   default_table = vrf_alloc ("Default-IP-Routing-Table");
                    143: 
                    144:   /* Default table index must be 0.  */
                    145:   vector_set_index (vrf_vector, 0, default_table);
                    146: }
                    147: 
                    148: /* Lookup route table.  */
                    149: struct route_table *
                    150: vrf_table (afi_t afi, safi_t safi, u_int32_t id)
                    151: {
                    152:   struct vrf *vrf;
                    153: 
                    154:   vrf = vrf_lookup (id);
                    155:   if (! vrf)
                    156:     return NULL;
                    157: 
1.1.1.3 ! misho     158:   if( afi >= AFI_MAX  || safi >= SAFI_MAX )
        !           159:     return NULL;
        !           160: 
1.1       misho     161:   return vrf->table[afi][safi];
                    162: }
                    163: 
                    164: /* Lookup static route table.  */
                    165: struct route_table *
                    166: vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
                    167: {
                    168:   struct vrf *vrf;
                    169: 
                    170:   vrf = vrf_lookup (id);
                    171:   if (! vrf)
                    172:     return NULL;
                    173: 
1.1.1.3 ! misho     174:   if( afi >= AFI_MAX  || safi >= SAFI_MAX )
        !           175:     return NULL;
        !           176: 
1.1       misho     177:   return vrf->stable[afi][safi];
                    178: }
                    179: 
1.1.1.3 ! misho     180: /*
        !           181:  * nexthop_type_to_str
        !           182:  */
        !           183: const char *
        !           184: nexthop_type_to_str (enum nexthop_types_t nh_type)
        !           185: {
        !           186:   static const char *desc[] = {
        !           187:     "none",
        !           188:     "Directly connected",
        !           189:     "Interface route",
        !           190:     "IPv4 nexthop",
        !           191:     "IPv4 nexthop with ifindex",
        !           192:     "IPv4 nexthop with ifname",
        !           193:     "IPv6 nexthop",
        !           194:     "IPv6 nexthop with ifindex",
        !           195:     "IPv6 nexthop with ifname",
        !           196:     "Null0 nexthop",
        !           197:   };
        !           198: 
        !           199:   if (nh_type >= ZEBRA_NUM_OF (desc))
        !           200:     return "<Invalid nh type>";
        !           201: 
        !           202:   return desc[nh_type];
        !           203: }
        !           204: 
1.1       misho     205: /* Add nexthop to the end of the list.  */
                    206: static void
                    207: nexthop_add (struct rib *rib, struct nexthop *nexthop)
                    208: {
                    209:   struct nexthop *last;
                    210: 
                    211:   for (last = rib->nexthop; last && last->next; last = last->next)
                    212:     ;
                    213:   if (last)
                    214:     last->next = nexthop;
                    215:   else
                    216:     rib->nexthop = nexthop;
                    217:   nexthop->prev = last;
                    218: 
                    219:   rib->nexthop_num++;
                    220: }
                    221: 
                    222: /* Delete specified nexthop from the list. */
                    223: static void
                    224: nexthop_delete (struct rib *rib, struct nexthop *nexthop)
                    225: {
                    226:   if (nexthop->next)
                    227:     nexthop->next->prev = nexthop->prev;
                    228:   if (nexthop->prev)
                    229:     nexthop->prev->next = nexthop->next;
                    230:   else
                    231:     rib->nexthop = nexthop->next;
                    232:   rib->nexthop_num--;
                    233: }
                    234: 
                    235: /* Free nexthop. */
                    236: static void
                    237: nexthop_free (struct nexthop *nexthop)
                    238: {
                    239:   if (nexthop->ifname)
                    240:     XFREE (0, nexthop->ifname);
                    241:   XFREE (MTYPE_NEXTHOP, nexthop);
                    242: }
                    243: 
                    244: struct nexthop *
                    245: nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
                    246: {
                    247:   struct nexthop *nexthop;
                    248: 
                    249:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    250:   nexthop->type = NEXTHOP_TYPE_IFINDEX;
                    251:   nexthop->ifindex = ifindex;
                    252: 
                    253:   nexthop_add (rib, nexthop);
                    254: 
                    255:   return nexthop;
                    256: }
                    257: 
                    258: struct nexthop *
                    259: nexthop_ifname_add (struct rib *rib, char *ifname)
                    260: {
                    261:   struct nexthop *nexthop;
                    262: 
                    263:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    264:   nexthop->type = NEXTHOP_TYPE_IFNAME;
                    265:   nexthop->ifname = XSTRDUP (0, ifname);
                    266: 
                    267:   nexthop_add (rib, nexthop);
                    268: 
                    269:   return nexthop;
                    270: }
                    271: 
                    272: struct nexthop *
                    273: nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
                    274: {
                    275:   struct nexthop *nexthop;
                    276: 
                    277:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    278:   nexthop->type = NEXTHOP_TYPE_IPV4;
                    279:   nexthop->gate.ipv4 = *ipv4;
                    280:   if (src)
                    281:     nexthop->src.ipv4 = *src;
                    282: 
                    283:   nexthop_add (rib, nexthop);
                    284: 
                    285:   return nexthop;
                    286: }
                    287: 
1.1.1.2   misho     288: struct nexthop *
1.1       misho     289: nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, 
                    290:                           struct in_addr *src, unsigned int ifindex)
                    291: {
                    292:   struct nexthop *nexthop;
                    293: 
                    294:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    295:   nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
                    296:   nexthop->gate.ipv4 = *ipv4;
                    297:   if (src)
                    298:     nexthop->src.ipv4 = *src;
                    299:   nexthop->ifindex = ifindex;
                    300: 
                    301:   nexthop_add (rib, nexthop);
                    302: 
                    303:   return nexthop;
                    304: }
                    305: 
                    306: #ifdef HAVE_IPV6
                    307: struct nexthop *
                    308: nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
                    309: {
                    310:   struct nexthop *nexthop;
                    311: 
                    312:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    313:   nexthop->type = NEXTHOP_TYPE_IPV6;
                    314:   nexthop->gate.ipv6 = *ipv6;
                    315: 
                    316:   nexthop_add (rib, nexthop);
                    317: 
                    318:   return nexthop;
                    319: }
                    320: 
                    321: static struct nexthop *
                    322: nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
                    323:                         char *ifname)
                    324: {
                    325:   struct nexthop *nexthop;
                    326: 
                    327:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    328:   nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
                    329:   nexthop->gate.ipv6 = *ipv6;
                    330:   nexthop->ifname = XSTRDUP (0, ifname);
                    331: 
                    332:   nexthop_add (rib, nexthop);
                    333: 
                    334:   return nexthop;
                    335: }
                    336: 
                    337: static struct nexthop *
                    338: nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
                    339:                          unsigned int ifindex)
                    340: {
                    341:   struct nexthop *nexthop;
                    342: 
                    343:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    344:   nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
                    345:   nexthop->gate.ipv6 = *ipv6;
                    346:   nexthop->ifindex = ifindex;
                    347: 
                    348:   nexthop_add (rib, nexthop);
                    349: 
                    350:   return nexthop;
                    351: }
                    352: #endif /* HAVE_IPV6 */
                    353: 
                    354: struct nexthop *
                    355: nexthop_blackhole_add (struct rib *rib)
                    356: {
                    357:   struct nexthop *nexthop;
                    358: 
                    359:   nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
                    360:   nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
                    361:   SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
                    362: 
                    363:   nexthop_add (rib, nexthop);
                    364: 
                    365:   return nexthop;
                    366: }
                    367: 
                    368: /* If force flag is not set, do not modify falgs at all for uninstall
                    369:    the route from FIB. */
                    370: static int
                    371: nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
                    372:                     struct route_node *top)
                    373: {
                    374:   struct prefix_ipv4 p;
                    375:   struct route_table *table;
                    376:   struct route_node *rn;
                    377:   struct rib *match;
                    378:   struct nexthop *newhop;
                    379: 
                    380:   if (nexthop->type == NEXTHOP_TYPE_IPV4)
                    381:     nexthop->ifindex = 0;
                    382: 
                    383:   if (set)
                    384:     UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
                    385: 
                    386:   /* Make lookup prefix. */
                    387:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    388:   p.family = AF_INET;
                    389:   p.prefixlen = IPV4_MAX_PREFIXLEN;
                    390:   p.prefix = nexthop->gate.ipv4;
                    391: 
                    392:   /* Lookup table.  */
                    393:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                    394:   if (! table)
                    395:     return 0;
                    396: 
                    397:   rn = route_node_match (table, (struct prefix *) &p);
                    398:   while (rn)
                    399:     {
                    400:       route_unlock_node (rn);
                    401:       
                    402:       /* If lookup self prefix return immediately. */
                    403:       if (rn == top)
                    404:        return 0;
                    405: 
                    406:       /* Pick up selected route. */
1.1.1.3 ! misho     407:       RNODE_FOREACH_RIB (rn, match)
1.1       misho     408:        {
                    409:          if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
                    410:            continue;
                    411:          if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
                    412:            break;
                    413:        }
                    414: 
                    415:       /* If there is no selected route or matched route is EGP, go up
                    416:          tree. */
                    417:       if (! match 
                    418:          || match->type == ZEBRA_ROUTE_BGP)
                    419:        {
                    420:          do {
                    421:            rn = rn->parent;
                    422:          } while (rn && rn->info == NULL);
                    423:          if (rn)
                    424:            route_lock_node (rn);
                    425:        }
                    426:       else
                    427:        {
                    428:          if (match->type == ZEBRA_ROUTE_CONNECT)
                    429:            {
                    430:              /* Directly point connected route. */
                    431:              newhop = match->nexthop;
                    432:              if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
                    433:                nexthop->ifindex = newhop->ifindex;
                    434:              
                    435:              return 1;
                    436:            }
                    437:          else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
                    438:            {
                    439:              for (newhop = match->nexthop; newhop; newhop = newhop->next)
                    440:                if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
                    441:                    && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
                    442:                  {
                    443:                    if (set)
                    444:                      {
                    445:                        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
                    446:                        nexthop->rtype = newhop->type;
                    447:                        if (newhop->type == NEXTHOP_TYPE_IPV4 ||
                    448:                            newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
                    449:                          nexthop->rgate.ipv4 = newhop->gate.ipv4;
                    450:                        if (newhop->type == NEXTHOP_TYPE_IFINDEX
                    451:                            || newhop->type == NEXTHOP_TYPE_IFNAME
                    452:                            || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
                    453:                          nexthop->rifindex = newhop->ifindex;
                    454:                      }
                    455:                    return 1;
                    456:                  }
                    457:              return 0;
                    458:            }
                    459:          else
                    460:            {
                    461:              return 0;
                    462:            }
                    463:        }
                    464:     }
                    465:   return 0;
                    466: }
                    467: 
                    468: #ifdef HAVE_IPV6
                    469: /* If force flag is not set, do not modify falgs at all for uninstall
                    470:    the route from FIB. */
                    471: static int
                    472: nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
                    473:                     struct route_node *top)
                    474: {
                    475:   struct prefix_ipv6 p;
                    476:   struct route_table *table;
                    477:   struct route_node *rn;
                    478:   struct rib *match;
                    479:   struct nexthop *newhop;
                    480: 
                    481:   if (nexthop->type == NEXTHOP_TYPE_IPV6)
                    482:     nexthop->ifindex = 0;
                    483: 
                    484:   if (set)
                    485:     UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
                    486: 
                    487:   /* Make lookup prefix. */
                    488:   memset (&p, 0, sizeof (struct prefix_ipv6));
                    489:   p.family = AF_INET6;
                    490:   p.prefixlen = IPV6_MAX_PREFIXLEN;
                    491:   p.prefix = nexthop->gate.ipv6;
                    492: 
                    493:   /* Lookup table.  */
                    494:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
                    495:   if (! table)
                    496:     return 0;
                    497: 
                    498:   rn = route_node_match (table, (struct prefix *) &p);
                    499:   while (rn)
                    500:     {
                    501:       route_unlock_node (rn);
                    502:       
                    503:       /* If lookup self prefix return immediately. */
                    504:       if (rn == top)
                    505:        return 0;
                    506: 
                    507:       /* Pick up selected route. */
1.1.1.3 ! misho     508:       RNODE_FOREACH_RIB (rn, match)
1.1       misho     509:        {
                    510:          if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
                    511:            continue;
                    512:          if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
                    513:            break;
                    514:        }
                    515: 
                    516:       /* If there is no selected route or matched route is EGP, go up
                    517:          tree. */
                    518:       if (! match
                    519:          || match->type == ZEBRA_ROUTE_BGP)
                    520:        {
                    521:          do {
                    522:            rn = rn->parent;
                    523:          } while (rn && rn->info == NULL);
                    524:          if (rn)
                    525:            route_lock_node (rn);
                    526:        }
                    527:       else
                    528:        {
                    529:          if (match->type == ZEBRA_ROUTE_CONNECT)
                    530:            {
                    531:              /* Directly point connected route. */
                    532:              newhop = match->nexthop;
                    533: 
                    534:              if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
                    535:                nexthop->ifindex = newhop->ifindex;
                    536:              
                    537:              return 1;
                    538:            }
                    539:          else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
                    540:            {
                    541:              for (newhop = match->nexthop; newhop; newhop = newhop->next)
                    542:                if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
                    543:                    && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
                    544:                  {
                    545:                    if (set)
                    546:                      {
                    547:                        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
                    548:                        nexthop->rtype = newhop->type;
                    549:                        if (newhop->type == NEXTHOP_TYPE_IPV6
                    550:                            || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
                    551:                            || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
                    552:                          nexthop->rgate.ipv6 = newhop->gate.ipv6;
                    553:                        if (newhop->type == NEXTHOP_TYPE_IFINDEX
                    554:                            || newhop->type == NEXTHOP_TYPE_IFNAME
                    555:                            || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
                    556:                            || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
                    557:                          nexthop->rifindex = newhop->ifindex;
                    558:                      }
                    559:                    return 1;
                    560:                  }
                    561:              return 0;
                    562:            }
                    563:          else
                    564:            {
                    565:              return 0;
                    566:            }
                    567:        }
                    568:     }
                    569:   return 0;
                    570: }
                    571: #endif /* HAVE_IPV6 */
                    572: 
                    573: struct rib *
                    574: rib_match_ipv4 (struct in_addr addr)
                    575: {
                    576:   struct prefix_ipv4 p;
                    577:   struct route_table *table;
                    578:   struct route_node *rn;
                    579:   struct rib *match;
                    580:   struct nexthop *newhop;
                    581: 
                    582:   /* Lookup table.  */
                    583:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                    584:   if (! table)
                    585:     return 0;
                    586: 
                    587:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    588:   p.family = AF_INET;
                    589:   p.prefixlen = IPV4_MAX_PREFIXLEN;
                    590:   p.prefix = addr;
                    591: 
                    592:   rn = route_node_match (table, (struct prefix *) &p);
                    593: 
                    594:   while (rn)
                    595:     {
                    596:       route_unlock_node (rn);
                    597:       
                    598:       /* Pick up selected route. */
1.1.1.3 ! misho     599:       RNODE_FOREACH_RIB (rn, match)
1.1       misho     600:        {
                    601:          if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
                    602:            continue;
                    603:          if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
                    604:            break;
                    605:        }
                    606: 
                    607:       /* If there is no selected route or matched route is EGP, go up
                    608:          tree. */
                    609:       if (! match 
                    610:          || match->type == ZEBRA_ROUTE_BGP)
                    611:        {
                    612:          do {
                    613:            rn = rn->parent;
                    614:          } while (rn && rn->info == NULL);
                    615:          if (rn)
                    616:            route_lock_node (rn);
                    617:        }
                    618:       else
                    619:        {
                    620:          if (match->type == ZEBRA_ROUTE_CONNECT)
                    621:            /* Directly point connected route. */
                    622:            return match;
                    623:          else
                    624:            {
                    625:              for (newhop = match->nexthop; newhop; newhop = newhop->next)
                    626:                if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
                    627:                  return match;
                    628:              return NULL;
                    629:            }
                    630:        }
                    631:     }
                    632:   return NULL;
                    633: }
                    634: 
                    635: struct rib *
                    636: rib_lookup_ipv4 (struct prefix_ipv4 *p)
                    637: {
                    638:   struct route_table *table;
                    639:   struct route_node *rn;
                    640:   struct rib *match;
                    641:   struct nexthop *nexthop;
                    642: 
                    643:   /* Lookup table.  */
                    644:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                    645:   if (! table)
                    646:     return 0;
                    647: 
                    648:   rn = route_node_lookup (table, (struct prefix *) p);
                    649: 
                    650:   /* No route for this prefix. */
                    651:   if (! rn)
                    652:     return NULL;
                    653: 
                    654:   /* Unlock node. */
                    655:   route_unlock_node (rn);
                    656: 
1.1.1.3 ! misho     657:   RNODE_FOREACH_RIB (rn, match)
1.1       misho     658:     {
                    659:       if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
                    660:        continue;
                    661:       if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
                    662:        break;
                    663:     }
                    664: 
                    665:   if (! match || match->type == ZEBRA_ROUTE_BGP)
                    666:     return NULL;
                    667: 
                    668:   if (match->type == ZEBRA_ROUTE_CONNECT)
                    669:     return match;
                    670:   
                    671:   for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
                    672:     if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                    673:       return match;
                    674: 
                    675:   return NULL;
                    676: }
                    677: 
                    678: /*
                    679:  * This clone function, unlike its original rib_lookup_ipv4(), checks
                    680:  * if specified IPv4 route record (prefix/mask -> gate) exists in
                    681:  * the whole RIB and has ZEBRA_FLAG_SELECTED set.
                    682:  *
                    683:  * Return values:
                    684:  * -1: error
                    685:  * 0: exact match found
                    686:  * 1: a match was found with a different gate
                    687:  * 2: connected route found
                    688:  * 3: no matches found
                    689:  */
                    690: int
                    691: rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
                    692: {
                    693:   struct route_table *table;
                    694:   struct route_node *rn;
                    695:   struct rib *match;
                    696:   struct nexthop *nexthop;
                    697: 
                    698:   /* Lookup table.  */
                    699:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                    700:   if (! table)
                    701:     return ZEBRA_RIB_LOOKUP_ERROR;
                    702: 
                    703:   /* Scan the RIB table for exactly matching RIB entry. */
                    704:   rn = route_node_lookup (table, (struct prefix *) p);
                    705: 
                    706:   /* No route for this prefix. */
                    707:   if (! rn)
                    708:     return ZEBRA_RIB_NOTFOUND;
                    709: 
                    710:   /* Unlock node. */
                    711:   route_unlock_node (rn);
                    712: 
                    713:   /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
1.1.1.3 ! misho     714:   RNODE_FOREACH_RIB (rn, match)
1.1       misho     715:     {
                    716:       if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
                    717:        continue;
                    718:       if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
                    719:        break;
                    720:     }
                    721: 
                    722:   /* None such found :( */
                    723:   if (!match)
                    724:     return ZEBRA_RIB_NOTFOUND;
                    725: 
                    726:   if (match->type == ZEBRA_ROUTE_CONNECT)
                    727:     return ZEBRA_RIB_FOUND_CONNECTED;
                    728:   
                    729:   /* Ok, we have a cood candidate, let's check it's nexthop list... */
                    730:   for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
                    731:     if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                    732:     {
                    733:       /* We are happy with either direct or recursive hexthop */
1.1.1.3 ! misho     734:       if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
        !           735:           nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
1.1       misho     736:         return ZEBRA_RIB_FOUND_EXACT;
                    737:       else
                    738:       {
                    739:         if (IS_ZEBRA_DEBUG_RIB)
                    740:         {
                    741:           char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
                    742:           inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
                    743:           inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
1.1.1.3 ! misho     744:           inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
1.1       misho     745:           zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
                    746:         }
                    747:         return ZEBRA_RIB_FOUND_NOGATE;
                    748:       }
                    749:     }
                    750: 
                    751:   return ZEBRA_RIB_NOTFOUND;
                    752: }
                    753: 
                    754: #ifdef HAVE_IPV6
                    755: struct rib *
                    756: rib_match_ipv6 (struct in6_addr *addr)
                    757: {
                    758:   struct prefix_ipv6 p;
                    759:   struct route_table *table;
                    760:   struct route_node *rn;
                    761:   struct rib *match;
                    762:   struct nexthop *newhop;
                    763: 
                    764:   /* Lookup table.  */
                    765:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
                    766:   if (! table)
                    767:     return 0;
                    768: 
                    769:   memset (&p, 0, sizeof (struct prefix_ipv6));
                    770:   p.family = AF_INET6;
                    771:   p.prefixlen = IPV6_MAX_PREFIXLEN;
                    772:   IPV6_ADDR_COPY (&p.prefix, addr);
                    773: 
                    774:   rn = route_node_match (table, (struct prefix *) &p);
                    775: 
                    776:   while (rn)
                    777:     {
                    778:       route_unlock_node (rn);
                    779:       
                    780:       /* Pick up selected route. */
1.1.1.3 ! misho     781:       RNODE_FOREACH_RIB (rn, match)
1.1       misho     782:        {
                    783:          if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
                    784:            continue;
                    785:          if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
                    786:            break;
                    787:        }
                    788: 
                    789:       /* If there is no selected route or matched route is EGP, go up
                    790:          tree. */
                    791:       if (! match 
                    792:          || match->type == ZEBRA_ROUTE_BGP)
                    793:        {
                    794:          do {
                    795:            rn = rn->parent;
                    796:          } while (rn && rn->info == NULL);
                    797:          if (rn)
                    798:            route_lock_node (rn);
                    799:        }
                    800:       else
                    801:        {
                    802:          if (match->type == ZEBRA_ROUTE_CONNECT)
                    803:            /* Directly point connected route. */
                    804:            return match;
                    805:          else
                    806:            {
                    807:              for (newhop = match->nexthop; newhop; newhop = newhop->next)
                    808:                if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
                    809:                  return match;
                    810:              return NULL;
                    811:            }
                    812:        }
                    813:     }
                    814:   return NULL;
                    815: }
                    816: #endif /* HAVE_IPV6 */
                    817: 
                    818: #define RIB_SYSTEM_ROUTE(R) \
                    819:         ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
                    820: 
                    821: /* This function verifies reachability of one given nexthop, which can be
                    822:  * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
                    823:  * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
                    824:  * nexthop->ifindex will be updated appropriately as well.
                    825:  * An existing route map can turn (otherwise active) nexthop into inactive, but
                    826:  * not vice versa.
                    827:  *
                    828:  * The return value is the final value of 'ACTIVE' flag.
                    829:  */
                    830: 
                    831: static unsigned
                    832: nexthop_active_check (struct route_node *rn, struct rib *rib,
                    833:                      struct nexthop *nexthop, int set)
                    834: {
                    835:   struct interface *ifp;
                    836:   route_map_result_t ret = RMAP_MATCH;
                    837:   extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
                    838:   struct route_map *rmap;
                    839:   int family;
                    840: 
                    841:   family = 0;
                    842:   switch (nexthop->type)
                    843:     {
                    844:     case NEXTHOP_TYPE_IFINDEX:
                    845:       ifp = if_lookup_by_index (nexthop->ifindex);
                    846:       if (ifp && if_is_operative(ifp))
                    847:        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    848:       else
                    849:        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    850:       break;
                    851:     case NEXTHOP_TYPE_IPV6_IFNAME:
                    852:       family = AFI_IP6;
                    853:     case NEXTHOP_TYPE_IFNAME:
                    854:       ifp = if_lookup_by_name (nexthop->ifname);
                    855:       if (ifp && if_is_operative(ifp))
                    856:        {
                    857:          if (set)
                    858:            nexthop->ifindex = ifp->ifindex;
                    859:          SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    860:        }
                    861:       else
                    862:        {
                    863:          if (set)
                    864:            nexthop->ifindex = 0;
                    865:          UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    866:        }
                    867:       break;
                    868:     case NEXTHOP_TYPE_IPV4:
                    869:     case NEXTHOP_TYPE_IPV4_IFINDEX:
                    870:       family = AFI_IP;
                    871:       if (nexthop_active_ipv4 (rib, nexthop, set, rn))
                    872:        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    873:       else
                    874:        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    875:       break;
                    876: #ifdef HAVE_IPV6
                    877:     case NEXTHOP_TYPE_IPV6:
                    878:       family = AFI_IP6;
                    879:       if (nexthop_active_ipv6 (rib, nexthop, set, rn))
                    880:        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    881:       else
                    882:        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    883:       break;
                    884:     case NEXTHOP_TYPE_IPV6_IFINDEX:
                    885:       family = AFI_IP6;
                    886:       if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
                    887:        {
                    888:          ifp = if_lookup_by_index (nexthop->ifindex);
                    889:          if (ifp && if_is_operative(ifp))
                    890:            SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    891:          else
                    892:            UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    893:        }
                    894:       else
                    895:        {
                    896:          if (nexthop_active_ipv6 (rib, nexthop, set, rn))
                    897:            SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    898:          else
                    899:            UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    900:        }
                    901:       break;
                    902: #endif /* HAVE_IPV6 */
                    903:     case NEXTHOP_TYPE_BLACKHOLE:
                    904:       SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    905:       break;
                    906:     default:
                    907:       break;
                    908:     }
                    909:   if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                    910:     return 0;
                    911: 
                    912:   if (RIB_SYSTEM_ROUTE(rib) ||
                    913:       (family == AFI_IP && rn->p.family != AF_INET) ||
                    914:       (family == AFI_IP6 && rn->p.family != AF_INET6))
                    915:     return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    916: 
                    917:   rmap = 0;
                    918:   if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
                    919:                proto_rm[family][rib->type])
                    920:     rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
                    921:   if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
                    922:     rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
                    923:   if (rmap) {
                    924:       ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
                    925:   }
                    926: 
                    927:   if (ret == RMAP_DENYMATCH)
                    928:     UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    929:   return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    930: }
                    931: 
                    932: /* Iterate over all nexthops of the given RIB entry and refresh their
                    933:  * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
                    934:  * nexthop is found to toggle the ACTIVE flag, the whole rib structure
                    935:  * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
                    936:  * transparently passed to nexthop_active_check().
                    937:  *
                    938:  * Return value is the new number of active nexthops.
                    939:  */
                    940: 
                    941: static int
                    942: nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
                    943: {
                    944:   struct nexthop *nexthop;
                    945:   unsigned int prev_active, prev_index, new_active;
                    946: 
                    947:   rib->nexthop_active_num = 0;
                    948:   UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
                    949: 
                    950:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                    951:   {
                    952:     prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                    953:     prev_index = nexthop->ifindex;
                    954:     if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
                    955:       rib->nexthop_active_num++;
                    956:     if (prev_active != new_active ||
                    957:        prev_index != nexthop->ifindex)
                    958:       SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
                    959:   }
                    960:   return rib->nexthop_active_num;
                    961: }
                    962: 
                    963: 
                    964: 
                    965: static void
                    966: rib_install_kernel (struct route_node *rn, struct rib *rib)
                    967: {
                    968:   int ret = 0;
                    969:   struct nexthop *nexthop;
                    970: 
1.1.1.3 ! misho     971:   /*
        !           972:    * Make sure we update the FPM any time we send new information to
        !           973:    * the kernel.
        !           974:    */
        !           975:   zfpm_trigger_update (rn, "installing in kernel");
1.1       misho     976:   switch (PREFIX_FAMILY (&rn->p))
                    977:     {
                    978:     case AF_INET:
                    979:       ret = kernel_add_ipv4 (&rn->p, rib);
                    980:       break;
                    981: #ifdef HAVE_IPV6
                    982:     case AF_INET6:
                    983:       ret = kernel_add_ipv6 (&rn->p, rib);
                    984:       break;
                    985: #endif /* HAVE_IPV6 */
                    986:     }
                    987: 
                    988:   /* This condition is never met, if we are using rt_socket.c */
                    989:   if (ret < 0)
                    990:     {
                    991:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                    992:        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                    993:     }
                    994: }
                    995: 
                    996: /* Uninstall the route from kernel. */
                    997: static int
                    998: rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
                    999: {
                   1000:   int ret = 0;
                   1001:   struct nexthop *nexthop;
                   1002: 
1.1.1.3 ! misho    1003:   /*
        !          1004:    * Make sure we update the FPM any time we send new information to
        !          1005:    * the kernel.
        !          1006:    */
        !          1007:   zfpm_trigger_update (rn, "uninstalling from kernel");
        !          1008: 
1.1       misho    1009:   switch (PREFIX_FAMILY (&rn->p))
                   1010:     {
                   1011:     case AF_INET:
                   1012:       ret = kernel_delete_ipv4 (&rn->p, rib);
                   1013:       break;
                   1014: #ifdef HAVE_IPV6
                   1015:     case AF_INET6:
                   1016:       ret = kernel_delete_ipv6 (&rn->p, rib);
                   1017:       break;
                   1018: #endif /* HAVE_IPV6 */
                   1019:     }
                   1020: 
                   1021:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   1022:     UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                   1023: 
                   1024:   return ret;
                   1025: }
                   1026: 
                   1027: /* Uninstall the route from kernel. */
                   1028: static void
                   1029: rib_uninstall (struct route_node *rn, struct rib *rib)
                   1030: {
                   1031:   if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
                   1032:     {
1.1.1.3 ! misho    1033:       zfpm_trigger_update (rn, "rib_uninstall");
        !          1034: 
1.1       misho    1035:       redistribute_delete (&rn->p, rib);
                   1036:       if (! RIB_SYSTEM_ROUTE (rib))
                   1037:        rib_uninstall_kernel (rn, rib);
                   1038:       UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
                   1039:     }
                   1040: }
                   1041: 
                   1042: static void rib_unlink (struct route_node *, struct rib *);
                   1043: 
1.1.1.3 ! misho    1044: /*
        !          1045:  * rib_can_delete_dest
        !          1046:  *
        !          1047:  * Returns TRUE if the given dest can be deleted from the table.
        !          1048:  */
        !          1049: static int
        !          1050: rib_can_delete_dest (rib_dest_t *dest)
        !          1051: {
        !          1052:   if (dest->routes)
        !          1053:     {
        !          1054:       return 0;
        !          1055:     }
        !          1056: 
        !          1057:   /*
        !          1058:    * Don't delete the dest if we have to update the FPM about this
        !          1059:    * prefix.
        !          1060:    */
        !          1061:   if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) ||
        !          1062:       CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM))
        !          1063:     return 0;
        !          1064: 
        !          1065:   return 1;
        !          1066: }
        !          1067: 
        !          1068: /*
        !          1069:  * rib_gc_dest
        !          1070:  *
        !          1071:  * Garbage collect the rib dest corresponding to the given route node
        !          1072:  * if appropriate.
        !          1073:  *
        !          1074:  * Returns TRUE if the dest was deleted, FALSE otherwise.
        !          1075:  */
        !          1076: int
        !          1077: rib_gc_dest (struct route_node *rn)
        !          1078: {
        !          1079:   rib_dest_t *dest;
        !          1080:   char buf[INET6_ADDRSTRLEN];
        !          1081: 
        !          1082:   dest = rib_dest_from_rnode (rn);
        !          1083:   if (!dest)
        !          1084:     return 0;
        !          1085: 
        !          1086:   if (!rib_can_delete_dest (dest))
        !          1087:     return 0;
        !          1088: 
        !          1089:   if (IS_ZEBRA_DEBUG_RIB)
        !          1090:     {
        !          1091:       inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
        !          1092:       zlog_debug ("%s: %s/%d: removing dest from table", __func__,
        !          1093:                  buf, rn->p.prefixlen);
        !          1094:     }
        !          1095: 
        !          1096:   dest->rnode = NULL;
        !          1097:   XFREE (MTYPE_RIB_DEST, dest);
        !          1098:   rn->info = NULL;
        !          1099: 
        !          1100:   /*
        !          1101:    * Release the one reference that we keep on the route node.
        !          1102:    */
        !          1103:   route_unlock_node (rn);
        !          1104:   return 1;
        !          1105: }
        !          1106: 
1.1       misho    1107: /* Core function for processing routing information base. */
                   1108: static void
                   1109: rib_process (struct route_node *rn)
                   1110: {
                   1111:   struct rib *rib;
                   1112:   struct rib *next;
                   1113:   struct rib *fib = NULL;
                   1114:   struct rib *select = NULL;
                   1115:   struct rib *del = NULL;
                   1116:   int installed = 0;
                   1117:   struct nexthop *nexthop = NULL;
                   1118:   char buf[INET6_ADDRSTRLEN];
                   1119:   
                   1120:   assert (rn);
                   1121:   
                   1122:   if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
                   1123:     inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
                   1124: 
1.1.1.3 ! misho    1125:   RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1       misho    1126:     {
                   1127:       /* Currently installed rib. */
                   1128:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
                   1129:         {
                   1130:           assert (fib == NULL);
                   1131:           fib = rib;
                   1132:         }
                   1133:       
                   1134:       /* Unlock removed routes, so they'll be freed, bar the FIB entry,
                   1135:        * which we need to do do further work with below.
                   1136:        */
                   1137:       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   1138:         {
                   1139:           if (rib != fib)
                   1140:             {
                   1141:               if (IS_ZEBRA_DEBUG_RIB)
                   1142:                 zlog_debug ("%s: %s/%d: rn %p, removing rib %p", __func__,
                   1143:                   buf, rn->p.prefixlen, rn, rib);
1.1.1.3 ! misho    1144:              rib_unlink (rn, rib);
1.1       misho    1145:             }
                   1146:           else
                   1147:             del = rib;
                   1148:           
                   1149:           continue;
                   1150:         }
                   1151:       
                   1152:       /* Skip unreachable nexthop. */
                   1153:       if (! nexthop_active_update (rn, rib, 0))
                   1154:         continue;
                   1155: 
                   1156:       /* Infinit distance. */
                   1157:       if (rib->distance == DISTANCE_INFINITY)
                   1158:         continue;
                   1159: 
                   1160:       /* Newly selected rib, the common case. */
                   1161:       if (!select)
                   1162:         {
                   1163:           select = rib;
                   1164:           continue;
                   1165:         }
                   1166:       
                   1167:       /* filter route selection in following order:
                   1168:        * - connected beats other types
                   1169:        * - lower distance beats higher
                   1170:        * - lower metric beats higher for equal distance
                   1171:        * - last, hence oldest, route wins tie break.
                   1172:        */
                   1173:       
                   1174:       /* Connected routes. Pick the last connected
                   1175:        * route of the set of lowest metric connected routes.
                   1176:        */
                   1177:       if (rib->type == ZEBRA_ROUTE_CONNECT)
                   1178:         {
                   1179:           if (select->type != ZEBRA_ROUTE_CONNECT
                   1180:               || rib->metric <= select->metric)
                   1181:             select = rib;
                   1182:           continue;
                   1183:         }
                   1184:       else if (select->type == ZEBRA_ROUTE_CONNECT)
                   1185:         continue;
                   1186:       
                   1187:       /* higher distance loses */
                   1188:       if (rib->distance > select->distance)
                   1189:         continue;
                   1190:       
                   1191:       /* lower wins */
                   1192:       if (rib->distance < select->distance)
                   1193:         {
                   1194:           select = rib;
                   1195:           continue;
                   1196:         }
                   1197:       
                   1198:       /* metric tie-breaks equal distance */
                   1199:       if (rib->metric <= select->metric)
                   1200:         select = rib;
1.1.1.3 ! misho    1201:     } /* RNODE_FOREACH_RIB_SAFE */
1.1       misho    1202: 
                   1203:   /* After the cycle is finished, the following pointers will be set:
                   1204:    * select --- the winner RIB entry, if any was found, otherwise NULL
                   1205:    * fib    --- the SELECTED RIB entry, if any, otherwise NULL
                   1206:    * del    --- equal to fib, if fib is queued for deletion, NULL otherwise
                   1207:    * rib    --- NULL
                   1208:    */
                   1209: 
                   1210:   /* Same RIB entry is selected. Update FIB and finish. */
                   1211:   if (select && select == fib)
                   1212:     {
                   1213:       if (IS_ZEBRA_DEBUG_RIB)
                   1214:         zlog_debug ("%s: %s/%d: Updating existing route, select %p, fib %p",
                   1215:                      __func__, buf, rn->p.prefixlen, select, fib);
                   1216:       if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
                   1217:         {
1.1.1.3 ! misho    1218:          zfpm_trigger_update (rn, "updating existing route");
        !          1219: 
1.1       misho    1220:           redistribute_delete (&rn->p, select);
                   1221:           if (! RIB_SYSTEM_ROUTE (select))
                   1222:             rib_uninstall_kernel (rn, select);
                   1223: 
                   1224:           /* Set real nexthop. */
                   1225:           nexthop_active_update (rn, select, 1);
                   1226:   
                   1227:           if (! RIB_SYSTEM_ROUTE (select))
                   1228:             rib_install_kernel (rn, select);
                   1229:           redistribute_add (&rn->p, select);
                   1230:         }
                   1231:       else if (! RIB_SYSTEM_ROUTE (select))
                   1232:         {
                   1233:           /* Housekeeping code to deal with 
                   1234:              race conditions in kernel with linux
                   1235:              netlink reporting interface up before IPv4 or IPv6 protocol
                   1236:              is ready to add routes.
                   1237:              This makes sure the routes are IN the kernel.
                   1238:            */
                   1239: 
                   1240:           for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
                   1241:             if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                   1242:             {
                   1243:               installed = 1;
                   1244:               break;
                   1245:             }
                   1246:           if (! installed) 
                   1247:             rib_install_kernel (rn, select);
                   1248:         }
                   1249:       goto end;
                   1250:     }
                   1251: 
                   1252:   /* At this point we either haven't found the best RIB entry or it is
                   1253:    * different from what we currently intend to flag with SELECTED. In both
                   1254:    * cases, if a RIB block is present in FIB, it should be withdrawn.
                   1255:    */
                   1256:   if (fib)
                   1257:     {
                   1258:       if (IS_ZEBRA_DEBUG_RIB)
                   1259:         zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
                   1260:           buf, rn->p.prefixlen, fib);
1.1.1.3 ! misho    1261: 
        !          1262:       zfpm_trigger_update (rn, "removing existing route");
        !          1263: 
1.1       misho    1264:       redistribute_delete (&rn->p, fib);
                   1265:       if (! RIB_SYSTEM_ROUTE (fib))
                   1266:        rib_uninstall_kernel (rn, fib);
                   1267:       UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
                   1268: 
                   1269:       /* Set real nexthop. */
                   1270:       nexthop_active_update (rn, fib, 1);
                   1271:     }
                   1272: 
                   1273:   /* Regardless of some RIB entry being SELECTED or not before, now we can
                   1274:    * tell, that if a new winner exists, FIB is still not updated with this
                   1275:    * data, but ready to be.
                   1276:    */
                   1277:   if (select)
                   1278:     {
                   1279:       if (IS_ZEBRA_DEBUG_RIB)
                   1280:         zlog_debug ("%s: %s/%d: Adding route, select %p", __func__, buf,
                   1281:           rn->p.prefixlen, select);
1.1.1.3 ! misho    1282: 
        !          1283:       zfpm_trigger_update (rn, "new route selected");
        !          1284: 
1.1       misho    1285:       /* Set real nexthop. */
                   1286:       nexthop_active_update (rn, select, 1);
                   1287: 
                   1288:       if (! RIB_SYSTEM_ROUTE (select))
                   1289:         rib_install_kernel (rn, select);
                   1290:       SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
                   1291:       redistribute_add (&rn->p, select);
                   1292:     }
                   1293: 
                   1294:   /* FIB route was removed, should be deleted */
                   1295:   if (del)
                   1296:     {
                   1297:       if (IS_ZEBRA_DEBUG_RIB)
                   1298:         zlog_debug ("%s: %s/%d: Deleting fib %p, rn %p", __func__, buf,
                   1299:           rn->p.prefixlen, del, rn);
                   1300:       rib_unlink (rn, del);
                   1301:     }
                   1302: 
                   1303: end:
                   1304:   if (IS_ZEBRA_DEBUG_RIB_Q)
                   1305:     zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
1.1.1.3 ! misho    1306: 
        !          1307:   /*
        !          1308:    * Check if the dest can be deleted now.
        !          1309:    */
        !          1310:   rib_gc_dest (rn);
1.1       misho    1311: }
                   1312: 
                   1313: /* Take a list of route_node structs and return 1, if there was a record
                   1314:  * picked from it and processed by rib_process(). Don't process more, 
                   1315:  * than one RN record; operate only in the specified sub-queue.
                   1316:  */
                   1317: static unsigned int
                   1318: process_subq (struct list * subq, u_char qindex)
                   1319: {
                   1320:   struct listnode *lnode  = listhead (subq);
                   1321:   struct route_node *rnode;
                   1322: 
                   1323:   if (!lnode)
                   1324:     return 0;
                   1325: 
                   1326:   rnode = listgetdata (lnode);
                   1327:   rib_process (rnode);
                   1328: 
1.1.1.3 ! misho    1329:   if (rnode->info)
        !          1330:     UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex));
        !          1331: 
1.1       misho    1332: #if 0
                   1333:   else
                   1334:     {
                   1335:       zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
                   1336:                   __func__, rnode, rnode->lock);
                   1337:       zlog_backtrace(LOG_DEBUG);
                   1338:     }
                   1339: #endif
                   1340:   route_unlock_node (rnode);
                   1341:   list_delete_node (subq, lnode);
                   1342:   return 1;
                   1343: }
                   1344: 
                   1345: /* Dispatch the meta queue by picking, processing and unlocking the next RN from
                   1346:  * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
                   1347:  * is pointed to the meta queue structure.
                   1348:  */
                   1349: static wq_item_status
                   1350: meta_queue_process (struct work_queue *dummy, void *data)
                   1351: {
                   1352:   struct meta_queue * mq = data;
                   1353:   unsigned i;
                   1354: 
                   1355:   for (i = 0; i < MQ_SIZE; i++)
                   1356:     if (process_subq (mq->subq[i], i))
                   1357:       {
                   1358:        mq->size--;
                   1359:        break;
                   1360:       }
                   1361:   return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
                   1362: }
                   1363: 
1.1.1.3 ! misho    1364: /*
        !          1365:  * Map from rib types to queue type (priority) in meta queue
        !          1366:  */
1.1       misho    1367: static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
                   1368:   [ZEBRA_ROUTE_SYSTEM]  = 4,
                   1369:   [ZEBRA_ROUTE_KERNEL]  = 0,
                   1370:   [ZEBRA_ROUTE_CONNECT] = 0,
                   1371:   [ZEBRA_ROUTE_STATIC]  = 1,
                   1372:   [ZEBRA_ROUTE_RIP]     = 2,
                   1373:   [ZEBRA_ROUTE_RIPNG]   = 2,
                   1374:   [ZEBRA_ROUTE_OSPF]    = 2,
                   1375:   [ZEBRA_ROUTE_OSPF6]   = 2,
                   1376:   [ZEBRA_ROUTE_ISIS]    = 2,
                   1377:   [ZEBRA_ROUTE_BGP]     = 3,
                   1378:   [ZEBRA_ROUTE_HSLS]    = 4,
1.1.1.2   misho    1379:   [ZEBRA_ROUTE_BABEL]   = 2,
1.1       misho    1380: };
                   1381: 
                   1382: /* Look into the RN and queue it into one or more priority queues,
                   1383:  * increasing the size for each data push done.
                   1384:  */
                   1385: static void
                   1386: rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
                   1387: {
                   1388:   struct rib *rib;
                   1389:   char buf[INET6_ADDRSTRLEN];
                   1390: 
                   1391:   if (IS_ZEBRA_DEBUG_RIB_Q)
                   1392:     inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
                   1393: 
1.1.1.3 ! misho    1394:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    1395:     {
                   1396:       u_char qindex = meta_queue_map[rib->type];
                   1397: 
                   1398:       /* Invariant: at this point we always have rn->info set. */
1.1.1.3 ! misho    1399:       if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags,
        !          1400:                      RIB_ROUTE_QUEUED (qindex)))
1.1       misho    1401:        {
                   1402:          if (IS_ZEBRA_DEBUG_RIB_Q)
                   1403:            zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
                   1404:                        __func__, buf, rn->p.prefixlen, rn, qindex);
                   1405:          continue;
                   1406:        }
                   1407: 
1.1.1.3 ! misho    1408:       SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex));
1.1       misho    1409:       listnode_add (mq->subq[qindex], rn);
                   1410:       route_lock_node (rn);
                   1411:       mq->size++;
                   1412: 
                   1413:       if (IS_ZEBRA_DEBUG_RIB_Q)
                   1414:        zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
                   1415:                    __func__, buf, rn->p.prefixlen, rn, qindex);
                   1416:     }
                   1417: }
                   1418: 
                   1419: /* Add route_node to work queue and schedule processing */
                   1420: static void
                   1421: rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
                   1422: {
1.1.1.2   misho    1423:   char buf[INET_ADDRSTRLEN];
                   1424:   assert (zebra && rn);
1.1       misho    1425:   
                   1426:   if (IS_ZEBRA_DEBUG_RIB_Q)
1.1.1.2   misho    1427:     inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN);
                   1428: 
                   1429:   /* Pointless to queue a route_node with no RIB entries to add or remove */
1.1.1.3 ! misho    1430:   if (!rnode_to_ribs (rn))
1.1       misho    1431:     {
1.1.1.2   misho    1432:       zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
                   1433:                   __func__, rn, rn->lock);
                   1434:       zlog_backtrace(LOG_DEBUG);
                   1435:       return;
                   1436:     }
                   1437: 
                   1438:   if (IS_ZEBRA_DEBUG_RIB_Q)
                   1439:     zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen);
1.1       misho    1440: 
1.1.1.2   misho    1441:   assert (zebra);
                   1442: 
                   1443:   if (zebra->ribq == NULL)
                   1444:     {
                   1445:       zlog_err ("%s: work_queue does not exist!", __func__);
                   1446:       return;
1.1       misho    1447:     }
                   1448: 
                   1449:   /*
                   1450:    * The RIB queue should normally be either empty or holding the only
                   1451:    * work_queue_item element. In the latter case this element would
                   1452:    * hold a pointer to the meta queue structure, which must be used to
                   1453:    * actually queue the route nodes to process. So create the MQ
                   1454:    * holder, if necessary, then push the work into it in any case.
                   1455:    * This semantics was introduced after 0.99.9 release.
                   1456:    */
                   1457:   if (!zebra->ribq->items->count)
                   1458:     work_queue_add (zebra->ribq, zebra->mq);
                   1459: 
                   1460:   rib_meta_queue_add (zebra->mq, rn);
1.1.1.2   misho    1461: 
                   1462:   if (IS_ZEBRA_DEBUG_RIB_Q)
                   1463:     zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
                   1464: 
                   1465:   return;
1.1       misho    1466: }
                   1467: 
                   1468: /* Create new meta queue.
                   1469:    A destructor function doesn't seem to be necessary here.
                   1470:  */
                   1471: static struct meta_queue *
                   1472: meta_queue_new (void)
                   1473: {
                   1474:   struct meta_queue *new;
                   1475:   unsigned i;
                   1476: 
                   1477:   new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
                   1478:   assert(new);
                   1479: 
                   1480:   for (i = 0; i < MQ_SIZE; i++)
                   1481:     {
                   1482:       new->subq[i] = list_new ();
                   1483:       assert(new->subq[i]);
                   1484:     }
                   1485: 
                   1486:   return new;
                   1487: }
                   1488: 
                   1489: /* initialise zebra rib work queue */
                   1490: static void
                   1491: rib_queue_init (struct zebra_t *zebra)
                   1492: {
1.1.1.2   misho    1493:   assert (zebra);
                   1494:   
1.1       misho    1495:   if (! (zebra->ribq = work_queue_new (zebra->master, 
                   1496:                                        "route_node processing")))
                   1497:     {
                   1498:       zlog_err ("%s: could not initialise work queue!", __func__);
                   1499:       return;
                   1500:     }
                   1501: 
                   1502:   /* fill in the work queue spec */
                   1503:   zebra->ribq->spec.workfunc = &meta_queue_process;
                   1504:   zebra->ribq->spec.errorfunc = NULL;
                   1505:   /* XXX: TODO: These should be runtime configurable via vty */
                   1506:   zebra->ribq->spec.max_retries = 3;
                   1507:   zebra->ribq->spec.hold = rib_process_hold_time;
                   1508:   
                   1509:   if (!(zebra->mq = meta_queue_new ()))
1.1.1.2   misho    1510:   {
1.1       misho    1511:     zlog_err ("%s: could not initialise meta queue!", __func__);
1.1.1.2   misho    1512:     return;
                   1513:   }
                   1514:   return;
1.1       misho    1515: }
                   1516: 
                   1517: /* RIB updates are processed via a queue of pointers to route_nodes.
                   1518:  *
                   1519:  * The queue length is bounded by the maximal size of the routing table,
                   1520:  * as a route_node will not be requeued, if already queued.
                   1521:  *
                   1522:  * RIBs are submitted via rib_addnode or rib_delnode which set minimal
                   1523:  * state, or static_install_ipv{4,6} (when an existing RIB is updated)
                   1524:  * and then submit route_node to queue for best-path selection later.
                   1525:  * Order of add/delete state changes are preserved for any given RIB.
                   1526:  *
                   1527:  * Deleted RIBs are reaped during best-path selection.
                   1528:  *
                   1529:  * rib_addnode
                   1530:  * |-> rib_link or unset RIB_ENTRY_REMOVE        |->Update kernel with
                   1531:  *       |-------->|                             |  best RIB, if required
                   1532:  *                 |                             |
                   1533:  * static_install->|->rib_addqueue...... -> rib_process
                   1534:  *                 |                             |
                   1535:  *       |-------->|                             |-> rib_unlink
                   1536:  * |-> set RIB_ENTRY_REMOVE                           |
                   1537:  * rib_delnode                                  (RIB freed)
                   1538:  *
1.1.1.3 ! misho    1539:  * The 'info' pointer of a route_node points to a rib_dest_t
        !          1540:  * ('dest'). Queueing state for a route_node is kept on the dest. The
        !          1541:  * dest is created on-demand by rib_link() and is kept around at least
        !          1542:  * as long as there are ribs hanging off it (@see rib_gc_dest()).
1.1       misho    1543:  * 
                   1544:  * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
                   1545:  *
                   1546:  * - route_nodes: refcounted by:
1.1.1.3 ! misho    1547:  *   - dest attached to route_node:
        !          1548:  *     - managed by: rib_link/rib_gc_dest
1.1       misho    1549:  *   - route_node processing queue
                   1550:  *     - managed by: rib_addqueue, rib_process.
                   1551:  *
                   1552:  */
                   1553:  
                   1554: /* Add RIB to head of the route node. */
                   1555: static void
                   1556: rib_link (struct route_node *rn, struct rib *rib)
                   1557: {
                   1558:   struct rib *head;
1.1.1.3 ! misho    1559:   rib_dest_t *dest;
1.1       misho    1560:   char buf[INET6_ADDRSTRLEN];
1.1.1.3 ! misho    1561: 
1.1       misho    1562:   assert (rib && rn);
                   1563:   
                   1564:   if (IS_ZEBRA_DEBUG_RIB)
                   1565:   {
                   1566:     inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
                   1567:     zlog_debug ("%s: %s/%d: rn %p, rib %p", __func__,
                   1568:       buf, rn->p.prefixlen, rn, rib);
                   1569:   }
                   1570: 
1.1.1.3 ! misho    1571:   dest = rib_dest_from_rnode (rn);
        !          1572:   if (!dest)
1.1       misho    1573:     {
                   1574:       if (IS_ZEBRA_DEBUG_RIB)
1.1.1.3 ! misho    1575:        {
        !          1576:          zlog_debug ("%s: %s/%d: adding dest to table", __func__,
        !          1577:                      buf, rn->p.prefixlen);
        !          1578:        }
        !          1579: 
        !          1580:       dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t));
        !          1581:       route_lock_node (rn); /* rn route table reference */
        !          1582:       rn->info = dest;
        !          1583:       dest->rnode = rn;
        !          1584:     }
        !          1585: 
        !          1586:   head = dest->routes;
        !          1587:   if (head)
        !          1588:     {
1.1       misho    1589:       head->prev = rib;
                   1590:     }
                   1591:   rib->next = head;
1.1.1.3 ! misho    1592:   dest->routes = rib;
1.1       misho    1593:   rib_queue_add (&zebrad, rn);
                   1594: }
                   1595: 
                   1596: static void
                   1597: rib_addnode (struct route_node *rn, struct rib *rib)
                   1598: {
                   1599:   /* RIB node has been un-removed before route-node is processed. 
                   1600:    * route_node must hence already be on the queue for processing.. 
                   1601:    */
                   1602:   if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   1603:     {
                   1604:       if (IS_ZEBRA_DEBUG_RIB)
                   1605:       {
                   1606:         char buf[INET6_ADDRSTRLEN];
                   1607:         inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
                   1608:         zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
                   1609:                     __func__, buf, rn->p.prefixlen, rn, rib);
                   1610:       }
                   1611:       UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
                   1612:       return;
                   1613:     }
                   1614:   rib_link (rn, rib);
                   1615: }
                   1616: 
1.1.1.3 ! misho    1617: /*
        !          1618:  * rib_unlink
        !          1619:  *
        !          1620:  * Detach a rib structure from a route_node.
        !          1621:  *
        !          1622:  * Note that a call to rib_unlink() should be followed by a call to
        !          1623:  * rib_gc_dest() at some point. This allows a rib_dest_t that is no
        !          1624:  * longer required to be deleted.
        !          1625:  */
1.1       misho    1626: static void
                   1627: rib_unlink (struct route_node *rn, struct rib *rib)
                   1628: {
                   1629:   struct nexthop *nexthop, *next;
                   1630:   char buf[INET6_ADDRSTRLEN];
1.1.1.3 ! misho    1631:   rib_dest_t *dest;
1.1       misho    1632: 
                   1633:   assert (rn && rib);
                   1634: 
                   1635:   if (IS_ZEBRA_DEBUG_RIB)
                   1636:   {
                   1637:     inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
                   1638:     zlog_debug ("%s: %s/%d: rn %p, rib %p",
                   1639:                 __func__, buf, rn->p.prefixlen, rn, rib);
                   1640:   }
                   1641: 
1.1.1.3 ! misho    1642:   dest = rib_dest_from_rnode (rn);
        !          1643: 
1.1       misho    1644:   if (rib->next)
                   1645:     rib->next->prev = rib->prev;
                   1646: 
                   1647:   if (rib->prev)
                   1648:     rib->prev->next = rib->next;
                   1649:   else
                   1650:     {
1.1.1.3 ! misho    1651:       dest->routes = rib->next;
1.1       misho    1652:     }
                   1653: 
                   1654:   /* free RIB and nexthops */
                   1655:   for (nexthop = rib->nexthop; nexthop; nexthop = next)
                   1656:     {
                   1657:       next = nexthop->next;
                   1658:       nexthop_free (nexthop);
                   1659:     }
                   1660:   XFREE (MTYPE_RIB, rib);
                   1661: 
                   1662: }
                   1663: 
                   1664: static void
                   1665: rib_delnode (struct route_node *rn, struct rib *rib)
                   1666: {
                   1667:   if (IS_ZEBRA_DEBUG_RIB)
                   1668:   {
                   1669:     char buf[INET6_ADDRSTRLEN];
                   1670:     inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
                   1671:     zlog_debug ("%s: %s/%d: rn %p, rib %p, removing", __func__,
                   1672:       buf, rn->p.prefixlen, rn, rib);
                   1673:   }
                   1674:   SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
                   1675:   rib_queue_add (&zebrad, rn);
                   1676: }
                   1677: 
                   1678: int
                   1679: rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
                   1680:              struct in_addr *gate, struct in_addr *src,
                   1681:              unsigned int ifindex, u_int32_t vrf_id,
1.1.1.2   misho    1682:              u_int32_t metric, u_char distance, safi_t safi)
1.1       misho    1683: {
                   1684:   struct rib *rib;
                   1685:   struct rib *same = NULL;
                   1686:   struct route_table *table;
                   1687:   struct route_node *rn;
                   1688:   struct nexthop *nexthop;
                   1689: 
                   1690:   /* Lookup table.  */
1.1.1.2   misho    1691:   table = vrf_table (AFI_IP, safi, 0);
1.1       misho    1692:   if (! table)
                   1693:     return 0;
                   1694: 
                   1695:   /* Make it sure prefixlen is applied to the prefix. */
                   1696:   apply_mask_ipv4 (p);
                   1697: 
                   1698:   /* Set default distance by route type. */
                   1699:   if (distance == 0)
                   1700:     {
1.1.1.3 ! misho    1701:       if ((unsigned)type >= array_size(route_info))
1.1.1.2   misho    1702:        distance = 150;
                   1703:       else
                   1704:         distance = route_info[type].distance;
1.1       misho    1705: 
                   1706:       /* iBGP distance is 200. */
                   1707:       if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
                   1708:        distance = 200;
                   1709:     }
                   1710: 
                   1711:   /* Lookup route node.*/
                   1712:   rn = route_node_get (table, (struct prefix *) p);
                   1713: 
                   1714:   /* If same type of route are installed, treat it as a implicit
                   1715:      withdraw. */
1.1.1.3 ! misho    1716:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    1717:     {
                   1718:       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   1719:         continue;
                   1720:       
                   1721:       if (rib->type != type)
                   1722:        continue;
                   1723:       if (rib->type != ZEBRA_ROUTE_CONNECT)
                   1724:         {
                   1725:           same = rib;
                   1726:           break;
                   1727:         }
                   1728:       /* Duplicate connected route comes in. */
                   1729:       else if ((nexthop = rib->nexthop) &&
                   1730:               nexthop->type == NEXTHOP_TYPE_IFINDEX &&
                   1731:               nexthop->ifindex == ifindex &&
                   1732:               !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   1733:        {
                   1734:          rib->refcnt++;
                   1735:          return 0 ;
                   1736:        }
                   1737:     }
                   1738: 
                   1739:   /* Allocate new rib structure. */
                   1740:   rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
                   1741:   rib->type = type;
                   1742:   rib->distance = distance;
                   1743:   rib->flags = flags;
                   1744:   rib->metric = metric;
                   1745:   rib->table = vrf_id;
                   1746:   rib->nexthop_num = 0;
                   1747:   rib->uptime = time (NULL);
                   1748: 
                   1749:   /* Nexthop settings. */
                   1750:   if (gate)
                   1751:     {
                   1752:       if (ifindex)
                   1753:        nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
                   1754:       else
                   1755:        nexthop_ipv4_add (rib, gate, src);
                   1756:     }
                   1757:   else
                   1758:     nexthop_ifindex_add (rib, ifindex);
                   1759: 
                   1760:   /* If this route is kernel route, set FIB flag to the route. */
                   1761:   if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
                   1762:     for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   1763:       SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                   1764: 
                   1765:   /* Link new rib to node.*/
                   1766:   if (IS_ZEBRA_DEBUG_RIB)
                   1767:     zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
                   1768:   rib_addnode (rn, rib);
                   1769:   
                   1770:   /* Free implicit route.*/
                   1771:   if (same)
                   1772:   {
                   1773:     if (IS_ZEBRA_DEBUG_RIB)
                   1774:       zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
                   1775:     rib_delnode (rn, same);
                   1776:   }
                   1777:   
                   1778:   route_unlock_node (rn);
                   1779:   return 0;
                   1780: }
                   1781: 
                   1782: /* This function dumps the contents of a given RIB entry into
                   1783:  * standard debug log. Calling function name and IP prefix in
                   1784:  * question are passed as 1st and 2nd arguments.
                   1785:  */
                   1786: 
                   1787: void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
                   1788: {
                   1789:   char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
                   1790:   struct nexthop *nexthop;
                   1791: 
                   1792:   inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
                   1793:   zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
                   1794:   zlog_debug
                   1795:   (
                   1796:     "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
                   1797:     func,
                   1798:     rib->refcnt,
                   1799:     (unsigned long) rib->uptime,
                   1800:     rib->type,
                   1801:     rib->table
                   1802:   );
                   1803:   zlog_debug
                   1804:   (
                   1805:     "%s: metric == %u, distance == %u, flags == %u, status == %u",
                   1806:     func,
                   1807:     rib->metric,
                   1808:     rib->distance,
                   1809:     rib->flags,
                   1810:     rib->status
                   1811:   );
                   1812:   zlog_debug
                   1813:   (
                   1814:     "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
                   1815:     func,
                   1816:     rib->nexthop_num,
                   1817:     rib->nexthop_active_num,
                   1818:     rib->nexthop_fib_num
                   1819:   );
                   1820:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   1821:   {
                   1822:     inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
                   1823:     inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
                   1824:     zlog_debug
                   1825:     (
                   1826:       "%s: NH %s (%s) with flags %s%s%s",
                   1827:       func,
                   1828:       straddr1,
                   1829:       straddr2,
                   1830:       (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
                   1831:       (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
                   1832:       (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
                   1833:     );
                   1834:   }
                   1835:   zlog_debug ("%s: dump complete", func);
                   1836: }
                   1837: 
                   1838: /* This is an exported helper to rtm_read() to dump the strange
                   1839:  * RIB entry found by rib_lookup_ipv4_route()
                   1840:  */
                   1841: 
                   1842: void rib_lookup_and_dump (struct prefix_ipv4 * p)
                   1843: {
                   1844:   struct route_table *table;
                   1845:   struct route_node *rn;
                   1846:   struct rib *rib;
                   1847:   char prefix_buf[INET_ADDRSTRLEN];
                   1848: 
                   1849:   /* Lookup table.  */
                   1850:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                   1851:   if (! table)
                   1852:   {
                   1853:     zlog_err ("%s: vrf_table() returned NULL", __func__);
                   1854:     return;
                   1855:   }
                   1856: 
                   1857:   inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
                   1858:   /* Scan the RIB table for exactly matching RIB entry. */
                   1859:   rn = route_node_lookup (table, (struct prefix *) p);
                   1860: 
                   1861:   /* No route for this prefix. */
                   1862:   if (! rn)
                   1863:   {
                   1864:     zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
                   1865:     return;
                   1866:   }
                   1867: 
                   1868:   /* Unlock node. */
                   1869:   route_unlock_node (rn);
                   1870: 
                   1871:   /* let's go */
1.1.1.3 ! misho    1872:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    1873:   {
                   1874:     zlog_debug
                   1875:     (
                   1876:       "%s: rn %p, rib %p: %s, %s",
                   1877:       __func__,
                   1878:       rn,
                   1879:       rib,
                   1880:       (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
                   1881:       (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
                   1882:     );
                   1883:     rib_dump (__func__, p, rib);
                   1884:   }
                   1885: }
                   1886: 
                   1887: /* Check if requested address assignment will fail due to another
                   1888:  * route being installed by zebra in FIB already. Take necessary
                   1889:  * actions, if needed: remove such a route from FIB and deSELECT
                   1890:  * corresponding RIB entry. Then put affected RN into RIBQ head.
                   1891:  */
                   1892: void rib_lookup_and_pushup (struct prefix_ipv4 * p)
                   1893: {
                   1894:   struct route_table *table;
                   1895:   struct route_node *rn;
                   1896:   struct rib *rib;
                   1897:   unsigned changed = 0;
                   1898: 
                   1899:   if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
                   1900:   {
                   1901:     zlog_err ("%s: vrf_table() returned NULL", __func__);
                   1902:     return;
                   1903:   }
                   1904: 
                   1905:   /* No matches would be the simplest case. */
                   1906:   if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
                   1907:     return;
                   1908: 
                   1909:   /* Unlock node. */
                   1910:   route_unlock_node (rn);
                   1911: 
                   1912:   /* Check all RIB entries. In case any changes have to be done, requeue
                   1913:    * the RN into RIBQ head. If the routing message about the new connected
                   1914:    * route (generated by the IP address we are going to assign very soon)
                   1915:    * comes before the RIBQ is processed, the new RIB entry will join
                   1916:    * RIBQ record already on head. This is necessary for proper revalidation
                   1917:    * of the rest of the RIB.
                   1918:    */
1.1.1.3 ! misho    1919:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    1920:   {
                   1921:     if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
                   1922:       ! RIB_SYSTEM_ROUTE (rib))
                   1923:     {
                   1924:       changed = 1;
                   1925:       if (IS_ZEBRA_DEBUG_RIB)
                   1926:       {
                   1927:         char buf[INET_ADDRSTRLEN];
                   1928:         inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
                   1929:         zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
                   1930:         rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
                   1931:       }
                   1932:       rib_uninstall (rn, rib);
                   1933:     }
                   1934:   }
                   1935:   if (changed)
                   1936:     rib_queue_add (&zebrad, rn);
                   1937: }
                   1938: 
                   1939: int
1.1.1.2   misho    1940: rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
1.1       misho    1941: {
                   1942:   struct route_table *table;
                   1943:   struct route_node *rn;
                   1944:   struct rib *same;
                   1945:   struct nexthop *nexthop;
                   1946:   
                   1947:   /* Lookup table.  */
1.1.1.2   misho    1948:   table = vrf_table (AFI_IP, safi, 0);
1.1       misho    1949:   if (! table)
                   1950:     return 0;
1.1.1.2   misho    1951: 
1.1       misho    1952:   /* Make it sure prefixlen is applied to the prefix. */
                   1953:   apply_mask_ipv4 (p);
                   1954: 
                   1955:   /* Set default distance by route type. */
                   1956:   if (rib->distance == 0)
                   1957:     {
                   1958:       rib->distance = route_info[rib->type].distance;
                   1959: 
                   1960:       /* iBGP distance is 200. */
                   1961:       if (rib->type == ZEBRA_ROUTE_BGP 
                   1962:          && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
                   1963:        rib->distance = 200;
                   1964:     }
                   1965: 
                   1966:   /* Lookup route node.*/
                   1967:   rn = route_node_get (table, (struct prefix *) p);
                   1968: 
                   1969:   /* If same type of route are installed, treat it as a implicit
                   1970:      withdraw. */
1.1.1.3 ! misho    1971:   RNODE_FOREACH_RIB (rn, same)
1.1       misho    1972:     {
                   1973:       if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
                   1974:         continue;
                   1975:       
                   1976:       if (same->type == rib->type && same->table == rib->table
                   1977:          && same->type != ZEBRA_ROUTE_CONNECT)
                   1978:         break;
                   1979:     }
                   1980:   
                   1981:   /* If this route is kernel route, set FIB flag to the route. */
                   1982:   if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
                   1983:     for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   1984:       SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                   1985: 
                   1986:   /* Link new rib to node.*/
                   1987:   rib_addnode (rn, rib);
                   1988:   if (IS_ZEBRA_DEBUG_RIB)
                   1989:   {
                   1990:     zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
                   1991:       __func__, rn, rib);
                   1992:     rib_dump (__func__, p, rib);
                   1993:   }
                   1994: 
                   1995:   /* Free implicit route.*/
                   1996:   if (same)
                   1997:   {
                   1998:     if (IS_ZEBRA_DEBUG_RIB)
                   1999:     {
                   2000:       zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
                   2001:         __func__, rn, same);
                   2002:       rib_dump (__func__, p, same);
                   2003:     }
                   2004:     rib_delnode (rn, same);
                   2005:   }
                   2006:   
                   2007:   route_unlock_node (rn);
                   2008:   return 0;
                   2009: }
                   2010: 
                   2011: /* XXX factor with rib_delete_ipv6 */
                   2012: int
                   2013: rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
1.1.1.2   misho    2014:                 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
1.1       misho    2015: {
                   2016:   struct route_table *table;
                   2017:   struct route_node *rn;
                   2018:   struct rib *rib;
                   2019:   struct rib *fib = NULL;
                   2020:   struct rib *same = NULL;
                   2021:   struct nexthop *nexthop;
                   2022:   char buf1[INET_ADDRSTRLEN];
                   2023:   char buf2[INET_ADDRSTRLEN];
                   2024: 
                   2025:   /* Lookup table.  */
1.1.1.2   misho    2026:   table = vrf_table (AFI_IP, safi, 0);
1.1       misho    2027:   if (! table)
                   2028:     return 0;
                   2029: 
                   2030:   /* Apply mask. */
                   2031:   apply_mask_ipv4 (p);
                   2032: 
                   2033:   if (IS_ZEBRA_DEBUG_KERNEL && gate)
                   2034:     zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
                   2035:                       inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                   2036:                       p->prefixlen, 
                   2037:                       inet_ntoa (*gate), 
                   2038:                       ifindex);
                   2039: 
                   2040:   /* Lookup route node. */
                   2041:   rn = route_node_lookup (table, (struct prefix *) p);
                   2042:   if (! rn)
                   2043:     {
                   2044:       if (IS_ZEBRA_DEBUG_KERNEL)
                   2045:        {
                   2046:          if (gate)
                   2047:            zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
                   2048:                       inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                   2049:                       p->prefixlen,
                   2050:                       inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
                   2051:                       ifindex);
                   2052:          else
                   2053:            zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
                   2054:                       inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                   2055:                       p->prefixlen,
                   2056:                       ifindex);
                   2057:        }
                   2058:       return ZEBRA_ERR_RTNOEXIST;
                   2059:     }
                   2060: 
                   2061:   /* Lookup same type route. */
1.1.1.3 ! misho    2062:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2063:     {
                   2064:       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   2065:         continue;
                   2066: 
                   2067:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
                   2068:        fib = rib;
                   2069: 
                   2070:       if (rib->type != type)
                   2071:        continue;
                   2072:       if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1.1.1.2   misho    2073:          nexthop->type == NEXTHOP_TYPE_IFINDEX)
1.1       misho    2074:        {
1.1.1.2   misho    2075:          if (nexthop->ifindex != ifindex)
                   2076:            continue;
1.1       misho    2077:          if (rib->refcnt)
                   2078:            {
                   2079:              rib->refcnt--;
                   2080:              route_unlock_node (rn);
                   2081:              route_unlock_node (rn);
                   2082:              return 0;
                   2083:            }
                   2084:          same = rib;
                   2085:          break;
                   2086:        }
                   2087:       /* Make sure that the route found has the same gateway. */
                   2088:       else if (gate == NULL ||
                   2089:               ((nexthop = rib->nexthop) &&
                   2090:                (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
                   2091:                 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate)))) 
                   2092:         {
                   2093:          same = rib;
                   2094:          break;
                   2095:        }
                   2096:     }
                   2097: 
                   2098:   /* If same type of route can't be found and this message is from
                   2099:      kernel. */
                   2100:   if (! same)
                   2101:     {
                   2102:       if (fib && type == ZEBRA_ROUTE_KERNEL)
                   2103:        {
                   2104:          /* Unset flags. */
                   2105:          for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
                   2106:            UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                   2107: 
                   2108:          UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
                   2109:        }
                   2110:       else
                   2111:        {
                   2112:          if (IS_ZEBRA_DEBUG_KERNEL)
                   2113:            {
                   2114:              if (gate)
                   2115:                zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
                   2116:                           inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                   2117:                           p->prefixlen,
                   2118:                           inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
                   2119:                           ifindex,
                   2120:                           type);
                   2121:              else
                   2122:                zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
                   2123:                           inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                   2124:                           p->prefixlen,
                   2125:                           ifindex,
                   2126:                           type);
                   2127:            }
                   2128:          route_unlock_node (rn);
                   2129:          return ZEBRA_ERR_RTNOEXIST;
                   2130:        }
                   2131:     }
                   2132:   
                   2133:   if (same)
                   2134:     rib_delnode (rn, same);
                   2135:   
                   2136:   route_unlock_node (rn);
                   2137:   return 0;
                   2138: }
                   2139: 
                   2140: /* Install static route into rib. */
                   2141: static void
                   2142: static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
                   2143: {
                   2144:   struct rib *rib;
                   2145:   struct route_node *rn;
                   2146:   struct route_table *table;
                   2147: 
                   2148:   /* Lookup table.  */
                   2149:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                   2150:   if (! table)
                   2151:     return;
                   2152: 
                   2153:   /* Lookup existing route */
                   2154:   rn = route_node_get (table, p);
1.1.1.3 ! misho    2155:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2156:     {
                   2157:        if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   2158:          continue;
                   2159:         
                   2160:        if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
                   2161:          break;
                   2162:     }
                   2163: 
                   2164:   if (rib)
                   2165:     {
                   2166:       /* Same distance static route is there.  Update it with new
                   2167:          nexthop. */
                   2168:       route_unlock_node (rn);
                   2169:       switch (si->type)
                   2170:         {
                   2171:           case STATIC_IPV4_GATEWAY:
                   2172:             nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
                   2173:             break;
                   2174:           case STATIC_IPV4_IFNAME:
                   2175:             nexthop_ifname_add (rib, si->gate.ifname);
                   2176:             break;
                   2177:           case STATIC_IPV4_BLACKHOLE:
                   2178:             nexthop_blackhole_add (rib);
                   2179:             break;
                   2180:         }
                   2181:       rib_queue_add (&zebrad, rn);
                   2182:     }
                   2183:   else
                   2184:     {
                   2185:       /* This is new static route. */
                   2186:       rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
                   2187:       
                   2188:       rib->type = ZEBRA_ROUTE_STATIC;
                   2189:       rib->distance = si->distance;
                   2190:       rib->metric = 0;
1.1.1.3 ! misho    2191:       rib->table = zebrad.rtm_table_default;
1.1       misho    2192:       rib->nexthop_num = 0;
                   2193: 
                   2194:       switch (si->type)
                   2195:         {
                   2196:           case STATIC_IPV4_GATEWAY:
                   2197:             nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
                   2198:             break;
                   2199:           case STATIC_IPV4_IFNAME:
                   2200:             nexthop_ifname_add (rib, si->gate.ifname);
                   2201:             break;
                   2202:           case STATIC_IPV4_BLACKHOLE:
                   2203:             nexthop_blackhole_add (rib);
                   2204:             break;
                   2205:         }
                   2206: 
                   2207:       /* Save the flags of this static routes (reject, blackhole) */
                   2208:       rib->flags = si->flags;
                   2209: 
                   2210:       /* Link this rib to the tree. */
                   2211:       rib_addnode (rn, rib);
                   2212:     }
                   2213: }
                   2214: 
                   2215: static int
                   2216: static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
                   2217: {
                   2218:   if (nexthop->type == NEXTHOP_TYPE_IPV4
                   2219:       && si->type == STATIC_IPV4_GATEWAY
                   2220:       && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
                   2221:     return 1;
                   2222:   if (nexthop->type == NEXTHOP_TYPE_IFNAME
                   2223:       && si->type == STATIC_IPV4_IFNAME
                   2224:       && strcmp (nexthop->ifname, si->gate.ifname) == 0)
                   2225:     return 1;
                   2226:   if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
                   2227:       && si->type == STATIC_IPV4_BLACKHOLE)
                   2228:     return 1;
                   2229:   return 0;
                   2230: }
                   2231: 
                   2232: /* Uninstall static route from RIB. */
                   2233: static void
                   2234: static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
                   2235: {
                   2236:   struct route_node *rn;
                   2237:   struct rib *rib;
                   2238:   struct nexthop *nexthop;
                   2239:   struct route_table *table;
                   2240: 
                   2241:   /* Lookup table.  */
                   2242:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                   2243:   if (! table)
                   2244:     return;
                   2245:   
                   2246:   /* Lookup existing route with type and distance. */
                   2247:   rn = route_node_lookup (table, p);
                   2248:   if (! rn)
                   2249:     return;
                   2250: 
1.1.1.3 ! misho    2251:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2252:     {
                   2253:       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   2254:         continue;
                   2255: 
                   2256:       if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
                   2257:         break;
                   2258:     }
                   2259: 
                   2260:   if (! rib)
                   2261:     {
                   2262:       route_unlock_node (rn);
                   2263:       return;
                   2264:     }
                   2265: 
                   2266:   /* Lookup nexthop. */
                   2267:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   2268:     if (static_ipv4_nexthop_same (nexthop, si))
                   2269:       break;
                   2270: 
                   2271:   /* Can't find nexthop. */
                   2272:   if (! nexthop)
                   2273:     {
                   2274:       route_unlock_node (rn);
                   2275:       return;
                   2276:     }
                   2277:   
                   2278:   /* Check nexthop. */
                   2279:   if (rib->nexthop_num == 1)
                   2280:     rib_delnode (rn, rib);
                   2281:   else
                   2282:     {
                   2283:       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                   2284:         rib_uninstall (rn, rib);
                   2285:       nexthop_delete (rib, nexthop);
                   2286:       nexthop_free (nexthop);
                   2287:       rib_queue_add (&zebrad, rn);
                   2288:     }
                   2289:   /* Unlock node. */
                   2290:   route_unlock_node (rn);
                   2291: }
                   2292: 
                   2293: /* Add static route into static route configuration. */
                   2294: int
                   2295: static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
                   2296:                 u_char flags, u_char distance, u_int32_t vrf_id)
                   2297: {
                   2298:   u_char type = 0;
                   2299:   struct route_node *rn;
                   2300:   struct static_ipv4 *si;
                   2301:   struct static_ipv4 *pp;
                   2302:   struct static_ipv4 *cp;
                   2303:   struct static_ipv4 *update = NULL;
                   2304:   struct route_table *stable;
                   2305: 
                   2306:   /* Lookup table.  */
                   2307:   stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
                   2308:   if (! stable)
                   2309:     return -1;
                   2310:   
                   2311:   /* Lookup static route prefix. */
                   2312:   rn = route_node_get (stable, p);
                   2313: 
                   2314:   /* Make flags. */
                   2315:   if (gate)
                   2316:     type = STATIC_IPV4_GATEWAY;
                   2317:   else if (ifname)
                   2318:     type = STATIC_IPV4_IFNAME;
                   2319:   else
                   2320:     type = STATIC_IPV4_BLACKHOLE;
                   2321: 
                   2322:   /* Do nothing if there is a same static route.  */
                   2323:   for (si = rn->info; si; si = si->next)
                   2324:     {
                   2325:       if (type == si->type
                   2326:          && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
                   2327:          && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
                   2328:        {
                   2329:          if (distance == si->distance)
                   2330:            {
                   2331:              route_unlock_node (rn);
                   2332:              return 0;
                   2333:            }
                   2334:          else
                   2335:            update = si;
                   2336:        }
                   2337:     }
                   2338: 
                   2339:   /* Distance changed.  */
                   2340:   if (update)
                   2341:     static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
                   2342: 
                   2343:   /* Make new static route structure. */
                   2344:   si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
                   2345: 
                   2346:   si->type = type;
                   2347:   si->distance = distance;
                   2348:   si->flags = flags;
                   2349: 
                   2350:   if (gate)
                   2351:     si->gate.ipv4 = *gate;
                   2352:   if (ifname)
                   2353:     si->gate.ifname = XSTRDUP (0, ifname);
                   2354: 
                   2355:   /* Add new static route information to the tree with sort by
                   2356:      distance value and gateway address. */
                   2357:   for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
                   2358:     {
                   2359:       if (si->distance < cp->distance)
                   2360:        break;
                   2361:       if (si->distance > cp->distance)
                   2362:        continue;
                   2363:       if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
                   2364:        {
                   2365:          if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
                   2366:            break;
                   2367:          if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
                   2368:            continue;
                   2369:        }
                   2370:     }
                   2371: 
                   2372:   /* Make linked list. */
                   2373:   if (pp)
                   2374:     pp->next = si;
                   2375:   else
                   2376:     rn->info = si;
                   2377:   if (cp)
                   2378:     cp->prev = si;
                   2379:   si->prev = pp;
                   2380:   si->next = cp;
                   2381: 
                   2382:   /* Install into rib. */
                   2383:   static_install_ipv4 (p, si);
                   2384: 
                   2385:   return 1;
                   2386: }
                   2387: 
                   2388: /* Delete static route from static route configuration. */
                   2389: int
                   2390: static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
                   2391:                    u_char distance, u_int32_t vrf_id)
                   2392: {
                   2393:   u_char type = 0;
                   2394:   struct route_node *rn;
                   2395:   struct static_ipv4 *si;
                   2396:   struct route_table *stable;
                   2397: 
                   2398:   /* Lookup table.  */
                   2399:   stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
                   2400:   if (! stable)
                   2401:     return -1;
                   2402: 
                   2403:   /* Lookup static route prefix. */
                   2404:   rn = route_node_lookup (stable, p);
                   2405:   if (! rn)
                   2406:     return 0;
                   2407: 
                   2408:   /* Make flags. */
                   2409:   if (gate)
                   2410:     type = STATIC_IPV4_GATEWAY;
                   2411:   else if (ifname)
                   2412:     type = STATIC_IPV4_IFNAME;
                   2413:   else
                   2414:     type = STATIC_IPV4_BLACKHOLE;
                   2415: 
                   2416:   /* Find same static route is the tree */
                   2417:   for (si = rn->info; si; si = si->next)
                   2418:     if (type == si->type
                   2419:        && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
                   2420:        && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
                   2421:       break;
                   2422: 
                   2423:   /* Can't find static route. */
                   2424:   if (! si)
                   2425:     {
                   2426:       route_unlock_node (rn);
                   2427:       return 0;
                   2428:     }
                   2429: 
                   2430:   /* Install into rib. */
                   2431:   static_uninstall_ipv4 (p, si);
                   2432: 
                   2433:   /* Unlink static route from linked list. */
                   2434:   if (si->prev)
                   2435:     si->prev->next = si->next;
                   2436:   else
                   2437:     rn->info = si->next;
                   2438:   if (si->next)
                   2439:     si->next->prev = si->prev;
                   2440:   route_unlock_node (rn);
                   2441:   
                   2442:   /* Free static route configuration. */
                   2443:   if (ifname)
                   2444:     XFREE (0, si->gate.ifname);
                   2445:   XFREE (MTYPE_STATIC_IPV4, si);
                   2446: 
                   2447:   route_unlock_node (rn);
                   2448: 
                   2449:   return 1;
                   2450: }
                   2451: 
                   2452: 
                   2453: #ifdef HAVE_IPV6
                   2454: static int
                   2455: rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
                   2456:                struct in6_addr *gate, unsigned int ifindex, int table)
                   2457: {
                   2458:   if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
                   2459: #if defined (MUSICA) || defined (LINUX)
                   2460:     /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
                   2461:     if (p->prefixlen == 96)
                   2462:       return 0;
                   2463: #endif /* MUSICA */
                   2464:     return 1;
                   2465:   }
                   2466:   if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
                   2467:       && p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
                   2468:     {
                   2469:       kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
                   2470:       return 1;
                   2471:     }
                   2472:   return 0;
                   2473: }
                   2474: 
                   2475: int
                   2476: rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
                   2477:              struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
1.1.1.2   misho    2478:              u_int32_t metric, u_char distance, safi_t safi)
1.1       misho    2479: {
                   2480:   struct rib *rib;
                   2481:   struct rib *same = NULL;
                   2482:   struct route_table *table;
                   2483:   struct route_node *rn;
                   2484:   struct nexthop *nexthop;
                   2485: 
                   2486:   /* Lookup table.  */
1.1.1.2   misho    2487:   table = vrf_table (AFI_IP6, safi, 0);
1.1       misho    2488:   if (! table)
                   2489:     return 0;
                   2490: 
                   2491:   /* Make sure mask is applied. */
                   2492:   apply_mask_ipv6 (p);
                   2493: 
                   2494:   /* Set default distance by route type. */
                   2495:   if (!distance)
                   2496:     distance = route_info[type].distance;
                   2497:   
                   2498:   if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
                   2499:     distance = 200;
                   2500: 
                   2501:   /* Filter bogus route. */
                   2502:   if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
                   2503:     return 0;
                   2504: 
                   2505:   /* Lookup route node.*/
                   2506:   rn = route_node_get (table, (struct prefix *) p);
                   2507: 
                   2508:   /* If same type of route are installed, treat it as a implicit
                   2509:      withdraw. */
1.1.1.3 ! misho    2510:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2511:     {
                   2512:       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   2513:         continue;
                   2514: 
                   2515:       if (rib->type != type)
                   2516:        continue;
                   2517:       if (rib->type != ZEBRA_ROUTE_CONNECT)
                   2518:        {
                   2519:          same = rib;
                   2520:          break;
                   2521:        }
                   2522:       else if ((nexthop = rib->nexthop) &&
                   2523:               nexthop->type == NEXTHOP_TYPE_IFINDEX &&
                   2524:               nexthop->ifindex == ifindex)
                   2525:        {
                   2526:          rib->refcnt++;
                   2527:          return 0;
                   2528:        }
                   2529:     }
                   2530: 
                   2531:   /* Allocate new rib structure. */
                   2532:   rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
                   2533:   
                   2534:   rib->type = type;
                   2535:   rib->distance = distance;
                   2536:   rib->flags = flags;
                   2537:   rib->metric = metric;
                   2538:   rib->table = vrf_id;
                   2539:   rib->nexthop_num = 0;
                   2540:   rib->uptime = time (NULL);
                   2541: 
                   2542:   /* Nexthop settings. */
                   2543:   if (gate)
                   2544:     {
                   2545:       if (ifindex)
                   2546:        nexthop_ipv6_ifindex_add (rib, gate, ifindex);
                   2547:       else
                   2548:        nexthop_ipv6_add (rib, gate);
                   2549:     }
                   2550:   else
                   2551:     nexthop_ifindex_add (rib, ifindex);
                   2552: 
                   2553:   /* If this route is kernel route, set FIB flag to the route. */
                   2554:   if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
                   2555:     for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   2556:       SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                   2557: 
                   2558:   /* Link new rib to node.*/
                   2559:   rib_addnode (rn, rib);
                   2560: 
                   2561:   /* Free implicit route.*/
                   2562:   if (same)
                   2563:     rib_delnode (rn, same);
                   2564:   
                   2565:   route_unlock_node (rn);
                   2566:   return 0;
                   2567: }
                   2568: 
                   2569: /* XXX factor with rib_delete_ipv6 */
                   2570: int
                   2571: rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
1.1.1.2   misho    2572:                 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
1.1       misho    2573: {
                   2574:   struct route_table *table;
                   2575:   struct route_node *rn;
                   2576:   struct rib *rib;
                   2577:   struct rib *fib = NULL;
                   2578:   struct rib *same = NULL;
                   2579:   struct nexthop *nexthop;
                   2580:   char buf1[INET6_ADDRSTRLEN];
                   2581:   char buf2[INET6_ADDRSTRLEN];
                   2582: 
                   2583:   /* Apply mask. */
                   2584:   apply_mask_ipv6 (p);
                   2585: 
                   2586:   /* Lookup table.  */
1.1.1.2   misho    2587:   table = vrf_table (AFI_IP6, safi, 0);
1.1       misho    2588:   if (! table)
                   2589:     return 0;
                   2590:   
                   2591:   /* Lookup route node. */
                   2592:   rn = route_node_lookup (table, (struct prefix *) p);
                   2593:   if (! rn)
                   2594:     {
                   2595:       if (IS_ZEBRA_DEBUG_KERNEL)
                   2596:        {
                   2597:          if (gate)
                   2598:            zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
                   2599:                       inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
                   2600:                       p->prefixlen,
                   2601:                       inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
                   2602:                       ifindex);
                   2603:          else
                   2604:            zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
                   2605:                       inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
                   2606:                       p->prefixlen,
                   2607:                       ifindex);
                   2608:        }
                   2609:       return ZEBRA_ERR_RTNOEXIST;
                   2610:     }
                   2611: 
                   2612:   /* Lookup same type route. */
1.1.1.3 ! misho    2613:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2614:     {
                   2615:       if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
                   2616:         continue;
                   2617: 
                   2618:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
                   2619:        fib = rib;
                   2620: 
                   2621:       if (rib->type != type)
                   2622:         continue;
                   2623:       if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
1.1.1.2   misho    2624:          nexthop->type == NEXTHOP_TYPE_IFINDEX)
1.1       misho    2625:        {
1.1.1.2   misho    2626:          if (nexthop->ifindex != ifindex)
                   2627:            continue;
1.1       misho    2628:          if (rib->refcnt)
                   2629:            {
                   2630:              rib->refcnt--;
                   2631:              route_unlock_node (rn);
                   2632:              route_unlock_node (rn);
                   2633:              return 0;
                   2634:            }
                   2635:          same = rib;
                   2636:          break;
                   2637:        }
                   2638:       /* Make sure that the route found has the same gateway. */
                   2639:       else if (gate == NULL ||
                   2640:               ((nexthop = rib->nexthop) &&
                   2641:                (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
                   2642:                 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
                   2643:        {
                   2644:          same = rib;
                   2645:          break;
                   2646:        }
                   2647:     }
                   2648: 
                   2649:   /* If same type of route can't be found and this message is from
                   2650:      kernel. */
                   2651:   if (! same)
                   2652:     {
                   2653:       if (fib && type == ZEBRA_ROUTE_KERNEL)
                   2654:        {
                   2655:          /* Unset flags. */
                   2656:          for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
                   2657:            UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
                   2658: 
                   2659:          UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
                   2660:        }
                   2661:       else
                   2662:        {
                   2663:          if (IS_ZEBRA_DEBUG_KERNEL)
                   2664:            {
                   2665:              if (gate)
                   2666:                zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
                   2667:                           inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
                   2668:                           p->prefixlen,
                   2669:                           inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
                   2670:                           ifindex,
                   2671:                           type);
                   2672:              else
                   2673:                zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
                   2674:                           inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
                   2675:                           p->prefixlen,
                   2676:                           ifindex,
                   2677:                           type);
                   2678:            }
                   2679:          route_unlock_node (rn);
                   2680:          return ZEBRA_ERR_RTNOEXIST;
                   2681:        }
                   2682:     }
                   2683: 
                   2684:   if (same)
                   2685:     rib_delnode (rn, same);
                   2686:   
                   2687:   route_unlock_node (rn);
                   2688:   return 0;
                   2689: }
                   2690: 
                   2691: /* Install static route into rib. */
                   2692: static void
                   2693: static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
                   2694: {
                   2695:   struct rib *rib;
                   2696:   struct route_table *table;
                   2697:   struct route_node *rn;
                   2698: 
                   2699:   /* Lookup table.  */
                   2700:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
                   2701:   if (! table)
                   2702:     return;
                   2703: 
                   2704:   /* Lookup existing route */
                   2705:   rn = route_node_get (table, p);
1.1.1.3 ! misho    2706:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2707:     {
                   2708:       if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
                   2709:         continue;
                   2710: 
                   2711:       if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
                   2712:         break;
                   2713:     }
                   2714: 
                   2715:   if (rib)
                   2716:     {
                   2717:       /* Same distance static route is there.  Update it with new
                   2718:          nexthop. */
                   2719:       route_unlock_node (rn);
                   2720: 
                   2721:       switch (si->type)
                   2722:        {
                   2723:        case STATIC_IPV6_GATEWAY:
                   2724:          nexthop_ipv6_add (rib, &si->ipv6);
                   2725:          break;
                   2726:        case STATIC_IPV6_IFNAME:
                   2727:          nexthop_ifname_add (rib, si->ifname);
                   2728:          break;
                   2729:        case STATIC_IPV6_GATEWAY_IFNAME:
                   2730:          nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
                   2731:          break;
                   2732:        }
                   2733:       rib_queue_add (&zebrad, rn);
                   2734:     }
                   2735:   else
                   2736:     {
                   2737:       /* This is new static route. */
                   2738:       rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
                   2739:       
                   2740:       rib->type = ZEBRA_ROUTE_STATIC;
                   2741:       rib->distance = si->distance;
                   2742:       rib->metric = 0;
                   2743:       rib->nexthop_num = 0;
                   2744: 
                   2745:       switch (si->type)
                   2746:        {
                   2747:        case STATIC_IPV6_GATEWAY:
                   2748:          nexthop_ipv6_add (rib, &si->ipv6);
                   2749:          break;
                   2750:        case STATIC_IPV6_IFNAME:
                   2751:          nexthop_ifname_add (rib, si->ifname);
                   2752:          break;
                   2753:        case STATIC_IPV6_GATEWAY_IFNAME:
                   2754:          nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
                   2755:          break;
                   2756:        }
                   2757: 
                   2758:       /* Save the flags of this static routes (reject, blackhole) */
                   2759:       rib->flags = si->flags;
                   2760: 
                   2761:       /* Link this rib to the tree. */
                   2762:       rib_addnode (rn, rib);
                   2763:     }
                   2764: }
                   2765: 
                   2766: static int
                   2767: static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
                   2768: {
                   2769:   if (nexthop->type == NEXTHOP_TYPE_IPV6
                   2770:       && si->type == STATIC_IPV6_GATEWAY
                   2771:       && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
                   2772:     return 1;
                   2773:   if (nexthop->type == NEXTHOP_TYPE_IFNAME
                   2774:       && si->type == STATIC_IPV6_IFNAME
                   2775:       && strcmp (nexthop->ifname, si->ifname) == 0)
                   2776:     return 1;
                   2777:   if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
                   2778:       && si->type == STATIC_IPV6_GATEWAY_IFNAME
                   2779:       && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
                   2780:       && strcmp (nexthop->ifname, si->ifname) == 0)
                   2781:     return 1;
                   2782:   return 0;
                   2783: }
                   2784: 
                   2785: static void
                   2786: static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
                   2787: {
                   2788:   struct route_table *table;
                   2789:   struct route_node *rn;
                   2790:   struct rib *rib;
                   2791:   struct nexthop *nexthop;
                   2792: 
                   2793:   /* Lookup table.  */
                   2794:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
                   2795:   if (! table)
                   2796:     return;
                   2797: 
                   2798:   /* Lookup existing route with type and distance. */
                   2799:   rn = route_node_lookup (table, (struct prefix *) p);
                   2800:   if (! rn)
                   2801:     return;
                   2802: 
1.1.1.3 ! misho    2803:   RNODE_FOREACH_RIB (rn, rib)
1.1       misho    2804:     {
                   2805:       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   2806:         continue;
                   2807:     
                   2808:       if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
                   2809:         break;
                   2810:     }
                   2811: 
                   2812:   if (! rib)
                   2813:     {
                   2814:       route_unlock_node (rn);
                   2815:       return;
                   2816:     }
                   2817: 
                   2818:   /* Lookup nexthop. */
                   2819:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                   2820:     if (static_ipv6_nexthop_same (nexthop, si))
                   2821:       break;
                   2822: 
                   2823:   /* Can't find nexthop. */
                   2824:   if (! nexthop)
                   2825:     {
                   2826:       route_unlock_node (rn);
                   2827:       return;
                   2828:     }
                   2829:   
                   2830:   /* Check nexthop. */
                   2831:   if (rib->nexthop_num == 1)
                   2832:     {
                   2833:       rib_delnode (rn, rib);
                   2834:     }
                   2835:   else
                   2836:     {
                   2837:       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                   2838:         rib_uninstall (rn, rib);
                   2839:       nexthop_delete (rib, nexthop);
                   2840:       nexthop_free (nexthop);
                   2841:       rib_queue_add (&zebrad, rn);
                   2842:     }
                   2843:   /* Unlock node. */
                   2844:   route_unlock_node (rn);
                   2845: }
                   2846: 
                   2847: /* Add static route into static route configuration. */
                   2848: int
                   2849: static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
                   2850:                 const char *ifname, u_char flags, u_char distance,
                   2851:                 u_int32_t vrf_id)
                   2852: {
                   2853:   struct route_node *rn;
                   2854:   struct static_ipv6 *si;
                   2855:   struct static_ipv6 *pp;
                   2856:   struct static_ipv6 *cp;
                   2857:   struct route_table *stable;
                   2858: 
                   2859:   /* Lookup table.  */
                   2860:   stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
                   2861:   if (! stable)
                   2862:     return -1;
                   2863:     
                   2864:   if (!gate &&
                   2865:       (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
                   2866:     return -1;
                   2867:   
                   2868:   if (!ifname && 
                   2869:       (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
                   2870:     return -1;
                   2871: 
                   2872:   /* Lookup static route prefix. */
                   2873:   rn = route_node_get (stable, p);
                   2874: 
                   2875:   /* Do nothing if there is a same static route.  */
                   2876:   for (si = rn->info; si; si = si->next)
                   2877:     {
                   2878:       if (distance == si->distance 
                   2879:          && type == si->type
                   2880:          && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
                   2881:          && (! ifname || strcmp (ifname, si->ifname) == 0))
                   2882:        {
                   2883:          route_unlock_node (rn);
                   2884:          return 0;
                   2885:        }
                   2886:     }
                   2887: 
                   2888:   /* Make new static route structure. */
                   2889:   si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
                   2890: 
                   2891:   si->type = type;
                   2892:   si->distance = distance;
                   2893:   si->flags = flags;
                   2894: 
                   2895:   switch (type)
                   2896:     {
                   2897:     case STATIC_IPV6_GATEWAY:
                   2898:       si->ipv6 = *gate;
                   2899:       break;
                   2900:     case STATIC_IPV6_IFNAME:
                   2901:       si->ifname = XSTRDUP (0, ifname);
                   2902:       break;
                   2903:     case STATIC_IPV6_GATEWAY_IFNAME:
                   2904:       si->ipv6 = *gate;
                   2905:       si->ifname = XSTRDUP (0, ifname);
                   2906:       break;
                   2907:     }
                   2908: 
                   2909:   /* Add new static route information to the tree with sort by
                   2910:      distance value and gateway address. */
                   2911:   for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
                   2912:     {
                   2913:       if (si->distance < cp->distance)
                   2914:        break;
                   2915:       if (si->distance > cp->distance)
                   2916:        continue;
                   2917:     }
                   2918: 
                   2919:   /* Make linked list. */
                   2920:   if (pp)
                   2921:     pp->next = si;
                   2922:   else
                   2923:     rn->info = si;
                   2924:   if (cp)
                   2925:     cp->prev = si;
                   2926:   si->prev = pp;
                   2927:   si->next = cp;
                   2928: 
                   2929:   /* Install into rib. */
                   2930:   static_install_ipv6 (p, si);
                   2931: 
                   2932:   return 1;
                   2933: }
                   2934: 
                   2935: /* Delete static route from static route configuration. */
                   2936: int
                   2937: static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
                   2938:                    const char *ifname, u_char distance, u_int32_t vrf_id)
                   2939: {
                   2940:   struct route_node *rn;
                   2941:   struct static_ipv6 *si;
                   2942:   struct route_table *stable;
                   2943: 
                   2944:   /* Lookup table.  */
                   2945:   stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
                   2946:   if (! stable)
                   2947:     return -1;
                   2948: 
                   2949:   /* Lookup static route prefix. */
                   2950:   rn = route_node_lookup (stable, p);
                   2951:   if (! rn)
                   2952:     return 0;
                   2953: 
                   2954:   /* Find same static route is the tree */
                   2955:   for (si = rn->info; si; si = si->next)
                   2956:     if (distance == si->distance 
                   2957:        && type == si->type
                   2958:        && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
                   2959:        && (! ifname || strcmp (ifname, si->ifname) == 0))
                   2960:       break;
                   2961: 
                   2962:   /* Can't find static route. */
                   2963:   if (! si)
                   2964:     {
                   2965:       route_unlock_node (rn);
                   2966:       return 0;
                   2967:     }
                   2968: 
                   2969:   /* Install into rib. */
                   2970:   static_uninstall_ipv6 (p, si);
                   2971: 
                   2972:   /* Unlink static route from linked list. */
                   2973:   if (si->prev)
                   2974:     si->prev->next = si->next;
                   2975:   else
                   2976:     rn->info = si->next;
                   2977:   if (si->next)
                   2978:     si->next->prev = si->prev;
                   2979:   
                   2980:   /* Free static route configuration. */
                   2981:   if (ifname)
                   2982:     XFREE (0, si->ifname);
                   2983:   XFREE (MTYPE_STATIC_IPV6, si);
                   2984: 
                   2985:   return 1;
                   2986: }
                   2987: #endif /* HAVE_IPV6 */
                   2988: 
                   2989: /* RIB update function. */
                   2990: void
                   2991: rib_update (void)
                   2992: {
                   2993:   struct route_node *rn;
                   2994:   struct route_table *table;
                   2995:   
                   2996:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
                   2997:   if (table)
                   2998:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho    2999:       if (rnode_to_ribs (rn))
1.1       misho    3000:         rib_queue_add (&zebrad, rn);
                   3001: 
                   3002:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
                   3003:   if (table)
                   3004:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho    3005:       if (rnode_to_ribs (rn))
1.1       misho    3006:         rib_queue_add (&zebrad, rn);
                   3007: }
                   3008: 
                   3009: 
                   3010: /* Remove all routes which comes from non main table.  */
                   3011: static void
                   3012: rib_weed_table (struct route_table *table)
                   3013: {
                   3014:   struct route_node *rn;
                   3015:   struct rib *rib;
                   3016:   struct rib *next;
                   3017: 
                   3018:   if (table)
                   3019:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho    3020:       RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1       misho    3021:        {
                   3022:          if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   3023:            continue;
                   3024: 
                   3025:          if (rib->table != zebrad.rtm_table_default &&
                   3026:              rib->table != RT_TABLE_MAIN)
                   3027:             rib_delnode (rn, rib);
                   3028:        }
                   3029: }
                   3030: 
                   3031: /* Delete all routes from non main table. */
                   3032: void
                   3033: rib_weed_tables (void)
                   3034: {
                   3035:   rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
                   3036:   rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
                   3037: }
                   3038: 
                   3039: /* Delete self installed routes after zebra is relaunched.  */
                   3040: static void
                   3041: rib_sweep_table (struct route_table *table)
                   3042: {
                   3043:   struct route_node *rn;
                   3044:   struct rib *rib;
                   3045:   struct rib *next;
                   3046:   int ret = 0;
                   3047: 
                   3048:   if (table)
                   3049:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho    3050:       RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1       misho    3051:        {
                   3052:          if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   3053:            continue;
                   3054: 
                   3055:          if (rib->type == ZEBRA_ROUTE_KERNEL && 
                   3056:              CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE))
                   3057:            {
                   3058:              ret = rib_uninstall_kernel (rn, rib);
                   3059:              if (! ret)
                   3060:                 rib_delnode (rn, rib);
                   3061:            }
                   3062:        }
                   3063: }
                   3064: 
                   3065: /* Sweep all RIB tables.  */
                   3066: void
                   3067: rib_sweep_route (void)
                   3068: {
                   3069:   rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
                   3070:   rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
                   3071: }
1.1.1.2   misho    3072: 
                   3073: /* Remove specific by protocol routes from 'table'. */
                   3074: static unsigned long
                   3075: rib_score_proto_table (u_char proto, struct route_table *table)
                   3076: {
                   3077:   struct route_node *rn;
                   3078:   struct rib *rib;
                   3079:   struct rib *next;
                   3080:   unsigned long n = 0;
                   3081: 
                   3082:   if (table)
                   3083:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho    3084:       RNODE_FOREACH_RIB_SAFE (rn, rib, next)
1.1.1.2   misho    3085:         {
                   3086:           if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
                   3087:             continue;
                   3088:           if (rib->type == proto)
                   3089:             {
                   3090:               rib_delnode (rn, rib);
                   3091:               n++;
                   3092:             }
                   3093:         }
                   3094: 
                   3095:   return n;
                   3096: }
                   3097: 
                   3098: /* Remove specific by protocol routes. */
                   3099: unsigned long
                   3100: rib_score_proto (u_char proto)
                   3101: {
                   3102:   return  rib_score_proto_table (proto, vrf_table (AFI_IP,  SAFI_UNICAST, 0))
                   3103:          +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
                   3104: }
                   3105: 
1.1       misho    3106: /* Close RIB and clean up kernel routes. */
                   3107: static void
                   3108: rib_close_table (struct route_table *table)
                   3109: {
                   3110:   struct route_node *rn;
                   3111:   struct rib *rib;
                   3112: 
                   3113:   if (table)
                   3114:     for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho    3115:       RNODE_FOREACH_RIB (rn, rib)
1.1       misho    3116:         {
1.1.1.3 ! misho    3117:           if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
        !          3118:            continue;
        !          3119: 
        !          3120:          zfpm_trigger_update (rn, NULL);
        !          3121: 
        !          3122:          if (! RIB_SYSTEM_ROUTE (rib))
        !          3123:            rib_uninstall_kernel (rn, rib);
1.1       misho    3124:         }
                   3125: }
                   3126: 
                   3127: /* Close all RIB tables.  */
                   3128: void
                   3129: rib_close (void)
                   3130: {
                   3131:   rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
                   3132:   rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
                   3133: }
                   3134: 
                   3135: /* Routing information base initialize. */
                   3136: void
                   3137: rib_init (void)
                   3138: {
                   3139:   rib_queue_init (&zebrad);
                   3140:   /* VRF initialization.  */
                   3141:   vrf_init ();
                   3142: }
1.1.1.3 ! misho    3143: 
        !          3144: /*
        !          3145:  * vrf_id_get_next
        !          3146:  *
        !          3147:  * Get the first vrf id that is greater than the given vrf id if any.
        !          3148:  *
        !          3149:  * Returns TRUE if a vrf id was found, FALSE otherwise.
        !          3150:  */
        !          3151: static inline int
        !          3152: vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
        !          3153: {
        !          3154:   while (++id < vector_active (vrf_vector))
        !          3155:     {
        !          3156:       if (vrf_lookup (id))
        !          3157:        {
        !          3158:          *next_id_p = id;
        !          3159:          return 1;
        !          3160:        }
        !          3161:     }
        !          3162: 
        !          3163:   return 0;
        !          3164: }
        !          3165: 
        !          3166: /*
        !          3167:  * rib_tables_iter_next
        !          3168:  *
        !          3169:  * Returns the next table in the iteration.
        !          3170:  */
        !          3171: struct route_table *
        !          3172: rib_tables_iter_next (rib_tables_iter_t *iter)
        !          3173: {
        !          3174:   struct route_table *table;
        !          3175: 
        !          3176:   /*
        !          3177:    * Array that helps us go over all AFI/SAFI combinations via one
        !          3178:    * index.
        !          3179:    */
        !          3180:   static struct {
        !          3181:     afi_t afi;
        !          3182:     safi_t safi;
        !          3183:   } afi_safis[] = {
        !          3184:     { AFI_IP, SAFI_UNICAST },
        !          3185:     { AFI_IP, SAFI_MULTICAST },
        !          3186:     { AFI_IP6, SAFI_UNICAST },
        !          3187:     { AFI_IP6, SAFI_MULTICAST },
        !          3188:   };
        !          3189: 
        !          3190:   table = NULL;
        !          3191: 
        !          3192:   switch (iter->state)
        !          3193:     {
        !          3194: 
        !          3195:     case RIB_TABLES_ITER_S_INIT:
        !          3196:       iter->vrf_id = 0;
        !          3197:       iter->afi_safi_ix = -1;
        !          3198: 
        !          3199:       /* Fall through */
        !          3200: 
        !          3201:     case RIB_TABLES_ITER_S_ITERATING:
        !          3202:       iter->afi_safi_ix++;
        !          3203:       while (1)
        !          3204:        {
        !          3205: 
        !          3206:          while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
        !          3207:            {
        !          3208:              table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
        !          3209:                                 afi_safis[iter->afi_safi_ix].safi,
        !          3210:                                 iter->vrf_id);
        !          3211:              if (table)
        !          3212:                break;
        !          3213: 
        !          3214:              iter->afi_safi_ix++;
        !          3215:            }
        !          3216: 
        !          3217:          /*
        !          3218:           * Found another table in this vrf.
        !          3219:           */
        !          3220:          if (table)
        !          3221:            break;
        !          3222: 
        !          3223:          /*
        !          3224:           * Done with all tables in the current vrf, go to the next
        !          3225:           * one.
        !          3226:           */
        !          3227:          if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id))
        !          3228:            break;
        !          3229: 
        !          3230:          iter->afi_safi_ix = 0;
        !          3231:        }
        !          3232: 
        !          3233:       break;
        !          3234: 
        !          3235:     case RIB_TABLES_ITER_S_DONE:
        !          3236:       return NULL;
        !          3237:     }
        !          3238: 
        !          3239:   if (table)
        !          3240:     iter->state = RIB_TABLES_ITER_S_ITERATING;
        !          3241:   else
        !          3242:     iter->state = RIB_TABLES_ITER_S_DONE;
        !          3243: 
        !          3244:   return table;
        !          3245: }

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