Commit d89fa273 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'rtnetlink-refactor-rtnl_-new-del-set-link-for-per-netns-rtnl'

Kuniyuki Iwashima says:

====================
rtnetlink: Refactor rtnl_{new,del,set}link() for per-netns RTNL.

This is a prep for the next series where we will push RTNL down to
rtnl_{new,del,set}link().

That means, for example, __rtnl_newlink() is always under RTNL, but
rtnl_newlink() has a non-RTNL section.

As a prerequisite for per-netns RTNL, we will move netns validation
(and RTNL-independent validations if possible) to that section.

rtnl_link_ops and rtnl_af_ops will be protected with SRCU not to
depend on RTNL.

Changes:
  v2:
    * Add Eric's Reviewed-by to patch 1-4,6,8-11, (no tag on 5,7,12-14)
    * Patch 7
      * Handle error of init_srcu_struct().
      * Call cleanup_srcu_struct() after synchronize_srcu().
    * Patch 12
      * Move put_net() before errorout label
    * Patch 13
      * Newly added as prep for patch 14
    * Patch 14
      * Handle error of init_srcu_struct().
      * Call cleanup_srcu_struct() after synchronize_srcu().

  v1: https://lore.kernel.org/netdev/20241009231656.57830-1-kuniyu@amazon.com/
====================

Link: https://patch.msgid.link/20241016185357.83849-1-kuniyu@amazon.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 6f07cd83 6ab0f866
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#define __NET_RTNETLINK_H

#include <linux/rtnetlink.h>
#include <linux/srcu.h>
#include <net/netlink.h>

typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *,
@@ -69,7 +70,8 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
/**
 *	struct rtnl_link_ops - rtnetlink link operations
 *
 *	@list: Used internally
 *	@list: Used internally, protected by RTNL and SRCU
 *	@srcu: Used internally
 *	@kind: Identifier
 *	@netns_refund: Physical device, move to init_net on netns exit
 *	@maxtype: Highest device specific netlink attribute number
@@ -100,6 +102,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
 */
struct rtnl_link_ops {
	struct list_head	list;
	struct srcu_struct	srcu;

	const char		*kind;

@@ -169,7 +172,8 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops);
/**
 * 	struct rtnl_af_ops - rtnetlink address family operations
 *
 *	@list: Used internally
 *	@list: Used internally, protected by RTNL and SRCU
 *	@srcu: Used internally
 * 	@family: Address family
 * 	@fill_link_af: Function to fill IFLA_AF_SPEC with address family
 * 		       specific netlink attributes.
@@ -182,6 +186,8 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops);
 */
struct rtnl_af_ops {
	struct list_head	list;
	struct srcu_struct	srcu;

	int			family;

	int			(*fill_link_af)(struct sk_buff *skb,
@@ -201,7 +207,7 @@ struct rtnl_af_ops {
	size_t			(*get_stats_af_size)(const struct net_device *dev);
};

void rtnl_af_register(struct rtnl_af_ops *ops);
int rtnl_af_register(struct rtnl_af_ops *ops);
void rtnl_af_unregister(struct rtnl_af_ops *ops);

struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]);
+5 −1
Original line number Diff line number Diff line
@@ -1924,7 +1924,9 @@ int __init br_netlink_init(void)
	if (err)
		goto out;

	rtnl_af_register(&br_af_ops);
	err = rtnl_af_register(&br_af_ops);
	if (err)
		goto out_vlan;

	err = rtnl_link_register(&br_link_ops);
	if (err)
@@ -1934,6 +1936,8 @@ int __init br_netlink_init(void)

out_af:
	rtnl_af_unregister(&br_af_ops);
out_vlan:
	br_vlan_rtnl_uninit();
out:
	return err;
}
+316 −251

File changed.

Preview size limit exceeded, changes collapsed.

+2 −1
Original line number Diff line number Diff line
@@ -2827,7 +2827,8 @@ void __init devinet_init(void)
	register_pernet_subsys(&devinet_ops);
	register_netdevice_notifier(&ip_netdev_notifier);

	rtnl_af_register(&inet_af_ops);
	if (rtnl_af_register(&inet_af_ops))
		panic("Unable to register inet_af_ops\n");

	rtnl_register_many(devinet_rtnl_msg_handlers);
}
+4 −1
Original line number Diff line number Diff line
@@ -7468,7 +7468,9 @@ int __init addrconf_init(void)

	addrconf_verify(&init_net);

	rtnl_af_register(&inet6_ops);
	err = rtnl_af_register(&inet6_ops);
	if (err)
		goto erraf;

	err = rtnl_register_many(addrconf_rtnl_msg_handlers);
	if (err)
@@ -7482,6 +7484,7 @@ int __init addrconf_init(void)
errout:
	rtnl_unregister_all(PF_INET6);
	rtnl_af_unregister(&inet6_ops);
erraf:
	unregister_netdevice_notifier(&ipv6_dev_notf);
errlo:
	destroy_workqueue(addrconf_wq);
Loading