summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2020-05-08 20:28:34 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-20 09:11:52 +0300
commit98ee7d0d6a2b4724a0760cf2a0cb72c38b2aa985 (patch)
tree01f2d1a12e8ee57837d20277493fd90d61adf34c
parent62b4ebf58fe989b00164e167421c1da0ad0b69e9 (diff)
downloadlinux-98ee7d0d6a2b4724a0760cf2a0cb72c38b2aa985.tar.xz
net: ipv4: really enforce backoff for redirects
[ Upstream commit 57644431a6c2faac5d754ebd35780cf43a531b1a ] In commit b406472b5ad7 ("net: ipv4: avoid mixed n_redirects and rate_tokens usage") I missed the fact that a 0 'rate_tokens' will bypass the backoff algorithm. Since rate_tokens is cleared after a redirect silence, and never incremented on redirects, if the host keeps receiving packets requiring redirect it will reply ignoring the backoff. Additionally, the 'rate_last' field will be updated with the cadence of the ingress packet requiring redirect. If that rate is high enough, that will prevent the host from generating any other kind of ICMP messages The check for a zero 'rate_tokens' value was likely a shortcut to avoid the more complex backoff algorithm after a redirect silence period. Address the issue checking for 'n_redirects' instead, which is incremented on successful redirect, and does not interfere with other ICMP replies. Fixes: b406472b5ad7 ("net: ipv4: avoid mixed n_redirects and rate_tokens usage") Reported-and-tested-by: Colin Walters <walters@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/ipv4/route.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 29a87fadf01b..325083464dbd 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -898,7 +898,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
/* Check for load limit; set rate_last to the latest sent
* redirect.
*/
- if (peer->rate_tokens == 0 ||
+ if (peer->n_redirects == 0 ||
time_after(jiffies,
(peer->rate_last +
(ip_rt_redirect_load << peer->n_redirects)))) {