aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipcomp6.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-10 18:45:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:56 -0400
commitceb1eec8291175686d0208e66595ff83bc0624e2 (patch)
tree83a7fdc7d292f1dbb80f32563d9573810bfe6e42 /net/ipv6/ipcomp6.c
parent87bdc48d304191313203df9b98d783e1ab5a55ab (diff)
[IPSEC]: Move IP length/checksum setting out of transforms
This patch moves the setting of the IP length and checksum fields out of the transforms and into the xfrmX_output functions. This would help future efforts in merging the transforms themselves. It also adds an optimisation to ipcomp due to the fact that the transport offset is guaranteed to be zero. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
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