aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-04-05 19:03:33 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-05 19:03:33 -0400
commit254d0d24e31c3df64ccfff349c9aa9d1e5989819 (patch)
treeadcbb19764ed646adb5fa2008d5a94d97db54566
parentd4b1e840629562953d81c9fe0a3a67473f3d993c (diff)
[XFRM]: beet: fix IP option decapsulation
Beet mode looks for the beet pseudo header after the outer IP header, which is wrong since that is followed by the ESP header. Additionally it needs to adjust the packet length after removing the pseudo header and point the data pointer to the real data location. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/xfrm4_mode_beet.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index b94775a86863..f68dfd8a0f5c 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -78,10 +78,11 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
78 protocol = iph->protocol; 78 protocol = iph->protocol;
79 79
80 if (unlikely(iph->protocol == IPPROTO_BEETPH)) { 80 if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
81 struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1); 81 struct ip_beet_phdr *ph;
82 82
83 if (!pskb_may_pull(skb, sizeof(*ph))) 83 if (!pskb_may_pull(skb, sizeof(*ph)))
84 goto out; 84 goto out;
85 ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1);
85 86
86 phlen = sizeof(*ph) + ph->padlen; 87 phlen = sizeof(*ph) + ph->padlen;
87 optlen = ph->hdrlen * 8 - phlen; 88 optlen = ph->hdrlen * 8 - phlen;
@@ -90,6 +91,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
90 91
91 if (!pskb_may_pull(skb, phlen + optlen)) 92 if (!pskb_may_pull(skb, phlen + optlen))
92 goto out; 93 goto out;
94 skb->len -= phlen + optlen;
93 95
94 ph_nexthdr = ph->nexthdr; 96 ph_nexthdr = ph->nexthdr;
95 } 97 }
@@ -97,6 +99,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
97 skb->nh.raw = skb->data + (phlen - sizeof(*iph)); 99 skb->nh.raw = skb->data + (phlen - sizeof(*iph));
98 memmove(skb->nh.raw, iph, sizeof(*iph)); 100 memmove(skb->nh.raw, iph, sizeof(*iph));
99 skb->h.raw = skb->data + (phlen + optlen); 101 skb->h.raw = skb->data + (phlen + optlen);
102 skb->data = skb->h.raw;
100 103
101 iph = skb->nh.iph; 104 iph = skb->nh.iph;
102 iph->ihl = (sizeof(*iph) + optlen) / 4; 105 iph->ihl = (sizeof(*iph) + optlen) / 4;