2008-03-11 Dan Williams <dcbw@redhat.com>
authorDan Williams <dcbw@redhat.com>
Tue, 11 Mar 2008 22:21:25 +0000 (22:21 +0000)
committerDan Williams <dcbw@redhat.com>
Tue, 11 Mar 2008 22:21:25 +0000 (22:21 +0000)
Fix address handling as a result of DHCP rebind/renew/reboot.

* src/NetworkManagerSystem.c
- (check_one_address): delete an address if it doesn't match a given
one for the same interface
- (nm_system_device_set_from_ip4_config): don't flush the default route,
be smarter about flushing addresses (only flush ones that don't
match the one we're about to apply)

* src/backends/NetworkManagerDebian.c
  src/backends/NetworkManagerSuSE.c
  src/backends/NetworkManagerArch.c
  src/backends/NetworkManagerSlackware.c
  src/backends/NetworkManagerRedHat.c
  src/backends/NetworkManagerPaldo.c
  src/backends/NetworkManagerFrugalware.c
  src/backends/NetworkManagerGentoo.c
- (nm_system_delete_default_route): remove

* src/backends/NetworkManagerGeneric.c
  src/backends/NetworkManagerGeneric.h
- (nm_generic_enable_loopback): fix the loopback device label
- (nm_generic_delete_default_route): remove; no longer used

git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3424 4912f4e0-d625-0410-9fb7-b9a5a253dbdc

13 files changed:
ChangeLog
src/NetworkManagerSystem.c
src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGeneric.c
src/backends/NetworkManagerGeneric.h
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c

index bc66bf4..427ccad 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 2008-03-11  Dan Williams  <dcbw@redhat.com>
 
+       Fix address handling as a result of DHCP rebind/renew/reboot.
+
+       * src/NetworkManagerSystem.c
+               - (check_one_address): delete an address if it doesn't match a given
+                       one for the same interface
+               - (nm_system_device_set_from_ip4_config): don't flush the default route,
+                       be smarter about flushing addresses (only flush ones that don't
+                       match the one we're about to apply)
+
+       * src/backends/NetworkManagerDebian.c
+         src/backends/NetworkManagerSuSE.c
+         src/backends/NetworkManagerArch.c
+         src/backends/NetworkManagerSlackware.c
+         src/backends/NetworkManagerRedHat.c
+         src/backends/NetworkManagerPaldo.c
+         src/backends/NetworkManagerFrugalware.c
+         src/backends/NetworkManagerGentoo.c
+               - (nm_system_delete_default_route): remove
+
+       * src/backends/NetworkManagerGeneric.c
+         src/backends/NetworkManagerGeneric.h
+               - (nm_generic_enable_loopback): fix the loopback device label
+               - (nm_generic_delete_default_route): remove; no longer used
+
+2008-03-11  Dan Williams  <dcbw@redhat.com>
+
        * src/nm-device-interface.h
                - Delimit property name words with '-', otherwise g_object_notify()
                        doesn't work the way we expect
index 603cd73..e6d156f 100644 (file)
@@ -179,6 +179,36 @@ out:
 }
 
 
+typedef struct {
+       const char *iface;
+       struct nl_handle *nlh;
+       struct rtnl_addr *match;
+} AddrCheckData;
+
+static void
+check_one_address (struct nl_object *object, void *user_data)
+{
+       AddrCheckData *data = (AddrCheckData *) user_data;
+       struct rtnl_addr *addr = (struct rtnl_addr *) object;
+       int err;
+
+       /* Delete addresses on this interface which don't match the one we
+        * are about to add to it.
+        */
+       if (nl_object_identical ((struct nl_object *) data->match, (struct nl_object *) addr))
+               return;
+       if (rtnl_addr_get_ifindex (addr) != rtnl_addr_get_ifindex (data->match))
+               return;
+       if (rtnl_addr_get_family (addr) != rtnl_addr_get_family (data->match))
+               return;
+
+       err = rtnl_addr_delete (data->nlh, addr, 0);
+       if (err < 0) {
+               nm_warning ("(%s) error %d returned from rtnl_addr_delete(): %s",
+                           data->iface, err, nl_geterror());
+       }
+}
+
 /*
  * nm_system_device_set_from_ip4_config
  *
@@ -192,8 +222,11 @@ nm_system_device_set_from_ip4_config (const char *iface,
 {
        struct nl_handle *nlh = NULL;
        struct rtnl_addr *addr = NULL;
+       struct nl_cache *addr_cache = NULL;
        int len, i, err;
        guint32 flags;
+       AddrCheckData check_data;
+       gboolean success = FALSE;
 
        g_return_val_if_fail (iface != NULL, FALSE);
        g_return_val_if_fail (config != NULL, FALSE);
@@ -202,23 +235,32 @@ nm_system_device_set_from_ip4_config (const char *iface,
        if (!nlh)
                return FALSE;
 
-       nm_system_delete_default_route ();
-       nm_system_device_flush_addresses_with_iface (iface);
-       nm_system_device_flush_routes_with_iface (iface);
-       nm_system_flush_arp_cache ();
+       addr_cache = rtnl_addr_alloc_cache (nlh);
+       if (!addr_cache)
+               goto out;
+       nl_cache_mngt_provide (addr_cache);
 
        flags = NM_RTNL_ADDR_DEFAULT;
        if (nm_ip4_config_get_ptp_address (config))
                flags |= NM_RTNL_ADDR_PTP_ADDR;
 
-       if ((addr = nm_ip4_config_to_rtnl_addr (config, flags))) {
-               rtnl_addr_set_ifindex (addr, nm_netlink_iface_to_index (iface));
-
-               if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
-                       nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", iface, err, nl_geterror());
-               rtnl_addr_put (addr);
-       } else
+       addr = nm_ip4_config_to_rtnl_addr (config, flags);
+       if (!addr) {
                nm_warning ("couldn't create rtnl address!\n");
+               goto out;
+       }
+       rtnl_addr_set_ifindex (addr, nm_netlink_iface_to_index (iface));
+
+       memset (&check_data, 0, sizeof (check_data));
+       check_data.iface = iface;
+       check_data.nlh = nlh;
+       check_data.match = addr;
+
+       /* Remove all addresses except the one we're about to add */
+       nl_cache_foreach (addr_cache, check_one_address, &check_data);
+
+       if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
+               nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", iface, err, nl_geterror());
 
        sleep (1);
 
@@ -234,7 +276,14 @@ nm_system_device_set_from_ip4_config (const char *iface,
        if (nm_ip4_config_get_mtu (config))
                nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
 
-       return TRUE;
+       success = TRUE;
+
+out:
+       if (addr)
+               rtnl_addr_put (addr);
+       if (addr_cache)
+               nl_cache_free (addr_cache);
+       return success;
 }
 
 
index aa21795..54ebf28 100644 (file)
@@ -49,7 +49,6 @@ void                  nm_system_device_flush_addresses_with_iface     (const char *iface);
 
 void                   nm_system_enable_loopback                               (void);
 void                   nm_system_flush_loopback_routes                 (void);
-void                   nm_system_delete_default_route                  (void);
 void                   nm_system_flush_arp_cache                               (void);
 void                   nm_system_kill_all_dhcp_daemons                 (void);
 void                   nm_system_update_dns                                    (void);
index e8550f5..9202780 100644 (file)
@@ -272,18 +272,6 @@ void nm_system_flush_loopback_routes (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-
-/*
  * nm_system_flush_arp_cache
  *
  * Flush all entries in the arp cache.
index a9acbe8..8eb3355 100644 (file)
@@ -150,18 +150,6 @@ void nm_system_flush_loopback_routes (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-
-/*
  * nm_system_flush_arp_cache
  *
  * Flush all entries in the arp cache.
index 78d2456..9342eac 100644 (file)
@@ -142,18 +142,6 @@ void nm_system_enable_loopback (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_spawn_process ("/usr/sbin/ip route del default");
-}
-
-
-/*
  * nm_system_kill_all_dhcp_daemons
  *
  * Kill all DHCP daemons currently running, done at startup.
index 50dd60f..9d0d7fc 100644 (file)
@@ -173,7 +173,7 @@ void nm_generic_device_flush_addresses_with_iface (const char *iface)
 void nm_generic_enable_loopback (void)
 {
        nm_spawn_process (IP_BINARY_PATH" link set dev lo up");
-       nm_spawn_process (IP_BINARY_PATH" addr add 127.0.0.1/8 brd 127.255.255.255 dev lo scope host label loopback");
+       nm_spawn_process (IP_BINARY_PATH" addr add 127.0.0.1/8 brd 127.255.255.255 dev lo scope host label lo");
 }
 
 
@@ -191,18 +191,6 @@ void nm_generic_flush_loopback_routes (void)
 
 
 /*
- * nm_generic_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_generic_delete_default_route (void)
-{
-       nm_spawn_process (IP_BINARY_PATH" route del default");
-}
-
-
-/*
  * nm_generic_flush_arp_cache
  *
  * Flush all entries in the arp cache.
index f69b08c..14c89d0 100644 (file)
@@ -48,7 +48,6 @@ void                  nm_generic_device_flush_addresses_with_iface    (const char *iface);
 
 void                   nm_generic_enable_loopback                              (void);
 void                   nm_generic_flush_loopback_routes                        (void);
-void                   nm_generic_delete_default_route                 (void);
 void                   nm_generic_flush_arp_cache                              (void);
 void                   nm_generic_kill_all_dhcp_daemons                        (void);
 void                   nm_generic_update_dns                                   (void);
index 944bb8c..23124ad 100644 (file)
@@ -161,17 +161,6 @@ void nm_system_flush_loopback_routes (void)
 }
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-/*
  * nm_system_flush_arp_cache
  *
  * Flush all entries in the arp cache.
index 9e457df..f250788 100644 (file)
@@ -165,18 +165,6 @@ void nm_system_flush_loopback_routes (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-
-/*
  * nm_system_flush_arp_cache
  *
  * Flush all entries in the arp cache.
index 7e3ce24..ab4ce22 100644 (file)
@@ -175,18 +175,6 @@ void nm_system_flush_loopback_routes (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-
-/*
  * nm_system_flush_arp_cache
  *
  * Flush all entries in the arp cache.
index 599534d..18229ae 100644 (file)
@@ -149,18 +149,6 @@ void nm_system_enable_loopback (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-
-/*
  * nm_system_kill_all_dhcp_daemons
  *
  * Kill all DHCP daemons currently running, done at startup.
index eeefb66..5fb0fd7 100644 (file)
@@ -169,18 +169,6 @@ void nm_system_flush_loopback_routes (void)
 
 
 /*
- * nm_system_delete_default_route
- *
- * Remove the old default route in preparation for a new one
- *
- */
-void nm_system_delete_default_route (void)
-{
-       nm_generic_delete_default_route ();
-}
-
-
-/*
  * nm_system_flush_arp_cache
  *
  * Flush all entries in the arp cache.