|
39 | 39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
|
40 | 40 | #define XFRM_MAX_QUEUE_LEN 100
|
41 | 41 |
|
| 42 | +struct xfrm_flo { |
| 43 | + struct dst_entry *dst_orig; |
| 44 | + u8 flags; |
| 45 | +}; |
| 46 | + |
42 | 47 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock);
|
43 | 48 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO]
|
44 | 49 | __read_mostly;
|
@@ -1877,23 +1882,27 @@ static int xdst_queue_output(struct sock *sk, struct sk_buff *skb)
|
1877 | 1882 | }
|
1878 | 1883 |
|
1879 | 1884 | static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
|
1880 |
| - struct dst_entry *dst, |
| 1885 | + struct xfrm_flo *xflo, |
1881 | 1886 | const struct flowi *fl,
|
1882 | 1887 | int num_xfrms,
|
1883 | 1888 | u16 family)
|
1884 | 1889 | {
|
1885 | 1890 | int err;
|
1886 | 1891 | struct net_device *dev;
|
| 1892 | + struct dst_entry *dst; |
1887 | 1893 | struct dst_entry *dst1;
|
1888 | 1894 | struct xfrm_dst *xdst;
|
1889 | 1895 |
|
1890 | 1896 | xdst = xfrm_alloc_dst(net, family);
|
1891 | 1897 | if (IS_ERR(xdst))
|
1892 | 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 | 1903 | return xdst;
|
1896 | 1904 |
|
| 1905 | + dst = xflo->dst_orig; |
1897 | 1906 | dst1 = &xdst->u.dst;
|
1898 | 1907 | dst_hold(dst);
|
1899 | 1908 | xdst->route = dst;
|
@@ -1935,7 +1944,7 @@ static struct flow_cache_object *
|
1935 | 1944 | xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
|
1936 | 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 | 1948 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
|
1940 | 1949 | struct xfrm_dst *xdst, *new_xdst;
|
1941 | 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 | 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 | 1990 | if (IS_ERR(new_xdst)) {
|
1981 | 1991 | err = PTR_ERR(new_xdst);
|
1982 | 1992 | if (err != -EAGAIN)
|
@@ -2010,7 +2020,7 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
|
2010 | 2020 | /* We found policies, but there's no bundles to instantiate:
|
2011 | 2021 | * either because the policy blocks, has no transformations or
|
2012 | 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 | 2024 | if (IS_ERR(xdst)) {
|
2015 | 2025 | xfrm_pols_put(pols, num_pols);
|
2016 | 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 | 2116 | if (xdst == NULL) {
|
| 2117 | + struct xfrm_flo xflo; |
| 2118 | + |
| 2119 | + xflo.dst_orig = dst_orig; |
| 2120 | + xflo.flags = flags; |
| 2121 | + |
2107 | 2122 | /* To accelerate a bit... */
|
2108 | 2123 | if ((dst_orig->flags & DST_NOXFRM) ||
|
2109 | 2124 | !net->xfrm.policy_count[XFRM_POLICY_OUT])
|
2110 | 2125 | goto nopol;
|
2111 | 2126 |
|
2112 | 2127 | flo = flow_cache_lookup(net, fl, family, dir,
|
2113 |
| - xfrm_bundle_lookup, dst_orig); |
| 2128 | + xfrm_bundle_lookup, &xflo); |
2114 | 2129 | if (flo == NULL)
|
2115 | 2130 | goto nopol;
|
2116 | 2131 | if (IS_ERR(flo)) {
|
@@ -2138,7 +2153,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
|
2138 | 2153 | xfrm_pols_put(pols, drop_pols);
|
2139 | 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 | 2159 | err = -EAGAIN;
|
@@ -2195,6 +2210,23 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
|
2195 | 2210 | }
|
2196 | 2211 | EXPORT_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 | + */ |
| 2216 | +struct 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 | +} |
| 2228 | +EXPORT_SYMBOL(xfrm_lookup_route); |
| 2229 | + |
2198 | 2230 | static inline int
|
2199 | 2231 | xfrm_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 | 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 | 2496 | if (IS_ERR(dst)) {
|
2465 | 2497 | res = 0;
|
2466 | 2498 | dst = NULL;
|
|
0 commit comments