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

Merge branch 'rtnetlink-handle-error-of-rtnl_register_module'

Kuniyuki Iwashima says:

====================
rtnetlink: Handle error of rtnl_register_module().

While converting phonet to per-netns RTNL, I found a weird comment

  /* Further rtnl_register_module() cannot fail */

that was true but no longer true after commit addf9b90 ("net:
rtnetlink: use rcu to free rtnl message handlers").

Many callers of rtnl_register_module() just ignore the returned
value but should handle them properly.

This series introduces two helpers, rtnl_register_many() and
rtnl_unregister_many(), to do that easily and fix such callers.

All rtnl_register() and rtnl_register_module() will be converted
to _many() variant and some rtnl_lock() will be saved in _many()
later in net-next.

Changes:
  v4:
    * Add more context in changelog of each patch

  v3: https://lore.kernel.org/all/20241007124459.5727-1-kuniyu@amazon.com/
    * Move module *owner to struct rtnl_msg_handler
    * Make struct rtnl_msg_handler args/vars const
    * Update mctp goto labels

  v2: https://lore.kernel.org/netdev/20241004222358.79129-1-kuniyu@amazon.com/
    * Remove __exit from mctp_neigh_exit().

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

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


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 9a3cd877 b5e837c8
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void)
	if (rc)
		goto out4;

	vxlan_vnifilter_init();
	rc = vxlan_vnifilter_init();
	if (rc)
		goto out5;

	return 0;
out5:
	rtnl_link_unregister(&vxlan_link_ops);
out4:
	unregister_switchdev_notifier(&vxlan_switchdev_notifier_block);
out3:
+1 −1
Original line number Diff line number Diff line
@@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);

void vxlan_vnifilter_init(void);
int vxlan_vnifilter_init(void);
void vxlan_vnifilter_uninit(void);
void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
			   struct vxlan_vni_node *vninode,
+9 −10
Original line number Diff line number Diff line
@@ -992,19 +992,18 @@ static int vxlan_vnifilter_process(struct sk_buff *skb, struct nlmsghdr *nlh,
	return err;
}

void vxlan_vnifilter_init(void)
static const struct rtnl_msg_handler vxlan_vnifilter_rtnl_msg_handlers[] = {
	{THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, vxlan_vnifilter_dump, 0},
	{THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, vxlan_vnifilter_process, NULL, 0},
	{THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, vxlan_vnifilter_process, NULL, 0},
};

int vxlan_vnifilter_init(void)
{
	rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL,
			     vxlan_vnifilter_dump, 0);
	rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL,
			     vxlan_vnifilter_process, NULL, 0);
	rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL,
			     vxlan_vnifilter_process, NULL, 0);
	return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers);
}

void vxlan_vnifilter_uninit(void)
{
	rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL);
	rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL);
	rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL);
	rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers);
}
+1 −1
Original line number Diff line number Diff line
@@ -295,7 +295,7 @@ void mctp_neigh_remove_dev(struct mctp_dev *mdev);
int mctp_routes_init(void);
void mctp_routes_exit(void);

void mctp_device_init(void);
int mctp_device_init(void);
void mctp_device_exit(void);

#endif /* __NET_MCTP_H */
+17 −0
Original line number Diff line number Diff line
@@ -29,6 +29,15 @@ static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype)
	return msgtype & RTNL_KIND_MASK;
}

struct rtnl_msg_handler {
	struct module *owner;
	int protocol;
	int msgtype;
	rtnl_doit_func doit;
	rtnl_dumpit_func dumpit;
	int flags;
};

void rtnl_register(int protocol, int msgtype,
		   rtnl_doit_func, rtnl_dumpit_func, unsigned int flags);
int rtnl_register_module(struct module *owner, int protocol, int msgtype,
@@ -36,6 +45,14 @@ int rtnl_register_module(struct module *owner, int protocol, int msgtype,
int rtnl_unregister(int protocol, int msgtype);
void rtnl_unregister_all(int protocol);

int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n);
void __rtnl_unregister_many(const struct rtnl_msg_handler *handlers, int n);

#define rtnl_register_many(handlers)				\
	__rtnl_register_many(handlers, ARRAY_SIZE(handlers))
#define rtnl_unregister_many(handlers)				\
	__rtnl_unregister_many(handlers, ARRAY_SIZE(handlers))

static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
{
	if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg))
Loading