Skip to content

Commit dc2a27e

Browse files
q2venkuba-moo
authored andcommitted
neighbour: Update pneigh_entry in pneigh_create().
neigh_add() updates pneigh_entry() found or created by pneigh_create(). This update is serialised by RTNL, but we will remove it. Let's move the update part to pneigh_create() and make it return errno instead of a pointer of pneigh_entry. Now, the pneigh code is RTNL free. Signed-off-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 13a936b commit dc2a27e

File tree

3 files changed

+20
-23
lines changed

3 files changed

+20
-23
lines changed

include/net/neighbour.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,9 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
382382
struct sk_buff *skb);
383383
struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net,
384384
const void *key, struct net_device *dev);
385-
struct pneigh_entry *pneigh_create(struct neigh_table *tbl, struct net *net,
386-
const void *key, struct net_device *dev);
385+
int pneigh_create(struct neigh_table *tbl, struct net *net, const void *key,
386+
struct net_device *dev, u32 flags, u8 protocol,
387+
bool permanent);
387388
int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key,
388389
struct net_device *dev);
389390

net/core/neighbour.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -747,24 +747,27 @@ struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl,
747747
}
748748
EXPORT_IPV6_MOD(pneigh_lookup);
749749

750-
struct pneigh_entry *pneigh_create(struct neigh_table *tbl,
751-
struct net *net, const void *pkey,
752-
struct net_device *dev)
750+
int pneigh_create(struct neigh_table *tbl, struct net *net,
751+
const void *pkey, struct net_device *dev,
752+
u32 flags, u8 protocol, bool permanent)
753753
{
754754
struct pneigh_entry *n;
755755
unsigned int key_len;
756756
u32 hash_val;
757+
int err = 0;
757758

758759
mutex_lock(&tbl->phash_lock);
759760

760761
n = pneigh_lookup(tbl, net, pkey, dev);
761762
if (n)
762-
goto out;
763+
goto update;
763764

764765
key_len = tbl->key_len;
765766
n = kzalloc(sizeof(*n) + key_len, GFP_KERNEL);
766-
if (!n)
767+
if (!n) {
768+
err = -ENOBUFS;
767769
goto out;
770+
}
768771

769772
write_pnet(&n->net, net);
770773
memcpy(n->key, pkey, key_len);
@@ -774,16 +777,20 @@ struct pneigh_entry *pneigh_create(struct neigh_table *tbl,
774777
if (tbl->pconstructor && tbl->pconstructor(n)) {
775778
netdev_put(dev, &n->dev_tracker);
776779
kfree(n);
777-
n = NULL;
780+
err = -ENOBUFS;
778781
goto out;
779782
}
780783

781784
hash_val = pneigh_hash(pkey, key_len);
782785
n->next = tbl->phash_buckets[hash_val];
783786
rcu_assign_pointer(tbl->phash_buckets[hash_val], n);
787+
update:
788+
WRITE_ONCE(n->flags, flags);
789+
n->permanent = permanent;
790+
WRITE_ONCE(n->protocol, protocol);
784791
out:
785792
mutex_unlock(&tbl->phash_lock);
786-
return n;
793+
return err;
787794
}
788795

789796
static void pneigh_destroy(struct rcu_head *rcu)
@@ -2015,22 +2022,13 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
20152022
if (tb[NDA_PROTOCOL])
20162023
protocol = nla_get_u8(tb[NDA_PROTOCOL]);
20172024
if (ndm_flags & NTF_PROXY) {
2018-
struct pneigh_entry *pn;
2019-
20202025
if (ndm_flags & (NTF_MANAGED | NTF_EXT_VALIDATED)) {
20212026
NL_SET_ERR_MSG(extack, "Invalid NTF_* flag combination");
20222027
goto out;
20232028
}
20242029

2025-
err = -ENOBUFS;
2026-
pn = pneigh_create(tbl, net, dst, dev);
2027-
if (pn) {
2028-
WRITE_ONCE(pn->flags, ndm_flags);
2029-
pn->permanent = !!(ndm->ndm_state & NUD_PERMANENT);
2030-
if (protocol)
2031-
WRITE_ONCE(pn->protocol, protocol);
2032-
err = 0;
2033-
}
2030+
err = pneigh_create(tbl, net, dst, dev, ndm_flags, protocol,
2031+
!!(ndm->ndm_state & NUD_PERMANENT));
20342032
goto out;
20352033
}
20362034

net/ipv4/arp.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,9 +1089,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
10891089
if (mask) {
10901090
__be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
10911091

1092-
if (!pneigh_create(&arp_tbl, net, &ip, dev))
1093-
return -ENOBUFS;
1094-
return 0;
1092+
return pneigh_create(&arp_tbl, net, &ip, dev, 0, 0, false);
10951093
}
10961094

10971095
return arp_req_set_proxy(net, dev, 1);

0 commit comments

Comments
 (0)