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

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Address linked list routine.
  3.  * Copyright (C) 1997, 98 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 "linklist.h"
  25. #include "if.h"
  26. #include "table.h"
  27. #include "rib.h"
  28. #include "table.h"
  29. #include "log.h"
  30. #include "zebra/zserv.h"
  31. #include "zebra/redistribute.h"
  32. /* If same interface address is already exist... */
  33. struct connected *
  34. connected_check_ipv4 (struct interface *ifp, struct prefix *p)
  35. {
  36.   struct connected *ifc;
  37.   listnode node;
  38.   for (node = listhead (ifp->connected); node; node = nextnode (node))
  39.     {
  40.       ifc = getdata (node);
  41.       if (prefix_same (ifc->address, p))
  42. return ifc;
  43.     }
  44.   return NULL;
  45. }
  46. /* Called from if_up(). */
  47. void
  48. connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
  49. {
  50.   struct prefix_ipv4 p;
  51.   struct prefix_ipv4 *addr;
  52.   struct prefix_ipv4 *dest;
  53.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  54.     return;
  55.   addr = (struct prefix_ipv4 *) ifc->address;
  56.   dest = (struct prefix_ipv4 *) ifc->destination;
  57.   memset (&p, 0, sizeof (struct prefix_ipv4));
  58.   p.family = AF_INET;
  59.   p.prefixlen = addr->prefixlen;
  60.   /* Point-to-point check. */
  61.   if (if_is_pointopoint (ifp))
  62.     p.prefix = dest->prefix;
  63.   else
  64.     p.prefix = addr->prefix;
  65.   /* Apply mask to the network. */
  66.   apply_mask_ipv4 (&p);
  67.   /* In case of connected address is 0.0.0.0/0 we treat it tunnel
  68.      address. */
  69.   if (prefix_ipv4_any (&p))
  70.     return;
  71.   rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0);
  72.   rib_update ();
  73. }
  74. /* Add connected IPv4 route to the interface. */
  75. void
  76. connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, 
  77.     int prefixlen, struct in_addr *broad, char *label)
  78. {
  79.   struct prefix_ipv4 *p;
  80.   struct connected *ifc;
  81.   struct connected *current;
  82.   /* Make connected structure. */
  83.   ifc = connected_new ();
  84.   ifc->ifp = ifp;
  85.   ifc->flags = flags;
  86.   /* Allocate new connected address. */
  87.   p = prefix_ipv4_new ();
  88.   p->family = AF_INET;
  89.   p->prefix = *addr;
  90.   p->prefixlen = prefixlen;
  91.   ifc->address = (struct prefix *) p;
  92.   /* If there is broadcast or pointopoint address. */
  93.   if (broad)
  94.     {
  95.       p = prefix_ipv4_new ();
  96.       p->family = AF_INET;
  97.       p->prefix = *broad;
  98.       ifc->destination = (struct prefix *) p;
  99.     }
  100.   /* Label of this address. */
  101.   if (label)
  102.     ifc->label = strdup (label);
  103.   /* Check same connected route. */
  104.   current = connected_check_ipv4 (ifp, (struct prefix *) ifc->address);
  105.   if (current)
  106.     {
  107.       connected_free (ifc);
  108.       ifc = current;
  109.     }
  110.   else
  111.     {
  112.       listnode_add (ifp->connected, ifc);
  113.     }
  114.   /* Update interface address information to protocol daemon. */
  115.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  116.     {
  117.       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  118.       zebra_interface_address_add_update (ifp, ifc);
  119.       if (if_is_up(ifp))
  120. connected_up_ipv4 (ifp, ifc);
  121.     }
  122. }
  123. void
  124. connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
  125. {
  126.   struct prefix_ipv4 p;
  127.   struct prefix_ipv4 *addr;
  128.   struct prefix_ipv4 *dest;
  129.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  130.     return;
  131.   addr = (struct prefix_ipv4 *)ifc->address;
  132.   dest = (struct prefix_ipv4 *)ifc->destination;
  133.   memset (&p, 0, sizeof (struct prefix_ipv4));
  134.   p.family = AF_INET;
  135.   p.prefixlen = addr->prefixlen;
  136.   if (if_is_pointopoint (ifp))
  137.     p.prefix = dest->prefix;
  138.   else
  139.     p.prefix = addr->prefix;
  140.   /* Apply mask to the network. */
  141.   apply_mask_ipv4 (&p);
  142.   /* In case of connected address is 0.0.0.0/0 we treat it tunnel
  143.      address. */
  144.   if (prefix_ipv4_any (&p))
  145.     return;
  146.   rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
  147.   rib_update ();
  148. }
  149. /* Delete connected IPv4 route to the interface. */
  150. void
  151. connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
  152.        int prefixlen, struct in_addr *broad, char *label)
  153. {
  154.   struct prefix_ipv4 p;
  155.   struct connected *ifc;
  156.   memset (&p, 0, sizeof (struct prefix_ipv4));
  157.   p.family = AF_INET;
  158.   p.prefix = *addr;
  159.   p.prefixlen = prefixlen;
  160.   ifc = connected_check_ipv4 (ifp, (struct prefix *) &p);
  161.   if (! ifc)
  162.     return;
  163.   /* Update interface address information to protocol daemon. */
  164.   if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  165.     {
  166.       zebra_interface_address_delete_update (ifp, ifc);
  167.       connected_down_ipv4 (ifp, ifc);
  168.       UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  169.     }
  170.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  171.     {
  172.       listnode_delete (ifp->connected, ifc);
  173.       connected_free (ifc);
  174.     }
  175. }
  176. #ifdef HAVE_IPV6
  177. /* If same interface address is already exist... */
  178. struct connected *
  179. connected_check_ipv6 (struct interface *ifp, struct prefix *p)
  180. {
  181.   struct connected *ifc;
  182.   listnode node;
  183.   for (node = listhead (ifp->connected); node; node = nextnode (node))
  184.     {
  185.       ifc = getdata (node);
  186.       if (prefix_same (ifc->address, p))
  187. return ifc;
  188.     }
  189.   return 0;
  190. }
  191. void
  192. connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
  193. {
  194.   struct prefix_ipv6 p;
  195.   struct prefix_ipv6 *addr;
  196.   struct prefix_ipv6 *dest;
  197.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  198.     return;
  199.   addr = (struct prefix_ipv6 *) ifc->address;
  200.   dest = (struct prefix_ipv6 *) ifc->destination;
  201.   memset (&p, 0, sizeof (struct prefix_ipv6));
  202.   p.family = AF_INET6;
  203.   p.prefixlen = addr->prefixlen;
  204.   if (if_is_pointopoint (ifp) && dest)
  205.     {
  206.       if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
  207. p.prefix = addr->prefix;
  208.       else
  209. p.prefix = dest->prefix;
  210.     }
  211.   else
  212.     p.prefix = addr->prefix;
  213.   /* Apply mask to the network. */
  214.   apply_mask_ipv6 (&p);
  215.   if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
  216.     return;
  217.   rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
  218.   rib_update ();
  219. }
  220. /* Add connected IPv6 route to the interface. */
  221. void
  222. connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr,
  223.     int prefixlen, struct in6_addr *broad)
  224. {
  225.   struct prefix_ipv6 *p;
  226.   struct connected *ifc;
  227.   struct connected *current;
  228.   /* Make connected structure. */
  229.   ifc = connected_new ();
  230.   ifc->ifp = ifp;
  231.   /* Allocate new connected address. */
  232.   p = prefix_ipv6_new ();
  233.   p->family = AF_INET6;
  234.   IPV6_ADDR_COPY (&p->prefix, addr);
  235.   p->prefixlen = prefixlen;
  236.   ifc->address = (struct prefix *) p;
  237.   /* If there is broadcast or pointopoint address. */
  238.   if (broad)
  239.     {
  240.       p = prefix_ipv6_new ();
  241.       p->family = AF_INET6;
  242.       IPV6_ADDR_COPY (&p->prefix, broad);
  243.       ifc->destination = (struct prefix *) p;
  244.     }
  245.   current = connected_check_ipv6 (ifp, (struct prefix *) ifc->address);
  246.   if (current)
  247.     {
  248.       connected_free (ifc);
  249.       ifc = current;
  250.     }
  251.   else
  252.     {
  253.       listnode_add (ifp->connected, ifc);
  254.     }
  255.   /* Update interface address information to protocol daemon. */
  256.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  257.     {
  258.       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  259.       zebra_interface_address_add_update (ifp, ifc);
  260.       if (if_is_up(ifp))
  261. connected_up_ipv6 (ifp, ifc);
  262.     }
  263. }
  264. void
  265. connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
  266. {
  267.   struct prefix_ipv6 p;
  268.   struct prefix_ipv6 *addr;
  269.   struct prefix_ipv6 *dest;
  270.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  271.     return;
  272.   addr = (struct prefix_ipv6 *) ifc->address;
  273.   dest = (struct prefix_ipv6 *) ifc->destination;
  274.   memset (&p, 0, sizeof (struct prefix_ipv6));
  275.   p.family = AF_INET6;
  276.   p.prefixlen = addr->prefixlen;
  277.   if (if_is_pointopoint (ifp) && dest)
  278.     {
  279.       if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
  280. p.prefix = addr->prefix;
  281.       else
  282. p.prefix = dest->prefix;
  283.     }
  284.   else
  285.     p.prefix = addr->prefix;
  286.   apply_mask_ipv6 (&p);
  287.   if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
  288.     return;
  289.   rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
  290.   rib_update ();
  291. }
  292. void
  293. connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
  294.                     int prefixlen, struct in6_addr *broad)
  295. {
  296.   struct prefix_ipv6 p;
  297.   struct connected *ifc;
  298.   
  299.   memset (&p, 0, sizeof (struct prefix_ipv6));
  300.   p.family = AF_INET6;
  301.   memcpy (&p.prefix, address, sizeof (struct in6_addr));
  302.   p.prefixlen = prefixlen;
  303.   ifc = connected_check_ipv6 (ifp, (struct prefix *) &p);
  304.   if (! ifc)
  305.     return;
  306.   /* Update interface address information to protocol daemon. */
  307.   if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  308.     {
  309.       zebra_interface_address_delete_update (ifp, ifc);
  310.       connected_down_ipv6 (ifp, ifc);
  311.       UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  312.     }
  313.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  314.     {
  315.       listnode_delete (ifp->connected, ifc);
  316.       connected_free (ifc);
  317.     }
  318. }
  319. #endif /* HAVE_IPV6 */