diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-14 16:01:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-14 16:01:14 -0500 |
commit | d33e455337ea2c71d09d7f4367d6ad6dd32b6965 (patch) | |
tree | d1b35b1be5ab73df6f7e57b86a2e68fad2990adf /net/ipv6 | |
parent | 9fe146aef44afe5ec677d8150b6ae94e09b773f7 (diff) |
net: Abstract default MTU metric calculation behind an accessor.
Like RTAX_ADVMSS, make the default calculation go through a dst_ops
method rather than caching the computation in the routing cache
entries.
Now dst metrics are pretty much left as-is when new entries are
created, thus optimizing metric sharing becomes a real possibility.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/route.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d9cb832be529..e7efb269a6e9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -77,6 +77,7 @@ | |||
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 unsigned int ip6_default_advmss(const struct dst_entry *dst); |
80 | static unsigned int ip6_default_mtu(const struct dst_entry *dst); | ||
80 | static struct dst_entry *ip6_negative_advice(struct dst_entry *); | 81 | static struct dst_entry *ip6_negative_advice(struct dst_entry *); |
81 | static void ip6_dst_destroy(struct dst_entry *); | 82 | static void ip6_dst_destroy(struct dst_entry *); |
82 | static void ip6_dst_ifdown(struct dst_entry *, | 83 | static void ip6_dst_ifdown(struct dst_entry *, |
@@ -105,6 +106,7 @@ static struct dst_ops ip6_dst_ops_template = { | |||
105 | .gc_thresh = 1024, | 106 | .gc_thresh = 1024, |
106 | .check = ip6_dst_check, | 107 | .check = ip6_dst_check, |
107 | .default_advmss = ip6_default_advmss, | 108 | .default_advmss = ip6_default_advmss, |
109 | .default_mtu = ip6_default_mtu, | ||
108 | .destroy = ip6_dst_destroy, | 110 | .destroy = ip6_dst_destroy, |
109 | .ifdown = ip6_dst_ifdown, | 111 | .ifdown = ip6_dst_ifdown, |
110 | .negative_advice = ip6_negative_advice, | 112 | .negative_advice = ip6_negative_advice, |
@@ -937,8 +939,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
937 | } | 939 | } |
938 | } | 940 | } |
939 | 941 | ||
940 | static int ipv6_get_mtu(struct net_device *dev); | ||
941 | |||
942 | static unsigned int ip6_default_advmss(const struct dst_entry *dst) | 942 | static unsigned int ip6_default_advmss(const struct dst_entry *dst) |
943 | { | 943 | { |
944 | struct net_device *dev = dst->dev; | 944 | struct net_device *dev = dst->dev; |
@@ -961,6 +961,20 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) | |||
961 | return mtu; | 961 | return mtu; |
962 | } | 962 | } |
963 | 963 | ||
964 | static unsigned int ip6_default_mtu(const struct dst_entry *dst) | ||
965 | { | ||
966 | unsigned int mtu = IPV6_MIN_MTU; | ||
967 | struct inet6_dev *idev; | ||
968 | |||
969 | rcu_read_lock(); | ||
970 | idev = __in6_dev_get(dst->dev); | ||
971 | if (idev) | ||
972 | mtu = idev->cnf.mtu6; | ||
973 | rcu_read_unlock(); | ||
974 | |||
975 | return mtu; | ||
976 | } | ||
977 | |||
964 | static struct dst_entry *icmp6_dst_gc_list; | 978 | static struct dst_entry *icmp6_dst_gc_list; |
965 | static DEFINE_SPINLOCK(icmp6_dst_lock); | 979 | static DEFINE_SPINLOCK(icmp6_dst_lock); |
966 | 980 | ||
@@ -995,7 +1009,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
995 | rt->rt6i_nexthop = neigh; | 1009 | rt->rt6i_nexthop = neigh; |
996 | atomic_set(&rt->dst.__refcnt, 1); | 1010 | atomic_set(&rt->dst.__refcnt, 1); |
997 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 1011 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); |
998 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); | ||
999 | rt->dst.output = ip6_output; | 1012 | rt->dst.output = ip6_output; |
1000 | 1013 | ||
1001 | #if 0 /* there's no chance to use these for ndisc */ | 1014 | #if 0 /* there's no chance to use these for ndisc */ |
@@ -1094,19 +1107,6 @@ out: | |||
1094 | Remove it only when all the things will work! | 1107 | Remove it only when all the things will work! |
1095 | */ | 1108 | */ |
1096 | 1109 | ||
1097 | static int ipv6_get_mtu(struct net_device *dev) | ||
1098 | { | ||
1099 | int mtu = IPV6_MIN_MTU; | ||
1100 | struct inet6_dev *idev; | ||
1101 | |||
1102 | rcu_read_lock(); | ||
1103 | idev = __in6_dev_get(dev); | ||
1104 | if (idev) | ||
1105 | mtu = idev->cnf.mtu6; | ||
1106 | rcu_read_unlock(); | ||
1107 | return mtu; | ||
1108 | } | ||
1109 | |||
1110 | int ip6_dst_hoplimit(struct dst_entry *dst) | 1110 | int ip6_dst_hoplimit(struct dst_entry *dst) |
1111 | { | 1111 | { |
1112 | int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); | 1112 | int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); |
@@ -1315,8 +1315,6 @@ install_route: | |||
1315 | } | 1315 | } |
1316 | } | 1316 | } |
1317 | 1317 | ||
1318 | if (!dst_mtu(&rt->dst)) | ||
1319 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); | ||
1320 | rt->dst.dev = dev; | 1318 | rt->dst.dev = dev; |
1321 | rt->rt6i_idev = idev; | 1319 | rt->rt6i_idev = idev; |
1322 | rt->rt6i_table = table; | 1320 | rt->rt6i_table = table; |
@@ -1541,8 +1539,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, | |||
1541 | 1539 | ||
1542 | 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); |
1543 | nrt->rt6i_nexthop = neigh_clone(neigh); | 1541 | nrt->rt6i_nexthop = neigh_clone(neigh); |
1544 | /* Reset pmtu, it may be better */ | ||
1545 | dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); | ||
1546 | 1542 | ||
1547 | if (ip6_ins_rt(nrt)) | 1543 | if (ip6_ins_rt(nrt)) |
1548 | goto out; | 1544 | goto out; |
@@ -1971,7 +1967,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1971 | rt->dst.output = ip6_output; | 1967 | rt->dst.output = ip6_output; |
1972 | rt->rt6i_dev = net->loopback_dev; | 1968 | rt->rt6i_dev = net->loopback_dev; |
1973 | rt->rt6i_idev = idev; | 1969 | rt->rt6i_idev = idev; |
1974 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); | ||
1975 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); | 1970 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); |
1976 | rt->dst.obsolete = -1; | 1971 | rt->dst.obsolete = -1; |
1977 | 1972 | ||