LCOV - code coverage report
Current view: top level - zebra - zebra_rib.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 886 1491 59.4 %
Date: 2015-11-19 Functions: 59 77 76.6 %

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

Generated by: LCOV version 1.10