| From 809a2c9b398e2b5375ff33c69195863378444d78 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 4 Feb 2022 12:15:45 -0800 |
| Subject: ipv6: make mc_forwarding atomic |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| [ Upstream commit 145c7a793838add5e004e7d49a67654dc7eba147 ] |
| |
| This fixes minor data-races in ip6_mc_input() and |
| batadv_mcast_mla_rtr_flags_softif_get_ipv6() |
| |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/ipv6.h | 2 +- |
| net/batman-adv/multicast.c | 2 +- |
| net/ipv6/addrconf.c | 4 ++-- |
| net/ipv6/ip6_input.c | 2 +- |
| net/ipv6/ip6mr.c | 8 ++++---- |
| 5 files changed, 9 insertions(+), 9 deletions(-) |
| |
| diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h |
| index a59d25f19385..b8641dc0ee66 100644 |
| --- a/include/linux/ipv6.h |
| +++ b/include/linux/ipv6.h |
| @@ -51,7 +51,7 @@ struct ipv6_devconf { |
| __s32 use_optimistic; |
| #endif |
| #ifdef CONFIG_IPV6_MROUTE |
| - __s32 mc_forwarding; |
| + atomic_t mc_forwarding; |
| #endif |
| __s32 disable_ipv6; |
| __s32 drop_unicast_in_l2_multicast; |
| diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c |
| index f4004cf0ff6f..9f311fddfaf9 100644 |
| --- a/net/batman-adv/multicast.c |
| +++ b/net/batman-adv/multicast.c |
| @@ -134,7 +134,7 @@ static u8 batadv_mcast_mla_rtr_flags_softif_get_ipv6(struct net_device *dev) |
| { |
| struct inet6_dev *in6_dev = __in6_dev_get(dev); |
| |
| - if (in6_dev && in6_dev->cnf.mc_forwarding) |
| + if (in6_dev && atomic_read(&in6_dev->cnf.mc_forwarding)) |
| return BATADV_NO_FLAGS; |
| else |
| return BATADV_MCAST_WANT_NO_RTR6; |
| diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
| index e92ca415756a..4f64fb285af7 100644 |
| --- a/net/ipv6/addrconf.c |
| +++ b/net/ipv6/addrconf.c |
| @@ -554,7 +554,7 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex, |
| #ifdef CONFIG_IPV6_MROUTE |
| if ((all || type == NETCONFA_MC_FORWARDING) && |
| nla_put_s32(skb, NETCONFA_MC_FORWARDING, |
| - devconf->mc_forwarding) < 0) |
| + atomic_read(&devconf->mc_forwarding)) < 0) |
| goto nla_put_failure; |
| #endif |
| if ((all || type == NETCONFA_PROXY_NEIGH) && |
| @@ -5539,7 +5539,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, |
| array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic; |
| #endif |
| #ifdef CONFIG_IPV6_MROUTE |
| - array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; |
| + array[DEVCONF_MC_FORWARDING] = atomic_read(&cnf->mc_forwarding); |
| #endif |
| array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; |
| array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; |
| diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c |
| index 80256717868e..d4b1e2c5aa76 100644 |
| --- a/net/ipv6/ip6_input.c |
| +++ b/net/ipv6/ip6_input.c |
| @@ -508,7 +508,7 @@ int ip6_mc_input(struct sk_buff *skb) |
| /* |
| * IPv6 multicast router mode is now supported ;) |
| */ |
| - if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding && |
| + if (atomic_read(&dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding) && |
| !(ipv6_addr_type(&hdr->daddr) & |
| (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) && |
| likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) { |
| diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c |
| index 6a4065d81aa9..91f1c5f56d5f 100644 |
| --- a/net/ipv6/ip6mr.c |
| +++ b/net/ipv6/ip6mr.c |
| @@ -739,7 +739,7 @@ static int mif6_delete(struct mr_table *mrt, int vifi, int notify, |
| |
| in6_dev = __in6_dev_get(dev); |
| if (in6_dev) { |
| - in6_dev->cnf.mc_forwarding--; |
| + atomic_dec(&in6_dev->cnf.mc_forwarding); |
| inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF, |
| NETCONFA_MC_FORWARDING, |
| dev->ifindex, &in6_dev->cnf); |
| @@ -907,7 +907,7 @@ static int mif6_add(struct net *net, struct mr_table *mrt, |
| |
| in6_dev = __in6_dev_get(dev); |
| if (in6_dev) { |
| - in6_dev->cnf.mc_forwarding++; |
| + atomic_inc(&in6_dev->cnf.mc_forwarding); |
| inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF, |
| NETCONFA_MC_FORWARDING, |
| dev->ifindex, &in6_dev->cnf); |
| @@ -1557,7 +1557,7 @@ static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk) |
| } else { |
| rcu_assign_pointer(mrt->mroute_sk, sk); |
| sock_set_flag(sk, SOCK_RCU_FREE); |
| - net->ipv6.devconf_all->mc_forwarding++; |
| + atomic_inc(&net->ipv6.devconf_all->mc_forwarding); |
| } |
| write_unlock_bh(&mrt_lock); |
| |
| @@ -1590,7 +1590,7 @@ int ip6mr_sk_done(struct sock *sk) |
| * so the RCU grace period before sk freeing |
| * is guaranteed by sk_destruct() |
| */ |
| - net->ipv6.devconf_all->mc_forwarding--; |
| + atomic_dec(&net->ipv6.devconf_all->mc_forwarding); |
| write_unlock_bh(&mrt_lock); |
| inet6_netconf_notify_devconf(net, RTM_NEWNETCONF, |
| NETCONFA_MC_FORWARDING, |
| -- |
| 2.35.1 |
| |