|
@@ -1150,7 +1150,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
|
|
|
}
|
|
|
|
|
|
/* Calculate MSS. Not accounting for SACKs here. */
|
|
|
-int tcp_mtu_to_mss(const struct sock *sk, int pmtu)
|
|
|
+int tcp_mtu_to_mss(struct sock *sk, int pmtu)
|
|
|
{
|
|
|
const struct tcp_sock *tp = tcp_sk(sk);
|
|
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
@@ -1161,6 +1161,14 @@ int tcp_mtu_to_mss(const struct sock *sk, int pmtu)
|
|
|
*/
|
|
|
mss_now = pmtu - icsk->icsk_af_ops->net_header_len - sizeof(struct tcphdr);
|
|
|
|
|
|
+ /* IPv6 adds a frag_hdr in case RTAX_FEATURE_ALLFRAG is set */
|
|
|
+ if (icsk->icsk_af_ops->net_frag_header_len) {
|
|
|
+ const struct dst_entry *dst = __sk_dst_get(sk);
|
|
|
+
|
|
|
+ if (dst && dst_allfrag(dst))
|
|
|
+ mss_now -= icsk->icsk_af_ops->net_frag_header_len;
|
|
|
+ }
|
|
|
+
|
|
|
/* Clamp it (mss_clamp does not include tcp options) */
|
|
|
if (mss_now > tp->rx_opt.mss_clamp)
|
|
|
mss_now = tp->rx_opt.mss_clamp;
|
|
@@ -1179,7 +1187,7 @@ int tcp_mtu_to_mss(const struct sock *sk, int pmtu)
|
|
|
}
|
|
|
|
|
|
/* Inverse of above */
|
|
|
-int tcp_mss_to_mtu(const struct sock *sk, int mss)
|
|
|
+int tcp_mss_to_mtu(struct sock *sk, int mss)
|
|
|
{
|
|
|
const struct tcp_sock *tp = tcp_sk(sk);
|
|
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
@@ -1190,6 +1198,13 @@ int tcp_mss_to_mtu(const struct sock *sk, int mss)
|
|
|
icsk->icsk_ext_hdr_len +
|
|
|
icsk->icsk_af_ops->net_header_len;
|
|
|
|
|
|
+ /* IPv6 adds a frag_hdr in case RTAX_FEATURE_ALLFRAG is set */
|
|
|
+ if (icsk->icsk_af_ops->net_frag_header_len) {
|
|
|
+ const struct dst_entry *dst = __sk_dst_get(sk);
|
|
|
+
|
|
|
+ if (dst && dst_allfrag(dst))
|
|
|
+ mtu += icsk->icsk_af_ops->net_frag_header_len;
|
|
|
+ }
|
|
|
return mtu;
|
|
|
}
|
|
|
|