diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 66 |
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; |