aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/tap-aix.c10
-rw-r--r--net/tap-bsd.c11
-rw-r--r--net/tap-haiku.c11
-rw-r--r--net/tap-linux.c52
-rw-r--r--net/tap-solaris.c11
-rw-r--r--net/tap_int.h2
6 files changed, 97 insertions, 0 deletions
diff --git a/net/tap-aix.c b/net/tap-aix.c
index aff6c527e9..66e0574fd7 100644
--- a/net/tap-aix.c
+++ b/net/tap-aix.c
@@ -59,3 +59,13 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
int tso6, int ecn, int ufo)
{
}
+
+int tap_fd_enable(int fd)
+{
+ return -1;
+}
+
+int tap_fd_disable(int fd)
+{
+ return -1;
+}
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 01c705b4c0..cfc7a289f8 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -145,3 +145,14 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
int tso6, int ecn, int ufo)
{
}
+
+int tap_fd_enable(int fd)
+{
+ return -1;
+}
+
+int tap_fd_disable(int fd)
+{
+ return -1;
+}
+
diff --git a/net/tap-haiku.c b/net/tap-haiku.c
index 08cc034cee..664d40fb4d 100644
--- a/net/tap-haiku.c
+++ b/net/tap-haiku.c
@@ -59,3 +59,14 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
int tso6, int ecn, int ufo)
{
}
+
+int tap_fd_enable(int fd)
+{
+ return -1;
+}
+
+int tap_fd_disable(int fd)
+{
+ return -1;
+}
+
diff --git a/net/tap-linux.c b/net/tap-linux.c
index 0a6acc7d5a..bdb0a790c8 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -41,6 +41,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
struct ifreq ifr;
int fd, ret;
int len = sizeof(struct virtio_net_hdr);
+ int mq_required = 0;
TFR(fd = open(PATH_NET_TUN, O_RDWR));
if (fd < 0) {
@@ -76,6 +77,20 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
ioctl(fd, TUNSETVNETHDRSZ, &len);
}
+ if (mq_required) {
+ unsigned int features;
+
+ if ((ioctl(fd, TUNGETFEATURES, &features) != 0) ||
+ !(features & IFF_MULTI_QUEUE)) {
+ error_report("multiqueue required, but no kernel "
+ "support for IFF_MULTI_QUEUE available");
+ close(fd);
+ return -1;
+ } else {
+ ifr.ifr_flags |= IFF_MULTI_QUEUE;
+ }
+ }
+
if (ifname[0] != '\0')
pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
else
@@ -209,3 +224,40 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
}
}
}
+
+/* Enable a specific queue of tap. */
+int tap_fd_enable(int fd)
+{
+ struct ifreq ifr;
+ int ret;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ ifr.ifr_flags = IFF_ATTACH_QUEUE;
+ ret = ioctl(fd, TUNSETQUEUE, (void *) &ifr);
+
+ if (ret != 0) {
+ error_report("could not enable queue");
+ }
+
+ return ret;
+}
+
+/* Disable a specific queue of tap/ */
+int tap_fd_disable(int fd)
+{
+ struct ifreq ifr;
+ int ret;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ ifr.ifr_flags = IFF_DETACH_QUEUE;
+ ret = ioctl(fd, TUNSETQUEUE, (void *) &ifr);
+
+ if (ret != 0) {
+ error_report("could not disable queue");
+ }
+
+ return ret;
+}
+
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index 486a7ea838..12cc392c94 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -225,3 +225,14 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
int tso6, int ecn, int ufo)
{
}
+
+int tap_fd_enable(int fd)
+{
+ return -1;
+}
+
+int tap_fd_disable(int fd)
+{
+ return -1;
+}
+
diff --git a/net/tap_int.h b/net/tap_int.h
index 1dffe12a45..ca1c21b451 100644
--- a/net/tap_int.h
+++ b/net/tap_int.h
@@ -42,5 +42,7 @@ 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);
void tap_fd_set_vnet_hdr_len(int fd, int len);
+int tap_fd_enable(int fd);
+int tap_fd_disable(int fd);
#endif /* QEMU_TAP_H */