Commit d0186842 authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller

net: vlan: Avoid using BUG() in vlan_proto_idx()

While we should always make sure that we specify a valid VLAN protocol
to vlan_proto_idx(), killing the machine when an invalid value is
specified is too harsh and not helpful for debugging. All callers are
capable of dealing with an error returned by vlan_proto_idx() so check
the index value and propagate it accordingly.
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7806f656
...@@ -57,6 +57,9 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, ...@@ -57,6 +57,9 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg,
ASSERT_RTNL(); ASSERT_RTNL();
pidx = vlan_proto_idx(vlan_proto); pidx = vlan_proto_idx(vlan_proto);
if (pidx < 0)
return -EINVAL;
vidx = vlan_id / VLAN_GROUP_ARRAY_PART_LEN; vidx = vlan_id / VLAN_GROUP_ARRAY_PART_LEN;
array = vg->vlan_devices_arrays[pidx][vidx]; array = vg->vlan_devices_arrays[pidx][vidx];
if (array != NULL) if (array != NULL)
......
...@@ -36,7 +36,7 @@ struct vlan_info { ...@@ -36,7 +36,7 @@ struct vlan_info {
struct rcu_head rcu; struct rcu_head rcu;
}; };
static inline unsigned int vlan_proto_idx(__be16 proto) static inline int vlan_proto_idx(__be16 proto)
{ {
switch (proto) { switch (proto) {
case htons(ETH_P_8021Q): case htons(ETH_P_8021Q):
...@@ -44,8 +44,8 @@ static inline unsigned int vlan_proto_idx(__be16 proto) ...@@ -44,8 +44,8 @@ static inline unsigned int vlan_proto_idx(__be16 proto)
case htons(ETH_P_8021AD): case htons(ETH_P_8021AD):
return VLAN_PROTO_8021AD; return VLAN_PROTO_8021AD;
default: default:
BUG(); WARN(1, "invalid VLAN protocol: 0x%04x\n", ntohs(proto));
return 0; return -EINVAL;
} }
} }
...@@ -64,17 +64,24 @@ static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, ...@@ -64,17 +64,24 @@ static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
__be16 vlan_proto, __be16 vlan_proto,
u16 vlan_id) u16 vlan_id)
{ {
return __vlan_group_get_device(vg, vlan_proto_idx(vlan_proto), vlan_id); int pidx = vlan_proto_idx(vlan_proto);
if (pidx < 0)
return NULL;
return __vlan_group_get_device(vg, pidx, vlan_id);
} }
static inline void vlan_group_set_device(struct vlan_group *vg, static inline void vlan_group_set_device(struct vlan_group *vg,
__be16 vlan_proto, u16 vlan_id, __be16 vlan_proto, u16 vlan_id,
struct net_device *dev) struct net_device *dev)
{ {
int pidx = vlan_proto_idx(vlan_proto);
struct net_device **array; struct net_device **array;
if (!vg)
if (!vg || pidx < 0)
return; return;
array = vg->vlan_devices_arrays[vlan_proto_idx(vlan_proto)] array = vg->vlan_devices_arrays[pidx]
[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; [vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment