Skip to content

Commit 84de67b

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2014-09-22 We generate a blackhole or queueing route if a packet matches an IPsec policy but a state can't be resolved. Here we assume that dst_output() is called to kill these packets. Unfortunately this assumption is not true in all cases, so it is possible that these packets leave the system without the necessary transformations. This pull request contains two patches to fix this issue: 1) Fix for blackhole routed packets. 2) Fix for queue routed packets. Both patches are serious stable candidates. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 09f3756 + b8c203b commit 84de67b

File tree

4 files changed

+60
-14
lines changed

4 files changed

+60
-14
lines changed

include/net/dst.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ void dst_init(void);
480480
/* Flags for xfrm_lookup flags argument. */
481481
enum {
482482
XFRM_LOOKUP_ICMP = 1 << 0,
483+
XFRM_LOOKUP_QUEUE = 1 << 1,
483484
};
484485

485486
struct flowi;
@@ -490,7 +491,16 @@ static inline struct dst_entry *xfrm_lookup(struct net *net,
490491
int flags)
491492
{
492493
return dst_orig;
493-
}
494+
}
495+
496+
static inline struct dst_entry *xfrm_lookup_route(struct net *net,
497+
struct dst_entry *dst_orig,
498+
const struct flowi *fl,
499+
struct sock *sk,
500+
int flags)
501+
{
502+
return dst_orig;
503+
}
494504

495505
static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
496506
{
@@ -502,6 +512,10 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
502512
const struct flowi *fl, struct sock *sk,
503513
int flags);
504514

515+
struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
516+
const struct flowi *fl, struct sock *sk,
517+
int flags);
518+
505519
/* skb attached with this dst needs transformation if dst->xfrm is valid */
506520
static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
507521
{

net/ipv4/route.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,9 +2265,9 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
22652265
return rt;
22662266

22672267
if (flp4->flowi4_proto)
2268-
rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
2269-
flowi4_to_flowi(flp4),
2270-
sk, 0);
2268+
rt = (struct rtable *)xfrm_lookup_route(net, &rt->dst,
2269+
flowi4_to_flowi(flp4),
2270+
sk, 0);
22712271

22722272
return rt;
22732273
}

net/ipv6/ip6_output.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
10091009
if (final_dst)
10101010
fl6->daddr = *final_dst;
10111011

1012-
return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1012+
return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
10131013
}
10141014
EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
10151015

@@ -1041,7 +1041,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
10411041
if (final_dst)
10421042
fl6->daddr = *final_dst;
10431043

1044-
return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1044+
return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
10451045
}
10461046
EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
10471047

net/xfrm/xfrm_policy.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
4040
#define XFRM_MAX_QUEUE_LEN 100
4141

42+
struct xfrm_flo {
43+
struct dst_entry *dst_orig;
44+
u8 flags;
45+
};
46+
4247
static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock);
4348
static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO]
4449
__read_mostly;
@@ -1877,23 +1882,27 @@ static int xdst_queue_output(struct sock *sk, struct sk_buff *skb)
18771882
}
18781883

18791884
static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
1880-
struct dst_entry *dst,
1885+
struct xfrm_flo *xflo,
18811886
const struct flowi *fl,
18821887
int num_xfrms,
18831888
u16 family)
18841889
{
18851890
int err;
18861891
struct net_device *dev;
1892+
struct dst_entry *dst;
18871893
struct dst_entry *dst1;
18881894
struct xfrm_dst *xdst;
18891895

18901896
xdst = xfrm_alloc_dst(net, family);
18911897
if (IS_ERR(xdst))
18921898
return xdst;
18931899

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)
18951903
return xdst;
18961904

1905+
dst = xflo->dst_orig;
18971906
dst1 = &xdst->u.dst;
18981907
dst_hold(dst);
18991908
xdst->route = dst;
@@ -1935,7 +1944,7 @@ static struct flow_cache_object *
19351944
xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
19361945
struct flow_cache_object *oldflo, void *ctx)
19371946
{
1938-
struct dst_entry *dst_orig = (struct dst_entry *)ctx;
1947+
struct xfrm_flo *xflo = (struct xfrm_flo *)ctx;
19391948
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
19401949
struct xfrm_dst *xdst, *new_xdst;
19411950
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,
19761985
goto make_dummy_bundle;
19771986
}
19781987

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);
19801990
if (IS_ERR(new_xdst)) {
19811991
err = PTR_ERR(new_xdst);
19821992
if (err != -EAGAIN)
@@ -2010,7 +2020,7 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
20102020
/* We found policies, but there's no bundles to instantiate:
20112021
* either because the policy blocks, has no transformations or
20122022
* 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);
20142024
if (IS_ERR(xdst)) {
20152025
xfrm_pols_put(pols, num_pols);
20162026
return ERR_CAST(xdst);
@@ -2104,13 +2114,18 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
21042114
}
21052115

21062116
if (xdst == NULL) {
2117+
struct xfrm_flo xflo;
2118+
2119+
xflo.dst_orig = dst_orig;
2120+
xflo.flags = flags;
2121+
21072122
/* To accelerate a bit... */
21082123
if ((dst_orig->flags & DST_NOXFRM) ||
21092124
!net->xfrm.policy_count[XFRM_POLICY_OUT])
21102125
goto nopol;
21112126

21122127
flo = flow_cache_lookup(net, fl, family, dir,
2113-
xfrm_bundle_lookup, dst_orig);
2128+
xfrm_bundle_lookup, &xflo);
21142129
if (flo == NULL)
21152130
goto nopol;
21162131
if (IS_ERR(flo)) {
@@ -2138,7 +2153,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
21382153
xfrm_pols_put(pols, drop_pols);
21392154
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
21402155

2141-
return make_blackhole(net, family, dst_orig);
2156+
return ERR_PTR(-EREMOTE);
21422157
}
21432158

21442159
err = -EAGAIN;
@@ -2195,6 +2210,23 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
21952210
}
21962211
EXPORT_SYMBOL(xfrm_lookup);
21972212

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+
21982230
static inline int
21992231
xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl)
22002232
{
@@ -2460,7 +2492,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
24602492

24612493
skb_dst_force(skb);
24622494

2463-
dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, 0);
2495+
dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, XFRM_LOOKUP_QUEUE);
24642496
if (IS_ERR(dst)) {
24652497
res = 0;
24662498
dst = NULL;

0 commit comments

Comments
 (0)