mirror of
https://github.com/torvalds/linux.git
synced 2026-10-16 04:39:02 +02:00
net: core: neighbour: Add a neigh_fill_info() helper for when lock not held
The netlink message needs to be formatted and sent inside the critical section where the neighbor is changed, so that it reflects the notified-upon neighbor state. Because it will happen inside an already existing critical section, it has to assume that the neighbor lock is held. Add a helper __neigh_fill_info(), which is like neigh_fill_info(), but makes this assumption. Convert neigh_fill_info() to a wrapper around this new helper. Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/7ec20113d5d809200e3534d3ed8f0004514914b8.1769012464.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e4faaf65a7
commit
77fa50dcb9
|
|
@ -2622,8 +2622,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
return skb->len;
|
||||
}
|
||||
|
||||
static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
|
||||
u32 pid, u32 seq, int type, unsigned int flags)
|
||||
static int __neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
|
||||
u32 pid, u32 seq, int type, unsigned int flags)
|
||||
{
|
||||
u32 neigh_flags, neigh_flags_ext;
|
||||
unsigned long now = jiffies;
|
||||
|
|
@ -2649,23 +2649,19 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
|
|||
if (nla_put(skb, NDA_DST, neigh->tbl->key_len, neigh->primary_key))
|
||||
goto nla_put_failure;
|
||||
|
||||
read_lock_bh(&neigh->lock);
|
||||
ndm->ndm_state = neigh->nud_state;
|
||||
if (neigh->nud_state & NUD_VALID) {
|
||||
char haddr[MAX_ADDR_LEN];
|
||||
|
||||
neigh_ha_snapshot(haddr, neigh, neigh->dev);
|
||||
if (nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, haddr) < 0) {
|
||||
read_unlock_bh(&neigh->lock);
|
||||
if (nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, haddr) < 0)
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
ci.ndm_used = jiffies_to_clock_t(now - neigh->used);
|
||||
ci.ndm_confirmed = jiffies_to_clock_t(now - neigh->confirmed);
|
||||
ci.ndm_updated = jiffies_to_clock_t(now - neigh->updated);
|
||||
ci.ndm_refcnt = refcount_read(&neigh->refcnt) - 1;
|
||||
read_unlock_bh(&neigh->lock);
|
||||
|
||||
if (nla_put_u32(skb, NDA_PROBES, atomic_read(&neigh->probes)) ||
|
||||
nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
|
||||
|
|
@ -2684,6 +2680,20 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
|
|||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
|
||||
u32 pid, u32 seq, int type, unsigned int flags)
|
||||
__releases(neigh->lock)
|
||||
__acquires(neigh->lock)
|
||||
{
|
||||
int err;
|
||||
|
||||
read_lock_bh(&neigh->lock);
|
||||
err = __neigh_fill_info(skb, neigh, pid, seq, type, flags);
|
||||
read_unlock_bh(&neigh->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
|
||||
u32 pid, u32 seq, int type, unsigned int flags,
|
||||
struct neigh_table *tbl)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user