From: Eric Dumazet <hidden> Date: 2011-09-23 06:02:31
While playing with a new ADSL box at home, I discovered that ECN
blackhole can trigger suboptimal quickack mode on linux : We send one
ACK for each incoming data frame, without any delay and eventual
piggyback.
This is because TCP_ECN_check_ce() considers that if no ECT is seen on a
segment, this is because this segment was a retransmit.
Refine this heuristic and apply it only if we seen ECT in a previous
segment, to detect ECN blackhole at IP level.
Signed-off-by: Eric Dumazet <redacted>
CC: Jamal Hadi Salim <jhs@mojatatu.com>
CC: Jerry Chu <redacted>
CC: Ilpo Järvinen <redacted>
CC: Jim Gettys <redacted>
CC: Dave Taht <redacted>
---
Another possibility is to remove this (not in RFC 3168) heuristic, what
do you think ?
include/net/tcp.h | 1 +
net/ipv4/tcp_input.c | 23 ++++++++++++++++-------
2 files changed, 17 insertions(+), 7 deletions(-)
@@ -217,16 +217,25 @@ static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp)tp->ecn_flags&=~TCP_ECN_DEMAND_CWR;}-staticinlinevoidTCP_ECN_check_ce(structtcp_sock*tp,structsk_buff*skb)+staticinlinevoidTCP_ECN_check_ce(structtcp_sock*tp,conststructsk_buff*skb){-if(tp->ecn_flags&TCP_ECN_OK){-if(INET_ECN_is_ce(TCP_SKB_CB(skb)->flags))-tp->ecn_flags|=TCP_ECN_DEMAND_CWR;+if(!(tp->ecn_flags&TCP_ECN_OK))+return;++switch(TCP_SKB_CB(skb)->flags&INET_ECN_MASK){+caseINET_ECN_NOT_ECT:/* Funny extension: if ECT is not set on a segment,-*itissurelyretransmit.ItisnotinECNRFC,-*butLinuxfollowsthisrule.*/-elseif(INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags)))+*andwealreadyseenECTonaprevioussegment,+*itisprobablyaretransmit.+*/+if(tp->ecn_flags&TCP_ECN_SEEN)tcp_enter_quickack_mode((structsock*)tp);+break;+caseINET_ECN_CE:+tp->ecn_flags|=TCP_ECN_DEMAND_CWR;+/* fallinto */+default:+tp->ecn_flags|=TCP_ECN_SEEN;}}
While playing with a new ADSL box at home, I discovered that ECN
blackhole can trigger suboptimal quickack mode on linux : We send one
ACK for each incoming data frame, without any delay and eventual
piggyback.
This is because TCP_ECN_check_ce() considers that if no ECT is seen on a
segment, this is because this segment was a retransmit.
Refine this heuristic and apply it only if we seen ECT in a previous
segment, to detect ECN blackhole at IP level.
Signed-off-by: Eric Dumazet <redacted>
CC: Jamal Hadi Salim <jhs@mojatatu.com>
CC: Jerry Chu <redacted>
CC: Ilpo Järvinen <redacted>
CC: Jim Gettys <redacted>
CC: Dave Taht <redacted>
---
Another possibility is to remove this (not in RFC 3168) heuristic, what
do you think ?
From: Ilpo Järvinen <hidden> Date: 2011-09-23 19:17:44
On Fri, 23 Sep 2011, Eric Dumazet wrote:
While playing with a new ADSL box at home, I discovered that ECN
blackhole can trigger suboptimal quickack mode on linux : We send one
ACK for each incoming data frame, without any delay and eventual
piggyback.
This is because TCP_ECN_check_ce() considers that if no ECT is seen on a
segment, this is because this segment was a retransmit.
Refine this heuristic and apply it only if we seen ECT in a previous
segment, to detect ECN blackhole at IP level.
This seems sensible thing to do.
Acked-by: Ilpo Järvinen <redacted>
--
i.
From: Jamal Hadi Salim <jhs@mojatatu.com> Date: 2011-09-24 00:59:22
On Fri, 2011-09-23 at 08:02 +0200, Eric Dumazet wrote:
While playing with a new ADSL box at home, I discovered that ECN
blackhole can trigger suboptimal quickack mode on linux : We send one
ACK for each incoming data frame, without any delay and eventual
piggyback.
This is because TCP_ECN_check_ce() considers that if no ECT is seen on a
segment, this is because this segment was a retransmit.
If you have Linux as the sender, that assumption is legit (i.e we never
set ECT on retransmits).
Refine this heuristic and apply it only if we seen ECT in a previous
segment, to detect ECN blackhole at IP level.
So small confusion for me, Eric:
Is theres some middlebox clearing the ECT but allowing the TCP header
ECN flags to be set during SYN echange? If yes, why would not allowing
quickack help?
cheers,
jamal
From: Eric Dumazet <hidden> Date: 2011-09-25 19:24:54
Le vendredi 23 septembre 2011 à 20:55 -0400, Jamal Hadi Salim a écrit :
So small confusion for me, Eric:
Is theres some middlebox clearing the ECT but allowing the TCP header
ECN flags to be set during SYN echange? If yes, why would not allowing
quickack help?
As you may know, the SYN and SYNACK packets dont have ECT bits, as
mandated by RFC. So there is no way to detect a TOS blackhole in TCP
session init.
On following trace taken from my laptop connecting to a ssh server
(192.168.2.1), you can see that my laptop sends ECT messages, but never
receive ECT bits. Each sides believe the session is ECN enabled, as the
SYN and SYNACK messages have the appropriate ECN markers.
So we have somewhere a box that mask the TOS bits. This is a well known
effect on some networks, unfortunately.
The 'linux funny extension' is wrong in this case, since I have no
retransmits, no losses, yet my laptop is in quickack mode (it sends an
ACK for every incoming data packet), because you assumed receiving a
packet with no ECT bits means this packet was a retransmit.
21:14:44.665405 IP (tos 0x0, ttl 64, id 63689, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.32.39529 > 192.168.2.1.22: Flags [SEW], cksum 0xf2ea (incorrect -> 0x2151), seq 1589453915, win 14600, options [mss 1460,sackOK,TS val 56466 ecr 0,nop,wscale 7], length 0
21:14:44.773643 IP (tos 0x0, ttl 46, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.1.22 > 192.168.2.32.39529: Flags [S.E], cksum 0xbce1 (correct), seq 1422101564, ack 1589453916, win 14480, options [mss 1452,sackOK,TS val 176781781 ecr 56466,nop,wscale 7], length 0
21:14:44.773691 IP (tos 0x0, ttl 64, id 63690, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.32.39529 > 192.168.2.1.22: Flags [.], cksum 0xf2e2 (incorrect -> 0x23f8), ack 1, win 115, options [nop,nop,TS val 56477 ecr 176781781], length 0
21:14:44.888804 IP (tos 0x0, ttl 46, id 62941, offset 0, flags [DF], proto TCP (6), length 91)
192.168.2.1.22 > 192.168.2.32.39529: Flags [P.], cksum 0x64d1 (correct), seq 1:40, ack 1, win 114, options [nop,nop,TS val 176781792 ecr 56477], length 39
21:14:44.888842 IP (tos 0x0, ttl 64, id 63691, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.32.39529 > 192.168.2.1.22: Flags [.], cksum 0xf2e2 (incorrect -> 0x23ba), ack 40, win 115, options [nop,nop,TS val 56489 ecr 176781792], length 0
21:14:44.888929 IP (tos 0x2,ECT(0), ttl 64, id 63692, offset 0, flags [DF], proto TCP (6), length 91)
192.168.2.32.39529 > 192.168.2.1.22: Flags [P.], cksum 0x649d (correct), seq 1:40, ack 40, win 115, options [nop,nop,TS val 56489 ecr 176781792], length 39
21:14:44.993714 IP (tos 0x0, ttl 46, id 62942, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.1.22 > 192.168.2.32.39529: Flags [.], cksum 0x2389 (correct), ack 40, win 114, options [nop,nop,TS val 176781803 ecr 56489], length 0
21:14:44.993758 IP (tos 0x2,ECT(0), ttl 64, id 63693, offset 0, flags [DF], proto TCP (6), length 1196)
192.168.2.32.39529 > 192.168.2.1.22: Flags [P.], cksum 0x1e1b (correct), seq 40:1184, ack 40, win 115, options [nop,nop,TS val 56499 ecr 176781803], length 1144
21:14:44.994447 IP (tos 0x0, ttl 46, id 62943, offset 0, flags [DF], proto TCP (6), length 900)
192.168.2.1.22 > 192.168.2.32.39529: Flags [P.], cksum 0xd3d4 (correct), seq 40:888, ack 40, win 114, options [nop,nop,TS val 176781803 ecr 56489], length 848
21:14:44.994463 IP (tos 0x0, ttl 64, id 63694, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.32.39529 > 192.168.2.1.22: Flags [.], cksum 0xf2e2 (incorrect -> 0x1ba9), ack 888, win 128, options [nop,nop,TS val 56499 ecr 176781803], length 0
21:14:45.546332 IP (tos 0x0, ttl 64, id 63695, offset 0, flags [DF], proto TCP (6), length 1196)
192.168.2.32.39529 > 192.168.2.1.22: Flags [P.], cksum 0x1a8c (correct), seq 40:1184, ack 888, win 128, options [nop,nop,TS val 56549 ecr 176781803], length 1144
On Sun, 2011-09-25 at 21:24 +0200, Eric Dumazet wrote:
So we have somewhere a box that mask the TOS bits. This is a well known
effect on some networks, unfortunately.
ok
The 'linux funny extension' is wrong in this case, since I have no
retransmits, no losses, yet my laptop is in quickack mode (it sends an
ACK for every incoming data packet), because you assumed receiving a
packet with no ECT bits means this packet was a retransmit.
No objection from me - only one corner case i can think of is if
expected behavior happens and the first data packet was a retransmit
(i.e you wouldnt have seen an ECT which you need for your heuristic),
but that is probably not a big a deal.
In regards to the 'linux funny extension' - this was a brilliant idea
in my opinion back then from Alexey; lots of discussions happened but
I cant remember if it made it in some RFC or not (I will try to search
some old archives).
cheers,
jamal
In regards to the 'linux funny extension' - this was a brilliant idea
in my opinion back then from Alexey; lots of discussions happened but
I cant remember if it made it in some RFC or not (I will try to search
some old archives).
Wasnt hard:
https://tools.ietf.org/id/draft-ietf-tsvwg-tcp-ecn-00.txt
It doesnt seem to have made it to RFC and i cant remember why.
[We dont wanna bring Sally out of retirement but we can ask KK if
it bugs you;->]
cheers,
jamal
From: Eric Dumazet <hidden> Date: 2011-09-26 08:26:45
Le dimanche 25 septembre 2011 à 21:13 -0400, jamal a écrit :
On Sun, 2011-09-25 at 21:07 -0400, jamal wrote:
quoted
In regards to the 'linux funny extension' - this was a brilliant idea
in my opinion back then from Alexey; lots of discussions happened but
I cant remember if it made it in some RFC or not (I will try to search
some old archives).
Thanks !
This refers to additions to RFC 2481 : This was refined by RFC 3168, and
the retransmitted TCP packets requirement is part of the final RFC :
6.1.5. Retransmitted TCP packets
This document specifies ECN-capable TCP implementations MUST NOT set
either ECT codepoint (ECT(0) or ECT(1)) in the IP header for
retransmitted data packets, ...
Followed by a very long description :)
BTW, the ECN+ proposal (RFC 5562 : Adding Explicit Congestion
Notification (ECN) Capability to TCP's SYN/ACK Packets) would allow the
client (receiving SYNACK message with ECT flags) to set the TCP_ECN_SEEN
I added in my patch, allowing even the first (retransmitted) data packet
to trigger quickack mode.
On Mon, 2011-09-26 at 10:26 +0200, Eric Dumazet wrote:
This refers to additions to RFC 2481 : This was refined by RFC 3168, and
the retransmitted TCP packets requirement is part of the final RFC :
Ah, yes - thats where it went.
BTW, the ECN+ proposal (RFC 5562 : Adding Explicit Congestion
Notification (ECN) Capability to TCP's SYN/ACK Packets) would allow the
client (receiving SYNACK message with ECT flags) to set the TCP_ECN_SEEN
I added in my patch, allowing even the first (retransmitted) data packet
to trigger quickack mode.
Excellent ;->
Are you going to add 5562 support?
cheers,
jamal
From: Eric Dumazet <hidden> Date: 2011-09-26 12:43:56
Le lundi 26 septembre 2011 à 08:00 -0400, jamal a écrit :
On Mon, 2011-09-26 at 10:26 +0200, Eric Dumazet wrote:
quoted
This refers to additions to RFC 2481 : This was refined by RFC 3168, and
the retransmitted TCP packets requirement is part of the final RFC :
Ah, yes - thats where it went.
quoted
BTW, the ECN+ proposal (RFC 5562 : Adding Explicit Congestion
Notification (ECN) Capability to TCP's SYN/ACK Packets) would allow the
client (receiving SYNACK message with ECT flags) to set the TCP_ECN_SEEN
I added in my patch, allowing even the first (retransmitted) data packet
to trigger quickack mode.
Excellent ;->
Are you going to add 5562 support?
I sent a private mail to Adam Langley this morning asking him if he
planned an official submission of a prior patch :
http://www.ietf.org/mail-archive/web/tcpm/current/msg03988.html
If Adam is too busy or not anymore interested, I would like to spend
some cycles on this.
Thanks
While playing with a new ADSL box at home, I discovered that ECN
blackhole can trigger suboptimal quickack mode on linux : We send one
ACK for each incoming data frame, without any delay and eventual
piggyback.
This is because TCP_ECN_check_ce() considers that if no ECT is seen on a
segment, this is because this segment was a retransmit.
Refine this heuristic and apply it only if we seen ECT in a previous
segment, to detect ECN blackhole at IP level.
Signed-off-by: Eric Dumazet <redacted>
From: Eric Dumazet <hidden> Date: 2011-09-27 06:00:55
struct tcp_skb_cb contains a "flags" field containing either tcp flags
or IP dsfield depending on context (input or output path)
Introduce ip_dsfield to make the difference clear and ease maintenance.
If later we want to save space, we can union flags/ip_dsfield
Signed-off-by: Eric Dumazet <redacted>
---
If there is no objection, I plan to rename "flags" to "tcp_flags" in a
following patch.
include/net/tcp.h | 3 ++-
net/ipv4/tcp_input.c | 2 +-
net/ipv4/tcp_ipv4.c | 2 +-
net/ipv6/tcp_ipv6.c | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
@@ -222,7 +222,7 @@ static inline void TCP_ECN_check_ce(struct tcp_sock *tp, const struct sk_buff *sif(!(tp->ecn_flags&TCP_ECN_OK))return;-switch(TCP_SKB_CB(skb)->flags&INET_ECN_MASK){+switch(TCP_SKB_CB(skb)->ip_dsfield&INET_ECN_MASK){caseINET_ECN_NOT_ECT:/* Funny extension: if ECT is not set on a segment,*andwealreadyseenECTonaprevioussegment,
struct tcp_skb_cb contains a "flags" field containing either tcp flags
or IP dsfield depending on context (input or output path)
Introduce ip_dsfield to make the difference clear and ease maintenance.
If later we want to save space, we can union flags/ip_dsfield
Signed-off-by: Eric Dumazet <redacted>
Applied, thanks Eric.
If there is no objection, I plan to rename "flags" to "tcp_flags" in a
following patch.
From: Christoph Paasch <hidden> Date: 2011-09-27 07:37:44
Hi,
I realize that before "struct tcp_skb_cb" is a comment saying that it's 44
bytes long.
However, (as far as I can see) before Eric's change it was 42 bytes long and
now it became 43 bytes.
Wouldn't it make sense to change the comment, so that it's consistent again
with the real size of tcp_skb_cb ?
Cheers,
Christoph
On Tuesday 27 September 2011 wrote David Miller:
struct tcp_skb_cb contains a "flags" field containing either tcp flags
or IP dsfield depending on context (input or output path)
Introduce ip_dsfield to make the difference clear and ease maintenance.
If later we want to save space, we can union flags/ip_dsfield
Signed-off-by: Eric Dumazet <redacted>
Applied, thanks Eric.
quoted
If there is no objection, I plan to rename "flags" to "tcp_flags" in a
following patch.
No objections.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Eric Dumazet <hidden> Date: 2011-09-27 08:01:35
Le mardi 27 septembre 2011 à 10:37 +0300, Christoph Paasch a écrit :
Hi,
I realize that before "struct tcp_skb_cb" is a comment saying that it's 44
bytes long.
However, (as far as I can see) before Eric's change it was 42 bytes long and
now it became 43 bytes.
Wouldn't it make sense to change the comment, so that it's consistent again
with the real size of tcp_skb_cb ?
You are mistaken :)
There was a two bytes hole.
I took one byte for dsfield, and left one byte hole,
I added a comment to remind there is this hole
Thanks !
However, (as far as I can see) before Eric's change it was 42 bytes long
and now it became 43 bytes.
Then, I suggest that you go buy a pair of glasses. :-)
Yeah, maybe it's time to... ;-)
This two-byte hole, is it because "flags" and "sacked" are both __u8 and
fields are aligned to 32-bit ?
Thanks,
Christoph
--
Christoph Paasch
PhD Student
IP Networking Lab --- http://inl.info.ucl.ac.be
MultiPath TCP in the Linux Kernel --- http://inl.info.ucl.ac.be/mptcp
Université Catholique de Louvain
www.rollerbulls.be
--
However, (as far as I can see) before Eric's change it was 42 bytes long
and now it became 43 bytes.
Then, I suggest that you go buy a pair of glasses. :-)
Yeah, maybe it's time to... ;-)
This two-byte hole, is it because "flags" and "sacked" are both __u8 and
fields are aligned to 32-bit ?
Not exactly.
Reason for the hole is the following :
struct whatever {
u8 first;
u8 second;
u32 third;
};
"third" field has an alignement requirement of 4 bytes on most arches.
Compiler inserts a 2 bytes hole before "third" to respect this
requirement.
There is no hole between "first" and "second", since second has no
alignment requirement.
sizeof(struct whatever) = 8
From: Christoph Paasch <hidden> Date: 2011-09-27 09:28:49
Eric,
On Tuesday 27 September 2011 wrote Eric Dumazet:
Le mardi 27 septembre 2011 à 11:38 +0300, Christoph Paasch a écrit :
quoted
On Tuesday 27 September 2011 wrote David Miller:
This two-byte hole, is it because "flags" and "sacked" are both __u8 and
fields are aligned to 32-bit ?
Not exactly.
Reason for the hole is the following :
struct whatever {
u8 first;
u8 second;
u32 third;
};
"third" field has an alignement requirement of 4 bytes on most arches.
Compiler inserts a 2 bytes hole before "third" to respect this
requirement.
There is no hole between "first" and "second", since second has no
alignment requirement.
sizeof(struct whatever) = 8
Ok, I understand.
Thanks for the info. I didn't knew this...
It's good news...
Maybe we win now a little bit of space in MultiPath TCP by rearranging our
fields... :-)
Cheers,
Christoph
--
Christoph Paasch
PhD Student
IP Networking Lab --- http://inl.info.ucl.ac.be
MultiPath TCP in the Linux Kernel --- http://inl.info.ucl.ac.be/mptcp
Université Catholique de Louvain
www.rollerbulls.be
--
From: Eric Dumazet <hidden> Date: 2011-09-27 09:40:14
Le mardi 27 septembre 2011 à 12:28 +0300, Christoph Paasch a écrit :
Ok, I understand.
Thanks for the info. I didn't knew this...
It's good news...
Maybe we win now a little bit of space in MultiPath TCP by rearranging our
fields... :-)
@@ -297,9 +297,9 @@ static u16 tcp_select_window(struct sock *sk)/* Packet ECN state for a SYN-ACK */staticinlinevoidTCP_ECN_send_synack(structtcp_sock*tp,structsk_buff*skb){-TCP_SKB_CB(skb)->flags&=~TCPHDR_CWR;+TCP_SKB_CB(skb)->tcp_flags&=~TCPHDR_CWR;if(!(tp->ecn_flags&TCP_ECN_OK))-TCP_SKB_CB(skb)->flags&=~TCPHDR_ECE;+TCP_SKB_CB(skb)->tcp_flags&=~TCPHDR_ECE;}/* Packet ECN state for a SYN. */
@@ -826,7 +826,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,tcb=TCP_SKB_CB(skb);memset(&opts,0,sizeof(opts));-if(unlikely(tcb->flags&TCPHDR_SYN))+if(unlikely(tcb->tcp_flags&TCPHDR_SYN))tcp_options_size=tcp_syn_options(sk,skb,&opts,&md5);elsetcp_options_size=tcp_established_options(sk,skb,&opts,
@@ -850,9 +850,9 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,th->seq=htonl(tcb->seq);th->ack_seq=htonl(tp->rcv_nxt);*(((__be16*)th)+6)=htons(((tcp_header_size>>2)<<12)|-tcb->flags);+tcb->tcp_flags);-if(unlikely(tcb->flags&TCPHDR_SYN)){+if(unlikely(tcb->tcp_flags&TCPHDR_SYN)){/* RFC1323: The window in SYN & SYN/ACK segments*isneverscaled.*/
@@ -875,7 +875,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,}tcp_options_write((__be32*)(th+1),tp,&opts);-if(likely((tcb->flags&TCPHDR_SYN)==0))+if(likely((tcb->tcp_flags&TCPHDR_SYN)==0))TCP_ECN_send(sk,skb,tcp_header_size);#ifdef CONFIG_TCP_MD5SIG
@@ -889,7 +889,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,icsk->icsk_af_ops->send_check(sk,skb);-if(likely(tcb->flags&TCPHDR_ACK))+if(likely(tcb->tcp_flags&TCPHDR_ACK))tcp_event_ack_sent(sk,tcp_skb_pcount(skb));if(skb->len!=tcp_header_size)
@@ -1032,9 +1032,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,TCP_SKB_CB(skb)->end_seq=TCP_SKB_CB(buff)->seq;/* PSH and FIN should only be set in the second packet. */-flags=TCP_SKB_CB(skb)->flags;-TCP_SKB_CB(skb)->flags=flags&~(TCPHDR_FIN|TCPHDR_PSH);-TCP_SKB_CB(buff)->flags=flags;+flags=TCP_SKB_CB(skb)->tcp_flags;+TCP_SKB_CB(skb)->tcp_flags=flags&~(TCPHDR_FIN|TCPHDR_PSH);+TCP_SKB_CB(buff)->tcp_flags=flags;TCP_SKB_CB(buff)->sacked=TCP_SKB_CB(skb)->sacked;if(!skb_shinfo(skb)->nr_frags&&skb->ip_summed!=CHECKSUM_PARTIAL){
@@ -1340,7 +1340,8 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp,u32in_flight,cwnd;/* Don't be strict about the congestion window for the final FIN. */-if((TCP_SKB_CB(skb)->flags&TCPHDR_FIN)&&tcp_skb_pcount(skb)==1)+if((TCP_SKB_CB(skb)->tcp_flags&TCPHDR_FIN)&&+tcp_skb_pcount(skb)==1)return1;in_flight=tcp_packets_in_flight(tp);
@@ -1497,9 +1498,9 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,TCP_SKB_CB(skb)->end_seq=TCP_SKB_CB(buff)->seq;/* PSH and FIN should only be set in the second packet. */-flags=TCP_SKB_CB(skb)->flags;-TCP_SKB_CB(skb)->flags=flags&~(TCPHDR_FIN|TCPHDR_PSH);-TCP_SKB_CB(buff)->flags=flags;+flags=TCP_SKB_CB(skb)->tcp_flags;+TCP_SKB_CB(skb)->tcp_flags=flags&~(TCPHDR_FIN|TCPHDR_PSH);+TCP_SKB_CB(buff)->tcp_flags=flags;/* This packet was never sent out yet, so no SACK bits. */TCP_SKB_CB(buff)->sacked=0;
@@ -1657,7 +1658,7 @@ static int tcp_mtu_probe(struct sock *sk)TCP_SKB_CB(nskb)->seq=TCP_SKB_CB(skb)->seq;TCP_SKB_CB(nskb)->end_seq=TCP_SKB_CB(skb)->seq+probe_size;-TCP_SKB_CB(nskb)->flags=TCPHDR_ACK;+TCP_SKB_CB(nskb)->tcp_flags=TCPHDR_ACK;TCP_SKB_CB(nskb)->sacked=0;nskb->csum=0;nskb->ip_summed=skb->ip_summed;
@@ -1677,11 +1678,11 @@ static int tcp_mtu_probe(struct sock *sk)if(skb->len<=copy){/* We've eaten all the data from this skb.*Throwitaway.*/-TCP_SKB_CB(nskb)->flags|=TCP_SKB_CB(skb)->flags;+TCP_SKB_CB(nskb)->tcp_flags|=TCP_SKB_CB(skb)->tcp_flags;tcp_unlink_write_queue(skb,sk);sk_wmem_free_skb(sk,skb);}else{-TCP_SKB_CB(nskb)->flags|=TCP_SKB_CB(skb)->flags&+TCP_SKB_CB(nskb)->tcp_flags|=TCP_SKB_CB(skb)->tcp_flags&~(TCPHDR_FIN|TCPHDR_PSH);if(!skb_shinfo(skb)->nr_frags){skb_pull(skb,copy);
@@ -1987,7 +1988,7 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)TCP_SKB_CB(skb)->end_seq=TCP_SKB_CB(next_skb)->end_seq;/* Merge over control information. This moves PSH/FIN etc. over */-TCP_SKB_CB(skb)->flags|=TCP_SKB_CB(next_skb)->flags;+TCP_SKB_CB(skb)->tcp_flags|=TCP_SKB_CB(next_skb)->tcp_flags;/* All done, get rid of second SKB and account for it so*packetcountingdoesnotbreak.
@@ -2127,12 +2128,12 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)*sinceitischeaptodosoandsavesbytesonthenetwork.*/if(skb->len>0&&-(TCP_SKB_CB(skb)->flags&TCPHDR_FIN)&&+(TCP_SKB_CB(skb)->tcp_flags&TCPHDR_FIN)&&tp->snd_una==(TCP_SKB_CB(skb)->end_seq-1)){if(!pskb_trim(skb,0)){/* Reuse, even though it does some unnecessary work */tcp_init_nondata_skb(skb,TCP_SKB_CB(skb)->end_seq-1,-TCP_SKB_CB(skb)->flags);+TCP_SKB_CB(skb)->tcp_flags);skb->ip_summed=CHECKSUM_NONE;}}
Rename struct tcp_skb_cb "flags" to "tcp_flags" to ease code review and
maintenance.
Its content is a combination of FIN/SYN/RST/PSH/ACK/URG/ECE/CWR flags
Signed-off-by: Eric Dumazet <redacted>