diff mbox series

[v1,net-next,3/8] rtnetlink: Add peer_type in struct rtnl_link_ops.

Message ID 20241105020514.41963-4-kuniyu@amazon.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series rtnetlink: Convert rtnl_newlink() to per-netns RTNL. | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 16 this patch: 16
netdev/build_tools success Errors and warnings before: 2 (+0) this patch: 2 (+0)
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 31 this patch: 31
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 2866 this patch: 2866
netdev/checkpatch warning WARNING: line length of 87 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 13 this patch: 13
netdev/source_inline success Was 0 now: 0
netdev/contest fail net-next-2024-11-05--09-00 (tests: 777)

Commit Message

Kuniyuki Iwashima Nov. 5, 2024, 2:05 a.m. UTC
For veth, vxcan, and netkit, we need to prefetch the peer device's
netns in rtnl_newlink() for per-netns RTNL.

All of the three get the netns in the same way peer netlink attr tb:

  1. Call rtnl_nla_parse_ifinfomsg()
  2. Call ops->validate() (vxcan doesn't have)
  3. Call rtnl_link_get_net_tb()

Let's add a new field peer_type to struct rtnl_link_ops and fetch
netns in peer attrbutes to add it to rtnl_nets in rtnl_newlink().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/rtnetlink.h |  2 ++
 net/core/rtnetlink.c    | 39 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

Comments

Eric Dumazet Nov. 5, 2024, 10:23 a.m. UTC | #1
On Tue, Nov 5, 2024 at 3:06 AM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> For veth, vxcan, and netkit, we need to prefetch the peer device's
> netns in rtnl_newlink() for per-netns RTNL.
>
> All of the three get the netns in the same way peer netlink attr tb:
>
>   1. Call rtnl_nla_parse_ifinfomsg()
>   2. Call ops->validate() (vxcan doesn't have)
>   3. Call rtnl_link_get_net_tb()
>
> Let's add a new field peer_type to struct rtnl_link_ops and fetch
> netns in peer attrbutes to add it to rtnl_nets in rtnl_newlink().
>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>

 Reviewed-by: Eric Dumazet <edumazet@google.com>
Jakub Kicinski Nov. 6, 2024, 12:39 a.m. UTC | #2
On Mon, 4 Nov 2024 18:05:09 -0800 Kuniyuki Iwashima wrote:
> +	const unsigned char	peer_type;

technically netlink attr types are 14b wide or some such
Jakub Kicinski Nov. 6, 2024, 12:39 a.m. UTC | #3
On Tue, 5 Nov 2024 16:39:11 -0800 Jakub Kicinski wrote:
> On Mon, 4 Nov 2024 18:05:09 -0800 Kuniyuki Iwashima wrote:
> > +	const unsigned char	peer_type;  
> 
> technically netlink attr types are 14b wide or some such

I guess compiler will warn if someone tries to use < 255
Kuniyuki Iwashima Nov. 6, 2024, 12:52 a.m. UTC | #4
From: Jakub Kicinski <kuba@kernel.org>
Date: Tue, 5 Nov 2024 16:39:57 -0800
> On Tue, 5 Nov 2024 16:39:11 -0800 Jakub Kicinski wrote:
> > On Mon, 4 Nov 2024 18:05:09 -0800 Kuniyuki Iwashima wrote:
> > > +	const unsigned char	peer_type;  
> > 
> > technically netlink attr types are 14b wide or some such
> 
> I guess compiler will warn if someone tries to use < 255

I chose 1 just because all of the three peer attr types were 1.
Should peer_type be u16 or extend when a future device use >255 for
peer ifla ?

  VETH_INFO_PEER
  VXCAN_INFO_PEER
  IFLA_NETKIT_PEER_INFO
Kuniyuki Iwashima Nov. 6, 2024, 12:58 a.m. UTC | #5
From: Kuniyuki Iwashima <kuniyu@amazon.com>
Date: Tue, 5 Nov 2024 16:52:37 -0800
> From: Jakub Kicinski <kuba@kernel.org>
> Date: Tue, 5 Nov 2024 16:39:57 -0800
> > On Tue, 5 Nov 2024 16:39:11 -0800 Jakub Kicinski wrote:
> > > On Mon, 4 Nov 2024 18:05:09 -0800 Kuniyuki Iwashima wrote:
> > > > +	const unsigned char	peer_type;  
> > > 
> > > technically netlink attr types are 14b wide or some such
> > 
> > I guess compiler will warn if someone tries to use < 255
> 
> I chose 1 just because all of the three peer attr types were 1.

s/chose 1/chose u8/ :)


> Should peer_type be u16 or extend when a future device use >255 for
> peer ifla ?
> 
>   VETH_INFO_PEER
>   VXCAN_INFO_PEER
>   IFLA_NETKIT_PEER_INFO
Jakub Kicinski Nov. 6, 2024, 1:04 a.m. UTC | #6
On Tue, 5 Nov 2024 16:58:25 -0800 Kuniyuki Iwashima wrote:
> > > I guess compiler will warn if someone tries to use < 255  
> > 
> > I chose 1 just because all of the three peer attr types were 1.  
> 
> s/chose 1/chose u8/ :)
> 
> 
> > Should peer_type be u16 or extend when a future device use >255 for
> > peer ifla ?

I think we can extend in the future if you're doing this for packing
reasons. Barely any family has more attrs than 256 and as I replied to
myself we will assign a constant so compiler will warn us.
Kuniyuki Iwashima Nov. 6, 2024, 1:22 a.m. UTC | #7
From: Jakub Kicinski <kuba@kernel.org>
Date: Tue, 5 Nov 2024 17:04:47 -0800
> On Tue, 5 Nov 2024 16:58:25 -0800 Kuniyuki Iwashima wrote:
> > > > I guess compiler will warn if someone tries to use < 255  
> > > 
> > > I chose 1 just because all of the three peer attr types were 1.  
> > 
> > s/chose 1/chose u8/ :)
> > 
> > 
> > > Should peer_type be u16 or extend when a future device use >255 for
> > > peer ifla ?
> 
> I think we can extend in the future if you're doing this for packing
> reasons. Barely any family has more attrs than 256 and as I replied to
> myself we will assign a constant so compiler will warn us.

I have no strong preference so will use u16.
Also, there was a 3-bytes hole.

Thanks!
diff mbox series

Patch

diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index b9ed44b2d056..c3548da95ffa 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -85,6 +85,7 @@  void rtnl_nets_add(struct rtnl_nets *rtnl_nets, struct net *net);
  *	@srcu: Used internally
  *	@kind: Identifier
  *	@netns_refund: Physical device, move to init_net on netns exit
+ *	@peer_type: Peer device specific netlink attribute number (e.g. VETH_INFO_PEER)
  *	@maxtype: Highest device specific netlink attribute number
  *	@policy: Netlink policy for device specific attribute validation
  *	@validate: Optional validation function for netlink/changelink parameters
@@ -126,6 +127,7 @@  struct rtnl_link_ops {
 	void			(*setup)(struct net_device *dev);
 
 	bool			netns_refund;
+	const unsigned char	peer_type;
 	unsigned int		maxtype;
 	const struct nla_policy	*policy;
 	int			(*validate)(struct nlattr *tb[],
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1bc8afcefc1e..48bd9e062550 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3798,6 +3798,37 @@  static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
 	goto out;
 }
 
+static int rtnl_add_peer_net(struct rtnl_nets *rtnl_nets,
+			     const struct rtnl_link_ops *ops,
+			     struct nlattr *data[],
+			     struct netlink_ext_ack *extack)
+{
+	struct nlattr *tb[IFLA_MAX + 1];
+	struct net *net;
+	int err;
+
+	if (!data || !data[ops->peer_type])
+		return 0;
+
+	err = rtnl_nla_parse_ifinfomsg(tb, data[ops->peer_type], extack);
+	if (err < 0)
+		return err;
+
+	if (ops->validate) {
+		err = ops->validate(tb, NULL, extack);
+		if (err < 0)
+			return err;
+	}
+
+	net = rtnl_link_get_net_tb(tb);
+	if (IS_ERR(net))
+		return PTR_ERR(net);
+	if (net)
+		rtnl_nets_add(rtnl_nets, net);
+
+	return 0;
+}
+
 static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 			  const struct rtnl_link_ops *ops,
 			  struct net *tgt_net, struct net *link_net,
@@ -3926,12 +3957,18 @@  static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (ret < 0)
 				goto put_ops;
 		}
+
+		if (ops->peer_type) {
+			ret = rtnl_add_peer_net(&rtnl_nets, ops, data, extack);
+			if (ret < 0)
+				goto put_ops;
+		}
 	}
 
 	tgt_net = rtnl_link_get_net_capable(skb, sock_net(skb->sk), tb, CAP_NET_ADMIN);
 	if (IS_ERR(tgt_net)) {
 		ret = PTR_ERR(tgt_net);
-		goto put_ops;
+		goto put_net;
 	}
 
 	rtnl_nets_add(&rtnl_nets, tgt_net);