Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8adff41c authored by Toshiaki Makita's avatar Toshiaki Makita Committed by David S. Miller
Browse files

bridge: Don't use VID 0 and 4095 in vlan filtering



IEEE 802.1Q says that:
- VID 0 shall not be configured as a PVID, or configured in any Filtering
Database entry.
- VID 4095 shall not be configured as a PVID, or transmitted in a tag
header. This VID value may be used to indicate a wildcard match for the VID
in management operations or Filtering Database entries.
(See IEEE 802.1Q-2011 6.9.1 and Table 9-2)

Don't accept adding these VIDs in the vlan_filtering implementation.

Signed-off-by: default avatarToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Reviewed-by: default avatarVlad Yasevich <vyasevic@redhat.com>
Acked-by: default avatarStephen Hemminger <stephen@networkplumber.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4b6c7879
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -700,7 +700,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],

		vid = nla_get_u16(tb[NDA_VLAN]);

		if (vid >= VLAN_N_VID) {
		if (!vid || vid >= VLAN_VID_MASK) {
			pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n",
				vid);
			return -EINVAL;
@@ -794,7 +794,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],

		vid = nla_get_u16(tb[NDA_VLAN]);

		if (vid >= VLAN_N_VID) {
		if (!vid || vid >= VLAN_VID_MASK) {
			pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n",
				vid);
			return -EINVAL;
+1 −1
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ static int br_afspec(struct net_bridge *br,

		vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]);

		if (vinfo->vid >= VLAN_N_VID)
		if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
			return -EINVAL;

		switch (cmd) {
+46 −51
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
		return 0;
	}

	if (vid) {
	if (v->port_idx) {
		p = v->parent.port;
		br = p->br;
@@ -76,8 +75,6 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
		goto out_filt;
	}

	}

	set_bit(vid, v->vlan_bitmap);
	v->num_vlans++;
	__vlan_add_flags(v, vid, flags);
@@ -98,7 +95,7 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid)
	__vlan_delete_pvid(v, vid);
	clear_bit(vid, v->untagged_bitmap);

	if (v->port_idx && vid) {
	if (v->port_idx) {
		struct net_device *dev = v->parent.port->dev;
		const struct net_device_ops *ops = dev->netdev_ops;

@@ -248,7 +245,9 @@ bool br_allowed_egress(struct net_bridge *br,
	return false;
}

/* Must be protected by RTNL */
/* Must be protected by RTNL.
 * Must be called with vid in range from 1 to 4094 inclusive.
 */
int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags)
{
	struct net_port_vlans *pv = NULL;
@@ -278,7 +277,9 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags)
	return err;
}

/* Must be protected by RTNL */
/* Must be protected by RTNL.
 * Must be called with vid in range from 1 to 4094 inclusive.
 */
int br_vlan_delete(struct net_bridge *br, u16 vid)
{
	struct net_port_vlans *pv;
@@ -289,14 +290,9 @@ int br_vlan_delete(struct net_bridge *br, u16 vid)
	if (!pv)
		return -EINVAL;

	if (vid) {
		/* If the VID !=0 remove fdb for this vid. VID 0 is special
		 * in that it's the default and is always there in the fdb.
		 */
	spin_lock_bh(&br->hash_lock);
	fdb_delete_by_addr(br, br->dev->dev_addr, vid);
	spin_unlock_bh(&br->hash_lock);
	}

	__vlan_del(pv, vid);
	return 0;
@@ -329,7 +325,9 @@ int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
	return 0;
}

/* Must be protected by RTNL */
/* Must be protected by RTNL.
 * Must be called with vid in range from 1 to 4094 inclusive.
 */
int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags)
{
	struct net_port_vlans *pv = NULL;
@@ -363,7 +361,9 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags)
	return err;
}

/* Must be protected by RTNL */
/* Must be protected by RTNL.
 * Must be called with vid in range from 1 to 4094 inclusive.
 */
int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
{
	struct net_port_vlans *pv;
@@ -374,14 +374,9 @@ int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
	if (!pv)
		return -EINVAL;

	if (vid) {
		/* If the VID !=0 remove fdb for this vid. VID 0 is special
		 * in that it's the default and is always there in the fdb.
		 */
	spin_lock_bh(&port->br->hash_lock);
	fdb_delete_by_addr(port->br, port->dev->dev_addr, vid);
	spin_unlock_bh(&port->br->hash_lock);
	}

	return __vlan_del(pv, vid);
}