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

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

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