[libvirt] [PATCH] macvtap IFF_VNET_HDR configuration
Daniel Veillard
veillard at redhat.com
Fri Feb 19 10:44:25 UTC 2010
On Thu, Feb 18, 2010 at 05:43:40PM -0500, Stefan Berger wrote:
> This patch sets or unsets the IFF_VNET_HDR flag depending on what device
> is used in the VM. The manipulation of the flag is done in the open
> function and is only fatal if the IFF_VNET_HDR flag could not be cleared
> although it has to be (or if an ioctl generally fails). In that case the
> macvtap tap is closed again and the macvtap interface torn.
>
> This patch also passes 'make syntax-check' :-).
Yup, thanks :-)
> Signed-off-by: Stefan Berger <stefanb at us.ibm.com>
>
>
> Index: libvirt-macvtap/src/qemu/qemu_conf.c
> ===================================================================
> --- libvirt-macvtap.orig/src/qemu/qemu_conf.c
> +++ libvirt-macvtap/src/qemu/qemu_conf.c
> @@ -1434,14 +1434,20 @@ int
> qemudPhysIfaceConnect(virConnectPtr conn,
> virDomainNetDefPtr net,
> char *linkdev,
> - int brmode)
> + int brmode,
> + unsigned long long qemuCmdFlags)
> {
> int rc;
> #if WITH_MACVTAP
> char *res_ifname = NULL;
> + int vnet_hdr = 0;
> +
> + if (qemuCmdFlags & QEMUD_CMD_FLAG_VNET_HDR &&
> + net->model && STREQ(net->model, "virtio"))
> + vnet_hdr = 1;
>
> rc = openMacvtapTap(conn, net->ifname, net->mac, linkdev, brmode,
> - &res_ifname);
> + &res_ifname, vnet_hdr);
> if (rc >= 0) {
> VIR_FREE(net->ifname);
> net->ifname = res_ifname;
> @@ -1451,6 +1457,7 @@ qemudPhysIfaceConnect(virConnectPtr conn
> (void)net;
> (void)linkdev;
> (void)brmode;
> + (void)qemuCmdFlags;
> qemuReportError(VIR_ERR_INTERNAL_ERROR,
> "%s", _("No support for macvtap device"));
> rc = -1;
> @@ -3752,7 +3759,8 @@ int qemudBuildCommandLine(virConnectPtr
> } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> int tapfd = qemudPhysIfaceConnect(conn, net,
> net->data.direct.linkdev,
> - net->data.direct.mode);
> + net->data.direct.mode,
> + qemuCmdFlags);
> if (tapfd < 0)
> goto error;
>
> Index: libvirt-macvtap/src/util/macvtap.c
> ===================================================================
> --- libvirt-macvtap.orig/src/util/macvtap.c
> +++ libvirt-macvtap/src/util/macvtap.c
> @@ -615,6 +615,64 @@ macvtapModeFromInt(enum virDomainNetdevM
>
>
> /**
> + * configMacvtapTap:
> + * @tapfd: file descriptor of the macvtap tap
> + * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it
> + *
> + * Returns 0 on success, -1 in case of fatal error, error code otherwise.
> + *
> + * Turn the IFF_VNET_HDR flag, if requested and available, make sure
> + * it's off in the other cases.
> + * A fatal error is defined as the VNET_HDR flag being set but it cannot
> + * be turned off for some reason. This is reported with -1. Other fatal
> + * error is not being able to read the interface flags. In that case the
> + * macvtap device should not be used.
> + */
> +static int
> +configMacvtapTap(int tapfd, int vnet_hdr)
> +{
> + unsigned int features;
> + struct ifreq ifreq;
> + short new_flags = 0;
> + int rc_on_fail = 0;
> + const char *errmsg = NULL;
> +
> + memset(&ifreq, 0, sizeof(ifreq));
> +
> + if (ioctl(tapfd, TUNGETIFF, &ifreq) < 0) {
> + virReportSystemError(errno, "%s",
> + _("cannot get interface flags on macvtap tap"));
> + return -1;
> + }
> +
> + new_flags = ifreq.ifr_flags;
> +
> + if ((ifreq.ifr_flags & IFF_VNET_HDR) && !vnet_hdr) {
> + new_flags = ifreq.ifr_flags & ~IFF_VNET_HDR;
> + rc_on_fail = -1;
> + errmsg = _("cannot clean IFF_VNET_HDR flag on macvtap tap");
> + } else if ((ifreq.ifr_flags & IFF_VNET_HDR) == 0 && vnet_hdr) {
> + if (ioctl(tapfd, TUNGETFEATURES, &features) != 0)
> + return errno;
> + if ((features & IFF_VNET_HDR)) {
> + new_flags = ifreq.ifr_flags | IFF_VNET_HDR;
> + errmsg = _("cannot set IFF_VNET_HDR flag on macvtap tap");
> + }
> + }
> +
> + if (new_flags != ifreq.ifr_flags) {
> + ifreq.ifr_flags = new_flags;
> + if (ioctl(tapfd, TUNSETIFF, &ifreq) < 0) {
> + virReportSystemError(errno, "%s", errmsg);
> + return rc_on_fail;
> + }
> + }
> +
> + return 0;
> +}
> +
> +
> +/**
> * openMacvtapTap:
> * Create an instance of a macvtap device and open its tap character
> * device.
> @@ -640,7 +698,8 @@ openMacvtapTap(virConnectPtr conn,
> const unsigned char *macaddress,
> const char *linkdev,
> int mode,
> - char **res_ifname)
> + char **res_ifname,
> + int vnet_hdr)
> {
> const char *type = "macvtap";
> int c, rc;
> @@ -699,9 +758,14 @@ create_name:
>
> rc = openTap(cr_ifname, 10);
>
> - if (rc >= 0)
> + if (rc >= 0) {
> + if (configMacvtapTap(rc, vnet_hdr) < 0) {
> + close(rc);
> + rc = -1;
> + goto link_del_exit;
> + }
> *res_ifname = strdup(cr_ifname);
> - else
> + } else
> goto link_del_exit;
>
> return rc;
> Index: libvirt-macvtap/src/util/macvtap.h
> ===================================================================
> --- libvirt-macvtap.orig/src/util/macvtap.h
> +++ libvirt-macvtap/src/util/macvtap.h
> @@ -33,9 +33,10 @@ int openMacvtapTap(virConnectPtr conn,
> const unsigned char *macaddress,
> const char *linkdev,
> int mode,
> - char **res_ifname);
> + char **res_ifname,
> + int vnet_hdr);
>
> -void delMacvtap(const char *name);
> +void delMacvtap(const char *ifname);
>
> #endif /* WITH_MACVTAP */
>
> Index: libvirt-macvtap/src/qemu/qemu_conf.h
> ===================================================================
> --- libvirt-macvtap.orig/src/qemu/qemu_conf.h
> +++ libvirt-macvtap/src/qemu/qemu_conf.h
> @@ -253,7 +253,8 @@ int qemudNetworkIfaceConnect
> int qemudPhysIfaceConnect(virConnectPtr conn,
> virDomainNetDefPtr net,
> char *linkdev,
> - int brmode);
> + int brmode,
> + unsigned long long qemuCmdFlags);
>
> int qemudProbeMachineTypes (const char *binary,
> virCapsGuestMachinePtr **machines,
> Index: libvirt-macvtap/src/qemu/qemu_driver.c
> ===================================================================
> --- libvirt-macvtap.orig/src/qemu/qemu_driver.c
> +++ libvirt-macvtap/src/qemu/qemu_driver.c
> @@ -5725,7 +5725,8 @@ static int qemudDomainAttachNetDevice(vi
>
> if ((tapfd = qemudPhysIfaceConnect(conn, net,
> net->data.direct.linkdev,
> - net->data.direct.mode)) < 0)
> + net->data.direct.mode,
> + qemuCmdFlags)) < 0)
> return -1;
> }
>
Looks reasonnable, ACK, applied !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list