]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/xfrm/xfrm_input.c
[IPSEC]: Store xfrm states in security path directly
[linux-2.6-omap-h63xx.git] / net / xfrm / xfrm_input.c
index b980095be935181e155e3da340fe6145e2bf26fc..587f3474ed3d13ce227c8c0dfca102710a322b7a 100644 (file)
@@ -100,19 +100,29 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 {
        int err;
        __be32 seq;
-       struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
        struct xfrm_state *x;
-       int xfrm_nr = 0;
        int decaps = 0;
        unsigned int nhoff = XFRM_SPI_SKB_CB(skb)->nhoff;
        unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
 
+       /* Allocate new secpath or COW existing one. */
+       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+               struct sec_path *sp;
+
+               sp = secpath_dup(skb->sp);
+               if (!sp)
+                       goto drop;
+               if (skb->sp)
+                       secpath_put(skb->sp);
+               skb->sp = sp;
+       }
+
        seq = 0;
        if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
                goto drop;
 
        do {
-               if (xfrm_nr == XFRM_MAX_DEPTH)
+               if (skb->sp->len == XFRM_MAX_DEPTH)
                        goto drop;
 
                x = xfrm_state_lookup((xfrm_address_t *)
@@ -121,6 +131,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
                if (x == NULL)
                        goto drop;
 
+               skb->sp->xvec[skb->sp->len++] = x;
+
                spin_lock(&x->lock);
                if (unlikely(x->km.state != XFRM_STATE_VALID))
                        goto drop_unlock;
@@ -151,8 +163,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
                spin_unlock(&x->lock);
 
-               xfrm_vec[xfrm_nr++] = x;
-
                if (x->inner_mode->input(x, skb))
                        goto drop;
 
@@ -166,24 +176,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
                        goto drop;
        } while (!err);
 
-       /* Allocate new secpath or COW existing one. */
-
-       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-               struct sec_path *sp;
-               sp = secpath_dup(skb->sp);
-               if (!sp)
-                       goto drop;
-               if (skb->sp)
-                       secpath_put(skb->sp);
-               skb->sp = sp;
-       }
-       if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-               goto drop;
-
-       memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
-              xfrm_nr * sizeof(xfrm_vec[0]));
-       skb->sp->len += xfrm_nr;
-
        nf_reset(skb);
 
        if (decaps) {
@@ -197,11 +189,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 drop_unlock:
        spin_unlock(&x->lock);
-       xfrm_state_put(x);
 drop:
-       while (--xfrm_nr >= 0)
-               xfrm_state_put(xfrm_vec[xfrm_nr]);
-
        kfree_skb(skb);
        return 0;
 }