Commit 36cbf39b authored by Vladimir Oltean's avatar Vladimir Oltean Committed by Jakub Kicinski
Browse files

net: dsa: hide dp->bridge_dev and dp->bridge_num in the core behind helpers



The location of the bridge device pointer and number is going to change.
It is not going to be kept individually per port, but in a common
structure allocated dynamically and which will have lockdep validation.

Create helpers to access these elements so that we have a migration path
to the new organization.

Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 65144067
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -599,6 +599,27 @@ struct net_device *dsa_port_to_bridge_port(const struct dsa_port *dp)
	return dp->slave;
}

static inline struct net_device *
dsa_port_bridge_dev_get(const struct dsa_port *dp)
{
	return dp->bridge_dev;
}

static inline unsigned int dsa_port_bridge_num_get(struct dsa_port *dp)
{
	return dp->bridge_num;
}

static inline bool dsa_port_bridge_same(const struct dsa_port *a,
					const struct dsa_port *b)
{
	struct net_device *br_a = dsa_port_bridge_dev_get(a);
	struct net_device *br_b = dsa_port_bridge_dev_get(b);

	/* Standalone ports are not in the same bridge with one another */
	return (!br_a || !br_b) ? false : (br_a == br_b);
}

typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
			      bool is_static, void *data);
struct dsa_switch_ops {
+2 −2
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ static inline bool dsa_port_offloads_bridge(struct dsa_port *dp,
	/* DSA ports connected to a bridge, and event was emitted
	 * for the bridge.
	 */
	return dp->bridge_dev == bridge_dev;
	return dsa_port_bridge_dev_get(dp) == bridge_dev;
}

/* Returns true if any port of this tree offloads the given net_device */
@@ -345,7 +345,7 @@ dsa_slave_to_master(const struct net_device *dev)
static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
{
	struct dsa_port *dp = dsa_slave_to_port(skb->dev);
	struct net_device *br = dp->bridge_dev;
	struct net_device *br = dsa_port_bridge_dev_get(dp);
	struct net_device *dev = skb->dev;
	struct net_device *upper_dev;
	u16 vid, pvid, proto;
+18 −17
Original line number Diff line number Diff line
@@ -221,7 +221,7 @@ static int dsa_port_switchdev_sync_attrs(struct dsa_port *dp,
					 struct netlink_ext_ack *extack)
{
	struct net_device *brport_dev = dsa_port_to_bridge_port(dp);
	struct net_device *br = dp->bridge_dev;
	struct net_device *br = dsa_port_bridge_dev_get(dp);
	int err;

	err = dsa_port_inherit_brport_flags(dp, extack);
@@ -372,7 +372,7 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
		goto out_rollback;

	tx_fwd_offload = dsa_port_bridge_tx_fwd_offload(dp, br,
							dp->bridge_num);
							dsa_port_bridge_num_get(dp));

	err = switchdev_bridge_port_offload(brport_dev, dev, dp,
					    &dsa_slave_switchdev_notifier,
@@ -415,13 +415,13 @@ void dsa_port_pre_bridge_leave(struct dsa_port *dp, struct net_device *br)

void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
{
	unsigned int bridge_num = dsa_port_bridge_num_get(dp);
	struct dsa_notifier_bridge_info info = {
		.tree_index = dp->ds->dst->index,
		.sw_index = dp->ds->index,
		.port = dp->index,
		.br = br,
	};
	int bridge_num = dp->bridge_num;
	int err;

	/* Here the port is already unbridged. Reflect the current configuration
@@ -507,12 +507,15 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag,

void dsa_port_pre_lag_leave(struct dsa_port *dp, struct net_device *lag)
{
	if (dp->bridge_dev)
		dsa_port_pre_bridge_leave(dp, dp->bridge_dev);
	struct net_device *br = dsa_port_bridge_dev_get(dp);

	if (br)
		dsa_port_pre_bridge_leave(dp, br);
}

void dsa_port_lag_leave(struct dsa_port *dp, struct net_device *lag)
{
	struct net_device *br = dsa_port_bridge_dev_get(dp);
	struct dsa_notifier_lag_info info = {
		.sw_index = dp->ds->index,
		.port = dp->index,
@@ -526,8 +529,8 @@ void dsa_port_lag_leave(struct dsa_port *dp, struct net_device *lag)
	/* Port might have been part of a LAG that in turn was
	 * attached to a bridge.
	 */
	if (dp->bridge_dev)
		dsa_port_bridge_leave(dp, dp->bridge_dev);
	if (br)
		dsa_port_bridge_leave(dp, br);

	dp->lag_tx_enabled = false;
	dp->lag_dev = NULL;
@@ -556,8 +559,8 @@ static bool dsa_port_can_apply_vlan_filtering(struct dsa_port *dp,
	 * as long as we have 8021q uppers.
	 */
	if (vlan_filtering && dsa_port_is_user(dp)) {
		struct net_device *br = dsa_port_bridge_dev_get(dp);
		struct net_device *upper_dev, *slave = dp->slave;
		struct net_device *br = dp->bridge_dev;
		struct list_head *iter;

		netdev_for_each_upper_dev_rcu(slave, upper_dev, iter) {
@@ -591,17 +594,15 @@ static bool dsa_port_can_apply_vlan_filtering(struct dsa_port *dp,
	 * different setting than what is being requested.
	 */
	dsa_switch_for_each_port(other_dp, ds) {
		struct net_device *other_bridge;
		struct net_device *other_br = dsa_port_bridge_dev_get(other_dp);

		other_bridge = other_dp->bridge_dev;
		if (!other_bridge)
			continue;
		/* If it's the same bridge, it also has same
		 * vlan_filtering setting => no need to check
		 */
		if (other_bridge == dp->bridge_dev)
		if (!other_br || other_br == dsa_port_bridge_dev_get(dp))
			continue;
		if (br_vlan_enabled(other_bridge) != vlan_filtering) {

		if (br_vlan_enabled(other_br) != vlan_filtering) {
			NL_SET_ERR_MSG_MOD(extack,
					   "VLAN filtering is a global setting");
			return false;
@@ -685,13 +686,13 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
 */
bool dsa_port_skip_vlan_configuration(struct dsa_port *dp)
{
	struct net_device *br = dsa_port_bridge_dev_get(dp);
	struct dsa_switch *ds = dp->ds;

	if (!dp->bridge_dev)
	if (!br)
		return false;

	return (!ds->configure_vlan_while_not_filtering &&
		!br_vlan_enabled(dp->bridge_dev));
	return !ds->configure_vlan_while_not_filtering && !br_vlan_enabled(br);
}

int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock)
+7 −6
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ static int dsa_slave_vlan_add(struct net_device *dev,
	/* Deny adding a bridge VLAN when there is already an 802.1Q upper with
	 * the same VID.
	 */
	if (br_vlan_enabled(dp->bridge_dev)) {
	if (br_vlan_enabled(dsa_port_bridge_dev_get(dp))) {
		rcu_read_lock();
		err = dsa_slave_vlan_check_for_8021q_uppers(dev, &vlan);
		rcu_read_unlock();
@@ -1580,7 +1580,7 @@ static void dsa_bridge_mtu_normalization(struct dsa_port *dp)
			if (other_dp->type != DSA_PORT_TYPE_USER)
				continue;

			if (other_dp->bridge_dev != dp->bridge_dev)
			if (!dsa_port_bridge_same(dp, other_dp))
				continue;

			if (!other_dp->ds->mtu_enforcement_ingress)
@@ -2220,7 +2220,7 @@ dsa_prevent_bridging_8021q_upper(struct net_device *dev,
				 struct netdev_notifier_changeupper_info *info)
{
	struct netlink_ext_ack *ext_ack;
	struct net_device *slave;
	struct net_device *slave, *br;
	struct dsa_port *dp;

	ext_ack = netdev_notifier_info_to_extack(&info->info);
@@ -2233,11 +2233,12 @@ dsa_prevent_bridging_8021q_upper(struct net_device *dev,
		return NOTIFY_DONE;

	dp = dsa_slave_to_port(slave);
	if (!dp->bridge_dev)
	br = dsa_port_bridge_dev_get(dp);
	if (!br)
		return NOTIFY_DONE;

	/* Deny enslaving a VLAN device into a VLAN-aware bridge */
	if (br_vlan_enabled(dp->bridge_dev) &&
	if (br_vlan_enabled(br) &&
	    netif_is_bridge_master(info->upper_dev) && info->linking) {
		NL_SET_ERR_MSG_MOD(ext_ack,
				   "Cannot enslave VLAN device into VLAN aware bridge");
@@ -2252,7 +2253,7 @@ dsa_slave_check_8021q_upper(struct net_device *dev,
			    struct netdev_notifier_changeupper_info *info)
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct net_device *br = dp->bridge_dev;
	struct net_device *br = dsa_port_bridge_dev_get(dp);
	struct bridge_vlan_info br_info;
	struct netlink_ext_ack *extack;
	int err = NOTIFY_DONE;
+2 −4
Original line number Diff line number Diff line
@@ -151,11 +151,9 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
	 */
	if (change_vlan_filtering && ds->vlan_filtering_is_global) {
		dsa_switch_for_each_port(dp, ds) {
			struct net_device *bridge_dev;
			struct net_device *br = dsa_port_bridge_dev_get(dp);

			bridge_dev = dp->bridge_dev;

			if (bridge_dev && br_vlan_enabled(bridge_dev)) {
			if (br && br_vlan_enabled(br)) {
				change_vlan_filtering = false;
				break;
			}
Loading