aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c309
1 files changed, 165 insertions, 144 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b582a0a0f1c5..4a62c47599b4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -62,17 +62,6 @@
62#include <linux/sysctl.h> 62#include <linux/sysctl.h>
63#endif 63#endif
64 64
65/* Set to 3 to get tracing. */
66#define RT6_DEBUG 2
67
68#if RT6_DEBUG >= 3
69#define RDBG(x) printk x
70#define RT6_TRACE(x...) printk(KERN_DEBUG x)
71#else
72#define RDBG(x)
73#define RT6_TRACE(x...) do { ; } while (0)
74#endif
75
76static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, 65static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
77 const struct in6_addr *dest); 66 const struct in6_addr *dest);
78static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); 67static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
@@ -134,7 +123,23 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
134 123
135static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr) 124static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr)
136{ 125{
137 return __neigh_lookup_errno(&nd_tbl, daddr, dst->dev); 126 struct neighbour *n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr);
127 if (n)
128 return n;
129 return neigh_create(&nd_tbl, daddr, dst->dev);
130}
131
132static int rt6_bind_neighbour(struct rt6_info *rt, struct net_device *dev)
133{
134 struct neighbour *n = __ipv6_neigh_lookup(&nd_tbl, dev, &rt->rt6i_gateway);
135 if (!n) {
136 n = neigh_create(&nd_tbl, &rt->rt6i_gateway, dev);
137 if (IS_ERR(n))
138 return PTR_ERR(n);
139 }
140 dst_set_neighbour(&rt->dst, n);
141
142 return 0;
138} 143}
139 144
140static struct dst_ops ip6_dst_ops_template = { 145static struct dst_ops ip6_dst_ops_template = {
@@ -247,9 +252,9 @@ static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
247{ 252{
248 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); 253 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags);
249 254
250 if (rt != NULL) 255 if (rt)
251 memset(&rt->rt6i_table, 0, 256 memset(&rt->rt6i_table, 0,
252 sizeof(*rt) - sizeof(struct dst_entry)); 257 sizeof(*rt) - sizeof(struct dst_entry));
253 258
254 return rt; 259 return rt;
255} 260}
@@ -263,7 +268,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)
263 if (!(rt->dst.flags & DST_HOST)) 268 if (!(rt->dst.flags & DST_HOST))
264 dst_destroy_metrics_generic(dst); 269 dst_destroy_metrics_generic(dst);
265 270
266 if (idev != NULL) { 271 if (idev) {
267 rt->rt6i_idev = NULL; 272 rt->rt6i_idev = NULL;
268 in6_dev_put(idev); 273 in6_dev_put(idev);
269 } 274 }
@@ -299,10 +304,10 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
299 struct net_device *loopback_dev = 304 struct net_device *loopback_dev =
300 dev_net(dev)->loopback_dev; 305 dev_net(dev)->loopback_dev;
301 306
302 if (dev != loopback_dev && idev != NULL && idev->dev == dev) { 307 if (dev != loopback_dev && idev && idev->dev == dev) {
303 struct inet6_dev *loopback_idev = 308 struct inet6_dev *loopback_idev =
304 in6_dev_get(loopback_dev); 309 in6_dev_get(loopback_dev);
305 if (loopback_idev != NULL) { 310 if (loopback_idev) {
306 rt->rt6i_idev = loopback_idev; 311 rt->rt6i_idev = loopback_idev;
307 in6_dev_put(idev); 312 in6_dev_put(idev);
308 } 313 }
@@ -312,7 +317,7 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
312static __inline__ int rt6_check_expired(const struct rt6_info *rt) 317static __inline__ int rt6_check_expired(const struct rt6_info *rt)
313{ 318{
314 return (rt->rt6i_flags & RTF_EXPIRES) && 319 return (rt->rt6i_flags & RTF_EXPIRES) &&
315 time_after(jiffies, rt->rt6i_expires); 320 time_after(jiffies, rt->dst.expires);
316} 321}
317 322
318static inline int rt6_need_strict(const struct in6_addr *daddr) 323static inline int rt6_need_strict(const struct in6_addr *daddr)
@@ -338,13 +343,13 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
338 goto out; 343 goto out;
339 344
340 for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) { 345 for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) {
341 struct net_device *dev = sprt->rt6i_dev; 346 struct net_device *dev = sprt->dst.dev;
342 347
343 if (oif) { 348 if (oif) {
344 if (dev->ifindex == oif) 349 if (dev->ifindex == oif)
345 return sprt; 350 return sprt;
346 if (dev->flags & IFF_LOOPBACK) { 351 if (dev->flags & IFF_LOOPBACK) {
347 if (sprt->rt6i_idev == NULL || 352 if (!sprt->rt6i_idev ||
348 sprt->rt6i_idev->dev->ifindex != oif) { 353 sprt->rt6i_idev->dev->ifindex != oif) {
349 if (flags & RT6_LOOKUP_F_IFACE && oif) 354 if (flags & RT6_LOOKUP_F_IFACE && oif)
350 continue; 355 continue;
@@ -385,7 +390,7 @@ static void rt6_probe(struct rt6_info *rt)
385 * to no more than one per minute. 390 * to no more than one per minute.
386 */ 391 */
387 rcu_read_lock(); 392 rcu_read_lock();
388 neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; 393 neigh = rt ? dst_get_neighbour_noref(&rt->dst) : NULL;
389 if (!neigh || (neigh->nud_state & NUD_VALID)) 394 if (!neigh || (neigh->nud_state & NUD_VALID))
390 goto out; 395 goto out;
391 read_lock_bh(&neigh->lock); 396 read_lock_bh(&neigh->lock);
@@ -399,7 +404,7 @@ static void rt6_probe(struct rt6_info *rt)
399 404
400 target = (struct in6_addr *)&neigh->primary_key; 405 target = (struct in6_addr *)&neigh->primary_key;
401 addrconf_addr_solict_mult(target, &mcaddr); 406 addrconf_addr_solict_mult(target, &mcaddr);
402 ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); 407 ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL);
403 } else { 408 } else {
404 read_unlock_bh(&neigh->lock); 409 read_unlock_bh(&neigh->lock);
405 } 410 }
@@ -417,7 +422,7 @@ static inline void rt6_probe(struct rt6_info *rt)
417 */ 422 */
418static inline int rt6_check_dev(struct rt6_info *rt, int oif) 423static inline int rt6_check_dev(struct rt6_info *rt, int oif)
419{ 424{
420 struct net_device *dev = rt->rt6i_dev; 425 struct net_device *dev = rt->dst.dev;
421 if (!oif || dev->ifindex == oif) 426 if (!oif || dev->ifindex == oif)
422 return 2; 427 return 2;
423 if ((dev->flags & IFF_LOOPBACK) && 428 if ((dev->flags & IFF_LOOPBACK) &&
@@ -432,7 +437,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
432 int m; 437 int m;
433 438
434 rcu_read_lock(); 439 rcu_read_lock();
435 neigh = dst_get_neighbour(&rt->dst); 440 neigh = dst_get_neighbour_noref(&rt->dst);
436 if (rt->rt6i_flags & RTF_NONEXTHOP || 441 if (rt->rt6i_flags & RTF_NONEXTHOP ||
437 !(rt->rt6i_flags & RTF_GATEWAY)) 442 !(rt->rt6i_flags & RTF_GATEWAY))
438 m = 1; 443 m = 1;
@@ -518,9 +523,6 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
518 struct rt6_info *match, *rt0; 523 struct rt6_info *match, *rt0;
519 struct net *net; 524 struct net *net;
520 525
521 RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n",
522 __func__, fn->leaf, oif);
523
524 rt0 = fn->rr_ptr; 526 rt0 = fn->rr_ptr;
525 if (!rt0) 527 if (!rt0)
526 fn->rr_ptr = rt0 = fn->leaf; 528 fn->rr_ptr = rt0 = fn->leaf;
@@ -539,10 +541,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
539 fn->rr_ptr = next; 541 fn->rr_ptr = next;
540 } 542 }
541 543
542 RT6_TRACE("%s() => %p\n", 544 net = dev_net(rt0->dst.dev);
543 __func__, match);
544
545 net = dev_net(rt0->rt6i_dev);
546 return match ? match : net->ipv6.ip6_null_entry; 545 return match ? match : net->ipv6.ip6_null_entry;
547} 546}
548 547
@@ -611,7 +610,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
611 if (!addrconf_finite_timeout(lifetime)) { 610 if (!addrconf_finite_timeout(lifetime)) {
612 rt->rt6i_flags &= ~RTF_EXPIRES; 611 rt->rt6i_flags &= ~RTF_EXPIRES;
613 } else { 612 } else {
614 rt->rt6i_expires = jiffies + HZ * lifetime; 613 rt->dst.expires = jiffies + HZ * lifetime;
615 rt->rt6i_flags |= RTF_EXPIRES; 614 rt->rt6i_flags |= RTF_EXPIRES;
616 } 615 }
617 dst_release(&rt->dst); 616 dst_release(&rt->dst);
@@ -636,7 +635,7 @@ do { \
636 goto restart; \ 635 goto restart; \
637 } \ 636 } \
638 } \ 637 } \
639} while(0) 638} while (0)
640 639
641static struct rt6_info *ip6_pol_route_lookup(struct net *net, 640static struct rt6_info *ip6_pol_route_lookup(struct net *net,
642 struct fib6_table *table, 641 struct fib6_table *table,
@@ -658,6 +657,13 @@ out:
658 657
659} 658}
660 659
660struct dst_entry * ip6_route_lookup(struct net *net, struct flowi6 *fl6,
661 int flags)
662{
663 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup);
664}
665EXPORT_SYMBOL_GPL(ip6_route_lookup);
666
661struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, 667struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
662 const struct in6_addr *saddr, int oif, int strict) 668 const struct in6_addr *saddr, int oif, int strict)
663{ 669{
@@ -706,7 +712,7 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
706int ip6_ins_rt(struct rt6_info *rt) 712int ip6_ins_rt(struct rt6_info *rt)
707{ 713{
708 struct nl_info info = { 714 struct nl_info info = {
709 .nl_net = dev_net(rt->rt6i_dev), 715 .nl_net = dev_net(rt->dst.dev),
710 }; 716 };
711 return __ip6_ins_rt(rt, &info); 717 return __ip6_ins_rt(rt, &info);
712} 718}
@@ -724,29 +730,27 @@ static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort,
724 rt = ip6_rt_copy(ort, daddr); 730 rt = ip6_rt_copy(ort, daddr);
725 731
726 if (rt) { 732 if (rt) {
727 struct neighbour *neigh;
728 int attempts = !in_softirq(); 733 int attempts = !in_softirq();
729 734
730 if (!(rt->rt6i_flags&RTF_GATEWAY)) { 735 if (!(rt->rt6i_flags & RTF_GATEWAY)) {
731 if (ort->rt6i_dst.plen != 128 && 736 if (ort->rt6i_dst.plen != 128 &&
732 ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) 737 ipv6_addr_equal(&ort->rt6i_dst.addr, daddr))
733 rt->rt6i_flags |= RTF_ANYCAST; 738 rt->rt6i_flags |= RTF_ANYCAST;
734 ipv6_addr_copy(&rt->rt6i_gateway, daddr); 739 rt->rt6i_gateway = *daddr;
735 } 740 }
736 741
737 rt->rt6i_flags |= RTF_CACHE; 742 rt->rt6i_flags |= RTF_CACHE;
738 743
739#ifdef CONFIG_IPV6_SUBTREES 744#ifdef CONFIG_IPV6_SUBTREES
740 if (rt->rt6i_src.plen && saddr) { 745 if (rt->rt6i_src.plen && saddr) {
741 ipv6_addr_copy(&rt->rt6i_src.addr, saddr); 746 rt->rt6i_src.addr = *saddr;
742 rt->rt6i_src.plen = 128; 747 rt->rt6i_src.plen = 128;
743 } 748 }
744#endif 749#endif
745 750
746 retry: 751 retry:
747 neigh = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); 752 if (rt6_bind_neighbour(rt, rt->dst.dev)) {
748 if (IS_ERR(neigh)) { 753 struct net *net = dev_net(rt->dst.dev);
749 struct net *net = dev_net(rt->rt6i_dev);
750 int saved_rt_min_interval = 754 int saved_rt_min_interval =
751 net->ipv6.sysctl.ip6_rt_gc_min_interval; 755 net->ipv6.sysctl.ip6_rt_gc_min_interval;
752 int saved_rt_elasticity = 756 int saved_rt_elasticity =
@@ -771,8 +775,6 @@ static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort,
771 dst_free(&rt->dst); 775 dst_free(&rt->dst);
772 return NULL; 776 return NULL;
773 } 777 }
774 dst_set_neighbour(&rt->dst, neigh);
775
776 } 778 }
777 779
778 return rt; 780 return rt;
@@ -785,7 +787,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
785 787
786 if (rt) { 788 if (rt) {
787 rt->rt6i_flags |= RTF_CACHE; 789 rt->rt6i_flags |= RTF_CACHE;
788 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst))); 790 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_noref_raw(&ort->dst)));
789 } 791 }
790 return rt; 792 return rt;
791} 793}
@@ -819,7 +821,7 @@ restart:
819 dst_hold(&rt->dst); 821 dst_hold(&rt->dst);
820 read_unlock_bh(&table->tb6_lock); 822 read_unlock_bh(&table->tb6_lock);
821 823
822 if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) 824 if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
823 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); 825 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
824 else if (!(rt->dst.flags & DST_HOST)) 826 else if (!(rt->dst.flags & DST_HOST))
825 nrt = rt6_alloc_clone(rt, &fl6->daddr); 827 nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -875,7 +877,7 @@ void ip6_route_input(struct sk_buff *skb)
875 .flowi6_iif = skb->dev->ifindex, 877 .flowi6_iif = skb->dev->ifindex,
876 .daddr = iph->daddr, 878 .daddr = iph->daddr,
877 .saddr = iph->saddr, 879 .saddr = iph->saddr,
878 .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, 880 .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
879 .flowi6_mark = skb->mark, 881 .flowi6_mark = skb->mark,
880 .flowi6_proto = iph->nexthdr, 882 .flowi6_proto = iph->nexthdr,
881 }; 883 };
@@ -932,9 +934,9 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
932 rt->rt6i_idev = ort->rt6i_idev; 934 rt->rt6i_idev = ort->rt6i_idev;
933 if (rt->rt6i_idev) 935 if (rt->rt6i_idev)
934 in6_dev_hold(rt->rt6i_idev); 936 in6_dev_hold(rt->rt6i_idev);
935 rt->rt6i_expires = 0; 937 rt->dst.expires = 0;
936 938
937 ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway); 939 rt->rt6i_gateway = ort->rt6i_gateway;
938 rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; 940 rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
939 rt->rt6i_metric = 0; 941 rt->rt6i_metric = 0;
940 942
@@ -997,7 +999,7 @@ static void ip6_link_failure(struct sk_buff *skb)
997 999
998 rt = (struct rt6_info *) skb_dst(skb); 1000 rt = (struct rt6_info *) skb_dst(skb);
999 if (rt) { 1001 if (rt) {
1000 if (rt->rt6i_flags&RTF_CACHE) { 1002 if (rt->rt6i_flags & RTF_CACHE) {
1001 dst_set_expires(&rt->dst, 0); 1003 dst_set_expires(&rt->dst, 0);
1002 rt->rt6i_flags |= RTF_EXPIRES; 1004 rt->rt6i_flags |= RTF_EXPIRES;
1003 } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) 1005 } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))
@@ -1067,34 +1069,38 @@ static DEFINE_SPINLOCK(icmp6_dst_lock);
1067 1069
1068struct dst_entry *icmp6_dst_alloc(struct net_device *dev, 1070struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1069 struct neighbour *neigh, 1071 struct neighbour *neigh,
1070 const struct in6_addr *addr) 1072 struct flowi6 *fl6)
1071{ 1073{
1074 struct dst_entry *dst;
1072 struct rt6_info *rt; 1075 struct rt6_info *rt;
1073 struct inet6_dev *idev = in6_dev_get(dev); 1076 struct inet6_dev *idev = in6_dev_get(dev);
1074 struct net *net = dev_net(dev); 1077 struct net *net = dev_net(dev);
1075 1078
1076 if (unlikely(idev == NULL)) 1079 if (unlikely(!idev))
1077 return NULL; 1080 return NULL;
1078 1081
1079 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); 1082 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0);
1080 if (unlikely(rt == NULL)) { 1083 if (unlikely(!rt)) {
1081 in6_dev_put(idev); 1084 in6_dev_put(idev);
1085 dst = ERR_PTR(-ENOMEM);
1082 goto out; 1086 goto out;
1083 } 1087 }
1084 1088
1085 if (neigh) 1089 if (neigh)
1086 neigh_hold(neigh); 1090 neigh_hold(neigh);
1087 else { 1091 else {
1088 neigh = ndisc_get_neigh(dev, addr); 1092 neigh = ip6_neigh_lookup(&rt->dst, &fl6->daddr);
1089 if (IS_ERR(neigh)) 1093 if (IS_ERR(neigh)) {
1090 neigh = NULL; 1094 dst_free(&rt->dst);
1095 return ERR_CAST(neigh);
1096 }
1091 } 1097 }
1092 1098
1093 rt->dst.flags |= DST_HOST; 1099 rt->dst.flags |= DST_HOST;
1094 rt->dst.output = ip6_output; 1100 rt->dst.output = ip6_output;
1095 dst_set_neighbour(&rt->dst, neigh); 1101 dst_set_neighbour(&rt->dst, neigh);
1096 atomic_set(&rt->dst.__refcnt, 1); 1102 atomic_set(&rt->dst.__refcnt, 1);
1097 ipv6_addr_copy(&rt->rt6i_dst.addr, addr); 1103 rt->rt6i_dst.addr = fl6->daddr;
1098 rt->rt6i_dst.plen = 128; 1104 rt->rt6i_dst.plen = 128;
1099 rt->rt6i_idev = idev; 1105 rt->rt6i_idev = idev;
1100 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); 1106 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
@@ -1106,8 +1112,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1106 1112
1107 fib6_force_start_gc(net); 1113 fib6_force_start_gc(net);
1108 1114
1115 dst = xfrm_lookup(net, &rt->dst, flowi6_to_flowi(fl6), NULL, 0);
1116
1109out: 1117out:
1110 return &rt->dst; 1118 return dst;
1111} 1119}
1112 1120
1113int icmp6_dst_gc(void) 1121int icmp6_dst_gc(void)
@@ -1237,21 +1245,30 @@ int ip6_route_add(struct fib6_config *cfg)
1237 if (cfg->fc_metric == 0) 1245 if (cfg->fc_metric == 0)
1238 cfg->fc_metric = IP6_RT_PRIO_USER; 1246 cfg->fc_metric = IP6_RT_PRIO_USER;
1239 1247
1240 table = fib6_new_table(net, cfg->fc_table); 1248 err = -ENOBUFS;
1241 if (table == NULL) { 1249 if (cfg->fc_nlinfo.nlh &&
1242 err = -ENOBUFS; 1250 !(cfg->fc_nlinfo.nlh->nlmsg_flags & NLM_F_CREATE)) {
1243 goto out; 1251 table = fib6_get_table(net, cfg->fc_table);
1252 if (!table) {
1253 printk(KERN_WARNING "IPv6: NLM_F_CREATE should be specified when creating new route\n");
1254 table = fib6_new_table(net, cfg->fc_table);
1255 }
1256 } else {
1257 table = fib6_new_table(net, cfg->fc_table);
1244 } 1258 }
1245 1259
1260 if (!table)
1261 goto out;
1262
1246 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT); 1263 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT);
1247 1264
1248 if (rt == NULL) { 1265 if (!rt) {
1249 err = -ENOMEM; 1266 err = -ENOMEM;
1250 goto out; 1267 goto out;
1251 } 1268 }
1252 1269
1253 rt->dst.obsolete = -1; 1270 rt->dst.obsolete = -1;
1254 rt->rt6i_expires = (cfg->fc_flags & RTF_EXPIRES) ? 1271 rt->dst.expires = (cfg->fc_flags & RTF_EXPIRES) ?
1255 jiffies + clock_t_to_jiffies(cfg->fc_expires) : 1272 jiffies + clock_t_to_jiffies(cfg->fc_expires) :
1256 0; 1273 0;
1257 1274
@@ -1294,8 +1311,9 @@ int ip6_route_add(struct fib6_config *cfg)
1294 they would result in kernel looping; promote them to reject routes 1311 they would result in kernel looping; promote them to reject routes
1295 */ 1312 */
1296 if ((cfg->fc_flags & RTF_REJECT) || 1313 if ((cfg->fc_flags & RTF_REJECT) ||
1297 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK) 1314 (dev && (dev->flags & IFF_LOOPBACK) &&
1298 && !(cfg->fc_flags&RTF_LOCAL))) { 1315 !(addr_type & IPV6_ADDR_LOOPBACK) &&
1316 !(cfg->fc_flags & RTF_LOCAL))) {
1299 /* hold loopback dev/idev if we haven't done so. */ 1317 /* hold loopback dev/idev if we haven't done so. */
1300 if (dev != net->loopback_dev) { 1318 if (dev != net->loopback_dev) {
1301 if (dev) { 1319 if (dev) {
@@ -1322,7 +1340,7 @@ int ip6_route_add(struct fib6_config *cfg)
1322 int gwa_type; 1340 int gwa_type;
1323 1341
1324 gw_addr = &cfg->fc_gateway; 1342 gw_addr = &cfg->fc_gateway;
1325 ipv6_addr_copy(&rt->rt6i_gateway, gw_addr); 1343 rt->rt6i_gateway = *gw_addr;
1326 gwa_type = ipv6_addr_type(gw_addr); 1344 gwa_type = ipv6_addr_type(gw_addr);
1327 1345
1328 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { 1346 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
@@ -1336,26 +1354,26 @@ int ip6_route_add(struct fib6_config *cfg)
1336 some exceptions. --ANK 1354 some exceptions. --ANK
1337 */ 1355 */
1338 err = -EINVAL; 1356 err = -EINVAL;
1339 if (!(gwa_type&IPV6_ADDR_UNICAST)) 1357 if (!(gwa_type & IPV6_ADDR_UNICAST))
1340 goto out; 1358 goto out;
1341 1359
1342 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); 1360 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1);
1343 1361
1344 err = -EHOSTUNREACH; 1362 err = -EHOSTUNREACH;
1345 if (grt == NULL) 1363 if (!grt)
1346 goto out; 1364 goto out;
1347 if (dev) { 1365 if (dev) {
1348 if (dev != grt->rt6i_dev) { 1366 if (dev != grt->dst.dev) {
1349 dst_release(&grt->dst); 1367 dst_release(&grt->dst);
1350 goto out; 1368 goto out;
1351 } 1369 }
1352 } else { 1370 } else {
1353 dev = grt->rt6i_dev; 1371 dev = grt->dst.dev;
1354 idev = grt->rt6i_idev; 1372 idev = grt->rt6i_idev;
1355 dev_hold(dev); 1373 dev_hold(dev);
1356 in6_dev_hold(grt->rt6i_idev); 1374 in6_dev_hold(grt->rt6i_idev);
1357 } 1375 }
1358 if (!(grt->rt6i_flags&RTF_GATEWAY)) 1376 if (!(grt->rt6i_flags & RTF_GATEWAY))
1359 err = 0; 1377 err = 0;
1360 dst_release(&grt->dst); 1378 dst_release(&grt->dst);
1361 1379
@@ -1363,12 +1381,12 @@ int ip6_route_add(struct fib6_config *cfg)
1363 goto out; 1381 goto out;
1364 } 1382 }
1365 err = -EINVAL; 1383 err = -EINVAL;
1366 if (dev == NULL || (dev->flags&IFF_LOOPBACK)) 1384 if (!dev || (dev->flags & IFF_LOOPBACK))
1367 goto out; 1385 goto out;
1368 } 1386 }
1369 1387
1370 err = -ENODEV; 1388 err = -ENODEV;
1371 if (dev == NULL) 1389 if (!dev)
1372 goto out; 1390 goto out;
1373 1391
1374 if (!ipv6_addr_any(&cfg->fc_prefsrc)) { 1392 if (!ipv6_addr_any(&cfg->fc_prefsrc)) {
@@ -1376,18 +1394,15 @@ int ip6_route_add(struct fib6_config *cfg)
1376 err = -EINVAL; 1394 err = -EINVAL;
1377 goto out; 1395 goto out;
1378 } 1396 }
1379 ipv6_addr_copy(&rt->rt6i_prefsrc.addr, &cfg->fc_prefsrc); 1397 rt->rt6i_prefsrc.addr = cfg->fc_prefsrc;
1380 rt->rt6i_prefsrc.plen = 128; 1398 rt->rt6i_prefsrc.plen = 128;
1381 } else 1399 } else
1382 rt->rt6i_prefsrc.plen = 0; 1400 rt->rt6i_prefsrc.plen = 0;
1383 1401
1384 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) { 1402 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
1385 struct neighbour *n = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); 1403 err = rt6_bind_neighbour(rt, dev);
1386 if (IS_ERR(n)) { 1404 if (err)
1387 err = PTR_ERR(n);
1388 goto out; 1405 goto out;
1389 }
1390 dst_set_neighbour(&rt->dst, n);
1391 } 1406 }
1392 1407
1393 rt->rt6i_flags = cfg->fc_flags; 1408 rt->rt6i_flags = cfg->fc_flags;
@@ -1433,7 +1448,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
1433{ 1448{
1434 int err; 1449 int err;
1435 struct fib6_table *table; 1450 struct fib6_table *table;
1436 struct net *net = dev_net(rt->rt6i_dev); 1451 struct net *net = dev_net(rt->dst.dev);
1437 1452
1438 if (rt == net->ipv6.ip6_null_entry) 1453 if (rt == net->ipv6.ip6_null_entry)
1439 return -ENOENT; 1454 return -ENOENT;
@@ -1452,7 +1467,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
1452int ip6_del_rt(struct rt6_info *rt) 1467int ip6_del_rt(struct rt6_info *rt)
1453{ 1468{
1454 struct nl_info info = { 1469 struct nl_info info = {
1455 .nl_net = dev_net(rt->rt6i_dev), 1470 .nl_net = dev_net(rt->dst.dev),
1456 }; 1471 };
1457 return __ip6_del_rt(rt, &info); 1472 return __ip6_del_rt(rt, &info);
1458} 1473}
@@ -1465,7 +1480,7 @@ static int ip6_route_del(struct fib6_config *cfg)
1465 int err = -ESRCH; 1480 int err = -ESRCH;
1466 1481
1467 table = fib6_get_table(cfg->fc_nlinfo.nl_net, cfg->fc_table); 1482 table = fib6_get_table(cfg->fc_nlinfo.nl_net, cfg->fc_table);
1468 if (table == NULL) 1483 if (!table)
1469 return err; 1484 return err;
1470 1485
1471 read_lock_bh(&table->tb6_lock); 1486 read_lock_bh(&table->tb6_lock);
@@ -1477,8 +1492,8 @@ static int ip6_route_del(struct fib6_config *cfg)
1477 if (fn) { 1492 if (fn) {
1478 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { 1493 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
1479 if (cfg->fc_ifindex && 1494 if (cfg->fc_ifindex &&
1480 (rt->rt6i_dev == NULL || 1495 (!rt->dst.dev ||
1481 rt->rt6i_dev->ifindex != cfg->fc_ifindex)) 1496 rt->dst.dev->ifindex != cfg->fc_ifindex))
1482 continue; 1497 continue;
1483 if (cfg->fc_flags & RTF_GATEWAY && 1498 if (cfg->fc_flags & RTF_GATEWAY &&
1484 !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway)) 1499 !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
@@ -1540,7 +1555,7 @@ restart:
1540 continue; 1555 continue;
1541 if (!(rt->rt6i_flags & RTF_GATEWAY)) 1556 if (!(rt->rt6i_flags & RTF_GATEWAY))
1542 continue; 1557 continue;
1543 if (fl6->flowi6_oif != rt->rt6i_dev->ifindex) 1558 if (fl6->flowi6_oif != rt->dst.dev->ifindex)
1544 continue; 1559 continue;
1545 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway)) 1560 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
1546 continue; 1561 continue;
@@ -1573,7 +1588,7 @@ static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest,
1573 }, 1588 },
1574 }; 1589 };
1575 1590
1576 ipv6_addr_copy(&rdfl.gateway, gateway); 1591 rdfl.gateway = *gateway;
1577 1592
1578 if (rt6_need_strict(dest)) 1593 if (rt6_need_strict(dest))
1579 flags |= RT6_LOOKUP_F_IFACE; 1594 flags |= RT6_LOOKUP_F_IFACE;
@@ -1618,18 +1633,18 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1618 dst_confirm(&rt->dst); 1633 dst_confirm(&rt->dst);
1619 1634
1620 /* Duplicate redirect: silently ignore. */ 1635 /* Duplicate redirect: silently ignore. */
1621 if (neigh == dst_get_neighbour_raw(&rt->dst)) 1636 if (neigh == dst_get_neighbour_noref_raw(&rt->dst))
1622 goto out; 1637 goto out;
1623 1638
1624 nrt = ip6_rt_copy(rt, dest); 1639 nrt = ip6_rt_copy(rt, dest);
1625 if (nrt == NULL) 1640 if (!nrt)
1626 goto out; 1641 goto out;
1627 1642
1628 nrt->rt6i_flags = RTF_GATEWAY|RTF_UP|RTF_DYNAMIC|RTF_CACHE; 1643 nrt->rt6i_flags = RTF_GATEWAY|RTF_UP|RTF_DYNAMIC|RTF_CACHE;
1629 if (on_link) 1644 if (on_link)
1630 nrt->rt6i_flags &= ~RTF_GATEWAY; 1645 nrt->rt6i_flags &= ~RTF_GATEWAY;
1631 1646
1632 ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); 1647 nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
1633 dst_set_neighbour(&nrt->dst, neigh_clone(neigh)); 1648 dst_set_neighbour(&nrt->dst, neigh_clone(neigh));
1634 1649
1635 if (ip6_ins_rt(nrt)) 1650 if (ip6_ins_rt(nrt))
@@ -1639,7 +1654,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1639 netevent.new = &nrt->dst; 1654 netevent.new = &nrt->dst;
1640 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); 1655 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
1641 1656
1642 if (rt->rt6i_flags&RTF_CACHE) { 1657 if (rt->rt6i_flags & RTF_CACHE) {
1643 ip6_del_rt(rt); 1658 ip6_del_rt(rt);
1644 return; 1659 return;
1645 } 1660 }
@@ -1660,7 +1675,7 @@ static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr
1660 int allfrag = 0; 1675 int allfrag = 0;
1661again: 1676again:
1662 rt = rt6_lookup(net, daddr, saddr, ifindex, 0); 1677 rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
1663 if (rt == NULL) 1678 if (!rt)
1664 return; 1679 return;
1665 1680
1666 if (rt6_check_expired(rt)) { 1681 if (rt6_check_expired(rt)) {
@@ -1710,7 +1725,7 @@ again:
1710 1. It is connected route. Action: COW 1725 1. It is connected route. Action: COW
1711 2. It is gatewayed route or NONEXTHOP route. Action: clone it. 1726 2. It is gatewayed route or NONEXTHOP route. Action: clone it.
1712 */ 1727 */
1713 if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) 1728 if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
1714 nrt = rt6_alloc_cow(rt, daddr, saddr); 1729 nrt = rt6_alloc_cow(rt, daddr, saddr);
1715 else 1730 else
1716 nrt = rt6_alloc_clone(rt, daddr); 1731 nrt = rt6_alloc_clone(rt, daddr);
@@ -1766,7 +1781,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad
1766static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, 1781static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
1767 const struct in6_addr *dest) 1782 const struct in6_addr *dest)
1768{ 1783{
1769 struct net *net = dev_net(ort->rt6i_dev); 1784 struct net *net = dev_net(ort->dst.dev);
1770 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, 1785 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
1771 ort->dst.dev, 0); 1786 ort->dst.dev, 0);
1772 1787
@@ -1775,7 +1790,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
1775 rt->dst.output = ort->dst.output; 1790 rt->dst.output = ort->dst.output;
1776 rt->dst.flags |= DST_HOST; 1791 rt->dst.flags |= DST_HOST;
1777 1792
1778 ipv6_addr_copy(&rt->rt6i_dst.addr, dest); 1793 rt->rt6i_dst.addr = *dest;
1779 rt->rt6i_dst.plen = 128; 1794 rt->rt6i_dst.plen = 128;
1780 dst_copy_metrics(&rt->dst, &ort->dst); 1795 dst_copy_metrics(&rt->dst, &ort->dst);
1781 rt->dst.error = ort->dst.error; 1796 rt->dst.error = ort->dst.error;
@@ -1783,9 +1798,9 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
1783 if (rt->rt6i_idev) 1798 if (rt->rt6i_idev)
1784 in6_dev_hold(rt->rt6i_idev); 1799 in6_dev_hold(rt->rt6i_idev);
1785 rt->dst.lastuse = jiffies; 1800 rt->dst.lastuse = jiffies;
1786 rt->rt6i_expires = 0; 1801 rt->dst.expires = 0;
1787 1802
1788 ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway); 1803 rt->rt6i_gateway = ort->rt6i_gateway;
1789 rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; 1804 rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
1790 rt->rt6i_metric = 0; 1805 rt->rt6i_metric = 0;
1791 1806
@@ -1808,7 +1823,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
1808 struct fib6_table *table; 1823 struct fib6_table *table;
1809 1824
1810 table = fib6_get_table(net, RT6_TABLE_INFO); 1825 table = fib6_get_table(net, RT6_TABLE_INFO);
1811 if (table == NULL) 1826 if (!table)
1812 return NULL; 1827 return NULL;
1813 1828
1814 write_lock_bh(&table->tb6_lock); 1829 write_lock_bh(&table->tb6_lock);
@@ -1817,7 +1832,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
1817 goto out; 1832 goto out;
1818 1833
1819 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { 1834 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
1820 if (rt->rt6i_dev->ifindex != ifindex) 1835 if (rt->dst.dev->ifindex != ifindex)
1821 continue; 1836 continue;
1822 if ((rt->rt6i_flags & (RTF_ROUTEINFO|RTF_GATEWAY)) != (RTF_ROUTEINFO|RTF_GATEWAY)) 1837 if ((rt->rt6i_flags & (RTF_ROUTEINFO|RTF_GATEWAY)) != (RTF_ROUTEINFO|RTF_GATEWAY))
1823 continue; 1838 continue;
@@ -1848,8 +1863,8 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
1848 .fc_nlinfo.nl_net = net, 1863 .fc_nlinfo.nl_net = net,
1849 }; 1864 };
1850 1865
1851 ipv6_addr_copy(&cfg.fc_dst, prefix); 1866 cfg.fc_dst = *prefix;
1852 ipv6_addr_copy(&cfg.fc_gateway, gwaddr); 1867 cfg.fc_gateway = *gwaddr;
1853 1868
1854 /* We should treat it as a default route if prefix length is 0. */ 1869 /* We should treat it as a default route if prefix length is 0. */
1855 if (!prefixlen) 1870 if (!prefixlen)
@@ -1867,12 +1882,12 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev
1867 struct fib6_table *table; 1882 struct fib6_table *table;
1868 1883
1869 table = fib6_get_table(dev_net(dev), RT6_TABLE_DFLT); 1884 table = fib6_get_table(dev_net(dev), RT6_TABLE_DFLT);
1870 if (table == NULL) 1885 if (!table)
1871 return NULL; 1886 return NULL;
1872 1887
1873 write_lock_bh(&table->tb6_lock); 1888 write_lock_bh(&table->tb6_lock);
1874 for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) { 1889 for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) {
1875 if (dev == rt->rt6i_dev && 1890 if (dev == rt->dst.dev &&
1876 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && 1891 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
1877 ipv6_addr_equal(&rt->rt6i_gateway, addr)) 1892 ipv6_addr_equal(&rt->rt6i_gateway, addr))
1878 break; 1893 break;
@@ -1898,7 +1913,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
1898 .fc_nlinfo.nl_net = dev_net(dev), 1913 .fc_nlinfo.nl_net = dev_net(dev),
1899 }; 1914 };
1900 1915
1901 ipv6_addr_copy(&cfg.fc_gateway, gwaddr); 1916 cfg.fc_gateway = *gwaddr;
1902 1917
1903 ip6_route_add(&cfg); 1918 ip6_route_add(&cfg);
1904 1919
@@ -1912,7 +1927,7 @@ void rt6_purge_dflt_routers(struct net *net)
1912 1927
1913 /* NOTE: Keep consistent with rt6_get_dflt_router */ 1928 /* NOTE: Keep consistent with rt6_get_dflt_router */
1914 table = fib6_get_table(net, RT6_TABLE_DFLT); 1929 table = fib6_get_table(net, RT6_TABLE_DFLT);
1915 if (table == NULL) 1930 if (!table)
1916 return; 1931 return;
1917 1932
1918restart: 1933restart:
@@ -1944,9 +1959,9 @@ static void rtmsg_to_fib6_config(struct net *net,
1944 1959
1945 cfg->fc_nlinfo.nl_net = net; 1960 cfg->fc_nlinfo.nl_net = net;
1946 1961
1947 ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); 1962 cfg->fc_dst = rtmsg->rtmsg_dst;
1948 ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); 1963 cfg->fc_src = rtmsg->rtmsg_src;
1949 ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); 1964 cfg->fc_gateway = rtmsg->rtmsg_gateway;
1950} 1965}
1951 1966
1952int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) 1967int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
@@ -2045,14 +2060,14 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb)
2045 2060
2046struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, 2061struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2047 const struct in6_addr *addr, 2062 const struct in6_addr *addr,
2048 int anycast) 2063 bool anycast)
2049{ 2064{
2050 struct net *net = dev_net(idev->dev); 2065 struct net *net = dev_net(idev->dev);
2051 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, 2066 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
2052 net->loopback_dev, 0); 2067 net->loopback_dev, 0);
2053 struct neighbour *neigh; 2068 int err;
2054 2069
2055 if (rt == NULL) { 2070 if (!rt) {
2056 if (net_ratelimit()) 2071 if (net_ratelimit())
2057 pr_warning("IPv6: Maximum number of routes reached," 2072 pr_warning("IPv6: Maximum number of routes reached,"
2058 " consider increasing route/max_size.\n"); 2073 " consider increasing route/max_size.\n");
@@ -2072,15 +2087,13 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2072 rt->rt6i_flags |= RTF_ANYCAST; 2087 rt->rt6i_flags |= RTF_ANYCAST;
2073 else 2088 else
2074 rt->rt6i_flags |= RTF_LOCAL; 2089 rt->rt6i_flags |= RTF_LOCAL;
2075 neigh = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); 2090 err = rt6_bind_neighbour(rt, rt->dst.dev);
2076 if (IS_ERR(neigh)) { 2091 if (err) {
2077 dst_free(&rt->dst); 2092 dst_free(&rt->dst);
2078 2093 return ERR_PTR(err);
2079 return ERR_CAST(neigh);
2080 } 2094 }
2081 dst_set_neighbour(&rt->dst, neigh);
2082 2095
2083 ipv6_addr_copy(&rt->rt6i_dst.addr, addr); 2096 rt->rt6i_dst.addr = *addr;
2084 rt->rt6i_dst.plen = 128; 2097 rt->rt6i_dst.plen = 128;
2085 rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); 2098 rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL);
2086 2099
@@ -2098,7 +2111,7 @@ int ip6_route_get_saddr(struct net *net,
2098 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt); 2111 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt);
2099 int err = 0; 2112 int err = 0;
2100 if (rt->rt6i_prefsrc.plen) 2113 if (rt->rt6i_prefsrc.plen)
2101 ipv6_addr_copy(saddr, &rt->rt6i_prefsrc.addr); 2114 *saddr = rt->rt6i_prefsrc.addr;
2102 else 2115 else
2103 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, 2116 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
2104 daddr, prefs, saddr); 2117 daddr, prefs, saddr);
@@ -2118,7 +2131,7 @@ static int fib6_remove_prefsrc(struct rt6_info *rt, void *arg)
2118 struct net *net = ((struct arg_dev_net_ip *)arg)->net; 2131 struct net *net = ((struct arg_dev_net_ip *)arg)->net;
2119 struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr; 2132 struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr;
2120 2133
2121 if (((void *)rt->rt6i_dev == dev || dev == NULL) && 2134 if (((void *)rt->dst.dev == dev || !dev) &&
2122 rt != net->ipv6.ip6_null_entry && 2135 rt != net->ipv6.ip6_null_entry &&
2123 ipv6_addr_equal(addr, &rt->rt6i_prefsrc.addr)) { 2136 ipv6_addr_equal(addr, &rt->rt6i_prefsrc.addr)) {
2124 /* remove prefsrc entry */ 2137 /* remove prefsrc entry */
@@ -2148,11 +2161,10 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg)
2148 const struct arg_dev_net *adn = arg; 2161 const struct arg_dev_net *adn = arg;
2149 const struct net_device *dev = adn->dev; 2162 const struct net_device *dev = adn->dev;
2150 2163
2151 if ((rt->rt6i_dev == dev || dev == NULL) && 2164 if ((rt->dst.dev == dev || !dev) &&
2152 rt != adn->net->ipv6.ip6_null_entry) { 2165 rt != adn->net->ipv6.ip6_null_entry)
2153 RT6_TRACE("deleted by ifdown %p\n", rt);
2154 return -1; 2166 return -1;
2155 } 2167
2156 return 0; 2168 return 0;
2157} 2169}
2158 2170
@@ -2185,7 +2197,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
2185 */ 2197 */
2186 2198
2187 idev = __in6_dev_get(arg->dev); 2199 idev = __in6_dev_get(arg->dev);
2188 if (idev == NULL) 2200 if (!idev)
2189 return 0; 2201 return 0;
2190 2202
2191 /* For administrative MTU increase, there is no way to discover 2203 /* For administrative MTU increase, there is no way to discover
@@ -2202,7 +2214,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
2202 also have the lowest MTU, TOO BIG MESSAGE will be lead to 2214 also have the lowest MTU, TOO BIG MESSAGE will be lead to
2203 PMTU discouvery. 2215 PMTU discouvery.
2204 */ 2216 */
2205 if (rt->rt6i_dev == arg->dev && 2217 if (rt->dst.dev == arg->dev &&
2206 !dst_metric_locked(&rt->dst, RTAX_MTU) && 2218 !dst_metric_locked(&rt->dst, RTAX_MTU) &&
2207 (dst_mtu(&rt->dst) >= arg->mtu || 2219 (dst_mtu(&rt->dst) >= arg->mtu ||
2208 (dst_mtu(&rt->dst) < arg->mtu && 2220 (dst_mtu(&rt->dst) < arg->mtu &&
@@ -2351,11 +2363,13 @@ static int rt6_fill_node(struct net *net,
2351 int iif, int type, u32 pid, u32 seq, 2363 int iif, int type, u32 pid, u32 seq,
2352 int prefix, int nowait, unsigned int flags) 2364 int prefix, int nowait, unsigned int flags)
2353{ 2365{
2366 const struct inet_peer *peer;
2354 struct rtmsg *rtm; 2367 struct rtmsg *rtm;
2355 struct nlmsghdr *nlh; 2368 struct nlmsghdr *nlh;
2356 long expires; 2369 long expires;
2357 u32 table; 2370 u32 table;
2358 struct neighbour *n; 2371 struct neighbour *n;
2372 u32 ts, tsage;
2359 2373
2360 if (prefix) { /* user wants prefix routes only */ 2374 if (prefix) { /* user wants prefix routes only */
2361 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { 2375 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
@@ -2365,7 +2379,7 @@ static int rt6_fill_node(struct net *net,
2365 } 2379 }
2366 2380
2367 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags); 2381 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
2368 if (nlh == NULL) 2382 if (!nlh)
2369 return -EMSGSIZE; 2383 return -EMSGSIZE;
2370 2384
2371 rtm = nlmsg_data(nlh); 2385 rtm = nlmsg_data(nlh);
@@ -2379,25 +2393,25 @@ static int rt6_fill_node(struct net *net,
2379 table = RT6_TABLE_UNSPEC; 2393 table = RT6_TABLE_UNSPEC;
2380 rtm->rtm_table = table; 2394 rtm->rtm_table = table;
2381 NLA_PUT_U32(skb, RTA_TABLE, table); 2395 NLA_PUT_U32(skb, RTA_TABLE, table);
2382 if (rt->rt6i_flags&RTF_REJECT) 2396 if (rt->rt6i_flags & RTF_REJECT)
2383 rtm->rtm_type = RTN_UNREACHABLE; 2397 rtm->rtm_type = RTN_UNREACHABLE;
2384 else if (rt->rt6i_flags&RTF_LOCAL) 2398 else if (rt->rt6i_flags & RTF_LOCAL)
2385 rtm->rtm_type = RTN_LOCAL; 2399 rtm->rtm_type = RTN_LOCAL;
2386 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) 2400 else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
2387 rtm->rtm_type = RTN_LOCAL; 2401 rtm->rtm_type = RTN_LOCAL;
2388 else 2402 else
2389 rtm->rtm_type = RTN_UNICAST; 2403 rtm->rtm_type = RTN_UNICAST;
2390 rtm->rtm_flags = 0; 2404 rtm->rtm_flags = 0;
2391 rtm->rtm_scope = RT_SCOPE_UNIVERSE; 2405 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
2392 rtm->rtm_protocol = rt->rt6i_protocol; 2406 rtm->rtm_protocol = rt->rt6i_protocol;
2393 if (rt->rt6i_flags&RTF_DYNAMIC) 2407 if (rt->rt6i_flags & RTF_DYNAMIC)
2394 rtm->rtm_protocol = RTPROT_REDIRECT; 2408 rtm->rtm_protocol = RTPROT_REDIRECT;
2395 else if (rt->rt6i_flags & RTF_ADDRCONF) 2409 else if (rt->rt6i_flags & RTF_ADDRCONF)
2396 rtm->rtm_protocol = RTPROT_KERNEL; 2410 rtm->rtm_protocol = RTPROT_KERNEL;
2397 else if (rt->rt6i_flags&RTF_DEFAULT) 2411 else if (rt->rt6i_flags & RTF_DEFAULT)
2398 rtm->rtm_protocol = RTPROT_RA; 2412 rtm->rtm_protocol = RTPROT_RA;
2399 2413
2400 if (rt->rt6i_flags&RTF_CACHE) 2414 if (rt->rt6i_flags & RTF_CACHE)
2401 rtm->rtm_flags |= RTM_F_CLONED; 2415 rtm->rtm_flags |= RTM_F_CLONED;
2402 2416
2403 if (dst) { 2417 if (dst) {
@@ -2437,7 +2451,7 @@ static int rt6_fill_node(struct net *net,
2437 2451
2438 if (rt->rt6i_prefsrc.plen) { 2452 if (rt->rt6i_prefsrc.plen) {
2439 struct in6_addr saddr_buf; 2453 struct in6_addr saddr_buf;
2440 ipv6_addr_copy(&saddr_buf, &rt->rt6i_prefsrc.addr); 2454 saddr_buf = rt->rt6i_prefsrc.addr;
2441 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2455 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2442 } 2456 }
2443 2457
@@ -2445,24 +2459,31 @@ static int rt6_fill_node(struct net *net,
2445 goto nla_put_failure; 2459 goto nla_put_failure;
2446 2460
2447 rcu_read_lock(); 2461 rcu_read_lock();
2448 n = dst_get_neighbour(&rt->dst); 2462 n = dst_get_neighbour_noref(&rt->dst);
2449 if (n) 2463 if (n)
2450 NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key); 2464 NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key);
2451 rcu_read_unlock(); 2465 rcu_read_unlock();
2452 2466
2453 if (rt->dst.dev) 2467 if (rt->dst.dev)
2454 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); 2468 NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex);
2455 2469
2456 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); 2470 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
2457 2471
2458 if (!(rt->rt6i_flags & RTF_EXPIRES)) 2472 if (!(rt->rt6i_flags & RTF_EXPIRES))
2459 expires = 0; 2473 expires = 0;
2460 else if (rt->rt6i_expires - jiffies < INT_MAX) 2474 else if (rt->dst.expires - jiffies < INT_MAX)
2461 expires = rt->rt6i_expires - jiffies; 2475 expires = rt->dst.expires - jiffies;
2462 else 2476 else
2463 expires = INT_MAX; 2477 expires = INT_MAX;
2464 2478
2465 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, 2479 peer = rt->rt6i_peer;
2480 ts = tsage = 0;
2481 if (peer && peer->tcp_ts_stamp) {
2482 ts = peer->tcp_ts;
2483 tsage = get_seconds() - peer->tcp_ts_stamp;
2484 }
2485
2486 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, ts, tsage,
2466 expires, rt->dst.error) < 0) 2487 expires, rt->dst.error) < 0)
2467 goto nla_put_failure; 2488 goto nla_put_failure;
2468 2489
@@ -2511,14 +2532,14 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2511 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) 2532 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
2512 goto errout; 2533 goto errout;
2513 2534
2514 ipv6_addr_copy(&fl6.saddr, nla_data(tb[RTA_SRC])); 2535 fl6.saddr = *(struct in6_addr *)nla_data(tb[RTA_SRC]);
2515 } 2536 }
2516 2537
2517 if (tb[RTA_DST]) { 2538 if (tb[RTA_DST]) {
2518 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) 2539 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
2519 goto errout; 2540 goto errout;
2520 2541
2521 ipv6_addr_copy(&fl6.daddr, nla_data(tb[RTA_DST])); 2542 fl6.daddr = *(struct in6_addr *)nla_data(tb[RTA_DST]);
2522 } 2543 }
2523 2544
2524 if (tb[RTA_IIF]) 2545 if (tb[RTA_IIF])
@@ -2537,7 +2558,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2537 } 2558 }
2538 2559
2539 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 2560 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2540 if (skb == NULL) { 2561 if (!skb) {
2541 err = -ENOBUFS; 2562 err = -ENOBUFS;
2542 goto errout; 2563 goto errout;
2543 } 2564 }
@@ -2572,10 +2593,10 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2572 int err; 2593 int err;
2573 2594
2574 err = -ENOBUFS; 2595 err = -ENOBUFS;
2575 seq = info->nlh != NULL ? info->nlh->nlmsg_seq : 0; 2596 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
2576 2597
2577 skb = nlmsg_new(rt6_nlmsg_size(), gfp_any()); 2598 skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
2578 if (skb == NULL) 2599 if (!skb)
2579 goto errout; 2600 goto errout;
2580 2601
2581 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, 2602 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
@@ -2642,7 +2663,7 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2642 seq_puts(m, "00000000000000000000000000000000 00 "); 2663 seq_puts(m, "00000000000000000000000000000000 00 ");
2643#endif 2664#endif
2644 rcu_read_lock(); 2665 rcu_read_lock();
2645 n = dst_get_neighbour(&rt->dst); 2666 n = dst_get_neighbour_noref(&rt->dst);
2646 if (n) { 2667 if (n) {
2647 seq_printf(m, "%pi6", n->primary_key); 2668 seq_printf(m, "%pi6", n->primary_key);
2648 } else { 2669 } else {
@@ -2652,7 +2673,7 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2652 seq_printf(m, " %08x %08x %08x %08x %8s\n", 2673 seq_printf(m, " %08x %08x %08x %08x %8s\n",
2653 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), 2674 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
2654 rt->dst.__use, rt->rt6i_flags, 2675 rt->dst.__use, rt->rt6i_flags,
2655 rt->rt6i_dev ? rt->rt6i_dev->name : ""); 2676 rt->dst.dev ? rt->dst.dev->name : "");
2656 return 0; 2677 return 0;
2657} 2678}
2658 2679