*/
#include "common.h"
+#include <linux/if_vlan.h>
+#include <linux/tcp.h>
#include <xen/balloon.h>
#include <xen/interface/memory.h>
return idx;
}
-#define PKT_PROT_LEN 64
+/*
+ * This is the amount of packet we copy rather than map, so that the
+ * guest can't fiddle with the contents of the headers while we do
+ * packet processing on them (netfilter, routing, etc).
+ */
+#define PKT_PROT_LEN (ETH_HLEN + VLAN_HLEN + \
+ sizeof(struct iphdr) + MAX_IPOPTLEN + \
+ sizeof(struct tcphdr) + 40 /* MAX_TCP_OPTION_SPACE */)
static struct pending_tx_info {
netif_tx_request_t req;
netbk_fill_frags(skb);
+ /*
+ * If the initial fragment was < PKT_PROT_LEN then
+ * pull through some bytes from the other fragments to
+ * increase the linear region to PKT_PROT_LEN bytes.
+ */
+ if (skb_headlen(skb) < PKT_PROT_LEN && skb_is_nonlinear(skb)) {
+ int target = min_t(int, skb->len, PKT_PROT_LEN);
+ __pskb_pull_tail(skb, target - skb_headlen(skb));
+ }
+
skb->dev = netif->dev;
skb->protocol = eth_type_trans(skb, skb->dev);