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.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index beeed602aeb3..fdde51f4271a 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -39,6 +39,11 @@
39#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) 39#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
40#define XFRM_MAX_QUEUE_LEN 100 40#define XFRM_MAX_QUEUE_LEN 100
41 41
42struct xfrm_flo {
43 struct dst_entry *dst_orig;
44 u8 flags;
45};
46
42static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); 47static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock);
43static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] 48static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO]
44 __read_mostly; 49 __read_mostly;
@@ -1877,13 +1882,14 @@ static int xdst_queue_output(struct sock *sk, struct sk_buff *skb)
1877} 1882}
1878 1883
1879static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net, 1884static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
1880 struct dst_entry *dst, 1885 struct xfrm_flo *xflo,
1881 const struct flowi *fl, 1886 const struct flowi *fl,
1882 int num_xfrms, 1887 int num_xfrms,
1883 u16 family) 1888 u16 family)
1884{ 1889{
1885 int err; 1890 int err;
1886 struct net_device *dev; 1891 struct net_device *dev;
1892 struct dst_entry *dst;
1887 struct dst_entry *dst1; 1893 struct dst_entry *dst1;
1888 struct xfrm_dst *xdst; 1894 struct xfrm_dst *xdst;
1889 1895
@@ -1891,9 +1897,12 @@ static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
1891 if (IS_ERR(xdst)) 1897 if (IS_ERR(xdst))
1892 return xdst; 1898 return xdst;
1893 1899
1894 if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0) 1900 if (!(xflo->flags & XFRM_LOOKUP_QUEUE) ||
1901 net->xfrm.sysctl_larval_drop ||
1902 num_xfrms <= 0)
1895 return xdst; 1903 return xdst;
1896 1904
1905 dst = xflo->dst_orig;
1897 dst1 = &xdst->u.dst; 1906 dst1 = &xdst->u.dst;
1898 dst_hold(dst); 1907 dst_hold(dst);
1899 xdst->route = dst; 1908 xdst->route = dst;
@@ -1935,7 +1944,7 @@ static struct flow_cache_object *
1935xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, 1944xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
1936 struct flow_cache_object *oldflo, void *ctx) 1945 struct flow_cache_object *oldflo, void *ctx)
1937{ 1946{
1938 struct dst_entry *dst_orig = (struct dst_entry *)ctx; 1947 struct xfrm_flo *xflo = (struct xfrm_flo *)ctx;
1939 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; 1948 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
1940 struct xfrm_dst *xdst, *new_xdst; 1949 struct xfrm_dst *xdst, *new_xdst;
1941 int num_pols = 0, num_xfrms = 0, i, err, pol_dead; 1950 int num_pols = 0, num_xfrms = 0, i, err, pol_dead;
@@ -1976,7 +1985,8 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
1976 goto make_dummy_bundle; 1985 goto make_dummy_bundle;
1977 } 1986 }
1978 1987
1979 new_xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, dst_orig); 1988 new_xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family,
1989 xflo->dst_orig);
1980 if (IS_ERR(new_xdst)) { 1990 if (IS_ERR(new_xdst)) {
1981 err = PTR_ERR(new_xdst); 1991 err = PTR_ERR(new_xdst);
1982 if (err != -EAGAIN) 1992 if (err != -EAGAIN)
@@ -2010,7 +2020,7 @@ make_dummy_bundle:
2010 /* We found policies, but there's no bundles to instantiate: 2020 /* We found policies, but there's no bundles to instantiate:
2011 * either because the policy blocks, has no transformations or 2021 * either because the policy blocks, has no transformations or
2012 * we could not build template (no xfrm_states).*/ 2022 * we could not build template (no xfrm_states).*/
2013 xdst = xfrm_create_dummy_bundle(net, dst_orig, fl, num_xfrms, family); 2023 xdst = xfrm_create_dummy_bundle(net, xflo, fl, num_xfrms, family);
2014 if (IS_ERR(xdst)) { 2024 if (IS_ERR(xdst)) {
2015 xfrm_pols_put(pols, num_pols); 2025 xfrm_pols_put(pols, num_pols);
2016 return ERR_CAST(xdst); 2026 return ERR_CAST(xdst);
@@ -2104,13 +2114,18 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
2104 } 2114 }
2105 2115
2106 if (xdst == NULL) { 2116 if (xdst == NULL) {
2117 struct xfrm_flo xflo;
2118
2119 xflo.dst_orig = dst_orig;
2120 xflo.flags = flags;
2121
2107 /* To accelerate a bit... */ 2122 /* To accelerate a bit... */
2108 if ((dst_orig->flags & DST_NOXFRM) || 2123 if ((dst_orig->flags & DST_NOXFRM) ||
2109 !net->xfrm.policy_count[XFRM_POLICY_OUT]) 2124 !net->xfrm.policy_count[XFRM_POLICY_OUT])
2110 goto nopol; 2125 goto nopol;
2111 2126
2112 flo = flow_cache_lookup(net, fl, family, dir, 2127 flo = flow_cache_lookup(net, fl, family, dir,
2113 xfrm_bundle_lookup, dst_orig); 2128 xfrm_bundle_lookup, &xflo);
2114 if (flo == NULL) 2129 if (flo == NULL)
2115 goto nopol; 2130 goto nopol;
2116 if (IS_ERR(flo)) { 2131 if (IS_ERR(flo)) {
@@ -2138,7 +2153,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
2138 xfrm_pols_put(pols, drop_pols); 2153 xfrm_pols_put(pols, drop_pols);
2139 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); 2154 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
2140 2155
2141 return make_blackhole(net, family, dst_orig); 2156 return ERR_PTR(-EREMOTE);
2142 } 2157 }
2143 2158
2144 err = -EAGAIN; 2159 err = -EAGAIN;
@@ -2195,6 +2210,23 @@ dropdst:
2195} 2210}
2196EXPORT_SYMBOL(xfrm_lookup); 2211EXPORT_SYMBOL(xfrm_lookup);
2197 2212
2213/* Callers of xfrm_lookup_route() must ensure a call to dst_output().
2214 * Otherwise we may send out blackholed packets.
2215 */
2216struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
2217 const struct flowi *fl,
2218 struct sock *sk, int flags)
2219{
2220 struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk,
2221 flags | XFRM_LOOKUP_QUEUE);
2222
2223 if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE)
2224 return make_blackhole(net, dst_orig->ops->family, dst_orig);
2225
2226 return dst;
2227}
2228EXPORT_SYMBOL(xfrm_lookup_route);
2229
2198static inline int 2230static inline int
2199xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl) 2231xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl)
2200{ 2232{
@@ -2460,7 +2492,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
2460 2492
2461 skb_dst_force(skb); 2493 skb_dst_force(skb);
2462 2494
2463 dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, 0); 2495 dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, XFRM_LOOKUP_QUEUE);
2464 if (IS_ERR(dst)) { 2496 if (IS_ERR(dst)) {
2465 res = 0; 2497 res = 0;
2466 dst = NULL; 2498 dst = NULL;