android_kernel_google_msm/net/ipv4
Florian Westphal 29a3cd4664 net: ip, ipv6: handle gso skbs in forwarding path
commit fe6cc55f3a upstream.

[ use zero netdev_feature mask to avoid backport of
  netif_skb_dev_features function ]

Marcelo Ricardo Leitner reported problems when the forwarding link path
has a lower mtu than the incoming one if the inbound interface supports GRO.

Given:
Host <mtu1500> R1 <mtu1200> R2

Host sends tcp stream which is routed via R1 and R2.  R1 performs GRO.

In this case, the kernel will fail to send ICMP fragmentation needed
messages (or pkt too big for ipv6), as GSO packets currently bypass dstmtu
checks in forward path. Instead, Linux tries to send out packets exceeding
the mtu.

When locking route MTU on Host (i.e., no ipv4 DF bit set), R1 does
not fragment the packets when forwarding, and again tries to send out
packets exceeding R1-R2 link mtu.

This alters the forwarding dstmtu checks to take the individual gso
segment lengths into account.

For ipv6, we send out pkt too big error for gso if the individual
segments are too big.

For ipv4, we either send icmp fragmentation needed, or, if the DF bit
is not set, perform software segmentation and let the output path
create fragments when the packet is leaving the machine.
It is not 100% correct as the error message will contain the headers of
the GRO skb instead of the original/segmented one, but it seems to
work fine in my (limited) tests.

Eric Dumazet suggested to simply shrink mss via ->gso_size to avoid
sofware segmentation.

However it turns out that skb_segment() assumes skb nr_frags is related
to mss size so we would BUG there.  I don't want to mess with it considering
Herbert and Eric disagree on what the correct behavior should be.

Hannes Frederic Sowa notes that when we would shrink gso_size
skb_segment would then also need to deal with the case where
SKB_MAX_FRAGS would be exceeded.

This uses sofware segmentation in the forward path when we hit ipv4
non-DF packets and the outgoing link mtu is too small.  Its not perfect,
but given the lack of bug reports wrt. GRO fwd being broken this is a
rare case anyway.  Also its not like this could not be improved later
once the dust settles.

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Reported-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-03-11 16:09:59 -07:00
..
netfilter netfilter: nf_nat: don't check for port change on ICMP tuples 2012-11-26 11:37:48 -08:00
af_inet.c ipv6: use a stronger hash for tcp 2013-02-28 06:59:06 -08:00
ah4.c
arp.c
cipso_ipv4.c cipso: don't follow a NULL pointer when setsockopt() is called 2012-08-09 08:31:42 -07:00
datagram.c ipv4: fix possible seqlock deadlock 2013-12-08 07:29:41 -08:00
devinet.c
esp4.c esp4: fix error return code in esp_output() 2013-05-01 09:41:07 -07:00
fib_frontend.c
fib_lookup.h
fib_rules.c
fib_semantics.c
fib_trie.c fib_trie: remove potential out of bound access 2013-09-14 06:02:09 -07:00
gre.c
icmp.c
igmp.c ipv4 igmp: use in_dev_put in timer handlers instead of __in_dev_put 2013-10-13 15:42:48 -07:00
inet_connection_sock.c inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock 2013-01-11 09:07:14 -08:00
inet_diag.c inet_diag: fix inet_diag_dump_icsk() timewait socket state logic 2014-02-06 11:05:48 -08:00
inet_fragment.c inet: limit length of fragment queue hash table bucket lists 2013-03-28 12:11:54 -07:00
inet_hashtables.c net: do not call sock_put() on TIMEWAIT sockets 2013-11-04 04:23:40 -08:00
inet_lro.c
inet_timewait_sock.c
inetpeer.c ip: generate unique IP identificator if local fragmentation is allowed 2013-10-13 15:42:48 -07:00
ip_forward.c net: ip, ipv6: handle gso skbs in forwarding path 2014-03-11 16:09:59 -07:00
ip_fragment.c net: drop dst before queueing fragments 2013-05-01 09:41:20 -07:00
ip_gre.c ip_tunnel: fix kernel panic with icmp_dest_unreach 2013-06-27 11:27:32 -07:00
ip_input.c
ip_options.c net/ipv4: Ensure that location of timestamp option is stored 2013-03-28 12:11:52 -07:00
ip_output.c inet: fix possible memory corruption with UDP_CORK and UFO 2013-11-04 04:23:41 -08:00
ip_sockglue.c inet: fix addr_len/msg->msg_namelen assignment in recv_error and rxpmtu functions 2013-12-08 07:29:42 -08:00
ipcomp.c
ipconfig.c
ipip.c ip_tunnel: fix kernel panic with icmp_dest_unreach 2013-06-27 11:27:32 -07:00
ipmr.c net: avoid reference counter overflows on fib_rules in multicast forwarding 2014-02-06 11:05:48 -08:00
Kconfig
Makefile
netfilter.c
ping.c inet: fix possible seqlock deadlocks 2013-12-08 07:29:42 -08:00
proc.c tcp: implement RFC 5961 4.2 2013-01-11 09:07:15 -08:00
protocol.c
raw.c inet: fix addr_len/msg->msg_namelen assignment in recv_error and rxpmtu functions 2013-12-08 07:29:42 -08:00
route.c ipv4: fix ineffective source address selection 2013-11-04 04:23:40 -08:00
syncookies.c tcp: incoming connections might use wrong route under synflood 2013-05-01 09:41:07 -07:00
sysctl_net_ipv4.c sysctl net: Keep tcp_syn_retries inside the boundary 2013-08-11 15:38:44 -07:00
tcp.c tcp: fix tcp_md5_hash_skb_data() 2013-06-27 11:27:30 -07:00
tcp_bic.c
tcp_cong.c tcp: Apply device TSO segment limit earlier 2012-10-02 10:29:34 -07:00
tcp_cubic.c tcp: cubic: fix bug in bictcp_acked() 2013-09-14 06:02:09 -07:00
tcp_diag.c
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c net: fix divide by zero in tcp algorithm illinois 2012-11-17 13:16:17 -08:00
tcp_input.c tcp: do not forget FIN in tcp_shifted_skb() 2013-11-04 04:23:40 -08:00
tcp_ipv4.c inet: fix possible seqlock deadlocks 2013-12-08 07:29:42 -08:00
tcp_lp.c
tcp_memcontrol.c
tcp_minisocks.c
tcp_output.c tcp: must unclone packets before mangling them 2013-11-04 04:23:40 -08:00
tcp_probe.c
tcp_scalable.c
tcp_timer.c
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tunnel4.c
udp.c Revert "net: update consumers of MSG_MORE to recognize MSG_SENDPAGE_NOTLAST" 2013-12-20 07:34:21 -08:00
udp_diag.c
udp_impl.h
udplite.c
xfrm4_input.c
xfrm4_mode_beet.c
xfrm4_mode_transport.c
xfrm4_mode_tunnel.c ip: generate unique IP identificator if local fragmentation is allowed 2013-10-13 15:42:48 -07:00
xfrm4_output.c
xfrm4_policy.c
xfrm4_state.c
xfrm4_tunnel.c