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

网络

开发平台:

Unix_Linux

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