From: Ian Campbell Subject: xen/netback: Always pull through PKT_PROT_LEN bytes into the linear part of an skb Previously PKT_PROT_LEN would only have an effect on the first fragment. Signed-off-by: Ian Campbell From: Steven Smith Subject: xen/netback: try to pull a minimum of 72 bytes into the skb data area ... when receiving a packet into netback. The previous number, 64, tended to place a fragment boundary in the middle of the TCP header options and led to unnecessary fragmentation in Windows <-> Windows networking. From: Paul Durrant Subject: Re-define PKT_PROT_LEN to be bigger. Re-define PKT_PROT_LEN to be big enough to handle maximal IPv4 and TCP options and phrase the definition so that it's reasonably obvious that's what it's for. Signed-off-by: Paul Durrant Signed-off-by: Jan Beulich --- sle10sp4-2010-12-15.orig/drivers/xen/netback/netback.c +++ sle10sp4-2010-12-15/drivers/xen/netback/netback.c @@ -35,6 +35,8 @@ */ #include "common.h" +#include +#include #include #include @@ -105,7 +107,14 @@ static inline int netif_page_index(struc 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; @@ -1458,6 +1467,16 @@ static void net_tx_action(unsigned long 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);