Skip to content

Commit 32affa5

Browse files
edumazetkuba-moo
authored andcommitted
fib: rules: no longer hold RTNL in fib_nl_dumprule()
- fib rules are already RCU protected, RTNL is not needed to get them. - Fix return value at the end of a dump, so that NLMSG_DONE can be appended to current skb, saving one recvmsg() system call. Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: David Ahern <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 195b7fc commit 32affa5

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

net/core/fib_rules.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,10 +1142,10 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
11421142
const struct nlmsghdr *nlh = cb->nlh;
11431143
struct net *net = sock_net(skb->sk);
11441144
struct fib_rules_ops *ops;
1145-
int idx = 0, family;
1145+
int err, idx = 0, family;
11461146

11471147
if (cb->strict_check) {
1148-
int err = fib_valid_dumprule_req(nlh, cb->extack);
1148+
err = fib_valid_dumprule_req(nlh, cb->extack);
11491149

11501150
if (err < 0)
11511151
return err;
@@ -1158,17 +1158,17 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
11581158
if (ops == NULL)
11591159
return -EAFNOSUPPORT;
11601160

1161-
dump_rules(skb, cb, ops);
1162-
1163-
return skb->len;
1161+
return dump_rules(skb, cb, ops);
11641162
}
11651163

1164+
err = 0;
11661165
rcu_read_lock();
11671166
list_for_each_entry_rcu(ops, &net->rules_ops, list) {
11681167
if (idx < cb->args[0] || !try_module_get(ops->owner))
11691168
goto skip;
11701169

1171-
if (dump_rules(skb, cb, ops) < 0)
1170+
err = dump_rules(skb, cb, ops);
1171+
if (err < 0)
11721172
break;
11731173

11741174
cb->args[1] = 0;
@@ -1178,7 +1178,7 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
11781178
rcu_read_unlock();
11791179
cb->args[0] = idx;
11801180

1181-
return skb->len;
1181+
return err;
11821182
}
11831183

11841184
static void notify_rule_change(int event, struct fib_rule *rule,
@@ -1293,7 +1293,8 @@ static int __init fib_rules_init(void)
12931293
int err;
12941294
rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, 0);
12951295
rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, 0);
1296-
rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule, 0);
1296+
rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule,
1297+
RTNL_FLAG_DUMP_UNLOCKED);
12971298

12981299
err = register_pernet_subsys(&fib_rules_net_ops);
12991300
if (err < 0)

0 commit comments

Comments
 (0)