aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-14 16:01:14 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-14 16:01:14 -0500
commitd33e455337ea2c71d09d7f4367d6ad6dd32b6965 (patch)
treed1b35b1be5ab73df6f7e57b86a2e68fad2990adf /net/ipv4
parent9fe146aef44afe5ec677d8150b6ae94e09b773f7 (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.c29
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
141static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); 141static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
142static unsigned int ipv4_default_advmss(const struct dst_entry *dst); 142static unsigned int ipv4_default_advmss(const struct dst_entry *dst);
143static unsigned int ipv4_default_mtu(const struct dst_entry *dst);
143static void ipv4_dst_destroy(struct dst_entry *dst); 144static void ipv4_dst_destroy(struct dst_entry *dst);
144static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); 145static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
145static void ipv4_link_failure(struct sk_buff *skb); 146static 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
1817static 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
1815static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) 1834static 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);