Repository : ssh://git@open-mesh.org/batman-adv
On branch : master
commit e2b064ff5cf53e75fb8176b1c749474366a20ab9 Author: Sven Eckelmann sven@narfation.org Date: Thu Jun 27 19:22:06 2019 +0200
batman-adv: Get inet(6) device inside RCU protected region
It is not necessary to get the inet(6)_dev outside of the rcu protected region by using reference counting. Instead, the in(6)_dev_get can be replaced by the non-refcnt function and everything can be moved inside the rcu protected region.
Fixes: 2b0f11124aad ("batman-adv: mcast: collect softif listeners from IP lists instead") Reported-by: David Miller davem@davemloft.net Signed-off-by: Sven Eckelmann sven@narfation.org
e2b064ff5cf53e75fb8176b1c749474366a20ab9 net/batman-adv/multicast.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index 40ceab95..67d7f830 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -379,11 +379,14 @@ batadv_mcast_mla_softif_get_ipv4(struct net_device *dev, if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4) return 0;
- in_dev = in_dev_get(dev); - if (!in_dev) + rcu_read_lock(); + + in_dev = __in_dev_get_rcu(dev); + if (!in_dev) { + rcu_read_unlock(); return 0; + }
- rcu_read_lock(); for (pmc = rcu_dereference(in_dev->mc_list); pmc; pmc = rcu_dereference(pmc->next_rcu)) { if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && @@ -410,7 +413,6 @@ batadv_mcast_mla_softif_get_ipv4(struct net_device *dev, ret++; } rcu_read_unlock(); - in_dev_put(in_dev);
return ret; } @@ -444,9 +446,13 @@ batadv_mcast_mla_softif_get_ipv6(struct net_device *dev, if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6) return 0;
- in6_dev = in6_dev_get(dev); - if (!in6_dev) + rcu_read_lock(); + + in6_dev = __in6_dev_get(dev); + if (!in6_dev) { + rcu_read_unlock(); return 0; + }
read_lock_bh(&in6_dev->lock); for (pmc6 = in6_dev->mc_list; pmc6; pmc6 = pmc6->next) { @@ -479,7 +485,7 @@ batadv_mcast_mla_softif_get_ipv6(struct net_device *dev, ret++; } read_unlock_bh(&in6_dev->lock); - in6_dev_put(in6_dev); + rcu_read_unlock();
return ret; }