From patchwork Wed Jan 30 00:55:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Fainelli X-Patchwork-Id: 1033098 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qZo+4Opb"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43q4jR1LPjz9s9h for ; Wed, 30 Jan 2019 11:58:03 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728541AbfA3A6B (ORCPT ); Tue, 29 Jan 2019 19:58:01 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:35905 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728176AbfA3A57 (ORCPT ); Tue, 29 Jan 2019 19:57:59 -0500 Received: by mail-pf1-f195.google.com with SMTP id b85so10564529pfc.3 for ; Tue, 29 Jan 2019 16:57:58 -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=JImFDnBsP6enld2qA1tUibEu/Ic5jrKcfz2zWMVyGZ0=; b=qZo+4Opbw9aagxSbpdizVXC96jITB9xAtR43of6n56NX/a/wwyjNMAr166cUWNnNPA 9ejZIy7r7zgbXpaQcC72Y/2vAewHnv42G1EmiND1PJNACPfoCn6sALUmT1tsDl8khgyK L4R9jFndI/f+vHGO4CcfBcIowFb8ITELTcSLYVEQPksIrC4fsWv4oAHn2UxqmvYD3fv8 yG7WBvlP90ATNvBh3NZ7qgb7Ndv9DfoqFVrR4GV/5vouFxuXIg1mtV7y19Kixcc2psoL vBnc4tsbxdnVwcBN7xNcE4sTGUFSwQkQi8NhwuVYUuUZwNvOyK/1LGIfvNxIsdXWb/Cu IJ3w== 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=JImFDnBsP6enld2qA1tUibEu/Ic5jrKcfz2zWMVyGZ0=; b=gx6hkYKSqDJ35La0iaTBimAYuKvmqOhf/CvRLbIfzx3VenHfH6Xg/4du1VnVN+b8qp mTFP3S9sQ55fOpCLffehVCxy4ew4n9SenxXIvWD6f1qYsW2LuvaOJg81As3etIIwDpG2 6b4ZrYHuqXG4xT0/gEnwNFpZ7ugs5LJ+DPKr9OVDXGvQU5z6UT8NcATlOzCAn+TW1nLx GN7mrkUnBhXgMLnB3J1NIoDXIdLW1fdKOJez14557UtaXVJdVxLa2ucgNggecJSDAqVj i0vOkTL57QLdmlMXdRJnWCZg5KnCJG5VGAGZlIdsZqe16dP099R1wNT0jLcLzu3uCtqD kF9g== X-Gm-Message-State: AJcUukc5Y+Qr+1qaD1/Iwc2wSGC4pJg9kojLCSuD2tGkkWm1VA39dgF9 zxlugEEVoK0QoOrE43uthSpax5Jd X-Google-Smtp-Source: ALg8bN4jBFUdLjfMtySrEUIX4dx1CIR+vsbc4QcxO04PEIiL5tU5BXy/JmTBgy1etpieP1erpg07rA== X-Received: by 2002:aa7:8802:: with SMTP id c2mr28247520pfo.20.1548809877725; Tue, 29 Jan 2019 16:57:57 -0800 (PST) Received: from fainelli-desktop.igp.broadcom.net ([192.19.223.250]) by smtp.gmail.com with ESMTPSA id v191sm67837137pgb.77.2019.01.29.16.57.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 16:57:56 -0800 (PST) From: Florian Fainelli To: netdev@vger.kernel.org Cc: Florian Fainelli , andrew@lunn.ch, vivien.didelot@gmail.com, davem@davemloft.net, idosch@mellanox.com, jiri@mellanox.com, ilias.apalodimas@linaro.org, ivan.khoronzhuk@linaro.org, roopa@cumulusnetworks.com, nikolay@cumulusnetworks.com Subject: [PATCH net-next v2 07/12] net: dsa: Add ability to program multicast filter for CPU port Date: Tue, 29 Jan 2019 16:55:43 -0800 Message-Id: <20190130005548.2212-8-f.fainelli@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190130005548.2212-1-f.fainelli@gmail.com> References: <20190130005548.2212-1-f.fainelli@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When the switch ports operate as individual network devices, the switch driver might have configured the switch to flood multicast all the way to the CPU port. This is really undesireable as it can lead to receiving a lot of unwanted traffic that the network stack needs to filter in software. For each valid multicast address, program it into the switch's MDB only when the host is interested in receiving such traffic, e.g: running an multicast application. Signed-off-by: Florian Fainelli --- net/dsa/slave.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 91de3a663226..a6a803262929 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -68,6 +68,39 @@ static int dsa_slave_get_iflink(const struct net_device *dev) return dsa_slave_to_master(dev)->ifindex; } +static int dsa_slave_sync_unsync_mdb_addr(struct net_device *dev, + const unsigned char *addr, bool add) +{ + struct switchdev_obj_port_mdb mdb = { + .obj = { + .id = SWITCHDEV_OBJ_ID_HOST_MDB, + .flags = SWITCHDEV_F_DEFER, + }, + .vid = 0, + }; + int ret = -EOPNOTSUPP; + + ether_addr_copy(mdb.addr, addr); + if (add) + ret = switchdev_port_obj_add(dev, &mdb.obj, NULL); + else + ret = switchdev_port_obj_del(dev, &mdb.obj); + + return ret; +} + +static int dsa_slave_sync_mdb_addr(struct net_device *dev, + const unsigned char *addr) +{ + return dsa_slave_sync_unsync_mdb_addr(dev, addr, true); +} + +static int dsa_slave_unsync_mdb_addr(struct net_device *dev, + const unsigned char *addr) +{ + return dsa_slave_sync_unsync_mdb_addr(dev, addr, false); +} + static int dsa_slave_open(struct net_device *dev) { struct net_device *master = dsa_slave_to_master(dev); @@ -126,6 +159,8 @@ static int dsa_slave_close(struct net_device *dev) dev_mc_unsync(master, dev); dev_uc_unsync(master, dev); + __hw_addr_unsync_dev(&dev->mc, dev, dsa_slave_unsync_mdb_addr); + if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(master, -1); if (dev->flags & IFF_PROMISC) @@ -150,7 +185,17 @@ static void dsa_slave_change_rx_flags(struct net_device *dev, int change) static void dsa_slave_set_rx_mode(struct net_device *dev) { struct net_device *master = dsa_slave_to_master(dev); + struct dsa_port *dp = dsa_slave_to_port(dev); + /* If the port is bridged, the bridge takes care of sending + * SWITCHDEV_OBJ_ID_HOST_MDB to program the host's MC filter + */ + if (netdev_mc_empty(dev) || dp->bridge_dev) + goto out; + + __hw_addr_sync_dev(&dev->mc, dev, dsa_slave_sync_mdb_addr, + dsa_slave_unsync_mdb_addr); +out: dev_mc_sync(master, dev); dev_uc_sync(master, dev); } @@ -1396,6 +1441,11 @@ static int dsa_slave_changeupper(struct net_device *dev, if (netif_is_bridge_master(info->upper_dev)) { if (info->linking) { + /* Remove existing MC addresses that might have been + * programmed + */ + __hw_addr_unsync_dev(&dev->mc, dev, + dsa_slave_unsync_mdb_addr); err = dsa_port_bridge_join(dp, info->upper_dev); err = notifier_from_errno(err); } else {