summaryrefslogtreecommitdiffstats
path: root/include/linux/if_vlan.h
diff options
context:
space:
mode:
authorToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>2015-03-27 14:31:11 +0900
committerDavid S. Miller <davem@davemloft.net>2015-03-29 13:33:22 -0700
commitf5a7fb88e1f82542ca14ba93a1d4fa35471c60ca (patch)
treee901a68ad66666d1566e9f0de7a358c43d117bec /include/linux/if_vlan.h
parent8d463504c191c2126d097ac94fb258aabe6d3e62 (diff)
downloadlinux-f5a7fb88e1f82542ca14ba93a1d4fa35471c60ca.tar.gz
linux-f5a7fb88e1f82542ca14ba93a1d4fa35471c60ca.tar.bz2
linux-f5a7fb88e1f82542ca14ba93a1d4fa35471c60ca.zip
vlan: Introduce helper functions to check if skb is tagged
Separate the two checks for single vlan and multiple vlans in netif_skb_features(). This allows us to move the check for multiple vlans to another function later. Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/if_vlan.h')
-rw-r--r--include/linux/if_vlan.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index b11b28a30b9e..4265d440ec4d 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -561,4 +561,49 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
skb->protocol = htons(ETH_P_802_2);
}
+/**
+ * skb_vlan_tagged - check if skb is vlan tagged.
+ * @skb: skbuff to query
+ *
+ * Returns true if the skb is tagged, regardless of whether it is hardware
+ * accelerated or not.
+ */
+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)))
+ return false;
+
+ return true;
+}
+
+/**
+ * skb_vlan_tagged_multi - check if skb is vlan tagged with multiple headers.
+ * @skb: skbuff to query
+ *
+ * Returns true if the skb is tagged with multiple vlan headers, regardless
+ * of whether it is hardware accelerated or not.
+ */
+static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
+{
+ __be16 protocol = skb->protocol;
+
+ if (!skb_vlan_tag_present(skb)) {
+ struct vlan_ethhdr *veh;
+
+ if (likely(protocol != htons(ETH_P_8021Q) &&
+ protocol != htons(ETH_P_8021AD)))
+ 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))
+ return false;
+
+ return true;
+}
+
#endif /* !(_LINUX_IF_VLAN_H_) */