When the last rmnet device attached to a real device is removed, the
real device is unregistered from rmnet. As a result, the real device
lookup fails resulting in a warning when the fill_info handler is
called as part of the rmnet device unregistration.
Fix this by returning the rmnet flags as 0 when no real device is
present.
WARNING: CPU: 0 PID: 1779 at net/core/rtnetlink.c:3254
rtmsg_ifinfo_build_skb+0xca/0x10d
Modules linked in:
CPU: 0 PID: 1779 Comm: ip Not tainted
4.16.0-11872-g7ce2367 #1
Stack:
7fe655f0 60371ea3 00000000 00000000
60282bc6 6006b116 7fe65600 60371ee8
7fe65660 6003a68c 00000000 900000000
Call Trace:
[<
6006b116>] ? printk+0x0/0x94
[<
6001f375>] show_stack+0xfe/0x158
[<
60371ea3>] ? dump_stack_print_info+0xe8/0xf1
[<
60282bc6>] ? rtmsg_ifinfo_build_skb+0xca/0x10d
[<
6006b116>] ? printk+0x0/0x94
[<
60371ee8>] dump_stack+0x2a/0x2c
[<
6003a68c>] __warn+0x10e/0x13e
[<
6003a82c>] warn_slowpath_null+0x48/0x4f
[<
60282bc6>] rtmsg_ifinfo_build_skb+0xca/0x10d
[<
60282c4d>] rtmsg_ifinfo_event.part.37+0x1e/0x43
[<
60282c2f>] ? rtmsg_ifinfo_event.part.37+0x0/0x43
[<
60282d03>] rtmsg_ifinfo+0x24/0x28
[<
60264e86>] dev_close_many+0xba/0x119
[<
60282cdf>] ? rtmsg_ifinfo+0x0/0x28
[<
6027c225>] ? rtnl_is_locked+0x0/0x1c
[<
6026ca67>] rollback_registered_many+0x1ae/0x4ae
[<
600314be>] ? unblock_signals+0x0/0xae
[<
6026cdc0>] ? unregister_netdevice_queue+0x19/0xec
[<
6026ceec>] unregister_netdevice_many+0x21/0xa1
[<
6027c765>] rtnl_delete_link+0x3e/0x4e
[<
60280ecb>] rtnl_dellink+0x262/0x29c
[<
6027c241>] ? rtnl_get_link+0x0/0x3e
[<
6027f867>] rtnetlink_rcv_msg+0x235/0x274
Fixes:
be81a85f5f87 ("net: qualcomm: rmnet: Implement fill_info")
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
real_dev = priv->real_dev;
- if (!rmnet_is_real_dev_registered(real_dev))
- return -ENODEV;
-
if (nla_put_u16(skb, IFLA_RMNET_MUX_ID, priv->mux_id))
goto nla_put_failure;
- port = rmnet_get_port_rtnl(real_dev);
+ if (rmnet_is_real_dev_registered(real_dev)) {
+ port = rmnet_get_port_rtnl(real_dev);
+ f.flags = port->data_format;
+ } else {
+ f.flags = 0;
+ }
- f.flags = port->data_format;
f.mask = ~0;
if (nla_put(skb, IFLA_RMNET_FLAGS, sizeof(f), &f))