From 5bded598ef84ac6a426c1c48232aa5fe0711b68a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 19 Oct 2010 00:39:26 +0000 Subject: [PATCH] --- yaml --- r: 215231 b: refs/heads/master c: 8723e1b4ad9be4444423b4d41509ce859a629649 h: refs/heads/master i: 215229: 88bb19f5e8bac1877faf3a63b71dd4dfbf31fbdf 215227: 0496ba8446f3c0211f8c6638a660a8161dbe486a 215223: a761265b30e532247b4cb565999a6b00efcfc192 215215: d1cf7a7a9a3bae2c28627860e398926e4193ec61 215199: c91c9731d3dbd2e6fbd97cb41055394eed5b5ac8 215167: 0d8c891f95e29020e4cda40e6618d0cd816e62ad v: v3 --- [refs] | 2 +- trunk/net/ipv4/devinet.c | 7 ++++--- trunk/net/ipv4/fib_semantics.c | 25 +++++++++++-------------- trunk/net/ipv4/igmp.c | 2 -- trunk/net/ipv4/ip_gre.c | 4 +--- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/[refs] b/[refs] index 1617e34e3fd5..0a442114caab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9e917dca74138cccf398ce8bb924c7fd2980ec1d +refs/heads/master: 8723e1b4ad9be4444423b4d41509ce859a629649 diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index c2ff48fa18c7..dc94b0316b78 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -403,6 +403,9 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) return inet_insert_ifa(ifa); } +/* Caller must hold RCU or RTNL : + * We dont take a reference on found in_device + */ struct in_device *inetdev_by_index(struct net *net, int ifindex) { struct net_device *dev; @@ -411,7 +414,7 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex) rcu_read_lock(); dev = dev_get_by_index_rcu(net, ifindex); if (dev) - in_dev = in_dev_get(dev); + in_dev = rcu_dereference_rtnl(dev->ip_ptr); rcu_read_unlock(); return in_dev; } @@ -453,8 +456,6 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg goto errout; } - __in_dev_put(in_dev); - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) { if (tb[IFA_LOCAL] && diff --git a/trunk/net/ipv4/fib_semantics.c b/trunk/net/ipv4/fib_semantics.c index 0f80dfc2f7fb..6734c9cab248 100644 --- a/trunk/net/ipv4/fib_semantics.c +++ b/trunk/net/ipv4/fib_semantics.c @@ -590,32 +590,29 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, if (!dev) goto out; dev_hold(dev); - err = -ENETDOWN; - if (!(dev->flags & IFF_UP)) - goto out; - err = 0; -out: - rcu_read_unlock(); - return err; + err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN; } else { struct in_device *in_dev; if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) return -EINVAL; + rcu_read_lock(); + err = -ENODEV; in_dev = inetdev_by_index(net, nh->nh_oif); if (in_dev == NULL) - return -ENODEV; - if (!(in_dev->dev->flags & IFF_UP)) { - in_dev_put(in_dev); - return -ENETDOWN; - } + goto out; + err = -ENETDOWN; + if (!(in_dev->dev->flags & IFF_UP)) + goto out; nh->nh_dev = in_dev->dev; dev_hold(nh->nh_dev); nh->nh_scope = RT_SCOPE_HOST; - in_dev_put(in_dev); + err = 0; } - return 0; +out: + rcu_read_unlock(); + return err; } static inline unsigned int fib_laddr_hashfn(__be32 val) diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index a525328ec372..c8877c6c7216 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -1429,8 +1429,6 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) if (imr->imr_ifindex) { idev = inetdev_by_index(net, imr->imr_ifindex); - if (idev) - __in_dev_put(idev); return idev; } if (imr->imr_address.s_addr) { diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 9d421f4cf3ef..d0ffcbe369b7 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -1245,10 +1245,8 @@ static int ipgre_close(struct net_device *dev) if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) { struct in_device *in_dev; in_dev = inetdev_by_index(dev_net(dev), t->mlink); - if (in_dev) { + if (in_dev) ip_mc_dec_group(in_dev, t->parms.iph.daddr); - in_dev_put(in_dev); - } } return 0; }