aboutsummaryrefslogtreecommitdiffstats
path: root/tools/vnet
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-06-07 11:06:00 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-06-07 11:06:00 +0100
commit918b0012a90c98b9868d0e17c0b9de887f5a57a1 (patch)
tree1da0112565f2c5ceab6540083db9937123acc5c3 /tools/vnet
parentc3a5cde5165ae7ed0ffeacb5743203a1c0ecf33d (diff)
downloadxen-918b0012a90c98b9868d0e17c0b9de887f5a57a1.tar.gz
xen-918b0012a90c98b9868d0e17c0b9de887f5a57a1.tar.bz2
xen-918b0012a90c98b9868d0e17c0b9de887f5a57a1.zip
Fix the vnet module for Xen 3.1.x.
Signed-off-by: Robert Valentan <R.Valentan@solid-soft.at>
Diffstat (limited to 'tools/vnet')
-rw-r--r--tools/vnet/vnet-module/esp.c10
-rw-r--r--tools/vnet/vnet-module/etherip.c39
-rw-r--r--tools/vnet/vnet-module/skb_util.h15
-rw-r--r--tools/vnet/vnet-module/varp.c6
-rw-r--r--tools/vnet/vnet-module/vnet_forward.c15
5 files changed, 51 insertions, 34 deletions
diff --git a/tools/vnet/vnet-module/esp.c b/tools/vnet/vnet-module/esp.c
index f18d1b1523..4575110921 100644
--- a/tools/vnet/vnet-module/esp.c
+++ b/tools/vnet/vnet-module/esp.c
@@ -341,12 +341,12 @@ static int esp_sa_send(SAState *sa, struct sk_buff *skb, Tunnel *tunnel){
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 @@ static int esp_sa_recv(SAState *sa, struct sk_buff *skb){
// 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 @@ static int esp_protocol_recv(struct sk_buff *skb){
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 @@ static int esp_protocol_recv(struct sk_buff *skb){
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);
diff --git a/tools/vnet/vnet-module/etherip.c b/tools/vnet/vnet-module/etherip.c
index 3e531c7fbe..f97099c3e7 100644
--- a/tools/vnet/vnet-module/etherip.c
+++ b/tools/vnet/vnet-module/etherip.c
@@ -270,6 +270,7 @@ int etherip_protocol_recv(struct sk_buff *skb){
u32 saddr, daddr;
char vnetbuf[VNET_ID_BUF];
struct ethhdr *eth;
+ struct sk_buff *newskb;
dprintf(">\n");
saddr = skb->nh.iph->saddr;
@@ -293,7 +294,7 @@ int etherip_protocol_recv(struct sk_buff *skb){
err = -EINVAL;
goto exit;
}
- skb_pull(skb, pull_n);
+ skb_pull_vn(skb, pull_n);
}
// Assume skb->data points at etherip header.
etheriph = (void*)skb->data;
@@ -318,7 +319,18 @@ int etherip_protocol_recv(struct sk_buff *skb){
goto exit;
}
// Point at the headers in the contained ethernet frame.
- skb->mac.raw = skb_pull(skb, etherip_n);
+ skb->mac.raw = skb_pull_vn(skb, etherip_n);
+
+ newskb = alloc_skb(skb->len, GFP_ATOMIC);
+ if (!newskb) {
+ wprintf("> alloc new sk_buff failed \n");
+ goto exit;
+ }
+ newskb->mac.raw = skb_put(newskb, skb->len);
+ skb_copy_bits(skb, 0, newskb->data, skb->len);
+ kfree_skb(skb);
+ skb = newskb;
+
eth = eth_hdr(skb);
// Simulate the logic from eth_type_trans()
@@ -340,27 +352,12 @@ int etherip_protocol_recv(struct sk_buff *skb){
// Assuming a standard Ethernet frame.
// Should check for protocol? Support ETH_P_8021Q too.
- skb->nh.raw = skb_pull(skb, ETH_HLEN);
-
-#ifdef __KERNEL__
- // Fix IP options, checksum, skb dst, netfilter state.
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- if (skb->ip_summed == CHECKSUM_HW){
- skb->ip_summed = CHECKSUM_NONE;
- }
- dst_release(skb->dst);
- skb->dst = NULL;
- nf_reset(skb);
-#ifdef CONFIG_BRIDGE_NETFILTER
- if(skb->nf_bridge){
- // Stop the eth header being clobbered by nf_bridge_maybe_copy_header().
- _nf_bridge_save_header(skb);
- }
-#endif
-#endif // __KERNEL__
+ skb->nh.raw = skb_pull_vn(skb, ETH_HLEN);
+ skb->h.raw = newskb->nh.raw + sizeof(struct iphdr);
- dprintf("> Unpacked srcaddr=" IPFMT " vnet=%s srcmac=" MACFMT " dstmac=" MACFMT "\n",
+ dprintf("> Unpacked srcaddr=" IPFMT " dstaddr=" IPFMT " vnet=%s srcmac=" MACFMT " dstmac=" MACFMT "\n",
NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr),
VnetId_ntoa(&vnet, vnetbuf),
MAC6TUPLE(eth->h_source),
MAC6TUPLE(eth->h_dest));
diff --git a/tools/vnet/vnet-module/skb_util.h b/tools/vnet/vnet-module/skb_util.h
index d8bd34c3ac..4c71adf8c6 100644
--- a/tools/vnet/vnet-module/skb_util.h
+++ b/tools/vnet/vnet-module/skb_util.h
@@ -67,6 +67,21 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
#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__
diff --git a/tools/vnet/vnet-module/varp.c b/tools/vnet/vnet-module/varp.c
index aefbd43d43..3dad417687 100644
--- a/tools/vnet/vnet-module/varp.c
+++ b/tools/vnet/vnet-module/varp.c
@@ -1365,7 +1365,7 @@ int varp_handle_message(struct sk_buff *skb){
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 @@ int varp_handle_message(struct sk_buff *skb){
}
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:
diff --git a/tools/vnet/vnet-module/vnet_forward.c b/tools/vnet/vnet-module/vnet_forward.c
index 2064d7890d..74a55c4582 100644
--- a/tools/vnet/vnet-module/vnet_forward.c
+++ b/tools/vnet/vnet-module/vnet_forward.c
@@ -186,7 +186,7 @@ static int VnetPeer_forward(VnetPeer *peer, struct sk_buff *fwdskb){
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 @@ int vnet_forward_recv(struct sk_buff *skb){
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 @@ int vnet_forward_recv(struct sk_buff *skb){
// 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);
}