platform: fix software device handling when announcing links
The handling for announcing links was broken resulting in duplicate link-added signals from platform. Co-Authored-By: Thomas Haller <thaller@redhat.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:

committed by
Thomas Haller

parent
f008c9fbea
commit
fd41c989d5
@@ -3594,38 +3594,40 @@ udev_device_added (NMPlatform *platform,
|
|||||||
auto_nl_object struct rtnl_link *rtnllink = NULL;
|
auto_nl_object struct rtnl_link *rtnllink = NULL;
|
||||||
const char *ifname;
|
const char *ifname;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
gboolean is_changed;
|
gboolean was_announceable = FALSE;
|
||||||
|
|
||||||
ifname = g_udev_device_get_name (udev_device);
|
ifname = g_udev_device_get_name (udev_device);
|
||||||
if (!ifname) {
|
if (!ifname) {
|
||||||
debug ("failed to get device's interface");
|
debug ("udev-add: failed to get device's interface");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_udev_device_get_property (udev_device, "IFINDEX"))
|
if (g_udev_device_get_property (udev_device, "IFINDEX"))
|
||||||
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
|
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
|
||||||
else {
|
else {
|
||||||
warning ("(%s): failed to get device's ifindex", ifname);
|
warning ("(%s): udev-add: failed to get device's ifindex", ifname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ifindex <= 0) {
|
||||||
|
warning ("(%s): udev-add: retrieved invalid IFINDEX=%d", ifname, ifindex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_udev_device_get_sysfs_path (udev_device)) {
|
if (!g_udev_device_get_sysfs_path (udev_device)) {
|
||||||
debug ("(%s): couldn't determine device path; ignoring...", ifname);
|
debug ("(%s): udev-add: couldn't determine device path; ignoring...", ifname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_changed = g_hash_table_lookup_extended (priv->udev_devices, GINT_TO_POINTER (ifindex), NULL, NULL);
|
rtnllink = rtnl_link_get (priv->link_cache, ifindex);
|
||||||
|
if (rtnllink)
|
||||||
|
was_announceable = link_is_announceable (platform, rtnllink);
|
||||||
|
|
||||||
g_hash_table_insert (priv->udev_devices, GINT_TO_POINTER (ifindex),
|
g_hash_table_insert (priv->udev_devices, GINT_TO_POINTER (ifindex),
|
||||||
g_object_ref (udev_device));
|
g_object_ref (udev_device));
|
||||||
|
|
||||||
/* Don't announce devices that have not yet been discovered via Netlink. */
|
/* Announce devices only if they also have been discovered via Netlink. */
|
||||||
rtnllink = rtnl_link_get (priv->link_cache, ifindex);
|
if (rtnllink && link_is_announceable (platform, rtnllink))
|
||||||
if (!rtnllink) {
|
announce_object (platform, (struct nl_object *) rtnllink, was_announceable ? NM_PLATFORM_SIGNAL_CHANGED : NM_PLATFORM_SIGNAL_ADDED, NM_PLATFORM_REASON_EXTERNAL);
|
||||||
debug ("%s: not found in link cache, ignoring...", ifname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
announce_object (platform, (struct nl_object *) rtnllink, is_changed ? NM_PLATFORM_SIGNAL_CHANGED : NM_PLATFORM_SIGNAL_ADDED, NM_PLATFORM_REASON_EXTERNAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3633,12 +3635,13 @@ udev_device_removed (NMPlatform *platform,
|
|||||||
GUdevDevice *udev_device)
|
GUdevDevice *udev_device)
|
||||||
{
|
{
|
||||||
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||||
|
auto_nl_object struct rtnl_link *rtnllink = NULL;
|
||||||
int ifindex = 0;
|
int ifindex = 0;
|
||||||
|
gboolean was_announceable = FALSE;
|
||||||
|
|
||||||
if (g_udev_device_get_property (udev_device, "IFINDEX")) {
|
if (g_udev_device_get_property (udev_device, "IFINDEX"))
|
||||||
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
|
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
|
||||||
g_hash_table_remove (priv->udev_devices, GINT_TO_POINTER (ifindex));
|
else {
|
||||||
} else {
|
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
gpointer key, value;
|
gpointer key, value;
|
||||||
|
|
||||||
@@ -3650,19 +3653,24 @@ udev_device_removed (NMPlatform *platform,
|
|||||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
if ((GUdevDevice *)value == udev_device) {
|
if ((GUdevDevice *)value == udev_device) {
|
||||||
ifindex = GPOINTER_TO_INT (key);
|
ifindex = GPOINTER_TO_INT (key);
|
||||||
g_hash_table_iter_remove (&iter);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Announce device removal if it's still in the Netlink cache. */
|
debug ("udev-remove: IFINDEX=%d", ifindex);
|
||||||
if (ifindex) {
|
if (ifindex <= 0)
|
||||||
auto_nl_object struct rtnl_link *device = rtnl_link_get (priv->link_cache, ifindex);
|
return;
|
||||||
|
|
||||||
if (device)
|
rtnllink = rtnl_link_get (priv->link_cache, ifindex);
|
||||||
announce_object (platform, (struct nl_object *) device, NM_PLATFORM_SIGNAL_REMOVED, NM_PLATFORM_REASON_EXTERNAL);
|
if (rtnllink)
|
||||||
}
|
was_announceable = link_is_announceable (platform, rtnllink);
|
||||||
|
|
||||||
|
g_hash_table_remove (priv->udev_devices, GINT_TO_POINTER (ifindex));
|
||||||
|
|
||||||
|
/* Announce device removal if it is no longer announceable. */
|
||||||
|
if (was_announceable && !link_is_announceable (platform, rtnllink))
|
||||||
|
announce_object (platform, (struct nl_object *) rtnllink, NM_PLATFORM_SIGNAL_REMOVED, NM_PLATFORM_REASON_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -461,9 +461,11 @@ test_internal (void)
|
|||||||
static void
|
static void
|
||||||
test_external (void)
|
test_external (void)
|
||||||
{
|
{
|
||||||
|
NMPlatformLink link;
|
||||||
SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME);
|
SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME);
|
||||||
SignalData *link_changed, *link_removed;
|
SignalData *link_changed, *link_removed;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
run_command ("ip link add %s type %s", DEVICE_NAME, "dummy");
|
run_command ("ip link add %s type %s", DEVICE_NAME, "dummy");
|
||||||
wait_signal (link_added);
|
wait_signal (link_added);
|
||||||
@@ -476,6 +478,13 @@ test_external (void)
|
|||||||
link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex);
|
link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex);
|
||||||
link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex);
|
link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex);
|
||||||
|
|
||||||
|
success = nm_platform_link_get (ifindex, &link);
|
||||||
|
g_assert (success);
|
||||||
|
if (!link.driver) {
|
||||||
|
/* we still lack the notification via UDEV. Expect another link changed signal. */
|
||||||
|
wait_signal (link_changed);
|
||||||
|
}
|
||||||
|
|
||||||
/* Up/connected/arp */
|
/* Up/connected/arp */
|
||||||
g_assert (!nm_platform_link_is_up (ifindex));
|
g_assert (!nm_platform_link_is_up (ifindex));
|
||||||
g_assert (!nm_platform_link_is_connected (ifindex));
|
g_assert (!nm_platform_link_is_connected (ifindex));
|
||||||
|
Reference in New Issue
Block a user