From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.9 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD174C43381 for ; Wed, 20 Feb 2019 23:35:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9A91F2146E for ; Wed, 20 Feb 2019 23:35:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GBvnvcOS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727069AbfBTXfZ (ORCPT ); Wed, 20 Feb 2019 18:35:25 -0500 Received: from mail-pg1-f195.google.com ([209.85.215.195]:40022 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727042AbfBTXfY (ORCPT ); Wed, 20 Feb 2019 18:35:24 -0500 Received: by mail-pg1-f195.google.com with SMTP id u9so9192928pgo.7 for ; Wed, 20 Feb 2019 15:35:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1lk+/jEtHMVVPLi1E2KXv4OsoQ4eo20/Y3I9SebTQ2s=; b=GBvnvcOSVdUsQNY2md50jPSps7MX1JdIxtSkDr1tLQLH1vL2hBmHlXP9SaJFSdYatb WE94qmy7SGk+xaRai95FMuykyEuBJVdguwZrn4jzYLSLt1ruNyWDuOGnL0vbzTtXAgow BqmLjAISyAF1jLyAvSrqCMvITRRU52J6ieQs7REIEZROjAtxLw2cguTUMNDXa0Ead4Z8 xvNNTtaitraJlFXXyeVxdlTWsZiWQDazJ4HejANlf0QtqnU9AZfB2G1PteqzM6dhJkeo 19aouvi7oDOr65NN+iBC0kpJX+uErRQ+8Vt9szfGpcCT0qEraVhGlzl2MuVZUXe5yvzO Y+PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1lk+/jEtHMVVPLi1E2KXv4OsoQ4eo20/Y3I9SebTQ2s=; b=Ugd/1rOIa7zWc7DnwiraLfbMLXkJivi+vDr+/alOve38LafPYfP3wN9mYv7w3Ycsyr iCD6SIx9m9PQSymmCBOycRRqmawWtDX37MAYV7VWkYyjiillSqCAhsFCWXp7X4bxp9LS ElBpaB7qz0AU1byOTHhaGjOrXvVii+6r3eSUZ0FjJLhRy5LpwynYNlENDU3K7oEcmQQD VEkep831zNHwjumem17U+m/sYJd6TWak0Vr0w2liwdRhnqxXJLbkQneJ32rkRHOoDR5R 89sg7bzmVzY9fVlsr9g1SULu5VLy2pptnt72jMq5jCfbZAHUv1vvx4WxTvstUvozlVdT Y6zw== X-Gm-Message-State: AHQUAubJKxkv8/xiHmHIr8ph9PCerYe5u+OLSUUb1NpgkJFLXOedjGQ8 u4vzCqArzIBPz/bka6/gvMAaaItj X-Google-Smtp-Source: AHgI3IbFbArCAQ04NOYXmAT3oSumC8PWl2zYiTtmSetwLglzJXX5qI5UU34s6Q1lsCd7nwDi2Ut2yw== X-Received: by 2002:a62:7592:: with SMTP id q140mr37545289pfc.164.1550705723000; Wed, 20 Feb 2019 15:35:23 -0800 (PST) Received: from fainelli-desktop.igp.broadcom.net ([192.19.223.250]) by smtp.gmail.com with ESMTPSA id z67sm14716589pfi.152.2019.02.20.15.35.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Feb 2019 15:35:22 -0800 (PST) From: Florian Fainelli To: netdev@vger.kernel.org Cc: Russell King , andrew@lunn.ch, vivien.didelot@gmail.com, davem@davemloft.net, hkallweit1@gmail.com Subject: [PATCH net-next v5 3/3] net: dsa: enable flooding for bridge ports Date: Wed, 20 Feb 2019 15:35:06 -0800 Message-Id: <20190220233506.22210-4-f.fainelli@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190220233506.22210-1-f.fainelli@gmail.com> References: <20190220233506.22210-1-f.fainelli@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Russell King Switches work by learning the MAC address for each attached station by monitoring traffic from each station. When a station sends a packet, the switch records which port the MAC address is connected to. With IPv4 networking, before communication commences with a neighbour, an ARP packet is broadcasted to all stations asking for the MAC address corresponding with the IPv4. The desired station responds with an ARP reply, and the ARP reply causes the switch to learn which port the station is connected to. With IPv6 networking, the situation is rather different. Rather than broadcasting ARP packets, a "neighbour solicitation" is multicasted rather than broadcasted. This multicast needs to reach the intended station in order for the neighbour to be discovered. Once a neighbour has been discovered, and entered into the sending stations neighbour cache, communication can restart at a point later without sending a new neighbour solicitation, even if the entry in the neighbour cache is marked as stale. This can be after the MAC address has expired from the forwarding cache of the DSA switch - when that occurs, there is a long pause in communication. Our DSA implementation for mv88e6xxx switches disables flooding of multicast and unicast frames for bridged ports. As per the above description, this is fine for IPv4 networking, since the broadcasted ARP queries will be sent to and received by all stations on the same network. However, this breaks IPv6 very badly - blocking neighbour solicitations and later causing connections to stall. The defaults that the Linux bridge code expect from bridges are for unknown unicast and unknown multicast frames to be flooded to all ports on the bridge, which is at odds to the defaults adopted by our DSA implementation for mv88e6xxx switches. This commit enables by default flooding of both unknown unicast and unknown multicast frames whenever a port is added to a bridge, and disables the flooding when a port leaves the bridge. This means that mv88e6xxx DSA switches now behave as per the bridge(8) man page, and IPv6 works flawlessly through such a switch. Reviewed-by: Florian Fainelli Reviewed-by: Vivien Didelot Signed-off-by: Russell King --- net/dsa/port.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/dsa/port.c b/net/dsa/port.c index 6df29bddf37e..7bc2a5ad95c6 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -105,16 +105,23 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br) }; int err; - /* Here the port is already bridged. Reflect the current configuration - * so that drivers can program their chips accordingly. + /* Set the flooding mode before joining the port in the switch */ + err = dsa_port_bridge_flags(dp, BR_FLOOD | BR_MCAST_FLOOD, NULL); + if (err) + return err; + + /* Here the interface is already bridged. Reflect the current + * configuration so that drivers can program their chips accordingly. */ dp->bridge_dev = br; err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info); /* The bridging is rolled back on error */ - if (err) + if (err) { + dsa_port_bridge_flags(dp, 0, NULL); dp->bridge_dev = NULL; + } return err; } @@ -137,6 +144,9 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) if (err) pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); + /* Port is leaving the bridge, disable flooding */ + dsa_port_bridge_flags(dp, 0, NULL); + /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, * so allow it to be in BR_STATE_FORWARDING to be kept functional */ -- 2.17.1