--- /dev/null
+From: Andy Ren <andy.ren@getcruise.com>
+Date: Mon, 7 Nov 2022 09:42:42 -0800
+Subject: [PATCH] net/core: Allow live renaming when an interface is up
+
+Allow a network interface to be renamed when the interface
+is up.
+
+As described in the netconsole documentation [1], when netconsole is
+used as a built-in, it will bring up the specified interface as soon as
+possible. As a result, user space will not be able to rename the
+interface since the kernel disallows renaming of interfaces that are
+administratively up unless the 'IFF_LIVE_RENAME_OK' private flag was set
+by the kernel.
+
+The original solution [2] to this problem was to add a new parameter to
+the netconsole configuration parameters that allows renaming of
+the interface used by netconsole while it is administratively up.
+However, during the discussion that followed, it became apparent that we
+have no reason to keep the current restriction and instead we should
+allow user space to rename interfaces regardless of their administrative
+state:
+
+1. The restriction was put in place over 20 years ago when renaming was
+only possible via IOCTL and before rtnetlink started notifying user
+space about such changes like it does today.
+
+2. The 'IFF_LIVE_RENAME_OK' flag was added over 3 years ago in version
+5.2 and no regressions were reported.
+
+3. In-kernel listeners to 'NETDEV_CHANGENAME' do not seem to care about
+the administrative state of interface.
+
+Therefore, allow user space to rename running interfaces by removing the
+restriction and the associated 'IFF_LIVE_RENAME_OK' flag. Help in
+possible triage by emitting a message to the kernel log that an
+interface was renamed while UP.
+
+[1] https://www.kernel.org/doc/Documentation/networking/netconsole.rst
+[2] https://lore.kernel.org/netdev/20221102002420.2613004-1-andy.ren@getcruise.com/
+
+Signed-off-by: Andy Ren <andy.ren@getcruise.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1642,7 +1642,6 @@ struct net_device_ops {
+ * @IFF_FAILOVER: device is a failover master device
+ * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
+ * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device
+- * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running
+ * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with
+ * skb_headlen(skb) == 0 (data starts from frag0)
+ */
+@@ -1677,7 +1676,7 @@ enum netdev_priv_flags {
+ IFF_FAILOVER = 1<<27,
+ IFF_FAILOVER_SLAVE = 1<<28,
+ IFF_L3MDEV_RX_HANDLER = 1<<29,
+- IFF_LIVE_RENAME_OK = 1<<30,
++ /* was IFF_LIVE_RENAME_OK */
+ IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
+ };
+
+@@ -1711,7 +1710,6 @@ enum netdev_priv_flags {
+ #define IFF_FAILOVER IFF_FAILOVER
+ #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
+ #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
+-#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
+ #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
+
+ /* Specifies the type of the struct net_device::ml_priv pointer */
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1222,22 +1222,6 @@ int dev_change_name(struct net_device *d
+
+ net = dev_net(dev);
+
+- /* Some auto-enslaved devices e.g. failover slaves are
+- * special, as userspace might rename the device after
+- * the interface had been brought up and running since
+- * the point kernel initiated auto-enslavement. Allow
+- * live name change even when these slave devices are
+- * up and running.
+- *
+- * Typically, users of these auto-enslaving devices
+- * don't actually care about slave name change, as
+- * they are supposed to operate on master interface
+- * directly.
+- */
+- if (dev->flags & IFF_UP &&
+- likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK)))
+- return -EBUSY;
+-
+ down_write(&devnet_rename_sem);
+
+ if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
+@@ -1254,7 +1238,8 @@ int dev_change_name(struct net_device *d
+ }
+
+ if (oldname[0] && !strchr(oldname, '%'))
+- netdev_info(dev, "renamed from %s\n", oldname);
++ netdev_info(dev, "renamed from %s%s\n", oldname,
++ dev->flags & IFF_UP ? " (while UP)" : "");
+
+ old_assign_type = dev->name_assign_type;
+ dev->name_assign_type = NET_NAME_RENAMED;
+--- a/net/core/failover.c
++++ b/net/core/failover.c
+@@ -80,14 +80,14 @@ static int failover_slave_register(struc
+ goto err_upper_link;
+ }
+
+- slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
++ slave_dev->priv_flags |= IFF_FAILOVER_SLAVE;
+
+ if (fops && fops->slave_register &&
+ !fops->slave_register(slave_dev, failover_dev))
+ return NOTIFY_OK;
+
+ netdev_upper_dev_unlink(slave_dev, failover_dev);
+- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
++ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
+ err_upper_link:
+ netdev_rx_handler_unregister(slave_dev);
+ done:
+@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net
+
+ netdev_rx_handler_unregister(slave_dev);
+ netdev_upper_dev_unlink(slave_dev, failover_dev);
+- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
++ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
+
+ if (fops && fops->slave_unregister &&
+ !fops->slave_unregister(slave_dev, failover_dev))
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
-@@ -1682,6 +1682,10 @@ enum netdev_priv_flags {
+@@ -1681,6 +1681,10 @@ enum netdev_priv_flags {
IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
};
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
#define IFF_EBRIDGE IFF_EBRIDGE
#define IFF_BONDING IFF_BONDING
-@@ -1714,6 +1718,7 @@ enum netdev_priv_flags {
+@@ -1712,6 +1716,7 @@ enum netdev_priv_flags {
+ #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
#define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
- #define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
#define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
/* Specifies the type of the struct net_device::ml_priv pointer */
enum netdev_ml_priv_type {
-@@ -2014,6 +2019,7 @@ struct net_device {
+@@ -2012,6 +2017,7 @@ struct net_device {
/* Read-mostly cache-line for fast-path access */
unsigned int flags;
unsigned int priv_flags;
const struct net_device_ops *netdev_ops;
int ifindex;
unsigned short gflags;
-@@ -2074,6 +2080,11 @@ struct net_device {
+@@ -2072,6 +2078,11 @@ struct net_device {
const struct tlsdev_ops *tlsdev_ops;
#endif
const struct header_ops *header_ops;
unsigned char operstate;
-@@ -2145,6 +2156,10 @@ struct net_device {
+@@ -2143,6 +2154,10 @@ struct net_device {
struct mctp_dev __rcu *mctp_ptr;
#endif
help
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -3592,6 +3592,11 @@ static int xmit_one(struct sk_buff *skb,
+@@ -3577,6 +3577,11 @@ static int xmit_one(struct sk_buff *skb,
if (dev_nit_active(dev))
dev_queue_xmit_nit(skb, dev);
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
-@@ -2100,6 +2100,8 @@ struct net_device {
+@@ -2098,6 +2098,8 @@ struct net_device {
struct netdev_hw_addr_list mc;
struct netdev_hw_addr_list dev_addrs;
__u8 inner_protocol_type:1;
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -6069,6 +6069,9 @@ static enum gro_result dev_gro_receive(s
+@@ -6054,6 +6054,9 @@ static enum gro_result dev_gro_receive(s
int same_flow;
int grow;
if (netif_elide_gro(skb->dev))
goto normal;
-@@ -8083,6 +8086,48 @@ static void __netdev_adjacent_dev_unlink
+@@ -8068,6 +8071,48 @@ static void __netdev_adjacent_dev_unlink
&upper_dev->adj_list.lower);
}
static int __netdev_upper_dev_link(struct net_device *dev,
struct net_device *upper_dev, bool master,
void *upper_priv, void *upper_info,
-@@ -8134,6 +8179,7 @@ static int __netdev_upper_dev_link(struc
+@@ -8119,6 +8164,7 @@ static int __netdev_upper_dev_link(struc
if (ret)
return ret;
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
ret = notifier_to_errno(ret);
-@@ -8230,6 +8276,7 @@ static void __netdev_upper_dev_unlink(st
+@@ -8215,6 +8261,7 @@ static void __netdev_upper_dev_unlink(st
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
-@@ -9049,6 +9096,7 @@ int dev_set_mac_address(struct net_devic
+@@ -9034,6 +9081,7 @@ int dev_set_mac_address(struct net_devic
if (err)
return err;
dev->addr_assign_type = NET_ADDR_SET;
/**
* napi_disable - prevent NAPI from scheduling
-@@ -3364,6 +3365,7 @@ struct softnet_data {
+@@ -3362,6 +3363,7 @@ struct softnet_data {
unsigned int processed;
unsigned int time_squeeze;
unsigned int received_rps;
#endif
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -4578,7 +4578,7 @@ static int rps_ipi_queued(struct softnet
+@@ -4563,7 +4563,7 @@ static int rps_ipi_queued(struct softnet
#ifdef CONFIG_RPS
struct softnet_data *mysd = this_cpu_ptr(&softnet_data);
sd->rps_ipi_next = mysd->rps_ipi_list;
mysd->rps_ipi_list = sd;
-@@ -5759,6 +5759,8 @@ static DEFINE_PER_CPU(struct work_struct
+@@ -5744,6 +5744,8 @@ static DEFINE_PER_CPU(struct work_struct
/* Network device is going away, flush any packets still pending */
static void flush_backlog(struct work_struct *work)
{
struct sk_buff *skb, *tmp;
struct softnet_data *sd;
-@@ -5774,9 +5776,18 @@ static void flush_backlog(struct work_st
+@@ -5759,9 +5761,18 @@ static void flush_backlog(struct work_st
input_queue_head_incr(sd);
}
}
skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
__skb_unlink(skb, &sd->process_queue);
-@@ -5784,7 +5795,18 @@ static void flush_backlog(struct work_st
+@@ -5769,7 +5780,18 @@ static void flush_backlog(struct work_st
input_queue_head_incr(sd);
}
}
}
static bool flush_required(int cpu)
-@@ -6467,6 +6489,7 @@ static int process_backlog(struct napi_s
+@@ -6452,6 +6474,7 @@ static int process_backlog(struct napi_s
local_irq_disable();
rps_lock(sd);
if (skb_queue_empty(&sd->input_pkt_queue)) {
/*
* Inline a custom version of __napi_complete().
-@@ -6476,7 +6499,8 @@ static int process_backlog(struct napi_s
+@@ -6461,7 +6484,8 @@ static int process_backlog(struct napi_s
* We can use a plain write instead of clear_bit(),
* and we dont need an smp_mb() memory barrier.
*/
again = false;
} else {
skb_queue_splice_tail_init(&sd->input_pkt_queue,
-@@ -6893,6 +6917,57 @@ int dev_set_threaded(struct net_device *
+@@ -6878,6 +6902,57 @@ int dev_set_threaded(struct net_device *
}
EXPORT_SYMBOL(dev_set_threaded);
void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
int (*poll)(struct napi_struct *, int), int weight)
{
-@@ -11369,6 +11444,9 @@ static int dev_cpu_dead(unsigned int old
+@@ -11354,6 +11429,9 @@ static int dev_cpu_dead(unsigned int old
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_enable();
#ifdef CONFIG_RPS
remsd = oldsd->rps_ipi_list;
oldsd->rps_ipi_list = NULL;
-@@ -11708,6 +11786,7 @@ static int __init net_dev_init(void)
+@@ -11693,6 +11771,7 @@ static int __init net_dev_init(void)
sd->cpu = i;
#endif