diff options
-rw-r--r-- | include/net/dst.h | 3 | ||||
-rw-r--r-- | include/net/ip6_fib.h | 9 | ||||
-rw-r--r-- | net/core/dst.c | 1 | ||||
-rw-r--r-- | net/ipv6/route.c | 34 |
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 { | |||
130 | struct rt6_info { | 130 | struct 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 | ||
187 | static u32 *rt6_pcpu_cow_metrics(struct rt6_info *rt) | 187 | static 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 | ||
192 | static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old) | 192 | 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) | |||
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 | ||
416 | static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | 416 | 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) | |||
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 */ |
1416 | int rt6_remove_exception_rt(struct rt6_info *rt) | 1416 | int 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 | */ |
1461 | static void rt6_update_exception_stamp_rt(struct rt6_info *rt) | 1461 | static 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 | ||
1930 | static void rt6_dst_from_metrics_check(struct rt6_info *rt) | 1930 | static 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 | ||
1937 | static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie) | 1937 | 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) | |||
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 | ||
3056 | static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) | 3056 | static 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 | ||