Skip to content
Permalink
Browse files
driver/net/tun: Added features for USO.
Added support for USO4 and USO6, also added code for new ioctl TUNGETSUPPORTEDOFFLOADS.
For now, to "enable" USO, it's required to set both USO4 and USO6 simultaneously.
USO enables NETIF_F_GSO_UDP_L4.

Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
  • Loading branch information
AndrewAtDaynix authored and intel-lab-lkp committed Jan 25, 2022
1 parent cfa49b7 commit 3c1c2daa10c8eac3d9b546fa8caf99fcb5a40454
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
@@ -940,6 +940,10 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
if (arg & TUN_F_TSO6)
feature_mask |= NETIF_F_TSO6;
}

/* TODO: for now USO4 and USO6 should work simultaneously */
if (arg & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
features |= NETIF_F_GSO_UDP_L4;
}

/* tun/tap driver inverts the usage for TSO offloads, where
@@ -950,7 +954,8 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
* When user space turns off TSO, we turn off GSO/LRO so that
* user-space will not receive TSO frames.
*/
if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6) ||
feature_mask & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
features |= RX_OFFLOADS;
else
features &= ~RX_OFFLOADS;
@@ -979,6 +984,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
unsigned short u;
int __user *sp = argp;
struct sockaddr sa;
unsigned int supported_offloads;
int s;
int ret;

@@ -1074,14 +1080,22 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
case TUNSETOFFLOAD:
/* let the user check for future flags */
if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
TUN_F_TSO_ECN | TUN_F_UFO))
TUN_F_TSO_ECN | TUN_F_UFO |
TUN_F_USO4 | TUN_F_USO6))
return -EINVAL;

rtnl_lock();
ret = set_offload(q, arg);
rtnl_unlock();
return ret;

case TUNGETSUPPORTEDOFFLOADS:
supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
return -EFAULT;
return 0;

case SIOCGIFHWADDR:
rtnl_lock();
tap = tap_get_tap_dev(q);
@@ -185,7 +185,7 @@ struct tun_struct {
struct net_device *dev;
netdev_features_t set_features;
#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
NETIF_F_TSO6)
NETIF_F_TSO6 | NETIF_F_GSO_UDP_L4)

int align;
int vnet_hdr_sz;
@@ -2821,6 +2821,12 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
}

arg &= ~TUN_F_UFO;

/* TODO: for now USO4 and USO6 should work simultaneously */
if (arg & TUN_F_USO4 && arg & TUN_F_USO6) {
features |= NETIF_F_GSO_UDP_L4;
arg &= ~(TUN_F_USO4 | TUN_F_USO6);
}
}

/* This gives the user a way to test for new features in future by
@@ -2991,6 +2997,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
int sndbuf;
int vnet_hdr_sz;
int le;
unsigned int supported_offloads;
int ret;
bool do_notify = false;

@@ -3154,6 +3161,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
case TUNSETOFFLOAD:
ret = set_offload(tun, arg);
break;
case TUNGETSUPPORTEDOFFLOADS:
supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
ret = -EFAULT;
break;

case TUNSETTXFILTER:
/* Can be set only for TAPs */

0 comments on commit 3c1c2da

Please sign in to comment.