Skip to content

Commit 2774c13

Browse files
committed
xfrm: Handle blackhole route creation via afinfo.
That way we don't have to potentially do this in every xfrm_lookup() caller. Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 69ead7a commit 2774c13

File tree

10 files changed

+50
-67
lines changed

10 files changed

+50
-67
lines changed

include/net/dst.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -432,17 +432,9 @@ static inline int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
432432
{
433433
return 0;
434434
}
435-
static inline int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
436-
const struct flowi *fl, struct sock *sk,
437-
int flags)
438-
{
439-
return 0;
440-
}
441435
#else
442436
extern int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
443437
const struct flowi *fl, struct sock *sk, int flags);
444-
extern int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
445-
const struct flowi *fl, struct sock *sk, int flags);
446438
#endif
447439
#endif
448440

include/net/ipv6.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,8 @@ extern struct dst_entry * ip6_sk_dst_lookup_flow(struct sock *sk,
520520
struct flowi *fl,
521521
const struct in6_addr *final_dst,
522522
bool can_sleep);
523-
extern struct dst_entry * ip6_dst_blackhole(struct net *net,
524-
struct dst_entry *orig_dst);
523+
extern struct dst_entry * ip6_blackhole_route(struct net *net,
524+
struct dst_entry *orig_dst);
525525

526526
/*
527527
* skb processing functions

include/net/route.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ extern void rt_cache_flush_batch(struct net *net);
121121
extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);
122122
extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
123123
extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk);
124+
extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig);
124125

125126
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
126127
u8 tos, struct net_device *devin, bool noref);

include/net/xfrm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ struct xfrm_policy_afinfo {
280280
int (*fill_dst)(struct xfrm_dst *xdst,
281281
struct net_device *dev,
282282
const struct flowi *fl);
283+
struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
283284
};
284285

285286
extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);

net/ipv4/route.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2675,12 +2675,10 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
26752675
.update_pmtu = ipv4_rt_blackhole_update_pmtu,
26762676
};
26772677

2678-
2679-
static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi *flp)
2678+
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
26802679
{
2681-
struct rtable *ort = *rp;
2682-
struct rtable *rt = (struct rtable *)
2683-
dst_alloc(&ipv4_dst_blackhole_ops, 1);
2680+
struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, 1);
2681+
struct rtable *ort = (struct rtable *) dst_orig;
26842682

26852683
if (rt) {
26862684
struct dst_entry *new = &rt->dst;
@@ -2714,9 +2712,9 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi
27142712
dst_free(new);
27152713
}
27162714

2717-
dst_release(&(*rp)->dst);
2718-
*rp = rt;
2719-
return rt ? 0 : -ENOMEM;
2715+
dst_release(dst_orig);
2716+
2717+
return rt ? &rt->dst : ERR_PTR(-ENOMEM);
27202718
}
27212719

27222720
int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp,
@@ -2732,11 +2730,7 @@ int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp,
27322730
flp->fl4_src = (*rp)->rt_src;
27332731
if (!flp->fl4_dst)
27342732
flp->fl4_dst = (*rp)->rt_dst;
2735-
err = __xfrm_lookup(net, (struct dst_entry **)rp, flp, sk, 0);
2736-
if (err == -EREMOTE)
2737-
err = ipv4_dst_blackhole(net, rp, flp);
2738-
2739-
return err;
2733+
return xfrm_lookup(net, (struct dst_entry **)rp, flp, sk, 0);
27402734
}
27412735

27422736
return 0;

net/ipv4/xfrm4_policy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
234234
.get_tos = xfrm4_get_tos,
235235
.init_path = xfrm4_init_path,
236236
.fill_dst = xfrm4_fill_dst,
237+
.blackhole_route = ipv4_blackhole_route,
237238
};
238239

239240
#ifdef CONFIG_SYSCTL

net/ipv6/ip6_output.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,18 +1025,12 @@ struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi *fl,
10251025
return ERR_PTR(err);
10261026
if (final_dst)
10271027
ipv6_addr_copy(&fl->fl6_dst, final_dst);
1028-
if (can_sleep) {
1028+
if (can_sleep)
10291029
fl->flags |= FLOWI_FLAG_CAN_SLEEP;
1030-
err = __xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1031-
if (err == -EREMOTE)
1032-
return ip6_dst_blackhole(sock_net(sk), dst);
1033-
if (err)
1034-
return ERR_PTR(err);
1035-
} else {
1036-
err = xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1037-
if (err)
1038-
return ERR_PTR(err);
1039-
}
1030+
1031+
err = xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1032+
if (err)
1033+
return ERR_PTR(err);
10401034
return dst;
10411035
}
10421036
EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
@@ -1070,18 +1064,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi *fl,
10701064
return ERR_PTR(err);
10711065
if (final_dst)
10721066
ipv6_addr_copy(&fl->fl6_dst, final_dst);
1073-
if (can_sleep) {
1067+
if (can_sleep)
10741068
fl->flags |= FLOWI_FLAG_CAN_SLEEP;
1075-
err = __xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1076-
if (err == -EREMOTE)
1077-
return ip6_dst_blackhole(sock_net(sk), dst);
1078-
if (err)
1079-
return ERR_PTR(err);
1080-
} else {
1081-
err = xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1082-
if (err)
1083-
return ERR_PTR(err);
1084-
}
1069+
1070+
err = xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1071+
if (err)
1072+
return ERR_PTR(err);
10851073
return dst;
10861074
}
10871075
EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);

net/ipv6/route.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
870870

871871
EXPORT_SYMBOL(ip6_route_output);
872872

873-
struct dst_entry *ip6_dst_blackhole(struct net *net, struct dst_entry *dst_orig)
873+
struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
874874
{
875875
struct rt6_info *rt = dst_alloc(&ip6_dst_blackhole_ops, 1);
876876
struct rt6_info *ort = (struct rt6_info *) dst_orig;
@@ -907,7 +907,6 @@ struct dst_entry *ip6_dst_blackhole(struct net *net, struct dst_entry *dst_orig)
907907
dst_release(dst_orig);
908908
return new ? new : ERR_PTR(-ENOMEM);
909909
}
910-
EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
911910

912911
/*
913912
* Destination cache support functions

net/ipv6/xfrm6_policy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
274274
.get_tos = xfrm6_get_tos,
275275
.init_path = xfrm6_init_path,
276276
.fill_dst = xfrm6_fill_dst,
277+
.blackhole_route = ip6_blackhole_route,
277278
};
278279

279280
static int __init xfrm6_policy_init(void)

net/xfrm/xfrm_policy.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,14 +1735,31 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
17351735
return ERR_PTR(err);
17361736
}
17371737

1738+
static struct dst_entry *make_blackhole(struct net *net, u16 family,
1739+
struct dst_entry *dst_orig)
1740+
{
1741+
struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
1742+
struct dst_entry *ret;
1743+
1744+
if (!afinfo) {
1745+
dst_release(dst_orig);
1746+
ret = ERR_PTR(-EINVAL);
1747+
} else {
1748+
ret = afinfo->blackhole_route(net, dst_orig);
1749+
}
1750+
xfrm_policy_put_afinfo(afinfo);
1751+
1752+
return ret;
1753+
}
1754+
17381755
/* Main function: finds/creates a bundle for given flow.
17391756
*
17401757
* At the moment we eat a raw IP route. Mostly to speed up lookups
17411758
* on interfaces with disabled IPsec.
17421759
*/
1743-
int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
1744-
const struct flowi *fl,
1745-
struct sock *sk, int flags)
1760+
int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
1761+
const struct flowi *fl,
1762+
struct sock *sk, int flags)
17461763
{
17471764
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
17481765
struct flow_cache_object *flo;
@@ -1829,7 +1846,12 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
18291846
dst_release(dst);
18301847
xfrm_pols_put(pols, drop_pols);
18311848
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
1832-
return -EREMOTE;
1849+
1850+
dst = make_blackhole(net, family, dst_orig);
1851+
if (IS_ERR(dst))
1852+
return PTR_ERR(dst);
1853+
*dst_p = dst;
1854+
return 0;
18331855
}
18341856
if (fl->flags & FLOWI_FLAG_CAN_SLEEP) {
18351857
DECLARE_WAITQUEUE(wait, current);
@@ -1895,22 +1917,6 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
18951917
xfrm_pols_put(pols, drop_pols);
18961918
return err;
18971919
}
1898-
EXPORT_SYMBOL(__xfrm_lookup);
1899-
1900-
int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
1901-
const struct flowi *fl,
1902-
struct sock *sk, int flags)
1903-
{
1904-
int err = __xfrm_lookup(net, dst_p, fl, sk, flags);
1905-
1906-
if (err == -EREMOTE) {
1907-
dst_release(*dst_p);
1908-
*dst_p = NULL;
1909-
err = -EAGAIN;
1910-
}
1911-
1912-
return err;
1913-
}
19141920
EXPORT_SYMBOL(xfrm_lookup);
19151921

19161922
static inline int

0 commit comments

Comments
 (0)