Skip to content

Commit

Permalink
Merge branch 'rtnetlink-use-rtnl_register_many'
Browse files Browse the repository at this point in the history
Kuniyuki Iwashima says:

====================
rtnetlink: Use rtnl_register_many().

This series converts all rtnl_register() and rtnl_register_module()
to rtnl_register_many() and finally removes them.

Once this series is applied, I'll start converting doit() to per-netns
RTNL.

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

Link: https://patch.msgid.link/20241014201828.91221-1-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Oct 16, 2024
2 parents df24129 + e1c6c38 commit 53bac83
Show file tree
Hide file tree
Showing 20 changed files with 267 additions and 258 deletions.
15 changes: 10 additions & 5 deletions include/net/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype)
return msgtype & RTNL_KIND_MASK;
}

/**
* struct rtnl_msg_handler - rtnetlink message type and handlers
*
* @owner: NULL for built-in, THIS_MODULE for module
* @protocol: Protocol family or PF_UNSPEC
* @msgtype: rtnetlink message type
* @doit: Function pointer called for each request message
* @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
* @flags: rtnl_link_flags to modify behaviour of doit/dumpit functions
*/
struct rtnl_msg_handler {
struct module *owner;
int protocol;
Expand All @@ -38,11 +48,6 @@ struct rtnl_msg_handler {
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,
rtnl_doit_func, rtnl_dumpit_func, unsigned int flags);
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);
Expand Down
29 changes: 12 additions & 17 deletions net/can/gw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,15 @@ static struct pernet_operations cangw_pernet_ops = {
.exit_batch = cangw_pernet_exit_batch,
};

static const struct rtnl_msg_handler cgw_rtnl_msg_handlers[] __initconst_or_module = {
{.owner = THIS_MODULE, .protocol = PF_CAN, .msgtype = RTM_NEWROUTE,
.doit = cgw_create_job},
{.owner = THIS_MODULE, .protocol = PF_CAN, .msgtype = RTM_DELROUTE,
.doit = cgw_remove_job},
{.owner = THIS_MODULE, .protocol = PF_CAN, .msgtype = RTM_GETROUTE,
.dumpit = cgw_dump_jobs},
};

static __init int cgw_module_init(void)
{
int ret;
Expand All @@ -1290,27 +1299,13 @@ static __init int cgw_module_init(void)
if (ret)
goto out_register_notifier;

ret = rtnl_register_module(THIS_MODULE, PF_CAN, RTM_GETROUTE,
NULL, cgw_dump_jobs, 0);
if (ret)
goto out_rtnl_register1;

ret = rtnl_register_module(THIS_MODULE, PF_CAN, RTM_NEWROUTE,
cgw_create_job, NULL, 0);
if (ret)
goto out_rtnl_register2;
ret = rtnl_register_module(THIS_MODULE, PF_CAN, RTM_DELROUTE,
cgw_remove_job, NULL, 0);
ret = rtnl_register_many(cgw_rtnl_msg_handlers);
if (ret)
goto out_rtnl_register3;
goto out_rtnl_register;

return 0;

out_rtnl_register3:
rtnl_unregister(PF_CAN, RTM_NEWROUTE);
out_rtnl_register2:
rtnl_unregister(PF_CAN, RTM_GETROUTE);
out_rtnl_register1:
out_rtnl_register:
unregister_netdevice_notifier(&notifier);
out_register_notifier:
kmem_cache_destroy(cgw_cache);
Expand Down
17 changes: 10 additions & 7 deletions net/core/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -1291,13 +1291,18 @@ static struct pernet_operations fib_rules_net_ops = {
.exit = fib_rules_net_exit,
};

static const struct rtnl_msg_handler fib_rules_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_NEWRULE, .doit = fib_nl_newrule},
{.msgtype = RTM_DELRULE, .doit = fib_nl_delrule},
{.msgtype = RTM_GETRULE, .dumpit = fib_nl_dumprule,
.flags = RTNL_FLAG_DUMP_UNLOCKED},
};

static int __init fib_rules_init(void)
{
int err;
rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule,
RTNL_FLAG_DUMP_UNLOCKED);

rtnl_register_many(fib_rules_rtnl_msg_handlers);

err = register_pernet_subsys(&fib_rules_net_ops);
if (err < 0)
Expand All @@ -1312,9 +1317,7 @@ static int __init fib_rules_init(void)
fail_unregister:
unregister_pernet_subsys(&fib_rules_net_ops);
fail:
rtnl_unregister(PF_UNSPEC, RTM_NEWRULE);
rtnl_unregister(PF_UNSPEC, RTM_DELRULE);
rtnl_unregister(PF_UNSPEC, RTM_GETRULE);
rtnl_unregister_many(fib_rules_rtnl_msg_handlers);
return err;
}

Expand Down
19 changes: 10 additions & 9 deletions net/core/neighbour.c
Original file line number Diff line number Diff line change
Expand Up @@ -3886,17 +3886,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);

#endif /* CONFIG_SYSCTL */

static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
.flags = RTNL_FLAG_DUMP_UNLOCKED},
{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
};

static int __init neigh_init(void)
{
rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_GETNEIGH, neigh_get, neigh_dump_info,
RTNL_FLAG_DUMP_UNLOCKED);

rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info,
0);
rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0);

rtnl_register_many(neigh_rtnl_msg_handlers);
return 0;
}

Expand Down
14 changes: 9 additions & 5 deletions net/core/net_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,14 @@ static void __init netns_ipv4_struct_check(void)
}
#endif

static const struct rtnl_msg_handler net_ns_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_NEWNSID, .doit = rtnl_net_newid,
.flags = RTNL_FLAG_DOIT_UNLOCKED},
{.msgtype = RTM_GETNSID, .doit = rtnl_net_getid,
.dumpit = rtnl_net_dumpid,
.flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
};

void __init net_ns_init(void)
{
struct net_generic *ng;
Expand Down Expand Up @@ -1206,11 +1214,7 @@ void __init net_ns_init(void)
if (register_pernet_subsys(&net_ns_ops))
panic("Could not register network namespace subsystems");

rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL,
RTNL_FLAG_DOIT_UNLOCKED);
rtnl_register(PF_UNSPEC, RTM_GETNSID, rtnl_net_getid, rtnl_net_dumpid,
RTNL_FLAG_DOIT_UNLOCKED |
RTNL_FLAG_DUMP_UNLOCKED);
rtnl_register_many(net_ns_rtnl_msg_handlers);
}

static void free_exit_list(struct pernet_operations *ops, struct list_head *net_exit_list)
Expand Down
141 changes: 58 additions & 83 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,65 +338,14 @@ static int rtnl_register_internal(struct module *owner,
return ret;
}

/**
* rtnl_register_module - Register a rtnetlink message type
*
* @owner: module registering the hook (THIS_MODULE)
* @protocol: Protocol family or PF_UNSPEC
* @msgtype: rtnetlink message type
* @doit: Function pointer called for each request message
* @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
* @flags: rtnl_link_flags to modify behaviour of doit/dumpit functions
*
* Like rtnl_register, but for use by removable modules.
*/
int rtnl_register_module(struct module *owner,
int protocol, int msgtype,
rtnl_doit_func doit, rtnl_dumpit_func dumpit,
unsigned int flags)
{
return rtnl_register_internal(owner, protocol, msgtype,
doit, dumpit, flags);
}
EXPORT_SYMBOL_GPL(rtnl_register_module);

/**
* rtnl_register - Register a rtnetlink message type
* @protocol: Protocol family or PF_UNSPEC
* @msgtype: rtnetlink message type
* @doit: Function pointer called for each request message
* @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
* @flags: rtnl_link_flags to modify behaviour of doit/dumpit functions
*
* Registers the specified function pointers (at least one of them has
* to be non-NULL) to be called whenever a request message for the
* specified protocol family and message type is received.
*
* The special protocol family PF_UNSPEC may be used to define fallback
* function pointers for the case when no entry for the specific protocol
* family exists.
*/
void rtnl_register(int protocol, int msgtype,
rtnl_doit_func doit, rtnl_dumpit_func dumpit,
unsigned int flags)
{
int err;

err = rtnl_register_internal(NULL, protocol, msgtype, doit, dumpit,
flags);
if (err)
pr_err("Unable to register rtnetlink message handler, "
"protocol = %d, message type = %d\n", protocol, msgtype);
}

/**
* rtnl_unregister - Unregister a rtnetlink message type
* @protocol: Protocol family or PF_UNSPEC
* @msgtype: rtnetlink message type
*
* Returns 0 on success or a negative error code.
*/
int rtnl_unregister(int protocol, int msgtype)
static int rtnl_unregister(int protocol, int msgtype)
{
struct rtnl_link __rcu **tab;
struct rtnl_link *link;
Expand All @@ -419,7 +368,6 @@ int rtnl_unregister(int protocol, int msgtype)

return 0;
}
EXPORT_SYMBOL_GPL(rtnl_unregister);

/**
* rtnl_unregister_all - Unregister all rtnetlink message type of a protocol
Expand Down Expand Up @@ -454,6 +402,26 @@ void rtnl_unregister_all(int protocol)
}
EXPORT_SYMBOL_GPL(rtnl_unregister_all);

/**
* __rtnl_register_many - Register rtnetlink message types
* @handlers: Array of struct rtnl_msg_handlers
* @n: The length of @handlers
*
* Registers the specified function pointers (at least one of them has
* to be non-NULL) to be called whenever a request message for the
* specified protocol family and message type is received.
*
* The special protocol family PF_UNSPEC may be used to define fallback
* function pointers for the case when no entry for the specific protocol
* family exists.
*
* When one element of @handlers fails to register,
* 1) built-in: panics.
* 2) modules : the previous successful registrations are unwinded
* and an error is returned.
*
* Use rtnl_register_many().
*/
int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n)
{
const struct rtnl_msg_handler *handler;
Expand All @@ -464,6 +432,10 @@ int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n)
handler->msgtype, handler->doit,
handler->dumpit, handler->flags);
if (err) {
if (!handler->owner)
panic("Unable to register rtnetlink message "
"handlers, %pS\n", handlers);

__rtnl_unregister_many(handlers, i);
break;
}
Expand Down Expand Up @@ -6839,41 +6811,44 @@ static struct pernet_operations rtnetlink_net_ops = {
.exit = rtnetlink_net_exit,
};

static const struct rtnl_msg_handler rtnetlink_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_NEWLINK, .doit = rtnl_newlink},
{.msgtype = RTM_DELLINK, .doit = rtnl_dellink},
{.msgtype = RTM_GETLINK, .doit = rtnl_getlink,
.dumpit = rtnl_dump_ifinfo, .flags = RTNL_FLAG_DUMP_SPLIT_NLM_DONE},
{.msgtype = RTM_SETLINK, .doit = rtnl_setlink},
{.msgtype = RTM_GETADDR, .dumpit = rtnl_dump_all},
{.msgtype = RTM_GETROUTE, .dumpit = rtnl_dump_all},
{.msgtype = RTM_GETNETCONF, .dumpit = rtnl_dump_all},
{.msgtype = RTM_GETSTATS, .doit = rtnl_stats_get,
.dumpit = rtnl_stats_dump},
{.msgtype = RTM_SETSTATS, .doit = rtnl_stats_set},
{.msgtype = RTM_NEWLINKPROP, .doit = rtnl_newlinkprop},
{.msgtype = RTM_DELLINKPROP, .doit = rtnl_dellinkprop},
{.protocol = PF_BRIDGE, .msgtype = RTM_GETLINK,
.dumpit = rtnl_bridge_getlink},
{.protocol = PF_BRIDGE, .msgtype = RTM_DELLINK,
.doit = rtnl_bridge_dellink},
{.protocol = PF_BRIDGE, .msgtype = RTM_SETLINK,
.doit = rtnl_bridge_setlink},
{.protocol = PF_BRIDGE, .msgtype = RTM_NEWNEIGH, .doit = rtnl_fdb_add},
{.protocol = PF_BRIDGE, .msgtype = RTM_DELNEIGH, .doit = rtnl_fdb_del,
.flags = RTNL_FLAG_BULK_DEL_SUPPORTED},
{.protocol = PF_BRIDGE, .msgtype = RTM_GETNEIGH, .doit = rtnl_fdb_get,
.dumpit = rtnl_fdb_dump},
{.protocol = PF_BRIDGE, .msgtype = RTM_NEWMDB, .doit = rtnl_mdb_add},
{.protocol = PF_BRIDGE, .msgtype = RTM_DELMDB, .doit = rtnl_mdb_del,
.flags = RTNL_FLAG_BULK_DEL_SUPPORTED},
{.protocol = PF_BRIDGE, .msgtype = RTM_GETMDB, .doit = rtnl_mdb_get,
.dumpit = rtnl_mdb_dump},
};

void __init rtnetlink_init(void)
{
if (register_pernet_subsys(&rtnetlink_net_ops))
panic("rtnetlink_init: cannot initialize rtnetlink\n");

register_netdevice_notifier(&rtnetlink_dev_notifier);

rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
rtnl_dump_ifinfo, RTNL_FLAG_DUMP_SPLIT_NLM_DONE);
rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, 0);

rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0);
rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0);
rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0);

rtnl_register(PF_UNSPEC, RTM_NEWLINKPROP, rtnl_newlinkprop, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_DELLINKPROP, rtnl_dellinkprop, NULL, 0);

rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0);
rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL,
RTNL_FLAG_BULK_DEL_SUPPORTED);
rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0);

rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0);
rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0);
rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0);

rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
0);
rtnl_register(PF_UNSPEC, RTM_SETSTATS, rtnl_stats_set, NULL, 0);

rtnl_register(PF_BRIDGE, RTM_GETMDB, rtnl_mdb_get, rtnl_mdb_dump, 0);
rtnl_register(PF_BRIDGE, RTM_NEWMDB, rtnl_mdb_add, NULL, 0);
rtnl_register(PF_BRIDGE, RTM_DELMDB, rtnl_mdb_del, NULL,
RTNL_FLAG_BULK_DEL_SUPPORTED);
rtnl_register_many(rtnetlink_rtnl_msg_handlers);
}
8 changes: 6 additions & 2 deletions net/dcb/dcbnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,11 @@ static struct notifier_block dcbnl_nb __read_mostly = {
.notifier_call = dcbnl_netdevice_event,
};

static const struct rtnl_msg_handler dcbnl_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_GETDCB, .doit = dcb_doit},
{.msgtype = RTM_SETDCB, .doit = dcb_doit},
};

static int __init dcbnl_init(void)
{
int err;
Expand All @@ -2416,8 +2421,7 @@ static int __init dcbnl_init(void)
if (err)
return err;

rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0);
rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
rtnl_register_many(dcbnl_rtnl_msg_handlers);

return 0;
}
Expand Down
Loading

0 comments on commit 53bac83

Please sign in to comment.