mirror of https://github.com/proxmox/mirror_qemu
net: add a vnet_hdr=on|off parameter
This allows people to disable the IFF_VNET_HDR flag, e.g. for debugging purposes or if they know they may migrate the guest to a machine without IFF_VNET_HDR support. It also allows making the lack of IFF_VNET_HDR support an error condition, e.g. in the case where a guest is being migrated from a host which does support it. Signed-off-by: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>master
parent
424a7f9674
commit
baf74c9580
42
net.c
42
net.c
|
@ -1494,7 +1494,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
|
#if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
|
||||||
static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
static int tap_open(char *ifname, int ifname_size,
|
||||||
|
int *vnet_hdr, int vnet_hdr_required)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char *dev;
|
char *dev;
|
||||||
|
@ -1636,7 +1637,8 @@ static int tap_alloc(char *dev, size_t dev_size)
|
||||||
return tap_fd;
|
return tap_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
static int tap_open(char *ifname, int ifname_size,
|
||||||
|
int *vnet_hdr, int vnet_hdr_required)
|
||||||
{
|
{
|
||||||
char dev[10]="";
|
char dev[10]="";
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -1649,13 +1651,15 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
#elif defined (_AIX)
|
#elif defined (_AIX)
|
||||||
static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
static int tap_open(char *ifname, int ifname_size,
|
||||||
|
int *vnet_hdr, int vnet_hdr_required)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "no tap on AIX\n");
|
fprintf (stderr, "no tap on AIX\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
static int tap_open(char *ifname, int ifname_size,
|
||||||
|
int *vnet_hdr, int vnet_hdr_required)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
|
@ -1668,7 +1672,7 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||||
|
|
||||||
{
|
if (*vnet_hdr) {
|
||||||
unsigned int features;
|
unsigned int features;
|
||||||
|
|
||||||
if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
|
if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
|
||||||
|
@ -1676,6 +1680,13 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
|
||||||
*vnet_hdr = 1;
|
*vnet_hdr = 1;
|
||||||
ifr.ifr_flags |= IFF_VNET_HDR;
|
ifr.ifr_flags |= IFF_VNET_HDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vnet_hdr_required && !*vnet_hdr) {
|
||||||
|
qemu_error("vnet_hdr=1 requested, but no kernel "
|
||||||
|
"support for IFF_VNET_HDR available");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifname[0] != '\0')
|
if (ifname[0] != '\0')
|
||||||
|
@ -1740,7 +1751,7 @@ static int launch_script(const char *setup_script, const char *ifname, int fd)
|
||||||
|
|
||||||
static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
|
static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd, vnet_hdr_required;
|
||||||
char ifname[128] = {0,};
|
char ifname[128] = {0,};
|
||||||
const char *setup_script;
|
const char *setup_script;
|
||||||
|
|
||||||
|
@ -1748,8 +1759,14 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
|
||||||
pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
|
pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
*vnet_hdr = 0;
|
*vnet_hdr = qemu_opt_get_bool(opts, "vnet_hdr", 1);
|
||||||
TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr));
|
if (qemu_opt_get(opts, "vnet_hdr")) {
|
||||||
|
vnet_hdr_required = *vnet_hdr;
|
||||||
|
} else {
|
||||||
|
vnet_hdr_required = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr, vnet_hdr_required));
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2698,8 +2715,9 @@ static int net_init_tap(QemuOpts *opts,
|
||||||
if (qemu_opt_get(opts, "fd")) {
|
if (qemu_opt_get(opts, "fd")) {
|
||||||
if (qemu_opt_get(opts, "ifname") ||
|
if (qemu_opt_get(opts, "ifname") ||
|
||||||
qemu_opt_get(opts, "script") ||
|
qemu_opt_get(opts, "script") ||
|
||||||
qemu_opt_get(opts, "downscript")) {
|
qemu_opt_get(opts, "downscript") ||
|
||||||
qemu_error("ifname=, script= and downscript= is invalid with fd=\n");
|
qemu_opt_get(opts, "vnet_hdr")) {
|
||||||
|
qemu_error("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3055,6 +3073,10 @@ static struct {
|
||||||
.name = "sndbuf",
|
.name = "sndbuf",
|
||||||
.type = QEMU_OPT_SIZE,
|
.type = QEMU_OPT_SIZE,
|
||||||
.help = "send buffer limit"
|
.help = "send buffer limit"
|
||||||
|
}, {
|
||||||
|
.name = "vnet_hdr",
|
||||||
|
.type = QEMU_OPT_BOOL,
|
||||||
|
.help = "enable the IFF_VNET_HDR flag on the tap interface"
|
||||||
},
|
},
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
|
|
|
@ -810,7 +810,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
|
||||||
"-net tap[,vlan=n][,name=str],ifname=name\n"
|
"-net tap[,vlan=n][,name=str],ifname=name\n"
|
||||||
" connect the host TAP network interface to VLAN 'n'\n"
|
" connect the host TAP network interface to VLAN 'n'\n"
|
||||||
#else
|
#else
|
||||||
"-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes]\n"
|
"-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n"
|
||||||
" connect the host TAP network interface to VLAN 'n' and use the\n"
|
" connect the host TAP network interface to VLAN 'n' and use the\n"
|
||||||
" network scripts 'file' (default=%s)\n"
|
" network scripts 'file' (default=%s)\n"
|
||||||
" and 'dfile' (default=%s);\n"
|
" and 'dfile' (default=%s);\n"
|
||||||
|
@ -818,6 +818,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
|
||||||
" use 'fd=h' to connect to an already opened TAP interface\n"
|
" use 'fd=h' to connect to an already opened TAP interface\n"
|
||||||
" use 'sndbuf=nbytes' to limit the size of the send buffer; the\n"
|
" use 'sndbuf=nbytes' to limit the size of the send buffer; the\n"
|
||||||
" default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
|
" default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
|
||||||
|
" use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use\n"
|
||||||
|
" vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition\n"
|
||||||
#endif
|
#endif
|
||||||
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
|
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
|
||||||
" connect the vlan 'n' to another VLAN using a socket connection\n"
|
" connect the vlan 'n' to another VLAN using a socket connection\n"
|
||||||
|
|
Loading…
Reference in New Issue