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/ipv4/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/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 770f70427f0b..80997333db0c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -139,6 +139,7 @@ static unsigned long expires_ljiffies; | |||
139 | */ | 139 | */ |
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 void ipv4_dst_destroy(struct dst_entry *dst); | 143 | static void ipv4_dst_destroy(struct dst_entry *dst); |
143 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); | 144 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); |
144 | static void ipv4_link_failure(struct sk_buff *skb); | 145 | static void ipv4_link_failure(struct sk_buff *skb); |
@@ -155,6 +156,7 @@ static struct dst_ops ipv4_dst_ops = { | |||
155 | .protocol = cpu_to_be16(ETH_P_IP), | 156 | .protocol = cpu_to_be16(ETH_P_IP), |
156 | .gc = rt_garbage_collect, | 157 | .gc = rt_garbage_collect, |
157 | .check = ipv4_dst_check, | 158 | .check = ipv4_dst_check, |
159 | .default_advmss = ipv4_default_advmss, | ||
158 | .destroy = ipv4_dst_destroy, | 160 | .destroy = ipv4_dst_destroy, |
159 | .ifdown = ipv4_dst_ifdown, | 161 | .ifdown = ipv4_dst_ifdown, |
160 | .negative_advice = ipv4_negative_advice, | 162 | .negative_advice = ipv4_negative_advice, |
@@ -383,8 +385,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
383 | (__force u32)r->rt_gateway, | 385 | (__force u32)r->rt_gateway, |
384 | r->rt_flags, atomic_read(&r->dst.__refcnt), | 386 | r->rt_flags, atomic_read(&r->dst.__refcnt), |
385 | r->dst.__use, 0, (__force u32)r->rt_src, | 387 | r->dst.__use, 0, (__force u32)r->rt_src, |
386 | (dst_metric(&r->dst, RTAX_ADVMSS) ? | 388 | dst_metric_advmss(&r->dst) + 40, |
387 | (int)dst_metric(&r->dst, RTAX_ADVMSS) + 40 : 0), | ||
388 | dst_metric(&r->dst, RTAX_WINDOW), | 389 | dst_metric(&r->dst, RTAX_WINDOW), |
389 | (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + | 390 | (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + |
390 | dst_metric(&r->dst, RTAX_RTTVAR)), | 391 | dst_metric(&r->dst, RTAX_RTTVAR)), |
@@ -1798,6 +1799,19 @@ static void set_class_tag(struct rtable *rt, u32 tag) | |||
1798 | } | 1799 | } |
1799 | #endif | 1800 | #endif |
1800 | 1801 | ||
1802 | static unsigned int ipv4_default_advmss(const struct dst_entry *dst) | ||
1803 | { | ||
1804 | unsigned int advmss = dst_metric_raw(dst, RTAX_ADVMSS); | ||
1805 | |||
1806 | if (advmss == 0) { | ||
1807 | advmss = max_t(unsigned int, dst->dev->mtu - 40, | ||
1808 | ip_rt_min_advmss); | ||
1809 | if (advmss > 65535 - 40) | ||
1810 | advmss = 65535 - 40; | ||
1811 | } | ||
1812 | return advmss; | ||
1813 | } | ||
1814 | |||
1801 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | 1815 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) |
1802 | { | 1816 | { |
1803 | struct dst_entry *dst = &rt->dst; | 1817 | struct dst_entry *dst = &rt->dst; |
@@ -1823,11 +1837,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | |||
1823 | 1837 | ||
1824 | if (dst_mtu(dst) > IP_MAX_MTU) | 1838 | if (dst_mtu(dst) > IP_MAX_MTU) |
1825 | dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); | 1839 | dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); |
1826 | if (dst_metric(dst, RTAX_ADVMSS) == 0) | 1840 | if (dst_metric_raw(dst, RTAX_ADVMSS) > 65535 - 40) |
1827 | dst_metric_set(dst, RTAX_ADVMSS, | ||
1828 | max_t(unsigned int, dst->dev->mtu - 40, | ||
1829 | ip_rt_min_advmss)); | ||
1830 | if (dst_metric(dst, RTAX_ADVMSS) > 65535 - 40) | ||
1831 | dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); | 1841 | dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); |
1832 | 1842 | ||
1833 | #ifdef CONFIG_NET_CLS_ROUTE | 1843 | #ifdef CONFIG_NET_CLS_ROUTE |