openvswitch_sources = \
actions.c \
+ checksum.c \
datapath.c \
dp_notify.c \
dp_sysfs_dp.c \
openvswitch_headers = \
actions.h \
+ checksum.h \
compat.h \
datapath.h \
dp_sysfs.h \
#include <net/checksum.h>
#include "actions.h"
+#include "checksum.h"
#include "datapath.h"
#include "openvswitch/datapath-protocol.h"
#include "vport.h"
if (vh->h_vlan_proto != htons(ETH_P_8021Q) || skb->len < VLAN_ETH_HLEN)
return skb;
- if (OVS_CB(skb)->ip_summed == OVS_CSUM_COMPLETE)
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_sub(skb->csum, csum_partial(skb->data
+ ETH_HLEN, VLAN_HLEN, 0));
vh->h_vlan_TCI = tci;
- if (OVS_CB(skb)->ip_summed == OVS_CSUM_COMPLETE) {
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) {
__be16 diff[] = { ~old_tci, vh->h_vlan_TCI };
skb->csum = ~csum_partial((char *)diff, sizeof(diff),
/* GSO doesn't fix up the hardware computed checksum so this
* will only be hit in the non-GSO case. */
- if (OVS_CB(skb)->ip_summed == OVS_CSUM_COMPLETE)
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_add(skb->csum, csum_partial(skb->data
+ ETH_HLEN, VLAN_HLEN, 0));
}
{
__be32 diff[] = { ~from, to };
- if (OVS_CB(skb)->ip_summed != OVS_CSUM_PARTIAL) {
+ if (get_ip_summed(skb) != OVS_CSUM_PARTIAL) {
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
~csum_unfold(*sum)));
- if (OVS_CB(skb)->ip_summed == OVS_CSUM_COMPLETE && pseudohdr)
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE && pseudohdr)
skb->csum = ~csum_partial((char *)diff, sizeof(diff),
~skb->csum);
} else if (pseudohdr)
const struct odp_flow_key *key,
const union odp_action *, int n_actions);
-static inline void set_skb_csum_bits(const struct sk_buff *old_skb,
- struct sk_buff *new_skb)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- /* Before 2.6.24 these fields were not copied when
- * doing an skb_copy_expand. */
- new_skb->ip_summed = old_skb->ip_summed;
- new_skb->csum = old_skb->csum;
-#endif
-#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
- /* These fields are copied in skb_clone but not in
- * skb_copy or related functions. We need to manually
- * copy them over here. */
- new_skb->proto_data_valid = old_skb->proto_data_valid;
- new_skb->proto_csum_blank = old_skb->proto_csum_blank;
-#endif
-}
-
#endif /* actions.h */
--- /dev/null
+/*
+ * Copyright (c) 2010 Nicira Networks.
+ * Distributed under the terms of the GNU GPL version 2.
+ *
+ * Significant portions of this file may be copied from parts of the Linux
+ * kernel, by Linus Torvalds and others.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+
+#include "checksum.h"
+#include "datapath.h"
+
+ /* Types of checksums that we can receive (these all refer to L4 checksums):
+ * 1. CHECKSUM_NONE: Device that did not compute checksum, contains full
+ * (though not verified) checksum in packet but not in skb->csum. Packets
+ * from the bridge local port will also have this type.
+ * 2. CHECKSUM_COMPLETE (CHECKSUM_HW): Good device that computes checksums,
+ * also the GRE module. This is the same as CHECKSUM_NONE, except it has
+ * a valid skb->csum. Importantly, both contain a full checksum (not
+ * verified) in the packet itself. The only difference is that if the
+ * packet gets to L4 processing on this machine (not in DomU) we won't
+ * have to recompute the checksum to verify. Most hardware devices do not
+ * produce packets with this type, even if they support receive checksum
+ * offloading (they produce type #5).
+ * 3. CHECKSUM_PARTIAL (CHECKSUM_HW): Packet without full checksum and needs to
+ * be computed if it is sent off box. Unfortunately on earlier kernels,
+ * this case is impossible to distinguish from #2, despite having opposite
+ * meanings. Xen adds an extra field on earlier kernels (see #4) in order
+ * to distinguish the different states.
+ * 4. CHECKSUM_UNNECESSARY (with proto_csum_blank true): This packet was
+ * generated locally by a Xen DomU and has a partial checksum. If it is
+ * handled on this machine (Dom0 or DomU), then the checksum will not be
+ * computed. If it goes off box, the checksum in the packet needs to be
+ * completed. Calling skb_checksum_setup converts this to CHECKSUM_HW
+ * (CHECKSUM_PARTIAL) so that the checksum can be completed. In later
+ * kernels, this combination is replaced with CHECKSUM_PARTIAL.
+ * 5. CHECKSUM_UNNECESSARY (with proto_csum_blank false): Packet with a correct
+ * full checksum or using a protocol without a checksum. skb->csum is
+ * undefined. This is common from devices with receive checksum
+ * offloading. This is somewhat similar to CHECKSUM_NONE, except that
+ * nobody will try to verify the checksum with CHECKSUM_UNNECESSARY.
+ *
+ * Note that on earlier kernels, CHECKSUM_COMPLETE and CHECKSUM_PARTIAL are
+ * both defined as CHECKSUM_HW. Normally the meaning of CHECKSUM_HW is clear
+ * based on whether it is on the transmit or receive path. After the datapath
+ * it will be intepreted as CHECKSUM_PARTIAL. If the packet already has a
+ * checksum, we will panic. Since we can receive packets with checksums, we
+ * assume that all CHECKSUM_HW packets have checksums and map them to
+ * CHECKSUM_NONE, which has a similar meaning (the it is only different if the
+ * packet is processed by the local IP stack, in which case it will need to
+ * be reverified). If we receive a packet with CHECKSUM_HW that really means
+ * CHECKSUM_PARTIAL, it will be sent with the wrong checksum. However, there
+ * shouldn't be any devices that do this with bridging.
+ */
+#ifdef NEED_CSUM_NORMALIZE
+void compute_ip_summed(struct sk_buff *skb, bool xmit)
+{
+ /* For our convenience these defines change repeatedly between kernel
+ * versions, so we can't just copy them over...
+ */
+ switch (skb->ip_summed) {
+ case CHECKSUM_NONE:
+ OVS_CB(skb)->ip_summed = OVS_CSUM_NONE;
+ break;
+ case CHECKSUM_UNNECESSARY:
+ OVS_CB(skb)->ip_summed = OVS_CSUM_UNNECESSARY;
+ break;
+#ifdef CHECKSUM_HW
+ /* In theory this could be either CHECKSUM_PARTIAL or CHECKSUM_COMPLETE.
+ * However, on the receive side we should only get CHECKSUM_PARTIAL
+ * packets from Xen, which uses some special fields to represent this
+ * (see below). Since we can only make one type work, pick the one
+ * that actually happens in practice.
+ *
+ * On the transmit side (basically after skb_checksum_setup()
+ * has been run or on internal dev transmit), packets with
+ * CHECKSUM_COMPLETE aren't generated, so assume CHECKSUM_PARTIAL.
+ */
+ case CHECKSUM_HW:
+ if (!xmit)
+ OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE;
+ else
+ OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
+
+ break;
+#else
+ case CHECKSUM_COMPLETE:
+ OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE;
+ break;
+ case CHECKSUM_PARTIAL:
+ OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
+ break;
+#endif
+ }
+
+#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
+ /* Xen has a special way of representing CHECKSUM_PARTIAL on older
+ * kernels. It should not be set on the transmit path though.
+ */
+ if (skb->proto_csum_blank)
+ OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
+
+ WARN_ON_ONCE(skb->proto_csum_blank && xmit);
+#endif
+}
+
+u8 get_ip_summed(struct sk_buff *skb)
+{
+ return OVS_CB(skb)->ip_summed;
+}
+#endif /* NEED_CSUM_NORMALIZE */
+
+#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
+/* This code is based on skb_checksum_setup() from Xen's net/dev/core.c. We
+ * can't call this function directly because it isn't exported in all
+ * versions. */
+int vswitch_skb_checksum_setup(struct sk_buff *skb)
+{
+ struct iphdr *iph;
+ unsigned char *th;
+ int err = -EPROTO;
+ __u16 csum_start, csum_offset;
+
+ if (!skb->proto_csum_blank)
+ return 0;
+
+ if (skb->protocol != htons(ETH_P_IP))
+ goto out;
+
+ if (!pskb_may_pull(skb, skb_network_header(skb) + sizeof(struct iphdr) - skb->data))
+ goto out;
+
+ iph = ip_hdr(skb);
+ th = skb_network_header(skb) + 4 * iph->ihl;
+
+ csum_start = th - skb->head;
+ switch (iph->protocol) {
+ case IPPROTO_TCP:
+ csum_offset = offsetof(struct tcphdr, check);
+ break;
+ case IPPROTO_UDP:
+ csum_offset = offsetof(struct udphdr, check);
+ break;
+ default:
+ if (net_ratelimit())
+ pr_err("Attempting to checksum a non-TCP/UDP packet, "
+ "dropping a protocol %d packet",
+ iph->protocol);
+ goto out;
+ }
+
+ if (!pskb_may_pull(skb, th + csum_offset + 2 - skb->data))
+ goto out;
+
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->proto_csum_blank = 0;
+ set_skb_csum_pointers(skb, csum_start, csum_offset);
+
+ err = 0;
+
+out:
+ return err;
+}
+#endif /* CONFIG_XEN && HAVE_PROTO_DATA_VALID */
--- /dev/null
+/*
+ * Copyright (c) 2010 Nicira Networks.
+ * Distributed under the terms of the GNU GPL version 2.
+ *
+ * Significant portions of this file may be copied from parts of the Linux
+ * kernel, by Linus Torvalds and others.
+ */
+
+#ifndef CHECKSUM_H
+#define CHECKSUM_H 1
+
+#include <linux/skbuff.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) || \
+ (defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID))
+#define NEED_CSUM_NORMALIZE
+#endif
+
+/* These are the same values as the checksum constants in 2.6.22+. */
+enum csum_type {
+ OVS_CSUM_NONE = 0,
+ OVS_CSUM_UNNECESSARY = 1,
+ OVS_CSUM_COMPLETE = 2,
+ OVS_CSUM_PARTIAL = 3,
+};
+
+#ifdef NEED_CSUM_NORMALIZE
+void compute_ip_summed(struct sk_buff *skb, bool xmit);
+u8 get_ip_summed(struct sk_buff *skb);
+#else
+static inline void compute_ip_summed(struct sk_buff *skb, bool xmit) { }
+static inline u8 get_ip_summed(struct sk_buff *skb)
+{
+ return skb->ip_summed;
+}
+#endif
+
+/* This function closely resembles skb_forward_csum() used by the bridge. It
+ * is slightly different because we are only concerned with bridging and not
+ * other types of forwarding and can get away with slightly more optimal
+ * behavior.
+ */
+static inline void forward_ip_summed(struct sk_buff *skb)
+{
+#ifdef CHECKSUM_HW
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+ skb->ip_summed = CHECKSUM_NONE;
+#endif
+}
+
+#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
+int vswitch_skb_checksum_setup(struct sk_buff *skb);
+#else
+static inline int vswitch_skb_checksum_setup(struct sk_buff *skb)
+{
+ return 0;
+}
+#endif
+
+static inline void set_skb_csum_bits(const struct sk_buff *old_skb,
+ struct sk_buff *new_skb)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ /* Before 2.6.24 these fields were not copied when
+ * doing an skb_copy_expand. */
+ new_skb->ip_summed = old_skb->ip_summed;
+ new_skb->csum = old_skb->csum;
+#endif
+#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
+ /* These fields are copied in skb_clone but not in
+ * skb_copy or related functions. We need to manually
+ * copy them over here. */
+ new_skb->proto_data_valid = old_skb->proto_data_valid;
+ new_skb->proto_csum_blank = old_skb->proto_csum_blank;
+#endif
+}
+
+static inline void get_skb_csum_pointers(const struct sk_buff *skb,
+ u16 *csum_start, u16 *csum_offset)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+ *csum_start = skb->csum_start - skb_headroom(skb);
+ *csum_offset = skb->csum_offset;
+#else
+ *csum_start = skb_transport_header(skb) - skb->data;
+ *csum_offset = skb->csum;
+#endif
+}
+
+static inline void set_skb_csum_pointers(struct sk_buff *skb, u16 csum_start,
+ u16 csum_offset)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+ skb->csum_start = csum_start;
+ skb->csum_offset = csum_offset;
+#else
+ skb_set_transport_header(skb, csum_start - skb_headroom(skb));
+ skb->csum = csum_offset;
+#endif
+}
+
+#endif /* checksum.h */
#include <linux/compat.h>
#include "openvswitch/datapath-protocol.h"
+#include "checksum.h"
#include "datapath.h"
#include "actions.h"
#include "flow.h"
local_bh_enable();
}
-#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
-/* This code is based on skb_checksum_setup() from Xen's net/dev/core.c. We
- * can't call this function directly because it isn't exported in all
- * versions. */
-int vswitch_skb_checksum_setup(struct sk_buff *skb)
-{
- struct iphdr *iph;
- unsigned char *th;
- int err = -EPROTO;
- __u16 csum_start, csum_offset;
-
- if (!skb->proto_csum_blank)
- return 0;
-
- if (skb->protocol != htons(ETH_P_IP))
- goto out;
-
- if (!pskb_may_pull(skb, skb_network_header(skb) + sizeof(struct iphdr) - skb->data))
- goto out;
-
- iph = ip_hdr(skb);
- th = skb_network_header(skb) + 4 * iph->ihl;
-
- csum_start = th - skb->head;
- switch (iph->protocol) {
- case IPPROTO_TCP:
- csum_offset = offsetof(struct tcphdr, check);
- break;
- case IPPROTO_UDP:
- csum_offset = offsetof(struct udphdr, check);
- break;
- default:
- if (net_ratelimit())
- pr_err("Attempting to checksum a non-TCP/UDP packet, "
- "dropping a protocol %d packet",
- iph->protocol);
- goto out;
- }
-
- if (!pskb_may_pull(skb, th + csum_offset + 2 - skb->data))
- goto out;
-
- skb->ip_summed = CHECKSUM_PARTIAL;
- skb->proto_csum_blank = 0;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
- skb->csum_start = csum_start;
- skb->csum_offset = csum_offset;
-#else
- skb_set_transport_header(skb, csum_start - skb_headroom(skb));
- skb->csum = csum_offset;
-#endif
-
- err = 0;
-
-out:
- return err;
-}
-#endif /* CONFIG_XEN && HAVE_PROTO_DATA_VALID */
-
- /* Types of checksums that we can receive (these all refer to L4 checksums):
- * 1. CHECKSUM_NONE: Device that did not compute checksum, contains full
- * (though not verified) checksum in packet but not in skb->csum. Packets
- * from the bridge local port will also have this type.
- * 2. CHECKSUM_COMPLETE (CHECKSUM_HW): Good device that computes checksums,
- * also the GRE module. This is the same as CHECKSUM_NONE, except it has
- * a valid skb->csum. Importantly, both contain a full checksum (not
- * verified) in the packet itself. The only difference is that if the
- * packet gets to L4 processing on this machine (not in DomU) we won't
- * have to recompute the checksum to verify. Most hardware devices do not
- * produce packets with this type, even if they support receive checksum
- * offloading (they produce type #5).
- * 3. CHECKSUM_PARTIAL (CHECKSUM_HW): Packet without full checksum and needs to
- * be computed if it is sent off box. Unfortunately on earlier kernels,
- * this case is impossible to distinguish from #2, despite having opposite
- * meanings. Xen adds an extra field on earlier kernels (see #4) in order
- * to distinguish the different states.
- * 4. CHECKSUM_UNNECESSARY (with proto_csum_blank true): This packet was
- * generated locally by a Xen DomU and has a partial checksum. If it is
- * handled on this machine (Dom0 or DomU), then the checksum will not be
- * computed. If it goes off box, the checksum in the packet needs to be
- * completed. Calling skb_checksum_setup converts this to CHECKSUM_HW
- * (CHECKSUM_PARTIAL) so that the checksum can be completed. In later
- * kernels, this combination is replaced with CHECKSUM_PARTIAL.
- * 5. CHECKSUM_UNNECESSARY (with proto_csum_blank false): Packet with a correct
- * full checksum or using a protocol without a checksum. skb->csum is
- * undefined. This is common from devices with receive checksum
- * offloading. This is somewhat similar to CHECKSUM_NONE, except that
- * nobody will try to verify the checksum with CHECKSUM_UNNECESSARY.
- *
- * Note that on earlier kernels, CHECKSUM_COMPLETE and CHECKSUM_PARTIAL are
- * both defined as CHECKSUM_HW. Normally the meaning of CHECKSUM_HW is clear
- * based on whether it is on the transmit or receive path. After the datapath
- * it will be intepreted as CHECKSUM_PARTIAL. If the packet already has a
- * checksum, we will panic. Since we can receive packets with checksums, we
- * assume that all CHECKSUM_HW packets have checksums and map them to
- * CHECKSUM_NONE, which has a similar meaning (the it is only different if the
- * packet is processed by the local IP stack, in which case it will need to
- * be reverified). If we receive a packet with CHECKSUM_HW that really means
- * CHECKSUM_PARTIAL, it will be sent with the wrong checksum. However, there
- * shouldn't be any devices that do this with bridging. */
-void compute_ip_summed(struct sk_buff *skb, bool xmit)
-{
- /* For our convenience these defines change repeatedly between kernel
- * versions, so we can't just copy them over... */
- switch (skb->ip_summed) {
- case CHECKSUM_NONE:
- OVS_CB(skb)->ip_summed = OVS_CSUM_NONE;
- break;
- case CHECKSUM_UNNECESSARY:
- OVS_CB(skb)->ip_summed = OVS_CSUM_UNNECESSARY;
- break;
-#ifdef CHECKSUM_HW
- /* In theory this could be either CHECKSUM_PARTIAL or CHECKSUM_COMPLETE.
- * However, on the receive side we should only get CHECKSUM_PARTIAL
- * packets from Xen, which uses some special fields to represent this
- * (see below). Since we can only make one type work, pick the one
- * that actually happens in practice.
- *
- * On the transmit side (basically after skb_checksum_setup()
- * has been run or on internal dev transmit), packets with
- * CHECKSUM_COMPLETE aren't generated, so assume CHECKSUM_PARTIAL. */
- case CHECKSUM_HW:
- if (!xmit)
- OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE;
- else
- OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
-
- break;
-#else
- case CHECKSUM_COMPLETE:
- OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE;
- break;
- case CHECKSUM_PARTIAL:
- OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
- break;
-#endif
- default:
- pr_err("unknown checksum type %d\n", skb->ip_summed);
- /* None seems the safest... */
- OVS_CB(skb)->ip_summed = OVS_CSUM_NONE;
- }
-
-#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
- /* Xen has a special way of representing CHECKSUM_PARTIAL on older
- * kernels. It should not be set on the transmit path though. */
- if (skb->proto_csum_blank)
- OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
-
- WARN_ON_ONCE(skb->proto_csum_blank && xmit);
-#endif
-}
-
-/* This function closely resembles skb_forward_csum() used by the bridge. It
- * is slightly different because we are only concerned with bridging and not
- * other types of forwarding and can get away with slightly more optimal
- * behavior.*/
-void forward_ip_summed(struct sk_buff *skb)
-{
-#ifdef CHECKSUM_HW
- if (OVS_CB(skb)->ip_summed == OVS_CSUM_COMPLETE)
- skb->ip_summed = CHECKSUM_NONE;
-#endif
-}
-
/* Append each packet in 'skb' list to 'queue'. There will be only one packet
* unless we broke up a GSO packet. */
static int queue_control_packets(struct sk_buff *skb, struct sk_buff_head *queue,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (copy_bytes == skb->len) {
__wsum csum = 0;
- unsigned int csum_start, csum_offset;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
- csum_start = skb->csum_start - skb_headroom(skb);
- csum_offset = skb->csum_offset;
-#else
- csum_start = skb_transport_header(skb) - skb->data;
- csum_offset = skb->csum;
-#endif
+ u16 csum_start, csum_offset;
+
+ get_skb_csum_pointers(skb, &csum_start, &csum_offset);
BUG_ON(csum_start >= skb_headlen(skb));
retval = skb_copy_and_csum_datagram(skb, csum_start, buf + csum_start,
copy_bytes - csum_start, &csum);
#include <linux/seqlock.h>
#include <linux/skbuff.h>
#include <linux/version.h>
+
+#include "checksum.h"
#include "flow.h"
#include "dp_sysfs.h"
unsigned int sflow_probability;
};
-enum csum_type {
- OVS_CSUM_NONE = 0,
- OVS_CSUM_UNNECESSARY = 1,
- OVS_CSUM_COMPLETE = 2,
- OVS_CSUM_PARTIAL = 3,
-};
-
/**
* struct ovs_skb_cb - OVS data in skb CB
* @vport: The datapath port on which the skb entered the switch.
struct ovs_skb_cb {
struct vport *vport;
struct sw_flow *flow;
+#ifdef NEED_CSUM_NORMALIZE
enum csum_type ip_summed;
+#endif
__be32 tun_id;
};
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
struct datapath *get_dp(int dp_idx);
const char *dp_name(const struct datapath *dp);
-#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
-int vswitch_skb_checksum_setup(struct sk_buff *skb);
-#else
-static inline int vswitch_skb_checksum_setup(struct sk_buff *skb)
-{
- return 0;
-}
-#endif
-
-void compute_ip_summed(struct sk_buff *skb, bool xmit);
-void forward_ip_summed(struct sk_buff *skb);
-
#endif /* datapath.h */
#include <net/xfrm.h>
#include "actions.h"
+#include "checksum.h"
#include "datapath.h"
#include "table.h"
#include "tunnel.h"
#include <linux/skbuff.h>
#include <linux/version.h>
+#include "checksum.h"
#include "datapath.h"
#include "vport-generic.h"
#include "vport-internal_dev.h"
#include <net/llc.h>
+#include "checksum.h"
#include "datapath.h"
#include "vport-internal_dev.h"
#include "vport-netdev.h"