if (!dev->rtnl_link_ops ||
                    dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
                        skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0,
-                                                    GFP_KERNEL, NULL);
+                                                    GFP_KERNEL, NULL, 0);
 
                /*
                 *      Flush the unicast and multicast chains
 
 int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat)
 {
-       int err, new_nsid;
+       int err, new_nsid, new_ifindex;
 
        ASSERT_RTNL();
 
        call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
        rcu_barrier();
        call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
+
        new_nsid = peernet2id_alloc(dev_net(dev), net);
-       rtmsg_ifinfo_newnet(RTM_DELLINK, dev, ~0U, GFP_KERNEL, &new_nsid);
+       /* If there is an ifindex conflict assign a new one */
+       if (__dev_get_by_index(net, dev->ifindex))
+               new_ifindex = dev_new_index(net);
+       else
+               new_ifindex = dev->ifindex;
+
+       rtmsg_ifinfo_newnet(RTM_DELLINK, dev, ~0U, GFP_KERNEL, &new_nsid,
+                           new_ifindex);
 
        /*
         *      Flush the unicast and multicast chains
 
        /* Actually switch the network namespace */
        dev_net_set(dev, net);
-
-       /* If there is an ifindex conflict assign a new one */
-       if (__dev_get_by_index(net, dev->ifindex))
-               dev->ifindex = dev_new_index(net);
+       dev->ifindex = new_ifindex;
 
        /* Send a netdev-add uevent to the new namespace */
        kobject_uevent(&dev->dev.kobj, KOBJ_ADD);
 
               + rtnl_xdp_size() /* IFLA_XDP */
               + nla_total_size(4)  /* IFLA_EVENT */
               + nla_total_size(4)  /* IFLA_NEW_NETNSID */
+              + nla_total_size(4)  /* IFLA_NEW_IFINDEX */
               + nla_total_size(1)  /* IFLA_PROTO_DOWN */
               + nla_total_size(4)  /* IFLA_IF_NETNSID */
               + nla_total_size(4)  /* IFLA_CARRIER_UP_COUNT */
                            struct net_device *dev, struct net *src_net,
                            int type, u32 pid, u32 seq, u32 change,
                            unsigned int flags, u32 ext_filter_mask,
-                           u32 event, int *new_nsid, int tgt_netnsid)
+                           u32 event, int *new_nsid, int new_ifindex,
+                           int tgt_netnsid)
 {
        struct ifinfomsg *ifm;
        struct nlmsghdr *nlh;
        if (new_nsid &&
            nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
                goto nla_put_failure;
+       if (new_ifindex &&
+           nla_put_s32(skb, IFLA_NEW_IFINDEX, new_ifindex) < 0)
+               goto nla_put_failure;
+
 
        rcu_read_lock();
        if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
                                               NETLINK_CB(cb->skb).portid,
                                               cb->nlh->nlmsg_seq, 0,
                                               flags,
-                                              ext_filter_mask, 0, NULL,
+                                              ext_filter_mask, 0, NULL, 0,
                                               netnsid);
 
                        if (err < 0) {
        err = rtnl_fill_ifinfo(nskb, dev, net,
                               RTM_NEWLINK, NETLINK_CB(skb).portid,
                               nlh->nlmsg_seq, 0, 0, ext_filter_mask,
-                              0, NULL, netnsid);
+                              0, NULL, 0, netnsid);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in if_nlmsg_size */
                WARN_ON(err == -EMSGSIZE);
 
 struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
                                       unsigned int change,
-                                      u32 event, gfp_t flags, int *new_nsid)
+                                      u32 event, gfp_t flags, int *new_nsid,
+                                      int new_ifindex)
 {
        struct net *net = dev_net(dev);
        struct sk_buff *skb;
 
        err = rtnl_fill_ifinfo(skb, dev, dev_net(dev),
                               type, 0, 0, change, 0, 0, event,
-                              new_nsid, -1);
+                              new_nsid, new_ifindex, -1);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in if_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
 
 static void rtmsg_ifinfo_event(int type, struct net_device *dev,
                               unsigned int change, u32 event,
-                              gfp_t flags, int *new_nsid)
+                              gfp_t flags, int *new_nsid, int new_ifindex)
 {
        struct sk_buff *skb;
 
        if (dev->reg_state != NETREG_REGISTERED)
                return;
 
-       skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid);
+       skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid,
+                                    new_ifindex);
        if (skb)
                rtmsg_ifinfo_send(skb, dev, flags);
 }
 void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
                  gfp_t flags)
 {
-       rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags, NULL);
+       rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags,
+                          NULL, 0);
 }
 
 void rtmsg_ifinfo_newnet(int type, struct net_device *dev, unsigned int change,
-                        gfp_t flags, int *new_nsid)
+                        gfp_t flags, int *new_nsid, int new_ifindex)
 {
        rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags,
-                          new_nsid);
+                          new_nsid, new_ifindex);
 }
 
 static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
        case NETDEV_CHANGELOWERSTATE:
        case NETDEV_CHANGE_TX_QUEUE_LEN:
                rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event),
-                                  GFP_KERNEL, NULL);
+                                  GFP_KERNEL, NULL, 0);
                break;
        default:
                break;