aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/route.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e0d3ad02ffb5..e8855706980f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -401,10 +401,9 @@ int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh,
401 with dst->error set to errno value. 401 with dst->error set to errno value.
402 */ 402 */
403 403
404static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, 404static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
405 struct in6_addr *saddr, struct netlink_skb_parms *req) 405 struct in6_addr *saddr)
406{ 406{
407 int err;
408 struct rt6_info *rt; 407 struct rt6_info *rt;
409 408
410 /* 409 /*
@@ -435,18 +434,29 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
435 434
436 rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); 435 rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
437 436
438 dst_hold(&rt->u.dst); 437 }
439 438
440 err = ip6_ins_rt(rt, NULL, NULL, req); 439 return rt;
441 if (err == 0) 440}
442 return rt;
443 441
444 rt->u.dst.error = err; 442static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
443 struct in6_addr *saddr, struct netlink_skb_parms *req)
444{
445 struct rt6_info *rt = rt6_alloc_cow(ort, daddr, saddr);
446 int err;
445 447
446 return rt; 448 if (!rt) {
449 dst_hold(&ip6_null_entry.u.dst);
450 return &ip6_null_entry;
447 } 451 }
448 dst_hold(&ip6_null_entry.u.dst); 452
449 return &ip6_null_entry; 453 dst_hold(&rt->u.dst);
454
455 err = ip6_ins_rt(rt, NULL, NULL, req);
456 if (err)
457 rt->u.dst.error = err;
458
459 return rt;
450} 460}
451 461
452#define BACKTRACK() \ 462#define BACKTRACK() \