diff options
Diffstat (limited to 'net/ipv6/ipcomp6.c')
-rw-r--r-- | net/ipv6/ipcomp6.c | 19 |
1 files changed, 6 insertions, 13 deletions
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 8f3f32faaf4c..28fc8edfdc3a 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -119,20 +119,15 @@ out: | |||
119 | static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) | 119 | static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) |
120 | { | 120 | { |
121 | int err; | 121 | int err; |
122 | struct ipv6hdr *top_iph; | ||
123 | struct ip_comp_hdr *ipch; | 122 | struct ip_comp_hdr *ipch; |
124 | struct ipcomp_data *ipcd = x->data; | 123 | struct ipcomp_data *ipcd = x->data; |
125 | int plen, dlen; | 124 | int plen, dlen; |
126 | u8 *start, *scratch; | 125 | u8 *start, *scratch; |
127 | struct crypto_comp *tfm; | 126 | struct crypto_comp *tfm; |
128 | int cpu; | 127 | int cpu; |
129 | int hdr_len; | ||
130 | |||
131 | skb_push(skb, -skb_network_offset(skb)); | ||
132 | hdr_len = skb_transport_offset(skb); | ||
133 | 128 | ||
134 | /* check whether datagram len is larger than threshold */ | 129 | /* check whether datagram len is larger than threshold */ |
135 | if ((skb->len - hdr_len) < ipcd->threshold) { | 130 | if (skb->len < ipcd->threshold) { |
136 | goto out_ok; | 131 | goto out_ok; |
137 | } | 132 | } |
138 | 133 | ||
@@ -140,9 +135,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
140 | goto out_ok; | 135 | goto out_ok; |
141 | 136 | ||
142 | /* compression */ | 137 | /* compression */ |
143 | plen = skb->len - hdr_len; | 138 | plen = skb->len; |
144 | dlen = IPCOMP_SCRATCH_SIZE; | 139 | dlen = IPCOMP_SCRATCH_SIZE; |
145 | start = skb_transport_header(skb); | 140 | start = skb->data; |
146 | 141 | ||
147 | cpu = get_cpu(); | 142 | cpu = get_cpu(); |
148 | scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); | 143 | scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); |
@@ -155,13 +150,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
155 | } | 150 | } |
156 | memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); | 151 | memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); |
157 | put_cpu(); | 152 | put_cpu(); |
158 | pskb_trim(skb, hdr_len + dlen + sizeof(struct ip_comp_hdr)); | 153 | pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); |
159 | 154 | ||
160 | /* insert ipcomp header and replace datagram */ | 155 | /* insert ipcomp header and replace datagram */ |
161 | top_iph = ipv6_hdr(skb); | ||
162 | |||
163 | top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); | ||
164 | |||
165 | ipch = ip_comp_hdr(skb); | 156 | ipch = ip_comp_hdr(skb); |
166 | ipch->nexthdr = *skb_mac_header(skb); | 157 | ipch->nexthdr = *skb_mac_header(skb); |
167 | ipch->flags = 0; | 158 | ipch->flags = 0; |
@@ -169,6 +160,8 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
169 | *skb_mac_header(skb) = IPPROTO_COMP; | 160 | *skb_mac_header(skb) = IPPROTO_COMP; |
170 | 161 | ||
171 | out_ok: | 162 | out_ok: |
163 | skb_push(skb, -skb_network_offset(skb)); | ||
164 | |||
172 | return 0; | 165 | return 0; |
173 | } | 166 | } |
174 | 167 | ||