Skip to content

Commit 3a2232e

Browse files
committed
ipv6: Move dst->from into struct rt6_info.
The dst->from value is only used by ipv6 routes to track where a route "came from". Any time we clone or copy a core ipv6 route in the ipv6 routing tables, we have the copy/clone's ->from point to the base route. This is used to handle route expiration properly. Only ipv6 uses this mechanism, and only ipv6 code references it. So it is safe to move it into rt6_info. Signed-off-by: David S. Miller <[email protected]> Reviewed-by: Eric Dumazet <[email protected]>
1 parent b6ca8bd commit 3a2232e

File tree

4 files changed

+22
-25
lines changed

4 files changed

+22
-25
lines changed

include/net/dst.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ struct dst_entry {
3939
unsigned long _metrics;
4040
unsigned long expires;
4141
struct dst_entry *path;
42-
struct dst_entry *from;
4342
#ifdef CONFIG_XFRM
4443
struct xfrm_state *xfrm;
4544
#else
@@ -88,7 +87,7 @@ struct dst_entry {
8887
* Align __refcnt to a 64 bytes alignment
8988
* (L1_CACHE_SIZE would be too much)
9089
*/
91-
long __pad_to_align_refcnt[3];
90+
long __pad_to_align_refcnt[4];
9291
#endif
9392
/*
9493
* __refcnt wants to be on a different cache line from

include/net/ip6_fib.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ struct rt6_exception {
130130
struct rt6_info {
131131
struct dst_entry dst;
132132
struct rt6_info __rcu *rt6_next;
133+
struct rt6_info *from;
133134

134135
/*
135136
* Tail elements of dst_entry (__refcnt etc.)
@@ -204,11 +205,9 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
204205
{
205206
struct rt6_info *rt;
206207

207-
for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES);
208-
rt = (struct rt6_info *)rt->dst.from);
208+
for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from);
209209
if (rt && rt != rt0)
210210
rt0->dst.expires = rt->dst.expires;
211-
212211
dst_set_expires(&rt0->dst, timeout);
213212
rt0->rt6i_flags |= RTF_EXPIRES;
214213
}
@@ -243,8 +242,8 @@ static inline u32 rt6_get_cookie(const struct rt6_info *rt)
243242
u32 cookie = 0;
244243

245244
if (rt->rt6i_flags & RTF_PCPU ||
246-
(unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from))
247-
rt = (struct rt6_info *)(rt->dst.from);
245+
(unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
246+
rt = rt->from;
248247

249248
rt6_get_cookie_safe(rt, &cookie);
250249

net/core/dst.c

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

net/ipv6/route.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
186186

187187
static u32 *rt6_pcpu_cow_metrics(struct rt6_info *rt)
188188
{
189-
return dst_metrics_write_ptr(rt->dst.from);
189+
return dst_metrics_write_ptr(&rt->from->dst);
190190
}
191191

192192
static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
@@ -391,7 +391,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)
391391
{
392392
struct rt6_info *rt = (struct rt6_info *)dst;
393393
struct rt6_exception_bucket *bucket;
394-
struct dst_entry *from = dst->from;
394+
struct rt6_info *from = rt->from;
395395
struct inet6_dev *idev;
396396

397397
dst_destroy_metrics_generic(dst);
@@ -409,8 +409,8 @@ static void ip6_dst_destroy(struct dst_entry *dst)
409409
kfree(bucket);
410410
}
411411

412-
dst->from = NULL;
413-
dst_release(from);
412+
rt->from = NULL;
413+
dst_release(&from->dst);
414414
}
415415

416416
static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@ -443,9 +443,9 @@ static bool rt6_check_expired(const struct rt6_info *rt)
443443
if (rt->rt6i_flags & RTF_EXPIRES) {
444444
if (time_after(jiffies, rt->dst.expires))
445445
return true;
446-
} else if (rt->dst.from) {
446+
} else if (rt->from) {
447447
return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK ||
448-
rt6_check_expired((struct rt6_info *)rt->dst.from);
448+
rt6_check_expired(rt->from);
449449
}
450450
return false;
451451
}
@@ -1054,7 +1054,7 @@ static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort,
10541054
*/
10551055

10561056
if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
1057-
ort = (struct rt6_info *)ort->dst.from;
1057+
ort = ort->from;
10581058

10591059
rcu_read_lock();
10601060
dev = ip6_rt_get_dev_rcu(ort);
@@ -1274,7 +1274,7 @@ static int rt6_insert_exception(struct rt6_info *nrt,
12741274

12751275
/* ort can't be a cache or pcpu route */
12761276
if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
1277-
ort = (struct rt6_info *)ort->dst.from;
1277+
ort = ort->from;
12781278
WARN_ON_ONCE(ort->rt6i_flags & (RTF_CACHE | RTF_PCPU));
12791279

12801280
spin_lock_bh(&rt6_exception_lock);
@@ -1415,8 +1415,8 @@ static struct rt6_info *rt6_find_cached_rt(struct rt6_info *rt,
14151415
/* Remove the passed in cached rt from the hash table that contains it */
14161416
int rt6_remove_exception_rt(struct rt6_info *rt)
14171417
{
1418-
struct rt6_info *from = (struct rt6_info *)rt->dst.from;
14191418
struct rt6_exception_bucket *bucket;
1419+
struct rt6_info *from = rt->from;
14201420
struct in6_addr *src_key = NULL;
14211421
struct rt6_exception *rt6_ex;
14221422
int err;
@@ -1460,8 +1460,8 @@ int rt6_remove_exception_rt(struct rt6_info *rt)
14601460
*/
14611461
static void rt6_update_exception_stamp_rt(struct rt6_info *rt)
14621462
{
1463-
struct rt6_info *from = (struct rt6_info *)rt->dst.from;
14641463
struct rt6_exception_bucket *bucket;
1464+
struct rt6_info *from = rt->from;
14651465
struct in6_addr *src_key = NULL;
14661466
struct rt6_exception *rt6_ex;
14671467

@@ -1929,9 +1929,9 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
19291929

19301930
static void rt6_dst_from_metrics_check(struct rt6_info *rt)
19311931
{
1932-
if (rt->dst.from &&
1933-
dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(rt->dst.from))
1934-
dst_init_metrics(&rt->dst, dst_metrics_ptr(rt->dst.from), true);
1932+
if (rt->from &&
1933+
dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(&rt->from->dst))
1934+
dst_init_metrics(&rt->dst, dst_metrics_ptr(&rt->from->dst), true);
19351935
}
19361936

19371937
static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie)
@@ -1951,7 +1951,7 @@ static struct dst_entry *rt6_dst_from_check(struct rt6_info *rt, u32 cookie)
19511951
{
19521952
if (!__rt6_check_expired(rt) &&
19531953
rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
1954-
rt6_check((struct rt6_info *)(rt->dst.from), cookie))
1954+
rt6_check(rt->from, cookie))
19551955
return &rt->dst;
19561956
else
19571957
return NULL;
@@ -1971,7 +1971,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
19711971
rt6_dst_from_metrics_check(rt);
19721972

19731973
if (rt->rt6i_flags & RTF_PCPU ||
1974-
(unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from))
1974+
(unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
19751975
return rt6_dst_from_check(rt, cookie);
19761976
else
19771977
return rt6_check(rt, cookie);
@@ -3055,11 +3055,11 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
30553055

30563056
static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
30573057
{
3058-
BUG_ON(from->dst.from);
3058+
BUG_ON(from->from);
30593059

30603060
rt->rt6i_flags &= ~RTF_EXPIRES;
30613061
dst_hold(&from->dst);
3062-
rt->dst.from = &from->dst;
3062+
rt->from = from;
30633063
dst_init_metrics(&rt->dst, dst_metrics_ptr(&from->dst), true);
30643064
}
30653065

0 commit comments

Comments
 (0)