Skip to content

Commit c9cabe0

Browse files
q2venPaolo Abeni
authored andcommitted
ipv6: Move nexthop_find_by_id() after fib6_info_alloc().
We will get rid of RTNL from RTM_NEWROUTE and SIOCADDRT. Then, we must perform two lookups for nexthop and dev under RCU to guarantee their lifetime. ip6_route_info_create() calls nexthop_find_by_id() first if RTA_NH_ID is specified, and then allocates struct fib6_info. nexthop_find_by_id() must be called under RCU, but we do not want to use GFP_ATOMIC for memory allocation here, which will be likely to fail in ip6_route_multipath_add(). Let's move nexthop_find_by_id() after the memory allocation so that we can later split ip6_route_info_create() into two parts: the sleepable part and the RCU part. Signed-off-by: Kuniyuki Iwashima <[email protected]> Acked-by: Paolo Abeni <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent e6f4979 commit c9cabe0

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

net/ipv6/route.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,24 +3734,11 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
37343734
{
37353735
struct net *net = cfg->fc_nlinfo.nl_net;
37363736
struct fib6_info *rt = NULL;
3737-
struct nexthop *nh = NULL;
37383737
struct fib6_table *table;
37393738
struct fib6_nh *fib6_nh;
3740-
int err = -EINVAL;
3739+
int err = -ENOBUFS;
37413740
int addr_type;
37423741

3743-
if (cfg->fc_nh_id) {
3744-
nh = nexthop_find_by_id(net, cfg->fc_nh_id);
3745-
if (!nh) {
3746-
NL_SET_ERR_MSG(extack, "Nexthop id does not exist");
3747-
goto out;
3748-
}
3749-
err = fib6_check_nexthop(nh, cfg, extack);
3750-
if (err)
3751-
goto out;
3752-
}
3753-
3754-
err = -ENOBUFS;
37553742
if (cfg->fc_nlinfo.nlh &&
37563743
!(cfg->fc_nlinfo.nlh->nlmsg_flags & NLM_F_CREATE)) {
37573744
table = fib6_get_table(net, cfg->fc_table);
@@ -3767,7 +3754,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
37673754
goto out;
37683755

37693756
err = -ENOMEM;
3770-
rt = fib6_info_alloc(gfp_flags, !nh);
3757+
rt = fib6_info_alloc(gfp_flags, !cfg->fc_nh_id);
37713758
if (!rt)
37723759
goto out;
37733760

@@ -3803,12 +3790,27 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
38033790
ipv6_addr_prefix(&rt->fib6_src.addr, &cfg->fc_src, cfg->fc_src_len);
38043791
rt->fib6_src.plen = cfg->fc_src_len;
38053792
#endif
3806-
if (nh) {
3793+
3794+
if (cfg->fc_nh_id) {
3795+
struct nexthop *nh;
3796+
3797+
nh = nexthop_find_by_id(net, cfg->fc_nh_id);
3798+
if (!nh) {
3799+
err = -EINVAL;
3800+
NL_SET_ERR_MSG(extack, "Nexthop id does not exist");
3801+
goto out_free;
3802+
}
3803+
3804+
err = fib6_check_nexthop(nh, cfg, extack);
3805+
if (err)
3806+
goto out_free;
3807+
38073808
if (!nexthop_get(nh)) {
38083809
NL_SET_ERR_MSG(extack, "Nexthop has been deleted");
38093810
err = -ENOENT;
38103811
goto out_free;
38113812
}
3813+
38123814
rt->nh = nh;
38133815
fib6_nh = nexthop_fib6_nh(rt->nh);
38143816
} else {

0 commit comments

Comments
 (0)