net: fib_rules: Split fib_nl2rule().

We will move RTNL down to fib_nl_newrule() and fib_nl_delrule().

Some operations in fib_nl2rule() require RTNL: fib_default_rule_pref()
and __dev_get_by_name().

Let's split the RTNL parts as fib_nl2rule_rtnl().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20250207072502.87775-4-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Kuniyuki Iwashima
2025-02-07 16:24:57 +09:00
committed by Jakub Kicinski
parent a9ffd24b55
commit 8b498773c8
+41 -17
View File
@@ -550,30 +550,18 @@ static int fib_nl2rule(struct net *net, struct nlmsghdr *nlh,
if (tb[FRA_PRIORITY]) {
nlrule->pref = nla_get_u32(tb[FRA_PRIORITY]);
*user_priority = true;
} else {
nlrule->pref = fib_default_rule_pref(ops);
}
nlrule->proto = nla_get_u8_default(tb[FRA_PROTOCOL], RTPROT_UNSPEC);
if (tb[FRA_IIFNAME]) {
struct net_device *dev;
nlrule->iifindex = -1;
nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
dev = __dev_get_by_name(net, nlrule->iifname);
if (dev)
nlrule->iifindex = dev->ifindex;
}
if (tb[FRA_OIFNAME]) {
struct net_device *dev;
nlrule->oifindex = -1;
nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
dev = __dev_get_by_name(net, nlrule->oifname);
if (dev)
nlrule->oifindex = dev->ifindex;
}
if (tb[FRA_FWMARK]) {
@@ -615,11 +603,6 @@ static int fib_nl2rule(struct net *net, struct nlmsghdr *nlh,
}
nlrule->target = nla_get_u32(tb[FRA_GOTO]);
/* Backward jumps are prohibited to avoid endless loops */
if (nlrule->target <= nlrule->pref) {
NL_SET_ERR_MSG(extack, "Backward goto not supported");
goto errout_free;
}
} else if (nlrule->action == FR_ACT_GOTO) {
NL_SET_ERR_MSG(extack, "Missing goto target for action goto");
goto errout_free;
@@ -679,6 +662,39 @@ errout:
return err;
}
static int fib_nl2rule_rtnl(struct fib_rule *nlrule,
struct fib_rules_ops *ops,
struct nlattr *tb[],
struct netlink_ext_ack *extack)
{
if (!tb[FRA_PRIORITY])
nlrule->pref = fib_default_rule_pref(ops);
/* Backward jumps are prohibited to avoid endless loops */
if (tb[FRA_GOTO] && nlrule->target <= nlrule->pref) {
NL_SET_ERR_MSG(extack, "Backward goto not supported");
return -EINVAL;
}
if (tb[FRA_IIFNAME]) {
struct net_device *dev;
dev = __dev_get_by_name(nlrule->fr_net, nlrule->iifname);
if (dev)
nlrule->iifindex = dev->ifindex;
}
if (tb[FRA_OIFNAME]) {
struct net_device *dev;
dev = __dev_get_by_name(nlrule->fr_net, nlrule->oifname);
if (dev)
nlrule->oifindex = dev->ifindex;
}
return 0;
}
static int rule_exists(struct fib_rules_ops *ops, struct fib_rule_hdr *frh,
struct nlattr **tb, struct fib_rule *rule)
{
@@ -801,6 +817,10 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
goto errout;
err = fib_nl2rule_rtnl(rule, ops, tb, extack);
if (err)
goto errout_free;
if ((nlh->nlmsg_flags & NLM_F_EXCL) &&
rule_exists(ops, frh, tb, rule)) {
err = -EEXIST;
@@ -909,6 +929,10 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
goto errout;
err = fib_nl2rule_rtnl(nlrule, ops, tb, extack);
if (err)
goto errout;
rule = rule_find(ops, frh, tb, nlrule, user_priority);
if (!rule) {
err = -ENOENT;