diff options
Diffstat (limited to 'net/ipv4/ipcomp.c')
| -rw-r--r-- | net/ipv4/ipcomp.c | 34 |
1 files changed, 8 insertions, 26 deletions
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 95278b22b669..3ed8b57a1002 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
| @@ -45,7 +45,6 @@ static LIST_HEAD(ipcomp_tfms_list); | |||
| 45 | static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) | 45 | static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) |
| 46 | { | 46 | { |
| 47 | int err, plen, dlen; | 47 | int err, plen, dlen; |
| 48 | struct iphdr *iph; | ||
| 49 | struct ipcomp_data *ipcd = x->data; | 48 | struct ipcomp_data *ipcd = x->data; |
| 50 | u8 *start, *scratch; | 49 | u8 *start, *scratch; |
| 51 | struct crypto_tfm *tfm; | 50 | struct crypto_tfm *tfm; |
| @@ -74,8 +73,6 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) | |||
| 74 | 73 | ||
| 75 | skb_put(skb, dlen - plen); | 74 | skb_put(skb, dlen - plen); |
| 76 | memcpy(skb->data, scratch, dlen); | 75 | memcpy(skb->data, scratch, dlen); |
| 77 | iph = skb->nh.iph; | ||
| 78 | iph->tot_len = htons(dlen + iph->ihl * 4); | ||
| 79 | out: | 76 | out: |
| 80 | put_cpu(); | 77 | put_cpu(); |
| 81 | return err; | 78 | return err; |
| @@ -83,34 +80,21 @@ out: | |||
| 83 | 80 | ||
| 84 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | 81 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
| 85 | { | 82 | { |
| 86 | u8 nexthdr; | 83 | int err = -ENOMEM; |
| 87 | int err = 0; | ||
| 88 | struct iphdr *iph; | 84 | struct iphdr *iph; |
| 89 | union { | 85 | struct ip_comp_hdr *ipch; |
| 90 | struct iphdr iph; | ||
| 91 | char buf[60]; | ||
| 92 | } tmp_iph; | ||
| 93 | |||
| 94 | 86 | ||
| 95 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 87 | if (skb_linearize_cow(skb)) |
| 96 | skb_linearize(skb, GFP_ATOMIC) != 0) { | ||
| 97 | err = -ENOMEM; | ||
| 98 | goto out; | 88 | goto out; |
| 99 | } | ||
| 100 | 89 | ||
| 101 | skb->ip_summed = CHECKSUM_NONE; | 90 | skb->ip_summed = CHECKSUM_NONE; |
| 102 | 91 | ||
| 103 | /* Remove ipcomp header and decompress original payload */ | 92 | /* Remove ipcomp header and decompress original payload */ |
| 104 | iph = skb->nh.iph; | 93 | iph = skb->nh.iph; |
| 105 | memcpy(&tmp_iph, iph, iph->ihl * 4); | 94 | ipch = (void *)skb->data; |
| 106 | nexthdr = *(u8 *)skb->data; | 95 | iph->protocol = ipch->nexthdr; |
| 107 | skb_pull(skb, sizeof(struct ip_comp_hdr)); | 96 | skb->h.raw = skb->nh.raw + sizeof(*ipch); |
| 108 | skb->nh.raw += sizeof(struct ip_comp_hdr); | 97 | __skb_pull(skb, sizeof(*ipch)); |
| 109 | memcpy(skb->nh.raw, &tmp_iph, tmp_iph.iph.ihl * 4); | ||
| 110 | iph = skb->nh.iph; | ||
| 111 | iph->tot_len = htons(ntohs(iph->tot_len) - sizeof(struct ip_comp_hdr)); | ||
| 112 | iph->protocol = nexthdr; | ||
| 113 | skb->h.raw = skb->data; | ||
| 114 | err = ipcomp_decompress(x, skb); | 98 | err = ipcomp_decompress(x, skb); |
| 115 | 99 | ||
| 116 | out: | 100 | out: |
| @@ -171,10 +155,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 171 | goto out_ok; | 155 | goto out_ok; |
| 172 | } | 156 | } |
| 173 | 157 | ||
| 174 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 158 | if (skb_linearize_cow(skb)) |
| 175 | skb_linearize(skb, GFP_ATOMIC) != 0) { | ||
| 176 | goto out_ok; | 159 | goto out_ok; |
| 177 | } | ||
| 178 | 160 | ||
| 179 | err = ipcomp_compress(x, skb); | 161 | err = ipcomp_compress(x, skb); |
| 180 | iph = skb->nh.iph; | 162 | iph = skb->nh.iph; |
