Thread (15 messages) 15 messages, 3 authors, 2022-08-19
STALE1403d

[RFC PATCH net-next 04/10] net: dsa: introduce and use robust form of dsa_port_notify()

From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: 2022-08-18 15:50:51
Subsystem: networking [dsa], networking [general], the rest · Maintainers: Andrew Lunn, Vladimir Oltean, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Introduce dsa_port_notify_robust(), which uses dsa_tree_notify_robust(),
and convert as many call paths to use it. Some notable exceptions are
DSA_NOTIFIER_LAG_CHANGE, for which it isn't clear how to restore the
state (or why this is allowed to return an error for that matter), and
DSA_NOTIFIER_MTU (which we'll convert separately to the robust form).

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/port.c | 51 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 11 deletions(-)
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 6aa6402d3ed9..2fec3df65643 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -30,6 +30,24 @@ static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v)
 	return dsa_tree_notify(dp->ds->dst, e, v);
 }
 
+/**
+ * dsa_port_notify_robust - Notify fabric of changes to port, with rollback
+ * @dp: port on which change occurred
+ * @e: event, must be of type DSA_NOTIFIER_*
+ * @v: event-specific value.
+ * @e_rollback: event, must be of type DSA_NOTIFIER_*
+ * @v_rollback: event-specific value.
+ *
+ * Like dsa_port_notify(), except makes sure that switches are restored to the
+ * previous state in case the notifier call chain fails mid way.
+ */
+static int dsa_port_notify_robust(const struct dsa_port *dp, unsigned long e,
+				  void *v, unsigned long e_rollback,
+				  void *v_rollback)
+{
+	return dsa_tree_notify_robust(dp->ds->dst, e, v, e_rollback, v_rollback);
+}
+
 static void dsa_port_notify_bridge_fdb_flush(const struct dsa_port *dp, u16 vid)
 {
 	struct net_device *brport_dev = dsa_port_to_bridge_port(dp);
@@ -641,7 +659,8 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag_dev,
 		goto err_lag_create;
 
 	info.lag = *dp->lag;
-	err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_JOIN, &info);
+	err = dsa_port_notify_robust(dp, DSA_NOTIFIER_LAG_JOIN, &info,
+				     DSA_NOTIFIER_LAG_LEAVE, &info);
 	if (err)
 		goto err_lag_join;
 
@@ -854,12 +873,14 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock)
 {
 	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock);
 	unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
-	struct dsa_notifier_ageing_time_info info;
+	struct dsa_notifier_ageing_time_info info, old_info;
 	int err;
 
 	info.ageing_time = ageing_time;
+	old_info.ageing_time = dp->ageing_time;
 
-	err = dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
+	err = dsa_port_notify_robust(dp, DSA_NOTIFIER_AGEING_TIME, &info,
+				     DSA_NOTIFIER_AGEING_TIME, &old_info);
 	if (err)
 		return err;
 
@@ -971,7 +992,8 @@ int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
 	if (!dp->ds->fdb_isolation)
 		info.db.bridge.num = 0;
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_FDB_ADD, &info,
+				      DSA_NOTIFIER_FDB_DEL, &info);
 }
 
 int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
@@ -1007,7 +1029,8 @@ static int dsa_port_host_fdb_add(struct dsa_port *dp,
 	if (!dp->ds->fdb_isolation)
 		info.db.bridge.num = 0;
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info,
+				      DSA_NOTIFIER_HOST_FDB_DEL, &info);
 }
 
 int dsa_port_standalone_host_fdb_add(struct dsa_port *dp,
@@ -1107,7 +1130,8 @@ int dsa_port_lag_fdb_add(struct dsa_port *dp, const unsigned char *addr,
 	if (!dp->ds->fdb_isolation)
 		info.db.bridge.num = 0;
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_LAG_FDB_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_LAG_FDB_ADD, &info,
+				      DSA_NOTIFIER_LAG_FDB_DEL, &info);
 }
 
 int dsa_port_lag_fdb_del(struct dsa_port *dp, const unsigned char *addr,
@@ -1155,7 +1179,8 @@ int dsa_port_mdb_add(const struct dsa_port *dp,
 	if (!dp->ds->fdb_isolation)
 		info.db.bridge.num = 0;
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_MDB_ADD, &info,
+				      DSA_NOTIFIER_MDB_DEL, &info);
 }
 
 int dsa_port_mdb_del(const struct dsa_port *dp,
@@ -1189,7 +1214,8 @@ static int dsa_port_host_mdb_add(const struct dsa_port *dp,
 	if (!dp->ds->fdb_isolation)
 		info.db.bridge.num = 0;
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_HOST_MDB_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_HOST_MDB_ADD, &info,
+				      DSA_NOTIFIER_HOST_MDB_DEL, &info);
 }
 
 int dsa_port_standalone_host_mdb_add(const struct dsa_port *dp,
@@ -1274,7 +1300,8 @@ int dsa_port_vlan_add(struct dsa_port *dp,
 		.extack = extack,
 	};
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_VLAN_ADD, &info,
+				      DSA_NOTIFIER_VLAN_DEL, &info);
 }
 
 int dsa_port_vlan_del(struct dsa_port *dp,
@@ -1300,7 +1327,8 @@ int dsa_port_host_vlan_add(struct dsa_port *dp,
 	struct dsa_port *cpu_dp = dp->cpu_dp;
 	int err;
 
-	err = dsa_port_notify(dp, DSA_NOTIFIER_HOST_VLAN_ADD, &info);
+	err = dsa_port_notify_robust(dp, DSA_NOTIFIER_HOST_VLAN_ADD, &info,
+				     DSA_NOTIFIER_HOST_VLAN_DEL, &info);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
@@ -1742,7 +1770,8 @@ int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast)
 		return dsa_broadcast_robust(DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info,
 					    DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info);
 
-	return dsa_port_notify(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info);
+	return dsa_port_notify_robust(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info,
+				      DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info);
 }
 
 void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast)
-- 
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help