Skip to content

Commit ffc8fa9

Browse files
author
Paolo Abeni
committed
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 addf9b9 ("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: Paolo Abeni <pabeni@redhat.com>
2 parents 9a3cd87 + b5e837c commit ffc8fa9

File tree

15 files changed

+176
-89
lines changed

15 files changed

+176
-89
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void)
49134913
if (rc)
49144914
goto out4;
49154915

4916-
vxlan_vnifilter_init();
4916+
rc = vxlan_vnifilter_init();
4917+
if (rc)
4918+
goto out5;
49174919

49184920
return 0;
4921+
out5:
4922+
rtnl_link_unregister(&vxlan_link_ops);
49194923
out4:
49204924
unregister_switchdev_notifier(&vxlan_switchdev_notifier_block);
49214925
out3:

drivers/net/vxlan/vxlan_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
202202
int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
203203
void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);
204204

205-
void vxlan_vnifilter_init(void);
205+
int vxlan_vnifilter_init(void);
206206
void vxlan_vnifilter_uninit(void);
207207
void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
208208
struct vxlan_vni_node *vninode,

drivers/net/vxlan/vxlan_vnifilter.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -992,19 +992,18 @@ static int vxlan_vnifilter_process(struct sk_buff *skb, struct nlmsghdr *nlh,
992992
return err;
993993
}
994994

995-
void vxlan_vnifilter_init(void)
995+
static const struct rtnl_msg_handler vxlan_vnifilter_rtnl_msg_handlers[] = {
996+
{THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, vxlan_vnifilter_dump, 0},
997+
{THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, vxlan_vnifilter_process, NULL, 0},
998+
{THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, vxlan_vnifilter_process, NULL, 0},
999+
};
1000+
1001+
int vxlan_vnifilter_init(void)
9961002
{
997-
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL,
998-
vxlan_vnifilter_dump, 0);
999-
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL,
1000-
vxlan_vnifilter_process, NULL, 0);
1001-
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL,
1002-
vxlan_vnifilter_process, NULL, 0);
1003+
return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers);
10031004
}
10041005

10051006
void vxlan_vnifilter_uninit(void)
10061007
{
1007-
rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL);
1008-
rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL);
1009-
rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL);
1008+
rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers);
10101009
}

include/net/mctp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ void mctp_neigh_remove_dev(struct mctp_dev *mdev);
295295
int mctp_routes_init(void);
296296
void mctp_routes_exit(void);
297297

298-
void mctp_device_init(void);
298+
int mctp_device_init(void);
299299
void mctp_device_exit(void);
300300

301301
#endif /* __NET_MCTP_H */

include/net/rtnetlink.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,30 @@ static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype)
2929
return msgtype & RTNL_KIND_MASK;
3030
}
3131

32+
struct rtnl_msg_handler {
33+
struct module *owner;
34+
int protocol;
35+
int msgtype;
36+
rtnl_doit_func doit;
37+
rtnl_dumpit_func dumpit;
38+
int flags;
39+
};
40+
3241
void rtnl_register(int protocol, int msgtype,
3342
rtnl_doit_func, rtnl_dumpit_func, unsigned int flags);
3443
int rtnl_register_module(struct module *owner, int protocol, int msgtype,
3544
rtnl_doit_func, rtnl_dumpit_func, unsigned int flags);
3645
int rtnl_unregister(int protocol, int msgtype);
3746
void rtnl_unregister_all(int protocol);
3847

48+
int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n);
49+
void __rtnl_unregister_many(const struct rtnl_msg_handler *handlers, int n);
50+
51+
#define rtnl_register_many(handlers) \
52+
__rtnl_register_many(handlers, ARRAY_SIZE(handlers))
53+
#define rtnl_unregister_many(handlers) \
54+
__rtnl_unregister_many(handlers, ARRAY_SIZE(handlers))
55+
3956
static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
4057
{
4158
if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg))

net/bridge/br_netlink.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,10 @@ int __init br_netlink_init(void)
19201920
{
19211921
int err;
19221922

1923-
br_vlan_rtnl_init();
1923+
err = br_vlan_rtnl_init();
1924+
if (err)
1925+
goto out;
1926+
19241927
rtnl_af_register(&br_af_ops);
19251928

19261929
err = rtnl_link_register(&br_link_ops);
@@ -1931,6 +1934,7 @@ int __init br_netlink_init(void)
19311934

19321935
out_af:
19331936
rtnl_af_unregister(&br_af_ops);
1937+
out:
19341938
return err;
19351939
}
19361940

net/bridge/br_private.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,7 +1571,7 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
15711571
void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
15721572
int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
15731573
void *ptr);
1574-
void br_vlan_rtnl_init(void);
1574+
int br_vlan_rtnl_init(void);
15751575
void br_vlan_rtnl_uninit(void);
15761576
void br_vlan_notify(const struct net_bridge *br,
15771577
const struct net_bridge_port *p,
@@ -1802,8 +1802,9 @@ static inline int br_vlan_bridge_event(struct net_device *dev,
18021802
return 0;
18031803
}
18041804

1805-
static inline void br_vlan_rtnl_init(void)
1805+
static inline int br_vlan_rtnl_init(void)
18061806
{
1807+
return 0;
18071808
}
18081809

18091810
static inline void br_vlan_rtnl_uninit(void)

net/bridge/br_vlan.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,19 +2296,18 @@ static int br_vlan_rtm_process(struct sk_buff *skb, struct nlmsghdr *nlh,
22962296
return err;
22972297
}
22982298

2299-
void br_vlan_rtnl_init(void)
2299+
static const struct rtnl_msg_handler br_vlan_rtnl_msg_handlers[] = {
2300+
{THIS_MODULE, PF_BRIDGE, RTM_NEWVLAN, br_vlan_rtm_process, NULL, 0},
2301+
{THIS_MODULE, PF_BRIDGE, RTM_DELVLAN, br_vlan_rtm_process, NULL, 0},
2302+
{THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL, br_vlan_rtm_dump, 0},
2303+
};
2304+
2305+
int br_vlan_rtnl_init(void)
23002306
{
2301-
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL,
2302-
br_vlan_rtm_dump, 0);
2303-
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWVLAN,
2304-
br_vlan_rtm_process, NULL, 0);
2305-
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELVLAN,
2306-
br_vlan_rtm_process, NULL, 0);
2307+
return rtnl_register_many(br_vlan_rtnl_msg_handlers);
23072308
}
23082309

23092310
void br_vlan_rtnl_uninit(void)
23102311
{
2311-
rtnl_unregister(PF_BRIDGE, RTM_GETVLAN);
2312-
rtnl_unregister(PF_BRIDGE, RTM_NEWVLAN);
2313-
rtnl_unregister(PF_BRIDGE, RTM_DELVLAN);
2312+
rtnl_unregister_many(br_vlan_rtnl_msg_handlers);
23142313
}

net/core/rtnetlink.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,35 @@ void rtnl_unregister_all(int protocol)
384384
}
385385
EXPORT_SYMBOL_GPL(rtnl_unregister_all);
386386

387+
int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n)
388+
{
389+
const struct rtnl_msg_handler *handler;
390+
int i, err;
391+
392+
for (i = 0, handler = handlers; i < n; i++, handler++) {
393+
err = rtnl_register_internal(handler->owner, handler->protocol,
394+
handler->msgtype, handler->doit,
395+
handler->dumpit, handler->flags);
396+
if (err) {
397+
__rtnl_unregister_many(handlers, i);
398+
break;
399+
}
400+
}
401+
402+
return err;
403+
}
404+
EXPORT_SYMBOL_GPL(__rtnl_register_many);
405+
406+
void __rtnl_unregister_many(const struct rtnl_msg_handler *handlers, int n)
407+
{
408+
const struct rtnl_msg_handler *handler;
409+
int i;
410+
411+
for (i = n - 1, handler = handlers + n - 1; i >= 0; i--, handler--)
412+
rtnl_unregister(handler->protocol, handler->msgtype);
413+
}
414+
EXPORT_SYMBOL_GPL(__rtnl_unregister_many);
415+
387416
static LIST_HEAD(link_ops);
388417

389418
static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)

net/mctp/af_mctp.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,14 @@ static __init int mctp_init(void)
756756
if (rc)
757757
goto err_unreg_routes;
758758

759-
mctp_device_init();
759+
rc = mctp_device_init();
760+
if (rc)
761+
goto err_unreg_neigh;
760762

761763
return 0;
762764

765+
err_unreg_neigh:
766+
mctp_neigh_exit();
763767
err_unreg_routes:
764768
mctp_routes_exit();
765769
err_unreg_proto:

0 commit comments

Comments
 (0)