diff --git a/AUTHORS b/AUTHORS index b3da70523c37c1f9261baac2637fa491099a9bbd..391f83aa23bdc33a18e1f2cf527edf8755aabd5a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -199,6 +199,7 @@ Patches have also been contributed by: Dan HorĂ¡k Sage Weil David L Stevens + Tyler Coumbes [....send patches to get your name here....] diff --git a/src/libvirt_bridge.syms b/src/libvirt_bridge.syms index c3773bdde305bdf9c2d9ceaab9f399eff6e91887..626f6eefd97040c68819569de017a25217d48064 100644 --- a/src/libvirt_bridge.syms +++ b/src/libvirt_bridge.syms @@ -9,13 +9,15 @@ brAddBridge; brAddInetAddress; brAddInterface; brAddTap; -brDeleteTap; -brDeleteBridge; +brCreateTap; brDelInetAddress; +brDeleteBridge; +brDeleteTap; brHasBridge; brInit; brSetEnableSTP; brSetForwardDelay; brSetInetNetmask; +brSetInterfaceMac; brSetInterfaceUp; brShutdown; diff --git a/src/util/bridge.c b/src/util/bridge.c index d63b2a0521dc2ef07454368888f765517c245d02..952f0f3235ccfb1e04f17bf5a39e768a156c78e1 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,8 +288,9 @@ 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, - const unsigned char *macaddr) +int +brSetInterfaceMac(brControl *ctl, const char *ifname, + const unsigned char *macaddr) { struct ifreq ifr; @@ -478,32 +479,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; - -# 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; - } + errno = brCreateTap(ctl, ifname, vnet_hdr, tapfd); - if (ioctl(fd, TUNSETIFF, &ifr) < 0) + if (*tapfd < 0 || errno) goto error; /* We need to set the interface MAC before adding it @@ -512,32 +493,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 +774,70 @@ 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 ATTRIBUTE_UNUSED, + 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; +# 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 93f0b3381a616c4af3d3833d70f701c80ad98d8f..c462a082171a631cb75a343777cb1bf0c0cd29f0 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__ */