From 09778e0908822e9bf57a8b55e0150ad80e64e01f Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Mar 26 2015 19:31:34 +0000 Subject: util: use netlink to delete bridge devices https://bugzilla.redhat.com/show_bug.cgi?id=1125755 reported that a stray bridge device was left on the system when a libvirt network failed to start due to an illegal iptables rule caused by bad config. Apparently the reason this was happening was that NetworkManager was noticing immediately when the bridge device was created and automatically setting it IFF_UP. libvirt would then try to setup the iptables rules, get an error back, and since libvirt had never IFF_UPed the bridge, it didn't expect that it needed to set it ~IFF_UP before deleting it during the cleanup process. But the ioctl(SIOCBRDELBR) ioctl will fail to delete a bridge if it is IFF_UP. Since that bug was reported, NetworkManager has gotten a bit more polite in this respect, but just in case something similar happens in the future, this patch switches to using the netlink RTM_DELLINK message to delete the bridge - unlike SIOCBRDELBR, it will delete the requested bridge no matter what the setting of IFF_UP. --- diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c index d9dcc39..2bad40a 100644 --- a/src/util/virnetdevbridge.c +++ b/src/util/virnetdevbridge.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2014 Red Hat, Inc. + * Copyright (C) 2007-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -457,7 +457,15 @@ int virNetDevBridgeCreate(const char *brname) * * Returns 0 in case of success or an errno code in case of failure. */ -#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRDELBR) +#if defined(__linux__) && defined(HAVE_LIBNL) +int virNetDevBridgeDelete(const char *brname) +{ + /* If netlink is available, use it, as it is successful at + * deleting a bridge even if it is currently IFF_UP. + */ + return virNetlinkDelLink(brname); +} +#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRDELBR) int virNetDevBridgeDelete(const char *brname) { int fd = -1;