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

网络

开发平台:

Unix_Linux

  1. /* Redistribution Handler
  2.  * Copyright (C) 1998 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. #include <zebra.h>
  22. #include "vector.h"
  23. #include "vty.h"
  24. #include "command.h"
  25. #include "prefix.h"
  26. #include "table.h"
  27. #include "stream.h"
  28. #include "zclient.h"
  29. #include "linklist.h"
  30. #include "log.h"
  31. #include "zebra/rib.h"
  32. #include "zebra/zserv.h"
  33. #include "zebra/redistribute.h"
  34. #include "zebra/debug.h"
  35. int
  36. zebra_check_addr (struct prefix *p)
  37. {
  38.   if (p->family == AF_INET)
  39.     {
  40.       u_int32_t addr;
  41.       addr = p->u.prefix4.s_addr;
  42.       addr = ntohl (addr);
  43.       if (IPV4_NET127 (addr) || IN_CLASSD (addr))
  44. return 0;
  45.     }
  46. #ifdef HAVE_IPV6
  47.   if (p->family == AF_INET6)
  48.     {
  49.       if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
  50. return 0;
  51.       if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
  52. return 0;
  53.     }
  54. #endif /* HAVE_IPV6 */
  55.   return 1;
  56. }
  57. int
  58. is_default (struct prefix *p)
  59. {
  60.   if (p->family == AF_INET)
  61.     if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
  62.       return 1;
  63. #ifdef HAVE_IPV6
  64. #if 0  /* IPv6 default separation is now pending until protocol daemon
  65.           can handle that. */
  66.   if (p->family == AF_INET6)
  67.     if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
  68.       return 1;
  69. #endif /* 0 */
  70. #endif /* HAVE_IPV6 */
  71.   return 0;
  72. }
  73. void
  74. zebra_redistribute_default (struct zserv *client)
  75. {
  76.   struct prefix_ipv4 p;
  77.   struct route_table *table;
  78.   struct route_node *rn;
  79.   struct rib *newrib;
  80. #ifdef HAVE_IPV6
  81.   struct prefix_ipv6 p6;
  82. #endif /* HAVE_IPV6 */
  83.   /* Lookup default route. */
  84.   memset (&p, 0, sizeof (struct prefix_ipv4));
  85.   p.family = AF_INET;
  86.   /* Lookup table.  */
  87.   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  88.   if (table)
  89.     {
  90.       rn = route_node_lookup (table, (struct prefix *)&p);
  91.       if (rn)
  92. {
  93.   for (newrib = rn->info; newrib; newrib = newrib->next)
  94.     if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
  95. && newrib->distance != DISTANCE_INFINITY)
  96.       zsend_ipv4_add_multipath (client, &rn->p, newrib);
  97.   route_unlock_node (rn);
  98. }
  99.     }
  100. #ifdef HAVE_IPV6
  101.   /* Lookup default route. */
  102.   memset (&p6, 0, sizeof (struct prefix_ipv6));
  103.   p6.family = AF_INET6;
  104.   /* Lookup table.  */
  105.   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  106.   if (table)
  107.     {
  108.       rn = route_node_lookup (table, (struct prefix *)&p6);
  109.       if (rn)
  110. {
  111.   for (newrib = rn->info; newrib; newrib = newrib->next)
  112.     if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
  113. && newrib->distance != DISTANCE_INFINITY)
  114.       zsend_ipv6_add_multipath (client, &rn->p, newrib);
  115.   route_unlock_node (rn);
  116. }
  117.     }
  118. #endif /* HAVE_IPV6 */
  119. }
  120. /* Redistribute routes. */
  121. void
  122. zebra_redistribute (struct zserv *client, int type)
  123. {
  124.   struct rib *newrib;
  125.   struct route_table *table;
  126.   struct route_node *rn;
  127.   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  128.   if (table)
  129.     for (rn = route_top (table); rn; rn = route_next (rn))
  130.       for (newrib = rn->info; newrib; newrib = newrib->next)
  131. if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) 
  132.     && newrib->type == type 
  133.     && newrib->distance != DISTANCE_INFINITY
  134.     && zebra_check_addr (&rn->p))
  135.   zsend_ipv4_add_multipath (client, &rn->p, newrib);
  136.   
  137. #ifdef HAVE_IPV6
  138.   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  139.   if (table)
  140.     for (rn = route_top (table); rn; rn = route_next (rn))
  141.       for (newrib = rn->info; newrib; newrib = newrib->next)
  142. if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
  143.     && newrib->type == type 
  144.     && newrib->distance != DISTANCE_INFINITY
  145.     && zebra_check_addr (&rn->p))
  146.   zsend_ipv6_add_multipath (client, &rn->p, newrib);
  147. #endif /* HAVE_IPV6 */
  148. }
  149. extern list client_list;
  150. void
  151. redistribute_add (struct prefix *p, struct rib *rib)
  152. {
  153.   listnode node;
  154.   struct zserv *client;
  155.   for (node = listhead (client_list); node; nextnode (node))
  156.     if ((client = getdata (node)) != NULL)
  157.       {
  158. if (is_default (p))
  159.   {
  160.     if (client->redist_default || client->redist[rib->type])
  161.       {
  162. if (p->family == AF_INET)
  163.   zsend_ipv4_add_multipath (client, p, rib);
  164. #ifdef HAVE_IPV6
  165. if (p->family == AF_INET6)
  166.   zsend_ipv6_add_multipath (client, p, rib);
  167. #endif /* HAVE_IPV6 */   
  168.       }
  169.   }
  170. else if (client->redist[rib->type])
  171.   {
  172.     if (p->family == AF_INET)
  173.       zsend_ipv4_add_multipath (client, p, rib);
  174. #ifdef HAVE_IPV6
  175.     if (p->family == AF_INET6)
  176.       zsend_ipv6_add_multipath (client, p, rib);
  177. #endif /* HAVE_IPV6 */   
  178.   }
  179.       }
  180. }
  181. void
  182. redistribute_delete (struct prefix *p, struct rib *rib)
  183. {
  184.   listnode node;
  185.   struct zserv *client;
  186.   /* Add DISTANCE_INFINITY check. */
  187.   if (rib->distance == DISTANCE_INFINITY)
  188.     return;
  189.   for (node = listhead (client_list); node; nextnode (node))
  190.     if ((client = getdata (node)) != NULL)
  191.       {
  192. if (is_default (p))
  193.   {
  194.     if (client->redist_default || client->redist[rib->type])
  195.       {
  196. if (p->family == AF_INET)
  197.   zsend_ipv4_delete_multipath (client, p, rib);
  198. #ifdef HAVE_IPV6
  199. if (p->family == AF_INET6)
  200.   zsend_ipv6_delete_multipath (client, p, rib);
  201. #endif /* HAVE_IPV6 */   
  202.       }
  203.   }
  204. else if (client->redist[rib->type])
  205.   {
  206.     if (p->family == AF_INET)
  207.       zsend_ipv4_delete_multipath (client, p, rib);
  208. #ifdef HAVE_IPV6
  209.     if (p->family == AF_INET6)
  210.       zsend_ipv6_delete_multipath (client, p, rib);
  211. #endif /* HAVE_IPV6 */   
  212.   }
  213.       }
  214. }
  215. void
  216. zebra_redistribute_add (int command, struct zserv *client, int length)
  217. {
  218.   int type;
  219.   type = stream_getc (client->ibuf);
  220.   switch (type)
  221.     {
  222.     case ZEBRA_ROUTE_KERNEL:
  223.     case ZEBRA_ROUTE_CONNECT:
  224.     case ZEBRA_ROUTE_STATIC:
  225.     case ZEBRA_ROUTE_RIP:
  226.     case ZEBRA_ROUTE_RIPNG:
  227.     case ZEBRA_ROUTE_OSPF:
  228.     case ZEBRA_ROUTE_OSPF6:
  229.     case ZEBRA_ROUTE_BGP:
  230.       if (! client->redist[type])
  231. {
  232.   client->redist[type] = 1;
  233.   zebra_redistribute (client, type);
  234. }
  235.       break;
  236.     default:
  237.       break;
  238.     }
  239. }     
  240. void
  241. zebra_redistribute_delete (int command, struct zserv *client, int length)
  242. {
  243.   int type;
  244.   type = stream_getc (client->ibuf);
  245.   switch (type)
  246.     {
  247.     case ZEBRA_ROUTE_KERNEL:
  248.     case ZEBRA_ROUTE_CONNECT:
  249.     case ZEBRA_ROUTE_STATIC:
  250.     case ZEBRA_ROUTE_RIP:
  251.     case ZEBRA_ROUTE_RIPNG:
  252.     case ZEBRA_ROUTE_OSPF:
  253.     case ZEBRA_ROUTE_OSPF6:
  254.     case ZEBRA_ROUTE_BGP:
  255.       client->redist[type] = 0;
  256.       break;
  257.     default:
  258.       break;
  259.     }
  260. }     
  261. void
  262. zebra_redistribute_default_add (int command, struct zserv *client, int length)
  263. {
  264.   client->redist_default = 1;
  265.   zebra_redistribute_default (client);
  266. }     
  267. void
  268. zebra_redistribute_default_delete (int command, struct zserv *client,
  269.    int length)
  270. {
  271.   client->redist_default = 0;;
  272. }     
  273. /* Interface up information. */
  274. void
  275. zebra_interface_up_update (struct interface *ifp)
  276. {
  277.   listnode node;
  278.   struct zserv *client;
  279.   if (IS_ZEBRA_DEBUG_EVENT)
  280.     zlog_info ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
  281.   for (node = listhead (client_list); node; nextnode (node))
  282.     if ((client = getdata (node)) != NULL)
  283.       zsend_interface_up (client, ifp);
  284. }
  285. /* Interface down information. */
  286. void
  287. zebra_interface_down_update (struct interface *ifp)
  288. {
  289.   listnode node;
  290.   struct zserv *client;
  291.   if (IS_ZEBRA_DEBUG_EVENT)
  292.     zlog_info ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
  293.   for (node = listhead (client_list); node; nextnode (node))
  294.     if ((client = getdata (node)) != NULL)
  295.       zsend_interface_down (client, ifp);
  296. }
  297. /* Interface information update. */
  298. void
  299. zebra_interface_add_update (struct interface *ifp)
  300. {
  301.   listnode node;
  302.   struct zserv *client;
  303.   if (IS_ZEBRA_DEBUG_EVENT)
  304.     zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
  305.     
  306.   for (node = listhead (client_list); node; nextnode (node))
  307.     if ((client = getdata (node)) != NULL)
  308.       if (client->ifinfo)
  309. zsend_interface_add (client, ifp);
  310. }
  311. void
  312. zebra_interface_delete_update (struct interface *ifp)
  313. {
  314.   listnode node;
  315.   struct zserv *client;
  316.   if (IS_ZEBRA_DEBUG_EVENT)
  317.     zlog_info ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
  318.   for (node = listhead (client_list); node; nextnode (node))
  319.     if ((client = getdata (node)) != NULL)
  320.       if (client->ifinfo)
  321. zsend_interface_delete (client, ifp);
  322. }
  323. /* Interface address addition. */
  324. void
  325. zebra_interface_address_add_update (struct interface *ifp,
  326.     struct connected *ifc)
  327. {
  328.   listnode node;
  329.   struct zserv *client;
  330.   struct prefix *p;
  331.   char buf[BUFSIZ];
  332.   if (IS_ZEBRA_DEBUG_EVENT)
  333.     {
  334.       p = ifc->address;
  335.       zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
  336.  inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  337.  p->prefixlen, ifc->ifp->name);
  338.     }
  339.   for (node = listhead (client_list); node; nextnode (node))
  340.     if ((client = getdata (node)) != NULL)
  341.       if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  342. zsend_interface_address_add (client, ifp, ifc);
  343. }
  344. /* Interface address deletion. */
  345. void
  346. zebra_interface_address_delete_update (struct interface *ifp,
  347.        struct connected *ifc)
  348. {
  349.   listnode node;
  350.   struct zserv *client;
  351.   struct prefix *p;
  352.   char buf[BUFSIZ];
  353.   if (IS_ZEBRA_DEBUG_EVENT)
  354.     {
  355.       p = ifc->address;
  356.       zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
  357.  inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  358.  p->prefixlen, ifc->ifp->name);
  359.     }
  360.   for (node = listhead (client_list); node; nextnode (node))
  361.     if ((client = getdata (node)) != NULL)
  362.       if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  363. zsend_interface_address_delete (client, ifp, ifc);
  364. }