Skip to content

Commit 23d268e

Browse files
booxterdavem330
authored andcommitted
arp: honour gratuitous ARP _replies_
When arp_accept is 1, gratuitous ARPs are supposed to override matching entries irrespective of whether they arrive during locktime. This was implemented in commit 56022a8 ("ipv4: arp: update neighbour address when a gratuitous arp is received and arp_accept is set") There is a glitch in the patch though. RFC 2002, section 4.6, "ARP, Proxy ARP, and Gratuitous ARP", defines gratuitous ARPs so that they can be either of Request or Reply type. Those Reply gratuitous ARPs can be triggered with standard tooling, for example, arping -A option does just that. This patch fixes the glitch, making both Request and Reply flavours of gratuitous ARPs to behave identically. As per RFC, if gratuitous ARPs are of Reply type, their Target Hardware Address field should also be set to the link-layer address to which this cache entry should be updated. The field is present in ARP over Ethernet but not in IEEE 1394. In this patch, I don't consider any broadcasted ARP replies as gratuitous if the field is not present, to conform the standard. It's not clear whether there is such a thing for IEEE 1394 as a gratuitous ARP reply; until it's cleared up, we will ignore such broadcasts. Note that they will still update existing ARP cache entries, assuming they arrive out of locktime time interval. Signed-off-by: Ihar Hrachyshka <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2432a3f commit 23d268e

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

net/ipv4/arp.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
653653
unsigned char *arp_ptr;
654654
struct rtable *rt;
655655
unsigned char *sha;
656+
unsigned char *tha = NULL;
656657
__be32 sip, tip;
657658
u16 dev_type = dev->type;
658659
int addr_type;
@@ -724,6 +725,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
724725
break;
725726
#endif
726727
default:
728+
tha = arp_ptr;
727729
arp_ptr += dev->addr_len;
728730
}
729731
memcpy(&tip, arp_ptr, 4);
@@ -842,8 +844,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
842844
It is possible, that this option should be enabled for some
843845
devices (strip is candidate)
844846
*/
845-
is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
846-
addr_type == RTN_UNICAST;
847+
is_garp = tip == sip && addr_type == RTN_UNICAST;
848+
849+
/* Unsolicited ARP _replies_ also require target hwaddr to be
850+
* the same as source.
851+
*/
852+
if (is_garp && arp->ar_op == htons(ARPOP_REPLY))
853+
is_garp =
854+
/* IPv4 over IEEE 1394 doesn't provide target
855+
* hardware address field in its ARP payload.
856+
*/
857+
tha &&
858+
!memcmp(tha, sha, dev->addr_len);
847859

848860
if (!n &&
849861
((arp->ar_op == htons(ARPOP_REPLY) &&

0 commit comments

Comments
 (0)