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/ipv4 | |
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/ipv4')
-rw-r--r-- | net/ipv4/route.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 80997333db0..ae520963540 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -140,6 +140,7 @@ static unsigned long expires_ljiffies; | |||
140 | 140 | ||
141 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); | 141 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); |
142 | static unsigned int ipv4_default_advmss(const struct dst_entry *dst); | 142 | static unsigned int ipv4_default_advmss(const struct dst_entry *dst); |
143 | static unsigned int ipv4_default_mtu(const struct dst_entry *dst); | ||
143 | static void ipv4_dst_destroy(struct dst_entry *dst); | 144 | static void ipv4_dst_destroy(struct dst_entry *dst); |
144 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); | 145 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); |
145 | static void ipv4_link_failure(struct sk_buff *skb); | 146 | static void ipv4_link_failure(struct sk_buff *skb); |
@@ -157,6 +158,7 @@ static struct dst_ops ipv4_dst_ops = { | |||
157 | .gc = rt_garbage_collect, | 158 | .gc = rt_garbage_collect, |
158 | .check = ipv4_dst_check, | 159 | .check = ipv4_dst_check, |
159 | .default_advmss = ipv4_default_advmss, | 160 | .default_advmss = ipv4_default_advmss, |
161 | .default_mtu = ipv4_default_mtu, | ||
160 | .destroy = ipv4_dst_destroy, | 162 | .destroy = ipv4_dst_destroy, |
161 | .ifdown = ipv4_dst_ifdown, | 163 | .ifdown = ipv4_dst_ifdown, |
162 | .negative_advice = ipv4_negative_advice, | 164 | .negative_advice = ipv4_negative_advice, |
@@ -1812,6 +1814,23 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst) | |||
1812 | return advmss; | 1814 | return advmss; |
1813 | } | 1815 | } |
1814 | 1816 | ||
1817 | static unsigned int ipv4_default_mtu(const struct dst_entry *dst) | ||
1818 | { | ||
1819 | unsigned int mtu = dst->dev->mtu; | ||
1820 | |||
1821 | if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { | ||
1822 | const struct rtable *rt = (const struct rtable *) dst; | ||
1823 | |||
1824 | if (rt->rt_gateway != rt->rt_dst && mtu > 576) | ||
1825 | mtu = 576; | ||
1826 | } | ||
1827 | |||
1828 | if (mtu > IP_MAX_MTU) | ||
1829 | mtu = IP_MAX_MTU; | ||
1830 | |||
1831 | return mtu; | ||
1832 | } | ||
1833 | |||
1815 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | 1834 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) |
1816 | { | 1835 | { |
1817 | struct dst_entry *dst = &rt->dst; | 1836 | struct dst_entry *dst = &rt->dst; |
@@ -1822,18 +1841,10 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | |||
1822 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) | 1841 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) |
1823 | rt->rt_gateway = FIB_RES_GW(*res); | 1842 | rt->rt_gateway = FIB_RES_GW(*res); |
1824 | dst_import_metrics(dst, fi->fib_metrics); | 1843 | dst_import_metrics(dst, fi->fib_metrics); |
1825 | if (fi->fib_mtu == 0) { | ||
1826 | dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); | ||
1827 | if (dst_metric_locked(dst, RTAX_MTU) && | ||
1828 | rt->rt_gateway != rt->rt_dst && | ||
1829 | dst->dev->mtu > 576) | ||
1830 | dst_metric_set(dst, RTAX_MTU, 576); | ||
1831 | } | ||
1832 | #ifdef CONFIG_NET_CLS_ROUTE | 1844 | #ifdef CONFIG_NET_CLS_ROUTE |
1833 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; | 1845 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; |
1834 | #endif | 1846 | #endif |
1835 | } else | 1847 | } |
1836 | dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); | ||
1837 | 1848 | ||
1838 | if (dst_mtu(dst) > IP_MAX_MTU) | 1849 | if (dst_mtu(dst) > IP_MAX_MTU) |
1839 | dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); | 1850 | dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); |