Hi Florian, On Tue, 20 Aug 2019 at 06:15, Florian Fainelli <f.faine...@gmail.com> wrote: > > > > On 8/19/2019 5:00 PM, Vladimir Oltean wrote: > > Commit b2f81d304cee ("net: dsa: add CPU and DSA ports as VLAN members") > > programs the VLAN from the bridge into the specified port as well as the > > upstream port, with the same set of flags. > > > > Consider the typical case of installing pvid 1 on user port 1, pvid 2 on > > user port 2, etc. The upstream port would end up having a pvid equal to > > the last user port whose pvid was programmed from the bridge. Less than > > useful. > > > > So just don't change the pvid of the upstream port and let it be > > whatever the driver set it internally to be. > > This patch should allow removing the !dsa_is_cpu_port() checks from > b53_common.c:b53_vlan_add, about time :) > > It seems to me that the fundamental issue here is that because we do not > have a user visible network device that 1:1 maps with the CPU (or DSA) > ports for that matter (and for valid reasons, they would represent two > ends of the same pipe), we do not have a good way to control the CPU > port VLAN attributes. > > There was a prior attempt at allowing using the bridge master device to > program the CPU port's VLAN attributes, see [1], but I did not follow up > with that until [2] and then life caught me. If you can/want, that would > be great (not asking for TPS reports). > > [1]: > https://lists.linuxfoundation.org/pipermail/bridge/2016-November/010112.html > [2]: > https://lore.kernel.org/lkml/20180624153339.13572-1-f.faine...@gmail.com/T/ >
So what was the conclusion of that discussion? Should you or should you not add the check for vlan->flags & BRIDGE_VLAN_INFO_BRENTRY? I don't exactly handle the meaning of 'master' and 'self' options from a user perspective. Right now (no patches applied) I get the following behavior in DSA (swp2 is already member of br0): $ echo 1 | sudo tee /sys/class/net/br0/bridge/vlan_filtering $ sudo bridge vlan add vid 100 dev swp2 $ sudo bridge vlan add vid 101 dev swp2 self RTNETLINK answers: Operation not supported $ sudo bridge vlan add vid 102 dev swp2 master $ sudo bridge vlan add vid 103 dev br0 RTNETLINK answers: Operation not supported $ sudo bridge vlan add vid 104 dev br0 self $ sudo bridge vlan add vid 105 dev br0 master RTNETLINK answers: Operation not supported $ bridge vlan port vlan ids eth0 1 PVID Egress Untagged swp5 1 PVID Egress Untagged swp2 1 PVID Egress Untagged 100 102 swp3 1 PVID Egress Untagged swp4 1 PVID Egress Untagged br0 1 PVID Egress Untagged 104 Who returns EOPNOTSUPP for VID 101 and why? Why is VID 102 not installed in br0? This part I don't understand from your patchset. Does it mean that the CPU port (br0) will have to be explicitly configured from now on, even if I run the commands on swp2 with 'master'? > > > > Signed-off-by: Vladimir Oltean <olte...@gmail.com> > > --- > > net/dsa/switch.c | 16 ++++++++++++---- > > 1 file changed, 12 insertions(+), 4 deletions(-) > > > > diff --git a/net/dsa/switch.c b/net/dsa/switch.c > > index 84ab2336131e..02ccc53f1926 100644 > > --- a/net/dsa/switch.c > > +++ b/net/dsa/switch.c > > @@ -239,17 +239,21 @@ dsa_switch_vlan_prepare_bitmap(struct dsa_switch *ds, > > const struct switchdev_obj_port_vlan *vlan, > > const unsigned long *bitmap) > > { > > + struct switchdev_obj_port_vlan v = *vlan; > > int port, err; > > > > if (!ds->ops->port_vlan_prepare || !ds->ops->port_vlan_add) > > return -EOPNOTSUPP; > > > > for_each_set_bit(port, bitmap, ds->num_ports) { > > - err = dsa_port_vlan_check(ds, port, vlan); > > + if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) > > + v.flags &= ~BRIDGE_VLAN_INFO_PVID; > > + > > + err = dsa_port_vlan_check(ds, port, &v); > > if (err) > > return err; > > > > - err = ds->ops->port_vlan_prepare(ds, port, vlan); > > + err = ds->ops->port_vlan_prepare(ds, port, &v); > > if (err) > > return err; > > } > > @@ -262,10 +266,14 @@ dsa_switch_vlan_add_bitmap(struct dsa_switch *ds, > > const struct switchdev_obj_port_vlan *vlan, > > const unsigned long *bitmap) > > { > > + struct switchdev_obj_port_vlan v = *vlan; > > int port; > > > > - for_each_set_bit(port, bitmap, ds->num_ports) > > - ds->ops->port_vlan_add(ds, port, vlan); > > + for_each_set_bit(port, bitmap, ds->num_ports) { > > + if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) > > + v.flags &= ~BRIDGE_VLAN_INFO_PVID; > > + ds->ops->port_vlan_add(ds, port, &v); > > + } > > } > > > > static int dsa_switch_vlan_add(struct dsa_switch *ds, > > > > -- > Florian Regards, -Vladimir