diff -upN reference/net/ipv4/esp4.c current/net/ipv4/esp4.c --- reference/net/ipv4/esp4.c 2004-03-11 14:35:45.000000000 -0800 +++ current/net/ipv4/esp4.c 2004-04-09 11:53:04.000000000 -0700 @@ -10,6 +10,7 @@ #include #include #include +#include #define MAX_SG_ONSTACK 4 @@ -325,7 +326,15 @@ int esp_input(struct xfrm_state *x, stru skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; memcpy(skb->nh.raw, workbuf, iph->ihl*4); - skb->nh.iph->tot_len = htons(skb->len); + iph = skb->nh.iph; + iph->tot_len = htons(skb->len + (skb->data - skb->nh.raw)); + iph->check = 0; + iph->check = ip_fast_csum(skb->nh.raw, iph->ihl); + { + unsigned char *oldmac = skb->mac.raw; + skb->mac.raw += encap_len + sizeof(struct ip_esp_hdr) + esp -> conf.ivlen; + memmove(skb->mac.raw, oldmac, skb->nh.raw - skb->mac.raw); + } } return 0; diff -upN reference/net/ipv4/xfrm4_input.c current/net/ipv4/xfrm4_input.c --- reference/net/ipv4/xfrm4_input.c 2004-03-11 14:35:49.000000000 -0800 +++ current/net/ipv4/xfrm4_input.c 2004-04-09 11:53:04.000000000 -0700 @@ -95,6 +95,19 @@ int xfrm4_rcv_encap(struct sk_buff *skb, iph = skb->nh.iph; if (x->props.mode) { + if (iph->protocol == 0xfe) { + skb_push(skb, skb->data - skb->nh.raw); + if (!(skb->dev->flags&IFF_LOOPBACK)){ + dst_release(skb->dst); + skb->dst = NULL; + } + if (skb->sp) { + secpath_put(skb->sp); + skb->sp = NULL; + } + netif_rx(skb); + return 0; + } if (iph->protocol != IPPROTO_IPIP) goto drop; if (!pskb_may_pull(skb, sizeof(struct iphdr)))