]> git.puffer.fish Git - mirror/frr.git/commitdiff
2005-09-12 Paul Jakma <paul.jakma@sun.com>
authorpaul <paul>
Mon, 12 Sep 2005 16:58:52 +0000 (16:58 +0000)
committerpaul <paul>
Mon, 12 Sep 2005 16:58:52 +0000 (16:58 +0000)
* (general) RTM_CHANGE and implicit withdraw on RTM_NEWADDR
  support.
* connected.c: (connected_withdraw) new function. withdraw a
  connected subnet address set from zebra, and pass information
  along to clients.
  (connected_announce) similar, but to announce a new connected
  subnet address set.
  (connected_check_ipv4) renamed to connected_check, as its
  AFI independent.
  (connected_add_ipv{4,6}) Remove the connected address announce
  stuff, use connected_announce instead.
  If connected_check indicates address is already present,
  treat it as an implicit withdraw of the existing address, ie
  remove the old address details and replace with the new
  details.
  (connected_delete_ipv{4,6}) Use connected_withdraw.
  (connected_check_ipv6) deleted in favour of connected_check.
* connected.h: Rename connected_check_ipv4 to connected_check.
  delete connected_check_ipv6.
* interface.c: Use connected_check rather than the AFI specific
  symbols.
* kernel_socket.c: (rtm_read) RTM_CHANGE support. Create a
  rib delete event for the existing route, before adding route
  again.
  (kernel_read) we can handle RTM_CHANGE now.

zebra/ChangeLog
zebra/connected.c
zebra/connected.h
zebra/interface.c
zebra/kernel_socket.c

index 61b8b41ab393ed81d494ea823bbd2fc9bde399be..6225ce1a87357670db4e2c55415310384e2f6208 100644 (file)
@@ -1,3 +1,31 @@
+2005-09-12 Paul Jakma <paul.jakma@sun.com>
+
+       * (general) RTM_CHANGE and implicit withdraw on RTM_NEWADDR
+         support.
+       * connected.c: (connected_withdraw) new function. withdraw a
+         connected subnet address set from zebra, and pass information
+         along to clients.
+         (connected_announce) similar, but to announce a new connected
+         subnet address set.
+         (connected_check_ipv4) renamed to connected_check, as its
+         AFI independent.
+         (connected_add_ipv{4,6}) Remove the connected address announce
+         stuff, use connected_announce instead.
+         If connected_check indicates address is already present,
+         treat it as an implicit withdraw of the existing address, ie
+         remove the old address details and replace with the new
+         details.
+         (connected_delete_ipv{4,6}) Use connected_withdraw.
+         (connected_check_ipv6) deleted in favour of connected_check.
+       * connected.h: Rename connected_check_ipv4 to connected_check.
+         delete connected_check_ipv6.
+       * interface.c: Use connected_check rather than the AFI specific
+         symbols.
+       * kernel_socket.c: (rtm_read) RTM_CHANGE support. Create a 
+         rib delete event for the existing route, before adding route
+         again.
+         (kernel_read) we can handle RTM_CHANGE now.
+
 2005-08-27 Hasso Tepper <hasso at quagga.net>
 
        * zebra_rib.c, rib.h: Add distance and metric arguments to the
index 6826908884935a430c49317f6fcfbfbec9a21011..7599d24dd61ba011fc280a99f57fb6f949a1204d 100644 (file)
 #include "zebra/interface.h"
 #include "zebra/connected.h"
 \f
+/* withdraw a connected address */
+static void
+connected_withdraw (struct connected *ifc)
+{
+  if (! ifc)
+    return;
+
+  /* Update interface address information to protocol daemon. */
+  if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
+    {
+      zebra_interface_address_delete_update (ifc->ifp, ifc);
+
+      if_subnet_delete (ifc->ifp, ifc);
+      
+      if (ifc->address->family == AF_INET)
+        connected_down_ipv4 (ifc->ifp, ifc);
+      else
+        connected_down_ipv6 (ifc->ifp, ifc);
+
+      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
+    }
+
+  listnode_delete (ifc->ifp->connected, ifc);
+  connected_free (ifc);
+}
+
+static void
+connected_announce (struct interface *ifp, struct connected *ifc)
+{
+  if (!ifc)
+    return;
+  
+  listnode_add (ifp->connected, ifc);
+
+  /* Update interface address information to protocol daemon. */
+  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
+    {
+      if (ifc->address->family == AF_INET)
+        if_subnet_add (ifp, ifc);
+
+      SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
+
+      zebra_interface_address_add_update (ifp, ifc);
+
+      if (if_is_up(ifp))
+        {
+          if (ifc->address->family == AF_INET)
+           connected_up_ipv4 (ifp, ifc);
+          else
+            connected_up_ipv6 (ifp, ifc);
+        }
+    }
+}
+\f
 /* If same interface address is already exist... */
 struct connected *
-connected_check_ipv4 (struct interface *ifp, struct prefix *p)
+connected_check (struct interface *ifp, struct prefix *p)
 {
   struct connected *ifc;
   struct listnode *node;
@@ -106,7 +160,7 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
   p->prefix = *addr;
   p->prefixlen = prefixlen;
   ifc->address = (struct prefix *) p;
-
+  
   /* If there is broadcast or pointopoint address. */
   if (broad)
     {
@@ -163,29 +217,10 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
     ifc->label = strdup (label);
 
   /* Check same connected route. */
-  current = connected_check_ipv4 (ifp, (struct prefix *) ifc->address);
-  if (current)
-    {
-      connected_free (ifc);
-      ifc = current;
-    }
-  else
-    {
-      listnode_add (ifp->connected, ifc);
-    }
-
-  /* Update interface address information to protocol daemon. */
-  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
-    {
-      if_subnet_add (ifp, ifc);
-
-      SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
-
-      zebra_interface_address_add_update (ifp, ifc);
-
-      if (if_is_up(ifp))
-       connected_up_ipv4 (ifp, ifc);
-    }
+  if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
+    connected_withdraw (current); /* implicit withdraw - freebsd does this */
+  
+  connected_announce (ifp, ifc);
 }
 
 void
@@ -237,41 +272,14 @@ connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
   p.prefix = *addr;
   p.prefixlen = prefixlen;
 
-  ifc = connected_check_ipv4 (ifp, (struct prefix *) &p);
+  ifc = connected_check (ifp, (struct prefix *) &p);
   if (! ifc)
     return;
-
-  /* Update interface address information to protocol daemon. */
-  if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
-    {
-      zebra_interface_address_delete_update (ifp, ifc);
-
-      if_subnet_delete (ifp, ifc);
-
-      connected_down_ipv4 (ifp, ifc);
-
-      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
-    }
-
-  listnode_delete (ifp->connected, ifc);
-  connected_free (ifc);
+    
+  connected_withdraw (ifc);
 }
 
 #ifdef HAVE_IPV6
-/* If same interface address is already exist... */
-struct connected *
-connected_check_ipv6 (struct interface *ifp, struct prefix *p)
-{
-  struct connected *ifc;
-  struct listnode *node;
-
-  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
-    if (prefix_same (ifc->address, p))
-      return ifc;
-
-  return 0;
-}
-
 void
 connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
 {
@@ -342,27 +350,10 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr,
       ifc->destination = (struct prefix *) p;
     }
 
-  current = connected_check_ipv6 (ifp, (struct prefix *) ifc->address);
-  if (current)
-    {
-      connected_free (ifc);
-      ifc = current;
-    }
-  else
-    {
-      listnode_add (ifp->connected, ifc);
-    }
-
-  /* Update interface address information to protocol daemon. */
-  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
-    {
-      SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
-
-      zebra_interface_address_add_update (ifp, ifc);
-
-      if (if_is_up(ifp))
-       connected_up_ipv6 (ifp, ifc);
-    }
+  if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
+    connected_withdraw (current); /* implicit update of existing address */
+  
+  connected_announce (ifp, ifc);
 }
 
 void
@@ -414,21 +405,10 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
   memcpy (&p.prefix, address, sizeof (struct in6_addr));
   p.prefixlen = prefixlen;
 
-  ifc = connected_check_ipv6 (ifp, (struct prefix *) &p);
+  ifc = connected_check (ifp, (struct prefix *) &p);
   if (! ifc)
     return;
 
-  /* Update interface address information to protocol daemon. */
-  if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
-    {
-      zebra_interface_address_delete_update (ifp, ifc);
-
-      connected_down_ipv6 (ifp, ifc);
-
-      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
-    }
-
-  listnode_delete (ifp->connected, ifc);
-  connected_free (ifc);
+  connected_withdraw (ifc);
 }
 #endif /* HAVE_IPV6 */
index 726092aec47adfb1316174eb222f91e6fb270b27..73166eb5a1b273913100596a34302e2e2f9a5bcf 100644 (file)
@@ -24,7 +24,7 @@
 #define _ZEBRA_CONNECTED_H
 
 extern struct connected *
-connected_check_ipv4 (struct interface *ifp, struct prefix *p);
+connected_check (struct interface *ifp, struct prefix *p);
 
 extern void
 connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, 
@@ -38,9 +38,6 @@ extern void connected_up_ipv4 (struct interface *, struct connected *);
 extern void connected_down_ipv4 (struct interface *, struct connected *);
 
 #ifdef HAVE_IPV6
-extern struct connected *
-connected_check_ipv6 (struct interface *ifp, struct prefix *p);
-
 extern void
 connected_add_ipv6 (struct interface *ifp, struct in6_addr *address,
                    u_char prefixlen, struct in6_addr *broad);
index 92e43d97e0cd07cff8d2d895f540637244adab0a..49fffcf5de8dade19ec021a17d6172d8ebb27be2 100644 (file)
@@ -1150,7 +1150,7 @@ ip_address_install (struct vty *vty, struct interface *ifp,
       return CMD_WARNING;
     }
 
-  ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
+  ifc = connected_check (ifp, (struct prefix *) &cp);
   if (! ifc)
     {
       ifc = connected_new ();
@@ -1236,7 +1236,7 @@ ip_address_uninstall (struct vty *vty, struct interface *ifp,
     }
 
   /* Check current interface address. */
-  ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
+  ifc = connected_check (ifp, (struct prefix *) &cp);
   if (! ifc)
     {
       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
@@ -1346,7 +1346,7 @@ ipv6_address_install (struct vty *vty, struct interface *ifp,
       return CMD_WARNING;
     }
 
-  ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
+  ifc = connected_check (ifp, (struct prefix *) &cp);
   if (! ifc)
     {
       ifc = connected_new ();
@@ -1425,7 +1425,7 @@ ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
     }
 
   /* Check current interface address. */
-  ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
+  ifc = connected_check (ifp, (struct prefix *) &cp);
   if (! ifc)
     {
       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
index fe7411eed1e3269fda3c5fe7cca954ffccb1be77..f391d53a05a34dbd1df5c7f86649f2e94143eed3 100644 (file)
@@ -623,8 +623,17 @@ rtm_read (struct rt_msghdr *rtm)
        p.prefixlen = IPV4_MAX_PREFIXLEN;
       else
        p.prefixlen = ip_masklen (mask.sin.sin_addr);
-
-      if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)
+      
+      /* Change, delete the old prefix, we have no further information
+       * to specify the route really
+       */
+      if (rtm->rtm_type == RTM_CHANGE)
+        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
+                         NULL, 0, 0);
+      
+      if (rtm->rtm_type == RTM_GET 
+          || rtm->rtm_type == RTM_ADD
+          || rtm->rtm_type == RTM_CHANGE)
        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
                      &p, &gate.sin.sin_addr, 0, 0, 0, 0);
       else
@@ -652,7 +661,16 @@ rtm_read (struct rt_msghdr *rtm)
        }
 #endif /* KAME */
 
-      if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)
+      /* CHANGE: delete the old prefix, we have no further information
+       * to specify the route really
+       */
+      if (rtm->rtm_type == RTM_CHANGE)
+        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
+                         NULL, 0, 0);
+      
+      if (rtm->rtm_type == RTM_GET 
+          || rtm->rtm_type == RTM_ADD
+          || rtm->rtm_type == RTM_CHANGE)
        rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
                      &p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0);
       else
@@ -920,6 +938,7 @@ kernel_read (struct thread *thread)
     {
     case RTM_ADD:
     case RTM_DELETE:
+    case RTM_CHANGE:
       rtm_read (rtm);
       break;
     case RTM_IFINFO: