Преглед на файлове

tap: add APIs for vnet header length

Add APIs to control host header length. First user
will be vhost-net.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Michael S. Tsirkin преди 15 години
родител
ревизия
445d892f43
променени са 8 файла, в които са добавени 92 реда и са изтрити 0 реда
  1. 9 0
      net/tap-aix.c
  2. 9 0
      net/tap-bsd.c
  3. 29 0
      net/tap-linux.c
  4. 2 0
      net/tap-linux.h
  5. 9 0
      net/tap-solaris.c
  6. 9 0
      net/tap-win32.c
  7. 21 0
      net/tap.c
  8. 4 0
      net/tap.h

+ 9 - 0
net/tap-aix.c

@@ -46,6 +46,15 @@ int tap_probe_has_ufo(int fd)
     return 0;
     return 0;
 }
 }
 
 
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+    return 0;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+}
+
 void tap_fd_set_offload(int fd, int csum, int tso4,
 void tap_fd_set_offload(int fd, int csum, int tso4,
                         int tso6, int ecn, int ufo)
                         int tso6, int ecn, int ufo)
 {
 {

+ 9 - 0
net/tap-bsd.c

@@ -116,6 +116,15 @@ int tap_probe_has_ufo(int fd)
     return 0;
     return 0;
 }
 }
 
 
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+    return 0;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+}
+
 void tap_fd_set_offload(int fd, int csum, int tso4,
 void tap_fd_set_offload(int fd, int csum, int tso4,
                         int tso6, int ecn, int ufo)
                         int tso6, int ecn, int ufo)
 {
 {

+ 29 - 0
net/tap-linux.c

@@ -129,6 +129,35 @@ int tap_probe_has_ufo(int fd)
     return 1;
     return 1;
 }
 }
 
 
+/* Verify that we can assign given length */
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+    int orig;
+    if (ioctl(fd, TUNGETVNETHDRSZ, &orig) == -1) {
+        return 0;
+    }
+    if (ioctl(fd, TUNSETVNETHDRSZ, &len) == -1) {
+        return 0;
+    }
+    /* Restore original length: we can't handle failure. */
+    if (ioctl(fd, TUNSETVNETHDRSZ, &orig) == -1) {
+        fprintf(stderr, "TUNGETVNETHDRSZ ioctl() failed: %s. Exiting.\n",
+                strerror(errno));
+        assert(0);
+        return -errno;
+    }
+    return 1;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+    if (ioctl(fd, TUNSETVNETHDRSZ, &len) == -1) {
+        fprintf(stderr, "TUNSETVNETHDRSZ ioctl() failed: %s. Exiting.\n",
+                strerror(errno));
+        assert(0);
+    }
+}
+
 void tap_fd_set_offload(int fd, int csum, int tso4,
 void tap_fd_set_offload(int fd, int csum, int tso4,
                         int tso6, int ecn, int ufo)
                         int tso6, int ecn, int ufo)
 {
 {

+ 2 - 0
net/tap-linux.h

@@ -27,6 +27,8 @@
 #define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
 #define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
 #define TUNGETIFF      _IOR('T', 210, unsigned int)
 #define TUNGETIFF      _IOR('T', 210, unsigned int)
 #define TUNSETSNDBUF   _IOW('T', 212, int)
 #define TUNSETSNDBUF   _IOW('T', 212, int)
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
+#define TUNSETVNETHDRSZ _IOW('T', 216, int)
 
 
 #endif
 #endif
 
 

+ 9 - 0
net/tap-solaris.c

@@ -212,6 +212,15 @@ int tap_probe_has_ufo(int fd)
     return 0;
     return 0;
 }
 }
 
 
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+    return 0;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+}
+
 void tap_fd_set_offload(int fd, int csum, int tso4,
 void tap_fd_set_offload(int fd, int csum, int tso4,
                         int tso6, int ecn, int ufo)
                         int tso6, int ecn, int ufo)
 {
 {

+ 9 - 0
net/tap-win32.c

@@ -728,6 +728,15 @@ int tap_has_vnet_hdr(VLANClientState *vc)
     return 0;
     return 0;
 }
 }
 
 
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+    return 0;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+}
+
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
 {
 {
 }
 }

+ 21 - 0
net/tap.c

@@ -232,6 +232,27 @@ int tap_has_vnet_hdr(VLANClientState *nc)
     return !!s->host_vnet_hdr_len;
     return !!s->host_vnet_hdr_len;
 }
 }
 
 
+int tap_has_vnet_hdr_len(VLANClientState *nc, int len)
+{
+    TAPState *s = DO_UPCAST(TAPState, nc, nc);
+
+    assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+
+    return tap_probe_vnet_hdr_len(s->fd, len);
+}
+
+void tap_set_vnet_hdr_len(VLANClientState *nc, int len)
+{
+    TAPState *s = DO_UPCAST(TAPState, nc, nc);
+
+    assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+    assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) ||
+           len == sizeof(struct virtio_net_hdr));
+
+    tap_fd_set_vnet_hdr_len(s->fd, len);
+    s->host_vnet_hdr_len = len;
+}
+
 void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr)
 void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr)
 {
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
     TAPState *s = DO_UPCAST(TAPState, nc, nc);

+ 4 - 0
net/tap.h

@@ -40,13 +40,17 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
 
 
 int tap_has_ufo(VLANClientState *vc);
 int tap_has_ufo(VLANClientState *vc);
 int tap_has_vnet_hdr(VLANClientState *vc);
 int tap_has_vnet_hdr(VLANClientState *vc);
+int tap_has_vnet_hdr_len(VLANClientState *vc, int len);
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
 void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn, int ufo);
 void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn, int ufo);
+void tap_set_vnet_hdr_len(VLANClientState *vc, int len);
 
 
 int tap_set_sndbuf(int fd, QemuOpts *opts);
 int tap_set_sndbuf(int fd, QemuOpts *opts);
 int tap_probe_vnet_hdr(int fd);
 int tap_probe_vnet_hdr(int fd);
+int tap_probe_vnet_hdr_len(int fd, int len);
 int tap_probe_has_ufo(int fd);
 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_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_get_fd(VLANClientState *vc);
 int tap_get_fd(VLANClientState *vc);