diff mbox series

[net,v1] dev_ioctl: fix the type of ifr_flags

Message ID 20240911034608.43192-1-atlas.yu@canonical.com (mailing list archive)
State Rejected
Delegated to: Netdev Maintainers
Headers show
Series [net,v1] dev_ioctl: fix the type of ifr_flags | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present fail Series targets non-next tree, but doesn't contain any Fixes tags
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 90 this patch: 90
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 1 maintainers not CCed: kory.maincent@bootlin.com
netdev/build_clang success Errors and warnings before: 1088 this patch: 1088
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 15064 this patch: 15064
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 16 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 3 this patch: 3
netdev/source_inline success Was 0 now: 0

Commit Message

Atlas Yu Sept. 11, 2024, 3:46 a.m. UTC
SIOCxIFFAGS call dev_get_flags/dev_change_flags under the hood, which
take a unsigned int flags instead of short. This mismatch makes it
impossible to get/set IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO that are
beyond 16 bits.

Signed-off-by: Atlas Yu <atlas.yu@canonical.com>
---
 include/uapi/linux/if.h | 2 +-
 net/core/dev_ioctl.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Comments

Stephen Hemminger Sept. 11, 2024, 3:56 a.m. UTC | #1
On Wed, 11 Sep 2024 11:46:08 +0800
Atlas Yu <atlas.yu@canonical.com> wrote:

> diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
> index 797ba2c1562a..b612b6cd7446 100644
> --- a/include/uapi/linux/if.h
> +++ b/include/uapi/linux/if.h
> @@ -244,7 +244,7 @@ struct ifreq {
>  		struct	sockaddr ifru_broadaddr;
>  		struct	sockaddr ifru_netmask;
>  		struct  sockaddr ifru_hwaddr;
> -		short	ifru_flags;
> +		unsigned int	ifru_flags;
>  		int	ifru_ivalue;
>  		int	ifru_mtu;
>  		struct  ifmap ifru_map;

NAK
This breaks userspace ABI. There is no guarantee that
older application correctly zeros the upper flag bits.
Atlas Yu Sept. 11, 2024, 4:20 a.m. UTC | #2
On Wed, Sep 11, 2024 at 11:56 AM
Stephen Hemminger <stephen@networkplumber.org> wrote:
> On Wed, 11 Sep 2024 11:46:08 +0800
> Atlas Yu <atlas.yu@canonical.com> wrote:
> > diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
> > index 797ba2c1562a..b612b6cd7446 100644
> > --- a/include/uapi/linux/if.h
> > +++ b/include/uapi/linux/if.h
> > @@ -244,7 +244,7 @@ struct ifreq {
> >               struct  sockaddr ifru_broadaddr;
> >               struct  sockaddr ifru_netmask;
> >               struct  sockaddr ifru_hwaddr;
> > -             short   ifru_flags;
> > +             unsigned int    ifru_flags;
> >               int     ifru_ivalue;
> >               int     ifru_mtu;
> >               struct  ifmap ifru_map;
>
> NAK
> This breaks userspace ABI. There is no guarantee that
> older application correctly zeros the upper flag bits.

Thanks, any suggestions though? How about introducing
another ioctl request for these extended bits.
Stephen Hemminger Sept. 11, 2024, 5 a.m. UTC | #3
On Wed, 11 Sep 2024 12:17:24 +0800
Atlas Yu <atlas.yu@canonical.com> wrote:

> On Wed, Sep 11, 2024 at 11:56 AM
> Stephen Hemminger <stephen@networkplumber.org> wrote:
> 
> > On Wed, 11 Sep 2024 11:46:08 +0800
> > Atlas Yu <atlas.yu@canonical.com> wrote:  
> > > diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
> > > index 797ba2c1562a..b612b6cd7446 100644
> > > --- a/include/uapi/linux/if.h
> > > +++ b/include/uapi/linux/if.h
> > > @@ -244,7 +244,7 @@ struct ifreq {
> > >               struct  sockaddr ifru_broadaddr;
> > >               struct  sockaddr ifru_netmask;
> > >               struct  sockaddr ifru_hwaddr;
> > > -             short   ifru_flags;
> > > +             unsigned int    ifru_flags;
> > >               int     ifru_ivalue;
> > >               int     ifru_mtu;
> > >               struct  ifmap ifru_map;  
> >
> > NAK
> > This breaks userspace ABI. There is no guarantee that
> > older application correctly zeros the upper flag bits.  
> 
> Thanks, any suggestions though? How about introducing
> another ioctl request for these extended bits.

Doing anything with ioctl's is hard, there are so many layers to deal with.
Mostly, networking has treated ioctl's as legacy API and switched to using
netlink for any new features.
Eric Dumazet Sept. 11, 2024, 7:21 a.m. UTC | #4
On Wed, Sep 11, 2024 at 7:00 AM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Wed, 11 Sep 2024 12:17:24 +0800
> Atlas Yu <atlas.yu@canonical.com> wrote:
>
> > On Wed, Sep 11, 2024 at 11:56 AM
> > Stephen Hemminger <stephen@networkplumber.org> wrote:
> >
> > > On Wed, 11 Sep 2024 11:46:08 +0800
> > > Atlas Yu <atlas.yu@canonical.com> wrote:
> > > > diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
> > > > index 797ba2c1562a..b612b6cd7446 100644
> > > > --- a/include/uapi/linux/if.h
> > > > +++ b/include/uapi/linux/if.h
> > > > @@ -244,7 +244,7 @@ struct ifreq {
> > > >               struct  sockaddr ifru_broadaddr;
> > > >               struct  sockaddr ifru_netmask;
> > > >               struct  sockaddr ifru_hwaddr;
> > > > -             short   ifru_flags;
> > > > +             unsigned int    ifru_flags;
> > > >               int     ifru_ivalue;
> > > >               int     ifru_mtu;
> > > >               struct  ifmap ifru_map;
> > >
> > > NAK
> > > This breaks userspace ABI. There is no guarantee that
> > > older application correctly zeros the upper flag bits.
> >
> > Thanks, any suggestions though? How about introducing
> > another ioctl request for these extended bits.
>
> Doing anything with ioctl's is hard, there are so many layers to deal with.
> Mostly, networking has treated ioctl's as legacy API and switched to using
> netlink for any new features.

Note that rtnetlink gets the 32bit flags already, this has been the
case for 20 years or more.

include/uapi/linux/rtnetlink.h:566:     unsigned        ifi_flags;
         /* IFF_* flags  */

net/core/rtnetlink.c  : rtnl_fill_ifinfo(...)

ifm->ifi_flags = dev_get_flags(dev);

iproute2 also displays more than 16 bits in print_link_flags()
Atlas Yu Sept. 11, 2024, 8:30 a.m. UTC | #5
> On Wed, Sep 11, 2024 at 3:21 PM
> Eric Dumazet <edumazet@google.com> wrote:
> 
> Note that rtnetlink gets the 32bit flags already, this has been the
> case for 20 years or more.
> 
> include/uapi/linux/rtnetlink.h:566:     unsigned        ifi_flags;
>          /* IFF_* flags  */
> 
> net/core/rtnetlink.c  : rtnl_fill_ifinfo(...)
> 
> ifm->ifi_flags = dev_get_flags(dev);
> 
> iproute2 also displays more than 16 bits in print_link_flags()

Thank you Eric, I am switching to the netlink API for my use case.
diff mbox series

Patch

diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
index 797ba2c1562a..b612b6cd7446 100644
--- a/include/uapi/linux/if.h
+++ b/include/uapi/linux/if.h
@@ -244,7 +244,7 @@  struct ifreq {
 		struct	sockaddr ifru_broadaddr;
 		struct	sockaddr ifru_netmask;
 		struct  sockaddr ifru_hwaddr;
-		short	ifru_flags;
+		unsigned int	ifru_flags;
 		int	ifru_ivalue;
 		int	ifru_mtu;
 		struct  ifmap ifru_map;
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 8592c052c0f4..4b317561e503 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -145,7 +145,7 @@  static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cm
 
 	switch (cmd) {
 	case SIOCGIFFLAGS:	/* Get interface flags */
-		ifr->ifr_flags = (short) dev_get_flags(dev);
+		ifr->ifr_flags = dev_get_flags(dev);
 		return 0;
 
 	case SIOCGIFMETRIC:	/* Get the metric on the interface