aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-10-18 20:39:26 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-19 06:50:48 -0400
commit8723e1b4ad9be4444423b4d41509ce859a629649 (patch)
tree00b0121c12e62736807e998b22b8964f1a5e1df9 /net/ipv4/fib_semantics.c
parent9e917dca74138cccf398ce8bb924c7fd2980ec1d (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.c25
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;
597out:
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; 613out:
614 rcu_read_unlock();
615 return err;
619} 616}
620 617
621static inline unsigned int fib_laddr_hashfn(__be32 val) 618static inline unsigned int fib_laddr_hashfn(__be32 val)