if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
+ err = PTR_ERR(policy);
if (IS_ERR(policy))
- return PTR_ERR(policy);
+ goto dropdst;
}
if (!policy) {
policy = flow_cache_lookup(fl, dst_orig->ops->family,
dir, xfrm_policy_lookup);
+ err = PTR_ERR(policy);
if (IS_ERR(policy))
- return PTR_ERR(policy);
+ goto dropdst;
}
if (!policy)
xfrm_nr += pols[0]->xfrm_nr;
switch (policy->action) {
+ default:
case XFRM_POLICY_BLOCK:
/* Prohibit the flow */
err = -EPERM;
return 0;
error:
- dst_release(dst_orig);
xfrm_pols_put(pols, npols);
+dropdst:
+ dst_release(dst_orig);
*dst_p = NULL;
return err;
}
return 0;
if (strict && fl &&
- !(dst->xfrm->mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
+ !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
!xfrm_state_addr_flow_check(dst->xfrm, fl, family))
return 0;