diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-18 20:39:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-19 06:50:48 -0400 |
commit | 8723e1b4ad9be4444423b4d41509ce859a629649 (patch) | |
tree | 00b0121c12e62736807e998b22b8964f1a5e1df9 /net/ipv4/fib_semantics.c | |
parent | 9e917dca74138cccf398ce8bb924c7fd2980ec1d (diff) |
inet: RCU changes in inetdev_by_index()
Convert inetdev_by_index() to not increment in_dev refcount.
Callers hold RCU or RTNL, and should not decrement in_dev refcount.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r-- | net/ipv4/fib_semantics.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 0f80dfc2f7fb..6734c9cab248 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -590,32 +590,29 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, | |||
590 | if (!dev) | 590 | if (!dev) |
591 | goto out; | 591 | goto out; |
592 | dev_hold(dev); | 592 | dev_hold(dev); |
593 | err = -ENETDOWN; | 593 | err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN; |
594 | if (!(dev->flags & IFF_UP)) | ||
595 | goto out; | ||
596 | err = 0; | ||
597 | out: | ||
598 | rcu_read_unlock(); | ||
599 | return err; | ||
600 | } else { | 594 | } else { |
601 | struct in_device *in_dev; | 595 | struct in_device *in_dev; |
602 | 596 | ||
603 | if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) | 597 | if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) |
604 | return -EINVAL; | 598 | return -EINVAL; |
605 | 599 | ||
600 | rcu_read_lock(); | ||
601 | err = -ENODEV; | ||
606 | in_dev = inetdev_by_index(net, nh->nh_oif); | 602 | in_dev = inetdev_by_index(net, nh->nh_oif); |
607 | if (in_dev == NULL) | 603 | if (in_dev == NULL) |
608 | return -ENODEV; | 604 | goto out; |
609 | if (!(in_dev->dev->flags & IFF_UP)) { | 605 | err = -ENETDOWN; |
610 | in_dev_put(in_dev); | 606 | if (!(in_dev->dev->flags & IFF_UP)) |
611 | return -ENETDOWN; | 607 | goto out; |
612 | } | ||
613 | nh->nh_dev = in_dev->dev; | 608 | nh->nh_dev = in_dev->dev; |
614 | dev_hold(nh->nh_dev); | 609 | dev_hold(nh->nh_dev); |
615 | nh->nh_scope = RT_SCOPE_HOST; | 610 | nh->nh_scope = RT_SCOPE_HOST; |
616 | in_dev_put(in_dev); | 611 | err = 0; |
617 | } | 612 | } |
618 | return 0; | 613 | out: |
614 | rcu_read_unlock(); | ||
615 | return err; | ||
619 | } | 616 | } |
620 | 617 | ||
621 | static inline unsigned int fib_laddr_hashfn(__be32 val) | 618 | static inline unsigned int fib_laddr_hashfn(__be32 val) |