Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752335AbdFOURR (ORCPT ); Thu, 15 Jun 2017 16:17:17 -0400 Received: from mail.savoirfairelinux.com ([208.88.110.44]:37594 "EHLO mail.savoirfairelinux.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750801AbdFOURP (ORCPT ); Thu, 15 Jun 2017 16:17:15 -0400 From: Vivien Didelot To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel@savoirfairelinux.com, "David S. Miller" , Florian Fainelli , Andrew Lunn , Jason Cobham , Vivien Didelot Subject: [PATCH net-next] net: dsa: add cross-chip multicast support Date: Thu, 15 Jun 2017 16:14:48 -0400 Message-Id: <20170615201448.22424-1-vivien.didelot@savoirfairelinux.com> X-Mailer: git-send-email 2.13.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2486 Lines: 77 Similarly to how cross-chip VLAN works, define a bitmap of multicast group members for a switch, now including its DSA ports, so that multicast traffic can be sent to all switches of the fabric. A switch may drop the frames if no user port is a member. This brings support for multicast in a multi-chip environment. As of now, all switches of the fabric must support the multicast operations in order to program a single fabric port. Reported-by: Jason Cobham Signed-off-by: Vivien Didelot --- net/dsa/switch.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/net/dsa/switch.c b/net/dsa/switch.c index f1029a8d0e20..97e2e9c8cf3f 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -122,19 +122,30 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds, { const struct switchdev_obj_port_mdb *mdb = info->mdb; struct switchdev_trans *trans = info->trans; + DECLARE_BITMAP(group, ds->num_ports); + int port, err; - /* Do not care yet about other switch chips of the fabric */ - if (ds->index != info->sw_index) - return 0; + /* Build a mask of Multicast group members */ + bitmap_zero(group, ds->num_ports); + if (ds->index == info->sw_index) + set_bit(info->port, group); + for (port = 0; port < ds->num_ports; port++) + if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) + set_bit(port, group); if (switchdev_trans_ph_prepare(trans)) { if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add) return -EOPNOTSUPP; - return ds->ops->port_mdb_prepare(ds, info->port, mdb, trans); + for_each_set_bit(port, group, ds->num_ports) { + err = ds->ops->port_mdb_prepare(ds, port, mdb, trans); + if (err) + return err; + } } - ds->ops->port_mdb_add(ds, info->port, mdb, trans); + for_each_set_bit(port, group, ds->num_ports) + ds->ops->port_mdb_add(ds, port, mdb, trans); return 0; } @@ -144,14 +155,13 @@ static int dsa_switch_mdb_del(struct dsa_switch *ds, { const struct switchdev_obj_port_mdb *mdb = info->mdb; - /* Do not care yet about other switch chips of the fabric */ - if (ds->index != info->sw_index) - return 0; - if (!ds->ops->port_mdb_del) return -EOPNOTSUPP; - return ds->ops->port_mdb_del(ds, info->port, mdb); + if (ds->index == info->sw_index) + return ds->ops->port_mdb_del(ds, info->port, mdb); + + return 0; } static int dsa_switch_vlan_add(struct dsa_switch *ds, -- 2.13.1