aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2019-04-16 17:36:01 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-18 02:10:46 -0400
commit85bd05deb35a55f04faaf4393faaaa0f3153d515 (patch)
treec7da95dbb0951203170f6f5c5b0b8cd05818bbd5 /net/ipv6
parent7e4b5128757397132ffff1d7b1be9f992e9cd9f2 (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.c48
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
787static bool rt6_is_gw_or_nonexthop(const struct fib6_info *rt) 787static 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
1177static struct rt6_info *ip6_rt_cache_alloc(struct fib6_info *ort, 1178static 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
3485out: 3489out:
3486 fib6_info_release(from); 3490 fib6_info_release(res.f6i);
3487 neigh_release(neigh); 3491 neigh_release(neigh);
3488} 3492}
3489 3493