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(a)danny.cz>
Sage Weil <sage(a)newdream.net>
David L Stevens <dlstevens(a)us.ibm.com>
+ Tyler Coumbes <coumbes(a)gmail.com>
[....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__ */