aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d965a2bad8d3..2b3ed7ad4933 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
1594 1594
1595 /* Try to instantiate a bundle */ 1595 /* Try to instantiate a bundle */
1596 err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); 1596 err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
1597 if (err < 0) { 1597 if (err <= 0) {
1598 if (err != -EAGAIN) 1598 if (err != 0 && err != -EAGAIN)
1599 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); 1599 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
1600 return ERR_PTR(err); 1600 return ERR_PTR(err);
1601 } 1601 }
@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
1678 goto make_dummy_bundle; 1678 goto make_dummy_bundle;
1679 dst_hold(&xdst->u.dst); 1679 dst_hold(&xdst->u.dst);
1680 return oldflo; 1680 return oldflo;
1681 } else if (new_xdst == NULL) {
1682 num_xfrms = 0;
1683 if (oldflo == NULL)
1684 goto make_dummy_bundle;
1685 xdst->num_xfrms = 0;
1686 dst_hold(&xdst->u.dst);
1687 return oldflo;
1681 } 1688 }
1682 1689
1683 /* Kill the previous bundle */ 1690 /* Kill the previous bundle */
@@ -1760,6 +1767,10 @@ restart:
1760 xfrm_pols_put(pols, num_pols); 1767 xfrm_pols_put(pols, num_pols);
1761 err = PTR_ERR(xdst); 1768 err = PTR_ERR(xdst);
1762 goto dropdst; 1769 goto dropdst;
1770 } else if (xdst == NULL) {
1771 num_xfrms = 0;
1772 drop_pols = num_pols;
1773 goto no_transform;
1763 } 1774 }
1764 1775
1765 spin_lock_bh(&xfrm_policy_sk_bundle_lock); 1776 spin_lock_bh(&xfrm_policy_sk_bundle_lock);
@@ -2153,6 +2164,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
2153 return 0; 2164 return 0;
2154 } 2165 }
2155 2166
2167 skb_dst_force(skb);
2156 dst = skb_dst(skb); 2168 dst = skb_dst(skb);
2157 2169
2158 res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0; 2170 res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0;
@@ -2299,7 +2311,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
2299 return 0; 2311 return 0;
2300 if (xdst->xfrm_genid != dst->xfrm->genid) 2312 if (xdst->xfrm_genid != dst->xfrm->genid)
2301 return 0; 2313 return 0;
2302 if (xdst->policy_genid != atomic_read(&xdst->pols[0]->genid)) 2314 if (xdst->num_pols > 0 &&
2315 xdst->policy_genid != atomic_read(&xdst->pols[0]->genid))
2303 return 0; 2316 return 0;
2304 2317
2305 if (strict && fl && 2318 if (strict && fl &&
@@ -2479,7 +2492,8 @@ static int __net_init xfrm_statistics_init(struct net *net)
2479 int rv; 2492 int rv;
2480 2493
2481 if (snmp_mib_init((void __percpu **)net->mib.xfrm_statistics, 2494 if (snmp_mib_init((void __percpu **)net->mib.xfrm_statistics,
2482 sizeof(struct linux_xfrm_mib)) < 0) 2495 sizeof(struct linux_xfrm_mib),
2496 __alignof__(struct linux_xfrm_mib)) < 0)
2483 return -ENOMEM; 2497 return -ENOMEM;
2484 rv = xfrm_proc_init(net); 2498 rv = xfrm_proc_init(net);
2485 if (rv < 0) 2499 if (rv < 0)