diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-13 15:52:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-13 15:52:14 -0500 |
commit | 0dbaee3b37e118a96bb7b8eb0d9bbaeeb46264be (patch) | |
tree | 37000c5d7e663e4ae9800a7bcde9934984b8bae9 /net/ipv6/route.c | |
parent | cc6f02dd490dac4ad821d5077b934c9b37037cd0 (diff) |
net: Abstract default ADVMSS behind an accessor.
Make all RTAX_ADVMSS metric accesses go through a new helper function,
dst_metric_advmss().
Leave the actual default metric as "zero" in the real metric slot,
and compute the actual default value dynamically via a new dst_ops
AF specific callback.
For stacked IPSEC routes, we use the advmss of the path which
preserves existing behavior.
Unlike ipv4/ipv6, DecNET ties the advmss to the mtu and thus updates
advmss on pmtu updates. This inconsistency in advmss handling
results in more raw metric accesses than I wish we ended up with.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 98796b0dc2b7..d9cb832be529 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -76,6 +76,7 @@ | |||
76 | 76 | ||
77 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); | 77 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); |
78 | static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); | 78 | static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); |
79 | static unsigned int ip6_default_advmss(const struct dst_entry *dst); | ||
79 | static struct dst_entry *ip6_negative_advice(struct dst_entry *); | 80 | static struct dst_entry *ip6_negative_advice(struct dst_entry *); |
80 | static void ip6_dst_destroy(struct dst_entry *); | 81 | static void ip6_dst_destroy(struct dst_entry *); |
81 | static void ip6_dst_ifdown(struct dst_entry *, | 82 | static void ip6_dst_ifdown(struct dst_entry *, |
@@ -103,6 +104,7 @@ static struct dst_ops ip6_dst_ops_template = { | |||
103 | .gc = ip6_dst_gc, | 104 | .gc = ip6_dst_gc, |
104 | .gc_thresh = 1024, | 105 | .gc_thresh = 1024, |
105 | .check = ip6_dst_check, | 106 | .check = ip6_dst_check, |
107 | .default_advmss = ip6_default_advmss, | ||
106 | .destroy = ip6_dst_destroy, | 108 | .destroy = ip6_dst_destroy, |
107 | .ifdown = ip6_dst_ifdown, | 109 | .ifdown = ip6_dst_ifdown, |
108 | .negative_advice = ip6_negative_advice, | 110 | .negative_advice = ip6_negative_advice, |
@@ -937,8 +939,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
937 | 939 | ||
938 | static int ipv6_get_mtu(struct net_device *dev); | 940 | static int ipv6_get_mtu(struct net_device *dev); |
939 | 941 | ||
940 | static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu) | 942 | static unsigned int ip6_default_advmss(const struct dst_entry *dst) |
941 | { | 943 | { |
944 | struct net_device *dev = dst->dev; | ||
945 | unsigned int mtu = dst_mtu(dst); | ||
946 | struct net *net = dev_net(dev); | ||
947 | |||
942 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); | 948 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); |
943 | 949 | ||
944 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) | 950 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) |
@@ -990,7 +996,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
990 | atomic_set(&rt->dst.__refcnt, 1); | 996 | atomic_set(&rt->dst.__refcnt, 1); |
991 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 997 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); |
992 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); | 998 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); |
993 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); | ||
994 | rt->dst.output = ip6_output; | 999 | rt->dst.output = ip6_output; |
995 | 1000 | ||
996 | #if 0 /* there's no chance to use these for ndisc */ | 1001 | #if 0 /* there's no chance to use these for ndisc */ |
@@ -1312,8 +1317,6 @@ install_route: | |||
1312 | 1317 | ||
1313 | if (!dst_mtu(&rt->dst)) | 1318 | if (!dst_mtu(&rt->dst)) |
1314 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); | 1319 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); |
1315 | if (!dst_metric(&rt->dst, RTAX_ADVMSS)) | ||
1316 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); | ||
1317 | rt->dst.dev = dev; | 1320 | rt->dst.dev = dev; |
1318 | rt->rt6i_idev = idev; | 1321 | rt->rt6i_idev = idev; |
1319 | rt->rt6i_table = table; | 1322 | rt->rt6i_table = table; |
@@ -1540,8 +1543,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, | |||
1540 | nrt->rt6i_nexthop = neigh_clone(neigh); | 1543 | nrt->rt6i_nexthop = neigh_clone(neigh); |
1541 | /* Reset pmtu, it may be better */ | 1544 | /* Reset pmtu, it may be better */ |
1542 | dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); | 1545 | dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); |
1543 | dst_metric_set(&nrt->dst, RTAX_ADVMSS, ipv6_advmss(dev_net(neigh->dev), | ||
1544 | dst_mtu(&nrt->dst))); | ||
1545 | 1546 | ||
1546 | if (ip6_ins_rt(nrt)) | 1547 | if (ip6_ins_rt(nrt)) |
1547 | goto out; | 1548 | goto out; |
@@ -1971,7 +1972,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1971 | rt->rt6i_dev = net->loopback_dev; | 1972 | rt->rt6i_dev = net->loopback_dev; |
1972 | rt->rt6i_idev = idev; | 1973 | rt->rt6i_idev = idev; |
1973 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); | 1974 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); |
1974 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); | ||
1975 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); | 1975 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); |
1976 | rt->dst.obsolete = -1; | 1976 | rt->dst.obsolete = -1; |
1977 | 1977 | ||
@@ -2041,7 +2041,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
2041 | { | 2041 | { |
2042 | struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; | 2042 | struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; |
2043 | struct inet6_dev *idev; | 2043 | struct inet6_dev *idev; |
2044 | struct net *net = dev_net(arg->dev); | ||
2045 | 2044 | ||
2046 | /* In IPv6 pmtu discovery is not optional, | 2045 | /* In IPv6 pmtu discovery is not optional, |
2047 | so that RTAX_MTU lock cannot disable it. | 2046 | so that RTAX_MTU lock cannot disable it. |
@@ -2073,7 +2072,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
2073 | (dst_mtu(&rt->dst) < arg->mtu && | 2072 | (dst_mtu(&rt->dst) < arg->mtu && |
2074 | dst_mtu(&rt->dst) == idev->cnf.mtu6))) { | 2073 | dst_mtu(&rt->dst) == idev->cnf.mtu6))) { |
2075 | dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); | 2074 | dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); |
2076 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, arg->mtu)); | ||
2077 | } | 2075 | } |
2078 | return 0; | 2076 | return 0; |
2079 | } | 2077 | } |