netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] net: ipv4: use a dedicated counter for icmp_v4 redirect packets
       [not found] <cover.1549476789.git.lorenzo.bianconi@redhat.com>
@ 2019-02-06 18:18 ` Lorenzo Bianconi
  2019-02-09  5:50   ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Lorenzo Bianconi @ 2019-02-06 18:18 UTC (permalink / raw)
  To: davem; +Cc: netdev

According to the algorithm described in the comment block at the
beginning of ip_rt_send_redirect, the host should try to send
'ip_rt_redirect_number' ICMP redirect packets with an exponential
backoff and then stop sending them at all assuming that the destination
ignores redirects.
If the device has previously sent some ICMP error packets that are
rate-limited (e.g TTL expired) and continues to receive traffic,
the redirect packets will never be transmitted. This happens since
peer->rate_tokens will be typically greater than 'ip_rt_redirect_number'
and so it will never be reset even if the redirect silence timeout
(ip_rt_redirect_silence) has elapsed without receiving any packet
requiring redirects.

Fix it by using a dedicated counter for the number of ICMP redirect
packets that has been sent by the host

I have not been able to identify a given commit that introduced the
issue since ip_rt_send_redirect implements the same rate-limiting
algorithm from commit 1da177e4c3f4 ("Linux-2.6.12-rc2")

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 include/net/inetpeer.h | 1 +
 net/ipv4/inetpeer.c    | 1 +
 net/ipv4/route.c       | 7 +++++--
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 00b5e7825508..74ff688568a0 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -39,6 +39,7 @@ struct inet_peer {
 
 	u32			metrics[RTAX_MAX];
 	u32			rate_tokens;	/* rate limiting for ICMP */
+	u32			n_redirects;
 	unsigned long		rate_last;
 	/*
 	 * Once inet_peer is queued for deletion (refcnt == 0), following field
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index d757b9642d0d..be778599bfed 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -216,6 +216,7 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base,
 			atomic_set(&p->rid, 0);
 			p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
 			p->rate_tokens = 0;
+			p->n_redirects = 0;
 			/* 60*HZ is arbitrary, but chosen enough high so that the first
 			 * calculation of tokens is at its maximum.
 			 */
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ce92f73cf104..5163b64f8fb3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -887,13 +887,15 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 	/* No redirected packets during ip_rt_redirect_silence;
 	 * reset the algorithm.
 	 */
-	if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence))
+	if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) {
 		peer->rate_tokens = 0;
+		peer->n_redirects = 0;
+	}
 
 	/* Too many ignored redirects; do not send anything
 	 * set dst.rate_last to the last seen redirected packet.
 	 */
-	if (peer->rate_tokens >= ip_rt_redirect_number) {
+	if (peer->n_redirects >= ip_rt_redirect_number) {
 		peer->rate_last = jiffies;
 		goto out_put_peer;
 	}
@@ -910,6 +912,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw);
 		peer->rate_last = jiffies;
 		++peer->rate_tokens;
+		++peer->n_redirects;
 #ifdef CONFIG_IP_ROUTE_VERBOSE
 		if (log_martians &&
 		    peer->rate_tokens == ip_rt_redirect_number)
-- 
2.20.1


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

* Re: [PATCH net] net: ipv4: use a dedicated counter for icmp_v4 redirect packets
  2019-02-06 18:18 ` [PATCH net] net: ipv4: use a dedicated counter for icmp_v4 redirect packets Lorenzo Bianconi
@ 2019-02-09  5:50   ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2019-02-09  5:50 UTC (permalink / raw)
  To: lorenzo.bianconi; +Cc: netdev

From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Wed,  6 Feb 2019 19:18:04 +0100

> According to the algorithm described in the comment block at the
> beginning of ip_rt_send_redirect, the host should try to send
> 'ip_rt_redirect_number' ICMP redirect packets with an exponential
> backoff and then stop sending them at all assuming that the destination
> ignores redirects.
> If the device has previously sent some ICMP error packets that are
> rate-limited (e.g TTL expired) and continues to receive traffic,
> the redirect packets will never be transmitted. This happens since
> peer->rate_tokens will be typically greater than 'ip_rt_redirect_number'
> and so it will never be reset even if the redirect silence timeout
> (ip_rt_redirect_silence) has elapsed without receiving any packet
> requiring redirects.
> 
> Fix it by using a dedicated counter for the number of ICMP redirect
> packets that has been sent by the host
> 
> I have not been able to identify a given commit that introduced the
> issue since ip_rt_send_redirect implements the same rate-limiting
> algorithm from commit 1da177e4c3f4 ("Linux-2.6.12-rc2")
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>

Applied and queued up for -stable, thanks.

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

end of thread, other threads:[~2019-02-09  5:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1549476789.git.lorenzo.bianconi@redhat.com>
2019-02-06 18:18 ` [PATCH net] net: ipv4: use a dedicated counter for icmp_v4 redirect packets Lorenzo Bianconi
2019-02-09  5:50   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).