[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1326824111.2259.54.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Date: Tue, 17 Jan 2012 19:15:11 +0100
From: Eric Dumazet <eric.dumazet@...il.com>
To: David Miller <davem@...emloft.net>
Cc: netdev@...r.kernel.org, tore@....no
Subject: Re: [RFC] ipv6: dst_allfrag() not taken into account by TCP
Le mardi 17 janvier 2012 à 12:34 -0500, David Miller a écrit :
> From: Eric Dumazet <eric.dumazet@...il.com>
> Date: Tue, 17 Jan 2012 17:28:19 +0100
>
> > It seems that dst_allfrag() will force us to use ip6_fragment() and
> > reduce effective MSS to :
>
> Don't use TCP with forced fragmentation.
>
> Use path MTU discovery or an artificially reduced route MTU on paths
> where ICMP blocking is causing problems.
We receive a correct ICMP message and we process it correctly.
It should work without fragments, if we hadnt a bug, when we hit the
minimum IPv6 MTU (1280) ?
Problem is we build too large TCP frames (by 8 bytes) and they must be
fragmented in ip6_finish_output(), wasting cpu and network bandwidth.
We do the following in tcp_mtu_to_mss()
mss_now = pmtu - icsk->icsk_af_ops->net_header_len - sizeof(struct tcphdr);
(net_header_len being a constant value : sizeof(struct ipv6hdr) for IPv6)
For IPv6, effective network header len would be either :
1) sizeof(struct ipv6hdr)
2) sizeof(struct ipv6hdr) + sizeof(frag_hdr)
We could change net_header_len to be a method, and for ipv6 do :
static unsigned int ipv6_net_header_len(struct sock *sk)
{
const struct dst_entry *dst = __sk_dst_get(sk);
return sizeof(struct ipv6hdr) +
(dst && dst_allfrag(dst)) ? sizeof(struct frag_hdr) : 0;
}
/* for ipv4 : */
static unsigned int ipv4_net_header_len(struct sock *sk)
{
return sizeof(struct iphdr);
}
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists