diff options
| author | David Ahern <dsahern@gmail.com> | 2019-04-16 17:36:01 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-04-18 02:10:46 -0400 |
| commit | 85bd05deb35a55f04faaf4393faaaa0f3153d515 (patch) | |
| tree | c7da95dbb0951203170f6f5c5b0b8cd05818bbd5 /net/ipv6 | |
| parent | 7e4b5128757397132ffff1d7b1be9f992e9cd9f2 (diff) | |
ipv6: Pass fib6_result to ip6_rt_cache_alloc
Change ip6_rt_cache_alloc to take a fib6_result over a fib6_info.
Since ip6_rt_cache_alloc is only the caller, update the
rt6_is_gw_or_nonexthop helper to take fib6_result.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/route.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e3c5f95550bc..5dd6113c8f8f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -784,9 +784,10 @@ static struct fib6_info *rt6_select(struct net *net, struct fib6_node *fn, | |||
| 784 | return match ? match : net->ipv6.fib6_null_entry; | 784 | return match ? match : net->ipv6.fib6_null_entry; |
| 785 | } | 785 | } |
| 786 | 786 | ||
| 787 | static bool rt6_is_gw_or_nonexthop(const struct fib6_info *rt) | 787 | static bool rt6_is_gw_or_nonexthop(const struct fib6_result *res) |
| 788 | { | 788 | { |
| 789 | return (rt->fib6_flags & RTF_NONEXTHOP) || rt->fib6_nh.fib_nh_gw_family; | 789 | return (res->f6i->fib6_flags & RTF_NONEXTHOP) || |
| 790 | res->nh->fib_nh_gw_family; | ||
| 790 | } | 791 | } |
| 791 | 792 | ||
| 792 | #ifdef CONFIG_IPV6_ROUTE_INFO | 793 | #ifdef CONFIG_IPV6_ROUTE_INFO |
| @@ -1174,10 +1175,11 @@ int ip6_ins_rt(struct net *net, struct fib6_info *rt) | |||
| 1174 | return __ip6_ins_rt(rt, &info, NULL); | 1175 | return __ip6_ins_rt(rt, &info, NULL); |
| 1175 | } | 1176 | } |
| 1176 | 1177 | ||
| 1177 | static struct rt6_info *ip6_rt_cache_alloc(struct fib6_info *ort, | 1178 | static struct rt6_info *ip6_rt_cache_alloc(const struct fib6_result *res, |
| 1178 | const struct in6_addr *daddr, | 1179 | const struct in6_addr *daddr, |
| 1179 | const struct in6_addr *saddr) | 1180 | const struct in6_addr *saddr) |
| 1180 | { | 1181 | { |
| 1182 | struct fib6_info *f6i = res->f6i; | ||
| 1181 | struct net_device *dev; | 1183 | struct net_device *dev; |
| 1182 | struct rt6_info *rt; | 1184 | struct rt6_info *rt; |
| 1183 | 1185 | ||
| @@ -1185,25 +1187,25 @@ static struct rt6_info *ip6_rt_cache_alloc(struct fib6_info *ort, | |||
| 1185 | * Clone the route. | 1187 | * Clone the route. |
| 1186 | */ | 1188 | */ |
| 1187 | 1189 | ||
| 1188 | if (!fib6_info_hold_safe(ort)) | 1190 | if (!fib6_info_hold_safe(f6i)) |
| 1189 | return NULL; | 1191 | return NULL; |
| 1190 | 1192 | ||
| 1191 | dev = ip6_rt_get_dev_rcu(ort); | 1193 | dev = ip6_rt_get_dev_rcu(f6i); |
| 1192 | rt = ip6_dst_alloc(dev_net(dev), dev, 0); | 1194 | rt = ip6_dst_alloc(dev_net(dev), dev, 0); |
| 1193 | if (!rt) { | 1195 | if (!rt) { |
| 1194 | fib6_info_release(ort); | 1196 | fib6_info_release(f6i); |
| 1195 | return NULL; | 1197 | return NULL; |
| 1196 | } | 1198 | } |
| 1197 | 1199 | ||
| 1198 | ip6_rt_copy_init(rt, ort); | 1200 | ip6_rt_copy_init(rt, res->f6i); |
| 1199 | rt->rt6i_flags |= RTF_CACHE; | 1201 | rt->rt6i_flags |= RTF_CACHE; |
| 1200 | rt->dst.flags |= DST_HOST; | 1202 | rt->dst.flags |= DST_HOST; |
| 1201 | rt->rt6i_dst.addr = *daddr; | 1203 | rt->rt6i_dst.addr = *daddr; |
| 1202 | rt->rt6i_dst.plen = 128; | 1204 | rt->rt6i_dst.plen = 128; |
| 1203 | 1205 | ||
| 1204 | if (!rt6_is_gw_or_nonexthop(ort)) { | 1206 | if (!rt6_is_gw_or_nonexthop(res)) { |
| 1205 | if (ort->fib6_dst.plen != 128 && | 1207 | if (f6i->fib6_dst.plen != 128 && |
| 1206 | ipv6_addr_equal(&ort->fib6_dst.addr, daddr)) | 1208 | ipv6_addr_equal(&f6i->fib6_dst.addr, daddr)) |
| 1207 | rt->rt6i_flags |= RTF_ANYCAST; | 1209 | rt->rt6i_flags |= RTF_ANYCAST; |
| 1208 | #ifdef CONFIG_IPV6_SUBTREES | 1210 | #ifdef CONFIG_IPV6_SUBTREES |
| 1209 | if (rt->rt6i_src.plen && saddr) { | 1211 | if (rt->rt6i_src.plen && saddr) { |
| @@ -1885,7 +1887,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, | |||
| 1885 | */ | 1887 | */ |
| 1886 | struct rt6_info *uncached_rt; | 1888 | struct rt6_info *uncached_rt; |
| 1887 | 1889 | ||
| 1888 | uncached_rt = ip6_rt_cache_alloc(res.f6i, &fl6->daddr, NULL); | 1890 | uncached_rt = ip6_rt_cache_alloc(&res, &fl6->daddr, NULL); |
| 1889 | 1891 | ||
| 1890 | rcu_read_unlock(); | 1892 | rcu_read_unlock(); |
| 1891 | 1893 | ||
| @@ -2329,19 +2331,20 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, | |||
| 2329 | if (rt6->rt6i_flags & RTF_CACHE) | 2331 | if (rt6->rt6i_flags & RTF_CACHE) |
| 2330 | rt6_update_exception_stamp_rt(rt6); | 2332 | rt6_update_exception_stamp_rt(rt6); |
| 2331 | } else if (daddr) { | 2333 | } else if (daddr) { |
| 2332 | struct fib6_info *from; | 2334 | struct fib6_result res = {}; |
| 2333 | struct rt6_info *nrt6; | 2335 | struct rt6_info *nrt6; |
| 2334 | 2336 | ||
| 2335 | rcu_read_lock(); | 2337 | rcu_read_lock(); |
| 2336 | from = rcu_dereference(rt6->from); | 2338 | res.f6i = rcu_dereference(rt6->from); |
| 2337 | if (!from) { | 2339 | if (!res.f6i) { |
| 2338 | rcu_read_unlock(); | 2340 | rcu_read_unlock(); |
| 2339 | return; | 2341 | return; |
| 2340 | } | 2342 | } |
| 2341 | nrt6 = ip6_rt_cache_alloc(from, daddr, saddr); | 2343 | res.nh = &res.f6i->fib6_nh; |
| 2344 | nrt6 = ip6_rt_cache_alloc(&res, daddr, saddr); | ||
| 2342 | if (nrt6) { | 2345 | if (nrt6) { |
| 2343 | rt6_do_update_pmtu(nrt6, mtu); | 2346 | rt6_do_update_pmtu(nrt6, mtu); |
| 2344 | if (rt6_insert_exception(nrt6, from)) | 2347 | if (rt6_insert_exception(nrt6, res.f6i)) |
| 2345 | dst_release_immediate(&nrt6->dst); | 2348 | dst_release_immediate(&nrt6->dst); |
| 2346 | } | 2349 | } |
| 2347 | rcu_read_unlock(); | 2350 | rcu_read_unlock(); |
| @@ -3364,10 +3367,10 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3364 | { | 3367 | { |
| 3365 | struct netevent_redirect netevent; | 3368 | struct netevent_redirect netevent; |
| 3366 | struct rt6_info *rt, *nrt = NULL; | 3369 | struct rt6_info *rt, *nrt = NULL; |
| 3370 | struct fib6_result res = {}; | ||
| 3367 | struct ndisc_options ndopts; | 3371 | struct ndisc_options ndopts; |
| 3368 | struct inet6_dev *in6_dev; | 3372 | struct inet6_dev *in6_dev; |
| 3369 | struct neighbour *neigh; | 3373 | struct neighbour *neigh; |
| 3370 | struct fib6_info *from; | ||
| 3371 | struct rd_msg *msg; | 3374 | struct rd_msg *msg; |
| 3372 | int optlen, on_link; | 3375 | int optlen, on_link; |
| 3373 | u8 *lladdr; | 3376 | u8 *lladdr; |
| @@ -3450,14 +3453,15 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3450 | NDISC_REDIRECT, &ndopts); | 3453 | NDISC_REDIRECT, &ndopts); |
| 3451 | 3454 | ||
| 3452 | rcu_read_lock(); | 3455 | rcu_read_lock(); |
| 3453 | from = rcu_dereference(rt->from); | 3456 | res.f6i = rcu_dereference(rt->from); |
| 3454 | /* This fib6_info_hold() is safe here because we hold reference to rt | 3457 | /* This fib6_info_hold() is safe here because we hold reference to rt |
| 3455 | * and rt already holds reference to fib6_info. | 3458 | * and rt already holds reference to fib6_info. |
| 3456 | */ | 3459 | */ |
| 3457 | fib6_info_hold(from); | 3460 | fib6_info_hold(res.f6i); |
| 3458 | rcu_read_unlock(); | 3461 | rcu_read_unlock(); |
| 3459 | 3462 | ||
| 3460 | nrt = ip6_rt_cache_alloc(from, &msg->dest, NULL); | 3463 | res.nh = &res.f6i->fib6_nh; |
| 3464 | nrt = ip6_rt_cache_alloc(&res, &msg->dest, NULL); | ||
| 3461 | if (!nrt) | 3465 | if (!nrt) |
| 3462 | goto out; | 3466 | goto out; |
| 3463 | 3467 | ||
| @@ -3471,7 +3475,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3471 | * a cached route because rt6_insert_exception() will | 3475 | * a cached route because rt6_insert_exception() will |
| 3472 | * takes care of it | 3476 | * takes care of it |
| 3473 | */ | 3477 | */ |
| 3474 | if (rt6_insert_exception(nrt, from)) { | 3478 | if (rt6_insert_exception(nrt, res.f6i)) { |
| 3475 | dst_release_immediate(&nrt->dst); | 3479 | dst_release_immediate(&nrt->dst); |
| 3476 | goto out; | 3480 | goto out; |
| 3477 | } | 3481 | } |
| @@ -3483,7 +3487,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3483 | call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); | 3487 | call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); |
| 3484 | 3488 | ||
| 3485 | out: | 3489 | out: |
| 3486 | fib6_info_release(from); | 3490 | fib6_info_release(res.f6i); |
| 3487 | neigh_release(neigh); | 3491 | neigh_release(neigh); |
| 3488 | } | 3492 | } |
| 3489 | 3493 | ||
