aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-13 15:52:14 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-13 15:52:14 -0500
commit0dbaee3b37e118a96bb7b8eb0d9bbaeeb46264be (patch)
tree37000c5d7e663e4ae9800a7bcde9934984b8bae9
parentcc6f02dd490dac4ad821d5077b934c9b37037cd0 (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>
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c2
-rw-r--r--include/net/dst.h14
-rw-r--r--include/net/dst_ops.h1
-rw-r--r--net/decnet/af_decnet.c4
-rw-r--r--net/decnet/dn_route.c22
-rw-r--r--net/ipv4/route.c24
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_output.c14
-rw-r--r--net/ipv6/route.c16
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/xfrm/xfrm_policy.c7
11 files changed, 75 insertions, 33 deletions
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index be5661707df..d2ad3d67672 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -825,7 +825,7 @@ unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *csk, unsigned int pmtu)
825 unsigned int idx; 825 unsigned int idx;
826 struct dst_entry *dst = csk->dst; 826 struct dst_entry *dst = csk->dst;
827 827
828 csk->advmss = dst_metric(dst, RTAX_ADVMSS); 828 csk->advmss = dst_metric_advmss(dst);
829 829
830 if (csk->advmss > pmtu - 40) 830 if (csk->advmss > pmtu - 40)
831 csk->advmss = pmtu - 40; 831 csk->advmss = pmtu - 40;
diff --git a/include/net/dst.h b/include/net/dst.h
index 755ac6c1aa0..03a1c3d52d8 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -112,10 +112,22 @@ dst_metric_raw(const struct dst_entry *dst, const int metric)
112static inline u32 112static inline u32
113dst_metric(const struct dst_entry *dst, const int metric) 113dst_metric(const struct dst_entry *dst, const int metric)
114{ 114{
115 WARN_ON_ONCE(metric == RTAX_HOPLIMIT); 115 WARN_ON_ONCE(metric == RTAX_HOPLIMIT ||
116 metric == RTAX_ADVMSS);
116 return dst_metric_raw(dst, metric); 117 return dst_metric_raw(dst, metric);
117} 118}
118 119
120static inline u32
121dst_metric_advmss(const struct dst_entry *dst)
122{
123 u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS);
124
125 if (!advmss)
126 advmss = dst->ops->default_advmss(dst);
127
128 return advmss;
129}
130
119static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) 131static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
120{ 132{
121 dst->_metrics[metric-1] = val; 133 dst->_metrics[metric-1] = val;
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
index 51665b3461b..15fb7af08c4 100644
--- a/include/net/dst_ops.h
+++ b/include/net/dst_ops.h
@@ -16,6 +16,7 @@ struct dst_ops {
16 16
17 int (*gc)(struct dst_ops *ops); 17 int (*gc)(struct dst_ops *ops);
18 struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); 18 struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
19 unsigned int (*default_advmss)(const struct dst_entry *);
19 void (*destroy)(struct dst_entry *); 20 void (*destroy)(struct dst_entry *);
20 void (*ifdown)(struct dst_entry *, 21 void (*ifdown)(struct dst_entry *,
21 struct net_device *dev, int how); 22 struct net_device *dev, int how);
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 0065e7e14af..2af15b15d1f 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 e2e926841fe..b8a5c0515be 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
111static int dn_dst_gc(struct dst_ops *ops); 111static int dn_dst_gc(struct dst_ops *ops);
112static struct dst_entry *dn_dst_check(struct dst_entry *, __u32); 112static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
113static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
113static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 114static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
114static void dn_dst_link_failure(struct sk_buff *); 115static void dn_dst_link_failure(struct sk_buff *);
115static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 116static 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
801static 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
798static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) 806static 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 770f70427f0..80997333db0 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -139,6 +139,7 @@ static unsigned long expires_ljiffies;
139 */ 139 */
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 void ipv4_dst_destroy(struct dst_entry *dst); 143static void ipv4_dst_destroy(struct dst_entry *dst);
143static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); 144static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
144static void ipv4_link_failure(struct sk_buff *skb); 145static 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
1802static 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
1801static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) 1815static 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 4fc3387aa99..f4011027543 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 97041f24cd2..2d390669d40 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 98796b0dc2b..d9cb832be52 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -76,6 +76,7 @@
76 76
77static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); 77static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
78static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); 78static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
79static unsigned int ip6_default_advmss(const struct dst_entry *dst);
79static struct dst_entry *ip6_negative_advice(struct dst_entry *); 80static struct dst_entry *ip6_negative_advice(struct dst_entry *);
80static void ip6_dst_destroy(struct dst_entry *); 81static void ip6_dst_destroy(struct dst_entry *);
81static void ip6_dst_ifdown(struct dst_entry *, 82static 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
938static int ipv6_get_mtu(struct net_device *dev); 940static int ipv6_get_mtu(struct net_device *dev);
939 941
940static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu) 942static 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 fee07689164..20aa95e3735 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 6e50ccd8c53..36936c8ae96 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
2364static unsigned int xfrm_default_advmss(const struct dst_entry *dst)
2365{
2366 return dst_metric_advmss(dst->path);
2367}
2368
2364int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2369int 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))