diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-02-22 02:28:07 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-02-22 02:28:07 +0300 |
| commit | 376cd9a2abe4b630e76ae5a3d68f7483edd42003 (patch) | |
| tree | 66e660ee33de0ed798930fd0aa24d7ca3b2228b4 /include | |
| parent | 4fe67dd2d5e5a21a181814bb7ac2a8cb81380753 (diff) | |
| parent | 85cb3711acb84ffb42e935cf1447708e19ccaee9 (diff) | |
| download | linux-376cd9a2abe4b630e76ae5a3d68f7483edd42003.tar.xz | |
Merge branch 'net-improve-netns-handling-in-rtnetlink'
Xiao Liang says:
====================
net: Improve netns handling in rtnetlink
This patch series includes some netns-related improvements and fixes for
rtnetlink, to make link creation more intuitive:
1) Creating link in another net namespace doesn't conflict with link
names in current one.
2) Refector rtnetlink link creation. Create link in target namespace
directly.
So that
# ip link add netns ns1 link-netns ns2 tun0 type gre ...
will create tun0 in ns1, rather than create it in ns2 and move to ns1.
And don't conflict with another interface named "tun0" in current netns.
Patch 01 avoids link name conflict in different netns.
To achieve 2), there're mainly 3 steps:
- Patch 02 packs newlink() parameters into a struct, including
the original "src_net" along with more netns context. No semantic
changes are introduced.
- Patch 03 ~ 09 converts device drivers to use the explicit netns
extracted from params.
- Patch 10 ~ 11 removes the old netns parameter, and converts
rtnetlink to create device in target netns directly.
Patch 12 ~ 13 adds some tests for link name and link netns.
---
Please note there're some issues found in current code:
- In amt_newlink() drivers/net/amt.c:
amt->net = net;
...
amt->stream_dev = dev_get_by_index(net, ...
Uses net, but amt_lookup_upper_dev() only searches in dev_net.
So the AMT device may not be properly deleted if it's in a different
netns from lower dev.
- In lowpan_newlink() in net/ieee802154/6lowpan/core.c:
wdev = dev_get_by_index(dev_net(ldev), nla_get_u32(tb[IFLA_LINK]));
Looks for IFLA_LINK in dev_net, but in theory the ifindex is defined
in link netns.
And thanks to Kuniyuki for fixing related issues in gtp and pfcp:
https://lore.kernel.org/netdev/20250110014754.33847-1-kuniyu@amazon.com/
v9: https://lore.kernel.org/20250210133002.883422-1-shaw.leon@gmail.com
v8: https://lore.kernel.org/20250113143719.7948-1-shaw.leon@gmail.com
v7: https://lore.kernel.org/20250104125732.17335-1-shaw.leon@gmail.com
v6: https://lore.kernel.org/20241218130909.2173-1-shaw.leon@gmail.com
v5: https://lore.kernel.org/20241209140151.231257-1-shaw.leon@gmail.com
v4: https://lore.kernel.org/20241118143244.1773-1-shaw.leon@gmail.com
v3: https://lore.kernel.org/20241113125715.150201-1-shaw.leon@gmail.com
v2: https://lore.kernel.org/20241107133004.7469-1-shaw.leon@gmail.com
v1: https://lore.kernel.org/20241023023146.372653-1-shaw.leon@gmail.com
====================
Link: https://patch.msgid.link/20250219125039.18024-1-shaw.leon@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/if_macvlan.h | 6 | ||||
| -rw-r--r-- | include/net/ip_tunnels.h | 5 | ||||
| -rw-r--r-- | include/net/rtnetlink.h | 40 |
3 files changed, 43 insertions, 8 deletions
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index 523025106a64..0f7281e3e448 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -59,8 +59,10 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, extern void macvlan_common_setup(struct net_device *dev); -extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev, - struct nlattr *tb[], struct nlattr *data[], +struct rtnl_newlink_params; + +extern int macvlan_common_newlink(struct net_device *dev, + struct rtnl_newlink_params *params, struct netlink_ext_ack *extack); extern void macvlan_dellink(struct net_device *dev, struct list_head *head); diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index e041e4865373..a36a335cef9f 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -407,8 +407,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[], diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index bc0069a8b6ea..ec65a8cebb99 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -70,6 +70,40 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh) } /** + * 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 + * @peer_net: Peer netns + * @tb: IFLA_* attributes + * @data: IFLA_INFO_DATA attributes + */ +struct rtnl_newlink_params { + struct net *src_net; + struct net *link_net; + struct net *peer_net; + struct nlattr **tb; + 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 * * @list: Used internally, protected by link_ops_mutex and SRCU @@ -125,10 +159,8 @@ 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[], + int (*newlink)(struct net_device *dev, + struct rtnl_newlink_params *params, struct netlink_ext_ack *extack); int (*changelink)(struct net_device *dev, struct nlattr *tb[], |
