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 | |
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')
-rw-r--r-- | net/decnet/af_decnet.c | 4 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 22 | ||||
-rw-r--r-- | net/ipv4/route.c | 24 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 14 | ||||
-rw-r--r-- | net/ipv6/route.c | 16 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 7 |
8 files changed, 60 insertions, 31 deletions
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 0065e7e14af4..2af15b15d1fa 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -829,7 +829,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) | |||
829 | return -EINVAL; | 829 | return -EINVAL; |
830 | 830 | ||
831 | scp->state = DN_CC; | 831 | scp->state = DN_CC; |
832 | scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS); | 832 | scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk)); |
833 | dn_send_conn_conf(sk, allocation); | 833 | dn_send_conn_conf(sk, allocation); |
834 | 834 | ||
835 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 835 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
@@ -958,7 +958,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen, | |||
958 | sk->sk_route_caps = sk->sk_dst_cache->dev->features; | 958 | sk->sk_route_caps = sk->sk_dst_cache->dev->features; |
959 | sock->state = SS_CONNECTING; | 959 | sock->state = SS_CONNECTING; |
960 | scp->state = DN_CI; | 960 | scp->state = DN_CI; |
961 | scp->segsize_loc = dst_metric(sk->sk_dst_cache, RTAX_ADVMSS); | 961 | scp->segsize_loc = dst_metric_advmss(sk->sk_dst_cache); |
962 | 962 | ||
963 | dn_nsp_send_conninit(sk, NSP_CI); | 963 | dn_nsp_send_conninit(sk, NSP_CI); |
964 | err = -EINPROGRESS; | 964 | err = -EINPROGRESS; |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index e2e926841fe6..b8a5c0515be8 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -110,6 +110,7 @@ static unsigned long dn_rt_deadline; | |||
110 | 110 | ||
111 | static int dn_dst_gc(struct dst_ops *ops); | 111 | static int dn_dst_gc(struct dst_ops *ops); |
112 | static struct dst_entry *dn_dst_check(struct dst_entry *, __u32); | 112 | static struct dst_entry *dn_dst_check(struct dst_entry *, __u32); |
113 | static unsigned int dn_dst_default_advmss(const struct dst_entry *dst); | ||
113 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); | 114 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); |
114 | static void dn_dst_link_failure(struct sk_buff *); | 115 | static void dn_dst_link_failure(struct sk_buff *); |
115 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); | 116 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); |
@@ -129,6 +130,7 @@ static struct dst_ops dn_dst_ops = { | |||
129 | .gc_thresh = 128, | 130 | .gc_thresh = 128, |
130 | .gc = dn_dst_gc, | 131 | .gc = dn_dst_gc, |
131 | .check = dn_dst_check, | 132 | .check = dn_dst_check, |
133 | .default_advmss = dn_dst_default_advmss, | ||
132 | .negative_advice = dn_dst_negative_advice, | 134 | .negative_advice = dn_dst_negative_advice, |
133 | .link_failure = dn_dst_link_failure, | 135 | .link_failure = dn_dst_link_failure, |
134 | .update_pmtu = dn_dst_update_pmtu, | 136 | .update_pmtu = dn_dst_update_pmtu, |
@@ -245,7 +247,8 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
245 | } | 247 | } |
246 | if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { | 248 | if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { |
247 | u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; | 249 | u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; |
248 | if (dst_metric(dst, RTAX_ADVMSS) > mss) | 250 | u32 existing_mss = dst_metric_raw(dst, RTAX_ADVMSS); |
251 | if (!existing_mss || existing_mss > mss) | ||
249 | dst_metric_set(dst, RTAX_ADVMSS, mss); | 252 | dst_metric_set(dst, RTAX_ADVMSS, mss); |
250 | } | 253 | } |
251 | } | 254 | } |
@@ -795,12 +798,17 @@ static int dn_rt_bug(struct sk_buff *skb) | |||
795 | return NET_RX_DROP; | 798 | return NET_RX_DROP; |
796 | } | 799 | } |
797 | 800 | ||
801 | static unsigned int dn_dst_default_advmss(const struct dst_entry *dst) | ||
802 | { | ||
803 | return dn_mss_from_pmtu(dst->dev, dst_mtu(dst)); | ||
804 | } | ||
805 | |||
798 | static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) | 806 | static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) |
799 | { | 807 | { |
800 | struct dn_fib_info *fi = res->fi; | 808 | struct dn_fib_info *fi = res->fi; |
801 | struct net_device *dev = rt->dst.dev; | 809 | struct net_device *dev = rt->dst.dev; |
802 | struct neighbour *n; | 810 | struct neighbour *n; |
803 | unsigned mss; | 811 | unsigned int metric; |
804 | 812 | ||
805 | if (fi) { | 813 | if (fi) { |
806 | if (DN_FIB_RES_GW(*res) && | 814 | if (DN_FIB_RES_GW(*res) && |
@@ -820,10 +828,12 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) | |||
820 | if (dst_metric(&rt->dst, RTAX_MTU) == 0 || | 828 | if (dst_metric(&rt->dst, RTAX_MTU) == 0 || |
821 | dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) | 829 | dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) |
822 | dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu); | 830 | dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu); |
823 | mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst)); | 831 | metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS); |
824 | if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 || | 832 | if (metric) { |
825 | dst_metric(&rt->dst, RTAX_ADVMSS) > mss) | 833 | unsigned int mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst)); |
826 | dst_metric_set(&rt->dst, RTAX_ADVMSS, mss); | 834 | if (metric > mss) |
835 | dst_metric_set(&rt->dst, RTAX_ADVMSS, mss); | ||
836 | } | ||
827 | return 0; | 837 | return 0; |
828 | } | 838 | } |
829 | 839 | ||
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 |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4fc3387aa994..f4011027543d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1436,7 +1436,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1436 | 1436 | ||
1437 | tcp_mtup_init(newsk); | 1437 | tcp_mtup_init(newsk); |
1438 | tcp_sync_mss(newsk, dst_mtu(dst)); | 1438 | tcp_sync_mss(newsk, dst_mtu(dst)); |
1439 | newtp->advmss = dst_metric(dst, RTAX_ADVMSS); | 1439 | newtp->advmss = dst_metric_advmss(dst); |
1440 | if (tcp_sk(sk)->rx_opt.user_mss && | 1440 | if (tcp_sk(sk)->rx_opt.user_mss && |
1441 | tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) | 1441 | tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) |
1442 | newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; | 1442 | newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 97041f24cd27..2d390669d406 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -119,9 +119,13 @@ static __u16 tcp_advertise_mss(struct sock *sk) | |||
119 | struct dst_entry *dst = __sk_dst_get(sk); | 119 | struct dst_entry *dst = __sk_dst_get(sk); |
120 | int mss = tp->advmss; | 120 | int mss = tp->advmss; |
121 | 121 | ||
122 | if (dst && dst_metric(dst, RTAX_ADVMSS) < mss) { | 122 | if (dst) { |
123 | mss = dst_metric(dst, RTAX_ADVMSS); | 123 | unsigned int metric = dst_metric_advmss(dst); |
124 | tp->advmss = mss; | 124 | |
125 | if (metric < mss) { | ||
126 | mss = metric; | ||
127 | tp->advmss = mss; | ||
128 | } | ||
125 | } | 129 | } |
126 | 130 | ||
127 | return (__u16)mss; | 131 | return (__u16)mss; |
@@ -2422,7 +2426,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2422 | 2426 | ||
2423 | skb_dst_set(skb, dst_clone(dst)); | 2427 | skb_dst_set(skb, dst_clone(dst)); |
2424 | 2428 | ||
2425 | mss = dst_metric(dst, RTAX_ADVMSS); | 2429 | mss = dst_metric_advmss(dst); |
2426 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) | 2430 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) |
2427 | mss = tp->rx_opt.user_mss; | 2431 | mss = tp->rx_opt.user_mss; |
2428 | 2432 | ||
@@ -2556,7 +2560,7 @@ static void tcp_connect_init(struct sock *sk) | |||
2556 | 2560 | ||
2557 | if (!tp->window_clamp) | 2561 | if (!tp->window_clamp) |
2558 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); | 2562 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); |
2559 | tp->advmss = dst_metric(dst, RTAX_ADVMSS); | 2563 | tp->advmss = dst_metric_advmss(dst); |
2560 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss) | 2564 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss) |
2561 | tp->advmss = tp->rx_opt.user_mss; | 2565 | tp->advmss = tp->rx_opt.user_mss; |
2562 | 2566 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 98796b0dc2b7..d9cb832be529 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -76,6 +76,7 @@ | |||
76 | 76 | ||
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 struct dst_entry *ip6_negative_advice(struct dst_entry *); | 80 | static struct dst_entry *ip6_negative_advice(struct dst_entry *); |
80 | static void ip6_dst_destroy(struct dst_entry *); | 81 | static void ip6_dst_destroy(struct dst_entry *); |
81 | static void ip6_dst_ifdown(struct dst_entry *, | 82 | static void ip6_dst_ifdown(struct dst_entry *, |
@@ -103,6 +104,7 @@ static struct dst_ops ip6_dst_ops_template = { | |||
103 | .gc = ip6_dst_gc, | 104 | .gc = ip6_dst_gc, |
104 | .gc_thresh = 1024, | 105 | .gc_thresh = 1024, |
105 | .check = ip6_dst_check, | 106 | .check = ip6_dst_check, |
107 | .default_advmss = ip6_default_advmss, | ||
106 | .destroy = ip6_dst_destroy, | 108 | .destroy = ip6_dst_destroy, |
107 | .ifdown = ip6_dst_ifdown, | 109 | .ifdown = ip6_dst_ifdown, |
108 | .negative_advice = ip6_negative_advice, | 110 | .negative_advice = ip6_negative_advice, |
@@ -937,8 +939,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
937 | 939 | ||
938 | static int ipv6_get_mtu(struct net_device *dev); | 940 | static int ipv6_get_mtu(struct net_device *dev); |
939 | 941 | ||
940 | static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu) | 942 | static unsigned int ip6_default_advmss(const struct dst_entry *dst) |
941 | { | 943 | { |
944 | struct net_device *dev = dst->dev; | ||
945 | unsigned int mtu = dst_mtu(dst); | ||
946 | struct net *net = dev_net(dev); | ||
947 | |||
942 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); | 948 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); |
943 | 949 | ||
944 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) | 950 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) |
@@ -990,7 +996,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
990 | atomic_set(&rt->dst.__refcnt, 1); | 996 | atomic_set(&rt->dst.__refcnt, 1); |
991 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 997 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); |
992 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); | 998 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); |
993 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); | ||
994 | rt->dst.output = ip6_output; | 999 | rt->dst.output = ip6_output; |
995 | 1000 | ||
996 | #if 0 /* there's no chance to use these for ndisc */ | 1001 | #if 0 /* there's no chance to use these for ndisc */ |
@@ -1312,8 +1317,6 @@ install_route: | |||
1312 | 1317 | ||
1313 | if (!dst_mtu(&rt->dst)) | 1318 | if (!dst_mtu(&rt->dst)) |
1314 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); | 1319 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(dev)); |
1315 | if (!dst_metric(&rt->dst, RTAX_ADVMSS)) | ||
1316 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); | ||
1317 | rt->dst.dev = dev; | 1320 | rt->dst.dev = dev; |
1318 | rt->rt6i_idev = idev; | 1321 | rt->rt6i_idev = idev; |
1319 | rt->rt6i_table = table; | 1322 | rt->rt6i_table = table; |
@@ -1540,8 +1543,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, | |||
1540 | nrt->rt6i_nexthop = neigh_clone(neigh); | 1543 | nrt->rt6i_nexthop = neigh_clone(neigh); |
1541 | /* Reset pmtu, it may be better */ | 1544 | /* Reset pmtu, it may be better */ |
1542 | dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); | 1545 | dst_metric_set(&nrt->dst, RTAX_MTU, ipv6_get_mtu(neigh->dev)); |
1543 | dst_metric_set(&nrt->dst, RTAX_ADVMSS, ipv6_advmss(dev_net(neigh->dev), | ||
1544 | dst_mtu(&nrt->dst))); | ||
1545 | 1546 | ||
1546 | if (ip6_ins_rt(nrt)) | 1547 | if (ip6_ins_rt(nrt)) |
1547 | goto out; | 1548 | goto out; |
@@ -1971,7 +1972,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1971 | rt->rt6i_dev = net->loopback_dev; | 1972 | rt->rt6i_dev = net->loopback_dev; |
1972 | rt->rt6i_idev = idev; | 1973 | rt->rt6i_idev = idev; |
1973 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); | 1974 | dst_metric_set(&rt->dst, RTAX_MTU, ipv6_get_mtu(rt->rt6i_dev)); |
1974 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, dst_mtu(&rt->dst))); | ||
1975 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); | 1975 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); |
1976 | rt->dst.obsolete = -1; | 1976 | rt->dst.obsolete = -1; |
1977 | 1977 | ||
@@ -2041,7 +2041,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
2041 | { | 2041 | { |
2042 | struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; | 2042 | struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; |
2043 | struct inet6_dev *idev; | 2043 | struct inet6_dev *idev; |
2044 | struct net *net = dev_net(arg->dev); | ||
2045 | 2044 | ||
2046 | /* In IPv6 pmtu discovery is not optional, | 2045 | /* In IPv6 pmtu discovery is not optional, |
2047 | so that RTAX_MTU lock cannot disable it. | 2046 | so that RTAX_MTU lock cannot disable it. |
@@ -2073,7 +2072,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
2073 | (dst_mtu(&rt->dst) < arg->mtu && | 2072 | (dst_mtu(&rt->dst) < arg->mtu && |
2074 | dst_mtu(&rt->dst) == idev->cnf.mtu6))) { | 2073 | dst_mtu(&rt->dst) == idev->cnf.mtu6))) { |
2075 | dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); | 2074 | dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); |
2076 | dst_metric_set(&rt->dst, RTAX_ADVMSS, ipv6_advmss(net, arg->mtu)); | ||
2077 | } | 2075 | } |
2078 | return 0; | 2076 | return 0; |
2079 | } | 2077 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fee076891646..20aa95e37359 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1521,7 +1521,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1521 | 1521 | ||
1522 | tcp_mtup_init(newsk); | 1522 | tcp_mtup_init(newsk); |
1523 | tcp_sync_mss(newsk, dst_mtu(dst)); | 1523 | tcp_sync_mss(newsk, dst_mtu(dst)); |
1524 | newtp->advmss = dst_metric(dst, RTAX_ADVMSS); | 1524 | newtp->advmss = dst_metric_advmss(dst); |
1525 | tcp_initialize_rcv_mss(newsk); | 1525 | tcp_initialize_rcv_mss(newsk); |
1526 | 1526 | ||
1527 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; | 1527 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 6e50ccd8c532..36936c8ae961 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2361,6 +2361,11 @@ static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, | |||
2361 | return 1; | 2361 | return 1; |
2362 | } | 2362 | } |
2363 | 2363 | ||
2364 | static unsigned int xfrm_default_advmss(const struct dst_entry *dst) | ||
2365 | { | ||
2366 | return dst_metric_advmss(dst->path); | ||
2367 | } | ||
2368 | |||
2364 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 2369 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
2365 | { | 2370 | { |
2366 | struct net *net; | 2371 | struct net *net; |
@@ -2378,6 +2383,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
2378 | dst_ops->kmem_cachep = xfrm_dst_cache; | 2383 | dst_ops->kmem_cachep = xfrm_dst_cache; |
2379 | if (likely(dst_ops->check == NULL)) | 2384 | if (likely(dst_ops->check == NULL)) |
2380 | dst_ops->check = xfrm_dst_check; | 2385 | dst_ops->check = xfrm_dst_check; |
2386 | if (likely(dst_ops->default_advmss == NULL)) | ||
2387 | dst_ops->default_advmss = xfrm_default_advmss; | ||
2381 | if (likely(dst_ops->negative_advice == NULL)) | 2388 | if (likely(dst_ops->negative_advice == NULL)) |
2382 | dst_ops->negative_advice = xfrm_negative_advice; | 2389 | dst_ops->negative_advice = xfrm_negative_advice; |
2383 | if (likely(dst_ops->link_failure == NULL)) | 2390 | if (likely(dst_ops->link_failure == NULL)) |