[ovs-dev] [PATCH v4 4/4] netdev-linux: Read packet auxdata to obtain vlan_tid

Ben Pfaff blp at nicira.com
Wed Jan 8 01:09:38 UTC 2014


On Tue, Jan 07, 2014 at 02:33:40PM +0900, Simon Horman wrote:
> If VLAN acceleration is used when the kernel receives a packet
> then the outer-most VLAN tag will not be present in the packet
> when it is received by netdev-linux. Rather, it will be present
> in auxdata.
> 
> This patch uses recvmsg() instead of recv() to read auxdata for
> each packet and if the vlan_tid is set then it is added to the packet.
> 
> Adding the vlan_tid makes use of headroom available
> in the buffer parameter of rx_recv.
> 
> Signed-off-by: Simon Horman <horms at verge.net.au>

I'd like to eliminate the dependency on the kernel headers used for
the build, by folding this in.  What do you think?

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 444369e..4d0544e 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -107,6 +107,33 @@ COVERAGE_DEFINE(netdev_set_ethtool);
 #define TC_RTAB_SIZE 1024
 #endif
 
+/* Linux 2.6.21 introduced struct tpacket_auxdata.
+ * Linux 2.6.27 added the tp_vlan_tci member.
+ * Linux 3.0 defined TP_STATUS_VLAN_VALID.
+ * Linux 3.13 repurposed a padding member for tp_vlan_tpid and defined
+ * TP_STATUS_VLAN_TPID_VALID.
+ *
+ * With all this churn it's easiest to unconditionally define a replacement
+ * structure that has everything we want.
+ */
+#ifndef TP_STATUS_VLAN_VALID
+#define TP_STATUS_VLAN_VALID            (1 << 4)
+#endif
+#ifndef TP_STATUS_VLAN_TPID_VALID
+#define TP_STATUS_VLAN_TPID_VALID       (1 << 6)
+#endif
+#undef tpacket_auxdata
+#define tpacket_auxdata rpl_tpacket_auxdata
+struct tpacket_auxdata {
+    uint32_t tp_status;
+    uint32_t tp_len;
+    uint32_t tp_snaplen;
+    uint16_t tp_mac;
+    uint16_t tp_net;
+    uint16_t tp_vlan_tci;
+    uint16_t tp_vlan_tpid;
+};
+
 enum {
     VALID_IFINDEX           = 1 << 0,
     VALID_ETHERADDR         = 1 << 1,
@@ -855,7 +882,6 @@ netdev_linux_rx_dealloc(struct netdev_rx *rx_)
     free(rx);
 }
 
-#ifdef TP_STATUS_VLAN_TPID_VALID
 static ovs_be16
 auxdata_to_vlan_tpid(const struct tpacket_auxdata *aux)
 {
@@ -865,30 +891,12 @@ auxdata_to_vlan_tpid(const struct tpacket_auxdata *aux)
         return htons(ETH_TYPE_VLAN);
     }
 }
-#else
-static ovs_be16
-auxdata_to_vlan_tpid(const struct tpacket_auxdata *aux OVS_UNUSED)
-{
-    return htons(ETH_TYPE_VLAN);
-}
-#endif
 
-/* TP_STATUS_VLAN_VALID was added to v3.0 of the linux kernel
- * to allow VLAN 0 to be accessed via auxdata. Use it if it
- * is available */
-#ifdef TP_STATUS_VLAN_VALID
 static bool
 auxdata_has_vlan_tci(const struct tpacket_auxdata *aux)
 {
-    return aux->tp_vlan_tci || (aux->tp_status & TP_STATUS_VLAN_VALID);
+    return aux->tp_vlan_tci || aux->tp_status & TP_STATUS_VLAN_VALID;
 }
-#else
-static bool
-auxdata_has_vlan_tci(const struct tpacket_auxdata *aux)
-{
-    return aux->tp_vlan_tci;
-}
-#endif
 
 static int
 netdev_linux_rx_recv_sock(int fd, struct ofpbuf *buffer)



More information about the dev mailing list