Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp4835401pxb; Thu, 14 Oct 2021 12:58:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwzYuI5k9pTVrq5uyTnjVmukiED65hGCdETQwOvu7wE/bkKf3n20Oa9bIzFrs7vmU4UOvb8 X-Received: by 2002:a17:90a:d3cb:: with SMTP id d11mr8424786pjw.109.1634241517617; Thu, 14 Oct 2021 12:58:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634241517; cv=none; d=google.com; s=arc-20160816; b=AkUdII8dJFtugQzBZfENHCI5cpsanMgX2Je6R9gBxnxgmHsmgkANL+t7THp2ZZFwWd FNkgYj0z8KacqMVrWrR4Zhfp2RJUmebqw9DUO3Nwimk8sXZqO2KeGGXEDqa40mEH5gdk Yq7io1A1x5Rsnjfqu1ln4S8NdyrsgCoDq1EjY37JnJ+QdoAQbmT044xASnM9TY4uVgvJ jUyWI8iUE3qs4fi7VhGRYsVey2mnUj4rfqnPj7kerduuQ7dFj2uaezbR84MqZK6zH1s3 DxN6q93xiQz3gPYlDcRxQ1wYrPvjVA0tZzVnwlKuZGVr+yBgBmsD9kTR8tJBPyZmvhK/ ORwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=1lO5BBdPCutWHSAHaDZnGkLu0cvGjf0hrCdtL8oZXe0=; b=sNte+NGDNhLz0UBwEIRG4lZeCX6EwtR1Jelp6YNHHQhMyW6rLoDG6Z9UKuYvXupaif Ev0am2ezLMm0ukHzNj4AMo76L8K1WKMqigepxFw76HpiLZ6RPcKhnquuxoNP3JZE9YR3 bTDs9EtKNgrcM+S97lP7LM1nt+Y218DcnTi8sJDIsPtFr3k+cQTcKA12aGCXOm5/CKY6 E9V2KBjOiOYlzJHzWtAIB6emUl7ti80LbFDx6VGPbZnv0L4Y6rVjFC7ylpQY66HJsTh7 EEJE+YYNdTElio3lYC2XwMFyo3rOisDYPByRzju1oQVr+3sM0o+js2hmnOYP9wrtBZKr mKVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=QKTONx50; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d5si5489683plr.252.2021.10.14.12.58.25; Thu, 14 Oct 2021 12:58:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=QKTONx50; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233352AbhJNPGM (ORCPT + 99 others); Thu, 14 Oct 2021 11:06:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:51874 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233348AbhJNPEf (ORCPT ); Thu, 14 Oct 2021 11:04:35 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 73A5461244; Thu, 14 Oct 2021 15:00:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1634223645; bh=D+8LE65aJeazr7MPs5PYlzMbV8Jvff7TNv/Kb2Y+raE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QKTONx50NpAEepD0caQhYbq7OW0b8iUhMZ89StvoLtsWkAd4DXxMrYXIsG8Vij46R yrG1gvp2+/FT9Fxn6+MENsPzXVDZQUaS4XU54K5/Q/NWWI/IKDIYI4XqlS5hich/lb tPi/45AVov1IQb9edn85qByryw1nKFVaEnN9aG1Q= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Florian Westphal , Pablo Neira Ayuso , Sasha Levin , Martin Zaharinov Subject: [PATCH 5.14 13/30] netfilter: nf_nat_masquerade: defer conntrack walk to work queue Date: Thu, 14 Oct 2021 16:54:18 +0200 Message-Id: <20211014145209.966283591@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211014145209.520017940@linuxfoundation.org> References: <20211014145209.520017940@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Florian Westphal [ Upstream commit 7970a19b71044bf4dc2c1becc200275bdf1884d4 ] The ipv4 and device notifiers are called with RTNL mutex held. The table walk can take some time, better not block other RTNL users. 'ip a' has been reported to block for up to 20 seconds when conntrack table has many entries and device down events are frequent (e.g., PPP). Reported-and-tested-by: Martin Zaharinov Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_nat_masquerade.c | 50 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/net/netfilter/nf_nat_masquerade.c b/net/netfilter/nf_nat_masquerade.c index 415919a6ac1a..acd73f717a08 100644 --- a/net/netfilter/nf_nat_masquerade.c +++ b/net/netfilter/nf_nat_masquerade.c @@ -131,13 +131,14 @@ static void nf_nat_masq_schedule(struct net *net, union nf_inet_addr *addr, put_net(net); } -static int device_cmp(struct nf_conn *i, void *ifindex) +static int device_cmp(struct nf_conn *i, void *arg) { const struct nf_conn_nat *nat = nfct_nat(i); + const struct masq_dev_work *w = arg; if (!nat) return 0; - return nat->masq_index == (int)(long)ifindex; + return nat->masq_index == w->ifindex; } static int masq_device_event(struct notifier_block *this, @@ -153,8 +154,8 @@ static int masq_device_event(struct notifier_block *this, * and forget them. */ - nf_ct_iterate_cleanup_net(net, device_cmp, - (void *)(long)dev->ifindex, 0, 0); + nf_nat_masq_schedule(net, NULL, dev->ifindex, + device_cmp, GFP_KERNEL); } return NOTIFY_DONE; @@ -162,35 +163,45 @@ static int masq_device_event(struct notifier_block *this, static int inet_cmp(struct nf_conn *ct, void *ptr) { - struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; - struct net_device *dev = ifa->ifa_dev->dev; struct nf_conntrack_tuple *tuple; + struct masq_dev_work *w = ptr; - if (!device_cmp(ct, (void *)(long)dev->ifindex)) + if (!device_cmp(ct, ptr)) return 0; tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; - return ifa->ifa_address == tuple->dst.u3.ip; + return nf_inet_addr_cmp(&w->addr, &tuple->dst.u3); } static int masq_inet_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev; - struct net *net = dev_net(idev->dev); + const struct in_ifaddr *ifa = ptr; + const struct in_device *idev; + const struct net_device *dev; + union nf_inet_addr addr; + + if (event != NETDEV_DOWN) + return NOTIFY_DONE; /* The masq_dev_notifier will catch the case of the device going * down. So if the inetdev is dead and being destroyed we have * no work to do. Otherwise this is an individual address removal * and we have to perform the flush. */ + idev = ifa->ifa_dev; if (idev->dead) return NOTIFY_DONE; - if (event == NETDEV_DOWN) - nf_ct_iterate_cleanup_net(net, inet_cmp, ptr, 0, 0); + memset(&addr, 0, sizeof(addr)); + + addr.ip = ifa->ifa_address; + + dev = idev->dev; + nf_nat_masq_schedule(dev_net(idev->dev), &addr, dev->ifindex, + inet_cmp, GFP_KERNEL); return NOTIFY_DONE; } @@ -253,19 +264,6 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, } EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6); -static int inet6_cmp(struct nf_conn *ct, void *work) -{ - struct masq_dev_work *w = (struct masq_dev_work *)work; - struct nf_conntrack_tuple *tuple; - - if (!device_cmp(ct, (void *)(long)w->ifindex)) - return 0; - - tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; - - return nf_inet_addr_cmp(&w->addr, &tuple->dst.u3); -} - /* atomic notifier; can't call nf_ct_iterate_cleanup_net (it can sleep). * * Defer it to the system workqueue. @@ -289,7 +287,7 @@ static int masq_inet6_event(struct notifier_block *this, addr.in6 = ifa->addr; - nf_nat_masq_schedule(dev_net(dev), &addr, dev->ifindex, inet6_cmp, + nf_nat_masq_schedule(dev_net(dev), &addr, dev->ifindex, inet_cmp, GFP_ATOMIC); return NOTIFY_DONE; } -- 2.33.0