platform: change links via event netlink socket
This commit is contained in:
@@ -3790,13 +3790,19 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NMPlatformError
|
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;
|
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:
|
retry:
|
||||||
nle = nl_send_auto_complete (priv->nlh, nlmsg);
|
nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result);
|
||||||
if (nle < 0) {
|
if (nle < 0) {
|
||||||
_LOGE ("do-change-link[%d]: failure sending netlink request \"%s\" (%d)",
|
_LOGE ("do-change-link[%d]: failure sending netlink request \"%s\" (%d)",
|
||||||
ifindex,
|
ifindex,
|
||||||
@@ -3804,35 +3810,39 @@ retry:
|
|||||||
return NM_PLATFORM_ERROR_UNSPECIFIED;
|
return NM_PLATFORM_ERROR_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
nle = nl_wait_for_ack (priv->nlh);
|
/* always refetch the link after changing it. There seems to be issues
|
||||||
if ( nle == -NLE_OPNOTSUPP
|
* 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_NEWLINK) {
|
||||||
nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK;
|
nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (nle) {
|
if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) {
|
||||||
case -NLE_SUCCESS:
|
log_result = "success";
|
||||||
_LOGD ("do-change-link[%d]: success changing link", ifindex);
|
} else if (NM_IN_SET (-((int) seq_result), EEXIST, EADDRINUSE)) {
|
||||||
break;
|
/* */
|
||||||
case -NLE_EXIST:
|
} else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) {
|
||||||
_LOGD ("do-change-link[%d]: success changing link: %s (%d)",
|
log_detail = ", firmware not found";
|
||||||
ifindex, nl_geterror (nle), -nle);
|
result = NM_PLATFORM_ERROR_NO_FIRMWARE;
|
||||||
break;
|
} else {
|
||||||
case -NLE_OBJ_NOTFOUND:
|
log_level = LOGL_ERR;
|
||||||
_LOGD ("do-change-link[%d]: failure changing link: firmware not found (%s, %d)",
|
result = NM_PLATFORM_ERROR_UNSPECIFIED;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
_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
|
return result;
|
||||||
* sync and we have to refetch the link. */
|
|
||||||
do_request_link (platform, ifindex, NULL);
|
|
||||||
return NM_PLATFORM_ERROR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -4056,7 +4066,7 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable
|
|||||||
if ( !nlmsg
|
if ( !nlmsg
|
||||||
|| !_nl_msg_new_link_set_afspec (nlmsg,
|
|| !_nl_msg_new_link_set_afspec (nlmsg,
|
||||||
mode))
|
mode))
|
||||||
return FALSE;
|
g_return_val_if_reached (FALSE);
|
||||||
|
|
||||||
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
|
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_n_ingress_map,
|
||||||
new_egress_map,
|
new_egress_map,
|
||||||
new_n_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;
|
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -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 (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||||
g_assert (!nm_platform_link_get_type_name (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_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_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_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_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||||
|
|
||||||
g_assert (!nm_platform_link_is_up (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 (!addrlen);
|
||||||
g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
|
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_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU));
|
||||||
|
|
||||||
g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||||
|
Reference in New Issue
Block a user