Skip to content

Commit 3dfe0b5

Browse files
q2venkuba-moo
authored andcommitted
neighbour: Allocate skb in neigh_get().
We will remove RTNL for neigh_get() and run it under RCU instead. neigh_get_reply() and pneigh_get_reply() allocate skb with GFP_KERNEL. Let's move the allocation before __dev_get_by_index() in neigh_get(). Now, neigh_get_reply() and pneigh_get_reply() are inlined and rtnl_unicast() is factorised. We will convert pneigh_lookup() to __pneigh_lookup() later. Signed-off-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f5046fb commit 3dfe0b5

File tree

1 file changed

+32
-56
lines changed

1 file changed

+32
-56
lines changed

net/core/neighbour.c

Lines changed: 32 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,27 +2988,6 @@ static inline size_t neigh_nlmsg_size(void)
29882988
+ nla_total_size(1); /* NDA_PROTOCOL */
29892989
}
29902990

2991-
static int neigh_get_reply(struct net *net, struct neighbour *neigh,
2992-
u32 pid, u32 seq)
2993-
{
2994-
struct sk_buff *skb;
2995-
int err = 0;
2996-
2997-
skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
2998-
if (!skb)
2999-
return -ENOBUFS;
3000-
3001-
err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
3002-
if (err) {
3003-
kfree_skb(skb);
3004-
goto errout;
3005-
}
3006-
3007-
err = rtnl_unicast(skb, net, pid);
3008-
errout:
3009-
return err;
3010-
}
3011-
30122991
static inline size_t pneigh_nlmsg_size(void)
30132992
{
30142993
return NLMSG_ALIGN(sizeof(struct ndmsg))
@@ -3017,34 +2996,16 @@ static inline size_t pneigh_nlmsg_size(void)
30172996
+ nla_total_size(1); /* NDA_PROTOCOL */
30182997
}
30192998

3020-
static int pneigh_get_reply(struct net *net, struct pneigh_entry *neigh,
3021-
u32 pid, u32 seq, struct neigh_table *tbl)
3022-
{
3023-
struct sk_buff *skb;
3024-
int err = 0;
3025-
3026-
skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
3027-
if (!skb)
3028-
return -ENOBUFS;
3029-
3030-
err = pneigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0, tbl);
3031-
if (err) {
3032-
kfree_skb(skb);
3033-
goto errout;
3034-
}
3035-
3036-
err = rtnl_unicast(skb, net, pid);
3037-
errout:
3038-
return err;
3039-
}
3040-
30412999
static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
30423000
struct netlink_ext_ack *extack)
30433001
{
30443002
struct net *net = sock_net(in_skb->sk);
3003+
u32 pid = NETLINK_CB(in_skb).portid;
30453004
struct net_device *dev = NULL;
30463005
struct neigh_table *tbl = NULL;
3006+
u32 seq = nlh->nlmsg_seq;
30473007
struct neighbour *neigh;
3008+
struct sk_buff *skb;
30483009
struct ndmsg *ndm;
30493010
void *dst = NULL;
30503011
int err;
@@ -3053,11 +3014,19 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
30533014
if (IS_ERR(ndm))
30543015
return PTR_ERR(ndm);
30553016

3017+
if (ndm->ndm_flags & NTF_PROXY)
3018+
skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
3019+
else
3020+
skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
3021+
if (!skb)
3022+
return -ENOBUFS;
3023+
30563024
if (ndm->ndm_ifindex) {
30573025
dev = __dev_get_by_index(net, ndm->ndm_ifindex);
30583026
if (!dev) {
30593027
NL_SET_ERR_MSG(extack, "Unknown device ifindex");
3060-
return -ENODEV;
3028+
err = -ENODEV;
3029+
goto err_free_skb;
30613030
}
30623031
}
30633032

@@ -3067,23 +3036,30 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
30673036
pn = pneigh_lookup(tbl, net, dst, dev, 0);
30683037
if (!pn) {
30693038
NL_SET_ERR_MSG(extack, "Proxy neighbour entry not found");
3070-
return -ENOENT;
3039+
err = -ENOENT;
3040+
goto err_free_skb;
30713041
}
3072-
return pneigh_get_reply(net, pn, NETLINK_CB(in_skb).portid,
3073-
nlh->nlmsg_seq, tbl);
3074-
}
3075-
3076-
neigh = neigh_lookup(tbl, dst, dev);
3077-
if (!neigh) {
3078-
NL_SET_ERR_MSG(extack, "Neighbour entry not found");
3079-
return -ENOENT;
3080-
}
30813042

3082-
err = neigh_get_reply(net, neigh, NETLINK_CB(in_skb).portid,
3083-
nlh->nlmsg_seq);
3043+
err = pneigh_fill_info(skb, pn, pid, seq, RTM_NEWNEIGH, 0, tbl);
3044+
if (err)
3045+
goto err_free_skb;
3046+
} else {
3047+
neigh = neigh_lookup(tbl, dst, dev);
3048+
if (!neigh) {
3049+
NL_SET_ERR_MSG(extack, "Neighbour entry not found");
3050+
err = -ENOENT;
3051+
goto err_free_skb;
3052+
}
30843053

3085-
neigh_release(neigh);
3054+
err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
3055+
neigh_release(neigh);
3056+
if (err)
3057+
goto err_free_skb;
3058+
}
30863059

3060+
return rtnl_unicast(skb, net, pid);
3061+
err_free_skb:
3062+
kfree_skb(skb);
30873063
return err;
30883064
}
30893065

0 commit comments

Comments
 (0)