diff options
Diffstat (limited to 'net/ipv4/ip_output.c')
| -rw-r--r-- | net/ipv4/ip_output.c | 9 | 
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 9a4a6c96cb0..041d41df122 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -873,8 +873,10 @@ int ip_append_data(struct sock *sk,  	    !exthdrlen)  		csummode = CHECKSUM_PARTIAL; +	skb = skb_peek_tail(&sk->sk_write_queue); +  	inet->cork.length += length; -	if (((length> mtu) || !skb_queue_empty(&sk->sk_write_queue)) && +	if (((length > mtu) || (skb && skb_is_gso(skb))) &&  	    (sk->sk_protocol == IPPROTO_UDP) &&  	    (rt->u.dst.dev->features & NETIF_F_UFO)) {  		err = ip_ufo_append_data(sk, getfrag, from, length, hh_len, @@ -892,7 +894,7 @@ int ip_append_data(struct sock *sk,  	 * adding appropriate IP header.  	 */ -	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) +	if (!skb)  		goto alloc_new_skb;  	while (length > 0) { @@ -1121,7 +1123,8 @@ ssize_t	ip_append_page(struct sock *sk, struct page *page,  		return -EINVAL;  	inet->cork.length += size; -	if ((sk->sk_protocol == IPPROTO_UDP) && +	if ((size + skb->len > mtu) && +	    (sk->sk_protocol == IPPROTO_UDP) &&  	    (rt->u.dst.dev->features & NETIF_F_UFO)) {  		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;  		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;  |