} else {
/* Add vlan header */
- /* xxx The vlan_put_tag function, doesn't seem to work
- * xxx reliably when it attempts to use the hardware-accelerated
- * xxx version. We'll directly use the software version
- * xxx until the problem can be diagnosed.
+ /* Set up checksumming pointers for checksum-deferred packets
+ * on Xen. Otherwise, dev_queue_xmit() will try to do this
+ * when we send the packet out on the wire, and it will fail at
+ * that point because skb_checksum_setup() will not look inside
+ * an 802.1Q header. */
+ skb_checksum_setup(skb);
+
+ /* The hardware-accelerated version of vlan_put_tag() works
+ * only for a device that has a VLAN group configured (with
+ * e.g. vconfig(8)), so call the software-only version
+ * __vlan_put_tag() directly instead.
*/
skb = __vlan_put_tag(skb, tci & mask);
if (!skb)
}
}
-inline int skb_checksum_setup(struct sk_buff *skb)
+int skb_checksum_setup(struct sk_buff *skb)
{
if (skb->proto_csum_blank) {
if (skb->protocol != htons(ETH_P_IP))
/* Should hold at least RCU read lock when calling */
struct datapath *get_dp(int dp_idx);
+#ifdef CONFIG_XEN
+int skb_checksum_setup(struct sk_buff *skb);
+#else
+static inline int skb_checksum_setup(struct sk_buff *skb)
+{
+ return 0;
+}
+#endif
+
#endif /* datapath.h */