Implementation uses SIOCIFCREATE2 and SIOCIFDESTROY ioctls. Also, drop static virNetDevSetupControl() as we have public one avialable now. --- src/util/virnetdevbridge.c | 91 ++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c index 130829c..df606d2 100644 --- a/src/util/virnetdevbridge.c +++ b/src/util/virnetdevbridge.c @@ -23,6 +23,7 @@ #include <config.h> #include "virnetdevbridge.h" +#include "virnetdev.h" #include "virerror.h" #include "virutil.h" #include "virfile.h" @@ -48,49 +49,6 @@ #if defined(HAVE_STRUCT_IFREQ) && defined(__linux__) -static int virNetDevSetupControlFull(const char *ifname, - struct ifreq *ifr, - int domain, - int type) -{ - int fd; - - if (ifname && ifr) { - memset(ifr, 0, sizeof(*ifr)); - - if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - ifname); - return -1; - } - } - - if ((fd = socket(domain, type, 0)) < 0) { - virReportSystemError(errno, "%s", - _("Cannot open network interface control socket")); - return -1; - } - - if (virSetInherit(fd, false) < 0) { - virReportSystemError(errno, "%s", - _("Cannot set close-on-exec flag for socket")); - VIR_FORCE_CLOSE(fd); - return -1; - } - - return fd; -} - - -static int virNetDevSetupControl(const char *ifname, - struct ifreq *ifr) -{ - return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); -} -#endif - -#if defined(HAVE_STRUCT_IFREQ) && defined(__linux__) # define SYSFS_NET_DIR "/sys/class/net" /* * Bridge parameters can be set via sysfs on newish kernels, @@ -233,6 +191,31 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } +#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCIFCREATE2) +int virNetDevBridgeCreate(const char *brname) +{ + int s; + struct ifreq ifr; + int ret = - 1; + + if ((s = virNetDevSetupControl("bridge", &ifr)) < 0) + return -1; + + if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) { + virReportSystemError(errno, "%s", + _("Unable to create bridge device")); + goto cleanup; + } + + if (virNetDevSetName(ifr.ifr_name, brname) == -1) { + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(s); + return ret; +} #else int virNetDevBridgeCreate(const char *brname) { @@ -271,6 +254,28 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } +#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCIFDESTROY) +int virNetDevBridgeDelete(const char *brname) +{ + int s; + struct ifreq ifr; + int ret = -1; + + if ((s = virNetDevSetupControl(brname, &ifr)) < 0) + return -1; + + if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) { + virReportSystemError(errno, + _("Unable to remove bridge %s"), + brname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(s); + return ret; +} #else int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) { -- 1.8.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list