@@ -211,7 +211,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
{
}
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
{
return 0;
}
@@ -147,13 +147,15 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
}
}
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
{
struct ifreq ifr;
if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
- error_report("TUNGETIFF ioctl() failed: %s", strerror(errno));
- return 0;
+ /* TUNGETIFF is available since kernel v2.6.27 */
+ error_setg_errno(errp, errno,
+ "Unable to query TUNGETIFF on FD %d", fd);
+ return -1;
}
return ifr.ifr_flags & IFF_VNET_HDR;
@@ -207,7 +207,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
{
}
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
{
return 0;
}
@@ -37,7 +37,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
{
}
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
{
return 0;
}
@@ -598,7 +598,11 @@ int net_init_bridge(const Netdev *netdev, const char *name,
}
qemu_set_nonblock(fd);
- vnet_hdr = tap_probe_vnet_hdr(fd);
+ vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ if (vnet_hdr < 0) {
+ close(fd);
+ return -1;
+ }
s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper,
@@ -810,7 +814,11 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
- vnet_hdr = tap_probe_vnet_hdr(fd);
+ vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ if (vnet_hdr < 0) {
+ close(fd);
+ return -1;
+ }
net_init_tap_one(tap, peer, "tap", name, NULL,
script, downscript,
@@ -862,8 +870,11 @@ int net_init_tap(const Netdev *netdev, const char *name,
}
if (i == 0) {
- vnet_hdr = tap_probe_vnet_hdr(fd);
- } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
+ vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ if (vnet_hdr < 0) {
+ goto free_fail;
+ }
+ } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
error_setg(errp,
"vnet_hdr not consistent across given tap fds");
ret = -1;
@@ -908,7 +919,11 @@ free_fail:
}
qemu_set_nonblock(fd);
- vnet_hdr = tap_probe_vnet_hdr(fd);
+ vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ if (vnet_hdr < 0) {
+ close(fd);
+ return -1;
+ }
net_init_tap_one(tap, peer, "bridge", name, ifname,
script, downscript, vhostfdname,
@@ -34,7 +34,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
-int tap_probe_vnet_hdr(int fd);
+int tap_probe_vnet_hdr(int fd, Error **errp);
int tap_probe_vnet_hdr_len(int fd, int len);
int tap_probe_has_ufo(int fd);
void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo);