@@ -97,10 +97,13 @@ static int ipoib_changelink(struct net_device *dev, struct nlattr *tb[],
return ret;
}
-static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ipoib_new_child_link(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct net_device *pdev;
struct ipoib_dev_priv *ppriv;
u16 child_pkey;
@@ -109,7 +112,7 @@ static int ipoib_new_child_link(struct net *src_net, 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;
@@ -3161,14 +3161,17 @@ static int amt_validate(struct nlattr *tb[], struct nlattr *data[],
return 0;
}
-static int amt_newlink(struct net *net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int amt_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct amt_dev *amt = netdev_priv(dev);
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] &&
@@ -3183,7 +3186,7 @@ static int amt_newlink(struct net *net, 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],
@@ -698,10 +698,13 @@ static void bareudp_dellink(struct net_device *dev, struct list_head *head)
unregister_netdevice_queue(dev, head);
}
-static int bareudp_newlink(struct net *net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int bareudp_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct bareudp_conf conf;
int err;
@@ -709,7 +712,7 @@ static int bareudp_newlink(struct net *net, 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;
@@ -564,10 +564,12 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
return 0;
}
-static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int bond_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *bond_dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
int err;
err = bond_changelink(bond_dev, tb, data, extack);
@@ -624,9 +624,7 @@ static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
return -EMSGSIZE;
}
-static int can_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int can_newlink(struct rtnl_newlink_params *params)
{
return -EOPNOTSUPP;
}
@@ -172,10 +172,13 @@ static void vxcan_setup(struct net_device *dev)
/* forward declaration for rtnl_create_link() */
static struct rtnl_link_ops vxcan_link_ops;
-static int vxcan_newlink(struct net *net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int vxcan_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct vxcan_priv *priv;
struct net_device *peer;
struct net *peer_net;
@@ -203,7 +206,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
name_assign_type = NET_NAME_ENUM;
}
- peer_net = rtnl_link_get_net(net, tbp);
+ peer_net = rtnl_link_get_net(link_net, tbp);
peer = rtnl_create_link(peer_net, ifname, name_assign_type,
&vxcan_link_ops, tbp, extack);
if (IS_ERR(peer)) {
@@ -117,10 +117,13 @@ static void rmnet_unregister_bridge(struct rmnet_port *port)
rmnet_unregister_real_device(bridge_dev);
}
-static int rmnet_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int rmnet_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
u32 data_format = RMNET_FLAGS_INGRESS_DEAGGREGATION;
struct net_device *real_dev;
int mode = RMNET_EPMODE_VND;
@@ -134,7 +137,7 @@ static int rmnet_newlink(struct net *src_net, 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;
@@ -1614,10 +1614,13 @@ static void geneve_link_config(struct net_device *dev,
geneve_change_mtu(dev, ldev_mtu - info->options_len);
}
-static int geneve_newlink(struct net *net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int geneve_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct geneve_config cfg = {
.df = GENEVE_DF_UNSET,
.use_udp6_rx_checksums = false,
@@ -1631,7 +1634,7 @@ static int geneve_newlink(struct net *net, 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;
@@ -1460,10 +1460,11 @@ static int gtp_create_sockets(struct gtp_dev *gtp, const struct nlattr *nla,
#define GTP_TH_MAXLEN (sizeof(struct udphdr) + sizeof(struct gtp0_header))
#define GTP_IPV6_MAXLEN (sizeof(struct ipv6hdr) + GTP_TH_MAXLEN)
-static int gtp_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int gtp_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
+ struct net *link_net = rtnl_newlink_link_net(params);
unsigned int role = GTP_ROLE_GGSN;
struct gtp_dev *gtp;
struct gtp_net *gn;
@@ -1494,7 +1495,7 @@ static int gtp_newlink(struct net *src_net, 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)
@@ -166,9 +166,7 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h,
void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type);
void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
unsigned int len, bool success, bool mcast);
-int ipvlan_link_new(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack);
+int ipvlan_link_new(struct rtnl_newlink_params *params);
void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
void ipvlan_link_setup(struct net_device *dev);
int ipvlan_link_register(struct rtnl_link_ops *ops);
@@ -532,10 +532,13 @@ static int ipvlan_nl_fillinfo(struct sk_buff *skb,
return ret;
}
-int ipvlan_link_new(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+int ipvlan_link_new(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct ipvl_dev *ipvlan = netdev_priv(dev);
struct ipvl_port *port;
struct net_device *phy_dev;
@@ -545,7 +548,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
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;
@@ -73,10 +73,9 @@ static void ipvtap_update_features(struct tap_dev *tap,
netdev_update_features(vlan->dev);
}
-static int ipvtap_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ipvtap_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
struct ipvtap_dev *vlantap = netdev_priv(dev);
int err;
@@ -97,7 +96,7 @@ static int ipvtap_newlink(struct net *src_net, struct net_device *dev,
/* Don't put anything that may fail after macvlan_common_newlink
* because we can't undo what it does.
*/
- err = ipvlan_link_new(src_net, dev, tb, data, extack);
+ err = ipvlan_link_new(params);
if (err) {
netdev_rx_handler_unregister(dev);
return err;
@@ -4141,10 +4141,13 @@ static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
static struct lock_class_key macsec_netdev_addr_lock_key;
-static int macsec_newlink(struct net *net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int macsec_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct macsec_dev *macsec = macsec_priv(dev);
rx_handler_func_t *rx_handler;
u8 icv_len = MACSEC_DEFAULT_ICV_LEN;
@@ -4154,7 +4157,7 @@ static int macsec_newlink(struct net *net, 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)
@@ -1565,11 +1565,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
}
EXPORT_SYMBOL_GPL(macvlan_common_newlink);
-static int macvlan_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int macvlan_newlink(struct rtnl_newlink_params *params)
{
- return macvlan_common_newlink(src_net, dev, tb, data, extack);
+ return macvlan_common_newlink(rtnl_newlink_link_net(params),
+ params->dev, params->tb, params->data,
+ params->extack);
}
void macvlan_dellink(struct net_device *dev, struct list_head *head)
@@ -77,10 +77,9 @@ static void macvtap_update_features(struct tap_dev *tap,
netdev_update_features(vlan->dev);
}
-static int macvtap_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int macvtap_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
struct macvtap_dev *vlantap = netdev_priv(dev);
int err;
@@ -105,7 +104,8 @@ static int macvtap_newlink(struct net *src_net, struct net_device *dev,
/* Don't put anything that may fail after macvlan_common_newlink
* because we can't undo what it does.
*/
- err = macvlan_common_newlink(src_net, dev, tb, data, extack);
+ err = macvlan_common_newlink(rtnl_newlink_link_net(params), dev,
+ params->tb, params->data, params->extack);
if (err) {
netdev_rx_handler_unregister(dev);
return err;
@@ -327,10 +327,13 @@ static int netkit_validate(struct nlattr *tb[], struct nlattr *data[],
static struct rtnl_link_ops netkit_link_ops;
-static int netkit_new_link(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int netkit_new_link(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb, *attr;
enum netkit_action policy_prim = NETKIT_PASS;
enum netkit_action policy_peer = NETKIT_PASS;
@@ -385,7 +388,7 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
(tb[IFLA_ADDRESS] || tbp[IFLA_ADDRESS]))
return -EOPNOTSUPP;
- net = rtnl_link_get_net(src_net, tbp);
+ net = rtnl_link_get_net(link_net, tbp);
peer = rtnl_create_link(net, ifname, ifname_assign_type,
&netkit_link_ops, tbp, extack);
if (IS_ERR(peer)) {
@@ -184,15 +184,15 @@ static int pfcp_add_sock(struct pfcp_dev *pfcp)
return PTR_ERR_OR_ZERO(pfcp->sock);
}
-static int pfcp_newlink(struct net *net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int pfcp_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct pfcp_dev *pfcp = netdev_priv(dev);
struct pfcp_net *pn;
int err;
- pfcp->net = net;
+ pfcp->net = link_net;
err = pfcp_add_sock(pfcp);
if (err) {
@@ -1303,10 +1303,12 @@ static int ppp_nl_validate(struct nlattr *tb[], struct nlattr *data[],
return 0;
}
-static int ppp_nl_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ppp_nl_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct ppp_config conf = {
.unit = -1,
.ifname_is_set = true,
@@ -1343,7 +1345,7 @@ static int ppp_nl_newlink(struct net *src_net, 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);
@@ -2206,10 +2206,11 @@ static void team_setup(struct net_device *dev)
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
}
-static int team_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int team_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+
if (tb[IFLA_ADDRESS] == NULL)
eth_hw_addr_random(dev);
@@ -1765,10 +1765,13 @@ static int veth_init_queues(struct net_device *dev, struct nlattr *tb[])
return 0;
}
-static int veth_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int veth_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
int err;
struct net_device *peer;
struct veth_priv *priv;
@@ -1800,7 +1803,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
name_assign_type = NET_NAME_ENUM;
}
- net = rtnl_link_get_net(src_net, tbp);
+ net = rtnl_link_get_net(link_net, tbp);
peer = rtnl_create_link(net, ifname, name_assign_type,
&veth_link_ops, tbp, extack);
if (IS_ERR(peer)) {
@@ -1698,10 +1698,11 @@ static void vrf_dellink(struct net_device *dev, struct list_head *head)
unregister_netdevice_queue(dev, head);
}
-static int vrf_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int vrf_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
struct net_vrf *vrf = netdev_priv(dev);
struct netns_vrf *nn_vrf;
bool *add_fib_rules;
@@ -4351,10 +4351,13 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
return 0;
}
-static int vxlan_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int vxlan_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct vxlan_config conf;
int err;
@@ -4362,7 +4365,7 @@ static int vxlan_newlink(struct net *src_net, 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[],
@@ -306,14 +306,14 @@ static void wg_setup(struct net_device *dev)
wg->dev = dev;
}
-static int wg_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int wg_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct wg_device *wg = netdev_priv(dev);
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);
@@ -519,10 +519,12 @@ static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb)
}
/* Called with rtnl lock held. */
-static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int virt_wifi_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
int err;
@@ -532,7 +534,7 @@ static int virt_wifi_newlink(struct net *src_net, 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)
@@ -967,10 +967,11 @@ static struct net_device *wwan_rtnl_alloc(struct nlattr *tb[],
return dev;
}
-static int wwan_rtnl_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int wwan_rtnl_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
struct wwan_device *wwandev = wwan_dev_get_by_parent(dev->dev.parent);
u32 link_id = nla_get_u32(data[IFLA_WWAN_LINK_ID]);
struct wwan_netdev_priv *priv = netdev_priv(dev);
@@ -1064,6 +1065,11 @@ static void wwan_create_default_link(struct wwan_device *wwandev,
struct net_device *dev;
struct nlmsghdr *nlh;
struct sk_buff *msg;
+ struct rtnl_newlink_params params = {
+ .src_net = &init_net,
+ .tb = tb,
+ .data = data,
+ };
/* Forge attributes required to create a WWAN netdev. We first
* build a netlink message and then parse it. This looks
@@ -1105,7 +1111,8 @@ static void wwan_create_default_link(struct wwan_device *wwandev,
if (WARN_ON(IS_ERR(dev)))
goto unlock;
- if (WARN_ON(wwan_rtnl_newlink(&init_net, dev, tb, data, NULL))) {
+ params.dev = dev;
+ if (WARN_ON(wwan_rtnl_newlink(¶ms))) {
free_netdev(dev);
goto unlock;
}
@@ -406,8 +406,9 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
bool log_ecn_error);
int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
struct ip_tunnel_parm_kern *p, __u32 fwmark);
-int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
- struct ip_tunnel_parm_kern *p, __u32 fwmark);
+int ip_tunnel_newlink(struct net *net, struct net_device *dev,
+ struct nlattr *tb[], struct ip_tunnel_parm_kern *p,
+ __u32 fwmark);
void ip_tunnel_setup(struct net_device *dev, unsigned int net_id);
bool ip_tunnel_netlink_encap_parms(struct nlattr *data[],
@@ -69,6 +69,34 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
return AF_UNSPEC;
}
+/**
+ * struct rtnl_newlink_params - parameters of rtnl_link_ops::newlink()
+ *
+ * @src_net: Source netns of rtnetlink socket
+ * @link_net: Link netns by IFLA_LINK_NETNSID, NULL if not specified
+ * @dev: The net_device being created
+ * @tb: IFLA_* attributes
+ * @data: IFLA_INFO_DATA attributes
+ * @extack: Netlink extended ACK
+ */
+struct rtnl_newlink_params {
+ struct net *src_net;
+ struct net *link_net;
+ struct net_device *dev;
+ struct nlattr **tb;
+ struct nlattr **data;
+ struct netlink_ext_ack *extack;
+};
+
+/* 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;
+}
+
/**
* struct rtnl_link_ops - rtnetlink link operations
*
@@ -125,11 +153,7 @@ struct rtnl_link_ops {
struct nlattr *data[],
struct netlink_ext_ack *extack);
- int (*newlink)(struct net *src_net,
- struct net_device *dev,
- struct nlattr *tb[],
- struct nlattr *data[],
- struct netlink_ext_ack *extack);
+ int (*newlink)(struct rtnl_newlink_params *params);
int (*changelink)(struct net_device *dev,
struct nlattr *tb[],
struct nlattr *data[],
@@ -135,10 +135,13 @@ static int vlan_changelink(struct net_device *dev, struct nlattr *tb[],
return 0;
}
-static int vlan_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int vlan_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
struct net_device *real_dev;
unsigned int max_mtu;
@@ -155,7 +158,7 @@ static int vlan_newlink(struct net *src_net, 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;
@@ -1063,7 +1063,7 @@ static int batadv_softif_validate(struct nlattr *tb[], struct nlattr *data[],
/**
* batadv_softif_newlink() - pre-initialize and register new batadv link
- * @src_net: the applicable net namespace
+ * @nets: the applicable net namespaces
* @dev: network device to register
* @tb: IFLA_INFO_DATA netlink attributes
* @data: enum batadv_ifla_attrs attributes
@@ -1071,10 +1071,10 @@ static int batadv_softif_validate(struct nlattr *tb[], struct nlattr *data[],
*
* Return: 0 if successful or error otherwise.
*/
-static int batadv_softif_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int batadv_softif_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
struct batadv_priv *bat_priv = netdev_priv(dev);
const char *algo_name;
int err;
@@ -1553,10 +1553,12 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
return 0;
}
-static int br_dev_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int br_dev_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
struct net_bridge *br = netdev_priv(dev);
int err;
@@ -438,10 +438,10 @@ static void caif_netlink_parms(struct nlattr *data[],
}
}
-static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ipcaif_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
int ret;
struct chnl_net *caifdev;
ASSERT_RTNL();
@@ -3750,6 +3750,13 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
struct net_device *dev;
char ifname[IFNAMSIZ];
int err;
+ struct rtnl_newlink_params params = {
+ .src_net = net,
+ .link_net = link_net,
+ .tb = tb,
+ .data = data,
+ .extack = extack,
+ };
if (!ops->alloc && !ops->setup)
return -EOPNOTSUPP;
@@ -3761,17 +3768,18 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
name_assign_type = NET_NAME_ENUM;
}
- dev = rtnl_create_link(link_net ? : tgt_net, ifname,
- name_assign_type, ops, tb, extack);
+ dev = rtnl_create_link(tgt_net, ifname, name_assign_type, ops, tb,
+ extack);
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
goto out;
}
dev->ifindex = ifm->ifi_index;
+ params.dev = dev;
if (ops->newlink)
- err = ops->newlink(link_net ? : net, dev, tb, data, extack);
+ err = ops->newlink(¶ms);
else
err = register_netdevice(dev);
if (err < 0) {
@@ -3782,11 +3790,6 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
err = rtnl_configure_link(dev, ifm, portid, nlh);
if (err < 0)
goto out_unregister;
- if (link_net) {
- err = dev_change_net_namespace(dev, tgt_net, ifname);
- if (err < 0)
- goto out_unregister;
- }
if (tb[IFLA_MASTER]) {
err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
if (err)
@@ -29,10 +29,12 @@ static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = {
/* Here, it seems a netdevice has already been allocated for us, and the
* hsr_dev_setup routine has been executed. Nice!
*/
-static int hsr_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int hsr_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *link_net = rtnl_newlink_link_net(params);
enum hsr_version proto_version;
unsigned char multicast_spec;
u8 proto = HSR_PROTOCOL_HSR;
@@ -46,7 +48,7 @@ static int hsr_newlink(struct net *src_net, 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");
@@ -56,7 +58,7 @@ static int hsr_newlink(struct net *src_net, 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");
@@ -69,7 +71,7 @@ static int hsr_newlink(struct net *src_net, 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]) {
@@ -129,10 +129,10 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[],
return 0;
}
-static int lowpan_newlink(struct net *src_net, struct net_device *ldev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int lowpan_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *ldev = params->dev;
+ struct nlattr **tb = params->tb;
struct net_device *wdev;
int ret;
@@ -143,7 +143,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *ldev,
if (!tb[IFLA_LINK])
return -EINVAL;
/* find and hold wpan device */
- wdev = dev_get_by_index(dev_net(ldev), nla_get_u32(tb[IFLA_LINK]));
+ wdev = dev_get_by_index(params->link_net ? : dev_net(ldev),
+ nla_get_u32(tb[IFLA_LINK]));
if (!wdev)
return -ENODEV;
if (wdev->type != ARPHRD_IEEE802154) {
@@ -1389,10 +1389,12 @@ ipgre_newlink_encap_setup(struct net_device *dev, struct nlattr *data[])
return 0;
}
-static int ipgre_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ipgre_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip_tunnel_parm_kern p;
__u32 fwmark = 0;
int err;
@@ -1404,13 +1406,15 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev,
err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark);
if (err < 0)
return err;
- return ip_tunnel_newlink(dev, tb, &p, fwmark);
+ return ip_tunnel_newlink(net, dev, tb, &p, fwmark);
}
-static int erspan_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int erspan_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip_tunnel_parm_kern p;
__u32 fwmark = 0;
int err;
@@ -1422,7 +1426,7 @@ static int erspan_newlink(struct net *src_net, struct net_device *dev,
err = erspan_netlink_parms(dev, data, tb, &p, &fwmark);
if (err)
return err;
- return ip_tunnel_newlink(dev, tb, &p, fwmark);
+ return ip_tunnel_newlink(net, dev, tb, &p, fwmark);
}
static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
@@ -1695,6 +1699,10 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
LIST_HEAD(list_kill);
struct ip_tunnel *t;
int err;
+ struct rtnl_newlink_params params = {
+ .src_net = net,
+ .tb = tb,
+ };
memset(&tb, 0, sizeof(tb));
@@ -1707,7 +1715,8 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
t = netdev_priv(dev);
t->collect_md = true;
- err = ipgre_newlink(net, dev, tb, NULL, NULL);
+ params.dev = dev;
+ err = ipgre_newlink(¶ms);
if (err < 0) {
free_netdev(dev);
return ERR_PTR(err);
@@ -1213,11 +1213,11 @@ void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id,
}
EXPORT_SYMBOL_GPL(ip_tunnel_delete_nets);
-int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
- struct ip_tunnel_parm_kern *p, __u32 fwmark)
+int ip_tunnel_newlink(struct net *net, struct net_device *dev,
+ struct nlattr *tb[], struct ip_tunnel_parm_kern *p,
+ __u32 fwmark)
{
struct ip_tunnel *nt;
- struct net *net = dev_net(dev);
struct ip_tunnel_net *itn;
int mtu;
int err;
@@ -1326,7 +1326,9 @@ int ip_tunnel_init(struct net_device *dev)
}
tunnel->dev = dev;
- tunnel->net = dev_net(dev);
+ if (!tunnel->net)
+ tunnel->net = dev_net(dev);
+
strscpy(tunnel->parms.name, dev->name);
iph->version = 4;
iph->ihl = 5;
@@ -575,15 +575,17 @@ static void vti_netlink_parms(struct nlattr *data[],
*fwmark = nla_get_u32(data[IFLA_VTI_FWMARK]);
}
-static int vti_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int vti_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
struct ip_tunnel_parm_kern parms;
__u32 fwmark = 0;
vti_netlink_parms(data, &parms, &fwmark);
- return ip_tunnel_newlink(dev, tb, &parms, fwmark);
+ return ip_tunnel_newlink(params->link_net ? : dev_net(dev), dev, tb,
+ &parms, fwmark);
}
static int vti_changelink(struct net_device *dev, struct nlattr *tb[],
@@ -436,10 +436,11 @@ static void ipip_netlink_parms(struct nlattr *data[],
*fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
}
-static int ipip_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ipip_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
struct ip_tunnel *t = netdev_priv(dev);
struct ip_tunnel_encap ipencap;
struct ip_tunnel_parm_kern p;
@@ -453,7 +454,8 @@ static int ipip_newlink(struct net *src_net, struct net_device *dev,
}
ipip_netlink_parms(data, &p, &t->collect_md, &fwmark);
- return ip_tunnel_newlink(dev, tb, &p, fwmark);
+ return ip_tunnel_newlink(params->link_net ? : dev_net(dev), dev, tb, &p,
+ fwmark);
}
static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
@@ -1971,7 +1971,7 @@ static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
return ret;
}
-static int ip6gre_newlink_common(struct net *src_net, struct net_device *dev,
+static int ip6gre_newlink_common(struct net *link_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
@@ -1992,7 +1992,7 @@ static int ip6gre_newlink_common(struct net *src_net, struct net_device *dev,
eth_hw_addr_random(dev);
nt->dev = dev;
- nt->net = dev_net(dev);
+ nt->net = link_net;
err = register_netdevice(dev);
if (err)
@@ -2005,12 +2005,14 @@ static int ip6gre_newlink_common(struct net *src_net, struct net_device *dev,
return err;
}
-static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ip6gre_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
struct ip6_tnl *nt = netdev_priv(dev);
- struct net *net = dev_net(dev);
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip6gre_net *ign;
int err;
@@ -2025,7 +2027,7 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
}
- err = ip6gre_newlink_common(src_net, dev, tb, data, extack);
+ err = ip6gre_newlink_common(net, dev, tb, data, extack);
if (!err) {
ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
ip6gre_tunnel_link_md(ign, nt);
@@ -2241,12 +2243,14 @@ static void ip6erspan_tap_setup(struct net_device *dev)
netif_keep_dst(dev);
}
-static int ip6erspan_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ip6erspan_newlink(struct rtnl_newlink_params *params)
{
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
struct ip6_tnl *nt = netdev_priv(dev);
- struct net *net = dev_net(dev);
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip6gre_net *ign;
int err;
@@ -2262,7 +2266,7 @@ static int ip6erspan_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
}
- err = ip6gre_newlink_common(src_net, dev, tb, data, extack);
+ err = ip6gre_newlink_common(net, dev, tb, data, extack);
if (!err) {
ip6erspan_tnl_link_config(nt, !tb[IFLA_MTU]);
ip6erspan_tunnel_link_md(ign, nt);
@@ -250,10 +250,9 @@ static void ip6_dev_free(struct net_device *dev)
dst_cache_destroy(&t->dst_cache);
}
-static int ip6_tnl_create2(struct net_device *dev)
+static int ip6_tnl_create2(struct net *net, struct net_device *dev)
{
struct ip6_tnl *t = netdev_priv(dev);
- struct net *net = dev_net(dev);
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
int err;
@@ -308,7 +307,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
t = netdev_priv(dev);
t->parms = *p;
t->net = dev_net(dev);
- err = ip6_tnl_create2(dev);
+ err = ip6_tnl_create2(net, dev);
if (err < 0)
goto failed_free;
@@ -2002,11 +2001,12 @@ static void ip6_tnl_netlink_parms(struct nlattr *data[],
parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
}
-static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ip6_tnl_newlink(struct rtnl_newlink_params *params)
{
- struct net *net = dev_net(dev);
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
struct ip_tunnel_encap ipencap;
struct ip6_tnl *nt, *t;
@@ -2031,7 +2031,7 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
}
- err = ip6_tnl_create2(dev);
+ err = ip6_tnl_create2(net, dev);
if (!err && tb[IFLA_MTU])
ip6_tnl_change_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
@@ -174,10 +174,9 @@ vti6_tnl_unlink(struct vti6_net *ip6n, struct ip6_tnl *t)
}
}
-static int vti6_tnl_create2(struct net_device *dev)
+static int vti6_tnl_create2(struct net *net, struct net_device *dev)
{
struct ip6_tnl *t = netdev_priv(dev);
- struct net *net = dev_net(dev);
struct vti6_net *ip6n = net_generic(net, vti6_net_id);
int err;
@@ -221,7 +220,7 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p
t->parms = *p;
t->net = dev_net(dev);
- err = vti6_tnl_create2(dev);
+ err = vti6_tnl_create2(net, dev);
if (err < 0)
goto failed_free;
@@ -997,11 +996,11 @@ static void vti6_netlink_parms(struct nlattr *data[],
parms->fwmark = nla_get_u32(data[IFLA_VTI_FWMARK]);
}
-static int vti6_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int vti6_newlink(struct rtnl_newlink_params *params)
{
- struct net *net = dev_net(dev);
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip6_tnl *nt;
nt = netdev_priv(dev);
@@ -1012,7 +1011,7 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev,
if (vti6_locate(net, &nt->parms, 0))
return -EEXIST;
- return vti6_tnl_create2(dev);
+ return vti6_tnl_create2(net, dev);
}
static void vti6_dellink(struct net_device *dev, struct list_head *head)
@@ -198,10 +198,9 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
#endif
}
-static int ipip6_tunnel_create(struct net_device *dev)
+static int ipip6_tunnel_create(struct net *net, struct net_device *dev)
{
struct ip_tunnel *t = netdev_priv(dev);
- struct net *net = dev_net(dev);
struct sit_net *sitn = net_generic(net, sit_net_id);
int err;
@@ -270,7 +269,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
nt = netdev_priv(dev);
nt->parms = *parms;
- if (ipip6_tunnel_create(dev) < 0)
+ if (ipip6_tunnel_create(net, dev) < 0)
goto failed_free;
if (!parms->name[0])
@@ -1550,11 +1549,12 @@ static bool ipip6_netlink_6rd_parms(struct nlattr *data[],
}
#endif
-static int ipip6_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int ipip6_newlink(struct rtnl_newlink_params *params)
{
- struct net *net = dev_net(dev);
+ struct net_device *dev = params->dev;
+ struct nlattr **tb = params->tb;
+ struct nlattr **data = params->data;
+ struct net *net = params->link_net ? : dev_net(dev);
struct ip_tunnel *nt;
struct ip_tunnel_encap ipencap;
#ifdef CONFIG_IPV6_SIT_6RD
@@ -1575,7 +1575,7 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev,
if (ipip6_tunnel_locate(net, &nt->parms, 0))
return -EEXIST;
- err = ipip6_tunnel_create(dev);
+ err = ipip6_tunnel_create(net, dev);
if (err < 0)
return err;
@@ -242,10 +242,9 @@ static void xfrmi_dev_free(struct net_device *dev)
gro_cells_destroy(&xi->gro_cells);
}
-static int xfrmi_create(struct net_device *dev)
+static int xfrmi_create(struct net *net, struct net_device *dev)
{
struct xfrm_if *xi = netdev_priv(dev);
- struct net *net = dev_net(dev);
struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
int err;
@@ -814,11 +813,12 @@ static void xfrmi_netlink_parms(struct nlattr *data[],
parms->collect_md = true;
}
-static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[],
- struct netlink_ext_ack *extack)
+static int xfrmi_newlink(struct rtnl_newlink_params *params)
{
- struct net *net = dev_net(dev);
+ struct net_device *dev = params->dev;
+ struct nlattr **data = params->data;
+ struct netlink_ext_ack *extack = params->extack;
+ struct net *net = params->link_net ? : dev_net(dev);
struct xfrm_if_parms p = {};
struct xfrm_if *xi;
int err;
@@ -851,7 +851,7 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
xi->net = net;
xi->dev = dev;
- err = xfrmi_create(dev);
+ err = xfrmi_create(net, dev);
return err;
}