summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Šimerda <psimerda@redhat.com>2013-07-30 00:03:48 +0200
committerPavel Šimerda <psimerda@redhat.com>2013-07-30 11:40:19 +0200
commit68c3e1153c415111e9254c1086c82360c069bc92 (patch)
treed63dabe661ff484c7d9ad38a3de87133a7c6227c
parent3cf1b71de214e265f88cd7902d44d389a7f5c095 (diff)
downloadNetworkManager-68c3e1153c415111e9254c1086c82360c069bc92.tar.gz
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
-rw-r--r--src/platform/nm-fake-platform.c34
-rw-r--r--src/platform/nm-linux-platform.c2
-rw-r--r--src/platform/nm-platform.c68
-rw-r--r--src/platform/tests/test-address.c26
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);
}