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.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 026caef0326c..4aed0812b512 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -129,7 +129,6 @@ static struct rt6_info ip6_null_entry_template = {
129 .__use = 1, 129 .__use = 1,
130 .obsolete = -1, 130 .obsolete = -1,
131 .error = -ENETUNREACH, 131 .error = -ENETUNREACH,
132 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
133 .input = ip6_pkt_discard, 132 .input = ip6_pkt_discard,
134 .output = ip6_pkt_discard_out, 133 .output = ip6_pkt_discard_out,
135 }, 134 },
@@ -150,7 +149,6 @@ static struct rt6_info ip6_prohibit_entry_template = {
150 .__use = 1, 149 .__use = 1,
151 .obsolete = -1, 150 .obsolete = -1,
152 .error = -EACCES, 151 .error = -EACCES,
153 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
154 .input = ip6_pkt_prohibit, 152 .input = ip6_pkt_prohibit,
155 .output = ip6_pkt_prohibit_out, 153 .output = ip6_pkt_prohibit_out,
156 }, 154 },
@@ -166,7 +164,6 @@ static struct rt6_info ip6_blk_hole_entry_template = {
166 .__use = 1, 164 .__use = 1,
167 .obsolete = -1, 165 .obsolete = -1,
168 .error = -EINVAL, 166 .error = -EINVAL,
169 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
170 .input = dst_discard, 167 .input = dst_discard,
171 .output = dst_discard, 168 .output = dst_discard,
172 }, 169 },
@@ -844,7 +841,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
844 new->input = dst_discard; 841 new->input = dst_discard;
845 new->output = dst_discard; 842 new->output = dst_discard;
846 843
847 memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32)); 844 dst_copy_metrics(new, &ort->dst);
848 new->dev = ort->dst.dev; 845 new->dev = ort->dst.dev;
849 if (new->dev) 846 if (new->dev)
850 dev_hold(new->dev); 847 dev_hold(new->dev);
@@ -928,10 +925,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
928 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { 925 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
929 rt6->rt6i_flags |= RTF_MODIFIED; 926 rt6->rt6i_flags |= RTF_MODIFIED;
930 if (mtu < IPV6_MIN_MTU) { 927 if (mtu < IPV6_MIN_MTU) {
928 u32 features = dst_metric(dst, RTAX_FEATURES);
931 mtu = IPV6_MIN_MTU; 929 mtu = IPV6_MIN_MTU;
932 dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; 930 features |= RTAX_FEATURE_ALLFRAG;
931 dst_metric_set(dst, RTAX_FEATURES, features);
933 } 932 }
934 dst->metrics[RTAX_MTU-1] = mtu; 933 dst_metric_set(dst, RTAX_MTU, mtu);
935 call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); 934 call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
936 } 935 }
937} 936}
@@ -989,9 +988,9 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
989 rt->rt6i_idev = idev; 988 rt->rt6i_idev = idev;
990 rt->rt6i_nexthop = neigh; 989 rt->rt6i_nexthop = neigh;
991 atomic_set(&rt->dst.__refcnt, 1); 990 atomic_set(&rt->dst.__refcnt, 1);
992 rt->dst.metrics[RTAX_HOPLIMIT-1] = 255; 991 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
993 rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); 992 dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev));
994 rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst)); 993 dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst)));
995 rt->dst.output = ip6_output; 994 rt->dst.output = ip6_output;
996 995
997#if 0 /* there's no chance to use these for ndisc */ 996#if 0 /* there's no chance to use these for ndisc */
@@ -1305,17 +1304,17 @@ install_route:
1305 goto out; 1304 goto out;
1306 } 1305 }
1307 1306
1308 rt->dst.metrics[type - 1] = nla_get_u32(nla); 1307 dst_metric_set(&rt->dst, type, nla_get_u32(nla));
1309 } 1308 }
1310 } 1309 }
1311 } 1310 }
1312 1311
1313 if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0) 1312 if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0)
1314 rt->dst.metrics[RTAX_HOPLIMIT-1] = -1; 1313 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1);
1315 if (!dst_mtu(&rt->dst)) 1314 if (!dst_mtu(&rt->dst))
1316 rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); 1315 dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev));
1317 if (!dst_metric(&rt->dst, RTAX_ADVMSS)) 1316 if (!dst_metric(&rt->dst, RTAX_ADVMSS))
1318 rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst)); 1317 dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst)));
1319 rt->dst.dev = dev; 1318 rt->dst.dev = dev;
1320 rt->rt6i_idev = idev; 1319 rt->rt6i_idev = idev;
1321 rt->rt6i_table = table; 1320 rt->rt6i_table = table;
@@ -1541,9 +1540,9 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1541 ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); 1540 ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key);
1542 nrt->rt6i_nexthop = neigh_clone(neigh); 1541 nrt->rt6i_nexthop = neigh_clone(neigh);
1543 /* Reset pmtu, it may be better */ 1542 /* Reset pmtu, it may be better */
1544 nrt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); 1543 dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev));
1545 nrt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dev_net(neigh->dev), 1544 dst_metric_set(&nrt->dst, RTAX_ADVMSS, ipv6_advmss(dev_net(neigh->dev),
1546 dst_mtu(&nrt->dst)); 1545 dst_mtu(&nrt->dst)));
1547 1546
1548 if (ip6_ins_rt(nrt)) 1547 if (ip6_ins_rt(nrt))
1549 goto out; 1548 goto out;
@@ -1602,9 +1601,12 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
1602 would return automatically. 1601 would return automatically.
1603 */ 1602 */
1604 if (rt->rt6i_flags & RTF_CACHE) { 1603 if (rt->rt6i_flags & RTF_CACHE) {
1605 rt->dst.metrics[RTAX_MTU-1] = pmtu; 1604 dst_metric_set(&rt->dst, RTAX_MTU, pmtu);
1606 if (allfrag) 1605 if (allfrag) {
1607 rt->dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; 1606 u32 features = dst_metric(&rt->dst, RTAX_FEATURES);
1607 features |= RTAX_FEATURE_ALLFRAG;
1608 dst_metric_set(&rt->dst, RTAX_FEATURES, features);
1609 }
1608 dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); 1610 dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
1609 rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; 1611 rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
1610 goto out; 1612 goto out;
@@ -1621,9 +1623,12 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
1621 nrt = rt6_alloc_clone(rt, daddr); 1623 nrt = rt6_alloc_clone(rt, daddr);
1622 1624
1623 if (nrt) { 1625 if (nrt) {
1624 nrt->dst.metrics[RTAX_MTU-1] = pmtu; 1626 dst_metric_set(&nrt->dst, RTAX_MTU, pmtu);
1625 if (allfrag) 1627 if (allfrag) {
1626 nrt->dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; 1628 u32 features = dst_metric(&nrt->dst, RTAX_FEATURES);
1629 features |= RTAX_FEATURE_ALLFRAG;
1630 dst_metric_set(&nrt->dst, RTAX_FEATURES, features);
1631 }
1627 1632
1628 /* According to RFC 1981, detecting PMTU increase shouldn't be 1633 /* According to RFC 1981, detecting PMTU increase shouldn't be
1629 * happened within 5 mins, the recommended timer is 10 mins. 1634 * happened within 5 mins, the recommended timer is 10 mins.
@@ -1674,7 +1679,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1674 rt->dst.input = ort->dst.input; 1679 rt->dst.input = ort->dst.input;
1675 rt->dst.output = ort->dst.output; 1680 rt->dst.output = ort->dst.output;
1676 1681
1677 memcpy(rt->dst.metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32)); 1682 dst_copy_metrics(&rt->dst, &ort->dst);
1678 rt->dst.error = ort->dst.error; 1683 rt->dst.error = ort->dst.error;
1679 rt->dst.dev = ort->dst.dev; 1684 rt->dst.dev = ort->dst.dev;
1680 if (rt->dst.dev) 1685 if (rt->dst.dev)
@@ -1966,9 +1971,9 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1966 rt->dst.output = ip6_output; 1971 rt->dst.output = ip6_output;
1967 rt->rt6i_dev = net->loopback_dev; 1972 rt->rt6i_dev = net->loopback_dev;
1968 rt->rt6i_idev = idev; 1973 rt->rt6i_idev = idev;
1969 rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); 1974 dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev));
1970 rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst)); 1975 dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst)));
1971 rt->dst.metrics[RTAX_HOPLIMIT-1] = -1; 1976 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1);
1972 rt->dst.obsolete = -1; 1977 rt->dst.obsolete = -1;
1973 1978
1974 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; 1979 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
@@ -2068,8 +2073,8 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
2068 (dst_mtu(&rt->dst) >= arg->mtu || 2073 (dst_mtu(&rt->dst) >= arg->mtu ||
2069 (dst_mtu(&rt->dst) < arg->mtu && 2074 (dst_mtu(&rt->dst) < arg->mtu &&
2070 dst_mtu(&rt->dst) == idev->cnf.mtu6))) { 2075 dst_mtu(&rt->dst) == idev->cnf.mtu6))) {
2071 rt->dst.metrics[RTAX_MTU-1] = arg->mtu; 2076 dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
2072 rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, arg->mtu); 2077 dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, arg->mtu));
2073 } 2078 }
2074 return 0; 2079 return 0;
2075} 2080}
@@ -2295,7 +2300,7 @@ static int rt6_fill_node(struct net *net,
2295 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2300 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2296 } 2301 }
2297 2302
2298 if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) 2303 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
2299 goto nla_put_failure; 2304 goto nla_put_failure;
2300 2305
2301 if (rt->dst.neighbour) 2306 if (rt->dst.neighbour)
@@ -2686,6 +2691,7 @@ static int __net_init ip6_route_net_init(struct net *net)
2686 net->ipv6.ip6_null_entry->dst.path = 2691 net->ipv6.ip6_null_entry->dst.path =
2687 (struct dst_entry *)net->ipv6.ip6_null_entry; 2692 (struct dst_entry *)net->ipv6.ip6_null_entry;
2688 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2693 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2694 dst_metric_set(&net->ipv6.ip6_null_entry->dst, RTAX_HOPLIMIT, 255);
2689 2695
2690#ifdef CONFIG_IPV6_MULTIPLE_TABLES 2696#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2691 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, 2697 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
@@ -2696,6 +2702,7 @@ static int __net_init ip6_route_net_init(struct net *net)
2696 net->ipv6.ip6_prohibit_entry->dst.path = 2702 net->ipv6.ip6_prohibit_entry->dst.path =
2697 (struct dst_entry *)net->ipv6.ip6_prohibit_entry; 2703 (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
2698 net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2704 net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2705 dst_metric_set(&net->ipv6.ip6_prohibit_entry->dst, RTAX_HOPLIMIT, 255);
2699 2706
2700 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, 2707 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
2701 sizeof(*net->ipv6.ip6_blk_hole_entry), 2708 sizeof(*net->ipv6.ip6_blk_hole_entry),
@@ -2705,6 +2712,7 @@ static int __net_init ip6_route_net_init(struct net *net)
2705 net->ipv6.ip6_blk_hole_entry->dst.path = 2712 net->ipv6.ip6_blk_hole_entry->dst.path =
2706 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; 2713 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
2707 net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2714 net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2715 dst_metric_set(&net->ipv6.ip6_blk_hole_entry->dst, RTAX_HOPLIMIT, 255);
2708#endif 2716#endif
2709 2717
2710 net->ipv6.sysctl.flush_delay = 0; 2718 net->ipv6.sysctl.flush_delay = 0;