Received: by 2002:a05:6512:3d0e:0:0:0:0 with SMTP id d14csp51038lfv; Tue, 12 Apr 2022 16:54:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxRPnJhC3iVpqbPikjBfICB66JdoUCKlRd784ubGoLlWUTdcF9Fv1HkjZZI8uK6r60VVUwc X-Received: by 2002:a17:90a:6389:b0:1c9:ee11:6c2c with SMTP id f9-20020a17090a638900b001c9ee116c2cmr7753917pjj.107.1649807690567; Tue, 12 Apr 2022 16:54:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649807690; cv=none; d=google.com; s=arc-20160816; b=YQ3jWg0lf8vKAYu+uuABr+XB6iSVFoZPBaQMqfMz2XGfHOJEsCK2TKssEcCBKjrvRs abGgZv9M6uK7GcPO6dfn87Ev+ZjpeHYIctwYYs61O77aarxyF2mnrDv4odmZIvRVPTFW 3EURnDMAub7JyyeoW+TUIfcNK+yJd7/k2URrW6+cPG7gbsAFJYTuZvCBht29ypK9ajx5 OiYwlZ/Q0UYcBY/aKKOqAEGAgXrRsnijtQlmyz+38kJ545iXVa5BBuCFoxyYttW6V+2i s/jZTFzKopAJ10FR9XuRZwECjhoWhDPMIgoH9T7wVn2sTtD8hbUGFxg1Y6z9fGw7pErN 05lw== 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=8XKXKqdbSQqPjgUmU5rFl4FR+Wy5WaJxHxIfMEy5kQA=; b=ysA1tD7fYbDj4iXTdZp+TmweMBMWFR3Ws7U+/ycaL9IjTDpq+iZ4dNmbiZS0iVz1vX h8tMr8JdjFZyrZyq5lyNgvadPLn1Ywnh3aAtNkZrlJL3gwRpQyZl972AfvnaAzF/6htT PCVJLFmPFgXC2AotwwpsiIN9c6KnsYD3HFAUTgPueZTiMYftgd3ZUtao+9MTXMguYmAT PVYs5Zg6yNCLb2+DJyiov+P16b5zH/cSJWjNR7YEyZH6gbS4o2urKJsACA2E3wSr42H5 8fW4Z++J/A+2wSy1tCCkrhjh3QadpuotnI2NuKqwpUlrtTL1bYPLS8V9bwPFZf8iu6Rq l5/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=y9o7zYfO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1: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 lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id i19-20020a170902eb5300b00153b2d16568si12019433pli.368.2022.04.12.16.54.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Apr 2022 16:54:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=y9o7zYfO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1: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: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7C8D113CEE9; Tue, 12 Apr 2022 14:49:41 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352118AbiDLHNb (ORCPT + 99 others); Tue, 12 Apr 2022 03:13:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351728AbiDLGyQ (ORCPT ); Tue, 12 Apr 2022 02:54:16 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10AA8387B6; Mon, 11 Apr 2022 23:43:45 -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 9837860B5E; Tue, 12 Apr 2022 06:43:44 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA4FAC385A6; Tue, 12 Apr 2022 06:43:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1649745824; bh=tgXZ+T0V+L8EBmfKx+TgIYJSgQuX+mpqJd2hK9Yv/4o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=y9o7zYfOgmGkopBTOc8LrmHOcVMQnt37EvuzCUcdvBMXAalxBPbfTcmq7Ghp9dNs9 54451lKXh9oyhomyqEkQiS+X9Zt88It2hTEr5qLREK5kudaXZ+6XufRrn6p03USS5B 1mogH6//6Kk1gAhWMN2kU7qJgLyiTc5Fc+/MQHXY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Wang Hai , Ido Schimmel , "David S. Miller" , Sasha Levin Subject: [PATCH 5.15 062/277] ipv4: Invalidate neighbour for broadcast address upon address addition Date: Tue, 12 Apr 2022 08:27:45 +0200 Message-Id: <20220412062943.843611618@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220412062942.022903016@linuxfoundation.org> References: <20220412062942.022903016@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no 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 4950191f6b2b..4a23a97195f3 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -71,6 +71,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 922dd73e5740..83a47998c4b1 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 4d61ddd8a0ec..1eb7795edb9d 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1112,9 +1112,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)) { @@ -1128,6 +1130,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.35.1