]> err.no Git - linux-2.6/blobdiff - net/xfrm/xfrm_state.c
[PATCH] m68k: separate handler for auto and user vector interrupt
[linux-2.6] / net / xfrm / xfrm_state.c
index 3dc3e1f3b7aae687346e4f9f8ff8926d658b65d0..17b29ec3c41779d70562113ed1219e68ff3ae5fc 100644 (file)
@@ -77,6 +77,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
        kfree(x->ealg);
        kfree(x->calg);
        kfree(x->encap);
+       if (x->mode)
+               xfrm_put_mode(x->mode);
        if (x->type) {
                x->type->destructor(x);
                xfrm_put_type(x->type);
@@ -1061,7 +1063,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
                return -EINVAL;
        if (unlikely(afinfo->family >= NPROTO))
                return -EAFNOSUPPORT;
-       write_lock(&xfrm_state_afinfo_lock);
+       write_lock_bh(&xfrm_state_afinfo_lock);
        if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
                err = -ENOBUFS;
        else {
@@ -1069,7 +1071,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
                afinfo->state_byspi = xfrm_state_byspi;
                xfrm_state_afinfo[afinfo->family] = afinfo;
        }
-       write_unlock(&xfrm_state_afinfo_lock);
+       write_unlock_bh(&xfrm_state_afinfo_lock);
        return err;
 }
 EXPORT_SYMBOL(xfrm_state_register_afinfo);
@@ -1081,7 +1083,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
                return -EINVAL;
        if (unlikely(afinfo->family >= NPROTO))
                return -EAFNOSUPPORT;
-       write_lock(&xfrm_state_afinfo_lock);
+       write_lock_bh(&xfrm_state_afinfo_lock);
        if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
                if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
                        err = -EINVAL;
@@ -1091,7 +1093,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
                        afinfo->state_bydst = NULL;
                }
        }
-       write_unlock(&xfrm_state_afinfo_lock);
+       write_unlock_bh(&xfrm_state_afinfo_lock);
        return err;
 }
 EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
@@ -1103,17 +1105,14 @@ static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
                return NULL;
        read_lock(&xfrm_state_afinfo_lock);
        afinfo = xfrm_state_afinfo[family];
-       if (likely(afinfo != NULL))
-               read_lock(&afinfo->lock);
-       read_unlock(&xfrm_state_afinfo_lock);
+       if (unlikely(!afinfo))
+               read_unlock(&xfrm_state_afinfo_lock);
        return afinfo;
 }
 
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
 {
-       if (unlikely(afinfo == NULL))
-               return;
-       read_unlock(&afinfo->lock);
+       read_unlock(&xfrm_state_afinfo_lock);
 }
 
 /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
@@ -1196,6 +1195,10 @@ int xfrm_init_state(struct xfrm_state *x)
        if (err)
                goto error;
 
+       x->mode = xfrm_get_mode(x->props.mode, family);
+       if (x->mode == NULL)
+               goto error;
+
        x->km.state = XFRM_STATE_VALID;
 
 error: