Commit 776ee323 authored by David S. Miller's avatar David S. Miller

Merge branch 'arp-always-override-existing-neigh-entries-with-gratuitous-ARP'

Ihar Hrachyshka says:

====================
arp: always override existing neigh entries with gratuitous ARP

This patchset is spurred by discussion started at
https://patchwork.ozlabs.org/patch/760372/ where we figured that there is no
real reason for enforcing override by gratuitous ARP packets only when
arp_accept is 1. Same should happen when it's 0 (the default value).

changelog v2: handled review comments by Julian Anastasov
- fixed a mistake in a comment;
- postponed addr_type calculation to as late as possible.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 499350a5 7d472a59
...@@ -641,6 +641,32 @@ void arp_xmit(struct sk_buff *skb) ...@@ -641,6 +641,32 @@ void arp_xmit(struct sk_buff *skb)
} }
EXPORT_SYMBOL(arp_xmit); EXPORT_SYMBOL(arp_xmit);
static bool arp_is_garp(struct net *net, struct net_device *dev,
int *addr_type, __be16 ar_op,
__be32 sip, __be32 tip,
unsigned char *sha, unsigned char *tha)
{
bool is_garp = tip == sip;
/* Gratuitous ARP _replies_ also require target hwaddr to be
* the same as source.
*/
if (is_garp && ar_op == htons(ARPOP_REPLY))
is_garp =
/* IPv4 over IEEE 1394 doesn't provide target
* hardware address field in its ARP payload.
*/
tha &&
!memcmp(tha, sha, dev->addr_len);
if (is_garp) {
*addr_type = inet_addr_type_dev_table(net, dev, sip);
if (*addr_type != RTN_UNICAST)
is_garp = false;
}
return is_garp;
}
/* /*
* Process an arp request. * Process an arp request.
*/ */
...@@ -837,29 +863,25 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) ...@@ -837,29 +863,25 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
n = __neigh_lookup(&arp_tbl, &sip, dev, 0); n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
if (IN_DEV_ARP_ACCEPT(in_dev)) { if (n || IN_DEV_ARP_ACCEPT(in_dev)) {
unsigned int addr_type = inet_addr_type_dev_table(net, dev, sip); addr_type = -1;
is_garp = arp_is_garp(net, dev, &addr_type, arp->ar_op,
sip, tip, sha, tha);
}
if (IN_DEV_ARP_ACCEPT(in_dev)) {
/* Unsolicited ARP is not accepted by default. /* Unsolicited ARP is not accepted by default.
It is possible, that this option should be enabled for some It is possible, that this option should be enabled for some
devices (strip is candidate) devices (strip is candidate)
*/ */
is_garp = tip == sip && addr_type == RTN_UNICAST;
/* Unsolicited ARP _replies_ also require target hwaddr to be
* the same as source.
*/
if (is_garp && arp->ar_op == htons(ARPOP_REPLY))
is_garp =
/* IPv4 over IEEE 1394 doesn't provide target
* hardware address field in its ARP payload.
*/
tha &&
!memcmp(tha, sha, dev->addr_len);
if (!n && if (!n &&
((arp->ar_op == htons(ARPOP_REPLY) && (is_garp ||
addr_type == RTN_UNICAST) || is_garp)) (arp->ar_op == htons(ARPOP_REPLY) &&
(addr_type == RTN_UNICAST ||
(addr_type < 0 &&
/* postpone calculation to as late as possible */
inet_addr_type_dev_table(net, dev, sip) ==
RTN_UNICAST)))))
n = __neigh_lookup(&arp_tbl, &sip, dev, 1); n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment