Willem de Bruijn wrote: > Akihiko Odaki wrote: > > Decouple vnet-related functions from tun_struct so that we can reuse > > them for tap in the future. > > > > Signed-off-by: Akihiko Odaki <akihiko.odaki@xxxxxxxxxx> > > --- > > drivers/net/tun.c | 53 +++++++++++++++++++++++++++-------------------------- > > 1 file changed, 27 insertions(+), 26 deletions(-) > > > > diff --git a/drivers/net/tun.c b/drivers/net/tun.c > > index ec56ac865848..add09dfdada5 100644 > > --- a/drivers/net/tun.c > > +++ b/drivers/net/tun.c > > @@ -298,16 +298,16 @@ static bool tun_napi_frags_enabled(const struct tun_file *tfile) > > return tfile->napi_frags_enabled; > > } > > > > -static inline bool tun_legacy_is_little_endian(struct tun_struct *tun) > > +static inline bool tun_legacy_is_little_endian(unsigned int flags) > > { > > return !(IS_ENABLED(CONFIG_TUN_VNET_CROSS_LE) && > > - (tun->flags & TUN_VNET_BE)) && > > + (flags & TUN_VNET_BE)) && > > virtio_legacy_is_little_endian(); > > } > > > > -static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp) > > +static long tun_get_vnet_be(unsigned int flags, int __user *argp) > > { > > - int be = !!(tun->flags & TUN_VNET_BE); > > + int be = !!(flags & TUN_VNET_BE); > > > > if (!IS_ENABLED(CONFIG_TUN_VNET_CROSS_LE)) > > return -EINVAL; > > @@ -318,7 +318,7 @@ static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp) > > return 0; > > } > > > > -static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp) > > +static long tun_set_vnet_be(unsigned int *flags, int __user *argp) > > { > > int be; > > > > @@ -329,27 +329,26 @@ static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp) > > return -EFAULT; > > > > if (be) > > - tun->flags |= TUN_VNET_BE; > > + *flags |= TUN_VNET_BE; > > else > > - tun->flags &= ~TUN_VNET_BE; > > + *flags &= ~TUN_VNET_BE; > > > > return 0; > > } > > > > -static inline bool tun_is_little_endian(struct tun_struct *tun) > > +static inline bool tun_is_little_endian(unsigned int flags) > > { > > - return tun->flags & TUN_VNET_LE || > > - tun_legacy_is_little_endian(tun); > > + return flags & TUN_VNET_LE || tun_legacy_is_little_endian(flags); > > } > > > > -static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val) > > +static inline u16 tun16_to_cpu(unsigned int flags, __virtio16 val) > > { > > - return __virtio16_to_cpu(tun_is_little_endian(tun), val); > > + return __virtio16_to_cpu(tun_is_little_endian(flags), val); > > } > > > > -static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) > > +static inline __virtio16 cpu_to_tun16(unsigned int flags, u16 val) > > { > > - return __cpu_to_virtio16(tun_is_little_endian(tun), val); > > + return __cpu_to_virtio16(tun_is_little_endian(flags), val); > > } > > > > static inline u32 tun_hashfn(u32 rxhash) > > @@ -1764,6 +1763,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, > > > > if (tun->flags & IFF_VNET_HDR) { > > int vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz); > > + int flags = tun->flags; > > Here and elsewhere: instead of passing around and repeatedly parsing > flags, have a variable is_little_endian (or is_le)? I guess this will not work everywhere, because endianness is not a boolean flag.. Code checks both TUN_VNET_LE and TUN_VNET_BE.