table.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:10k
源码类别:

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Routing Table functions.
  3.  * Copyright (C) 1998 Kunihiro Ishiguro
  4.  *
  5.  * This file is part of GNU Zebra.
  6.  *
  7.  * GNU Zebra is free software; you can redistribute it and/or modify it
  8.  * under the terms of the GNU General Public License as published by the
  9.  * Free Software Foundation; either version 2, or (at your option) any
  10.  * later version.
  11.  *
  12.  * GNU Zebra is distributed in the hope that it will be useful, but
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  19.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20.  * 02111-1307, USA.  
  21.  */
  22. #include <zebra.h>
  23. #include "prefix.h"
  24. #include "table.h"
  25. #include "memory.h"
  26. #include "sockunion.h"
  27. void route_node_delete (struct route_node *);
  28. void route_table_free (struct route_table *);
  29. struct route_table *
  30. route_table_init (void)
  31. {
  32.   struct route_table *rt;
  33.   rt = XCALLOC (MTYPE_ROUTE_TABLE, sizeof (struct route_table));
  34.   return rt;
  35. }
  36. void
  37. route_table_finish (struct route_table *rt)
  38. {
  39.   route_table_free (rt);
  40. }
  41. /* Allocate new route node. */
  42. struct route_node *
  43. route_node_new ()
  44. {
  45.   struct route_node *node;
  46.   node = XCALLOC (MTYPE_ROUTE_NODE, sizeof (struct route_node));
  47.   return node;
  48. }
  49. /* Allocate new route node with prefix set. */
  50. struct route_node *
  51. route_node_set (struct route_table *table, struct prefix *prefix)
  52. {
  53.   struct route_node *node;
  54.   
  55.   node = route_node_new ();
  56.   prefix_copy (&node->p, prefix);
  57.   node->table = table;
  58.   return node;
  59. }
  60. /* Free route node. */
  61. void
  62. route_node_free (struct route_node *node)
  63. {
  64.   XFREE (MTYPE_ROUTE_NODE, node);
  65. }
  66. /* Free route table. */
  67. void
  68. route_table_free (struct route_table *rt)
  69. {
  70.   struct route_node *tmp_node;
  71.   struct route_node *node;
  72.  
  73.   if (rt == NULL)
  74.     return;
  75.   node = rt->top;
  76.   while (node)
  77.     {
  78.       if (node->l_left)
  79. {
  80.   node = node->l_left;
  81.   continue;
  82. }
  83.       if (node->l_right)
  84. {
  85.   node = node->l_right;
  86.   continue;
  87. }
  88.       tmp_node = node;
  89.       node = node->parent;
  90.       if (node != NULL)
  91. {
  92.   if (node->l_left == tmp_node)
  93.     node->l_left = NULL;
  94.   else
  95.     node->l_right = NULL;
  96.   route_node_free (tmp_node);
  97. }
  98.       else
  99. {
  100.   route_node_free (tmp_node);
  101.   break;
  102. }
  103.     }
  104.  
  105.   XFREE (MTYPE_ROUTE_TABLE, rt);
  106.   return;
  107. }
  108. /* Utility mask array. */
  109. static u_char maskbit[] = 
  110. {
  111.   0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
  112. };
  113. /* Common prefix route genaration. */
  114. static void
  115. route_common (struct prefix *n, struct prefix *p, struct prefix *new)
  116. {
  117.   int i;
  118.   u_char diff;
  119.   u_char mask;
  120.   u_char *np = (u_char *)&n->u.prefix;
  121.   u_char *pp = (u_char *)&p->u.prefix;
  122.   u_char *newp = (u_char *)&new->u.prefix;
  123.   for (i = 0; i < p->prefixlen / 8; i++)
  124.     {
  125.       if (np[i] == pp[i])
  126. newp[i] = np[i];
  127.       else
  128. break;
  129.     }
  130.   new->prefixlen = i * 8;
  131.   if (new->prefixlen != p->prefixlen)
  132.     {
  133.       diff = np[i] ^ pp[i];
  134.       mask = 0x80;
  135.       while (new->prefixlen < p->prefixlen && !(mask & diff))
  136. {
  137.   mask >>= 1;
  138.   new->prefixlen++;
  139. }
  140.       newp[i] = np[i] & maskbit[new->prefixlen % 8];
  141.     }
  142. }
  143. /* Macro version of check_bit (). */
  144. #define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
  145. /* Check bit of the prefix. */
  146. static int
  147. check_bit (u_char *prefix, u_char prefixlen)
  148. {
  149.   int offset;
  150.   int shift;
  151.   u_char *p = (u_char *)prefix;
  152.   assert (prefixlen <= 128);
  153.   offset = prefixlen / 8;
  154.   shift = 7 - (prefixlen % 8);
  155.   
  156.   return (p[offset] >> shift & 1);
  157. }
  158. /* Macro version of set_link (). */
  159. #define SET_LINK(X,Y) (X)->link[CHECK_BIT(&(Y)->prefix,(X)->prefixlen)] = (Y);
  160.                       (Y)->parent = (X)
  161. static void
  162. set_link (struct route_node *node, struct route_node *new)
  163. {
  164.   int bit;
  165.     
  166.   bit = check_bit (&new->p.u.prefix, node->p.prefixlen);
  167.   assert (bit == 0 || bit == 1);
  168.   node->link[bit] = new;
  169.   new->parent = node;
  170. }
  171. /* Lock node. */
  172. struct route_node *
  173. route_lock_node (struct route_node *node)
  174. {
  175.   node->lock++;
  176.   return node;
  177. }
  178. /* Unlock node. */
  179. void
  180. route_unlock_node (struct route_node *node)
  181. {
  182.   node->lock--;
  183.   if (node->lock == 0)
  184.     route_node_delete (node);
  185. }
  186. /* Dump routing table. */
  187. void
  188. route_dump_node (struct route_table *t)
  189. {
  190.   struct route_node *node;
  191.   char buf[46];
  192.   for (node = route_top (t); node != NULL; node = route_next (node))
  193.     {
  194.       printf ("[%d] %p %s/%dn", 
  195.       node->lock,
  196.       node->info,
  197.       inet_ntop (node->p.family, &node->p.u.prefix, buf, 46),
  198.       node->p.prefixlen);
  199.     }
  200. }
  201. /* Find matched prefix. */
  202. struct route_node *
  203. route_node_match (struct route_table *table, struct prefix *p)
  204. {
  205.   struct route_node *node;
  206.   struct route_node *matched;
  207.   matched = NULL;
  208.   node = table->top;
  209.   /* Walk down tree.  If there is matched route then store it to
  210.      matched. */
  211.   while (node && node->p.prefixlen <= p->prefixlen && 
  212.  prefix_match (&node->p, p))
  213.     {
  214.       if (node->info)
  215. matched = node;
  216.       node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)];
  217.     }
  218.   /* If matched route found, return it. */
  219.   if (matched)
  220.     return route_lock_node (matched);
  221.   return NULL;
  222. }
  223. struct route_node *
  224. route_node_match_ipv4 (struct route_table *table, struct in_addr *addr)
  225. {
  226.   struct prefix_ipv4 p;
  227.   memset (&p, 0, sizeof (struct prefix_ipv4));
  228.   p.family = AF_INET;
  229.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  230.   p.prefix = *addr;
  231.   return route_node_match (table, (struct prefix *) &p);
  232. }
  233. #ifdef HAVE_IPV6
  234. struct route_node *
  235. route_node_match_ipv6 (struct route_table *table, struct in6_addr *addr)
  236. {
  237.   struct prefix_ipv6 p;
  238.   memset (&p, 0, sizeof (struct prefix_ipv6));
  239.   p.family = AF_INET6;
  240.   p.prefixlen = IPV6_MAX_PREFIXLEN;
  241.   p.prefix = *addr;
  242.   return route_node_match (table, (struct prefix *) &p);
  243. }
  244. #endif /* HAVE_IPV6 */
  245. /* Lookup same prefix node.  Return NULL when we can't find route. */
  246. struct route_node *
  247. route_node_lookup (struct route_table *table, struct prefix *p)
  248. {
  249.   struct route_node *node;
  250.   node = table->top;
  251.   while (node && node->p.prefixlen <= p->prefixlen && 
  252.  prefix_match (&node->p, p))
  253.     {
  254.       if (node->p.prefixlen == p->prefixlen && node->info)
  255. return route_lock_node (node);
  256.       node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)];
  257.     }
  258.   return NULL;
  259. }
  260. /* Add node to routing table. */
  261. struct route_node *
  262. route_node_get (struct route_table *table, struct prefix *p)
  263. {
  264.   struct route_node *new;
  265.   struct route_node *node;
  266.   struct route_node *match;
  267.   match = NULL;
  268.   node = table->top;
  269.   while (node && node->p.prefixlen <= p->prefixlen && 
  270.  prefix_match (&node->p, p))
  271.     {
  272.       if (node->p.prefixlen == p->prefixlen)
  273. {
  274.   route_lock_node (node);
  275.   return node;
  276. }
  277.       match = node;
  278.       node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)];
  279.     }
  280.   if (node == NULL)
  281.     {
  282.       new = route_node_set (table, p);
  283.       if (match)
  284. set_link (match, new);
  285.       else
  286. table->top = new;
  287.     }
  288.   else
  289.     {
  290.       new = route_node_new ();
  291.       route_common (&node->p, p, &new->p);
  292.       new->p.family = p->family;
  293.       new->table = table;
  294.       set_link (new, node);
  295.       if (match)
  296. set_link (match, new);
  297.       else
  298. table->top = new;
  299.       if (new->p.prefixlen != p->prefixlen)
  300. {
  301.   match = new;
  302.   new = route_node_set (table, p);
  303.   set_link (match, new);
  304. }
  305.     }
  306.   route_lock_node (new);
  307.   
  308.   return new;
  309. }
  310. /* Delete node from the routing table. */
  311. void
  312. route_node_delete (struct route_node *node)
  313. {
  314.   struct route_node *child;
  315.   struct route_node *parent;
  316.   assert (node->lock == 0);
  317.   assert (node->info == NULL);
  318.   if (node->l_left && node->l_right)
  319.     return;
  320.   if (node->l_left)
  321.     child = node->l_left;
  322.   else
  323.     child = node->l_right;
  324.   parent = node->parent;
  325.   if (child)
  326.     child->parent = parent;
  327.   if (parent)
  328.     {
  329.       if (parent->l_left == node)
  330. parent->l_left = child;
  331.       else
  332. parent->l_right = child;
  333.     }
  334.   else
  335.     node->table->top = child;
  336.   route_node_free (node);
  337.   /* If parent node is stub then delete it also. */
  338.   if (parent && parent->lock == 0)
  339.     route_node_delete (parent);
  340. }
  341. /* Get fist node and lock it.  This function is useful when one want
  342.    to lookup all the node exist in the routing table. */
  343. struct route_node *
  344. route_top (struct route_table *table)
  345. {
  346.   /* If there is no node in the routing table return NULL. */
  347.   if (table->top == NULL)
  348.     return NULL;
  349.   /* Lock the top node and return it. */
  350.   route_lock_node (table->top);
  351.   return table->top;
  352. }
  353. /* Unlock current node and lock next node then return it. */
  354. struct route_node *
  355. route_next (struct route_node *node)
  356. {
  357.   struct route_node *next;
  358.   struct route_node *start;
  359.   /* Node may be deleted from route_unlock_node so we have to preserve
  360.      next node's pointer. */
  361.   if (node->l_left)
  362.     {
  363.       next = node->l_left;
  364.       route_lock_node (next);
  365.       route_unlock_node (node);
  366.       return next;
  367.     }
  368.   if (node->l_right)
  369.     {
  370.       next = node->l_right;
  371.       route_lock_node (next);
  372.       route_unlock_node (node);
  373.       return next;
  374.     }
  375.   start = node;
  376.   while (node->parent)
  377.     {
  378.       if (node->parent->l_left == node && node->parent->l_right)
  379. {
  380.   next = node->parent->l_right;
  381.   route_lock_node (next);
  382.   route_unlock_node (start);
  383.   return next;
  384. }
  385.       node = node->parent;
  386.     }
  387.   route_unlock_node (start);
  388.   return NULL;
  389. }
  390. /* Unlock current node and lock next node until limit. */
  391. struct route_node *
  392. route_next_until (struct route_node *node, struct route_node *limit)
  393. {
  394.   struct route_node *next;
  395.   struct route_node *start;
  396.   /* Node may be deleted from route_unlock_node so we have to preserve
  397.      next node's pointer. */
  398.   if (node->l_left)
  399.     {
  400.       next = node->l_left;
  401.       route_lock_node (next);
  402.       route_unlock_node (node);
  403.       return next;
  404.     }
  405.   if (node->l_right)
  406.     {
  407.       next = node->l_right;
  408.       route_lock_node (next);
  409.       route_unlock_node (node);
  410.       return next;
  411.     }
  412.   start = node;
  413.   while (node->parent && node != limit)
  414.     {
  415.       if (node->parent->l_left == node && node->parent->l_right)
  416. {
  417.   next = node->parent->l_right;
  418.   route_lock_node (next);
  419.   route_unlock_node (start);
  420.   return next;
  421. }
  422.       node = node->parent;
  423.     }
  424.   route_unlock_node (start);
  425.   return NULL;
  426. }