Skip to content

Commit 56022a8

Browse files
Salam Noureddinedavem330
authored andcommitted
ipv4: arp: update neighbour address when a gratuitous arp is received and arp_accept is set
Gratuitous arp packets are useful in switchover scenarios to update client arp tables as quickly as possible. Currently, the mac address of a neighbour is only updated after a locktime period has elapsed since the last update. In most use cases such delays are unacceptable for network admins. Moreover, the "updated" field of the neighbour stucture doesn't record the last time the address of a neighbour changed but records any change that happens to the neighbour. This is clearly a bug since locktime uses that field as meaning "addr_updated". With this observation, I was able to perpetuate a stale address by sending a stream of gratuitous arp packets spaced less than locktime apart. With this change the address is updated when a gratuitous arp is received and the arp_accept sysctl is set. Signed-off-by: Salam Noureddine <[email protected]> Acked-by: Hannes Frederic Sowa <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e824353 commit 56022a8

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

net/ipv4/arp.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ static int arp_process(struct sk_buff *skb)
732732
int addr_type;
733733
struct neighbour *n;
734734
struct net *net = dev_net(dev);
735+
bool is_garp = false;
735736

736737
/* arp_rcv below verifies the ARP header and verifies the device
737738
* is ARP'able.
@@ -898,10 +899,12 @@ static int arp_process(struct sk_buff *skb)
898899
It is possible, that this option should be enabled for some
899900
devices (strip is candidate)
900901
*/
902+
is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
903+
inet_addr_type(net, sip) == RTN_UNICAST;
904+
901905
if (n == NULL &&
902-
(arp->ar_op == htons(ARPOP_REPLY) ||
903-
(arp->ar_op == htons(ARPOP_REQUEST) && tip == sip)) &&
904-
inet_addr_type(net, sip) == RTN_UNICAST)
906+
((arp->ar_op == htons(ARPOP_REPLY) &&
907+
inet_addr_type(net, sip) == RTN_UNICAST) || is_garp))
905908
n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
906909
}
907910

@@ -914,8 +917,10 @@ static int arp_process(struct sk_buff *skb)
914917
agents are active. Taking the first reply prevents
915918
arp trashing and chooses the fastest router.
916919
*/
917-
override = time_after(jiffies, n->updated +
918-
NEIGH_VAR(n->parms, LOCKTIME));
920+
override = time_after(jiffies,
921+
n->updated +
922+
NEIGH_VAR(n->parms, LOCKTIME)) ||
923+
is_garp;
919924

920925
/* Broadcast replies and request packets
921926
do not assert neighbour reachability.

0 commit comments

Comments
 (0)