aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipcomp.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/ipv4/ipcomp.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/ipv4/ipcomp.c')
-rw-r--r--net/ipv4/ipcomp.c22
1 files changed, 5 insertions, 17 deletions
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 78d6ddb02d1d..32b02deca2ec 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -98,10 +98,9 @@ out:
98static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) 98static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
99{ 99{
100 struct ipcomp_data *ipcd = x->data; 100 struct ipcomp_data *ipcd = x->data;
101 const int ihlen = skb_transport_offset(skb); 101 const int plen = skb->len;
102 const int plen = skb->len - ihlen;
103 int dlen = IPCOMP_SCRATCH_SIZE; 102 int dlen = IPCOMP_SCRATCH_SIZE;
104 u8 *start = skb_transport_header(skb); 103 u8 *start = skb->data;
105 const int cpu = get_cpu(); 104 const int cpu = get_cpu();
106 u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); 105 u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
107 struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); 106 struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
@@ -118,7 +117,7 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
118 memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); 117 memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
119 put_cpu(); 118 put_cpu();
120 119
121 pskb_trim(skb, ihlen + dlen + sizeof(struct ip_comp_hdr)); 120 pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr));
122 return 0; 121 return 0;
123 122
124out: 123out:
@@ -131,13 +130,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
131 int err; 130 int err;
132 struct ip_comp_hdr *ipch; 131 struct ip_comp_hdr *ipch;
133 struct ipcomp_data *ipcd = x->data; 132 struct ipcomp_data *ipcd = x->data;
134 int hdr_len = 0;
135 struct iphdr *iph = ip_hdr(skb);
136 133
137 skb_push(skb, -skb_network_offset(skb)); 134 if (skb->len < ipcd->threshold) {
138 iph->tot_len = htons(skb->len);
139 hdr_len = iph->ihl * 4;
140 if ((skb->len - hdr_len) < ipcd->threshold) {
141 /* Don't bother compressing */ 135 /* Don't bother compressing */
142 goto out_ok; 136 goto out_ok;
143 } 137 }
@@ -146,25 +140,19 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
146 goto out_ok; 140 goto out_ok;
147 141
148 err = ipcomp_compress(x, skb); 142 err = ipcomp_compress(x, skb);
149 iph = ip_hdr(skb);
150 143
151 if (err) { 144 if (err) {
152 goto out_ok; 145 goto out_ok;
153 } 146 }
154 147
155 /* Install ipcomp header, convert into ipcomp datagram. */ 148 /* Install ipcomp header, convert into ipcomp datagram. */
156 iph->tot_len = htons(skb->len);
157 ipch = ip_comp_hdr(skb); 149 ipch = ip_comp_hdr(skb);
158 ipch->nexthdr = *skb_mac_header(skb); 150 ipch->nexthdr = *skb_mac_header(skb);
159 ipch->flags = 0; 151 ipch->flags = 0;
160 ipch->cpi = htons((u16 )ntohl(x->id.spi)); 152 ipch->cpi = htons((u16 )ntohl(x->id.spi));
161 *skb_mac_header(skb) = IPPROTO_COMP; 153 *skb_mac_header(skb) = IPPROTO_COMP;
162 ip_send_check(iph);
163 return 0;
164
165out_ok: 154out_ok:
166 if (x->props.mode == XFRM_MODE_TUNNEL) 155 skb_push(skb, -skb_network_offset(skb));
167 ip_send_check(iph);
168 return 0; 156 return 0;
169} 157}
170 158