From patchwork Wed Jun 14 11:27:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesper Dangaard Brouer X-Patchwork-Id: 775744 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3wnkrk4B7Fz9s3s for ; Wed, 14 Jun 2017 21:27:50 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752143AbdFNL1r (ORCPT ); Wed, 14 Jun 2017 07:27:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52454 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751771AbdFNL1p (ORCPT ); Wed, 14 Jun 2017 07:27:45 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3BD3180F97; Wed, 14 Jun 2017 11:27:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3BD3180F97 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=brouer@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3BD3180F97 Received: from firesoul.localdomain (ovpn-200-38.brq.redhat.com [10.40.200.38]) by smtp.corp.redhat.com (Postfix) with ESMTP id 881428ED47; Wed, 14 Jun 2017 11:27:38 +0000 (UTC) Received: from [192.168.42.3] (localhost [IPv6:::1]) by firesoul.localdomain (Postfix) with ESMTP id 31D8F32567C98; Wed, 14 Jun 2017 13:27:37 +0200 (CEST) Subject: [PATCH net] net: don't global ICMP rate limit packets originating from loopback From: Jesper Dangaard Brouer To: netdev@vger.kernel.org Cc: fweimer@redhat.com, hjl.tools@gmail.com, Jesper Dangaard Brouer Date: Wed, 14 Jun 2017 13:27:37 +0200 Message-ID: <149743965710.19877.13901728209731997446.stgit@firesoul> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 14 Jun 2017 11:27:45 +0000 (UTC) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Florian Weimer seems to have a glibc test-case which requires that loopback interfaces does not get ICMP ratelimited. This was broken by commit c0303efeab73 ("net: reduce cycles spend on ICMP replies that gets rate limited"). An ICMP response will usually be routed back-out the same incoming interface. Thus, take advantage of this and skip global ICMP ratelimit when the incoming device is loopback. In the unlikely event that the outgoing it not loopback, due to strange routing policy rules, ICMP rate limiting still works via peer ratelimiting via icmpv4_xrlim_allow(). Thus, we should still comply with RFC1812 (section 4.3.2.8 "Rate Limiting"). This seems to fix the reproducer given by Florian. While still avoiding to perform expensive and unneeded outgoing route lookup for rate limited packets (in the non-loopback case). Fixes: c0303efeab73 ("net: reduce cycles spend on ICMP replies that gets rate limited") Reported-by: Florian Weimer Reported-by: "H.J. Lu" Signed-off-by: Jesper Dangaard Brouer --- net/ipv4/icmp.c | 8 ++++++-- net/ipv6/icmp.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 43318b5f5647..9144fa7df2ad 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -657,8 +657,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) /* Needed by both icmp_global_allow and icmp_xmit_lock */ local_bh_disable(); - /* Check global sysctl_icmp_msgs_per_sec ratelimit */ - if (!icmpv4_global_allow(net, type, code)) + /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless + * incoming dev is loopback. If outgoing dev change to not be + * loopback, then peer ratelimit still work (in icmpv4_xrlim_allow) + */ + if (!(skb_in->dev && (skb_in->dev->flags&IFF_LOOPBACK)) && + !icmpv4_global_allow(net, type, code)) goto out_bh_enable; sk = icmp_xmit_lock(net); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 230b5aac9f03..8d7b113958b1 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -491,7 +491,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, local_bh_disable(); /* Check global sysctl_icmp_msgs_per_sec ratelimit */ - if (!icmpv6_global_allow(type)) + if (!(skb->dev->flags&IFF_LOOPBACK) && !icmpv6_global_allow(type)) goto out_bh_enable; mip6_addr_swap(skb);