aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipcomp6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ipcomp6.c')
-rw-r--r--net/ipv6/ipcomp6.c19
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:
119static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) 119static 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
171out_ok: 162out_ok:
163 skb_push(skb, -skb_network_offset(skb));
164
172 return 0; 165 return 0;
173} 166}
174 167