Merge branch 'for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[sfrench/cifs-2.6.git] / net / xfrm / xfrm_state.c
index 500b3391f474b96fe273060ff8eae16f1e23f3c2..a3785f538018dc8a777f7768752d8f5f7cedb1e1 100644 (file)
@@ -313,13 +313,14 @@ retry:
        if ((type && !try_module_get(type->owner)))
                type = NULL;
 
+       rcu_read_unlock();
+
        if (!type && try_load) {
                request_module("xfrm-offload-%d-%d", family, proto);
-               try_load = 0;
+               try_load = false;
                goto retry;
        }
 
-       rcu_read_unlock();
        return type;
 }
 
@@ -1534,8 +1535,12 @@ out:
        err = -EINVAL;
        spin_lock_bh(&x1->lock);
        if (likely(x1->km.state == XFRM_STATE_VALID)) {
-               if (x->encap && x1->encap)
+               if (x->encap && x1->encap &&
+                   x->encap->encap_type == x1->encap->encap_type)
                        memcpy(x1->encap, x->encap, sizeof(*x1->encap));
+               else if (x->encap || x1->encap)
+                       goto fail;
+
                if (x->coaddr && x1->coaddr) {
                        memcpy(x1->coaddr, x->coaddr, sizeof(*x1->coaddr));
                }
@@ -1552,6 +1557,8 @@ out:
                x->km.state = XFRM_STATE_DEAD;
                __xfrm_state_put(x);
        }
+
+fail:
        spin_unlock_bh(&x1->lock);
 
        xfrm_state_put(x1);
@@ -2265,8 +2272,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
                        goto error;
        }
 
-       x->km.state = XFRM_STATE_VALID;
-
 error:
        return err;
 }
@@ -2275,7 +2280,13 @@ EXPORT_SYMBOL(__xfrm_init_state);
 
 int xfrm_init_state(struct xfrm_state *x)
 {
-       return __xfrm_init_state(x, true, false);
+       int err;
+
+       err = __xfrm_init_state(x, true, false);
+       if (!err)
+               x->km.state = XFRM_STATE_VALID;
+
+       return err;
 }
 
 EXPORT_SYMBOL(xfrm_init_state);