struct dst_entry *dst);
        struct inet_peer *(*get_peer)(struct sock *sk, bool *release_it);
        u16         net_header_len;
+       u16         net_frag_header_len;
        u16         sockaddr_len;
        int         (*setsockopt)(struct sock *sk, int level, int optname, 
                                  char __user *optval, unsigned int optlen);
 
 
 extern void tcp_initialize_rcv_mss(struct sock *sk);
 
-extern int tcp_mtu_to_mss(const struct sock *sk, int pmtu);
-extern int tcp_mss_to_mtu(const struct sock *sk, int mss);
+extern int tcp_mtu_to_mss(struct sock *sk, int pmtu);
+extern int tcp_mss_to_mtu(struct sock *sk, int mss);
 extern void tcp_mtup_init(struct sock *sk);
 extern void tcp_valid_rtt_meas(struct sock *sk, u32 seq_rtt);
 
 
 }
 
 /* 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);
         */
        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;
 }
 
 /* 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);
              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;
 }
 
 
        .syn_recv_sock     = tcp_v6_syn_recv_sock,
        .get_peer          = tcp_v6_get_peer,
        .net_header_len    = sizeof(struct ipv6hdr),
+       .net_frag_header_len = sizeof(struct frag_hdr),
        .setsockopt        = ipv6_setsockopt,
        .getsockopt        = ipv6_getsockopt,
        .addr2sockaddr     = inet6_csk_addr2sockaddr,