Merge branch 'rc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuil...
[linux-drm-fsl-dcu.git] / net / xfrm / xfrm_policy.c
index 4bf27d90133336a1f862e6c7b28e4939397284c5..a7ec5a8a2380e6277fa4a3755e01fb0aa58076fb 100644 (file)
@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
 
        /* Try to instantiate a bundle */
        err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
-       if (err < 0) {
-               if (err != -EAGAIN)
+       if (err <= 0) {
+               if (err != 0 && err != -EAGAIN)
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
                return ERR_PTR(err);
        }
@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
                        goto make_dummy_bundle;
                dst_hold(&xdst->u.dst);
                return oldflo;
+       } else if (new_xdst == NULL) {
+               num_xfrms = 0;
+               if (oldflo == NULL)
+                       goto make_dummy_bundle;
+               xdst->num_xfrms = 0;
+               dst_hold(&xdst->u.dst);
+               return oldflo;
        }
 
        /* Kill the previous bundle */
@@ -1760,6 +1767,10 @@ restart:
                                xfrm_pols_put(pols, num_pols);
                                err = PTR_ERR(xdst);
                                goto dropdst;
+                       } else if (xdst == NULL) {
+                               num_xfrms = 0;
+                               drop_pols = num_pols;
+                               goto no_transform;
                        }
 
                        spin_lock_bh(&xfrm_policy_sk_bundle_lock);
@@ -2300,7 +2311,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
                        return 0;
                if (xdst->xfrm_genid != dst->xfrm->genid)
                        return 0;
-               if (xdst->policy_genid != atomic_read(&xdst->pols[0]->genid))
+               if (xdst->num_pols > 0 &&
+                   xdst->policy_genid != atomic_read(&xdst->pols[0]->genid))
                        return 0;
 
                if (strict && fl &&