From bb99a0e43304336a9eb8f12a3fb0f745201b6f8f Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 7 Sep 2017 09:23:42 +0200 Subject: [PATCH] platform: refetch IPv6 address if still present after deletion After commit 5a69b27a64a0 ("platform: let platform operations only consider kernel response") the platform only relies on kernel messages and doesn't check if a deleted object is gone from the cache. For IPv6 addresses it can happen that the RTM_DELADDR comes after the ack, and this causes random failures in test /address/ipv6/general-2: [10.8009] platform: address: deleting IPv6 address 2001:db8:a:b:1:2:3:4/64, ifindex 12 dev nm-test-device [10.8009] platform-linux: delayed-action: schedule wait-for-nl-response (seq 55, timeout in 0.199999680, response-type 0) [10.8009] platform-linux: delayed-action: handle wait-for-nl-response (any) [10.8009] platform-linux: netlink: recvmsg: new message (2), flags 0x0100, seq 55 [10.8009] platform-linux: delayed-action: complete wait-for-nl-response (seq 55, timeout in 0.199980533, response-type 0, success) [10.8009] platform-linux: do-delete-ip6-address[12: 2001:db8:a:b:1:2:3:4]: success ** NetworkManager:ERROR:src/platform/tests/test-common.c:1127:_ip_address_del: assertion failed: (external_command) Use the same workaround in place for the addition of IPv6 addresses, i.e. refetch the object if the address is still present after the ack. --- src/platform/nm-linux-platform.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 10a5eab6b..a018f6b70 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -4249,8 +4249,7 @@ do_add_addrroute (NMPlatform *platform, * whether the object exists. * * rh#1484434 */ - if (!nmp_cache_lookup_obj (nm_platform_get_cache (platform), - obj_id)) + if (!nmp_cache_lookup_obj (nm_platform_get_cache (platform), obj_id)) do_request_one_type (platform, NMP_OBJECT_GET_TYPE (obj_id)); } @@ -4303,6 +4302,18 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg * wait_for_nl_response_to_string (seq_result, s_buf, sizeof (s_buf)), log_detail); + if (NMP_OBJECT_GET_TYPE (obj_id) == NMP_OBJECT_TYPE_IP6_ADDRESS) { + /* In rare cases, the object is still there after we receive the ACK from + * kernel. Need to refetch. + * + * We want to safe the expensive refetch, thus we look first into the cache + * whether the object exists. + * + * rh#1484434 */ + if (nmp_cache_lookup_obj (nm_platform_get_cache (platform), obj_id)) + do_request_one_type (platform, NMP_OBJECT_GET_TYPE (obj_id)); + } + return success; }