summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-12-14 19:18:35 +0100
committerThomas Haller <thaller@redhat.com>2015-12-16 20:14:15 +0100
commit2970adc414dfb5f76d9050ef91b9ed84949978e5 (patch)
treed7fea3e9a31ad4bf55bc2d585659405355b19b3d
parentecb542948eef00d13d66b9f452d7d70900b79306 (diff)
downloadNetworkManager-2970adc414dfb5f76d9050ef91b9ed84949978e5.tar.gz
platform: change links via event netlink socket
-rw-r--r--src/platform/nm-linux-platform.c64
-rw-r--r--src/platform/tests/test-link.c10
2 files changed, 42 insertions, 32 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index d36830cc4e..86568e90d7 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -3790,13 +3790,19 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
}
static NMPlatformError
-do_change_link (NMPlatform *platform, int ifindex, struct nl_msg *nlmsg)
+do_change_link (NMPlatform *platform,
+ int ifindex,
+ struct nl_msg *nlmsg)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
+ WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
int nle;
+ char s_buf[256];
+ NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
+ NMLogLevel log_level = LOGL_DEBUG;
+ const char *log_result = "failure", *log_detail = "";
retry:
- nle = nl_send_auto_complete (priv->nlh, nlmsg);
+ nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result);
if (nle < 0) {
_LOGE ("do-change-link[%d]: failure sending netlink request \"%s\" (%d)",
ifindex,
@@ -3804,35 +3810,39 @@ retry:
return NM_PLATFORM_ERROR_UNSPECIFIED;
}
- nle = nl_wait_for_ack (priv->nlh);
- if ( nle == -NLE_OPNOTSUPP
+ /* always refetch the link after changing it. There seems to be issues
+ * and we sometimes lack events. Nuke it from the orbit... */
+ delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_LINK, GINT_TO_POINTER (ifindex));
+
+ delayed_action_handle_all (platform, FALSE);
+
+ nm_assert (seq_result);
+
+ if ( NM_IN_SET (-((int) seq_result), EOPNOTSUPP)
&& nlmsg_hdr (nlmsg)->nlmsg_type == RTM_NEWLINK) {
nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK;
goto retry;
}
- switch (nle) {
- case -NLE_SUCCESS:
- _LOGD ("do-change-link[%d]: success changing link", ifindex);
- break;
- case -NLE_EXIST:
- _LOGD ("do-change-link[%d]: success changing link: %s (%d)",
- ifindex, nl_geterror (nle), -nle);
- break;
- case -NLE_OBJ_NOTFOUND:
- _LOGD ("do-change-link[%d]: failure changing link: firmware not found (%s, %d)",
- ifindex, nl_geterror (nle), -nle);
- return NM_PLATFORM_ERROR_NO_FIRMWARE;
- default:
- _LOGE ("do-change-link[%d]: failure changing link: netlink error (%s, %d)",
- ifindex, nl_geterror (nle), -nle);
- return NM_PLATFORM_ERROR_UNSPECIFIED;
+ if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) {
+ log_result = "success";
+ } else if (NM_IN_SET (-((int) seq_result), EEXIST, EADDRINUSE)) {
+ /* */
+ } else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) {
+ log_detail = ", firmware not found";
+ result = NM_PLATFORM_ERROR_NO_FIRMWARE;
+ } else {
+ log_level = LOGL_ERR;
+ result = NM_PLATFORM_ERROR_UNSPECIFIED;
}
+ _NMLOG (log_level,
+ "do-change-link[%d]: %s changing link: %s%s",
+ ifindex,
+ log_result,
+ wait_for_nl_response_to_string (seq_result, s_buf, sizeof (s_buf)),
+ log_detail);
- /* FIXME: as we modify the link via a separate socket, the cache is not in
- * sync and we have to refetch the link. */
- do_request_link (platform, ifindex, NULL);
- return NM_PLATFORM_ERROR_SUCCESS;
+ return result;
}
static gboolean
@@ -4056,7 +4066,7 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable
if ( !nlmsg
|| !_nl_msg_new_link_set_afspec (nlmsg,
mode))
- return FALSE;
+ g_return_val_if_reached (FALSE);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
}
@@ -4745,7 +4755,7 @@ link_vlan_change (NMPlatform *platform,
new_n_ingress_map,
new_egress_map,
new_n_egress_map))
- return FALSE;
+ g_return_val_if_reached (FALSE);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
}
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index af6c4878b2..8b4962620b 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -32,16 +32,16 @@ test_bogus(void)
g_assert (!nm_platform_link_get_type (NM_PLATFORM_GET, BOGUS_IFINDEX));
g_assert (!nm_platform_link_get_type_name (NM_PLATFORM_GET, BOGUS_IFINDEX));
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
g_assert (!nm_platform_link_set_up (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
g_assert (!nm_platform_link_set_down (NM_PLATFORM_GET, BOGUS_IFINDEX));
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
g_assert (!nm_platform_link_set_arp (NM_PLATFORM_GET, BOGUS_IFINDEX));
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
g_assert (!nm_platform_link_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX));
g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, BOGUS_IFINDEX));
@@ -52,7 +52,7 @@ test_bogus(void)
g_assert (!addrlen);
g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
g_assert (!nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU));
g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX));