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.c110
1 files changed, 59 insertions, 51 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index de2b1decd786..e8987da06667 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -72,7 +72,8 @@
72#define RT6_TRACE(x...) do { ; } while (0) 72#define RT6_TRACE(x...) do { ; } while (0)
73#endif 73#endif
74 74
75static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); 75static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
76 const struct in6_addr *dest);
76static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); 77static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
77static unsigned int ip6_default_advmss(const struct dst_entry *dst); 78static unsigned int ip6_default_advmss(const struct dst_entry *dst);
78static unsigned int ip6_default_mtu(const struct dst_entry *dst); 79static unsigned int ip6_default_mtu(const struct dst_entry *dst);
@@ -127,6 +128,11 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
127 return p; 128 return p;
128} 129}
129 130
131static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr)
132{
133 return __neigh_lookup_errno(&nd_tbl, daddr, dst->dev);
134}
135
130static struct dst_ops ip6_dst_ops_template = { 136static struct dst_ops ip6_dst_ops_template = {
131 .family = AF_INET6, 137 .family = AF_INET6,
132 .protocol = cpu_to_be16(ETH_P_IPV6), 138 .protocol = cpu_to_be16(ETH_P_IPV6),
@@ -142,6 +148,7 @@ static struct dst_ops ip6_dst_ops_template = {
142 .link_failure = ip6_link_failure, 148 .link_failure = ip6_link_failure,
143 .update_pmtu = ip6_rt_update_pmtu, 149 .update_pmtu = ip6_rt_update_pmtu,
144 .local_out = __ip6_local_out, 150 .local_out = __ip6_local_out,
151 .neigh_lookup = ip6_neigh_lookup,
145}; 152};
146 153
147static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) 154static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst)
@@ -168,6 +175,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
168 .default_advmss = ip6_default_advmss, 175 .default_advmss = ip6_default_advmss,
169 .update_pmtu = ip6_rt_blackhole_update_pmtu, 176 .update_pmtu = ip6_rt_blackhole_update_pmtu,
170 .cow_metrics = ip6_rt_blackhole_cow_metrics, 177 .cow_metrics = ip6_rt_blackhole_cow_metrics,
178 .neigh_lookup = ip6_neigh_lookup,
171}; 179};
172 180
173static const u32 ip6_template_metrics[RTAX_MAX] = { 181static const u32 ip6_template_metrics[RTAX_MAX] = {
@@ -228,9 +236,10 @@ static struct rt6_info ip6_blk_hole_entry_template = {
228 236
229/* allocate dst with ip6_dst_ops */ 237/* allocate dst with ip6_dst_ops */
230static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, 238static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
231 struct net_device *dev) 239 struct net_device *dev,
240 int flags)
232{ 241{
233 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0); 242 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags);
234 243
235 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); 244 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
236 245
@@ -355,7 +364,7 @@ out:
355#ifdef CONFIG_IPV6_ROUTER_PREF 364#ifdef CONFIG_IPV6_ROUTER_PREF
356static void rt6_probe(struct rt6_info *rt) 365static void rt6_probe(struct rt6_info *rt)
357{ 366{
358 struct neighbour *neigh = rt ? rt->rt6i_nexthop : NULL; 367 struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL;
359 /* 368 /*
360 * Okay, this does not seem to be appropriate 369 * Okay, this does not seem to be appropriate
361 * for now, however, we need to check if it 370 * for now, however, we need to check if it
@@ -403,7 +412,7 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif)
403 412
404static inline int rt6_check_neigh(struct rt6_info *rt) 413static inline int rt6_check_neigh(struct rt6_info *rt)
405{ 414{
406 struct neighbour *neigh = rt->rt6i_nexthop; 415 struct neighbour *neigh = dst_get_neighbour(&rt->dst);
407 int m; 416 int m;
408 if (rt->rt6i_flags & RTF_NONEXTHOP || 417 if (rt->rt6i_flags & RTF_NONEXTHOP ||
409 !(rt->rt6i_flags & RTF_GATEWAY)) 418 !(rt->rt6i_flags & RTF_GATEWAY))
@@ -682,7 +691,8 @@ int ip6_ins_rt(struct rt6_info *rt)
682 return __ip6_ins_rt(rt, &info); 691 return __ip6_ins_rt(rt, &info);
683} 692}
684 693
685static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_addr *daddr, 694static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort,
695 const struct in6_addr *daddr,
686 const struct in6_addr *saddr) 696 const struct in6_addr *saddr)
687{ 697{
688 struct rt6_info *rt; 698 struct rt6_info *rt;
@@ -691,7 +701,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add
691 * Clone the route. 701 * Clone the route.
692 */ 702 */
693 703
694 rt = ip6_rt_copy(ort); 704 rt = ip6_rt_copy(ort, daddr);
695 705
696 if (rt) { 706 if (rt) {
697 struct neighbour *neigh; 707 struct neighbour *neigh;
@@ -699,12 +709,11 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add
699 709
700 if (!(rt->rt6i_flags&RTF_GATEWAY)) { 710 if (!(rt->rt6i_flags&RTF_GATEWAY)) {
701 if (rt->rt6i_dst.plen != 128 && 711 if (rt->rt6i_dst.plen != 128 &&
702 ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)) 712 ipv6_addr_equal(&ort->rt6i_dst.addr, daddr))
703 rt->rt6i_flags |= RTF_ANYCAST; 713 rt->rt6i_flags |= RTF_ANYCAST;
704 ipv6_addr_copy(&rt->rt6i_gateway, daddr); 714 ipv6_addr_copy(&rt->rt6i_gateway, daddr);
705 } 715 }
706 716
707 ipv6_addr_copy(&rt->rt6i_dst.addr, daddr);
708 rt->rt6i_dst.plen = 128; 717 rt->rt6i_dst.plen = 128;
709 rt->rt6i_flags |= RTF_CACHE; 718 rt->rt6i_flags |= RTF_CACHE;
710 rt->dst.flags |= DST_HOST; 719 rt->dst.flags |= DST_HOST;
@@ -744,22 +753,23 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add
744 dst_free(&rt->dst); 753 dst_free(&rt->dst);
745 return NULL; 754 return NULL;
746 } 755 }
747 rt->rt6i_nexthop = neigh; 756 dst_set_neighbour(&rt->dst, neigh);
748 757
749 } 758 }
750 759
751 return rt; 760 return rt;
752} 761}
753 762
754static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr) 763static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
764 const struct in6_addr *daddr)
755{ 765{
756 struct rt6_info *rt = ip6_rt_copy(ort); 766 struct rt6_info *rt = ip6_rt_copy(ort, daddr);
767
757 if (rt) { 768 if (rt) {
758 ipv6_addr_copy(&rt->rt6i_dst.addr, daddr);
759 rt->rt6i_dst.plen = 128; 769 rt->rt6i_dst.plen = 128;
760 rt->rt6i_flags |= RTF_CACHE; 770 rt->rt6i_flags |= RTF_CACHE;
761 rt->dst.flags |= DST_HOST; 771 rt->dst.flags |= DST_HOST;
762 rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop); 772 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst)));
763 } 773 }
764 return rt; 774 return rt;
765} 775}
@@ -793,7 +803,7 @@ restart:
793 dst_hold(&rt->dst); 803 dst_hold(&rt->dst);
794 read_unlock_bh(&table->tb6_lock); 804 read_unlock_bh(&table->tb6_lock);
795 805
796 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 806 if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
797 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); 807 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
798 else if (!(rt->dst.flags & DST_HOST)) 808 else if (!(rt->dst.flags & DST_HOST))
799 nrt = rt6_alloc_clone(rt, &fl6->daddr); 809 nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -899,7 +909,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
899 new->input = dst_discard; 909 new->input = dst_discard;
900 new->output = dst_discard; 910 new->output = dst_discard;
901 911
902 dst_copy_metrics(new, &ort->dst); 912 if (dst_metrics_read_only(&ort->dst))
913 new->_metrics = ort->dst._metrics;
914 else
915 dst_copy_metrics(new, &ort->dst);
903 rt->rt6i_idev = ort->rt6i_idev; 916 rt->rt6i_idev = ort->rt6i_idev;
904 if (rt->rt6i_idev) 917 if (rt->rt6i_idev)
905 in6_dev_hold(rt->rt6i_idev); 918 in6_dev_hold(rt->rt6i_idev);
@@ -1042,7 +1055,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1042 if (unlikely(idev == NULL)) 1055 if (unlikely(idev == NULL))
1043 return NULL; 1056 return NULL;
1044 1057
1045 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev); 1058 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0);
1046 if (unlikely(rt == NULL)) { 1059 if (unlikely(rt == NULL)) {
1047 in6_dev_put(idev); 1060 in6_dev_put(idev);
1048 goto out; 1061 goto out;
@@ -1057,19 +1070,12 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1057 } 1070 }
1058 1071
1059 rt->rt6i_idev = idev; 1072 rt->rt6i_idev = idev;
1060 rt->rt6i_nexthop = neigh; 1073 dst_set_neighbour(&rt->dst, neigh);
1061 atomic_set(&rt->dst.__refcnt, 1); 1074 atomic_set(&rt->dst.__refcnt, 1);
1075 ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
1062 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); 1076 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
1063 rt->dst.output = ip6_output; 1077 rt->dst.output = ip6_output;
1064 1078
1065#if 0 /* there's no chance to use these for ndisc */
1066 rt->dst.flags = ipv6_addr_type(addr) & IPV6_ADDR_UNICAST
1067 ? DST_HOST
1068 : 0;
1069 ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
1070 rt->rt6i_dst.plen = 128;
1071#endif
1072
1073 spin_lock_bh(&icmp6_dst_lock); 1079 spin_lock_bh(&icmp6_dst_lock);
1074 rt->dst.next = icmp6_dst_gc_list; 1080 rt->dst.next = icmp6_dst_gc_list;
1075 icmp6_dst_gc_list = &rt->dst; 1081 icmp6_dst_gc_list = &rt->dst;
@@ -1214,7 +1220,7 @@ int ip6_route_add(struct fib6_config *cfg)
1214 goto out; 1220 goto out;
1215 } 1221 }
1216 1222
1217 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL); 1223 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT);
1218 1224
1219 if (rt == NULL) { 1225 if (rt == NULL) {
1220 err = -ENOMEM; 1226 err = -ENOMEM;
@@ -1244,7 +1250,7 @@ int ip6_route_add(struct fib6_config *cfg)
1244 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); 1250 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
1245 rt->rt6i_dst.plen = cfg->fc_dst_len; 1251 rt->rt6i_dst.plen = cfg->fc_dst_len;
1246 if (rt->rt6i_dst.plen == 128) 1252 if (rt->rt6i_dst.plen == 128)
1247 rt->dst.flags = DST_HOST; 1253 rt->dst.flags |= DST_HOST;
1248 1254
1249#ifdef CONFIG_IPV6_SUBTREES 1255#ifdef CONFIG_IPV6_SUBTREES
1250 ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); 1256 ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len);
@@ -1345,12 +1351,12 @@ int ip6_route_add(struct fib6_config *cfg)
1345 rt->rt6i_prefsrc.plen = 0; 1351 rt->rt6i_prefsrc.plen = 0;
1346 1352
1347 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) { 1353 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
1348 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); 1354 struct neighbour *n = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
1349 if (IS_ERR(rt->rt6i_nexthop)) { 1355 if (IS_ERR(n)) {
1350 err = PTR_ERR(rt->rt6i_nexthop); 1356 err = PTR_ERR(n);
1351 rt->rt6i_nexthop = NULL;
1352 goto out; 1357 goto out;
1353 } 1358 }
1359 dst_set_neighbour(&rt->dst, n);
1354 } 1360 }
1355 1361
1356 rt->rt6i_flags = cfg->fc_flags; 1362 rt->rt6i_flags = cfg->fc_flags;
@@ -1581,10 +1587,10 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1581 dst_confirm(&rt->dst); 1587 dst_confirm(&rt->dst);
1582 1588
1583 /* Duplicate redirect: silently ignore. */ 1589 /* Duplicate redirect: silently ignore. */
1584 if (neigh == rt->dst.neighbour) 1590 if (neigh == dst_get_neighbour(&rt->dst))
1585 goto out; 1591 goto out;
1586 1592
1587 nrt = ip6_rt_copy(rt); 1593 nrt = ip6_rt_copy(rt, dest);
1588 if (nrt == NULL) 1594 if (nrt == NULL)
1589 goto out; 1595 goto out;
1590 1596
@@ -1592,12 +1598,11 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1592 if (on_link) 1598 if (on_link)
1593 nrt->rt6i_flags &= ~RTF_GATEWAY; 1599 nrt->rt6i_flags &= ~RTF_GATEWAY;
1594 1600
1595 ipv6_addr_copy(&nrt->rt6i_dst.addr, dest);
1596 nrt->rt6i_dst.plen = 128; 1601 nrt->rt6i_dst.plen = 128;
1597 nrt->dst.flags |= DST_HOST; 1602 nrt->dst.flags |= DST_HOST;
1598 1603
1599 ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); 1604 ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key);
1600 nrt->rt6i_nexthop = neigh_clone(neigh); 1605 dst_set_neighbour(&nrt->dst, neigh_clone(neigh));
1601 1606
1602 if (ip6_ins_rt(nrt)) 1607 if (ip6_ins_rt(nrt))
1603 goto out; 1608 goto out;
@@ -1677,7 +1682,7 @@ again:
1677 1. It is connected route. Action: COW 1682 1. It is connected route. Action: COW
1678 2. It is gatewayed route or NONEXTHOP route. Action: clone it. 1683 2. It is gatewayed route or NONEXTHOP route. Action: clone it.
1679 */ 1684 */
1680 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 1685 if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
1681 nrt = rt6_alloc_cow(rt, daddr, saddr); 1686 nrt = rt6_alloc_cow(rt, daddr, saddr);
1682 else 1687 else
1683 nrt = rt6_alloc_clone(rt, daddr); 1688 nrt = rt6_alloc_clone(rt, daddr);
@@ -1730,16 +1735,19 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad
1730 * Misc support functions 1735 * Misc support functions
1731 */ 1736 */
1732 1737
1733static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) 1738static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
1739 const struct in6_addr *dest)
1734{ 1740{
1735 struct net *net = dev_net(ort->rt6i_dev); 1741 struct net *net = dev_net(ort->rt6i_dev);
1736 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, 1742 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
1737 ort->dst.dev); 1743 ort->dst.dev, 0);
1738 1744
1739 if (rt) { 1745 if (rt) {
1740 rt->dst.input = ort->dst.input; 1746 rt->dst.input = ort->dst.input;
1741 rt->dst.output = ort->dst.output; 1747 rt->dst.output = ort->dst.output;
1742 1748
1749 ipv6_addr_copy(&rt->rt6i_dst.addr, dest);
1750 rt->rt6i_dst.plen = ort->rt6i_dst.plen;
1743 dst_copy_metrics(&rt->dst, &ort->dst); 1751 dst_copy_metrics(&rt->dst, &ort->dst);
1744 rt->dst.error = ort->dst.error; 1752 rt->dst.error = ort->dst.error;
1745 rt->rt6i_idev = ort->rt6i_idev; 1753 rt->rt6i_idev = ort->rt6i_idev;
@@ -1752,7 +1760,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1752 rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; 1760 rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
1753 rt->rt6i_metric = 0; 1761 rt->rt6i_metric = 0;
1754 1762
1755 memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
1756#ifdef CONFIG_IPV6_SUBTREES 1763#ifdef CONFIG_IPV6_SUBTREES
1757 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); 1764 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
1758#endif 1765#endif
@@ -2013,7 +2020,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2013{ 2020{
2014 struct net *net = dev_net(idev->dev); 2021 struct net *net = dev_net(idev->dev);
2015 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, 2022 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
2016 net->loopback_dev); 2023 net->loopback_dev, 0);
2017 struct neighbour *neigh; 2024 struct neighbour *neigh;
2018 2025
2019 if (rt == NULL) { 2026 if (rt == NULL) {
@@ -2025,7 +2032,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2025 2032
2026 in6_dev_hold(idev); 2033 in6_dev_hold(idev);
2027 2034
2028 rt->dst.flags = DST_HOST; 2035 rt->dst.flags |= DST_HOST;
2029 rt->dst.input = ip6_input; 2036 rt->dst.input = ip6_input;
2030 rt->dst.output = ip6_output; 2037 rt->dst.output = ip6_output;
2031 rt->rt6i_idev = idev; 2038 rt->rt6i_idev = idev;
@@ -2042,7 +2049,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2042 2049
2043 return ERR_CAST(neigh); 2050 return ERR_CAST(neigh);
2044 } 2051 }
2045 rt->rt6i_nexthop = neigh; 2052 dst_set_neighbour(&rt->dst, neigh);
2046 2053
2047 ipv6_addr_copy(&rt->rt6i_dst.addr, addr); 2054 ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
2048 rt->rt6i_dst.plen = 128; 2055 rt->rt6i_dst.plen = 128;
@@ -2407,8 +2414,8 @@ static int rt6_fill_node(struct net *net,
2407 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 2414 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
2408 goto nla_put_failure; 2415 goto nla_put_failure;
2409 2416
2410 if (rt->dst.neighbour) 2417 if (dst_get_neighbour(&rt->dst))
2411 NLA_PUT(skb, RTA_GATEWAY, 16, &rt->dst.neighbour->primary_key); 2418 NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key);
2412 2419
2413 if (rt->dst.dev) 2420 if (rt->dst.dev)
2414 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); 2421 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
@@ -2592,6 +2599,7 @@ struct rt6_proc_arg
2592static int rt6_info_route(struct rt6_info *rt, void *p_arg) 2599static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2593{ 2600{
2594 struct seq_file *m = p_arg; 2601 struct seq_file *m = p_arg;
2602 struct neighbour *n;
2595 2603
2596 seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); 2604 seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
2597 2605
@@ -2600,9 +2608,9 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2600#else 2608#else
2601 seq_puts(m, "00000000000000000000000000000000 00 "); 2609 seq_puts(m, "00000000000000000000000000000000 00 ");
2602#endif 2610#endif
2603 2611 n = dst_get_neighbour(&rt->dst);
2604 if (rt->rt6i_nexthop) { 2612 if (n) {
2605 seq_printf(m, "%pi6", rt->rt6i_nexthop->primary_key); 2613 seq_printf(m, "%pi6", n->primary_key);
2606 } else { 2614 } else {
2607 seq_puts(m, "00000000000000000000000000000000"); 2615 seq_puts(m, "00000000000000000000000000000000");
2608 } 2616 }
@@ -2925,9 +2933,9 @@ int __init ip6_route_init(void)
2925 goto xfrm6_init; 2933 goto xfrm6_init;
2926 2934
2927 ret = -ENOBUFS; 2935 ret = -ENOBUFS;
2928 if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL) || 2936 if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) ||
2929 __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL) || 2937 __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) ||
2930 __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL)) 2938 __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL))
2931 goto fib6_rules_init; 2939 goto fib6_rules_init;
2932 2940
2933 ret = register_netdevice_notifier(&ip6_route_dev_notifier); 2941 ret = register_netdevice_notifier(&ip6_route_dev_notifier);