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

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

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