commit fe19c4f971a55cea3be442d8032a5f6021702791
    Author: Eric Garver <e...@erig.me>
    Date:   Wed Sep 7 12:56:58 2016 -0400

    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 <thomasfherb...@gmail.com>
    Signed-off-by: Eric Garver <e...@erig.me>
    Acked-by: Pravin B Shelar <pshe...@ovn.org>
    Signed-off-by: David S. Miller <da...@davemloft.net>

Signed-off-by: Yi Yang <yi.y.y...@intel.com>
---
 acinclude.m4                                  |  1 +
 datapath/linux/compat/include/linux/if_vlan.h | 32 ++++++++++++++++++++-------
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 9166da8..f219bec 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -664,6 +664,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [__vlan_insert_tag])
   OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [vlan_get_protocol])
   OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [skb_vlan_tagged])
+  OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [eth_type_vlan])
 
   OVS_GREP_IFELSE([$KSRC/include/linux/u64_stats_sync.h], 
[u64_stats_fetch_begin_irq])
 
diff --git a/datapath/linux/compat/include/linux/if_vlan.h 
b/datapath/linux/compat/include/linux/if_vlan.h
index c8ddef1..d51e5c9 100644
--- a/datapath/linux/compat/include/linux/if_vlan.h
+++ b/datapath/linux/compat/include/linux/if_vlan.h
@@ -100,6 +100,25 @@ static inline struct sk_buff 
*rpl___vlan_hwaccel_put_tag(struct sk_buff *skb,
 #define __vlan_hwaccel_put_tag rpl___vlan_hwaccel_put_tag
 #endif
 
+#ifndef HAVE_ETH_TYPE_VLAN
+/**
+ * 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;
+       }
+}
+#endif
+
 /* All of these were introduced in a single commit preceding 2.6.33, so
  * presumably all of them or none of them are present. */
 #ifndef VLAN_PRIO_MASK
@@ -188,7 +207,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;
@@ -206,8 +225,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)
@@ -241,8 +259,7 @@ static inline __be16 vlan_get_protocol(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;
@@ -262,15 +279,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;
-- 
2.1.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to