diff options
| author | Greg Kroah-Hartman <[email protected]> | 2022-01-30 15:00:39 +0100 | 
|---|---|---|
| committer | Greg Kroah-Hartman <[email protected]> | 2022-01-30 15:00:39 +0100 | 
| commit | 7ab004dbcbee38b8a70798835d3ffcd97a985a5e (patch) | |
| tree | 0caa6cb97801736046823ca785a5ba36bf684ac6 /net/ipv4/ip_output.c | |
| parent | 710f8af199ee9d72dd87083edd55c5ee250ee6f4 (diff) | |
| parent | 26291c54e111ff6ba87a164d85d4a4e134b7315c (diff) | |
Merge tag 'v5.17-rc2' into char-misc-next
We need the char/misc fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Diffstat (limited to 'net/ipv4/ip_output.c')
| -rw-r--r-- | net/ipv4/ip_output.c | 26 | 
1 files changed, 21 insertions, 5 deletions
| diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 57c1d8431386..139cec29ed06 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -162,12 +162,19 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,  	iph->daddr    = (opt && opt->opt.srr ? opt->opt.faddr : daddr);  	iph->saddr    = saddr;  	iph->protocol = sk->sk_protocol; -	if (ip_dont_fragment(sk, &rt->dst)) { +	/* Do not bother generating IPID for small packets (eg SYNACK) */ +	if (skb->len <= IPV4_MIN_MTU || ip_dont_fragment(sk, &rt->dst)) {  		iph->frag_off = htons(IP_DF);  		iph->id = 0;  	} else {  		iph->frag_off = 0; -		__ip_select_ident(net, iph, 1); +		/* TCP packets here are SYNACK with fat IPv4/TCP options. +		 * Avoid using the hashed IP ident generator. +		 */ +		if (sk->sk_protocol == IPPROTO_TCP) +			iph->id = (__force __be16)prandom_u32(); +		else +			__ip_select_ident(net, iph, 1);  	}  	if (opt && opt->opt.optlen) { @@ -825,15 +832,24 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,  		/* Everything is OK. Generate! */  		ip_fraglist_init(skb, iph, hlen, &iter); -		if (iter.frag) -			ip_options_fragment(iter.frag); -  		for (;;) {  			/* Prepare header of the next frame,  			 * before previous one went down. */  			if (iter.frag) { +				bool first_frag = (iter.offset == 0); +  				IPCB(iter.frag)->flags = IPCB(skb)->flags;  				ip_fraglist_prepare(skb, &iter); +				if (first_frag && IPCB(skb)->opt.optlen) { +					/* ipcb->opt is not populated for frags +					 * coming from __ip_make_skb(), +					 * ip_options_fragment() needs optlen +					 */ +					IPCB(iter.frag)->opt.optlen = +						IPCB(skb)->opt.optlen; +					ip_options_fragment(iter.frag); +					ip_send_check(iter.iph); +				}  			}  			skb->tstamp = tstamp; |