From 68c3e1153c415111e9254c1086c82360c069bc92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20=C5=A0imerda?= Date: Tue, 30 Jul 2013 00:03:48 +0200 Subject: platform: update all address lifetimes The nm_platform_ip[46]_address_sync() functions no longer use nm_platform_ip[46]_address_exists() to avoid adding already existing addresses. That means nm_platform_ip[46]_address_add() is now called for *all* commited addresses and the lifetimes are thus always updated. Because of that, nm_platform_ip[46]_address_add() had to be modified to accept existing addresses and update their lifetimes when appropriate. https://bugzilla.gnome.org/show_bug.cgi?id=705102 --- src/platform/nm-fake-platform.c | 34 ++++++++++++++++++-- src/platform/nm-linux-platform.c | 2 +- src/platform/nm-platform.c | 68 ++++++++++++++------------------------- src/platform/tests/test-address.c | 26 +++++++++------ 4 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 0b10a27df9..8604f64aea 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -734,6 +734,7 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, gu { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP4Address address; + int i; memset (&address, 0, sizeof (address)); address.ifindex = ifindex; @@ -743,8 +744,22 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, gu address.lifetime = lifetime; address.preferred = preferred; - g_array_append_val (priv->ip4_addresses, address); + for (i = 0; i < priv->ip4_addresses->len; i++) { + NMPlatformIP4Address *item = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i); + + if (item->ifindex != address.ifindex) + continue; + if (item->address != address.address) + continue; + if (item->plen != address.plen) + continue; + memcpy (item, &address, sizeof (address)); + g_signal_emit_by_name (platform, NM_PLATFORM_IP4_ADDRESS_CHANGED, ifindex, &address); + return TRUE; + } + + g_array_append_val (priv->ip4_addresses, address); g_signal_emit_by_name (platform, NM_PLATFORM_IP4_ADDRESS_ADDED, ifindex, &address); return TRUE; @@ -755,6 +770,7 @@ ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int pl { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP6Address address; + int i; memset (&address, 0, sizeof (address)); address.ifindex = ifindex; @@ -764,8 +780,22 @@ ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int pl address.lifetime = lifetime; address.preferred = preferred; - g_array_append_val (priv->ip6_addresses, address); + for (i = 0; i < priv->ip6_addresses->len; i++) { + NMPlatformIP6Address *item = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i); + + if (item->ifindex != address.ifindex) + continue; + if (!IN6_ARE_ADDR_EQUAL (&item->address, &address.address)) + continue; + if (item->plen != address.plen) + continue; + memcpy (item, &address, sizeof (address)); + g_signal_emit_by_name (platform, NM_PLATFORM_IP6_ADDRESS_CHANGED, ifindex, &address); + return TRUE; + } + + g_array_append_val (priv->ip6_addresses, address); g_signal_emit_by_name (platform, NM_PLATFORM_IP6_ADDRESS_ADDED, ifindex, &address); return TRUE; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 385c789955..01bd8cbb65 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -241,7 +241,7 @@ add_kernel_object (struct nl_sock *sock, struct nl_object *object) return rtnl_link_add (sock, (struct rtnl_link *) object, NLM_F_CREATE); case IP4_ADDRESS: case IP6_ADDRESS: - return rtnl_addr_add (sock, (struct rtnl_addr *) object, NLM_F_CREATE); + return rtnl_addr_add (sock, (struct rtnl_addr *) object, NLM_F_CREATE | NLM_F_REPLACE); case IP4_ROUTE: case IP6_ROUTE: return rtnl_route_add (sock, (struct rtnl_route *) object, NLM_F_CREATE); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 9065f290e8..87fbac0593 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1074,13 +1074,7 @@ nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, guint32 l g_return_val_if_fail (preferred >= 0, FALSE); g_return_val_if_fail (klass->ip4_address_add, FALSE); - if (nm_platform_ip4_address_exists (ifindex, address, plen)) { - debug ("address already exists"); - platform->error = NM_PLATFORM_ERROR_EXISTS; - return FALSE; - } - - debug ("address: adding IPv4 address"); + debug ("address: adding or updating IPv4 address"); return klass->ip4_address_add (platform, ifindex, address, plen, lifetime, preferred); } @@ -1095,13 +1089,7 @@ nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, gui g_return_val_if_fail (preferred >= 0, FALSE); g_return_val_if_fail (klass->ip6_address_add, FALSE); - if (nm_platform_ip6_address_exists (ifindex, address, plen)) { - debug ("address already exists"); - platform->error = NM_PLATFORM_ERROR_EXISTS; - return FALSE; - } - - debug ("address: adding IPv6 address"); + debug ("address: adding or updating IPv6 address"); return klass->ip6_address_add (platform, ifindex, address, plen, lifetime, preferred); } @@ -1233,7 +1221,6 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) { GArray *addresses; NMPlatformIP4Address *address; - const NMPlatformIP4Address *known_address; guint32 now = get_time (); int i; @@ -1252,23 +1239,20 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) /* Add missing addresses */ for (i = 0; i < known_addresses->len; i++) { - known_address = &g_array_index (known_addresses, NMPlatformIP4Address, i); - - if (!nm_platform_ip4_address_exists (ifindex, known_address->address, known_address->plen)) { - guint32 lifetime, preferred; + const NMPlatformIP4Address *known_address = &g_array_index (known_addresses, NMPlatformIP4Address, i); + guint32 lifetime, preferred; - if (known_address->lifetime) { - guint32 shift = addsubstract_guint32 (now, 0, known_address->timestamp); + if (known_address->lifetime) { + guint32 shift = addsubstract_guint32 (now, 0, known_address->timestamp); - /* Pad the lifetime by 5 seconds to avoid potential races. */ - lifetime = addsubstract_guint32 (known_address->lifetime, 5, shift); - preferred = addsubstract_guint32 (known_address->lifetime, 5, shift); - } else - lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + /* Pad the lifetime by 5 seconds to avoid potential races. */ + lifetime = addsubstract_guint32 (known_address->lifetime, 5, shift); + preferred = addsubstract_guint32 (known_address->lifetime, 5, shift); + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; - if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) - return FALSE; - } + if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) + return FALSE; } return TRUE; @@ -1290,7 +1274,6 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) { GArray *addresses; NMPlatformIP6Address *address; - const NMPlatformIP6Address *known_address; guint32 now = get_time (); int i; @@ -1313,23 +1296,20 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) /* Add missing addresses */ for (i = 0; i < known_addresses->len; i++) { - known_address = &g_array_index (known_addresses, NMPlatformIP6Address, i); - - if (!nm_platform_ip6_address_exists (ifindex, known_address->address, known_address->plen)) { - guint32 lifetime, preferred; + const NMPlatformIP6Address *known_address = &g_array_index (known_addresses, NMPlatformIP6Address, i); + guint32 lifetime, preferred; - if (known_address->lifetime) { - guint32 shift = addsubstract_guint32 (now, 0, known_address->timestamp); + if (known_address->lifetime) { + guint32 shift = addsubstract_guint32 (now, 0, known_address->timestamp); - /* Pad the lifetime by 5 seconds to avoid potential races. */ - lifetime = addsubstract_guint32 (known_address->lifetime, 5, shift); - preferred = addsubstract_guint32 (known_address->lifetime, 5, shift); - } else - lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + /* Pad the lifetime by 5 seconds to avoid potential races. */ + lifetime = addsubstract_guint32 (known_address->lifetime, 5, shift); + preferred = addsubstract_guint32 (known_address->lifetime, 5, shift); + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; - if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) - return FALSE; - } + if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) + return FALSE; } return TRUE; diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 99be977bd5..a8662daf9a 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -45,9 +45,10 @@ ip6_address_callback (NMPlatform *platform, int ifindex, NMPlatformIP6Address *r static void test_ip4_address (void) { - SignalData *address_added = add_signal (NM_PLATFORM_IP4_ADDRESS_ADDED, ip4_address_callback); - SignalData *address_removed = add_signal (NM_PLATFORM_IP4_ADDRESS_REMOVED, ip4_address_callback); int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); + SignalData *address_added = add_signal_ifindex (NM_PLATFORM_IP4_ADDRESS_ADDED, ip4_address_callback, ifindex); + SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_IP4_ADDRESS_CHANGED, ip4_address_callback, ifindex); + SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_IP4_ADDRESS_REMOVED, ip4_address_callback, ifindex); GArray *addresses; NMPlatformIP4Address *address; in_addr_t addr; @@ -65,9 +66,10 @@ test_ip4_address (void) no_error (); accept_signal (address_added); - /* Add address again */ - g_assert (!nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); - error (NM_PLATFORM_ERROR_EXISTS); + /* Add address again (aka update) */ + g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); + no_error (); + accept_signal (address_changed); /* Test address listing */ addresses = nm_platform_ip4_address_get_all (ifindex); @@ -91,15 +93,17 @@ test_ip4_address (void) error (NM_PLATFORM_ERROR_NOT_FOUND); free_signal (address_added); + free_signal (address_changed); free_signal (address_removed); } static void test_ip6_address (void) { - SignalData *address_added = add_signal (NM_PLATFORM_IP6_ADDRESS_ADDED, ip6_address_callback); - SignalData *address_removed = add_signal (NM_PLATFORM_IP6_ADDRESS_REMOVED, ip6_address_callback); int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); + SignalData *address_added = add_signal_ifindex (NM_PLATFORM_IP6_ADDRESS_ADDED, ip6_address_callback, ifindex); + SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_IP6_ADDRESS_CHANGED, ip6_address_callback, ifindex); + SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_IP6_ADDRESS_REMOVED, ip6_address_callback, ifindex); GArray *addresses; NMPlatformIP6Address *address; struct in6_addr addr; @@ -117,9 +121,10 @@ test_ip6_address (void) no_error (); accept_signal (address_added); - /* Add address again */ - g_assert (!nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); - error (NM_PLATFORM_ERROR_EXISTS); + /* Add address again (aka update) */ + g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); + no_error (); + accept_signal (address_changed); /* Test address listing */ addresses = nm_platform_ip6_address_get_all (ifindex); @@ -143,6 +148,7 @@ test_ip6_address (void) error (NM_PLATFORM_ERROR_NOT_FOUND); free_signal (address_added); + free_signal (address_changed); free_signal (address_removed); } -- cgit v1.2.1