All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arp: honour gratuitous ARP _replies_
@ 2017-05-10  0:16 Ihar Hrachyshka
  2017-05-15 18:08 ` David Miller
  0 siblings, 1 reply; 5+ messages in thread
From: Ihar Hrachyshka @ 2017-05-10  0:16 UTC (permalink / raw)
  To: David S. Miller, James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, netdev
  Cc: Ihar Hrachyshka

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 56022a8fdd87 ("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 <ihrachys@redhat.com>
---
 net/ipv4/arp.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 0937b34..fb97b9c 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -653,6 +653,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 	unsigned char *arp_ptr;
 	struct rtable *rt;
 	unsigned char *sha;
+	unsigned char *tha = NULL;
 	__be32 sip, tip;
 	u16 dev_type = dev->type;
 	int addr_type;
@@ -724,6 +725,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		break;
 #endif
 	default:
+		tha = arp_ptr;
 		arp_ptr += dev->addr_len;
 	}
 	memcpy(&tip, arp_ptr, 4);
@@ -842,8 +844,20 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		   It is possible, that this option should be enabled for some
 		   devices (strip is candidate)
 		 */
-		is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
-			  addr_type == RTN_UNICAST;
+		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 =
+#if IS_ENABLED(CONFIG_FIREWIRE_NET)
+				/* IPv4 over IEEE 1394 doesn't provide target
+				 * hardware address field in its ARP payload.
+				 */
+				tha &&
+#endif
+				!memcmp(tha, sha, dev->addr_len);
 
 		if (!n &&
 		    ((arp->ar_op == htons(ARPOP_REPLY)  &&
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] arp: honour gratuitous ARP _replies_
  2017-05-10  0:16 [PATCH] arp: honour gratuitous ARP _replies_ Ihar Hrachyshka
@ 2017-05-15 18:08 ` David Miller
  2017-05-15 21:16   ` Ihar Hrachyshka
  2017-05-16 14:53   ` [PATCH v2] " Ihar Hrachyshka
  0 siblings, 2 replies; 5+ messages in thread
From: David Miller @ 2017-05-15 18:08 UTC (permalink / raw)
  To: ihrachys; +Cc: jmorris, yoshfuji, kaber, netdev

From: Ihar Hrachyshka <ihrachys@redhat.com>
Date: Tue,  9 May 2017 17:16:07 -0700

> @@ -842,8 +844,20 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
>  		   It is possible, that this option should be enabled for some
>  		   devices (strip is candidate)
>  		 */
> -		is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
> -			  addr_type == RTN_UNICAST;
> +		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 =
> +#if IS_ENABLED(CONFIG_FIREWIRE_NET)
> +				/* IPv4 over IEEE 1394 doesn't provide target
> +				 * hardware address field in its ARP payload.
> +				 */
> +				tha &&
> +#endif
> +				!memcmp(tha, sha, dev->addr_len);
>  

The ifdefs here make the test harder to understand.

I would suggest removing the ifdef and letting the compiler remove the 'tha'
check if it can.

Thank you.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] arp: honour gratuitous ARP _replies_
  2017-05-15 18:08 ` David Miller
@ 2017-05-15 21:16   ` Ihar Hrachyshka
  2017-05-16 15:01     ` Ihar Hrachyshka
  2017-05-16 14:53   ` [PATCH v2] " Ihar Hrachyshka
  1 sibling, 1 reply; 5+ messages in thread
From: Ihar Hrachyshka @ 2017-05-15 21:16 UTC (permalink / raw)
  To: davem; +Cc: netdev, Ihar Hrachyshka

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 56022a8fdd87 ("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 <ihrachys@redhat.com>
---
 net/ipv4/arp.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 0937b34..d54345a 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -653,6 +653,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 	unsigned char *arp_ptr;
 	struct rtable *rt;
 	unsigned char *sha;
+	unsigned char *tha = NULL;
 	__be32 sip, tip;
 	u16 dev_type = dev->type;
 	int addr_type;
@@ -724,6 +725,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		break;
 #endif
 	default:
+		tha = arp_ptr;
 		arp_ptr += dev->addr_len;
 	}
 	memcpy(&tip, arp_ptr, 4);
@@ -842,8 +844,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		   It is possible, that this option should be enabled for some
 		   devices (strip is candidate)
 		 */
-		is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
-			  addr_type == RTN_UNICAST;
+		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 &&
 		    ((arp->ar_op == htons(ARPOP_REPLY)  &&
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] arp: honour gratuitous ARP _replies_
  2017-05-15 18:08 ` David Miller
  2017-05-15 21:16   ` Ihar Hrachyshka
@ 2017-05-16 14:53   ` Ihar Hrachyshka
  1 sibling, 0 replies; 5+ messages in thread
From: Ihar Hrachyshka @ 2017-05-16 14:53 UTC (permalink / raw)
  To: davem; +Cc: netdev, Ihar Hrachyshka

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 56022a8fdd87 ("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 <ihrachys@redhat.com>
---
v2:
- removed #ifdef for CONFIG_FIREWIRE_NET
---
 net/ipv4/arp.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 0937b34..d54345a 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -653,6 +653,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 	unsigned char *arp_ptr;
 	struct rtable *rt;
 	unsigned char *sha;
+	unsigned char *tha = NULL;
 	__be32 sip, tip;
 	u16 dev_type = dev->type;
 	int addr_type;
@@ -724,6 +725,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		break;
 #endif
 	default:
+		tha = arp_ptr;
 		arp_ptr += dev->addr_len;
 	}
 	memcpy(&tip, arp_ptr, 4);
@@ -842,8 +844,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		   It is possible, that this option should be enabled for some
 		   devices (strip is candidate)
 		 */
-		is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
-			  addr_type == RTN_UNICAST;
+		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 &&
 		    ((arp->ar_op == htons(ARPOP_REPLY)  &&
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] arp: honour gratuitous ARP _replies_
  2017-05-15 21:16   ` Ihar Hrachyshka
@ 2017-05-16 15:01     ` Ihar Hrachyshka
  0 siblings, 0 replies; 5+ messages in thread
From: Ihar Hrachyshka @ 2017-05-16 15:01 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Ihar Hrachyshka

On Mon, May 15, 2017 at 2:16 PM, Ihar Hrachyshka <ihrachys@redhat.com> wrote:
> 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 56022a8fdd87 ("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 <ihrachys@redhat.com>

Please disregard this email, I forgot to update the patch version to
v2 and provide changelog. I posted (hopefully) correct version. Still
learning the process...

Ihar

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-05-16 15:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10  0:16 [PATCH] arp: honour gratuitous ARP _replies_ Ihar Hrachyshka
2017-05-15 18:08 ` David Miller
2017-05-15 21:16   ` Ihar Hrachyshka
2017-05-16 15:01     ` Ihar Hrachyshka
2017-05-16 14:53   ` [PATCH v2] " Ihar Hrachyshka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.