summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@google.com>2025-07-16 22:08:13 +0000
committerJakub Kicinski <kuba@kernel.org>2025-07-17 16:25:21 -0700
commitcc03492c7b92cb4414bd72a88f4d88ceb78362f9 (patch)
tree1b46db70c93a096173d0d4e1e0ebff603dbdc1cf
parentd539d8fbd8fcf64a1492c51f5ee99aaa8a8dc9ab (diff)
neighbour: Annotate access to struct pneigh_entry.{flags,protocol}.
We will convert pneigh readers to RCU, and its flags and protocol will be read locklessly. Let's annotate the access to the two fields. Note that all access to pn->permanent is under RTNL (neigh_add() and pneigh_ifdown_and_unlock()), so WRITE_ONCE() and READ_ONCE() are not needed. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20250716221221.442239-9-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/core/neighbour.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index fa2e60a479ef..59dfdecddff3 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2044,10 +2044,10 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
err = -ENOBUFS;
pn = pneigh_create(tbl, net, dst, dev);
if (pn) {
- pn->flags = ndm_flags;
+ WRITE_ONCE(pn->flags, ndm_flags);
pn->permanent = !!(ndm->ndm_state & NUD_PERMANENT);
if (protocol)
- pn->protocol = protocol;
+ WRITE_ONCE(pn->protocol, protocol);
err = 0;
}
goto out;
@@ -2678,13 +2678,15 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
u32 neigh_flags, neigh_flags_ext;
struct nlmsghdr *nlh;
struct ndmsg *ndm;
+ u8 protocol;
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
if (nlh == NULL)
return -EMSGSIZE;
- neigh_flags_ext = pn->flags >> NTF_EXT_SHIFT;
- neigh_flags = pn->flags & NTF_OLD_MASK;
+ neigh_flags = READ_ONCE(pn->flags);
+ neigh_flags_ext = neigh_flags >> NTF_EXT_SHIFT;
+ neigh_flags &= NTF_OLD_MASK;
ndm = nlmsg_data(nlh);
ndm->ndm_family = tbl->family;
@@ -2698,7 +2700,8 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
if (nla_put(skb, NDA_DST, tbl->key_len, pn->key))
goto nla_put_failure;
- if (pn->protocol && nla_put_u8(skb, NDA_PROTOCOL, pn->protocol))
+ protocol = READ_ONCE(pn->protocol);
+ if (protocol && nla_put_u8(skb, NDA_PROTOCOL, protocol))
goto nla_put_failure;
if (neigh_flags_ext && nla_put_u32(skb, NDA_FLAGS_EXT, neigh_flags_ext))
goto nla_put_failure;