diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-04-26 04:31:28 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-04-26 04:31:28 -0400 |
commit | ef2e58ea6b9931c3a4816c66593da49bb20e3b24 (patch) | |
tree | ce7432add3becbe78de4ea06425cd2d9e91f4ada /net/ipv4/xfrm4_mode_beet.c | |
parent | 06d63cc51d47f572009138a7f3ac34d95773405d (diff) | |
parent | de46c33745f5e2ad594c72f2cf5f490861b16ce1 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/ipv4/xfrm4_mode_beet.c')
-rw-r--r-- | net/ipv4/xfrm4_mode_beet.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index 89cf59ea7bbe..d419e15d9803 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c | |||
@@ -42,10 +42,9 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
42 | 42 | ||
43 | skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen); | 43 | skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen); |
44 | top_iph = skb->nh.iph; | 44 | top_iph = skb->nh.iph; |
45 | hdrlen = iph->ihl * 4 - optlen; | 45 | skb->h.raw += sizeof(*iph) - hdrlen; |
46 | skb->h.raw += hdrlen; | ||
47 | 46 | ||
48 | memmove(top_iph, iph, hdrlen); | 47 | memmove(top_iph, iph, sizeof(*iph)); |
49 | if (unlikely(optlen)) { | 48 | if (unlikely(optlen)) { |
50 | struct ip_beet_phdr *ph; | 49 | struct ip_beet_phdr *ph; |
51 | 50 | ||
@@ -53,8 +52,10 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
53 | 52 | ||
54 | ph = (struct ip_beet_phdr *)skb->h.raw; | 53 | ph = (struct ip_beet_phdr *)skb->h.raw; |
55 | ph->padlen = 4 - (optlen & 4); | 54 | ph->padlen = 4 - (optlen & 4); |
56 | ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8; | 55 | ph->hdrlen = optlen / 8; |
57 | ph->nexthdr = top_iph->protocol; | 56 | ph->nexthdr = top_iph->protocol; |
57 | if (ph->padlen) | ||
58 | memset(ph + 1, IPOPT_NOP, ph->padlen); | ||
58 | 59 | ||
59 | top_iph->protocol = IPPROTO_BEETPH; | 60 | top_iph->protocol = IPPROTO_BEETPH; |
60 | top_iph->ihl = sizeof(struct iphdr) / 4; | 61 | top_iph->ihl = sizeof(struct iphdr) / 4; |
@@ -77,29 +78,32 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) | |||
77 | protocol = iph->protocol; | 78 | protocol = iph->protocol; |
78 | 79 | ||
79 | if (unlikely(iph->protocol == IPPROTO_BEETPH)) { | 80 | if (unlikely(iph->protocol == IPPROTO_BEETPH)) { |
80 | struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1); | 81 | struct ip_beet_phdr *ph; |
81 | 82 | ||
82 | if (!pskb_may_pull(skb, sizeof(*ph))) | 83 | if (!pskb_may_pull(skb, sizeof(*ph))) |
83 | goto out; | 84 | goto out; |
85 | ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1); | ||
84 | 86 | ||
85 | phlen = ph->hdrlen * 8; | 87 | phlen = sizeof(*ph) + ph->padlen; |
86 | optlen = phlen - ph->padlen - sizeof(*ph); | 88 | optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen); |
87 | if (optlen < 0 || optlen & 3 || optlen > 250) | 89 | if (optlen < 0 || optlen & 3 || optlen > 250) |
88 | goto out; | 90 | goto out; |
89 | 91 | ||
90 | if (!pskb_may_pull(skb, phlen)) | 92 | if (!pskb_may_pull(skb, phlen + optlen)) |
91 | goto out; | 93 | goto out; |
94 | skb->len -= phlen + optlen; | ||
92 | 95 | ||
93 | ph_nexthdr = ph->nexthdr; | 96 | ph_nexthdr = ph->nexthdr; |
94 | } | 97 | } |
95 | 98 | ||
96 | skb_push(skb, sizeof(*iph) - phlen + optlen); | 99 | skb->nh.raw = skb->data + (phlen - sizeof(*iph)); |
97 | memmove(skb->data, skb->nh.raw, sizeof(*iph)); | 100 | memmove(skb->nh.raw, iph, sizeof(*iph)); |
98 | skb->nh.raw = skb->data; | 101 | skb->h.raw = skb->data + (phlen + optlen); |
102 | skb->data = skb->h.raw; | ||
99 | 103 | ||
100 | iph = skb->nh.iph; | 104 | iph = skb->nh.iph; |
101 | iph->ihl = (sizeof(*iph) + optlen) / 4; | 105 | iph->ihl = (sizeof(*iph) + optlen) / 4; |
102 | iph->tot_len = htons(skb->len); | 106 | iph->tot_len = htons(skb->len + iph->ihl * 4); |
103 | iph->daddr = x->sel.daddr.a4; | 107 | iph->daddr = x->sel.daddr.a4; |
104 | iph->saddr = x->sel.saddr.a4; | 108 | iph->saddr = x->sel.saddr.a4; |
105 | if (ph_nexthdr) | 109 | if (ph_nexthdr) |