Hi Russell, On Tue, 19 Feb 2019 17:14:14 +0000, Russell King - ARM Linux admin <li...@armlinux.org.uk> wrote: > > > > > +static unsigned long mv88e6xxx_bridge_flags_support(struct > > > > > dsa_switch *ds) > > > > > +{ > > > > > + struct mv88e6xxx_chip *chip = ds->priv; > > > > > + unsigned long support = 0; > > > > > + > > > > > + if (chip->info->ops->port_set_egress_floods) > > > > > + support |= BR_FLOOD | BR_MCAST_FLOOD; > > > > > + > > > > > + return support; > > > > > +} > > > > > > > > I think that it isn't necessary to propagate the notion of bridge flags > > > > down > > > > to the DSA drivers. It might be just enough to add: > > > > > > > > port_egress_flood(dsa_switch *ds, int port, bool uc, bool mc) > > > > > > > > to dsa_switch_ops and set BR_FLOOD | BR_MCAST_FLOOD from the DSA core, > > > > if the targeted driver has ds->ops->port_set_egress_flood. What do you > > > > think? > > > > > > There are two other flags that I haven't covered which the bridge code > > > expects to be offloaded, and those are the broadcast flood flag and > > > the learning flag. > > > > I see. What does the bridge code do if these flags are set? Does it expect > > the underlying devices to handle ff:ff:ff:ff:ff:ff magically or does it > > program this entry into the bridged ports? > > The bridge code defaults to all four flags set. See new_nbp() in > net/bridge/br_if.c: > > p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; > > bridge(8) doesn't touch BR_BCAST_FLOOD, but it is made available to > userspace via netlink and IFLA_BRPORT_BCAST_FLOOD. Hence, there's > no man page documentation for that flag. > > According to br_flood() in net/bridge/br_forward.c, it controls > whether broadcast frames are flooded to all ports or not. Changing > this flag is merely handled just like the multicast/unicast flooding > flags - a call is made to set the offloaded flags, and if it isn't > returned as being supported, a warning is printed. No attempt is > made to create or change a forwarding entry for the broadcast MAC > address.
OK, thanks for the details. The programming of the broadcast MAC address must be handled in the core then, I will move this from mv88e6xxx up to the DSA layer later, but that's totally orthogonal here. > > bridge(8) does document BR_LEARNING via IFLA_BRPORT_LEARNING: > > learning on or learning off > Controls whether a given port will learn MAC addresses from > received traffic or not. If learning if off, the bridge will end > up flooding any traffic for which it has no FDB entry. By > default this flag is on. > > > In the latter case we have almost nothing to do. In the former case, we can > > make the core call dsa_port_mdb_add on setup and when a VLAN is added. > > > > mv88e6xxx tries to be smart and is already doing that and I'm really not a > > fan. > > > > If tomorrow there's a switch capable of simply toggling a bit to do that, > > we can add a new ops and skip the port_mdb_add call in the core. > > > > > I know that the Marvell switches don't have a bit to control the > > > broadcast flooding, that appears to be controlled via a static entry > > > in the ATU which would have to be modified as the broadcast flood flag > > > is manipulated. I don't know how that is handled in other bridges. > > > > > > Do we want to include the broadcast flood in the above prototype? > > > If we go for this, how do we detect which options a switch supports? > > > > If the necessary dsa_switch_ops routine is correctly prototyped, having it > > implemented by a driver or not should be enough to inform the core that the > > related feature(s) is/are supported by the switch. > > > > I'll try to give a bit more context on why I'd prefer this approach, hoping > > it makes sense: a switch driver does not need to understand bridge flags > > per-se, the core should give enough abstraction to this layer (and any other > > net-specifics). The core just needs to know if a driver can program this or > > that. More importantly, it can easily become messy to maintain switch-cases > > of arbitrary flags in all drivers and the core. > > So, should we go the other way and have: > > int (*port_learning)(struct dsa_switch *ds, int port, bool enable); > int (*port_egress_flood_uc)(struct dsa_switch *ds, int port, bool > enable); > int (*port_egress_flood_mc)(struct dsa_switch *ds, int port, bool > enable); > int (*port_egress_flood_bc)(struct dsa_switch *ds, int port, bool > enable); > > rather than trying to combine uc/mc into one? It would mean that we'd > be performing more bus reads/writes, but I guess that doesn't matter > for these configuration parameters. I like this very much. As long as these flags can be programmed in switch devices, these ops totally make sense. Thanks, Vivien