diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-14 13:01:14 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-14 13:01:14 -0800 |
commit | d33e455337ea2c71d09d7f4367d6ad6dd32b6965 (patch) | |
tree | d1b35b1be5ab73df6f7e57b86a2e68fad2990adf /net/ipv6 | |
parent | 9fe146aef44afe5ec677d8150b6ae94e09b773f7 (diff) | |
download | linux-d33e455337ea2c71d09d7f4367d6ad6dd32b6965.tar.bz2 |
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 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); +static unsigned int ip6_default_mtu(const struct dst_entry *dst); static struct dst_entry *ip6_negative_advice(struct dst_entry *); static void ip6_dst_destroy(struct dst_entry *); static void ip6_dst_ifdown(struct dst_entry *, @@ -105,6 +106,7 @@ static struct dst_ops ip6_dst_ops_template = { .gc_thresh = 1024, .check = ip6_dst_check, .default_advmss = ip6_default_advmss, + .default_mtu = ip6_default_mtu, .destroy = ip6_dst_destroy, .ifdown = ip6_dst_ifdown, .negative_advice = ip6_negative_advice, @@ -937,8 +939,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } } -static int ipv6_get_mtu(struct net_device *dev); - static unsigned int ip6_default_advmss(const struct dst_entry *dst) { struct net_device *dev = dst->dev; @@ -961,6 +961,20 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) return mtu; } +static unsigned int ip6_default_mtu(const struct dst_entry *dst) +{ + unsigned int mtu = IPV6_MIN_MTU; + struct inet6_dev *idev; + + rcu_read_lock(); + idev = __in6_dev_get(dst->dev); + if (idev) + mtu = idev->cnf.mtu6; + rcu_read_unlock(); + + return mtu; +} + static struct dst_entry *icmp6_dst_gc_list; static DEFINE_SPINLOCK(icmp6_dst_lock); @@ -995,7 +1009,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_nexthop = neigh; atomic_set(&rt->dst.__refcnt, 1); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); - dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); rt->dst.output = ip6_output; #if 0 /* there's no chance to use these for ndisc */ @@ -1094,19 +1107,6 @@ out: Remove it only when all the things will work! */ -static int ipv6_get_mtu(struct net_device *dev) -{ - int mtu = IPV6_MIN_MTU; - struct inet6_dev *idev; - - rcu_read_lock(); - idev = __in6_dev_get(dev); - if (idev) - mtu = idev->cnf.mtu6; - rcu_read_unlock(); - return mtu; -} - int ip6_dst_hoplimit(struct dst_entry *dst) { int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); @@ -1315,8 +1315,6 @@ install_route: } } - if (!dst_mtu(&rt->dst)) - dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); rt->dst.dev = dev; rt->rt6i_idev = idev; rt->rt6i_table = table; @@ -1541,8 +1539,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); nrt->rt6i_nexthop = neigh_clone(neigh); - /* Reset pmtu, it may be better */ - dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); if (ip6_ins_rt(nrt)) goto out; @@ -1971,7 +1967,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, rt->dst.output = ip6_output; rt->rt6i_dev = net->loopback_dev; rt->rt6i_idev = idev; - dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); rt->dst.obsolete = -1; |