summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/dst.h3
-rw-r--r--include/net/ip6_fib.h9
-rw-r--r--net/core/dst.c1
-rw-r--r--net/ipv6/route.c34
4 files changed, 22 insertions, 25 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index cef46207408c..13c839d8235a 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -39,7 +39,6 @@ struct dst_entry {
39 unsigned long _metrics; 39 unsigned long _metrics;
40 unsigned long expires; 40 unsigned long expires;
41 struct dst_entry *path; 41 struct dst_entry *path;
42 struct dst_entry *from;
43#ifdef CONFIG_XFRM 42#ifdef CONFIG_XFRM
44 struct xfrm_state *xfrm; 43 struct xfrm_state *xfrm;
45#else 44#else
@@ -88,7 +87,7 @@ struct dst_entry {
88 * Align __refcnt to a 64 bytes alignment 87 * Align __refcnt to a 64 bytes alignment
89 * (L1_CACHE_SIZE would be too much) 88 * (L1_CACHE_SIZE would be too much)
90 */ 89 */
91 long __pad_to_align_refcnt[3]; 90 long __pad_to_align_refcnt[4];
92#endif 91#endif
93 /* 92 /*
94 * __refcnt wants to be on a different cache line from 93 * __refcnt wants to be on a different cache line from
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 281a922f0c62..44d96a91e745 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -130,6 +130,7 @@ struct rt6_exception {
130struct rt6_info { 130struct rt6_info {
131 struct dst_entry dst; 131 struct dst_entry dst;
132 struct rt6_info __rcu *rt6_next; 132 struct rt6_info __rcu *rt6_next;
133 struct rt6_info *from;
133 134
134 /* 135 /*
135 * Tail elements of dst_entry (__refcnt etc.) 136 * Tail elements of dst_entry (__refcnt etc.)
@@ -204,11 +205,9 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
204{ 205{
205 struct rt6_info *rt; 206 struct rt6_info *rt;
206 207
207 for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); 208 for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from);
208 rt = (struct rt6_info *)rt->dst.from);
209 if (rt && rt != rt0) 209 if (rt && rt != rt0)
210 rt0->dst.expires = rt->dst.expires; 210 rt0->dst.expires = rt->dst.expires;
211
212 dst_set_expires(&rt0->dst, timeout); 211 dst_set_expires(&rt0->dst, timeout);
213 rt0->rt6i_flags |= RTF_EXPIRES; 212 rt0->rt6i_flags |= RTF_EXPIRES;
214} 213}
@@ -243,8 +242,8 @@ static inline u32 rt6_get_cookie(const struct rt6_info *rt)
243 u32 cookie = 0; 242 u32 cookie = 0;
244 243
245 if (rt->rt6i_flags & RTF_PCPU || 244 if (rt->rt6i_flags & RTF_PCPU ||
246 (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from)) 245 (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
247 rt = (struct rt6_info *)(rt->dst.from); 246 rt = rt->from;
248 247
249 rt6_get_cookie_safe(rt, &cookie); 248 rt6_get_cookie_safe(rt, &cookie);
250 249
diff --git a/net/core/dst.c b/net/core/dst.c
index 5cf96179e8e0..cf2076c0eb22 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -70,7 +70,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
70 dst_init_metrics(dst, dst_default_metrics.metrics, true); 70 dst_init_metrics(dst, dst_default_metrics.metrics, true);
71 dst->expires = 0UL; 71 dst->expires = 0UL;
72 dst->path = dst; 72 dst->path = dst;
73 dst->from = NULL;
74#ifdef CONFIG_XFRM 73#ifdef CONFIG_XFRM
75 dst->xfrm = NULL; 74 dst->xfrm = NULL;
76#endif 75#endif
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 22c5e70361d6..1f1ef1e071c2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -186,7 +186,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
186 186
187static u32 *rt6_pcpu_cow_metrics(struct rt6_info *rt) 187static u32 *rt6_pcpu_cow_metrics(struct rt6_info *rt)
188{ 188{
189 return dst_metrics_write_ptr(rt->dst.from); 189 return dst_metrics_write_ptr(&rt->from->dst);
190} 190}
191 191
192static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old) 192static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
@@ -391,7 +391,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)
391{ 391{
392 struct rt6_info *rt = (struct rt6_info *)dst; 392 struct rt6_info *rt = (struct rt6_info *)dst;
393 struct rt6_exception_bucket *bucket; 393 struct rt6_exception_bucket *bucket;
394 struct dst_entry *from = dst->from; 394 struct rt6_info *from = rt->from;
395 struct inet6_dev *idev; 395 struct inet6_dev *idev;
396 396
397 dst_destroy_metrics_generic(dst); 397 dst_destroy_metrics_generic(dst);
@@ -409,8 +409,8 @@ static void ip6_dst_destroy(struct dst_entry *dst)
409 kfree(bucket); 409 kfree(bucket);
410 } 410 }
411 411
412 dst->from = NULL; 412 rt->from = NULL;
413 dst_release(from); 413 dst_release(&from->dst);
414} 414}
415 415
416static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 416static 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)
443 if (rt->rt6i_flags & RTF_EXPIRES) { 443 if (rt->rt6i_flags & RTF_EXPIRES) {
444 if (time_after(jiffies, rt->dst.expires)) 444 if (time_after(jiffies, rt->dst.expires))
445 return true; 445 return true;
446 } else if (rt->dst.from) { 446 } else if (rt->from) {
447 return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK || 447 return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK ||
448 rt6_check_expired((struct rt6_info *)rt->dst.from); 448 rt6_check_expired(rt->from);
449 } 449 }
450 return false; 450 return false;
451} 451}
@@ -1054,7 +1054,7 @@ static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort,
1054 */ 1054 */
1055 1055
1056 if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU)) 1056 if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
1057 ort = (struct rt6_info *)ort->dst.from; 1057 ort = ort->from;
1058 1058
1059 rcu_read_lock(); 1059 rcu_read_lock();
1060 dev = ip6_rt_get_dev_rcu(ort); 1060 dev = ip6_rt_get_dev_rcu(ort);
@@ -1274,7 +1274,7 @@ static int rt6_insert_exception(struct rt6_info *nrt,
1274 1274
1275 /* ort can't be a cache or pcpu route */ 1275 /* ort can't be a cache or pcpu route */
1276 if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU)) 1276 if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
1277 ort = (struct rt6_info *)ort->dst.from; 1277 ort = ort->from;
1278 WARN_ON_ONCE(ort->rt6i_flags & (RTF_CACHE | RTF_PCPU)); 1278 WARN_ON_ONCE(ort->rt6i_flags & (RTF_CACHE | RTF_PCPU));
1279 1279
1280 spin_lock_bh(&rt6_exception_lock); 1280 spin_lock_bh(&rt6_exception_lock);
@@ -1415,8 +1415,8 @@ static struct rt6_info *rt6_find_cached_rt(struct rt6_info *rt,
1415/* Remove the passed in cached rt from the hash table that contains it */ 1415/* Remove the passed in cached rt from the hash table that contains it */
1416int rt6_remove_exception_rt(struct rt6_info *rt) 1416int rt6_remove_exception_rt(struct rt6_info *rt)
1417{ 1417{
1418 struct rt6_info *from = (struct rt6_info *)rt->dst.from;
1419 struct rt6_exception_bucket *bucket; 1418 struct rt6_exception_bucket *bucket;
1419 struct rt6_info *from = rt->from;
1420 struct in6_addr *src_key = NULL; 1420 struct in6_addr *src_key = NULL;
1421 struct rt6_exception *rt6_ex; 1421 struct rt6_exception *rt6_ex;
1422 int err; 1422 int err;
@@ -1460,8 +1460,8 @@ int rt6_remove_exception_rt(struct rt6_info *rt)
1460 */ 1460 */
1461static void rt6_update_exception_stamp_rt(struct rt6_info *rt) 1461static void rt6_update_exception_stamp_rt(struct rt6_info *rt)
1462{ 1462{
1463 struct rt6_info *from = (struct rt6_info *)rt->dst.from;
1464 struct rt6_exception_bucket *bucket; 1463 struct rt6_exception_bucket *bucket;
1464 struct rt6_info *from = rt->from;
1465 struct in6_addr *src_key = NULL; 1465 struct in6_addr *src_key = NULL;
1466 struct rt6_exception *rt6_ex; 1466 struct rt6_exception *rt6_ex;
1467 1467
@@ -1929,9 +1929,9 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
1929 1929
1930static void rt6_dst_from_metrics_check(struct rt6_info *rt) 1930static void rt6_dst_from_metrics_check(struct rt6_info *rt)
1931{ 1931{
1932 if (rt->dst.from && 1932 if (rt->from &&
1933 dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(rt->dst.from)) 1933 dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(&rt->from->dst))
1934 dst_init_metrics(&rt->dst, dst_metrics_ptr(rt->dst.from), true); 1934 dst_init_metrics(&rt->dst, dst_metrics_ptr(&rt->from->dst), true);
1935} 1935}
1936 1936
1937static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie) 1937static 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)
1951{ 1951{
1952 if (!__rt6_check_expired(rt) && 1952 if (!__rt6_check_expired(rt) &&
1953 rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK && 1953 rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
1954 rt6_check((struct rt6_info *)(rt->dst.from), cookie)) 1954 rt6_check(rt->from, cookie))
1955 return &rt->dst; 1955 return &rt->dst;
1956 else 1956 else
1957 return NULL; 1957 return NULL;
@@ -1971,7 +1971,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
1971 rt6_dst_from_metrics_check(rt); 1971 rt6_dst_from_metrics_check(rt);
1972 1972
1973 if (rt->rt6i_flags & RTF_PCPU || 1973 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))
1975 return rt6_dst_from_check(rt, cookie); 1975 return rt6_dst_from_check(rt, cookie);
1976 else 1976 else
1977 return rt6_check(rt, cookie); 1977 return rt6_check(rt, cookie);
@@ -3055,11 +3055,11 @@ out:
3055 3055
3056static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) 3056static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
3057{ 3057{
3058 BUG_ON(from->dst.from); 3058 BUG_ON(from->from);
3059 3059
3060 rt->rt6i_flags &= ~RTF_EXPIRES; 3060 rt->rt6i_flags &= ~RTF_EXPIRES;
3061 dst_hold(&from->dst); 3061 dst_hold(&from->dst);
3062 rt->dst.from = &from->dst; 3062 rt->from = from;
3063 dst_init_metrics(&rt->dst, dst_metrics_ptr(&from->dst), true); 3063 dst_init_metrics(&rt->dst, dst_metrics_ptr(&from->dst), true);
3064} 3064}
3065 3065