vlan: Check for vlan ethernet types for 8021.q or 802.1ad
This is to simplify using double tagged vlans. This function allows all valid vlan ethertypes to be checked in a single function call. Also replace some instances that check for both ETH_P_8021Q and ETH_P_8021AD. Patch based on one originally by Thomas F Herbert. Signed-off-by: Thomas F Herbert <thomasfherbert@gmail.com> Signed-off-by: Eric Garver <e@erig.me> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
8c146bb9d5
Коммит
fe19c4f971
|
@ -272,6 +272,23 @@ static inline int vlan_get_encap_level(struct net_device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* eth_type_vlan - check for valid vlan ether type.
|
||||
* @ethertype: ether type to check
|
||||
*
|
||||
* Returns true if the ether type is a vlan ether type.
|
||||
*/
|
||||
static inline bool eth_type_vlan(__be16 ethertype)
|
||||
{
|
||||
switch (ethertype) {
|
||||
case htons(ETH_P_8021Q):
|
||||
case htons(ETH_P_8021AD):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool vlan_hw_offload_capable(netdev_features_t features,
|
||||
__be16 proto)
|
||||
{
|
||||
|
@ -425,8 +442,7 @@ static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
|
|||
{
|
||||
struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
|
||||
|
||||
if (veth->h_vlan_proto != htons(ETH_P_8021Q) &&
|
||||
veth->h_vlan_proto != htons(ETH_P_8021AD))
|
||||
if (!eth_type_vlan(veth->h_vlan_proto))
|
||||
return -EINVAL;
|
||||
|
||||
*vlan_tci = ntohs(veth->h_vlan_TCI);
|
||||
|
@ -488,7 +504,7 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
|
|||
* present at mac_len - VLAN_HLEN (if mac_len > 0), or at
|
||||
* ETH_HLEN otherwise
|
||||
*/
|
||||
if (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) {
|
||||
if (eth_type_vlan(type)) {
|
||||
if (vlan_depth) {
|
||||
if (WARN_ON(vlan_depth < VLAN_HLEN))
|
||||
return 0;
|
||||
|
@ -506,8 +522,7 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
|
|||
vh = (struct vlan_hdr *)(skb->data + vlan_depth);
|
||||
type = vh->h_vlan_encapsulated_proto;
|
||||
vlan_depth += VLAN_HLEN;
|
||||
} while (type == htons(ETH_P_8021Q) ||
|
||||
type == htons(ETH_P_8021AD));
|
||||
} while (eth_type_vlan(type));
|
||||
}
|
||||
|
||||
if (depth)
|
||||
|
@ -572,8 +587,7 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
|
|||
static inline bool skb_vlan_tagged(const struct sk_buff *skb)
|
||||
{
|
||||
if (!skb_vlan_tag_present(skb) &&
|
||||
likely(skb->protocol != htons(ETH_P_8021Q) &&
|
||||
skb->protocol != htons(ETH_P_8021AD)))
|
||||
likely(!eth_type_vlan(skb->protocol)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -593,15 +607,14 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
|
|||
if (!skb_vlan_tag_present(skb)) {
|
||||
struct vlan_ethhdr *veh;
|
||||
|
||||
if (likely(protocol != htons(ETH_P_8021Q) &&
|
||||
protocol != htons(ETH_P_8021AD)))
|
||||
if (likely(!eth_type_vlan(protocol)))
|
||||
return false;
|
||||
|
||||
veh = (struct vlan_ethhdr *)skb->data;
|
||||
protocol = veh->h_vlan_encapsulated_proto;
|
||||
}
|
||||
|
||||
if (protocol != htons(ETH_P_8021Q) && protocol != htons(ETH_P_8021AD))
|
||||
if (!eth_type_vlan(protocol))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче