diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-12-16 18:55:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:53:51 -0500 |
commit | 668dc8af3150f837f7f0461001bbbc0ce25d7bdf (patch) | |
tree | 9ba3534a190bb69b3aebf24aaa4340685fe16539 /net/ipv4/esp4.c | |
parent | b2aa5e9d43a38dcdfa0878ed750cf32f98460278 (diff) |
[IPSEC]: Move integrity stat collection into xfrm_input
Similar to the moving out of the replay processing on the output, this
patch moves the integrity stat collectin from x->type->input into
xfrm_input.
This would eventually allow transforms such as AH/ESP to be lockless.
The error value EBADMSG (currently unused in the crypto layer) is used
to indicate a failed integrity check. In future this error can be
directly returned by the crypto layer once we switch to aead
algorithms.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/esp4.c')
-rw-r--r-- | net/ipv4/esp4.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 1738113268bc..3350a7d50669 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -163,7 +163,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
163 | u8 nexthdr[2]; | 163 | u8 nexthdr[2]; |
164 | struct scatterlist *sg; | 164 | struct scatterlist *sg; |
165 | int padlen; | 165 | int padlen; |
166 | int err; | 166 | int err = -EINVAL; |
167 | 167 | ||
168 | if (!pskb_may_pull(skb, sizeof(*esph))) | 168 | if (!pskb_may_pull(skb, sizeof(*esph))) |
169 | goto out; | 169 | goto out; |
@@ -183,13 +183,14 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
183 | BUG(); | 183 | BUG(); |
184 | 184 | ||
185 | if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { | 185 | if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { |
186 | x->stats.integrity_failed++; | 186 | err = -EBADMSG; |
187 | goto out; | 187 | goto out; |
188 | } | 188 | } |
189 | } | 189 | } |
190 | 190 | ||
191 | if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) | 191 | if ((err = skb_cow_data(skb, 0, &trailer)) < 0) |
192 | goto out; | 192 | goto out; |
193 | nfrags = err; | ||
193 | 194 | ||
194 | skb->ip_summed = CHECKSUM_NONE; | 195 | skb->ip_summed = CHECKSUM_NONE; |
195 | 196 | ||
@@ -202,6 +203,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
202 | sg = &esp->sgbuf[0]; | 203 | sg = &esp->sgbuf[0]; |
203 | 204 | ||
204 | if (unlikely(nfrags > ESP_NUM_FAST_SG)) { | 205 | if (unlikely(nfrags > ESP_NUM_FAST_SG)) { |
206 | err = -ENOMEM; | ||
205 | sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); | 207 | sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); |
206 | if (!sg) | 208 | if (!sg) |
207 | goto out; | 209 | goto out; |
@@ -214,11 +216,12 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
214 | if (unlikely(sg != &esp->sgbuf[0])) | 216 | if (unlikely(sg != &esp->sgbuf[0])) |
215 | kfree(sg); | 217 | kfree(sg); |
216 | if (unlikely(err)) | 218 | if (unlikely(err)) |
217 | return err; | 219 | goto out; |
218 | 220 | ||
219 | if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) | 221 | if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) |
220 | BUG(); | 222 | BUG(); |
221 | 223 | ||
224 | err = -EINVAL; | ||
222 | padlen = nexthdr[0]; | 225 | padlen = nexthdr[0]; |
223 | if (padlen+2 >= elen) | 226 | if (padlen+2 >= elen) |
224 | goto out; | 227 | goto out; |
@@ -276,7 +279,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
276 | return nexthdr[1]; | 279 | return nexthdr[1]; |
277 | 280 | ||
278 | out: | 281 | out: |
279 | return -EINVAL; | 282 | return err; |
280 | } | 283 | } |
281 | 284 | ||
282 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) | 285 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) |