Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp3484165pxb; Mon, 4 Apr 2022 18:27:08 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxaksvDlbHKv2SpbQEwJekT/o91tmAVa3dLSEoq8weeEaa6mr53DpjgmWUFiI5MP8nlzQE9 X-Received: by 2002:a63:5d4d:0:b0:398:fd64:3793 with SMTP id o13-20020a635d4d000000b00398fd643793mr781205pgm.597.1649122027830; Mon, 04 Apr 2022 18:27:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649122027; cv=none; d=google.com; s=arc-20160816; b=WXiPgEd7at+e4Mfz1W7nEOkwMB03Q6qRqsipDn8emAe0Yy8Tk9FkvAoUXoDtTJcV02 DfDe1uzHwW7J5w63a5qwkLmQvwjXyn4wOVn7xaN5tqij0/x/yNHj0MUg1kN4rKbMRNbA 0K47mGqiCQbGXcFVfoKLMKk7yPUsIp8bJQpwiclQWk9bOzlpSI5mXPyQ7c1pADCnc0Ga Hq13hFU7yxsx37NNCUY0hFTXz4nz9z9Isb3ybZHe8CZs3GuQS1vAaDM3TRDFuwDTTg7o ytVCeaoNW0a22SyCn1aRNJjSLhwsTN6IQMqcpdrUDbLAkkMt2AvhwvFlZn2QS8Hc0tRe XyTw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=jup1WApPlHvuLwXvT9y+7bBDA2I4e9rIYasWR3MiUe8=; b=fG1aHToOgZL0oiSVI5nhoaYr+josAJLH5XVwNnI2pFMYuagzXz6o6Wz8HPVwKCg90D z3BnsXQbKuh9dNwU1PXKI7aroAZ6V223EH8VOC3ZVat3L3pE2kd9GK7l7pFrgZ+qc25s BxVTjZKf6wk5P+lMWGGhokem5JXn7viNVTC7U0RytSaZQ3gRuf+hbueK+j6yvfR7uz2E Xj1RiDcRJvgycXc6fz7p06RZlM05RS5ZrSV0Ws+EuWMy4z/5mdRzbeg+w9WDF5zeWDhm VHqqmmo4GSG6HQ0BkZ2/yBkL6YcOBFVad6Vw/P8xJMOdD0NckoK3noXaqigMJdn/uAyQ RnwA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=U5FRFZNX; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id f132-20020a636a8a000000b0038211111ec0si11053196pgc.197.2022.04.04.18.27.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Apr 2022 18:27:07 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=U5FRFZNX; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8242019FF7A; Mon, 4 Apr 2022 17:16:42 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348185AbiDAOhq (ORCPT + 99 others); Fri, 1 Apr 2022 10:37:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347642AbiDAOdQ (ORCPT ); Fri, 1 Apr 2022 10:33:16 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E2F3258FE2; Fri, 1 Apr 2022 07:30:23 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CE21C61CDA; Fri, 1 Apr 2022 14:30:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2657C3410F; Fri, 1 Apr 2022 14:30:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1648823422; bh=87Guaka6wTKCQQ2dGz7TejaULZhyCDHBU3/Rw1kEO8E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U5FRFZNXBtxeUm8y+Ay/0lcl9k8JAi7olMhiD189dHPTcHtzG9l+javvUKDip0Lrl 0R2HpBAd7hIxQFW57qdK0r3rCKCBtEpKa1K5W0xbUcXI7nNFZkW2b9SVzPXMKVBKix SqpiLzvsQT68WdjKalZZokk/p9IDADbuPIQCEZetm5TclbNLDOBmJ9juILTwe9TRxp kb2qCfqInDxaMK3P1NW4TGciGKPvOoWScTI23aUY26dK4S1GsMCPY+PH1EViUgyaOG Ax/ZFHqrcO5eYaEF64gudSrjF6akvawHIOJvQ/g+mcTFaxANAbJf9Xfw7/fcF37anc DyL/3VY2aUMHQ== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Ido Schimmel , Wang Hai , "David S . Miller" , Sasha Levin , kuba@kernel.org, pabeni@redhat.com, yoshfuji@linux-ipv6.org, dsahern@kernel.org, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 5.17 087/149] ipv4: Invalidate neighbour for broadcast address upon address addition Date: Fri, 1 Apr 2022 10:24:34 -0400 Message-Id: <20220401142536.1948161-87-sashal@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220401142536.1948161-1-sashal@kernel.org> References: <20220401142536.1948161-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ido Schimmel [ Upstream commit 0c51e12e218f20b7d976158fdc18019627326f7a ] In case user space sends a packet destined to a broadcast address when a matching broadcast route is not configured, the kernel will create a unicast neighbour entry that will never be resolved [1]. When the broadcast route is configured, the unicast neighbour entry will not be invalidated and continue to linger, resulting in packets being dropped. Solve this by invalidating unresolved neighbour entries for broadcast addresses after routes for these addresses are internally configured by the kernel. This allows the kernel to create a broadcast neighbour entry following the next route lookup. Another possible solution that is more generic but also more complex is to have the ARP code register a listener to the FIB notification chain and invalidate matching neighbour entries upon the addition of broadcast routes. It is also possible to wave off the issue as a user space problem, but it seems a bit excessive to expect user space to be that intimately familiar with the inner workings of the FIB/neighbour kernel code. [1] https://lore.kernel.org/netdev/55a04a8f-56f3-f73c-2aea-2195923f09d1@huawei.com/ Reported-by: Wang Hai Signed-off-by: Ido Schimmel Tested-by: Wang Hai Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/arp.h | 1 + net/ipv4/arp.c | 9 +++++++-- net/ipv4/fib_frontend.c | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/net/arp.h b/include/net/arp.h index 031374ac2f22..d7ef4ec71dfe 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -65,6 +65,7 @@ void arp_send(int type, int ptype, __be32 dest_ip, const unsigned char *src_hw, const unsigned char *th); int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir); void arp_ifdown(struct net_device *dev); +int arp_invalidate(struct net_device *dev, __be32 ip, bool force); struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, struct net_device *dev, __be32 src_ip, diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 4db0325f6e1a..dc28f0588e54 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1116,13 +1116,18 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) return err; } -static int arp_invalidate(struct net_device *dev, __be32 ip) +int arp_invalidate(struct net_device *dev, __be32 ip, bool force) { struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev); int err = -ENXIO; struct neigh_table *tbl = &arp_tbl; if (neigh) { + if ((neigh->nud_state & NUD_VALID) && !force) { + neigh_release(neigh); + return 0; + } + if (neigh->nud_state & ~NUD_NOARP) err = neigh_update(neigh, NULL, NUD_FAILED, NEIGH_UPDATE_F_OVERRIDE| @@ -1169,7 +1174,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r, if (!dev) return -EINVAL; } - return arp_invalidate(dev, ip); + return arp_invalidate(dev, ip, true); } /* diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 85117b45216d..89a5a4875595 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1115,9 +1115,11 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) return; /* Add broadcast address, if it is explicitly assigned. */ - if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) + if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) { fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim, 0); + arp_invalidate(dev, ifa->ifa_broadcast, false); + } if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) && (prefix != addr || ifa->ifa_prefixlen < 32)) { @@ -1131,6 +1133,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) if (ifa->ifa_prefixlen < 31) { fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask, 32, prim, 0); + arp_invalidate(dev, prefix | ~mask, false); } } } -- 2.34.1