Skip to content

Commit 0f6c480

Browse files
committed
xfrm: Move dst->path into struct xfrm_dst
The first member of an IPSEC route bundle chain sets it's dst->path to the underlying ipv4/ipv6 route that carries the bundle. Stated another way, if one were to follow the xfrm_dst->child chain of the bundle, the final non-NULL pointer would be the path and point to either an ipv4 or an ipv6 route. This is largely used to make sure that PMTU events propagate down to the correct ipv4 or ipv6 route. When we don't have the top of an IPSEC bundle 'dst->path == dst'. Move it down into xfrm_dst and key off of dst->xfrm. Signed-off-by: David S. Miller <[email protected]> Reviewed-by: Eric Dumazet <[email protected]>
1 parent 3a2232e commit 0f6c480

File tree

9 files changed

+33
-29
lines changed

9 files changed

+33
-29
lines changed

include/net/dst.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ struct dst_entry {
3838
struct dst_ops *ops;
3939
unsigned long _metrics;
4040
unsigned long expires;
41-
struct dst_entry *path;
4241
#ifdef CONFIG_XFRM
4342
struct xfrm_state *xfrm;
4443
#else
@@ -87,7 +86,7 @@ struct dst_entry {
8786
* Align __refcnt to a 64 bytes alignment
8887
* (L1_CACHE_SIZE would be too much)
8988
*/
90-
long __pad_to_align_refcnt[4];
89+
long __pad_to_align_refcnt[5];
9190
#endif
9291
/*
9392
* __refcnt wants to be on a different cache line from

include/net/xfrm.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ struct xfrm_dst {
985985
} u;
986986
struct dst_entry *route;
987987
struct dst_entry *child;
988+
struct dst_entry *path;
988989
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
989990
int num_pols, num_xfrms;
990991
u32 xfrm_genid;
@@ -995,6 +996,18 @@ struct xfrm_dst {
995996
u32 path_cookie;
996997
};
997998

999+
static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
1000+
{
1001+
#ifdef CONFIG_XFRM
1002+
if (dst->xfrm) {
1003+
const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
1004+
1005+
return xdst->path;
1006+
}
1007+
#endif
1008+
return (struct dst_entry *) dst;
1009+
}
1010+
9981011
static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
9991012
{
10001013
#ifdef CONFIG_XFRM
@@ -1889,7 +1902,7 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
18891902
return false;
18901903

18911904
xdst = (struct xfrm_dst *) dst;
1892-
if (x->xso.offload_handle && (x->xso.dev == dst->path->dev) &&
1905+
if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
18931906
!xdst->child->xfrm)
18941907
return true;
18951908

net/bridge/br_nf_core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ void br_netfilter_rtable_init(struct net_bridge *br)
7878

7979
atomic_set(&rt->dst.__refcnt, 1);
8080
rt->dst.dev = br->dev;
81-
rt->dst.path = &rt->dst;
8281
dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
8382
rt->dst.flags = DST_NOXFRM | DST_FAKE_RTABLE;
8483
rt->dst.ops = &fake_dst_ops;

net/core/dst.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
6969
dst->ops = ops;
7070
dst_init_metrics(dst, dst_default_metrics.metrics, true);
7171
dst->expires = 0UL;
72-
dst->path = dst;
7372
#ifdef CONFIG_XFRM
7473
dst->xfrm = NULL;
7574
#endif

net/ipv4/route.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
11061106
new = true;
11071107
}
11081108

1109-
__ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu);
1109+
__ip_rt_update_pmtu((struct rtable *) xfrm_dst_path(&rt->dst), &fl4, mtu);
11101110

11111111
if (!dst_check(&rt->dst, 0)) {
11121112
if (new)

net/ipv6/ip6_output.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,13 +1201,13 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
12011201
rt->dst.dev->mtu : dst_mtu(&rt->dst);
12021202
else
12031203
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1204-
rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1204+
rt->dst.dev->mtu : dst_mtu(xfrm_dst_path(&rt->dst));
12051205
if (np->frag_size < mtu) {
12061206
if (np->frag_size)
12071207
mtu = np->frag_size;
12081208
}
12091209
cork->base.fragsize = mtu;
1210-
if (dst_allfrag(rt->dst.path))
1210+
if (dst_allfrag(xfrm_dst_path(&rt->dst)))
12111211
cork->base.flags |= IPCORK_ALLFRAG;
12121212
cork->base.length = 0;
12131213

net/ipv6/route.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4596,8 +4596,6 @@ static int __net_init ip6_route_net_init(struct net *net)
45964596
GFP_KERNEL);
45974597
if (!net->ipv6.ip6_null_entry)
45984598
goto out_ip6_dst_entries;
4599-
net->ipv6.ip6_null_entry->dst.path =
4600-
(struct dst_entry *)net->ipv6.ip6_null_entry;
46014599
net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
46024600
dst_init_metrics(&net->ipv6.ip6_null_entry->dst,
46034601
ip6_template_metrics, true);
@@ -4609,8 +4607,6 @@ static int __net_init ip6_route_net_init(struct net *net)
46094607
GFP_KERNEL);
46104608
if (!net->ipv6.ip6_prohibit_entry)
46114609
goto out_ip6_null_entry;
4612-
net->ipv6.ip6_prohibit_entry->dst.path =
4613-
(struct dst_entry *)net->ipv6.ip6_prohibit_entry;
46144610
net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
46154611
dst_init_metrics(&net->ipv6.ip6_prohibit_entry->dst,
46164612
ip6_template_metrics, true);
@@ -4620,8 +4616,6 @@ static int __net_init ip6_route_net_init(struct net *net)
46204616
GFP_KERNEL);
46214617
if (!net->ipv6.ip6_blk_hole_entry)
46224618
goto out_ip6_prohibit_entry;
4623-
net->ipv6.ip6_blk_hole_entry->dst.path =
4624-
(struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
46254619
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
46264620
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
46274621
ip6_template_metrics, true);

net/xfrm/xfrm_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
120120
if (!x->type_offload || x->encap)
121121
return false;
122122

123-
if ((x->xso.offload_handle && (dev == dst->path->dev)) &&
123+
if ((x->xso.offload_handle && (dev == xfrm_dst_path(dst)->dev)) &&
124124
!xdst->child->xfrm && x->type->get_mtu) {
125125
mtu = x->type->get_mtu(x, xdst->child_mtu_cached);
126126

net/xfrm/xfrm_policy.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
16261626
}
16271627

16281628
xfrm_dst_set_child(xdst_prev, dst);
1629-
xdst0->u.dst.path = dst;
1629+
xdst0->path = dst;
16301630

16311631
err = -ENODEV;
16321632
dev = dst->dev;
@@ -1879,8 +1879,8 @@ static void xfrm_policy_queue_process(struct timer_list *t)
18791879
xfrm_decode_session(skb, &fl, dst->ops->family);
18801880
spin_unlock(&pq->hold_queue.lock);
18811881

1882-
dst_hold(dst->path);
1883-
dst = xfrm_lookup(net, dst->path, &fl, sk, 0);
1882+
dst_hold(xfrm_dst_path(dst));
1883+
dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, 0);
18841884
if (IS_ERR(dst))
18851885
goto purge_queue;
18861886

@@ -1909,8 +1909,8 @@ static void xfrm_policy_queue_process(struct timer_list *t)
19091909
skb = __skb_dequeue(&list);
19101910

19111911
xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
1912-
dst_hold(skb_dst(skb)->path);
1913-
dst = xfrm_lookup(net, skb_dst(skb)->path, &fl, skb->sk, 0);
1912+
dst_hold(xfrm_dst_path(skb_dst(skb)));
1913+
dst = xfrm_lookup(net, xfrm_dst_path(skb_dst(skb)), &fl, skb->sk, 0);
19141914
if (IS_ERR(dst)) {
19151915
kfree_skb(skb);
19161916
continue;
@@ -2012,7 +2012,7 @@ static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
20122012

20132013
dst_hold(dst);
20142014
xfrm_dst_set_child(xdst, dst);
2015-
dst1->path = dst;
2015+
xdst->path = dst;
20162016

20172017
xfrm_init_path((struct xfrm_dst *)dst1, dst, 0);
20182018

@@ -2630,7 +2630,7 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
26302630
struct xfrm_dst *last;
26312631
u32 mtu;
26322632

2633-
if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) ||
2633+
if (!dst_check(xfrm_dst_path(dst), ((struct xfrm_dst *)dst)->path_cookie) ||
26342634
(dst->dev && !netif_running(dst->dev)))
26352635
return 0;
26362636

@@ -2691,22 +2691,20 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
26912691

26922692
static unsigned int xfrm_default_advmss(const struct dst_entry *dst)
26932693
{
2694-
return dst_metric_advmss(dst->path);
2694+
return dst_metric_advmss(xfrm_dst_path(dst));
26952695
}
26962696

26972697
static unsigned int xfrm_mtu(const struct dst_entry *dst)
26982698
{
26992699
unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
27002700

2701-
return mtu ? : dst_mtu(dst->path);
2701+
return mtu ? : dst_mtu(xfrm_dst_path(dst));
27022702
}
27032703

27042704
static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
27052705
const void *daddr)
27062706
{
2707-
const struct dst_entry *path = dst->path;
2708-
2709-
for (; dst != path; dst = xfrm_dst_child(dst)) {
2707+
while (dst->xfrm) {
27102708
const struct xfrm_state *xfrm = dst->xfrm;
27112709

27122710
if (xfrm->props.mode == XFRM_MODE_TRANSPORT)
@@ -2715,6 +2713,8 @@ static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
27152713
daddr = xfrm->coaddr;
27162714
else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR))
27172715
daddr = &xfrm->id.daddr;
2716+
2717+
dst = xfrm_dst_child(dst);
27182718
}
27192719
return daddr;
27202720
}
@@ -2723,7 +2723,7 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
27232723
struct sk_buff *skb,
27242724
const void *daddr)
27252725
{
2726-
const struct dst_entry *path = dst->path;
2726+
const struct dst_entry *path = xfrm_dst_path(dst);
27272727

27282728
if (!skb)
27292729
daddr = xfrm_get_dst_nexthop(dst, daddr);
@@ -2732,7 +2732,7 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
27322732

27332733
static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr)
27342734
{
2735-
const struct dst_entry *path = dst->path;
2735+
const struct dst_entry *path = xfrm_dst_path(dst);
27362736

27372737
daddr = xfrm_get_dst_nexthop(dst, daddr);
27382738
path->ops->confirm_neigh(path, daddr);

0 commit comments

Comments
 (0)