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.c186
1 files changed, 113 insertions, 73 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e7db7014e89f..6814c8722fa7 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -97,6 +97,36 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
97 struct in6_addr *gwaddr, int ifindex); 97 struct in6_addr *gwaddr, int ifindex);
98#endif 98#endif
99 99
100static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
101{
102 struct rt6_info *rt = (struct rt6_info *) dst;
103 struct inet_peer *peer;
104 u32 *p = NULL;
105
106 if (!rt->rt6i_peer)
107 rt6_bind_peer(rt, 1);
108
109 peer = rt->rt6i_peer;
110 if (peer) {
111 u32 *old_p = __DST_METRICS_PTR(old);
112 unsigned long prev, new;
113
114 p = peer->metrics;
115 if (inet_metrics_new(peer))
116 memcpy(p, old_p, sizeof(u32) * RTAX_MAX);
117
118 new = (unsigned long) p;
119 prev = cmpxchg(&dst->_metrics, old, new);
120
121 if (prev != old) {
122 p = __DST_METRICS_PTR(prev);
123 if (prev & DST_METRICS_READ_ONLY)
124 p = NULL;
125 }
126 }
127 return p;
128}
129
100static struct dst_ops ip6_dst_ops_template = { 130static struct dst_ops ip6_dst_ops_template = {
101 .family = AF_INET6, 131 .family = AF_INET6,
102 .protocol = cpu_to_be16(ETH_P_IPV6), 132 .protocol = cpu_to_be16(ETH_P_IPV6),
@@ -105,6 +135,7 @@ static struct dst_ops ip6_dst_ops_template = {
105 .check = ip6_dst_check, 135 .check = ip6_dst_check,
106 .default_advmss = ip6_default_advmss, 136 .default_advmss = ip6_default_advmss,
107 .default_mtu = ip6_default_mtu, 137 .default_mtu = ip6_default_mtu,
138 .cow_metrics = ipv6_cow_metrics,
108 .destroy = ip6_dst_destroy, 139 .destroy = ip6_dst_destroy,
109 .ifdown = ip6_dst_ifdown, 140 .ifdown = ip6_dst_ifdown,
110 .negative_advice = ip6_negative_advice, 141 .negative_advice = ip6_negative_advice,
@@ -132,6 +163,10 @@ static struct dst_ops ip6_dst_blackhole_ops = {
132 .update_pmtu = ip6_rt_blackhole_update_pmtu, 163 .update_pmtu = ip6_rt_blackhole_update_pmtu,
133}; 164};
134 165
166static const u32 ip6_template_metrics[RTAX_MAX] = {
167 [RTAX_HOPLIMIT - 1] = 255,
168};
169
135static struct rt6_info ip6_null_entry_template = { 170static struct rt6_info ip6_null_entry_template = {
136 .dst = { 171 .dst = {
137 .__refcnt = ATOMIC_INIT(1), 172 .__refcnt = ATOMIC_INIT(1),
@@ -187,7 +222,7 @@ static struct rt6_info ip6_blk_hole_entry_template = {
187/* allocate dst with ip6_dst_ops */ 222/* allocate dst with ip6_dst_ops */
188static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops) 223static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops)
189{ 224{
190 return (struct rt6_info *)dst_alloc(ops); 225 return (struct rt6_info *)dst_alloc(ops, 0);
191} 226}
192 227
193static void ip6_dst_destroy(struct dst_entry *dst) 228static void ip6_dst_destroy(struct dst_entry *dst)
@@ -206,6 +241,13 @@ static void ip6_dst_destroy(struct dst_entry *dst)
206 } 241 }
207} 242}
208 243
244static atomic_t __rt6_peer_genid = ATOMIC_INIT(0);
245
246static u32 rt6_peer_genid(void)
247{
248 return atomic_read(&__rt6_peer_genid);
249}
250
209void rt6_bind_peer(struct rt6_info *rt, int create) 251void rt6_bind_peer(struct rt6_info *rt, int create)
210{ 252{
211 struct inet_peer *peer; 253 struct inet_peer *peer;
@@ -213,6 +255,8 @@ void rt6_bind_peer(struct rt6_info *rt, int create)
213 peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); 255 peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create);
214 if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) 256 if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL)
215 inet_putpeer(peer); 257 inet_putpeer(peer);
258 else
259 rt->rt6i_peer_genid = rt6_peer_genid();
216} 260}
217 261
218static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 262static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@ -555,17 +599,17 @@ do { \
555 599
556static struct rt6_info *ip6_pol_route_lookup(struct net *net, 600static struct rt6_info *ip6_pol_route_lookup(struct net *net,
557 struct fib6_table *table, 601 struct fib6_table *table,
558 struct flowi *fl, int flags) 602 struct flowi6 *fl6, int flags)
559{ 603{
560 struct fib6_node *fn; 604 struct fib6_node *fn;
561 struct rt6_info *rt; 605 struct rt6_info *rt;
562 606
563 read_lock_bh(&table->tb6_lock); 607 read_lock_bh(&table->tb6_lock);
564 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 608 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
565restart: 609restart:
566 rt = fn->leaf; 610 rt = fn->leaf;
567 rt = rt6_device_match(net, rt, &fl->fl6_src, fl->oif, flags); 611 rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
568 BACKTRACK(net, &fl->fl6_src); 612 BACKTRACK(net, &fl6->saddr);
569out: 613out:
570 dst_use(&rt->dst, jiffies); 614 dst_use(&rt->dst, jiffies);
571 read_unlock_bh(&table->tb6_lock); 615 read_unlock_bh(&table->tb6_lock);
@@ -576,19 +620,19 @@ out:
576struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, 620struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
577 const struct in6_addr *saddr, int oif, int strict) 621 const struct in6_addr *saddr, int oif, int strict)
578{ 622{
579 struct flowi fl = { 623 struct flowi6 fl6 = {
580 .oif = oif, 624 .flowi6_oif = oif,
581 .fl6_dst = *daddr, 625 .daddr = *daddr,
582 }; 626 };
583 struct dst_entry *dst; 627 struct dst_entry *dst;
584 int flags = strict ? RT6_LOOKUP_F_IFACE : 0; 628 int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
585 629
586 if (saddr) { 630 if (saddr) {
587 memcpy(&fl.fl6_src, saddr, sizeof(*saddr)); 631 memcpy(&fl6.saddr, saddr, sizeof(*saddr));
588 flags |= RT6_LOOKUP_F_HAS_SADDR; 632 flags |= RT6_LOOKUP_F_HAS_SADDR;
589 } 633 }
590 634
591 dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_lookup); 635 dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup);
592 if (dst->error == 0) 636 if (dst->error == 0)
593 return (struct rt6_info *) dst; 637 return (struct rt6_info *) dst;
594 638
@@ -709,7 +753,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
709} 753}
710 754
711static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, 755static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
712 struct flowi *fl, int flags) 756 struct flowi6 *fl6, int flags)
713{ 757{
714 struct fib6_node *fn; 758 struct fib6_node *fn;
715 struct rt6_info *rt, *nrt; 759 struct rt6_info *rt, *nrt;
@@ -724,12 +768,12 @@ relookup:
724 read_lock_bh(&table->tb6_lock); 768 read_lock_bh(&table->tb6_lock);
725 769
726restart_2: 770restart_2:
727 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 771 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
728 772
729restart: 773restart:
730 rt = rt6_select(fn, oif, strict | reachable); 774 rt = rt6_select(fn, oif, strict | reachable);
731 775
732 BACKTRACK(net, &fl->fl6_src); 776 BACKTRACK(net, &fl6->saddr);
733 if (rt == net->ipv6.ip6_null_entry || 777 if (rt == net->ipv6.ip6_null_entry ||
734 rt->rt6i_flags & RTF_CACHE) 778 rt->rt6i_flags & RTF_CACHE)
735 goto out; 779 goto out;
@@ -738,9 +782,9 @@ restart:
738 read_unlock_bh(&table->tb6_lock); 782 read_unlock_bh(&table->tb6_lock);
739 783
740 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 784 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
741 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); 785 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
742 else if (!(rt->dst.flags & DST_HOST)) 786 else if (!(rt->dst.flags & DST_HOST))
743 nrt = rt6_alloc_clone(rt, &fl->fl6_dst); 787 nrt = rt6_alloc_clone(rt, &fl6->daddr);
744 else 788 else
745 goto out2; 789 goto out2;
746 790
@@ -779,9 +823,9 @@ out2:
779} 823}
780 824
781static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, 825static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
782 struct flowi *fl, int flags) 826 struct flowi6 *fl6, int flags)
783{ 827{
784 return ip6_pol_route(net, table, fl->iif, fl, flags); 828 return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
785} 829}
786 830
787void ip6_route_input(struct sk_buff *skb) 831void ip6_route_input(struct sk_buff *skb)
@@ -789,56 +833,54 @@ void ip6_route_input(struct sk_buff *skb)
789 struct ipv6hdr *iph = ipv6_hdr(skb); 833 struct ipv6hdr *iph = ipv6_hdr(skb);
790 struct net *net = dev_net(skb->dev); 834 struct net *net = dev_net(skb->dev);
791 int flags = RT6_LOOKUP_F_HAS_SADDR; 835 int flags = RT6_LOOKUP_F_HAS_SADDR;
792 struct flowi fl = { 836 struct flowi6 fl6 = {
793 .iif = skb->dev->ifindex, 837 .flowi6_iif = skb->dev->ifindex,
794 .fl6_dst = iph->daddr, 838 .daddr = iph->daddr,
795 .fl6_src = iph->saddr, 839 .saddr = iph->saddr,
796 .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, 840 .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
797 .mark = skb->mark, 841 .flowi6_mark = skb->mark,
798 .proto = iph->nexthdr, 842 .flowi6_proto = iph->nexthdr,
799 }; 843 };
800 844
801 if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) 845 if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
802 flags |= RT6_LOOKUP_F_IFACE; 846 flags |= RT6_LOOKUP_F_IFACE;
803 847
804 skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input)); 848 skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input));
805} 849}
806 850
807static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, 851static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
808 struct flowi *fl, int flags) 852 struct flowi6 *fl6, int flags)
809{ 853{
810 return ip6_pol_route(net, table, fl->oif, fl, flags); 854 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
811} 855}
812 856
813struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, 857struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
814 struct flowi *fl) 858 struct flowi6 *fl6)
815{ 859{
816 int flags = 0; 860 int flags = 0;
817 861
818 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst)) 862 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr))
819 flags |= RT6_LOOKUP_F_IFACE; 863 flags |= RT6_LOOKUP_F_IFACE;
820 864
821 if (!ipv6_addr_any(&fl->fl6_src)) 865 if (!ipv6_addr_any(&fl6->saddr))
822 flags |= RT6_LOOKUP_F_HAS_SADDR; 866 flags |= RT6_LOOKUP_F_HAS_SADDR;
823 else if (sk) 867 else if (sk)
824 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 868 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
825 869
826 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); 870 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
827} 871}
828 872
829EXPORT_SYMBOL(ip6_route_output); 873EXPORT_SYMBOL(ip6_route_output);
830 874
831int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl) 875struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
832{ 876{
833 struct rt6_info *ort = (struct rt6_info *) *dstp; 877 struct rt6_info *rt = dst_alloc(&ip6_dst_blackhole_ops, 1);
834 struct rt6_info *rt = (struct rt6_info *) 878 struct rt6_info *ort = (struct rt6_info *) dst_orig;
835 dst_alloc(&ip6_dst_blackhole_ops);
836 struct dst_entry *new = NULL; 879 struct dst_entry *new = NULL;
837 880
838 if (rt) { 881 if (rt) {
839 new = &rt->dst; 882 new = &rt->dst;
840 883
841 atomic_set(&new->__refcnt, 1);
842 new->__use = 1; 884 new->__use = 1;
843 new->input = dst_discard; 885 new->input = dst_discard;
844 new->output = dst_discard; 886 new->output = dst_discard;
@@ -864,11 +906,9 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
864 dst_free(new); 906 dst_free(new);
865 } 907 }
866 908
867 dst_release(*dstp); 909 dst_release(dst_orig);
868 *dstp = new; 910 return new ? new : ERR_PTR(-ENOMEM);
869 return new ? 0 : -ENOMEM;
870} 911}
871EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
872 912
873/* 913/*
874 * Destination cache support functions 914 * Destination cache support functions
@@ -880,9 +920,14 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
880 920
881 rt = (struct rt6_info *) dst; 921 rt = (struct rt6_info *) dst;
882 922
883 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) 923 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
924 if (rt->rt6i_peer_genid != rt6_peer_genid()) {
925 if (!rt->rt6i_peer)
926 rt6_bind_peer(rt, 0);
927 rt->rt6i_peer_genid = rt6_peer_genid();
928 }
884 return dst; 929 return dst;
885 930 }
886 return NULL; 931 return NULL;
887} 932}
888 933
@@ -933,7 +978,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
933 dst_metric_set(dst, RTAX_FEATURES, features); 978 dst_metric_set(dst, RTAX_FEATURES, features);
934 } 979 }
935 dst_metric_set(dst, RTAX_MTU, mtu); 980 dst_metric_set(dst, RTAX_MTU, mtu);
936 call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
937 } 981 }
938} 982}
939 983
@@ -1030,11 +1074,9 @@ out:
1030 1074
1031int icmp6_dst_gc(void) 1075int icmp6_dst_gc(void)
1032{ 1076{
1033 struct dst_entry *dst, *next, **pprev; 1077 struct dst_entry *dst, **pprev;
1034 int more = 0; 1078 int more = 0;
1035 1079
1036 next = NULL;
1037
1038 spin_lock_bh(&icmp6_dst_lock); 1080 spin_lock_bh(&icmp6_dst_lock);
1039 pprev = &icmp6_dst_gc_list; 1081 pprev = &icmp6_dst_gc_list;
1040 1082
@@ -1402,16 +1444,16 @@ static int ip6_route_del(struct fib6_config *cfg)
1402 * Handle redirects 1444 * Handle redirects
1403 */ 1445 */
1404struct ip6rd_flowi { 1446struct ip6rd_flowi {
1405 struct flowi fl; 1447 struct flowi6 fl6;
1406 struct in6_addr gateway; 1448 struct in6_addr gateway;
1407}; 1449};
1408 1450
1409static struct rt6_info *__ip6_route_redirect(struct net *net, 1451static struct rt6_info *__ip6_route_redirect(struct net *net,
1410 struct fib6_table *table, 1452 struct fib6_table *table,
1411 struct flowi *fl, 1453 struct flowi6 *fl6,
1412 int flags) 1454 int flags)
1413{ 1455{
1414 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl; 1456 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
1415 struct rt6_info *rt; 1457 struct rt6_info *rt;
1416 struct fib6_node *fn; 1458 struct fib6_node *fn;
1417 1459
@@ -1427,7 +1469,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
1427 */ 1469 */
1428 1470
1429 read_lock_bh(&table->tb6_lock); 1471 read_lock_bh(&table->tb6_lock);
1430 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 1472 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
1431restart: 1473restart:
1432 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { 1474 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
1433 /* 1475 /*
@@ -1442,7 +1484,7 @@ restart:
1442 continue; 1484 continue;
1443 if (!(rt->rt6i_flags & RTF_GATEWAY)) 1485 if (!(rt->rt6i_flags & RTF_GATEWAY))
1444 continue; 1486 continue;
1445 if (fl->oif != rt->rt6i_dev->ifindex) 1487 if (fl6->flowi6_oif != rt->rt6i_dev->ifindex)
1446 continue; 1488 continue;
1447 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway)) 1489 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
1448 continue; 1490 continue;
@@ -1451,7 +1493,7 @@ restart:
1451 1493
1452 if (!rt) 1494 if (!rt)
1453 rt = net->ipv6.ip6_null_entry; 1495 rt = net->ipv6.ip6_null_entry;
1454 BACKTRACK(net, &fl->fl6_src); 1496 BACKTRACK(net, &fl6->saddr);
1455out: 1497out:
1456 dst_hold(&rt->dst); 1498 dst_hold(&rt->dst);
1457 1499
@@ -1468,10 +1510,10 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1468 int flags = RT6_LOOKUP_F_HAS_SADDR; 1510 int flags = RT6_LOOKUP_F_HAS_SADDR;
1469 struct net *net = dev_net(dev); 1511 struct net *net = dev_net(dev);
1470 struct ip6rd_flowi rdfl = { 1512 struct ip6rd_flowi rdfl = {
1471 .fl = { 1513 .fl6 = {
1472 .oif = dev->ifindex, 1514 .flowi6_oif = dev->ifindex,
1473 .fl6_dst = *dest, 1515 .daddr = *dest,
1474 .fl6_src = *src, 1516 .saddr = *src,
1475 }, 1517 },
1476 }; 1518 };
1477 1519
@@ -1480,7 +1522,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1480 if (rt6_need_strict(dest)) 1522 if (rt6_need_strict(dest))
1481 flags |= RT6_LOOKUP_F_IFACE; 1523 flags |= RT6_LOOKUP_F_IFACE;
1482 1524
1483 return (struct rt6_info *)fib6_rule_lookup(net, (struct flowi *)&rdfl, 1525 return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6,
1484 flags, __ip6_route_redirect); 1526 flags, __ip6_route_redirect);
1485} 1527}
1486 1528
@@ -1982,12 +2024,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1982 if (IS_ERR(neigh)) { 2024 if (IS_ERR(neigh)) {
1983 dst_free(&rt->dst); 2025 dst_free(&rt->dst);
1984 2026
1985 /* We are casting this because that is the return 2027 return ERR_CAST(neigh);
1986 * value type. But an errno encoded pointer is the
1987 * same regardless of the underlying pointer type,
1988 * and that's what we are returning. So this is OK.
1989 */
1990 return (struct rt6_info *) neigh;
1991 } 2028 }
1992 rt->rt6i_nexthop = neigh; 2029 rt->rt6i_nexthop = neigh;
1993 2030
@@ -2348,7 +2385,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2348 struct rt6_info *rt; 2385 struct rt6_info *rt;
2349 struct sk_buff *skb; 2386 struct sk_buff *skb;
2350 struct rtmsg *rtm; 2387 struct rtmsg *rtm;
2351 struct flowi fl; 2388 struct flowi6 fl6;
2352 int err, iif = 0; 2389 int err, iif = 0;
2353 2390
2354 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); 2391 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
@@ -2356,27 +2393,27 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2356 goto errout; 2393 goto errout;
2357 2394
2358 err = -EINVAL; 2395 err = -EINVAL;
2359 memset(&fl, 0, sizeof(fl)); 2396 memset(&fl6, 0, sizeof(fl6));
2360 2397
2361 if (tb[RTA_SRC]) { 2398 if (tb[RTA_SRC]) {
2362 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) 2399 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
2363 goto errout; 2400 goto errout;
2364 2401
2365 ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC])); 2402 ipv6_addr_copy(&fl6.saddr, nla_data(tb[RTA_SRC]));
2366 } 2403 }
2367 2404
2368 if (tb[RTA_DST]) { 2405 if (tb[RTA_DST]) {
2369 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) 2406 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
2370 goto errout; 2407 goto errout;
2371 2408
2372 ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST])); 2409 ipv6_addr_copy(&fl6.daddr, nla_data(tb[RTA_DST]));
2373 } 2410 }
2374 2411
2375 if (tb[RTA_IIF]) 2412 if (tb[RTA_IIF])
2376 iif = nla_get_u32(tb[RTA_IIF]); 2413 iif = nla_get_u32(tb[RTA_IIF]);
2377 2414
2378 if (tb[RTA_OIF]) 2415 if (tb[RTA_OIF])
2379 fl.oif = nla_get_u32(tb[RTA_OIF]); 2416 fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]);
2380 2417
2381 if (iif) { 2418 if (iif) {
2382 struct net_device *dev; 2419 struct net_device *dev;
@@ -2399,10 +2436,10 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2399 skb_reset_mac_header(skb); 2436 skb_reset_mac_header(skb);
2400 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); 2437 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
2401 2438
2402 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); 2439 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6);
2403 skb_dst_set(skb, &rt->dst); 2440 skb_dst_set(skb, &rt->dst);
2404 2441
2405 err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, 2442 err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
2406 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2443 RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
2407 nlh->nlmsg_seq, 0, 0, 0); 2444 nlh->nlmsg_seq, 0, 0, 0);
2408 if (err < 0) { 2445 if (err < 0) {
@@ -2689,7 +2726,8 @@ static int __net_init ip6_route_net_init(struct net *net)
2689 net->ipv6.ip6_null_entry->dst.path = 2726 net->ipv6.ip6_null_entry->dst.path =
2690 (struct dst_entry *)net->ipv6.ip6_null_entry; 2727 (struct dst_entry *)net->ipv6.ip6_null_entry;
2691 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2728 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2692 dst_metric_set(&net->ipv6.ip6_null_entry->dst, RTAX_HOPLIMIT, 255); 2729 dst_init_metrics(&net->ipv6.ip6_null_entry->dst,
2730 ip6_template_metrics, true);
2693 2731
2694#ifdef CONFIG_IPV6_MULTIPLE_TABLES 2732#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2695 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, 2733 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
@@ -2700,7 +2738,8 @@ static int __net_init ip6_route_net_init(struct net *net)
2700 net->ipv6.ip6_prohibit_entry->dst.path = 2738 net->ipv6.ip6_prohibit_entry->dst.path =
2701 (struct dst_entry *)net->ipv6.ip6_prohibit_entry; 2739 (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
2702 net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2740 net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2703 dst_metric_set(&net->ipv6.ip6_prohibit_entry->dst, RTAX_HOPLIMIT, 255); 2741 dst_init_metrics(&net->ipv6.ip6_prohibit_entry->dst,
2742 ip6_template_metrics, true);
2704 2743
2705 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, 2744 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
2706 sizeof(*net->ipv6.ip6_blk_hole_entry), 2745 sizeof(*net->ipv6.ip6_blk_hole_entry),
@@ -2710,7 +2749,8 @@ static int __net_init ip6_route_net_init(struct net *net)
2710 net->ipv6.ip6_blk_hole_entry->dst.path = 2749 net->ipv6.ip6_blk_hole_entry->dst.path =
2711 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; 2750 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
2712 net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2751 net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2713 dst_metric_set(&net->ipv6.ip6_blk_hole_entry->dst, RTAX_HOPLIMIT, 255); 2752 dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
2753 ip6_template_metrics, true);
2714#endif 2754#endif
2715 2755
2716 net->ipv6.sysctl.flush_delay = 0; 2756 net->ipv6.sysctl.flush_delay = 0;