mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
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: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
65144067d3
commit
36cbf39b56
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 @@ err_lag_join:
|
||||
|
||||
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 @@ restore:
|
||||
*/
|
||||
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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ dsa_port_tag_8021q_bridge_match(struct dsa_port *dp,
|
||||
return false;
|
||||
|
||||
if (dsa_port_is_user(dp))
|
||||
return dp->bridge_dev == info->br;
|
||||
return dsa_port_bridge_dev_get(dp) == info->br;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
|
||||
u8 *dsa_header;
|
||||
|
||||
if (skb->offload_fwd_mark) {
|
||||
unsigned int bridge_num = dsa_port_bridge_num_get(dp);
|
||||
struct dsa_switch_tree *dst = dp->ds->dst;
|
||||
|
||||
cmd = DSA_CMD_FORWARD;
|
||||
@ -140,7 +141,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
|
||||
* packets on behalf of a virtual switch device with an index
|
||||
* past the physical switches.
|
||||
*/
|
||||
tag_dev = dst->last_switch + dp->bridge_num;
|
||||
tag_dev = dst->last_switch + bridge_num;
|
||||
tag_port = 0;
|
||||
} else {
|
||||
cmd = DSA_CMD_FROM_CPU;
|
||||
@ -165,7 +166,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
|
||||
dsa_header[2] &= ~0x10;
|
||||
}
|
||||
} else {
|
||||
struct net_device *br = dp->bridge_dev;
|
||||
struct net_device *br = dsa_port_bridge_dev_get(dp);
|
||||
u16 vid;
|
||||
|
||||
vid = br ? MV88E6XXX_VID_BRIDGED : MV88E6XXX_VID_STANDALONE;
|
||||
|
@ -12,7 +12,7 @@
|
||||
static void ocelot_xmit_get_vlan_info(struct sk_buff *skb, struct dsa_port *dp,
|
||||
u64 *vlan_tci, u64 *tag_type)
|
||||
{
|
||||
struct net_device *br = READ_ONCE(dp->bridge_dev);
|
||||
struct net_device *br = dsa_port_bridge_dev_get(dp);
|
||||
struct vlan_ethhdr *hdr;
|
||||
u16 proto, tci;
|
||||
|
||||
|
@ -159,14 +159,16 @@ static u16 sja1105_xmit_tpid(struct dsa_port *dp)
|
||||
* need to find it.
|
||||
*/
|
||||
dsa_switch_for_each_port(other_dp, ds) {
|
||||
if (!other_dp->bridge_dev)
|
||||
struct net_device *br = dsa_port_bridge_dev_get(other_dp);
|
||||
|
||||
if (!br)
|
||||
continue;
|
||||
|
||||
/* Error is returned only if CONFIG_BRIDGE_VLAN_FILTERING,
|
||||
* which seems pointless to handle, as our port cannot become
|
||||
* VLAN-aware in that case.
|
||||
*/
|
||||
br_vlan_get_proto(other_dp->bridge_dev, &proto);
|
||||
br_vlan_get_proto(br, &proto);
|
||||
|
||||
return proto;
|
||||
}
|
||||
@ -180,7 +182,8 @@ static struct sk_buff *sja1105_imprecise_xmit(struct sk_buff *skb,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(netdev);
|
||||
struct net_device *br = dp->bridge_dev;
|
||||
unsigned int bridge_num = dsa_port_bridge_num_get(dp);
|
||||
struct net_device *br = dsa_port_bridge_dev_get(dp);
|
||||
u16 tx_vid;
|
||||
|
||||
/* If the port is under a VLAN-aware bridge, just slide the
|
||||
@ -196,7 +199,7 @@ static struct sk_buff *sja1105_imprecise_xmit(struct sk_buff *skb,
|
||||
* TX VLAN that targets the bridge's entire broadcast domain,
|
||||
* instead of just the specific port.
|
||||
*/
|
||||
tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(dp->bridge_num);
|
||||
tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num);
|
||||
|
||||
return dsa_8021q_xmit(skb, netdev, sja1105_xmit_tpid(dp), tx_vid);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user