This refactors the TAP creation code out of brAddTap into a new function brCreateTap to allow it to be used on its own. I have also changed ifSetInterfaceMac to brSetInterfaceMac and exported it since it is will be needed by code outside of util/bridge.c in the next patch. AUTHORS | 1 + src/libvirt_bridge.syms | 2 + src/util/bridge.c | 116 +++++++++++++++++++++++++++++++---------------- src/util/bridge.h | 9 ++++ 4 files changed, 89 insertions(+), 39 deletions(-) --- diff --git a/AUTHORS b/AUTHORS index b3da705..391f83a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -199,6 +199,7 @@ Patches have also been contributed by: Dan Horák <dan@xxxxxxxx> Sage Weil <sage@xxxxxxxxxxxx> David L Stevens <dlstevens@xxxxxxxxxx> + Tyler Coumbes <coumbes@xxxxxxxxx> [....send patches to get your name here....] diff --git a/src/libvirt_bridge.syms b/src/libvirt_bridge.syms index c3773bd..669830b 100644 --- a/src/libvirt_bridge.syms +++ b/src/libvirt_bridge.syms @@ -12,10 +12,12 @@ brAddTap; brDeleteTap; brDeleteBridge; brDelInetAddress; +brCreateTap; brHasBridge; brInit; brSetEnableSTP; brSetForwardDelay; brSetInetNetmask; +brSetInterfaceMac; brSetInterfaceUp; brShutdown; diff --git a/src/util/bridge.c b/src/util/bridge.c index d63b2a0..4875f52 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -278,7 +278,7 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, # endif /** - * ifSetInterfaceMac: + * brSetInterfaceMac: * @ctl: bridge control pointer * @ifname: interface name to set MTU for * @macaddr: MAC address (VIR_MAC_BUFLEN in size) @@ -288,7 +288,7 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, * * Returns 0 in case of success or an errno code in case of failure. */ -static int ifSetInterfaceMac(brControl *ctl, const char *ifname, +int brSetInterfaceMac(brControl *ctl, const char *ifname, const unsigned char *macaddr) { struct ifreq ifr; @@ -478,32 +478,12 @@ brAddTap(brControl *ctl, bool up, int *tapfd) { - int fd; - struct ifreq ifr; - if (!ctl || !ctl->fd || !bridge || !ifname) return EINVAL; - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) - return errno; - - memset(&ifr, 0, sizeof(ifr)); - - ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + errno = brCreateTap(ctl, ifname, vnet_hdr, tapfd); -# ifdef IFF_VNET_HDR - if (vnet_hdr && brProbeVnetHdr(fd)) - ifr.ifr_flags |= IFF_VNET_HDR; -# else - (void) vnet_hdr; -# endif - - if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { - errno = EINVAL; - goto error; - } - - if (ioctl(fd, TUNSETIFF, &ifr) < 0) + if(*tapfd < 0 || errno) goto error; /* We need to set the interface MAC before adding it @@ -512,32 +492,22 @@ brAddTap(brControl *ctl, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if ((errno = ifSetInterfaceMac(ctl, ifr.ifr_name, macaddr))) + if ((errno = brSetInterfaceMac(ctl, *ifname, macaddr))) goto error; /* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if ((errno = brSetInterfaceMtu(ctl, bridge, ifr.ifr_name))) - goto error; - if ((errno = brAddInterface(ctl, bridge, ifr.ifr_name))) + if ((errno = brSetInterfaceMtu(ctl, bridge, *ifname))) goto error; - if (up && ((errno = brSetInterfaceUp(ctl, ifr.ifr_name, 1)))) + if ((errno = brAddInterface(ctl, bridge, *ifname))) goto error; - if (!tapfd && - (errno = ioctl(fd, TUNSETPERSIST, 1))) - goto error; - VIR_FREE(*ifname); - if (!(*ifname = strdup(ifr.ifr_name))) + if (up && ((errno = brSetInterfaceUp(ctl, *ifname, 1)))) goto error; - if (tapfd) - *tapfd = fd; - else - VIR_FORCE_CLOSE(fd); return 0; error: - VIR_FORCE_CLOSE(fd); + VIR_FORCE_CLOSE(*tapfd); return errno; } @@ -803,4 +773,72 @@ cleanup: return ret; } +/** + * brCreateTap: + * @ctl: bridge control pointer + * @ifname: the interface name + * @vnet_hr: whether to try enabling IFF_VNET_HDR + * @tapfd: file descriptor return value for the new tap device + * + * Creates a tap interface. + * If the @tapfd parameter is supplied, the open tap device file + * descriptor will be returned, otherwise the TAP device will be made + * persistent and closed. The caller must use brDeleteTap to remove + * a persistent TAP devices when it is no longer needed. + * + * Returns 0 in case of success or an errno code in case of failure. + */ + +int brCreateTap (brControl *ctl ATTRIBUTE_UNUSED, + char **ifname, + int vnet_hdr, + int *tapfd) +{ + + int fd; + struct ifreq ifr; + + if (!ifname) + return EINVAL; + + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) + return errno; + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + +# ifdef IFF_VNET_HDR + if (vnet_hdr && brProbeVnetHdr(fd)) + ifr.ifr_flags |= IFF_VNET_HDR; +# else + (void) vnet_hdr; +# endif + + if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { + errno = EINVAL; + goto error; + } + + if (ioctl(fd, TUNSETIFF, &ifr) < 0) + goto error; + + if (!tapfd && + (errno = ioctl(fd, TUNSETPERSIST, 1))) + goto error; + VIR_FREE(*ifname); + if (!(*ifname = strdup(ifr.ifr_name))) + goto error; + if(tapfd) + *tapfd = fd; + else + VIR_FORCE_CLOSE(fd); + return 0; + + error: + VIR_FORCE_CLOSE(fd); + + return errno; +} + #endif /* WITH_BRIDGE */ diff --git a/src/util/bridge.h b/src/util/bridge.h index 93f0b33..c462a08 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -106,6 +106,15 @@ int brGetEnableSTP (brControl *ctl, const char *bridge, int *enable); +int brCreateTap (brControl *ctl, + char **ifname, + int vnet_hdr, + int *tapfd); + +int brSetInterfaceMac (brControl *ctl, + const char *ifname, + const unsigned char *macaddr); + # endif /* WITH_BRIDGE */ #endif /* __QEMUD_BRIDGE_H__ */ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list