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

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

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