diff options
-rw-r--r-- | include/net/inet_connection_sock.h | 1 | ||||
-rw-r--r-- | include/net/tcp.h | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 19 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 1 |
4 files changed, 21 insertions, 4 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 46c9e2ccdf02..7d83f90f203f 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -45,6 +45,7 @@ struct inet_connection_sock_af_ops { | |||
45 | struct dst_entry *dst); | 45 | struct dst_entry *dst); |
46 | struct inet_peer *(*get_peer)(struct sock *sk, bool *release_it); | 46 | struct inet_peer *(*get_peer)(struct sock *sk, bool *release_it); |
47 | u16 net_header_len; | 47 | u16 net_header_len; |
48 | u16 net_frag_header_len; | ||
48 | u16 sockaddr_len; | 49 | u16 sockaddr_len; |
49 | int (*setsockopt)(struct sock *sk, int level, int optname, | 50 | int (*setsockopt)(struct sock *sk, int level, int optname, |
50 | char __user *optval, unsigned int optlen); | 51 | char __user *optval, unsigned int optlen); |
diff --git a/include/net/tcp.h b/include/net/tcp.h index fc880e92164a..0fb84de6da36 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -544,8 +544,8 @@ extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
544 | 544 | ||
545 | extern void tcp_initialize_rcv_mss(struct sock *sk); | 545 | extern void tcp_initialize_rcv_mss(struct sock *sk); |
546 | 546 | ||
547 | extern int tcp_mtu_to_mss(const struct sock *sk, int pmtu); | 547 | extern int tcp_mtu_to_mss(struct sock *sk, int pmtu); |
548 | extern int tcp_mss_to_mtu(const struct sock *sk, int mss); | 548 | extern int tcp_mss_to_mtu(struct sock *sk, int mss); |
549 | extern void tcp_mtup_init(struct sock *sk); | 549 | extern void tcp_mtup_init(struct sock *sk); |
550 | extern void tcp_valid_rtt_meas(struct sock *sk, u32 seq_rtt); | 550 | extern void tcp_valid_rtt_meas(struct sock *sk, u32 seq_rtt); |
551 | 551 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7b7cf3811348..834e89fc541b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -1150,7 +1150,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) | |||
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | /* Calculate MSS. Not accounting for SACKs here. */ | 1152 | /* Calculate MSS. Not accounting for SACKs here. */ |
1153 | int tcp_mtu_to_mss(const struct sock *sk, int pmtu) | 1153 | int tcp_mtu_to_mss(struct sock *sk, int pmtu) |
1154 | { | 1154 | { |
1155 | const struct tcp_sock *tp = tcp_sk(sk); | 1155 | const struct tcp_sock *tp = tcp_sk(sk); |
1156 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1156 | const struct inet_connection_sock *icsk = inet_csk(sk); |
@@ -1161,6 +1161,14 @@ int tcp_mtu_to_mss(const struct sock *sk, int pmtu) | |||
1161 | */ | 1161 | */ |
1162 | mss_now = pmtu - icsk->icsk_af_ops->net_header_len - sizeof(struct tcphdr); | 1162 | mss_now = pmtu - icsk->icsk_af_ops->net_header_len - sizeof(struct tcphdr); |
1163 | 1163 | ||
1164 | /* IPv6 adds a frag_hdr in case RTAX_FEATURE_ALLFRAG is set */ | ||
1165 | if (icsk->icsk_af_ops->net_frag_header_len) { | ||
1166 | const struct dst_entry *dst = __sk_dst_get(sk); | ||
1167 | |||
1168 | if (dst && dst_allfrag(dst)) | ||
1169 | mss_now -= icsk->icsk_af_ops->net_frag_header_len; | ||
1170 | } | ||
1171 | |||
1164 | /* Clamp it (mss_clamp does not include tcp options) */ | 1172 | /* Clamp it (mss_clamp does not include tcp options) */ |
1165 | if (mss_now > tp->rx_opt.mss_clamp) | 1173 | if (mss_now > tp->rx_opt.mss_clamp) |
1166 | mss_now = tp->rx_opt.mss_clamp; | 1174 | mss_now = tp->rx_opt.mss_clamp; |
@@ -1179,7 +1187,7 @@ int tcp_mtu_to_mss(const struct sock *sk, int pmtu) | |||
1179 | } | 1187 | } |
1180 | 1188 | ||
1181 | /* Inverse of above */ | 1189 | /* Inverse of above */ |
1182 | int tcp_mss_to_mtu(const struct sock *sk, int mss) | 1190 | int tcp_mss_to_mtu(struct sock *sk, int mss) |
1183 | { | 1191 | { |
1184 | const struct tcp_sock *tp = tcp_sk(sk); | 1192 | const struct tcp_sock *tp = tcp_sk(sk); |
1185 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1193 | const struct inet_connection_sock *icsk = inet_csk(sk); |
@@ -1190,6 +1198,13 @@ int tcp_mss_to_mtu(const struct sock *sk, int mss) | |||
1190 | icsk->icsk_ext_hdr_len + | 1198 | icsk->icsk_ext_hdr_len + |
1191 | icsk->icsk_af_ops->net_header_len; | 1199 | icsk->icsk_af_ops->net_header_len; |
1192 | 1200 | ||
1201 | /* IPv6 adds a frag_hdr in case RTAX_FEATURE_ALLFRAG is set */ | ||
1202 | if (icsk->icsk_af_ops->net_frag_header_len) { | ||
1203 | const struct dst_entry *dst = __sk_dst_get(sk); | ||
1204 | |||
1205 | if (dst && dst_allfrag(dst)) | ||
1206 | mtu += icsk->icsk_af_ops->net_frag_header_len; | ||
1207 | } | ||
1193 | return mtu; | 1208 | return mtu; |
1194 | } | 1209 | } |
1195 | 1210 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index cdbf292ad208..57b210969834 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1778,6 +1778,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = { | |||
1778 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1778 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1779 | .get_peer = tcp_v6_get_peer, | 1779 | .get_peer = tcp_v6_get_peer, |
1780 | .net_header_len = sizeof(struct ipv6hdr), | 1780 | .net_header_len = sizeof(struct ipv6hdr), |
1781 | .net_frag_header_len = sizeof(struct frag_hdr), | ||
1781 | .setsockopt = ipv6_setsockopt, | 1782 | .setsockopt = ipv6_setsockopt, |
1782 | .getsockopt = ipv6_getsockopt, | 1783 | .getsockopt = ipv6_getsockopt, |
1783 | .addr2sockaddr = inet6_csk_addr2sockaddr, | 1784 | .addr2sockaddr = inet6_csk_addr2sockaddr, |