diff options
-rw-r--r-- | net/ipv6/route.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1a326af18f28..cd60bcca1064 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -478,7 +478,6 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d | |||
478 | if (rt == &ip6_null_entry && strict) { \ | 478 | if (rt == &ip6_null_entry && strict) { \ |
479 | while ((fn = fn->parent) != NULL) { \ | 479 | while ((fn = fn->parent) != NULL) { \ |
480 | if (fn->fn_flags & RTN_ROOT) { \ | 480 | if (fn->fn_flags & RTN_ROOT) { \ |
481 | dst_hold(&rt->u.dst); \ | ||
482 | goto out; \ | 481 | goto out; \ |
483 | } \ | 482 | } \ |
484 | if (fn->fn_flags & RTN_RTINFO) \ | 483 | if (fn->fn_flags & RTN_RTINFO) \ |
@@ -508,17 +507,17 @@ restart: | |||
508 | if ((rt->rt6i_flags & RTF_CACHE)) { | 507 | if ((rt->rt6i_flags & RTF_CACHE)) { |
509 | rt = rt6_device_match(rt, skb->dev->ifindex, strict); | 508 | rt = rt6_device_match(rt, skb->dev->ifindex, strict); |
510 | BACKTRACK(); | 509 | BACKTRACK(); |
511 | dst_hold(&rt->u.dst); | ||
512 | goto out; | 510 | goto out; |
513 | } | 511 | } |
514 | 512 | ||
515 | rt = rt6_device_match(rt, skb->dev->ifindex, strict); | 513 | rt = rt6_device_match(rt, skb->dev->ifindex, strict); |
516 | BACKTRACK(); | 514 | BACKTRACK(); |
517 | 515 | ||
516 | dst_hold(&rt->u.dst); | ||
517 | read_unlock_bh(&rt6_lock); | ||
518 | |||
518 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { | 519 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { |
519 | struct rt6_info *nrt; | 520 | struct rt6_info *nrt; |
520 | dst_hold(&rt->u.dst); | ||
521 | read_unlock_bh(&rt6_lock); | ||
522 | 521 | ||
523 | nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr, | 522 | nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr, |
524 | &skb->nh.ipv6h->saddr, | 523 | &skb->nh.ipv6h->saddr, |
@@ -536,14 +535,16 @@ restart: | |||
536 | dst_release(&rt->u.dst); | 535 | dst_release(&rt->u.dst); |
537 | goto relookup; | 536 | goto relookup; |
538 | } | 537 | } |
539 | dst_hold(&rt->u.dst); | ||
540 | 538 | ||
541 | out: | ||
542 | read_unlock_bh(&rt6_lock); | ||
543 | out2: | 539 | out2: |
544 | rt->u.dst.lastuse = jiffies; | 540 | rt->u.dst.lastuse = jiffies; |
545 | rt->u.dst.__use++; | 541 | rt->u.dst.__use++; |
546 | skb->dst = (struct dst_entry *) rt; | 542 | skb->dst = (struct dst_entry *) rt; |
543 | return; | ||
544 | out: | ||
545 | dst_hold(&rt->u.dst); | ||
546 | read_unlock_bh(&rt6_lock); | ||
547 | goto out2; | ||
547 | } | 548 | } |
548 | 549 | ||
549 | struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) | 550 | struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) |
@@ -566,7 +567,6 @@ restart: | |||
566 | if ((rt->rt6i_flags & RTF_CACHE)) { | 567 | if ((rt->rt6i_flags & RTF_CACHE)) { |
567 | rt = rt6_device_match(rt, fl->oif, strict); | 568 | rt = rt6_device_match(rt, fl->oif, strict); |
568 | BACKTRACK(); | 569 | BACKTRACK(); |
569 | dst_hold(&rt->u.dst); | ||
570 | goto out; | 570 | goto out; |
571 | } | 571 | } |
572 | if (rt->rt6i_flags & RTF_DEFAULT) { | 572 | if (rt->rt6i_flags & RTF_DEFAULT) { |
@@ -577,10 +577,11 @@ restart: | |||
577 | BACKTRACK(); | 577 | BACKTRACK(); |
578 | } | 578 | } |
579 | 579 | ||
580 | dst_hold(&rt->u.dst); | ||
581 | read_unlock_bh(&rt6_lock); | ||
582 | |||
580 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { | 583 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { |
581 | struct rt6_info *nrt; | 584 | struct rt6_info *nrt; |
582 | dst_hold(&rt->u.dst); | ||
583 | read_unlock_bh(&rt6_lock); | ||
584 | 585 | ||
585 | nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL); | 586 | nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL); |
586 | 587 | ||
@@ -596,14 +597,14 @@ restart: | |||
596 | dst_release(&rt->u.dst); | 597 | dst_release(&rt->u.dst); |
597 | goto relookup; | 598 | goto relookup; |
598 | } | 599 | } |
599 | dst_hold(&rt->u.dst); | ||
600 | |||
601 | out: | ||
602 | read_unlock_bh(&rt6_lock); | ||
603 | out2: | 600 | out2: |
604 | rt->u.dst.lastuse = jiffies; | 601 | rt->u.dst.lastuse = jiffies; |
605 | rt->u.dst.__use++; | 602 | rt->u.dst.__use++; |
606 | return &rt->u.dst; | 603 | return &rt->u.dst; |
604 | out: | ||
605 | dst_hold(&rt->u.dst); | ||
606 | read_unlock_bh(&rt6_lock); | ||
607 | goto out2; | ||
607 | } | 608 | } |
608 | 609 | ||
609 | 610 | ||