File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zebra_rib.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:29 2012 UTC (11 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, HEAD
quagga

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

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