Skip to content

Commit 7e8c185

Browse files
vladimirolteandavem330
authored andcommitted
net: bridge: allow the switchdev replay functions to be called for deletion
When a switchdev port leaves a LAG that is a bridge port, the switchdev objects and port attributes offloaded to that port are not removed: ip link add br0 type bridge ip link add bond0 type bond mode 802.3ad ip link set swp0 master bond0 ip link set bond0 master br0 bridge vlan add dev bond0 vid 100 ip link set swp0 nomaster VLAN 100 will remain installed on swp0 despite it going into standalone mode, because as far as the bridge is concerned, nothing ever happened to its bridge port. Let's extend the bridge vlan, fdb and mdb replay functions to take a 'bool adding' argument, and make DSA and ocelot call the replay functions with 'adding' as false from the switchdev unsync path, for the switch port that leaves the bridge. Note that this patch in itself does not salvage anything, because in the current pull mode of operation, DSA still needs to call the replay helpers with adding=false. This will be done in another patch. Signed-off-by: Vladimir Oltean <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bdf123b commit 7e8c185

File tree

6 files changed

+47
-27
lines changed

6 files changed

+47
-27
lines changed

drivers/net/ethernet/mscc/ocelot_net.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,12 +1175,12 @@ static int ocelot_switchdev_sync(struct ocelot *ocelot, int port,
11751175
ageing_time = br_get_ageing_time(bridge_dev);
11761176
ocelot_port_attr_ageing_set(ocelot, port, ageing_time);
11771177

1178-
err = br_mdb_replay(bridge_dev, brport_dev, priv,
1178+
err = br_mdb_replay(bridge_dev, brport_dev, priv, true,
11791179
&ocelot_switchdev_blocking_nb, extack);
11801180
if (err && err != -EOPNOTSUPP)
11811181
return err;
11821182

1183-
err = br_vlan_replay(bridge_dev, brport_dev, priv,
1183+
err = br_vlan_replay(bridge_dev, brport_dev, priv, true,
11841184
&ocelot_switchdev_blocking_nb, extack);
11851185
if (err && err != -EOPNOTSUPP)
11861186
return err;

include/linux/if_bridge.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ bool br_multicast_has_router_adjacent(struct net_device *dev, int proto);
7171
bool br_multicast_enabled(const struct net_device *dev);
7272
bool br_multicast_router(const struct net_device *dev);
7373
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
74-
const void *ctx, struct notifier_block *nb,
74+
const void *ctx, bool adding, struct notifier_block *nb,
7575
struct netlink_ext_ack *extack);
7676
#else
7777
static inline int br_multicast_list_adjacent(struct net_device *dev,
@@ -106,7 +106,7 @@ static inline bool br_multicast_router(const struct net_device *dev)
106106
}
107107
static inline int br_mdb_replay(const struct net_device *br_dev,
108108
const struct net_device *dev, const void *ctx,
109-
struct notifier_block *nb,
109+
bool adding, struct notifier_block *nb,
110110
struct netlink_ext_ack *extack)
111111
{
112112
return -EOPNOTSUPP;
@@ -121,7 +121,7 @@ int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto);
121121
int br_vlan_get_info(const struct net_device *dev, u16 vid,
122122
struct bridge_vlan_info *p_vinfo);
123123
int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
124-
const void *ctx, struct notifier_block *nb,
124+
const void *ctx, bool adding, struct notifier_block *nb,
125125
struct netlink_ext_ack *extack);
126126
#else
127127
static inline bool br_vlan_enabled(const struct net_device *dev)
@@ -152,7 +152,7 @@ static inline int br_vlan_get_info(const struct net_device *dev, u16 vid,
152152

153153
static inline int br_vlan_replay(struct net_device *br_dev,
154154
struct net_device *dev, const void *ctx,
155-
struct notifier_block *nb,
155+
bool adding, struct notifier_block *nb,
156156
struct netlink_ext_ack *extack)
157157
{
158158
return -EOPNOTSUPP;
@@ -168,7 +168,7 @@ bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag);
168168
u8 br_port_get_stp_state(const struct net_device *dev);
169169
clock_t br_get_ageing_time(const struct net_device *br_dev);
170170
int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
171-
const void *ctx, struct notifier_block *nb);
171+
const void *ctx, bool adding, struct notifier_block *nb);
172172
#else
173173
static inline struct net_device *
174174
br_fdb_find_port(const struct net_device *br_dev,
@@ -200,7 +200,7 @@ static inline clock_t br_get_ageing_time(const struct net_device *br_dev)
200200

201201
static inline int br_fdb_replay(const struct net_device *br_dev,
202202
const struct net_device *dev, const void *ctx,
203-
struct notifier_block *nb)
203+
bool adding, struct notifier_block *nb)
204204
{
205205
return -EOPNOTSUPP;
206206
}

net/bridge/br_fdb.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,8 @@ static inline size_t fdb_nlmsg_size(void)
728728

729729
static int br_fdb_replay_one(struct notifier_block *nb,
730730
const struct net_bridge_fdb_entry *fdb,
731-
struct net_device *dev, const void *ctx)
731+
struct net_device *dev, unsigned long action,
732+
const void *ctx)
732733
{
733734
struct switchdev_notifier_fdb_info item;
734735
int err;
@@ -741,22 +742,28 @@ static int br_fdb_replay_one(struct notifier_block *nb,
741742
item.info.dev = dev;
742743
item.info.ctx = ctx;
743744

744-
err = nb->notifier_call(nb, SWITCHDEV_FDB_ADD_TO_DEVICE, &item);
745+
err = nb->notifier_call(nb, action, &item);
745746
return notifier_to_errno(err);
746747
}
747748

748749
int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
749-
const void *ctx, struct notifier_block *nb)
750+
const void *ctx, bool adding, struct notifier_block *nb)
750751
{
751752
struct net_bridge_fdb_entry *fdb;
752753
struct net_bridge *br;
754+
unsigned long action;
753755
int err = 0;
754756

755757
if (!netif_is_bridge_master(br_dev) || !netif_is_bridge_port(dev))
756758
return -EINVAL;
757759

758760
br = netdev_priv(br_dev);
759761

762+
if (adding)
763+
action = SWITCHDEV_FDB_ADD_TO_DEVICE;
764+
else
765+
action = SWITCHDEV_FDB_DEL_TO_DEVICE;
766+
760767
rcu_read_lock();
761768

762769
hlist_for_each_entry_rcu(fdb, &br->fdb_list, fdb_node) {
@@ -767,7 +774,7 @@ int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
767774
if (dst_dev != br_dev && dst_dev != dev)
768775
continue;
769776

770-
err = br_fdb_replay_one(nb, fdb, dst_dev, ctx);
777+
err = br_fdb_replay_one(nb, fdb, dst_dev, action, ctx);
771778
if (err)
772779
break;
773780
}

net/bridge/br_mdb.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,8 @@ static void br_switchdev_mdb_populate(struct switchdev_obj_port_mdb *mdb,
568568

569569
static int br_mdb_replay_one(struct notifier_block *nb, struct net_device *dev,
570570
const struct switchdev_obj_port_mdb *mdb,
571-
const void *ctx, struct netlink_ext_ack *extack)
571+
unsigned long action, const void *ctx,
572+
struct netlink_ext_ack *extack)
572573
{
573574
struct switchdev_notifier_port_obj_info obj_info = {
574575
.info = {
@@ -580,7 +581,7 @@ static int br_mdb_replay_one(struct notifier_block *nb, struct net_device *dev,
580581
};
581582
int err;
582583

583-
err = nb->notifier_call(nb, SWITCHDEV_PORT_OBJ_ADD, &obj_info);
584+
err = nb->notifier_call(nb, action, &obj_info);
584585
return notifier_to_errno(err);
585586
}
586587

@@ -604,12 +605,13 @@ static int br_mdb_queue_one(struct list_head *mdb_list,
604605
}
605606

606607
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
607-
const void *ctx, struct notifier_block *nb,
608+
const void *ctx, bool adding, struct notifier_block *nb,
608609
struct netlink_ext_ack *extack)
609610
{
610611
const struct net_bridge_mdb_entry *mp;
611612
struct switchdev_obj *obj, *tmp;
612613
struct net_bridge *br;
614+
unsigned long action;
613615
LIST_HEAD(mdb_list);
614616
int err = 0;
615617

@@ -664,9 +666,14 @@ int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
664666

665667
rcu_read_unlock();
666668

669+
if (adding)
670+
action = SWITCHDEV_PORT_OBJ_ADD;
671+
else
672+
action = SWITCHDEV_PORT_OBJ_DEL;
673+
667674
list_for_each_entry(obj, &mdb_list, list) {
668675
err = br_mdb_replay_one(nb, dev, SWITCHDEV_OBJ_PORT_MDB(obj),
669-
ctx, extack);
676+
action, ctx, extack);
670677
if (err)
671678
goto out_free_mdb;
672679
}

net/bridge/br_vlan.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,8 @@ void br_vlan_notify(const struct net_bridge *br,
18071807
static int br_vlan_replay_one(struct notifier_block *nb,
18081808
struct net_device *dev,
18091809
struct switchdev_obj_port_vlan *vlan,
1810-
const void *ctx, struct netlink_ext_ack *extack)
1810+
const void *ctx, unsigned long action,
1811+
struct netlink_ext_ack *extack)
18111812
{
18121813
struct switchdev_notifier_port_obj_info obj_info = {
18131814
.info = {
@@ -1819,18 +1820,19 @@ static int br_vlan_replay_one(struct notifier_block *nb,
18191820
};
18201821
int err;
18211822

1822-
err = nb->notifier_call(nb, SWITCHDEV_PORT_OBJ_ADD, &obj_info);
1823+
err = nb->notifier_call(nb, action, &obj_info);
18231824
return notifier_to_errno(err);
18241825
}
18251826

18261827
int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
1827-
const void *ctx, struct notifier_block *nb,
1828+
const void *ctx, bool adding, struct notifier_block *nb,
18281829
struct netlink_ext_ack *extack)
18291830
{
18301831
struct net_bridge_vlan_group *vg;
18311832
struct net_bridge_vlan *v;
18321833
struct net_bridge_port *p;
18331834
struct net_bridge *br;
1835+
unsigned long action;
18341836
int err = 0;
18351837
u16 pvid;
18361838

@@ -1857,6 +1859,11 @@ int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
18571859
if (!vg)
18581860
return 0;
18591861

1862+
if (adding)
1863+
action = SWITCHDEV_PORT_OBJ_ADD;
1864+
else
1865+
action = SWITCHDEV_PORT_OBJ_DEL;
1866+
18601867
pvid = br_get_pvid(vg);
18611868

18621869
list_for_each_entry(v, &vg->vlan_list, vlist) {
@@ -1870,7 +1877,7 @@ int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
18701877
if (!br_vlan_should_use(v))
18711878
continue;
18721879

1873-
err = br_vlan_replay_one(nb, dev, &vlan, ctx, extack);
1880+
err = br_vlan_replay_one(nb, dev, &vlan, ctx, action, extack);
18741881
if (err)
18751882
return err;
18761883
}

net/dsa/port.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,19 +194,18 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp,
194194
if (err && err != -EOPNOTSUPP)
195195
return err;
196196

197-
err = br_mdb_replay(br, brport_dev, dp,
198-
&dsa_slave_switchdev_blocking_notifier,
199-
extack);
197+
err = br_mdb_replay(br, brport_dev, dp, true,
198+
&dsa_slave_switchdev_blocking_notifier, extack);
200199
if (err && err != -EOPNOTSUPP)
201200
return err;
202201

203-
err = br_fdb_replay(br, brport_dev, dp, &dsa_slave_switchdev_notifier);
202+
err = br_fdb_replay(br, brport_dev, dp, true,
203+
&dsa_slave_switchdev_notifier);
204204
if (err && err != -EOPNOTSUPP)
205205
return err;
206206

207-
err = br_vlan_replay(br, brport_dev, dp,
208-
&dsa_slave_switchdev_blocking_notifier,
209-
extack);
207+
err = br_vlan_replay(br, brport_dev, dp, true,
208+
&dsa_slave_switchdev_blocking_notifier, extack);
210209
if (err && err != -EOPNOTSUPP)
211210
return err;
212211

0 commit comments

Comments
 (0)