Skip to content

Commit f869613

Browse files
q2venkuba-moo
authored andcommitted
arp: Factorise ip_route_output() call in arp_req_set() and arp_req_delete().
When ioctl(SIOCDARP/SIOCSARP) is issued for non-proxy entry (no ATF_COM) without arpreq.arp_dev[] set, arp_req_set() and arp_req_delete() looks up dev based on IPv4 address by ip_route_output(). Let's factorise the same code as arp_req_dev(). Signed-off-by: Kuniyuki Iwashima <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0592367 commit f869613

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

net/ipv4/arp.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,27 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
10031003
* User level interface (ioctl)
10041004
*/
10051005

1006+
static struct net_device *arp_req_dev(struct net *net, struct arpreq *r)
1007+
{
1008+
struct net_device *dev;
1009+
struct rtable *rt;
1010+
__be32 ip;
1011+
1012+
ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
1013+
1014+
rt = ip_route_output(net, ip, 0, 0, 0, RT_SCOPE_LINK);
1015+
if (IS_ERR(rt))
1016+
return ERR_CAST(rt);
1017+
1018+
dev = rt->dst.dev;
1019+
ip_rt_put(rt);
1020+
1021+
if (!dev)
1022+
return ERR_PTR(-EINVAL);
1023+
1024+
return dev;
1025+
}
1026+
10061027
/*
10071028
* Set (create) an ARP cache entry.
10081029
*/
@@ -1045,25 +1066,17 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
10451066
static int arp_req_set(struct net *net, struct arpreq *r,
10461067
struct net_device *dev)
10471068
{
1048-
__be32 ip;
10491069
struct neighbour *neigh;
1070+
__be32 ip;
10501071
int err;
10511072

10521073
if (r->arp_flags & ATF_PUBL)
10531074
return arp_req_set_public(net, r, dev);
10541075

1055-
ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
1056-
10571076
if (!dev) {
1058-
struct rtable *rt = ip_route_output(net, ip, 0, 0, 0,
1059-
RT_SCOPE_LINK);
1060-
1061-
if (IS_ERR(rt))
1062-
return PTR_ERR(rt);
1063-
dev = rt->dst.dev;
1064-
ip_rt_put(rt);
1065-
if (!dev)
1066-
return -EINVAL;
1077+
dev = arp_req_dev(net, r);
1078+
if (IS_ERR(dev))
1079+
return PTR_ERR(dev);
10671080
}
10681081
switch (dev->type) {
10691082
#if IS_ENABLED(CONFIG_FDDI)
@@ -1086,6 +1099,8 @@ static int arp_req_set(struct net *net, struct arpreq *r,
10861099
break;
10871100
}
10881101

1102+
ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
1103+
10891104
neigh = __neigh_lookup_errno(&arp_tbl, &ip, dev);
10901105
err = PTR_ERR(neigh);
10911106
if (!IS_ERR(neigh)) {
@@ -1191,14 +1206,9 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
11911206

11921207
ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
11931208
if (!dev) {
1194-
struct rtable *rt = ip_route_output(net, ip, 0, 0, 0,
1195-
RT_SCOPE_LINK);
1196-
if (IS_ERR(rt))
1197-
return PTR_ERR(rt);
1198-
dev = rt->dst.dev;
1199-
ip_rt_put(rt);
1200-
if (!dev)
1201-
return -EINVAL;
1209+
dev = arp_req_dev(net, r);
1210+
if (IS_ERR(dev))
1211+
return PTR_ERR(dev);
12021212
}
12031213
return arp_invalidate(dev, ip, true);
12041214
}

0 commit comments

Comments
 (0)