mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 05:41:55 +00:00
inet: annotate devconf data-races
Add READ_ONCE() in ipv4_devconf_get() and corresponding WRITE_ONCE() in ipv4_devconf_set() Add IPV4_DEVCONF_RO() and IPV4_DEVCONF_ALL_RO() macros, and use them when reading devconf fields. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Link: https://lore.kernel.org/r/20240227092411.2315725-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e83ddcea65
commit
0598f8f3bb
@ -53,13 +53,15 @@ struct in_device {
|
||||
};
|
||||
|
||||
#define IPV4_DEVCONF(cnf, attr) ((cnf).data[IPV4_DEVCONF_ ## attr - 1])
|
||||
#define IPV4_DEVCONF_RO(cnf, attr) READ_ONCE(IPV4_DEVCONF(cnf, attr))
|
||||
#define IPV4_DEVCONF_ALL(net, attr) \
|
||||
IPV4_DEVCONF((*(net)->ipv4.devconf_all), attr)
|
||||
#define IPV4_DEVCONF_ALL_RO(net, attr) READ_ONCE(IPV4_DEVCONF_ALL(net, attr))
|
||||
|
||||
static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
|
||||
static inline int ipv4_devconf_get(const struct in_device *in_dev, int index)
|
||||
{
|
||||
index--;
|
||||
return in_dev->cnf.data[index];
|
||||
return READ_ONCE(in_dev->cnf.data[index]);
|
||||
}
|
||||
|
||||
static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
|
||||
@ -67,7 +69,7 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
|
||||
{
|
||||
index--;
|
||||
set_bit(index, in_dev->cnf.state);
|
||||
in_dev->cnf.data[index] = val;
|
||||
WRITE_ONCE(in_dev->cnf.data[index], val);
|
||||
}
|
||||
|
||||
static inline void ipv4_devconf_setall(struct in_device *in_dev)
|
||||
@ -81,18 +83,18 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
|
||||
ipv4_devconf_set((in_dev), IPV4_DEVCONF_ ## attr, (val))
|
||||
|
||||
#define IN_DEV_ANDCONF(in_dev, attr) \
|
||||
(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) && \
|
||||
(IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), attr) && \
|
||||
IN_DEV_CONF_GET((in_dev), attr))
|
||||
|
||||
#define IN_DEV_NET_ORCONF(in_dev, net, attr) \
|
||||
(IPV4_DEVCONF_ALL(net, attr) || \
|
||||
(IPV4_DEVCONF_ALL_RO(net, attr) || \
|
||||
IN_DEV_CONF_GET((in_dev), attr))
|
||||
|
||||
#define IN_DEV_ORCONF(in_dev, attr) \
|
||||
IN_DEV_NET_ORCONF(in_dev, dev_net(in_dev->dev), attr)
|
||||
|
||||
#define IN_DEV_MAXCONF(in_dev, attr) \
|
||||
(max(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr), \
|
||||
(max(IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), attr), \
|
||||
IN_DEV_CONF_GET((in_dev), attr)))
|
||||
|
||||
#define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
|
||||
|
@ -1982,7 +1982,7 @@ static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
|
||||
return -EMSGSIZE;
|
||||
|
||||
for (i = 0; i < IPV4_DEVCONF_MAX; i++)
|
||||
((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i];
|
||||
((u32 *) nla_data(nla))[i] = READ_ONCE(in_dev->cnf.data[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2068,9 +2068,9 @@ static int inet_netconf_msgsize_devconf(int type)
|
||||
}
|
||||
|
||||
static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
||||
struct ipv4_devconf *devconf, u32 portid,
|
||||
u32 seq, int event, unsigned int flags,
|
||||
int type)
|
||||
const struct ipv4_devconf *devconf,
|
||||
u32 portid, u32 seq, int event,
|
||||
unsigned int flags, int type)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct netconfmsg *ncm;
|
||||
@ -2095,27 +2095,28 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
||||
|
||||
if ((all || type == NETCONFA_FORWARDING) &&
|
||||
nla_put_s32(skb, NETCONFA_FORWARDING,
|
||||
IPV4_DEVCONF(*devconf, FORWARDING)) < 0)
|
||||
IPV4_DEVCONF_RO(*devconf, FORWARDING)) < 0)
|
||||
goto nla_put_failure;
|
||||
if ((all || type == NETCONFA_RP_FILTER) &&
|
||||
nla_put_s32(skb, NETCONFA_RP_FILTER,
|
||||
IPV4_DEVCONF(*devconf, RP_FILTER)) < 0)
|
||||
IPV4_DEVCONF_RO(*devconf, RP_FILTER)) < 0)
|
||||
goto nla_put_failure;
|
||||
if ((all || type == NETCONFA_MC_FORWARDING) &&
|
||||
nla_put_s32(skb, NETCONFA_MC_FORWARDING,
|
||||
IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0)
|
||||
IPV4_DEVCONF_RO(*devconf, MC_FORWARDING)) < 0)
|
||||
goto nla_put_failure;
|
||||
if ((all || type == NETCONFA_BC_FORWARDING) &&
|
||||
nla_put_s32(skb, NETCONFA_BC_FORWARDING,
|
||||
IPV4_DEVCONF(*devconf, BC_FORWARDING)) < 0)
|
||||
IPV4_DEVCONF_RO(*devconf, BC_FORWARDING)) < 0)
|
||||
goto nla_put_failure;
|
||||
if ((all || type == NETCONFA_PROXY_NEIGH) &&
|
||||
nla_put_s32(skb, NETCONFA_PROXY_NEIGH,
|
||||
IPV4_DEVCONF(*devconf, PROXY_ARP)) < 0)
|
||||
IPV4_DEVCONF_RO(*devconf, PROXY_ARP)) < 0)
|
||||
goto nla_put_failure;
|
||||
if ((all || type == NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN) &&
|
||||
nla_put_s32(skb, NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
IPV4_DEVCONF(*devconf, IGNORE_ROUTES_WITH_LINKDOWN)) < 0)
|
||||
IPV4_DEVCONF_RO(*devconf,
|
||||
IGNORE_ROUTES_WITH_LINKDOWN)) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
out:
|
||||
|
@ -120,12 +120,12 @@
|
||||
*/
|
||||
|
||||
#define IGMP_V1_SEEN(in_dev) \
|
||||
(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 1 || \
|
||||
(IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 1 || \
|
||||
IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
|
||||
((in_dev)->mr_v1_seen && \
|
||||
time_before(jiffies, (in_dev)->mr_v1_seen)))
|
||||
#define IGMP_V2_SEEN(in_dev) \
|
||||
(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 2 || \
|
||||
(IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 2 || \
|
||||
IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
|
||||
((in_dev)->mr_v2_seen && \
|
||||
time_before(jiffies, (in_dev)->mr_v2_seen)))
|
||||
|
@ -395,7 +395,7 @@ static int snmp_seq_show_ipstats(struct seq_file *seq, void *v)
|
||||
seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
|
||||
|
||||
seq_printf(seq, "\nIp: %d %d",
|
||||
IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2,
|
||||
IPV4_DEVCONF_ALL_RO(net, FORWARDING) ? 1 : 2,
|
||||
READ_ONCE(net->ipv4.sysctl_ip_default_ttl));
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0);
|
||||
|
@ -2313,7 +2313,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
||||
if (IN_DEV_BFORWARD(in_dev))
|
||||
goto make_route;
|
||||
/* not do cache if bc_forwarding is enabled */
|
||||
if (IPV4_DEVCONF_ALL(net, BC_FORWARDING))
|
||||
if (IPV4_DEVCONF_ALL_RO(net, BC_FORWARDING))
|
||||
do_cache = false;
|
||||
goto brd_input;
|
||||
}
|
||||
@ -2993,7 +2993,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
|
||||
#ifdef CONFIG_IP_MROUTE
|
||||
if (ipv4_is_multicast(dst) &&
|
||||
!ipv4_is_local_multicast(dst) &&
|
||||
IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
|
||||
IPV4_DEVCONF_ALL_RO(net, MC_FORWARDING)) {
|
||||
int err = ipmr_get_route(net, skb,
|
||||
fl4->saddr, fl4->daddr,
|
||||
r, portid);
|
||||
|
Loading…
Reference in New Issue
Block a user