mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 14:43:16 +00:00
bridge: Add a default_pvid sysfs attribute
This patch allows the user to set and retrieve default_pvid value. A new value can only be stored when vlan filtering is disabled. Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e885439f37
commit
96a20d9d7f
@ -299,6 +299,7 @@ struct net_bridge
|
|||||||
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||||
u8 vlan_enabled;
|
u8 vlan_enabled;
|
||||||
__be16 vlan_proto;
|
__be16 vlan_proto;
|
||||||
|
u16 default_pvid;
|
||||||
struct net_port_vlans __rcu *vlan_info;
|
struct net_port_vlans __rcu *vlan_info;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -605,6 +606,7 @@ void br_recalculate_fwd_mask(struct net_bridge *br);
|
|||||||
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
|
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
|
||||||
int br_vlan_set_proto(struct net_bridge *br, unsigned long val);
|
int br_vlan_set_proto(struct net_bridge *br, unsigned long val);
|
||||||
void br_vlan_init(struct net_bridge *br);
|
void br_vlan_init(struct net_bridge *br);
|
||||||
|
int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val);
|
||||||
int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags);
|
int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags);
|
||||||
int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
|
int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
|
||||||
void nbp_vlan_flush(struct net_bridge_port *port);
|
void nbp_vlan_flush(struct net_bridge_port *port);
|
||||||
|
@ -725,6 +725,22 @@ static ssize_t vlan_protocol_store(struct device *d,
|
|||||||
return store_bridge_parm(d, buf, len, br_vlan_set_proto);
|
return store_bridge_parm(d, buf, len, br_vlan_set_proto);
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RW(vlan_protocol);
|
static DEVICE_ATTR_RW(vlan_protocol);
|
||||||
|
|
||||||
|
static ssize_t default_pvid_show(struct device *d,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct net_bridge *br = to_bridge(d);
|
||||||
|
return sprintf(buf, "%d\n", br->default_pvid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t default_pvid_store(struct device *d,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
return store_bridge_parm(d, buf, len, br_vlan_set_default_pvid);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RW(default_pvid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct attribute *bridge_attrs[] = {
|
static struct attribute *bridge_attrs[] = {
|
||||||
@ -771,6 +787,7 @@ static struct attribute *bridge_attrs[] = {
|
|||||||
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||||
&dev_attr_vlan_filtering.attr,
|
&dev_attr_vlan_filtering.attr,
|
||||||
&dev_attr_vlan_protocol.attr,
|
&dev_attr_vlan_protocol.attr,
|
||||||
|
&dev_attr_default_pvid.attr,
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -499,9 +499,38 @@ err_filt:
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
|
||||||
|
{
|
||||||
|
u16 pvid = val;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!val || val >= VLAN_VID_MASK)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!rtnl_trylock())
|
||||||
|
return restart_syscall();
|
||||||
|
|
||||||
|
if (pvid == br->default_pvid)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
/* Only allow default pvid change when filtering is disabled */
|
||||||
|
if (br->vlan_enabled) {
|
||||||
|
pr_info_once("Please disable vlan filtering to change default_pvid\n");
|
||||||
|
err = -EPERM;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
br->default_pvid = pvid;
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
rtnl_unlock();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void br_vlan_init(struct net_bridge *br)
|
void br_vlan_init(struct net_bridge *br)
|
||||||
{
|
{
|
||||||
br->vlan_proto = htons(ETH_P_8021Q);
|
br->vlan_proto = htons(ETH_P_8021Q);
|
||||||
|
br->default_pvid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be protected by RTNL.
|
/* Must be protected by RTNL.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user