]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/esp4.c
[IPSEC]: Move state lock into x->type->input
[linux-2.6-omap-h63xx.git] / net / ipv4 / esp4.c
index 3350a7d506699897811f0e76a45dd78ddedd2d41..28ea5c77ca238a72a424ae292c2decc622c2d70e 100644 (file)
@@ -171,29 +171,31 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        if (elen <= 0 || (elen & (blksize-1)))
                goto out;
 
+       if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+               goto out;
+       nfrags = err;
+
+       skb->ip_summed = CHECKSUM_NONE;
+
+       spin_lock(&x->lock);
+
        /* If integrity check is required, do this. */
        if (esp->auth.icv_full_len) {
                u8 sum[alen];
 
                err = esp_mac_digest(esp, skb, 0, skb->len - alen);
                if (err)
-                       goto out;
+                       goto unlock;
 
                if (skb_copy_bits(skb, skb->len - alen, sum, alen))
                        BUG();
 
                if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
                        err = -EBADMSG;
-                       goto out;
+                       goto unlock;
                }
        }
 
-       if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
-               goto out;
-       nfrags = err;
-
-       skb->ip_summed = CHECKSUM_NONE;
-
        esph = (struct ip_esp_hdr *)skb->data;
 
        /* Get ivec. This can be wrong, check against another impls. */
@@ -206,7 +208,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
                err = -ENOMEM;
                sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
                if (!sg)
-                       goto out;
+                       goto unlock;
        }
        sg_init_table(sg, nfrags);
        skb_to_sgvec(skb, sg,
@@ -215,6 +217,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
        if (unlikely(sg != &esp->sgbuf[0]))
                kfree(sg);
+
+unlock:
+       spin_unlock(&x->lock);
+
        if (unlikely(err))
                goto out;