> Since commit c09551c6ff7f ("net: ipv4: use a dedicated counter > for icmp_v4 redirect packets") we use 'n_redirects' to account > for redirect packets, but we still use 'rate_tokens' to compute > the redirect packets exponential backoff. > > If the device sent to the relevant peer any ICMP error packet > after sending a redirect, it will also update 'rate_token' according > to the leaking bucket schema; typically 'rate_token' will raise > above BITS_PER_LONG and the redirect packets backoff algorithm > will produce undefined behavior. > > Fix the issue using 'n_redirects' to compute the exponential backoff > in ip_rt_send_redirect(). > > Note that we still clear rate_tokens after a redirect silence period, > to avoid changing an established behaviour. > > The root cause predates git history; before the mentioned commit in > the critical scenario, the kernel stopped sending redirects, after > the mentioned commit the behavior more randomic. > > Reported-by: Xiumei Mu <x...@redhat.com> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Fixes: c09551c6ff7f ("net: ipv4: use a dedicated counter for icmp_v4 redirect > packets") > Signed-off-by: Paolo Abeni <pab...@redhat.com>
Acked-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com> > --- > net/ipv4/route.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/net/ipv4/route.c b/net/ipv4/route.c > index 7dcce724c78b..14654876127e 100644 > --- a/net/ipv4/route.c > +++ b/net/ipv4/route.c > @@ -916,16 +916,15 @@ void ip_rt_send_redirect(struct sk_buff *skb) > if (peer->rate_tokens == 0 || > time_after(jiffies, > (peer->rate_last + > - (ip_rt_redirect_load << peer->rate_tokens)))) { > + (ip_rt_redirect_load << peer->n_redirects)))) { > __be32 gw = rt_nexthop(rt, ip_hdr(skb)->daddr); > > 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) > + peer->n_redirects == ip_rt_redirect_number) > net_warn_ratelimited("host %pI4/if%d ignores redirects > for %pI4 to %pI4\n", > &ip_hdr(skb)->saddr, inet_iif(skb), > &ip_hdr(skb)->daddr, &gw); > -- > 2.21.0 >
signature.asc
Description: PGP signature