]> www.infradead.org Git - users/hch/misc.git/commitdiff
net: Use link/peer netns in newlink() of rtnl_link_ops
authorXiao Liang <shaw.leon@gmail.com>
Wed, 19 Feb 2025 12:50:29 +0000 (20:50 +0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 21 Feb 2025 23:28:02 +0000 (15:28 -0800)
Add two helper functions - rtnl_newlink_link_net() and
rtnl_newlink_peer_net() for netns fallback logic. Peer netns falls back
to link netns, and link netns falls back to source netns.

Convert the use of params->net in netdevice drivers to one of the helper
functions for clarity.

Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250219125039.18024-4-shaw.leon@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
21 files changed:
drivers/infiniband/ulp/ipoib/ipoib_netlink.c
drivers/net/amt.c
drivers/net/bareudp.c
drivers/net/can/vxcan.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
drivers/net/geneve.c
drivers/net/gtp.c
drivers/net/ipvlan/ipvlan_main.c
drivers/net/macsec.c
drivers/net/macvlan.c
drivers/net/netkit.c
drivers/net/pfcp.c
drivers/net/ppp/ppp_generic.c
drivers/net/veth.c
drivers/net/vxlan/vxlan_core.c
drivers/net/wireguard/device.c
drivers/net/wireless/virtual/virt_wifi.c
drivers/net/wwan/wwan_core.c
include/net/rtnetlink.h
net/8021q/vlan_netlink.c
net/hsr/hsr_netlink.c

index 16cb8ced9f35ceebc7179d0149361906610ba796..53db7c8191e38cf0424ead91142a68438a240705 100644 (file)
@@ -101,8 +101,8 @@ static int ipoib_new_child_link(struct net_device *dev,
                                struct rtnl_newlink_params *params,
                                struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct net_device *pdev;
        struct ipoib_dev_priv *ppriv;
@@ -112,7 +112,7 @@ static int ipoib_new_child_link(struct net_device *dev,
        if (!tb[IFLA_LINK])
                return -EINVAL;
 
-       pdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+       pdev = __dev_get_by_index(link_net, nla_get_u32(tb[IFLA_LINK]));
        if (!pdev || pdev->type != ARPHRD_INFINIBAND)
                return -ENODEV;
 
index 96b7ec9a2c13eb60a02c2e739382205b58153841..53899b70fae1ce056e6f13849c0de476338c48d2 100644 (file)
@@ -3165,13 +3165,13 @@ static int amt_newlink(struct net_device *dev,
                       struct rtnl_newlink_params *params,
                       struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct amt_dev *amt = netdev_priv(dev);
        struct nlattr **data = params->data;
        struct nlattr **tb = params->tb;
-       struct net *net = params->net;
        int err = -EINVAL;
 
-       amt->net = net;
+       amt->net = link_net;
        amt->mode = nla_get_u32(data[IFLA_AMT_MODE]);
 
        if (data[IFLA_AMT_MAX_TUNNELS] &&
@@ -3186,7 +3186,7 @@ static int amt_newlink(struct net_device *dev,
        amt->hash_buckets = AMT_HSIZE;
        amt->nr_tunnels = 0;
        get_random_bytes(&amt->hash_seed, sizeof(amt->hash_seed));
-       amt->stream_dev = dev_get_by_index(net,
+       amt->stream_dev = dev_get_by_index(link_net,
                                           nla_get_u32(data[IFLA_AMT_LINK]));
        if (!amt->stream_dev) {
                NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LINK],
index fc21dcfb4848db400ed480aa7df701b0ced68e11..d1473c5f8eefc4d884ca61517ebd8002debcd2ca 100644 (file)
@@ -702,9 +702,9 @@ static int bareudp_newlink(struct net_device *dev,
                           struct rtnl_newlink_params *params,
                           struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
        struct nlattr **tb = params->tb;
-       struct net *net = params->net;
        struct bareudp_conf conf;
        int err;
 
@@ -712,7 +712,7 @@ static int bareudp_newlink(struct net_device *dev,
        if (err)
                return err;
 
-       err = bareudp_configure(net, dev, &conf, extack);
+       err = bareudp_configure(link_net, dev, &conf, extack);
        if (err)
                return err;
 
index 6f8ebb1cfd7b2cd57a9283df405912364a875470..99a78a75716749bf858cc78eadb41ca2588fcf94 100644 (file)
@@ -176,8 +176,8 @@ static int vxcan_newlink(struct net_device *dev,
                         struct rtnl_newlink_params *params,
                         struct netlink_ext_ack *extack)
 {
+       struct net *peer_net = rtnl_newlink_peer_net(params);
        struct nlattr **data = params->data;
-       struct net *peer_net = params->net;
        struct nlattr **tb = params->tb;
        struct vxcan_priv *priv;
        struct net_device *peer;
index 8151e91395e2ec334c2457c84679887cedaecf44..ba8763cac9d9e6c84971f15b7212210cc125d0d4 100644 (file)
@@ -121,9 +121,9 @@ static int rmnet_newlink(struct net_device *dev,
                         struct rtnl_newlink_params *params,
                         struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        u32 data_format = RMNET_FLAGS_INGRESS_DEAGGREGATION;
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct net_device *real_dev;
        int mode = RMNET_EPMODE_VND;
@@ -137,7 +137,7 @@ static int rmnet_newlink(struct net_device *dev,
                return -EINVAL;
        }
 
-       real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+       real_dev = __dev_get_by_index(link_net, nla_get_u32(tb[IFLA_LINK]));
        if (!real_dev) {
                NL_SET_ERR_MSG_MOD(extack, "link does not exist");
                return -ENODEV;
index d6e8b2521052314f767ed749b5f3488cf9b786ea..fc62b25e0362a49d4d017193f73c8fb7213535e9 100644 (file)
@@ -1618,9 +1618,9 @@ static int geneve_newlink(struct net_device *dev,
                          struct rtnl_newlink_params *params,
                          struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
        struct nlattr **tb = params->tb;
-       struct net *net = params->net;
        struct geneve_config cfg = {
                .df = GENEVE_DF_UNSET,
                .use_udp6_rx_checksums = false,
@@ -1634,7 +1634,7 @@ static int geneve_newlink(struct net_device *dev,
        if (err)
                return err;
 
-       err = geneve_configure(net, dev, extack, &cfg);
+       err = geneve_configure(link_net, dev, extack, &cfg);
        if (err)
                return err;
 
index 762514af8b3051a14c4017121147f9c84d895f19..ef793607890d94c99f1b6df02f942ea6e5a73878 100644 (file)
@@ -1466,8 +1466,8 @@ static int gtp_newlink(struct net_device *dev,
                       struct rtnl_newlink_params *params,
                       struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        unsigned int role = GTP_ROLE_GGSN;
        struct gtp_dev *gtp;
        struct gtp_net *gn;
@@ -1498,7 +1498,7 @@ static int gtp_newlink(struct net_device *dev,
        gtp->restart_count = nla_get_u8_default(data[IFLA_GTP_RESTART_COUNT],
                                                0);
 
-       gtp->net = src_net;
+       gtp->net = link_net;
 
        err = gtp_hashtable_new(gtp, hashsize);
        if (err < 0)
@@ -1528,7 +1528,7 @@ static int gtp_newlink(struct net_device *dev,
                goto out_encap;
        }
 
-       gn = net_generic(src_net, gtp_net_id);
+       gn = net_generic(link_net, gtp_net_id);
        list_add(&gtp->list, &gn->gtp_dev_list);
        dev->priv_destructor = gtp_destructor;
 
index 19ce19ca7e3249e17cfb031fa2bd124c3183531b..b56144ca2fded21611724e86526c579d021d9581 100644 (file)
@@ -535,9 +535,9 @@ err:
 int ipvlan_link_new(struct net_device *dev, struct rtnl_newlink_params *params,
                    struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct ipvl_dev *ipvlan = netdev_priv(dev);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct ipvl_port *port;
        struct net_device *phy_dev;
@@ -547,7 +547,7 @@ int ipvlan_link_new(struct net_device *dev, struct rtnl_newlink_params *params,
        if (!tb[IFLA_LINK])
                return -EINVAL;
 
-       phy_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+       phy_dev = __dev_get_by_index(link_net, nla_get_u32(tb[IFLA_LINK]));
        if (!phy_dev)
                return -ENODEV;
 
index 1869b0513f57c0b1fcccb4bfead2bd0f83a1291f..4de5d63fd577cd1c8cb58b0ddbf932ce8d24452f 100644 (file)
@@ -4145,10 +4145,10 @@ static int macsec_newlink(struct net_device *dev,
                          struct rtnl_newlink_params *params,
                          struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct macsec_dev *macsec = macsec_priv(dev);
        struct nlattr **data = params->data;
        struct nlattr **tb = params->tb;
-       struct net *net = params->net;
        rx_handler_func_t *rx_handler;
        u8 icv_len = MACSEC_DEFAULT_ICV_LEN;
        struct net_device *real_dev;
@@ -4157,7 +4157,7 @@ static int macsec_newlink(struct net_device *dev,
 
        if (!tb[IFLA_LINK])
                return -EINVAL;
-       real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
+       real_dev = __dev_get_by_index(link_net, nla_get_u32(tb[IFLA_LINK]));
        if (!real_dev)
                return -ENODEV;
        if (real_dev->type != ARPHRD_ETHER)
index f903b414eaeb2ffda2483e9e92c74d9f99f2228e..4e9d54be887c1cb255b697f3ea51a49b055049db 100644 (file)
@@ -1444,9 +1444,9 @@ int macvlan_common_newlink(struct net_device *dev,
                           struct rtnl_newlink_params *params,
                           struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct macvlan_dev *vlan = netdev_priv(dev);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct net_device *lowerdev;
        struct macvlan_port *port;
@@ -1457,7 +1457,7 @@ int macvlan_common_newlink(struct net_device *dev,
        if (!tb[IFLA_LINK])
                return -EINVAL;
 
-       lowerdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+       lowerdev = __dev_get_by_index(link_net, nla_get_u32(tb[IFLA_LINK]));
        if (lowerdev == NULL)
                return -ENODEV;
 
index 640a2dbbbd28c1a60b2154f699fea07afc870d06..751347392570ea87397e6305f1d2f2a02265d206 100644 (file)
@@ -331,13 +331,13 @@ static int netkit_new_link(struct net_device *dev,
                           struct rtnl_newlink_params *params,
                           struct netlink_ext_ack *extack)
 {
+       struct net *peer_net = rtnl_newlink_peer_net(params);
        enum netkit_scrub scrub_prim = NETKIT_SCRUB_DEFAULT;
        enum netkit_scrub scrub_peer = NETKIT_SCRUB_DEFAULT;
        struct nlattr *peer_tb[IFLA_MAX + 1], **tbp, *attr;
        enum netkit_action policy_prim = NETKIT_PASS;
        enum netkit_action policy_peer = NETKIT_PASS;
        struct nlattr **data = params->data;
-       struct net *peer_net = params->net;
        enum netkit_mode mode = NETKIT_L3;
        unsigned char ifname_assign_type;
        struct nlattr **tb = params->tb;
index 7b0575940e1d6ea27335ee3997ab14b206f56cba..f873a92d24459802003ef7da0778f0b124f85940 100644 (file)
@@ -188,12 +188,12 @@ static int pfcp_newlink(struct net_device *dev,
                        struct rtnl_newlink_params *params,
                        struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct pfcp_dev *pfcp = netdev_priv(dev);
-       struct net *net = params->net;
        struct pfcp_net *pn;
        int err;
 
-       pfcp->net = net;
+       pfcp->net = link_net;
 
        err = pfcp_add_sock(pfcp);
        if (err) {
@@ -207,7 +207,7 @@ static int pfcp_newlink(struct net_device *dev,
                goto exit_del_pfcp_sock;
        }
 
-       pn = net_generic(net, pfcp_net_id);
+       pn = net_generic(link_net, pfcp_net_id);
        list_add(&pfcp->list, &pn->pfcp_dev_list);
 
        netdev_dbg(dev, "registered new PFCP interface\n");
index b3340f8a6149a0a7839cfca4da0c5f0511d37b54..6220866258fc43c1e2914a637ba8618d540afd67 100644 (file)
@@ -1307,8 +1307,8 @@ static int ppp_nl_newlink(struct net_device *dev,
                          struct rtnl_newlink_params *params,
                          struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct ppp_config conf = {
                .unit = -1,
@@ -1346,7 +1346,7 @@ static int ppp_nl_newlink(struct net_device *dev,
        if (!tb[IFLA_IFNAME] || !nla_len(tb[IFLA_IFNAME]) || !*(char *)nla_data(tb[IFLA_IFNAME]))
                conf.ifname_is_set = false;
 
-       err = ppp_dev_configure(src_net, dev, &conf);
+       err = ppp_dev_configure(link_net, dev, &conf);
 
 out_unlock:
        mutex_unlock(&ppp_mutex);
index 7dfda89f072fea855f0ed61c07ca26c26f3a3937..ba3ae2d8092f83a7110caa6d166e96fba9829964 100644 (file)
@@ -1769,8 +1769,8 @@ static int veth_newlink(struct net_device *dev,
                        struct rtnl_newlink_params *params,
                        struct netlink_ext_ack *extack)
 {
+       struct net *peer_net = rtnl_newlink_peer_net(params);
        struct nlattr **data = params->data;
-       struct net *peer_net = params->net;
        struct nlattr **tb = params->tb;
        int err;
        struct net_device *peer;
index 1a1d03abb6b99a9f0e7788dff11842d689bd9e95..227d7f5a302a9046df253f46148f45d88fbd1a93 100644 (file)
@@ -4404,8 +4404,8 @@ static int vxlan_newlink(struct net_device *dev,
                         struct rtnl_newlink_params *params,
                         struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct vxlan_config conf;
        int err;
@@ -4414,7 +4414,7 @@ static int vxlan_newlink(struct net_device *dev,
        if (err)
                return err;
 
-       return __vxlan_dev_create(src_net, dev, &conf, extack);
+       return __vxlan_dev_create(link_net, dev, &conf, extack);
 }
 
 static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
index 404cf05bd72bf649903c2debddf74c97a0557c86..c496d35b266ddf63831c00ad9a77cdf9471e551d 100644 (file)
@@ -311,11 +311,11 @@ static int wg_newlink(struct net_device *dev,
                      struct rtnl_newlink_params *params,
                      struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct wg_device *wg = netdev_priv(dev);
-       struct net *src_net = params->net;
        int ret = -ENOMEM;
 
-       rcu_assign_pointer(wg->creating_net, src_net);
+       rcu_assign_pointer(wg->creating_net, link_net);
        init_rwsem(&wg->static_identity.lock);
        mutex_init(&wg->socket_update_lock);
        mutex_init(&wg->device_update_lock);
index 26905b2b3ba3761641ef304c9abf57017aa932e1..f9d11a0233136a0b878c89f872b4094939af2ed5 100644 (file)
@@ -524,7 +524,7 @@ static int virt_wifi_newlink(struct net_device *dev,
                             struct netlink_ext_ack *extack)
 {
        struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
-       struct net *src_net = params->net;
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **tb = params->tb;
        int err;
 
@@ -534,7 +534,7 @@ static int virt_wifi_newlink(struct net_device *dev,
        netif_carrier_off(dev);
 
        priv->upperdev = dev;
-       priv->lowerdev = __dev_get_by_index(src_net,
+       priv->lowerdev = __dev_get_by_index(link_net,
                                            nla_get_u32(tb[IFLA_LINK]));
 
        if (!priv->lowerdev)
index a05c49b4e7f80b1b1678c93bcb72579d4b80c70d..63a47d420bc59bf0909e9af4ecf39e4820a999c2 100644 (file)
@@ -1065,7 +1065,7 @@ static void wwan_create_default_link(struct wwan_device *wwandev,
        struct nlattr *tb[IFLA_MAX + 1], *linkinfo[IFLA_INFO_MAX + 1];
        struct nlattr *data[IFLA_WWAN_MAX + 1];
        struct rtnl_newlink_params params = {
-               .net = &init_net,
+               .src_net = &init_net,
                .tb = tb,
                .data = data,
        };
index 563a6a27436c2eb2fb90bb34cb54dfe93750a679..b22a106621fb4a31a20f8cf6be89b53bd2695f65 100644 (file)
@@ -88,6 +88,23 @@ struct rtnl_newlink_params {
        struct nlattr **data;
 };
 
+/* Get effective link netns from newlink params. Generally, this is link_net
+ * and falls back to src_net. But for compatibility, a driver may * choose to
+ * use dev_net(dev) instead.
+ */
+static inline struct net *rtnl_newlink_link_net(struct rtnl_newlink_params *p)
+{
+       return p->link_net ? : p->src_net;
+}
+
+/* Get peer netns from newlink params. Fallback to link netns if peer netns is
+ * not specified explicitly.
+ */
+static inline struct net *rtnl_newlink_peer_net(struct rtnl_newlink_params *p)
+{
+       return p->peer_net ? : rtnl_newlink_link_net(p);
+}
+
 /**
  *     struct rtnl_link_ops - rtnetlink link operations
  *
index 91df0f96e32aedfc376884bf27d3c6f6c8bcb447..a000b1ef05206a08c2e26657852a3b0c384fbe0f 100644 (file)
@@ -139,9 +139,9 @@ static int vlan_newlink(struct net_device *dev,
                        struct rtnl_newlink_params *params,
                        struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        struct nlattr **tb = params->tb;
        struct net_device *real_dev;
        unsigned int max_mtu;
@@ -158,7 +158,7 @@ static int vlan_newlink(struct net_device *dev,
                return -EINVAL;
        }
 
-       real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+       real_dev = __dev_get_by_index(link_net, nla_get_u32(tb[IFLA_LINK]));
        if (!real_dev) {
                NL_SET_ERR_MSG_MOD(extack, "link does not exist");
                return -ENODEV;
index 39add538ba9987c52494c5b084414400afea4380..b120470246cc5660cd43bf85f18edfa5ac7ca349 100644 (file)
@@ -33,8 +33,8 @@ static int hsr_newlink(struct net_device *dev,
                       struct rtnl_newlink_params *params,
                       struct netlink_ext_ack *extack)
 {
+       struct net *link_net = rtnl_newlink_link_net(params);
        struct nlattr **data = params->data;
-       struct net *src_net = params->net;
        enum hsr_version proto_version;
        unsigned char multicast_spec;
        u8 proto = HSR_PROTOCOL_HSR;
@@ -48,7 +48,7 @@ static int hsr_newlink(struct net_device *dev,
                NL_SET_ERR_MSG_MOD(extack, "Slave1 device not specified");
                return -EINVAL;
        }
-       link[0] = __dev_get_by_index(src_net,
+       link[0] = __dev_get_by_index(link_net,
                                     nla_get_u32(data[IFLA_HSR_SLAVE1]));
        if (!link[0]) {
                NL_SET_ERR_MSG_MOD(extack, "Slave1 does not exist");
@@ -58,7 +58,7 @@ static int hsr_newlink(struct net_device *dev,
                NL_SET_ERR_MSG_MOD(extack, "Slave2 device not specified");
                return -EINVAL;
        }
-       link[1] = __dev_get_by_index(src_net,
+       link[1] = __dev_get_by_index(link_net,
                                     nla_get_u32(data[IFLA_HSR_SLAVE2]));
        if (!link[1]) {
                NL_SET_ERR_MSG_MOD(extack, "Slave2 does not exist");
@@ -71,7 +71,7 @@ static int hsr_newlink(struct net_device *dev,
        }
 
        if (data[IFLA_HSR_INTERLINK])
-               interlink = __dev_get_by_index(src_net,
+               interlink = __dev_get_by_index(link_net,
                                               nla_get_u32(data[IFLA_HSR_INTERLINK]));
 
        if (interlink && interlink == link[0]) {