netdevice reg_state was split into two 16 bit enums back in 2010
in commit 
a2835763e130 ("rtnetlink: handle rtnl_link netlink
notifications manually"). Since the split the fields have been
moved apart, and last year we converted reg_state to a normal
u8 in commit 
4d42b37def70 ("net: convert dev->reg_state to u8").
rtnl_link_state being a 16 bitfield makes no sense. Convert it
to a single bool, it seems very unlikely after 15 years that
we'll need more values in it.
We could drop dev->rtnl_link_ops from the conditions but feels
like having it there more clearly points at the reason for this
hack.
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250410014246.780885-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 struct list_head                    link_watch_list
 enum:8                              reg_state
 bool                                dismantle
-enum:16                             rtnl_link_state
+bool                                rtnl_link_initilizing
 bool                                needs_free_netdev
 void*priv_destructor                struct net_device
 struct netpoll_info*                npinfo                                          read_mostly         napi_poll/napi_poll_lock
 
  *
  *     @reg_state:             Register/unregister state machine
  *     @dismantle:             Device is going to be freed
- *     @rtnl_link_state:       This enum represents the phases of creating
- *                             a new link
- *
  *     @needs_free_netdev:     Should unregister perform free_netdev?
  *     @priv_destructor:       Called from unregister
  *     @npinfo:                XXX: need comments on this one
 
        /** @moving_ns: device is changing netns, protected by @lock */
        bool moving_ns;
-
-       enum {
-               RTNL_LINK_INITIALIZED,
-               RTNL_LINK_INITIALIZING,
-       } rtnl_link_state:16;
+       /** @rtnl_link_initializing: Device being created, suppress events */
+       bool rtnl_link_initializing;
 
        bool needs_free_netdev;
        void (*priv_destructor)(struct net_device *dev);
 
         *      Prevent userspace races by waiting until the network
         *      device is fully setup before sending notifications.
         */
-       if (!dev->rtnl_link_ops ||
-           dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
+       if (!(dev->rtnl_link_ops && dev->rtnl_link_initializing))
                rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL, 0, NULL);
 
 out:
                 */
                call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
 
-               if (!dev->rtnl_link_ops ||
-                   dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
+               if (!(dev->rtnl_link_ops && dev->rtnl_link_initializing))
                        skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0,
                                                     GFP_KERNEL, NULL, 0,
                                                     portid, nlh);
 
 int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm,
                        u32 portid, const struct nlmsghdr *nlh)
 {
-       unsigned int old_flags;
+       unsigned int old_flags, changed;
        int err;
 
        old_flags = dev->flags;
                        return err;
        }
 
-       if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) {
-               __dev_notify_flags(dev, old_flags, (old_flags ^ dev->flags), portid, nlh);
-       } else {
-               dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
-               __dev_notify_flags(dev, old_flags, ~0U, portid, nlh);
+       changed = old_flags ^ dev->flags;
+       if (dev->rtnl_link_initializing) {
+               dev->rtnl_link_initializing = false;
+               changed = ~0U;
        }
+
+       __dev_notify_flags(dev, old_flags, changed, portid, nlh);
        return 0;
 }
 EXPORT_SYMBOL(rtnl_configure_link);
 
        dev_net_set(dev, net);
        dev->rtnl_link_ops = ops;
-       dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
+       dev->rtnl_link_initializing = true;
 
        if (tb[IFLA_MTU]) {
                u32 mtu = nla_get_u32(tb[IFLA_MTU]);