vnet-module
PATCH 1/1 vnet-module
Hallo!
The attached patch repair the vnet-module (patch base is xen-3.1.0)
- moves the "skb_pull" function from kernel to skb_util.c because pulling in the data will rise a "BUG_ON" in the kernel.
- the skb_buff is not always possible to modify. (vnet_forward.c and etherip.c) The code now work's.. I think with no or less time-penalty.
Info for kernel-option CONFIG_BRIDGE_NETFILTER :
There is a race-condition in the code (nf_iterate), which will kill the kernel. With hyperthreading and vnet over 2 Server a scp will kill it in less 1 (one) second. Blocking hyperthreading the same will work less then 30 seconds. Dropping the bridge- netfilter code, no error's in 3 hours....
Signature · 2 lines
regards Robert Valentan
tools/vnet/vnet-module/esp.c +5 -5
@@ -341,12 +341,12 @@dprintf ("> ETH header pull...\n" );memmove (skb->data, skb->mac.raw,ETH_HLEN ); skb->mac.raw = skb->data; -__skb_pull (skb,ETH_HLEN ); +skb_pull_vn (skb,ETH_HLEN ); }dprintf ("> IP header pull...\n" );memmove (skb->data, skb->nh.raw, ip_n); skb->nh.raw = skb->data; -__skb_pull (skb, ip_n); +skb_pull_vn (skb, ip_n); esph = (void *)skb->data;// Add spi and sequence number. esph->spi = sa->ident.spi;
@@ -457,7 +457,7 @@// Move skb->data back to ethernet header. // Do in 2 moves to ensure offsets are +ve, // since args to skb_pull/skb_push are unsigned. -__skb_pull (skb, head_n); +skb_pull_vn (skb, head_n);__skb_push (skb, skb->data - skb->mac.raw);// After this esph is invalid. esph =NULL ;
@@ -763,7 +763,7 @@dprintf (">\n" );#ifdef DEBUG dprintf ("> recv skb=\n" ); -skb_print_bits (skb,0 , skb->len); +skb_print_bits ("" , skb,0 , skb->len);#endif ip_n = (skb->nh.iph->ihl <<2 );if (skb->data == skb->mac.raw){
@@ -773,7 +773,7 @@ err = -EINVAL ; goto exit; } -skb_pull (skb, eth_n + ip_n); +skb_pull_vn (skb, eth_n + ip_n); } addr = skb->nh.iph->daddr; err =esp_skb_header (skb, &esph);
tools/vnet/vnet-module/etherip.c +19 -22
66 lines not on this page · raw message
tools/vnet/vnet-module/skb_util.h +15 -0
@@ -66,6 +66,21 @@ }#endif + +/* +* It's a copy from {kernel}/include/linux/skbuff.h func '__skb_pull' and 'skb_pull' +* to aviodthe BUG_ON when pulling into the data (getting forwarded ip-frames) +*/ +static inline unsigned char *__skb_pull_vn (struct sk_buff *skb,unsigned int len) +{ + skb->len -= len; +//BUG_ON(skb->len < skb->data_len); +return skb->data += len; +} +static inline unsigned char *skb_pull_vn (struct sk_buff *skb,unsigned int len) +{ +return unlikely (len > skb->len) ?NULL :__skb_pull_vn (skb, len); +}#ifdef __KERNEL__
tools/vnet/vnet-module/varp.c +3 -3
@@ -1365,7 +1365,7 @@ goto exit; } } - varph = (void *)skb_pull (skb,sizeof (struct udphdr )); + varph = (void *)skb_pull_vn (skb,sizeof (struct udphdr ));if (skb->len <sizeof (struct VnetMsgHdr )){wprintf ("> Varp msg too short: %d < %d\n" , skb->len,sizeof (struct VnetMsgHdr )); goto exit;
@@ -1378,11 +1378,11 @@ }break ;case VUDP_ID :// Etherip-in-udp packet. -skb_pull (skb,sizeof (struct VnetMsgHdr )); +skb_pull_vn (skb,sizeof (struct VnetMsgHdr )); err =etherip_protocol_recv (skb); goto exit;case VFWD_ID :// Forwarded. -skb_pull (skb,sizeof (struct VnetMsgHdr )); +skb_pull_vn (skb,sizeof (struct VnetMsgHdr )); err =vnet_forward_recv (skb); goto exit;default :
tools/vnet/vnet-module/vnet_forward.c +10 -5
@@ -186,7 +186,7 @@printk ("\nWrapped packet:\n" );print_iphdr (__FUNCTION__, skb);print_udphdr (__FUNCTION__, skb); -skb_print_bits (__FUNCTION__, skb,0 ,0 * skb->len); +skb_print_bits (__FUNCTION__, skb,0 , skb->len);#endif err =_skb_xmit (skb, saddr);
@@ -304,7 +304,7 @@ peer->rx_packets++; skb->mac.raw =NULL ; skb->nh.raw = skb->data; - skb->h.raw = (void *)(skb->nh.iph +1 ); + skb->h.raw = skb->data +sizeof (struct iphdr );if (!skb->nh.iph->saddr){ skb->nh.iph->saddr = addr.u.ip4.s_addr; }
@@ -328,12 +328,17 @@// Handle (a copy of) it ourselves, because // if it is looped-back by xmit it will be ignored. -//recvskb = skb_clone(skb, GFP_ATOMIC); - recvskb =pskb_copy (skb,GFP_ATOMIC ); + recvskb =alloc_skb (skb->len,GFP_ATOMIC );if (recvskb){ + recvskb->protocol =htons (ETH_P_IP ); + + recvskb->nh.raw =skb_put (recvskb, skb->len); + recvskb->h.raw = recvskb->data +sizeof (struct iphdr ); +skb_copy_bits (skb,0 , recvskb->data, skb->len); +// Data points at the unwrapped iphdr, but varp_handle_message() // expects it to point at the udphdr, so pull. -skb_pull (recvskb,sizeof (struct iphdr )); +skb_pull_vn (recvskb,sizeof (struct iphdr ));if (varp_handle_message (recvskb) <=0 ){kfree_skb (recvskb); }
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel