diff mbox series

[1/4] tap: Added USO support to tap device.

Message ID 20230719152139.1316570-2-yuri.benditovich@daynix.com (mailing list archive)
State New, archived
Headers show
Series virtio-net: add USO feature (UDP segmentation offload) | expand

Commit Message

Yuri Benditovich July 19, 2023, 3:21 p.m. UTC
From: Andrew Melnychenko <andrew@daynix.com>

Passing additional parameters (USOv4 and USOv6 offloads) when
setting TAP offloads

Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
---
 hw/net/e1000e_core.c |  2 +-
 hw/net/igb_core.c    |  2 +-
 hw/net/virtio-net.c  |  4 +++-
 hw/net/vmxnet3.c     |  2 ++
 include/net/net.h    |  4 ++--
 net/net.c            |  4 ++--
 net/tap-bsd.c        |  2 +-
 net/tap-linux.c      | 15 ++++++++++++---
 net/tap-linux.h      |  2 ++
 net/tap-solaris.c    |  2 +-
 net/tap-stub.c       |  2 +-
 net/tap-win32.c      |  2 +-
 net/tap.c            |  6 +++---
 net/tap_int.h        |  3 ++-
 14 files changed, 34 insertions(+), 18 deletions(-)

Comments

Akihiko Odaki July 20, 2023, 12:31 a.m. UTC | #1
Nitpicking: the subject of this patch is somewhat unconventional. What 
about: "tap: Add USO support to tap device"?

On 2023/07/20 0:21, Yuri Benditovich wrote:
> From: Andrew Melnychenko <andrew@daynix.com>
> 
> Passing additional parameters (USOv4 and USOv6 offloads) when
> setting TAP offloads
> 
> Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
> Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> ---
>   hw/net/e1000e_core.c |  2 +-
>   hw/net/igb_core.c    |  2 +-
>   hw/net/virtio-net.c  |  4 +++-
>   hw/net/vmxnet3.c     |  2 ++
>   include/net/net.h    |  4 ++--
>   net/net.c            |  4 ++--
>   net/tap-bsd.c        |  2 +-
>   net/tap-linux.c      | 15 ++++++++++++---
>   net/tap-linux.h      |  2 ++
>   net/tap-solaris.c    |  2 +-
>   net/tap-stub.c       |  2 +-
>   net/tap-win32.c      |  2 +-
>   net/tap.c            |  6 +++---
>   net/tap_int.h        |  3 ++-
>   14 files changed, 34 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
> index f8aeafa16b..d4055956ad 100644
> --- a/hw/net/e1000e_core.c
> +++ b/hw/net/e1000e_core.c
> @@ -2852,7 +2852,7 @@ e1000e_update_rx_offloads(E1000ECore *core)
>   
>       if (core->has_vnet) {
>           qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
> -                         cso_state, 0, 0, 0, 0);
> +                         cso_state, 0, 0, 0, 0, 0, 0);
>       }
>   }
>   
> diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
> index 8b6b75c522..389eef1549 100644
> --- a/hw/net/igb_core.c
> +++ b/hw/net/igb_core.c
> @@ -2753,7 +2753,7 @@ igb_update_rx_offloads(IGBCore *core)
>   
>       if (core->has_vnet) {
>           qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
> -                         cso_state, 0, 0, 0, 0);
> +                         cso_state, 0, 0, 0, 0, 0, 0);
>       }
>   }
>   
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 7102ec4817..d2311e7d6e 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -859,7 +859,9 @@ static void virtio_net_apply_guest_offloads(VirtIONet *n)
>               !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
>               !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
>               !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
> -            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
> +            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)),
> +            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO4)),
> +            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO6)));
>   }
>   
>   static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
> diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
> index 5dfacb1098..886adae42b 100644
> --- a/hw/net/vmxnet3.c
> +++ b/hw/net/vmxnet3.c
> @@ -1341,6 +1341,8 @@ static void vmxnet3_update_features(VMXNET3State *s)
>                            s->lro_supported,
>                            s->lro_supported,
>                            0,
> +                         0,
> +                         0,
>                            0);
>       }
>   }
> diff --git a/include/net/net.h b/include/net/net.h
> index 1448d00afb..b5ccfbbffb 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -58,7 +58,7 @@ typedef bool (HasVnetHdr)(NetClientState *);
>   typedef bool (HasVnetHdrLen)(NetClientState *, int);
>   typedef bool (GetUsingVnetHdr)(NetClientState *);
>   typedef void (UsingVnetHdr)(NetClientState *, bool);
> -typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
> +typedef void (SetOffload)(NetClientState *, int, int, int, int, int, int, int);
>   typedef int (GetVnetHdrLen)(NetClientState *);
>   typedef void (SetVnetHdrLen)(NetClientState *, int);
>   typedef int (SetVnetLE)(NetClientState *, bool);
> @@ -192,7 +192,7 @@ bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
>   bool qemu_get_using_vnet_hdr(NetClientState *nc);
>   void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
>   void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
> -                      int ecn, int ufo);
> +                      int ecn, int ufo, int uso4, int uso6);
>   int qemu_get_vnet_hdr_len(NetClientState *nc);
>   void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
>   int qemu_set_vnet_le(NetClientState *nc, bool is_le);
> diff --git a/net/net.c b/net/net.c
> index 6492ad530e..543e6dec43 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -532,13 +532,13 @@ void qemu_using_vnet_hdr(NetClientState *nc, bool enable)
>   }
>   
>   void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
> -                          int ecn, int ufo)
> +                          int ecn, int ufo, int uso4, int uso6)
>   {
>       if (!nc || !nc->info->set_offload) {
>           return;
>       }
>   
> -    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
> +    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo, uso4, uso6);
>   }
>   
>   int qemu_get_vnet_hdr_len(NetClientState *nc)
> diff --git a/net/tap-bsd.c b/net/tap-bsd.c
> index 4c98fdd337..abd16a2ad2 100644
> --- a/net/tap-bsd.c
> +++ b/net/tap-bsd.c
> @@ -232,7 +232,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
>   }
>   
>   void tap_fd_set_offload(int fd, int csum, int tso4,
> -                        int tso6, int ecn, int ufo)
> +                        int tso6, int ecn, int ufo, int uso4, int uso6)
>   {
>   }
>   
> diff --git a/net/tap-linux.c b/net/tap-linux.c
> index f54f308d35..30fcca1bc2 100644
> --- a/net/tap-linux.c
> +++ b/net/tap-linux.c
> @@ -237,7 +237,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
>   }
>   
>   void tap_fd_set_offload(int fd, int csum, int tso4,
> -                        int tso6, int ecn, int ufo)
> +                        int tso6, int ecn, int ufo, int uso4, int uso6)
>   {
>       unsigned int offload = 0;
>   
> @@ -256,13 +256,22 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
>               offload |= TUN_F_TSO_ECN;
>           if (ufo)
>               offload |= TUN_F_UFO;
> +        if (uso4) {
> +            offload |= TUN_F_USO4;
> +        }
> +        if (uso6) {
> +            offload |= TUN_F_USO6;
> +        }
>       }
>   
>       if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> -        offload &= ~TUN_F_UFO;
> +        offload &= ~(TUN_F_USO4 | TUN_F_USO6);

Shouldn't we just report an error when USO is requested on a system that 
does not support it?

>           if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> -            fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
> +            offload &= ~TUN_F_UFO;
> +            if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> +                fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
>                       strerror(errno));
> +            }
>           }
>       }
>   }
> diff --git a/net/tap-linux.h b/net/tap-linux.h
> index bbbb62c2a7..9a58cecb7f 100644
> --- a/net/tap-linux.h
> +++ b/net/tap-linux.h
> @@ -50,5 +50,7 @@
>   #define TUN_F_TSO6    0x04    /* I can handle TSO for IPv6 packets */
>   #define TUN_F_TSO_ECN 0x08    /* I can handle TSO with ECN bits. */
>   #define TUN_F_UFO     0x10    /* I can handle UFO packets */
> +#define TUN_F_USO4    0x20    /* I can handle USO for IPv4 packets */
> +#define TUN_F_USO6    0x40    /* I can handle USO for IPv6 packets */
>   
>   #endif /* QEMU_TAP_LINUX_H */
> diff --git a/net/tap-solaris.c b/net/tap-solaris.c
> index 38e15028bf..a617a10e5c 100644
> --- a/net/tap-solaris.c
> +++ b/net/tap-solaris.c
> @@ -236,7 +236,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
>   }
>   
>   void tap_fd_set_offload(int fd, int csum, int tso4,
> -                        int tso6, int ecn, int ufo)
> +                        int tso6, int ecn, int ufo, int uso4, int uso6)
>   {
>   }
>   
> diff --git a/net/tap-stub.c b/net/tap-stub.c
> index a0fa25804b..ac8dfc03b4 100644
> --- a/net/tap-stub.c
> +++ b/net/tap-stub.c
> @@ -67,7 +67,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
>   }
>   
>   void tap_fd_set_offload(int fd, int csum, int tso4,
> -                        int tso6, int ecn, int ufo)
> +                        int tso6, int ecn, int ufo, int uso4, int uso6)
>   {
>   }
>   
> diff --git a/net/tap-win32.c b/net/tap-win32.c
> index f327d62ab0..7b8b4be02c 100644
> --- a/net/tap-win32.c
> +++ b/net/tap-win32.c
> @@ -741,7 +741,7 @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
>   }
>   
>   static void tap_set_offload(NetClientState *nc, int csum, int tso4,
> -                     int tso6, int ecn, int ufo)
> +                     int tso6, int ecn, int ufo, int uso4, int uso6)
>   {
>   }
>   
> diff --git a/net/tap.c b/net/tap.c
> index 1bf085d422..14ea4ef26f 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -307,14 +307,14 @@ static int tap_set_vnet_be(NetClientState *nc, bool is_be)
>   }
>   
>   static void tap_set_offload(NetClientState *nc, int csum, int tso4,
> -                     int tso6, int ecn, int ufo)
> +                     int tso6, int ecn, int ufo, int uso4, int uso6)
>   {
>       TAPState *s = DO_UPCAST(TAPState, nc, nc);
>       if (s->fd < 0) {
>           return;
>       }
>   
> -    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
> +    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo, uso4, uso6);
>   }
>   
>   static void tap_exit_notify(Notifier *notifier, void *data)
> @@ -414,7 +414,7 @@ static TAPState *net_tap_fd_init(NetClientState *peer,
>       s->using_vnet_hdr = false;
>       s->has_ufo = tap_probe_has_ufo(s->fd);
>       s->enabled = true;
> -    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
> +    tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
>       /*
>        * Make sure host header length is set correctly in tap:
>        * it might have been modified by another instance of qemu.
> diff --git a/net/tap_int.h b/net/tap_int.h
> index 547f8a5a28..d8861d81ba 100644
> --- a/net/tap_int.h
> +++ b/net/tap_int.h
> @@ -37,7 +37,8 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
>   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);
> +void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
> +                        int uso4, int uso6);
>   void tap_fd_set_vnet_hdr_len(int fd, int len);
>   int tap_fd_set_vnet_le(int fd, int vnet_is_le);
>   int tap_fd_set_vnet_be(int fd, int vnet_is_be);
Yuri Benditovich July 20, 2023, 3:53 p.m. UTC | #2
On Thu, Jul 20, 2023 at 3:31 AM Akihiko Odaki <akihiko.odaki@daynix.com>
wrote:

> Nitpicking: the subject of this patch is somewhat unconventional. What
> about: "tap: Add USO support to tap device"?
>
> Will take it in account in v2


> On 2023/07/20 0:21, Yuri Benditovich wrote:
> > From: Andrew Melnychenko <andrew@daynix.com>
> >
> > Passing additional parameters (USOv4 and USOv6 offloads) when
> > setting TAP offloads
> >
> > Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
> > Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> > ---
> >   hw/net/e1000e_core.c |  2 +-
> >   hw/net/igb_core.c    |  2 +-
> >   hw/net/virtio-net.c  |  4 +++-
> >   hw/net/vmxnet3.c     |  2 ++
> >   include/net/net.h    |  4 ++--
> >   net/net.c            |  4 ++--
> >   net/tap-bsd.c        |  2 +-
> >   net/tap-linux.c      | 15 ++++++++++++---
> >   net/tap-linux.h      |  2 ++
> >   net/tap-solaris.c    |  2 +-
> >   net/tap-stub.c       |  2 +-
> >   net/tap-win32.c      |  2 +-
> >   net/tap.c            |  6 +++---
> >   net/tap_int.h        |  3 ++-
> >   14 files changed, 34 insertions(+), 18 deletions(-)
> >
> > diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
> > index f8aeafa16b..d4055956ad 100644
> > --- a/hw/net/e1000e_core.c
> > +++ b/hw/net/e1000e_core.c
> > @@ -2852,7 +2852,7 @@ e1000e_update_rx_offloads(E1000ECore *core)
> >
> >       if (core->has_vnet) {
> >           qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
> > -                         cso_state, 0, 0, 0, 0);
> > +                         cso_state, 0, 0, 0, 0, 0, 0);
> >       }
> >   }
> >
> > diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
> > index 8b6b75c522..389eef1549 100644
> > --- a/hw/net/igb_core.c
> > +++ b/hw/net/igb_core.c
> > @@ -2753,7 +2753,7 @@ igb_update_rx_offloads(IGBCore *core)
> >
> >       if (core->has_vnet) {
> >           qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
> > -                         cso_state, 0, 0, 0, 0);
> > +                         cso_state, 0, 0, 0, 0, 0, 0);
> >       }
> >   }
> >
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index 7102ec4817..d2311e7d6e 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -859,7 +859,9 @@ static void
> virtio_net_apply_guest_offloads(VirtIONet *n)
> >               !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_TSO4)),
> >               !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_TSO6)),
> >               !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_ECN)),
> > -            !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_UFO)));
> > +            !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_UFO)),
> > +            !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_USO4)),
> > +            !!(n->curr_guest_offloads & (1ULL <<
> VIRTIO_NET_F_GUEST_USO6)));
> >   }
> >
> >   static uint64_t virtio_net_guest_offloads_by_features(uint32_t
> features)
> > diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
> > index 5dfacb1098..886adae42b 100644
> > --- a/hw/net/vmxnet3.c
> > +++ b/hw/net/vmxnet3.c
> > @@ -1341,6 +1341,8 @@ static void vmxnet3_update_features(VMXNET3State
> *s)
> >                            s->lro_supported,
> >                            s->lro_supported,
> >                            0,
> > +                         0,
> > +                         0,
> >                            0);
> >       }
> >   }
> > diff --git a/include/net/net.h b/include/net/net.h
> > index 1448d00afb..b5ccfbbffb 100644
> > --- a/include/net/net.h
> > +++ b/include/net/net.h
> > @@ -58,7 +58,7 @@ typedef bool (HasVnetHdr)(NetClientState *);
> >   typedef bool (HasVnetHdrLen)(NetClientState *, int);
> >   typedef bool (GetUsingVnetHdr)(NetClientState *);
> >   typedef void (UsingVnetHdr)(NetClientState *, bool);
> > -typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
> > +typedef void (SetOffload)(NetClientState *, int, int, int, int, int,
> int, int);
> >   typedef int (GetVnetHdrLen)(NetClientState *);
> >   typedef void (SetVnetHdrLen)(NetClientState *, int);
> >   typedef int (SetVnetLE)(NetClientState *, bool);
> > @@ -192,7 +192,7 @@ bool qemu_has_vnet_hdr_len(NetClientState *nc, int
> len);
> >   bool qemu_get_using_vnet_hdr(NetClientState *nc);
> >   void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
> >   void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
> > -                      int ecn, int ufo);
> > +                      int ecn, int ufo, int uso4, int uso6);
> >   int qemu_get_vnet_hdr_len(NetClientState *nc);
> >   void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
> >   int qemu_set_vnet_le(NetClientState *nc, bool is_le);
> > diff --git a/net/net.c b/net/net.c
> > index 6492ad530e..543e6dec43 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -532,13 +532,13 @@ void qemu_using_vnet_hdr(NetClientState *nc, bool
> enable)
> >   }
> >
> >   void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
> > -                          int ecn, int ufo)
> > +                          int ecn, int ufo, int uso4, int uso6)
> >   {
> >       if (!nc || !nc->info->set_offload) {
> >           return;
> >       }
> >
> > -    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
> > +    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo, uso4, uso6);
> >   }
> >
> >   int qemu_get_vnet_hdr_len(NetClientState *nc)
> > diff --git a/net/tap-bsd.c b/net/tap-bsd.c
> > index 4c98fdd337..abd16a2ad2 100644
> > --- a/net/tap-bsd.c
> > +++ b/net/tap-bsd.c
> > @@ -232,7 +232,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
> >   }
> >
> >   void tap_fd_set_offload(int fd, int csum, int tso4,
> > -                        int tso6, int ecn, int ufo)
> > +                        int tso6, int ecn, int ufo, int uso4, int uso6)
> >   {
> >   }
> >
> > diff --git a/net/tap-linux.c b/net/tap-linux.c
> > index f54f308d35..30fcca1bc2 100644
> > --- a/net/tap-linux.c
> > +++ b/net/tap-linux.c
> > @@ -237,7 +237,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
> >   }
> >
> >   void tap_fd_set_offload(int fd, int csum, int tso4,
> > -                        int tso6, int ecn, int ufo)
> > +                        int tso6, int ecn, int ufo, int uso4, int uso6)
> >   {
> >       unsigned int offload = 0;
> >
> > @@ -256,13 +256,22 @@ void tap_fd_set_offload(int fd, int csum, int tso4,
> >               offload |= TUN_F_TSO_ECN;
> >           if (ufo)
> >               offload |= TUN_F_UFO;
> > +        if (uso4) {
> > +            offload |= TUN_F_USO4;
> > +        }
> > +        if (uso6) {
> > +            offload |= TUN_F_USO6;
> > +        }
> >       }
> >
> >       if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> > -        offload &= ~TUN_F_UFO;
> > +        offload &= ~(TUN_F_USO4 | TUN_F_USO6);
>
> Shouldn't we just report an error when USO is requested on a system that
> does not support it?
>

Existing approach to non-critical features is silently drop them when not
supported by the kernel


>
> >           if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> > -            fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
> > +            offload &= ~TUN_F_UFO;
> > +            if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> > +                fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
> >                       strerror(errno));
> > +            }
> >           }
> >       }
> >   }
> > diff --git a/net/tap-linux.h b/net/tap-linux.h
> > index bbbb62c2a7..9a58cecb7f 100644
> > --- a/net/tap-linux.h
> > +++ b/net/tap-linux.h
> > @@ -50,5 +50,7 @@
> >   #define TUN_F_TSO6    0x04    /* I can handle TSO for IPv6 packets */
> >   #define TUN_F_TSO_ECN 0x08    /* I can handle TSO with ECN bits. */
> >   #define TUN_F_UFO     0x10    /* I can handle UFO packets */
> > +#define TUN_F_USO4    0x20    /* I can handle USO for IPv4 packets */
> > +#define TUN_F_USO6    0x40    /* I can handle USO for IPv6 packets */
> >
> >   #endif /* QEMU_TAP_LINUX_H */
> > diff --git a/net/tap-solaris.c b/net/tap-solaris.c
> > index 38e15028bf..a617a10e5c 100644
> > --- a/net/tap-solaris.c
> > +++ b/net/tap-solaris.c
> > @@ -236,7 +236,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
> >   }
> >
> >   void tap_fd_set_offload(int fd, int csum, int tso4,
> > -                        int tso6, int ecn, int ufo)
> > +                        int tso6, int ecn, int ufo, int uso4, int uso6)
> >   {
> >   }
> >
> > diff --git a/net/tap-stub.c b/net/tap-stub.c
> > index a0fa25804b..ac8dfc03b4 100644
> > --- a/net/tap-stub.c
> > +++ b/net/tap-stub.c
> > @@ -67,7 +67,7 @@ int tap_fd_set_vnet_be(int fd, int is_be)
> >   }
> >
> >   void tap_fd_set_offload(int fd, int csum, int tso4,
> > -                        int tso6, int ecn, int ufo)
> > +                        int tso6, int ecn, int ufo, int uso4, int uso6)
> >   {
> >   }
> >
> > diff --git a/net/tap-win32.c b/net/tap-win32.c
> > index f327d62ab0..7b8b4be02c 100644
> > --- a/net/tap-win32.c
> > +++ b/net/tap-win32.c
> > @@ -741,7 +741,7 @@ static void tap_using_vnet_hdr(NetClientState *nc,
> bool using_vnet_hdr)
> >   }
> >
> >   static void tap_set_offload(NetClientState *nc, int csum, int tso4,
> > -                     int tso6, int ecn, int ufo)
> > +                     int tso6, int ecn, int ufo, int uso4, int uso6)
> >   {
> >   }
> >
> > diff --git a/net/tap.c b/net/tap.c
> > index 1bf085d422..14ea4ef26f 100644
> > --- a/net/tap.c
> > +++ b/net/tap.c
> > @@ -307,14 +307,14 @@ static int tap_set_vnet_be(NetClientState *nc,
> bool is_be)
> >   }
> >
> >   static void tap_set_offload(NetClientState *nc, int csum, int tso4,
> > -                     int tso6, int ecn, int ufo)
> > +                     int tso6, int ecn, int ufo, int uso4, int uso6)
> >   {
> >       TAPState *s = DO_UPCAST(TAPState, nc, nc);
> >       if (s->fd < 0) {
> >           return;
> >       }
> >
> > -    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
> > +    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo, uso4, uso6);
> >   }
> >
> >   static void tap_exit_notify(Notifier *notifier, void *data)
> > @@ -414,7 +414,7 @@ static TAPState *net_tap_fd_init(NetClientState
> *peer,
> >       s->using_vnet_hdr = false;
> >       s->has_ufo = tap_probe_has_ufo(s->fd);
> >       s->enabled = true;
> > -    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
> > +    tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
> >       /*
> >        * Make sure host header length is set correctly in tap:
> >        * it might have been modified by another instance of qemu.
> > diff --git a/net/tap_int.h b/net/tap_int.h
> > index 547f8a5a28..d8861d81ba 100644
> > --- a/net/tap_int.h
> > +++ b/net/tap_int.h
> > @@ -37,7 +37,8 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions
> *tap, Error **errp);
> >   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);
> > +void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn,
> int ufo,
> > +                        int uso4, int uso6);
> >   void tap_fd_set_vnet_hdr_len(int fd, int len);
> >   int tap_fd_set_vnet_le(int fd, int vnet_is_le);
> >   int tap_fd_set_vnet_be(int fd, int vnet_is_be);
>
diff mbox series

Patch

diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index f8aeafa16b..d4055956ad 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -2852,7 +2852,7 @@  e1000e_update_rx_offloads(E1000ECore *core)
 
     if (core->has_vnet) {
         qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
-                         cso_state, 0, 0, 0, 0);
+                         cso_state, 0, 0, 0, 0, 0, 0);
     }
 }
 
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
index 8b6b75c522..389eef1549 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -2753,7 +2753,7 @@  igb_update_rx_offloads(IGBCore *core)
 
     if (core->has_vnet) {
         qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
-                         cso_state, 0, 0, 0, 0);
+                         cso_state, 0, 0, 0, 0, 0, 0);
     }
 }
 
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 7102ec4817..d2311e7d6e 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -859,7 +859,9 @@  static void virtio_net_apply_guest_offloads(VirtIONet *n)
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
-            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO4)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO6)));
 }
 
 static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 5dfacb1098..886adae42b 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -1341,6 +1341,8 @@  static void vmxnet3_update_features(VMXNET3State *s)
                          s->lro_supported,
                          s->lro_supported,
                          0,
+                         0,
+                         0,
                          0);
     }
 }
diff --git a/include/net/net.h b/include/net/net.h
index 1448d00afb..b5ccfbbffb 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -58,7 +58,7 @@  typedef bool (HasVnetHdr)(NetClientState *);
 typedef bool (HasVnetHdrLen)(NetClientState *, int);
 typedef bool (GetUsingVnetHdr)(NetClientState *);
 typedef void (UsingVnetHdr)(NetClientState *, bool);
-typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
+typedef void (SetOffload)(NetClientState *, int, int, int, int, int, int, int);
 typedef int (GetVnetHdrLen)(NetClientState *);
 typedef void (SetVnetHdrLen)(NetClientState *, int);
 typedef int (SetVnetLE)(NetClientState *, bool);
@@ -192,7 +192,7 @@  bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
 bool qemu_get_using_vnet_hdr(NetClientState *nc);
 void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
 void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
-                      int ecn, int ufo);
+                      int ecn, int ufo, int uso4, int uso6);
 int qemu_get_vnet_hdr_len(NetClientState *nc);
 void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
 int qemu_set_vnet_le(NetClientState *nc, bool is_le);
diff --git a/net/net.c b/net/net.c
index 6492ad530e..543e6dec43 100644
--- a/net/net.c
+++ b/net/net.c
@@ -532,13 +532,13 @@  void qemu_using_vnet_hdr(NetClientState *nc, bool enable)
 }
 
 void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
-                          int ecn, int ufo)
+                          int ecn, int ufo, int uso4, int uso6)
 {
     if (!nc || !nc->info->set_offload) {
         return;
     }
 
-    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
+    nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo, uso4, uso6);
 }
 
 int qemu_get_vnet_hdr_len(NetClientState *nc)
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 4c98fdd337..abd16a2ad2 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -232,7 +232,7 @@  int tap_fd_set_vnet_be(int fd, int is_be)
 }
 
 void tap_fd_set_offload(int fd, int csum, int tso4,
-                        int tso6, int ecn, int ufo)
+                        int tso6, int ecn, int ufo, int uso4, int uso6)
 {
 }
 
diff --git a/net/tap-linux.c b/net/tap-linux.c
index f54f308d35..30fcca1bc2 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -237,7 +237,7 @@  int tap_fd_set_vnet_be(int fd, int is_be)
 }
 
 void tap_fd_set_offload(int fd, int csum, int tso4,
-                        int tso6, int ecn, int ufo)
+                        int tso6, int ecn, int ufo, int uso4, int uso6)
 {
     unsigned int offload = 0;
 
@@ -256,13 +256,22 @@  void tap_fd_set_offload(int fd, int csum, int tso4,
             offload |= TUN_F_TSO_ECN;
         if (ufo)
             offload |= TUN_F_UFO;
+        if (uso4) {
+            offload |= TUN_F_USO4;
+        }
+        if (uso6) {
+            offload |= TUN_F_USO6;
+        }
     }
 
     if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
-        offload &= ~TUN_F_UFO;
+        offload &= ~(TUN_F_USO4 | TUN_F_USO6);
         if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
-            fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
+            offload &= ~TUN_F_UFO;
+            if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
+                fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
                     strerror(errno));
+            }
         }
     }
 }
diff --git a/net/tap-linux.h b/net/tap-linux.h
index bbbb62c2a7..9a58cecb7f 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -50,5 +50,7 @@ 
 #define TUN_F_TSO6    0x04    /* I can handle TSO for IPv6 packets */
 #define TUN_F_TSO_ECN 0x08    /* I can handle TSO with ECN bits. */
 #define TUN_F_UFO     0x10    /* I can handle UFO packets */
+#define TUN_F_USO4    0x20    /* I can handle USO for IPv4 packets */
+#define TUN_F_USO6    0x40    /* I can handle USO for IPv6 packets */
 
 #endif /* QEMU_TAP_LINUX_H */
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index 38e15028bf..a617a10e5c 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -236,7 +236,7 @@  int tap_fd_set_vnet_be(int fd, int is_be)
 }
 
 void tap_fd_set_offload(int fd, int csum, int tso4,
-                        int tso6, int ecn, int ufo)
+                        int tso6, int ecn, int ufo, int uso4, int uso6)
 {
 }
 
diff --git a/net/tap-stub.c b/net/tap-stub.c
index a0fa25804b..ac8dfc03b4 100644
--- a/net/tap-stub.c
+++ b/net/tap-stub.c
@@ -67,7 +67,7 @@  int tap_fd_set_vnet_be(int fd, int is_be)
 }
 
 void tap_fd_set_offload(int fd, int csum, int tso4,
-                        int tso6, int ecn, int ufo)
+                        int tso6, int ecn, int ufo, int uso4, int uso6)
 {
 }
 
diff --git a/net/tap-win32.c b/net/tap-win32.c
index f327d62ab0..7b8b4be02c 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -741,7 +741,7 @@  static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
 }
 
 static void tap_set_offload(NetClientState *nc, int csum, int tso4,
-                     int tso6, int ecn, int ufo)
+                     int tso6, int ecn, int ufo, int uso4, int uso6)
 {
 }
 
diff --git a/net/tap.c b/net/tap.c
index 1bf085d422..14ea4ef26f 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -307,14 +307,14 @@  static int tap_set_vnet_be(NetClientState *nc, bool is_be)
 }
 
 static void tap_set_offload(NetClientState *nc, int csum, int tso4,
-                     int tso6, int ecn, int ufo)
+                     int tso6, int ecn, int ufo, int uso4, int uso6)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
     if (s->fd < 0) {
         return;
     }
 
-    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
+    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo, uso4, uso6);
 }
 
 static void tap_exit_notify(Notifier *notifier, void *data)
@@ -414,7 +414,7 @@  static TAPState *net_tap_fd_init(NetClientState *peer,
     s->using_vnet_hdr = false;
     s->has_ufo = tap_probe_has_ufo(s->fd);
     s->enabled = true;
-    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
+    tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
     /*
      * Make sure host header length is set correctly in tap:
      * it might have been modified by another instance of qemu.
diff --git a/net/tap_int.h b/net/tap_int.h
index 547f8a5a28..d8861d81ba 100644
--- a/net/tap_int.h
+++ b/net/tap_int.h
@@ -37,7 +37,8 @@  void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
 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);
+void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
+                        int uso4, int uso6);
 void tap_fd_set_vnet_hdr_len(int fd, int len);
 int tap_fd_set_vnet_le(int fd, int vnet_is_le);
 int tap_fd_set_vnet_be(int fd, int vnet_is_be);