162306a36Sopenharmony_ci============
262306a36Sopenharmony_ciSNMP counter
362306a36Sopenharmony_ci============
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciThis document explains the meaning of SNMP counters.
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciGeneral IPv4 counters
862306a36Sopenharmony_ci=====================
962306a36Sopenharmony_ciAll layer 4 packets and ICMP packets will change these counters, but
1062306a36Sopenharmony_cithese counters won't be changed by layer 2 packets (such as STP) or
1162306a36Sopenharmony_ciARP packets.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci* IpInReceives
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciDefined in `RFC1213 ipInReceives`_
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci.. _RFC1213 ipInReceives: https://tools.ietf.org/html/rfc1213#page-26
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciThe number of packets received by the IP layer. It gets increasing at the
2062306a36Sopenharmony_cibeginning of ip_rcv function, always be updated together with
2162306a36Sopenharmony_ciIpExtInOctets. It will be increased even if the packet is dropped
2262306a36Sopenharmony_cilater (e.g. due to the IP header is invalid or the checksum is wrong
2362306a36Sopenharmony_ciand so on).  It indicates the number of aggregated segments after
2462306a36Sopenharmony_ciGRO/LRO.
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci* IpInDelivers
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciDefined in `RFC1213 ipInDelivers`_
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci.. _RFC1213 ipInDelivers: https://tools.ietf.org/html/rfc1213#page-28
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciThe number of packets delivers to the upper layer protocols. E.g. TCP, UDP,
3362306a36Sopenharmony_ciICMP and so on. If no one listens on a raw socket, only kernel
3462306a36Sopenharmony_cisupported protocols will be delivered, if someone listens on the raw
3562306a36Sopenharmony_cisocket, all valid IP packets will be delivered.
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci* IpOutRequests
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ciDefined in `RFC1213 ipOutRequests`_
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci.. _RFC1213 ipOutRequests: https://tools.ietf.org/html/rfc1213#page-28
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciThe number of packets sent via IP layer, for both single cast and
4462306a36Sopenharmony_cimulticast packets, and would always be updated together with
4562306a36Sopenharmony_ciIpExtOutOctets.
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci* IpExtInOctets and IpExtOutOctets
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciThey are Linux kernel extensions, no RFC definitions. Please note,
5062306a36Sopenharmony_ciRFC1213 indeed defines ifInOctets  and ifOutOctets, but they
5162306a36Sopenharmony_ciare different things. The ifInOctets and ifOutOctets include the MAC
5262306a36Sopenharmony_cilayer header size but IpExtInOctets and IpExtOutOctets don't, they
5362306a36Sopenharmony_cionly include the IP layer header and the IP layer data.
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci* IpExtInNoECTPkts, IpExtInECT1Pkts, IpExtInECT0Pkts, IpExtInCEPkts
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciThey indicate the number of four kinds of ECN IP packets, please refer
5862306a36Sopenharmony_ci`Explicit Congestion Notification`_ for more details.
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci.. _Explicit Congestion Notification: https://tools.ietf.org/html/rfc3168#page-6
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ciThese 4 counters calculate how many packets received per ECN
6362306a36Sopenharmony_cistatus. They count the real frame number regardless the LRO/GRO. So
6462306a36Sopenharmony_cifor the same packet, you might find that IpInReceives count 1, but
6562306a36Sopenharmony_ciIpExtInNoECTPkts counts 2 or more.
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci* IpInHdrErrors
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ciDefined in `RFC1213 ipInHdrErrors`_. It indicates the packet is
7062306a36Sopenharmony_cidropped due to the IP header error. It might happen in both IP input
7162306a36Sopenharmony_ciand IP forward paths.
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci.. _RFC1213 ipInHdrErrors: https://tools.ietf.org/html/rfc1213#page-27
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci* IpInAddrErrors
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ciDefined in `RFC1213 ipInAddrErrors`_. It will be increased in two
7862306a36Sopenharmony_ciscenarios: (1) The IP address is invalid. (2) The destination IP
7962306a36Sopenharmony_ciaddress is not a local address and IP forwarding is not enabled
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci.. _RFC1213 ipInAddrErrors: https://tools.ietf.org/html/rfc1213#page-27
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci* IpExtInNoRoutes
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciThis counter means the packet is dropped when the IP stack receives a
8662306a36Sopenharmony_cipacket and can't find a route for it from the route table. It might
8762306a36Sopenharmony_cihappen when IP forwarding is enabled and the destination IP address is
8862306a36Sopenharmony_cinot a local address and there is no route for the destination IP
8962306a36Sopenharmony_ciaddress.
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci* IpInUnknownProtos
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ciDefined in `RFC1213 ipInUnknownProtos`_. It will be increased if the
9462306a36Sopenharmony_cilayer 4 protocol is unsupported by kernel. If an application is using
9562306a36Sopenharmony_ciraw socket, kernel will always deliver the packet to the raw socket
9662306a36Sopenharmony_ciand this counter won't be increased.
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci.. _RFC1213 ipInUnknownProtos: https://tools.ietf.org/html/rfc1213#page-27
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci* IpExtInTruncatedPkts
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciFor IPv4 packet, it means the actual data size is smaller than the
10362306a36Sopenharmony_ci"Total Length" field in the IPv4 header.
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci* IpInDiscards
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciDefined in `RFC1213 ipInDiscards`_. It indicates the packet is dropped
10862306a36Sopenharmony_ciin the IP receiving path and due to kernel internal reasons (e.g. no
10962306a36Sopenharmony_cienough memory).
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci.. _RFC1213 ipInDiscards: https://tools.ietf.org/html/rfc1213#page-28
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci* IpOutDiscards
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciDefined in `RFC1213 ipOutDiscards`_. It indicates the packet is
11662306a36Sopenharmony_cidropped in the IP sending path and due to kernel internal reasons.
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci.. _RFC1213 ipOutDiscards: https://tools.ietf.org/html/rfc1213#page-28
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci* IpOutNoRoutes
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ciDefined in `RFC1213 ipOutNoRoutes`_. It indicates the packet is
12362306a36Sopenharmony_cidropped in the IP sending path and no route is found for it.
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci.. _RFC1213 ipOutNoRoutes: https://tools.ietf.org/html/rfc1213#page-29
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciICMP counters
12862306a36Sopenharmony_ci=============
12962306a36Sopenharmony_ci* IcmpInMsgs and IcmpOutMsgs
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ciDefined by `RFC1213 icmpInMsgs`_ and `RFC1213 icmpOutMsgs`_
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci.. _RFC1213 icmpInMsgs: https://tools.ietf.org/html/rfc1213#page-41
13462306a36Sopenharmony_ci.. _RFC1213 icmpOutMsgs: https://tools.ietf.org/html/rfc1213#page-43
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ciAs mentioned in the RFC1213, these two counters include errors, they
13762306a36Sopenharmony_ciwould be increased even if the ICMP packet has an invalid type. The
13862306a36Sopenharmony_ciICMP output path will check the header of a raw socket, so the
13962306a36Sopenharmony_ciIcmpOutMsgs would still be updated if the IP header is constructed by
14062306a36Sopenharmony_cia userspace program.
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci* ICMP named types
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci| These counters include most of common ICMP types, they are:
14562306a36Sopenharmony_ci| IcmpInDestUnreachs: `RFC1213 icmpInDestUnreachs`_
14662306a36Sopenharmony_ci| IcmpInTimeExcds: `RFC1213 icmpInTimeExcds`_
14762306a36Sopenharmony_ci| IcmpInParmProbs: `RFC1213 icmpInParmProbs`_
14862306a36Sopenharmony_ci| IcmpInSrcQuenchs: `RFC1213 icmpInSrcQuenchs`_
14962306a36Sopenharmony_ci| IcmpInRedirects: `RFC1213 icmpInRedirects`_
15062306a36Sopenharmony_ci| IcmpInEchos: `RFC1213 icmpInEchos`_
15162306a36Sopenharmony_ci| IcmpInEchoReps: `RFC1213 icmpInEchoReps`_
15262306a36Sopenharmony_ci| IcmpInTimestamps: `RFC1213 icmpInTimestamps`_
15362306a36Sopenharmony_ci| IcmpInTimestampReps: `RFC1213 icmpInTimestampReps`_
15462306a36Sopenharmony_ci| IcmpInAddrMasks: `RFC1213 icmpInAddrMasks`_
15562306a36Sopenharmony_ci| IcmpInAddrMaskReps: `RFC1213 icmpInAddrMaskReps`_
15662306a36Sopenharmony_ci| IcmpOutDestUnreachs: `RFC1213 icmpOutDestUnreachs`_
15762306a36Sopenharmony_ci| IcmpOutTimeExcds: `RFC1213 icmpOutTimeExcds`_
15862306a36Sopenharmony_ci| IcmpOutParmProbs: `RFC1213 icmpOutParmProbs`_
15962306a36Sopenharmony_ci| IcmpOutSrcQuenchs: `RFC1213 icmpOutSrcQuenchs`_
16062306a36Sopenharmony_ci| IcmpOutRedirects: `RFC1213 icmpOutRedirects`_
16162306a36Sopenharmony_ci| IcmpOutEchos: `RFC1213 icmpOutEchos`_
16262306a36Sopenharmony_ci| IcmpOutEchoReps: `RFC1213 icmpOutEchoReps`_
16362306a36Sopenharmony_ci| IcmpOutTimestamps: `RFC1213 icmpOutTimestamps`_
16462306a36Sopenharmony_ci| IcmpOutTimestampReps: `RFC1213 icmpOutTimestampReps`_
16562306a36Sopenharmony_ci| IcmpOutAddrMasks: `RFC1213 icmpOutAddrMasks`_
16662306a36Sopenharmony_ci| IcmpOutAddrMaskReps: `RFC1213 icmpOutAddrMaskReps`_
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci.. _RFC1213 icmpInDestUnreachs: https://tools.ietf.org/html/rfc1213#page-41
16962306a36Sopenharmony_ci.. _RFC1213 icmpInTimeExcds: https://tools.ietf.org/html/rfc1213#page-41
17062306a36Sopenharmony_ci.. _RFC1213 icmpInParmProbs: https://tools.ietf.org/html/rfc1213#page-42
17162306a36Sopenharmony_ci.. _RFC1213 icmpInSrcQuenchs: https://tools.ietf.org/html/rfc1213#page-42
17262306a36Sopenharmony_ci.. _RFC1213 icmpInRedirects: https://tools.ietf.org/html/rfc1213#page-42
17362306a36Sopenharmony_ci.. _RFC1213 icmpInEchos: https://tools.ietf.org/html/rfc1213#page-42
17462306a36Sopenharmony_ci.. _RFC1213 icmpInEchoReps: https://tools.ietf.org/html/rfc1213#page-42
17562306a36Sopenharmony_ci.. _RFC1213 icmpInTimestamps: https://tools.ietf.org/html/rfc1213#page-42
17662306a36Sopenharmony_ci.. _RFC1213 icmpInTimestampReps: https://tools.ietf.org/html/rfc1213#page-43
17762306a36Sopenharmony_ci.. _RFC1213 icmpInAddrMasks: https://tools.ietf.org/html/rfc1213#page-43
17862306a36Sopenharmony_ci.. _RFC1213 icmpInAddrMaskReps: https://tools.ietf.org/html/rfc1213#page-43
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci.. _RFC1213 icmpOutDestUnreachs: https://tools.ietf.org/html/rfc1213#page-44
18162306a36Sopenharmony_ci.. _RFC1213 icmpOutTimeExcds: https://tools.ietf.org/html/rfc1213#page-44
18262306a36Sopenharmony_ci.. _RFC1213 icmpOutParmProbs: https://tools.ietf.org/html/rfc1213#page-44
18362306a36Sopenharmony_ci.. _RFC1213 icmpOutSrcQuenchs: https://tools.ietf.org/html/rfc1213#page-44
18462306a36Sopenharmony_ci.. _RFC1213 icmpOutRedirects: https://tools.ietf.org/html/rfc1213#page-44
18562306a36Sopenharmony_ci.. _RFC1213 icmpOutEchos: https://tools.ietf.org/html/rfc1213#page-45
18662306a36Sopenharmony_ci.. _RFC1213 icmpOutEchoReps: https://tools.ietf.org/html/rfc1213#page-45
18762306a36Sopenharmony_ci.. _RFC1213 icmpOutTimestamps: https://tools.ietf.org/html/rfc1213#page-45
18862306a36Sopenharmony_ci.. _RFC1213 icmpOutTimestampReps: https://tools.ietf.org/html/rfc1213#page-45
18962306a36Sopenharmony_ci.. _RFC1213 icmpOutAddrMasks: https://tools.ietf.org/html/rfc1213#page-45
19062306a36Sopenharmony_ci.. _RFC1213 icmpOutAddrMaskReps: https://tools.ietf.org/html/rfc1213#page-46
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ciEvery ICMP type has two counters: 'In' and 'Out'. E.g., for the ICMP
19362306a36Sopenharmony_ciEcho packet, they are IcmpInEchos and IcmpOutEchos. Their meanings are
19462306a36Sopenharmony_cistraightforward. The 'In' counter means kernel receives such a packet
19562306a36Sopenharmony_ciand the 'Out' counter means kernel sends such a packet.
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci* ICMP numeric types
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ciThey are IcmpMsgInType[N] and IcmpMsgOutType[N], the [N] indicates the
20062306a36Sopenharmony_ciICMP type number. These counters track all kinds of ICMP packets. The
20162306a36Sopenharmony_ciICMP type number definition could be found in the `ICMP parameters`_
20262306a36Sopenharmony_cidocument.
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci.. _ICMP parameters: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ciFor example, if the Linux kernel sends an ICMP Echo packet, the
20762306a36Sopenharmony_ciIcmpMsgOutType8 would increase 1. And if kernel gets an ICMP Echo Reply
20862306a36Sopenharmony_cipacket, IcmpMsgInType0 would increase 1.
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci* IcmpInCsumErrors
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ciThis counter indicates the checksum of the ICMP packet is
21362306a36Sopenharmony_ciwrong. Kernel verifies the checksum after updating the IcmpInMsgs and
21462306a36Sopenharmony_cibefore updating IcmpMsgInType[N]. If a packet has bad checksum, the
21562306a36Sopenharmony_ciIcmpInMsgs would be updated but none of IcmpMsgInType[N] would be updated.
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci* IcmpInErrors and IcmpOutErrors
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ciDefined by `RFC1213 icmpInErrors`_ and `RFC1213 icmpOutErrors`_
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci.. _RFC1213 icmpInErrors: https://tools.ietf.org/html/rfc1213#page-41
22262306a36Sopenharmony_ci.. _RFC1213 icmpOutErrors: https://tools.ietf.org/html/rfc1213#page-43
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ciWhen an error occurs in the ICMP packet handler path, these two
22562306a36Sopenharmony_cicounters would be updated. The receiving packet path use IcmpInErrors
22662306a36Sopenharmony_ciand the sending packet path use IcmpOutErrors. When IcmpInCsumErrors
22762306a36Sopenharmony_ciis increased, IcmpInErrors would always be increased too.
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cirelationship of the ICMP counters
23062306a36Sopenharmony_ci---------------------------------
23162306a36Sopenharmony_ciThe sum of IcmpMsgOutType[N] is always equal to IcmpOutMsgs, as they
23262306a36Sopenharmony_ciare updated at the same time. The sum of IcmpMsgInType[N] plus
23362306a36Sopenharmony_ciIcmpInErrors should be equal or larger than IcmpInMsgs. When kernel
23462306a36Sopenharmony_cireceives an ICMP packet, kernel follows below logic:
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci1. increase IcmpInMsgs
23762306a36Sopenharmony_ci2. if has any error, update IcmpInErrors and finish the process
23862306a36Sopenharmony_ci3. update IcmpMsgOutType[N]
23962306a36Sopenharmony_ci4. handle the packet depending on the type, if has any error, update
24062306a36Sopenharmony_ci   IcmpInErrors and finish the process
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ciSo if all errors occur in step (2), IcmpInMsgs should be equal to the
24362306a36Sopenharmony_cisum of IcmpMsgOutType[N] plus IcmpInErrors. If all errors occur in
24462306a36Sopenharmony_cistep (4), IcmpInMsgs should be equal to the sum of
24562306a36Sopenharmony_ciIcmpMsgOutType[N]. If the errors occur in both step (2) and step (4),
24662306a36Sopenharmony_ciIcmpInMsgs should be less than the sum of IcmpMsgOutType[N] plus
24762306a36Sopenharmony_ciIcmpInErrors.
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ciGeneral TCP counters
25062306a36Sopenharmony_ci====================
25162306a36Sopenharmony_ci* TcpInSegs
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ciDefined in `RFC1213 tcpInSegs`_
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci.. _RFC1213 tcpInSegs: https://tools.ietf.org/html/rfc1213#page-48
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ciThe number of packets received by the TCP layer. As mentioned in
25862306a36Sopenharmony_ciRFC1213, it includes the packets received in error, such as checksum
25962306a36Sopenharmony_cierror, invalid TCP header and so on. Only one error won't be included:
26062306a36Sopenharmony_ciif the layer 2 destination address is not the NIC's layer 2
26162306a36Sopenharmony_ciaddress. It might happen if the packet is a multicast or broadcast
26262306a36Sopenharmony_cipacket, or the NIC is in promiscuous mode. In these situations, the
26362306a36Sopenharmony_cipackets would be delivered to the TCP layer, but the TCP layer will discard
26462306a36Sopenharmony_cithese packets before increasing TcpInSegs. The TcpInSegs counter
26562306a36Sopenharmony_ciisn't aware of GRO. So if two packets are merged by GRO, the TcpInSegs
26662306a36Sopenharmony_cicounter would only increase 1.
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci* TcpOutSegs
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ciDefined in `RFC1213 tcpOutSegs`_
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci.. _RFC1213 tcpOutSegs: https://tools.ietf.org/html/rfc1213#page-48
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ciThe number of packets sent by the TCP layer. As mentioned in RFC1213,
27562306a36Sopenharmony_ciit excludes the retransmitted packets. But it includes the SYN, ACK
27662306a36Sopenharmony_ciand RST packets. Doesn't like TcpInSegs, the TcpOutSegs is aware of
27762306a36Sopenharmony_ciGSO, so if a packet would be split to 2 by GSO, TcpOutSegs will
27862306a36Sopenharmony_ciincrease 2.
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci* TcpActiveOpens
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ciDefined in `RFC1213 tcpActiveOpens`_
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci.. _RFC1213 tcpActiveOpens: https://tools.ietf.org/html/rfc1213#page-47
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ciIt means the TCP layer sends a SYN, and come into the SYN-SENT
28762306a36Sopenharmony_cistate. Every time TcpActiveOpens increases 1, TcpOutSegs should always
28862306a36Sopenharmony_ciincrease 1.
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci* TcpPassiveOpens
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ciDefined in `RFC1213 tcpPassiveOpens`_
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci.. _RFC1213 tcpPassiveOpens: https://tools.ietf.org/html/rfc1213#page-47
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ciIt means the TCP layer receives a SYN, replies a SYN+ACK, come into
29762306a36Sopenharmony_cithe SYN-RCVD state.
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci* TcpExtTCPRcvCoalesce
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ciWhen packets are received by the TCP layer and are not be read by the
30262306a36Sopenharmony_ciapplication, the TCP layer will try to merge them. This counter
30362306a36Sopenharmony_ciindicate how many packets are merged in such situation. If GRO is
30462306a36Sopenharmony_cienabled, lots of packets would be merged by GRO, these packets
30562306a36Sopenharmony_ciwouldn't be counted to TcpExtTCPRcvCoalesce.
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci* TcpExtTCPAutoCorking
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ciWhen sending packets, the TCP layer will try to merge small packets to
31062306a36Sopenharmony_cia bigger one. This counter increase 1 for every packet merged in such
31162306a36Sopenharmony_cisituation. Please refer to the LWN article for more details:
31262306a36Sopenharmony_cihttps://lwn.net/Articles/576263/
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci* TcpExtTCPOrigDataSent
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ciThis counter is explained by `kernel commit f19c29e3e391`_, I pasted the
31762306a36Sopenharmony_ciexplanation below::
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci  TCPOrigDataSent: number of outgoing packets with original data (excluding
32062306a36Sopenharmony_ci  retransmission but including data-in-SYN). This counter is different from
32162306a36Sopenharmony_ci  TcpOutSegs because TcpOutSegs also tracks pure ACKs. TCPOrigDataSent is
32262306a36Sopenharmony_ci  more useful to track the TCP retransmission rate.
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci* TCPSynRetrans
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ciThis counter is explained by `kernel commit f19c29e3e391`_, I pasted the
32762306a36Sopenharmony_ciexplanation below::
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci  TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down
33062306a36Sopenharmony_ci  retransmissions into SYN, fast-retransmits, timeout retransmits, etc.
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci* TCPFastOpenActiveFail
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ciThis counter is explained by `kernel commit f19c29e3e391`_, I pasted the
33562306a36Sopenharmony_ciexplanation below::
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci  TCPFastOpenActiveFail: Fast Open attempts (SYN/data) failed because
33862306a36Sopenharmony_ci  the remote does not accept it or the attempts timed out.
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci.. _kernel commit f19c29e3e391: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f19c29e3e391a66a273e9afebaf01917245148cd
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci* TcpExtListenOverflows and TcpExtListenDrops
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ciWhen kernel receives a SYN from a client, and if the TCP accept queue
34562306a36Sopenharmony_ciis full, kernel will drop the SYN and add 1 to TcpExtListenOverflows.
34662306a36Sopenharmony_ciAt the same time kernel will also add 1 to TcpExtListenDrops. When a
34762306a36Sopenharmony_ciTCP socket is in LISTEN state, and kernel need to drop a packet,
34862306a36Sopenharmony_cikernel would always add 1 to TcpExtListenDrops. So increase
34962306a36Sopenharmony_ciTcpExtListenOverflows would let TcpExtListenDrops increasing at the
35062306a36Sopenharmony_cisame time, but TcpExtListenDrops would also increase without
35162306a36Sopenharmony_ciTcpExtListenOverflows increasing, e.g. a memory allocation fail would
35262306a36Sopenharmony_cialso let TcpExtListenDrops increase.
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ciNote: The above explanation is based on kernel 4.10 or above version, on
35562306a36Sopenharmony_cian old kernel, the TCP stack has different behavior when TCP accept
35662306a36Sopenharmony_ciqueue is full. On the old kernel, TCP stack won't drop the SYN, it
35762306a36Sopenharmony_ciwould complete the 3-way handshake. As the accept queue is full, TCP
35862306a36Sopenharmony_cistack will keep the socket in the TCP half-open queue. As it is in the
35962306a36Sopenharmony_cihalf open queue, TCP stack will send SYN+ACK on an exponential backoff
36062306a36Sopenharmony_citimer, after client replies ACK, TCP stack checks whether the accept
36162306a36Sopenharmony_ciqueue is still full, if it is not full, moves the socket to the accept
36262306a36Sopenharmony_ciqueue, if it is full, keeps the socket in the half-open queue, at next
36362306a36Sopenharmony_citime client replies ACK, this socket will get another chance to move
36462306a36Sopenharmony_cito the accept queue.
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ciTCP Fast Open
36862306a36Sopenharmony_ci=============
36962306a36Sopenharmony_ci* TcpEstabResets
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ciDefined in `RFC1213 tcpEstabResets`_.
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci.. _RFC1213 tcpEstabResets: https://tools.ietf.org/html/rfc1213#page-48
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci* TcpAttemptFails
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ciDefined in `RFC1213 tcpAttemptFails`_.
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci.. _RFC1213 tcpAttemptFails: https://tools.ietf.org/html/rfc1213#page-48
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci* TcpOutRsts
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ciDefined in `RFC1213 tcpOutRsts`_. The RFC says this counter indicates
38462306a36Sopenharmony_cithe 'segments sent containing the RST flag', but in linux kernel, this
38562306a36Sopenharmony_cicounter indicates the segments kernel tried to send. The sending
38662306a36Sopenharmony_ciprocess might be failed due to some errors (e.g. memory alloc failed).
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci.. _RFC1213 tcpOutRsts: https://tools.ietf.org/html/rfc1213#page-52
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci* TcpExtTCPSpuriousRtxHostQueues
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ciWhen the TCP stack wants to retransmit a packet, and finds that packet
39362306a36Sopenharmony_ciis not lost in the network, but the packet is not sent yet, the TCP
39462306a36Sopenharmony_cistack would give up the retransmission and update this counter. It
39562306a36Sopenharmony_cimight happen if a packet stays too long time in a qdisc or driver
39662306a36Sopenharmony_ciqueue.
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci* TcpEstabResets
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ciThe socket receives a RST packet in Establish or CloseWait state.
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci* TcpExtTCPKeepAlive
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ciThis counter indicates many keepalive packets were sent. The keepalive
40562306a36Sopenharmony_ciwon't be enabled by default. A userspace program could enable it by
40662306a36Sopenharmony_cisetting the SO_KEEPALIVE socket option.
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci* TcpExtTCPSpuriousRTOs
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ciThe spurious retransmission timeout detected by the `F-RTO`_
41162306a36Sopenharmony_cialgorithm.
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci.. _F-RTO: https://tools.ietf.org/html/rfc5682
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ciTCP Fast Path
41662306a36Sopenharmony_ci=============
41762306a36Sopenharmony_ciWhen kernel receives a TCP packet, it has two paths to handler the
41862306a36Sopenharmony_cipacket, one is fast path, another is slow path. The comment in kernel
41962306a36Sopenharmony_cicode provides a good explanation of them, I pasted them below::
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci  It is split into a fast path and a slow path. The fast path is
42262306a36Sopenharmony_ci  disabled when:
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci  - A zero window was announced from us
42562306a36Sopenharmony_ci  - zero window probing
42662306a36Sopenharmony_ci    is only handled properly on the slow path.
42762306a36Sopenharmony_ci  - Out of order segments arrived.
42862306a36Sopenharmony_ci  - Urgent data is expected.
42962306a36Sopenharmony_ci  - There is no buffer space left
43062306a36Sopenharmony_ci  - Unexpected TCP flags/window values/header lengths are received
43162306a36Sopenharmony_ci    (detected by checking the TCP header against pred_flags)
43262306a36Sopenharmony_ci  - Data is sent in both directions. The fast path only supports pure senders
43362306a36Sopenharmony_ci    or pure receivers (this means either the sequence number or the ack
43462306a36Sopenharmony_ci    value must stay constant)
43562306a36Sopenharmony_ci  - Unexpected TCP option.
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ciKernel will try to use fast path unless any of the above conditions
43862306a36Sopenharmony_ciare satisfied. If the packets are out of order, kernel will handle
43962306a36Sopenharmony_cithem in slow path, which means the performance might be not very
44062306a36Sopenharmony_cigood. Kernel would also come into slow path if the "Delayed ack" is
44162306a36Sopenharmony_ciused, because when using "Delayed ack", the data is sent in both
44262306a36Sopenharmony_cidirections. When the TCP window scale option is not used, kernel will
44362306a36Sopenharmony_citry to enable fast path immediately when the connection comes into the
44462306a36Sopenharmony_ciestablished state, but if the TCP window scale option is used, kernel
44562306a36Sopenharmony_ciwill disable the fast path at first, and try to enable it after kernel
44662306a36Sopenharmony_cireceives packets.
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci* TcpExtTCPPureAcks and TcpExtTCPHPAcks
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ciIf a packet set ACK flag and has no data, it is a pure ACK packet, if
45162306a36Sopenharmony_cikernel handles it in the fast path, TcpExtTCPHPAcks will increase 1,
45262306a36Sopenharmony_ciif kernel handles it in the slow path, TcpExtTCPPureAcks will
45362306a36Sopenharmony_ciincrease 1.
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci* TcpExtTCPHPHits
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ciIf a TCP packet has data (which means it is not a pure ACK packet),
45862306a36Sopenharmony_ciand this packet is handled in the fast path, TcpExtTCPHPHits will
45962306a36Sopenharmony_ciincrease 1.
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ciTCP abort
46362306a36Sopenharmony_ci=========
46462306a36Sopenharmony_ci* TcpExtTCPAbortOnData
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ciIt means TCP layer has data in flight, but need to close the
46762306a36Sopenharmony_ciconnection. So TCP layer sends a RST to the other side, indicate the
46862306a36Sopenharmony_ciconnection is not closed very graceful. An easy way to increase this
46962306a36Sopenharmony_cicounter is using the SO_LINGER option. Please refer to the SO_LINGER
47062306a36Sopenharmony_cisection of the `socket man page`_:
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci.. _socket man page: http://man7.org/linux/man-pages/man7/socket.7.html
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ciBy default, when an application closes a connection, the close function
47562306a36Sopenharmony_ciwill return immediately and kernel will try to send the in-flight data
47662306a36Sopenharmony_ciasync. If you use the SO_LINGER option, set l_onoff to 1, and l_linger
47762306a36Sopenharmony_cito a positive number, the close function won't return immediately, but
47862306a36Sopenharmony_ciwait for the in-flight data are acked by the other side, the max wait
47962306a36Sopenharmony_citime is l_linger seconds. If set l_onoff to 1 and set l_linger to 0,
48062306a36Sopenharmony_ciwhen the application closes a connection, kernel will send a RST
48162306a36Sopenharmony_ciimmediately and increase the TcpExtTCPAbortOnData counter.
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci* TcpExtTCPAbortOnClose
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ciThis counter means the application has unread data in the TCP layer when
48662306a36Sopenharmony_cithe application wants to close the TCP connection. In such a situation,
48762306a36Sopenharmony_cikernel will send a RST to the other side of the TCP connection.
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci* TcpExtTCPAbortOnMemory
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ciWhen an application closes a TCP connection, kernel still need to track
49262306a36Sopenharmony_cithe connection, let it complete the TCP disconnect process. E.g. an
49362306a36Sopenharmony_ciapp calls the close method of a socket, kernel sends fin to the other
49462306a36Sopenharmony_ciside of the connection, then the app has no relationship with the
49562306a36Sopenharmony_cisocket any more, but kernel need to keep the socket, this socket
49662306a36Sopenharmony_cibecomes an orphan socket, kernel waits for the reply of the other side,
49762306a36Sopenharmony_ciand would come to the TIME_WAIT state finally. When kernel has no
49862306a36Sopenharmony_cienough memory to keep the orphan socket, kernel would send an RST to
49962306a36Sopenharmony_cithe other side, and delete the socket, in such situation, kernel will
50062306a36Sopenharmony_ciincrease 1 to the TcpExtTCPAbortOnMemory. Two conditions would trigger
50162306a36Sopenharmony_ciTcpExtTCPAbortOnMemory:
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci1. the memory used by the TCP protocol is higher than the third value of
50462306a36Sopenharmony_cithe tcp_mem. Please refer the tcp_mem section in the `TCP man page`_:
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci.. _TCP man page: http://man7.org/linux/man-pages/man7/tcp.7.html
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci2. the orphan socket count is higher than net.ipv4.tcp_max_orphans
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci* TcpExtTCPAbortOnTimeout
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ciThis counter will increase when any of the TCP timers expire. In such
51462306a36Sopenharmony_cisituation, kernel won't send RST, just give up the connection.
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci* TcpExtTCPAbortOnLinger
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ciWhen a TCP connection comes into FIN_WAIT_2 state, instead of waiting
51962306a36Sopenharmony_cifor the fin packet from the other side, kernel could send a RST and
52062306a36Sopenharmony_cidelete the socket immediately. This is not the default behavior of
52162306a36Sopenharmony_ciLinux kernel TCP stack. By configuring the TCP_LINGER2 socket option,
52262306a36Sopenharmony_ciyou could let kernel follow this behavior.
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci* TcpExtTCPAbortFailed
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ciThe kernel TCP layer will send RST if the `RFC2525 2.17 section`_ is
52762306a36Sopenharmony_cisatisfied. If an internal error occurs during this process,
52862306a36Sopenharmony_ciTcpExtTCPAbortFailed will be increased.
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci.. _RFC2525 2.17 section: https://tools.ietf.org/html/rfc2525#page-50
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ciTCP Hybrid Slow Start
53362306a36Sopenharmony_ci=====================
53462306a36Sopenharmony_ciThe Hybrid Slow Start algorithm is an enhancement of the traditional
53562306a36Sopenharmony_ciTCP congestion window Slow Start algorithm. It uses two pieces of
53662306a36Sopenharmony_ciinformation to detect whether the max bandwidth of the TCP path is
53762306a36Sopenharmony_ciapproached. The two pieces of information are ACK train length and
53862306a36Sopenharmony_ciincrease in packet delay. For detail information, please refer the
53962306a36Sopenharmony_ci`Hybrid Slow Start paper`_. Either ACK train length or packet delay
54062306a36Sopenharmony_cihits a specific threshold, the congestion control algorithm will come
54162306a36Sopenharmony_ciinto the Congestion Avoidance state. Until v4.20, two congestion
54262306a36Sopenharmony_cicontrol algorithms are using Hybrid Slow Start, they are cubic (the
54362306a36Sopenharmony_cidefault congestion control algorithm) and cdg. Four snmp counters
54462306a36Sopenharmony_cirelate with the Hybrid Slow Start algorithm.
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci.. _Hybrid Slow Start paper: https://pdfs.semanticscholar.org/25e9/ef3f03315782c7f1cbcd31b587857adae7d1.pdf
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci* TcpExtTCPHystartTrainDetect
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ciHow many times the ACK train length threshold is detected
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci* TcpExtTCPHystartTrainCwnd
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ciThe sum of CWND detected by ACK train length. Dividing this value by
55562306a36Sopenharmony_ciTcpExtTCPHystartTrainDetect is the average CWND which detected by the
55662306a36Sopenharmony_ciACK train length.
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci* TcpExtTCPHystartDelayDetect
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ciHow many times the packet delay threshold is detected.
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci* TcpExtTCPHystartDelayCwnd
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ciThe sum of CWND detected by packet delay. Dividing this value by
56562306a36Sopenharmony_ciTcpExtTCPHystartDelayDetect is the average CWND which detected by the
56662306a36Sopenharmony_cipacket delay.
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ciTCP retransmission and congestion control
56962306a36Sopenharmony_ci=========================================
57062306a36Sopenharmony_ciThe TCP protocol has two retransmission mechanisms: SACK and fast
57162306a36Sopenharmony_cirecovery. They are exclusive with each other. When SACK is enabled,
57262306a36Sopenharmony_cithe kernel TCP stack would use SACK, or kernel would use fast
57362306a36Sopenharmony_cirecovery. The SACK is a TCP option, which is defined in `RFC2018`_,
57462306a36Sopenharmony_cithe fast recovery is defined in `RFC6582`_, which is also called
57562306a36Sopenharmony_ci'Reno'.
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ciThe TCP congestion control is a big and complex topic. To understand
57862306a36Sopenharmony_cithe related snmp counter, we need to know the states of the congestion
57962306a36Sopenharmony_cicontrol state machine. There are 5 states: Open, Disorder, CWR,
58062306a36Sopenharmony_ciRecovery and Loss. For details about these states, please refer page 5
58162306a36Sopenharmony_ciand page 6 of this document:
58262306a36Sopenharmony_cihttps://pdfs.semanticscholar.org/0e9c/968d09ab2e53e24c4dca5b2d67c7f7140f8e.pdf
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci.. _RFC2018: https://tools.ietf.org/html/rfc2018
58562306a36Sopenharmony_ci.. _RFC6582: https://tools.ietf.org/html/rfc6582
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci* TcpExtTCPRenoRecovery and TcpExtTCPSackRecovery
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ciWhen the congestion control comes into Recovery state, if sack is
59062306a36Sopenharmony_ciused, TcpExtTCPSackRecovery increases 1, if sack is not used,
59162306a36Sopenharmony_ciTcpExtTCPRenoRecovery increases 1. These two counters mean the TCP
59262306a36Sopenharmony_cistack begins to retransmit the lost packets.
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci* TcpExtTCPSACKReneging
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ciA packet was acknowledged by SACK, but the receiver has dropped this
59762306a36Sopenharmony_cipacket, so the sender needs to retransmit this packet. In this
59862306a36Sopenharmony_cisituation, the sender adds 1 to TcpExtTCPSACKReneging. A receiver
59962306a36Sopenharmony_cicould drop a packet which has been acknowledged by SACK, although it is
60062306a36Sopenharmony_ciunusual, it is allowed by the TCP protocol. The sender doesn't really
60162306a36Sopenharmony_ciknow what happened on the receiver side. The sender just waits until
60262306a36Sopenharmony_cithe RTO expires for this packet, then the sender assumes this packet
60362306a36Sopenharmony_cihas been dropped by the receiver.
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci* TcpExtTCPRenoReorder
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ciThe reorder packet is detected by fast recovery. It would only be used
60862306a36Sopenharmony_ciif SACK is disabled. The fast recovery algorithm detects recorder by
60962306a36Sopenharmony_cithe duplicate ACK number. E.g., if retransmission is triggered, and
61062306a36Sopenharmony_cithe original retransmitted packet is not lost, it is just out of
61162306a36Sopenharmony_ciorder, the receiver would acknowledge multiple times, one for the
61262306a36Sopenharmony_ciretransmitted packet, another for the arriving of the original out of
61362306a36Sopenharmony_ciorder packet. Thus the sender would find more ACks than its
61462306a36Sopenharmony_ciexpectation, and the sender knows out of order occurs.
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci* TcpExtTCPTSReorder
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ciThe reorder packet is detected when a hole is filled. E.g., assume the
61962306a36Sopenharmony_cisender sends packet 1,2,3,4,5, and the receiving order is
62062306a36Sopenharmony_ci1,2,4,5,3. When the sender receives the ACK of packet 3 (which will
62162306a36Sopenharmony_cifill the hole), two conditions will let TcpExtTCPTSReorder increase
62262306a36Sopenharmony_ci1: (1) if the packet 3 is not re-retransmitted yet. (2) if the packet
62362306a36Sopenharmony_ci3 is retransmitted but the timestamp of the packet 3's ACK is earlier
62462306a36Sopenharmony_cithan the retransmission timestamp.
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci* TcpExtTCPSACKReorder
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ciThe reorder packet detected by SACK. The SACK has two methods to
62962306a36Sopenharmony_cidetect reorder: (1) DSACK is received by the sender. It means the
63062306a36Sopenharmony_cisender sends the same packet more than one times. And the only reason
63162306a36Sopenharmony_ciis the sender believes an out of order packet is lost so it sends the
63262306a36Sopenharmony_cipacket again. (2) Assume packet 1,2,3,4,5 are sent by the sender, and
63362306a36Sopenharmony_cithe sender has received SACKs for packet 2 and 5, now the sender
63462306a36Sopenharmony_cireceives SACK for packet 4 and the sender doesn't retransmit the
63562306a36Sopenharmony_cipacket yet, the sender would know packet 4 is out of order. The TCP
63662306a36Sopenharmony_cistack of kernel will increase TcpExtTCPSACKReorder for both of the
63762306a36Sopenharmony_ciabove scenarios.
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci* TcpExtTCPSlowStartRetrans
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ciThe TCP stack wants to retransmit a packet and the congestion control
64262306a36Sopenharmony_cistate is 'Loss'.
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci* TcpExtTCPFastRetrans
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ciThe TCP stack wants to retransmit a packet and the congestion control
64762306a36Sopenharmony_cistate is not 'Loss'.
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci* TcpExtTCPLostRetransmit
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ciA SACK points out that a retransmission packet is lost again.
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci* TcpExtTCPRetransFail
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ciThe TCP stack tries to deliver a retransmission packet to lower layers
65662306a36Sopenharmony_cibut the lower layers return an error.
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci* TcpExtTCPSynRetrans
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ciThe TCP stack retransmits a SYN packet.
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ciDSACK
66362306a36Sopenharmony_ci=====
66462306a36Sopenharmony_ciThe DSACK is defined in `RFC2883`_. The receiver uses DSACK to report
66562306a36Sopenharmony_ciduplicate packets to the sender. There are two kinds of
66662306a36Sopenharmony_ciduplications: (1) a packet which has been acknowledged is
66762306a36Sopenharmony_ciduplicate. (2) an out of order packet is duplicate. The TCP stack
66862306a36Sopenharmony_cicounts these two kinds of duplications on both receiver side and
66962306a36Sopenharmony_cisender side.
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci.. _RFC2883 : https://tools.ietf.org/html/rfc2883
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci* TcpExtTCPDSACKOldSent
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ciThe TCP stack receives a duplicate packet which has been acked, so it
67662306a36Sopenharmony_cisends a DSACK to the sender.
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci* TcpExtTCPDSACKOfoSent
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ciThe TCP stack receives an out of order duplicate packet, so it sends a
68162306a36Sopenharmony_ciDSACK to the sender.
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci* TcpExtTCPDSACKRecv
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ciThe TCP stack receives a DSACK, which indicates an acknowledged
68662306a36Sopenharmony_ciduplicate packet is received.
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci* TcpExtTCPDSACKOfoRecv
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ciThe TCP stack receives a DSACK, which indicate an out of order
69162306a36Sopenharmony_ciduplicate packet is received.
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ciinvalid SACK and DSACK
69462306a36Sopenharmony_ci======================
69562306a36Sopenharmony_ciWhen a SACK (or DSACK) block is invalid, a corresponding counter would
69662306a36Sopenharmony_cibe updated. The validation method is base on the start/end sequence
69762306a36Sopenharmony_cinumber of the SACK block. For more details, please refer the comment
69862306a36Sopenharmony_ciof the function tcp_is_sackblock_valid in the kernel source code. A
69962306a36Sopenharmony_ciSACK option could have up to 4 blocks, they are checked
70062306a36Sopenharmony_ciindividually. E.g., if 3 blocks of a SACk is invalid, the
70162306a36Sopenharmony_cicorresponding counter would be updated 3 times. The comment of the
70262306a36Sopenharmony_ci`Add counters for discarded SACK blocks`_ patch has additional
70362306a36Sopenharmony_ciexplanation:
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci.. _Add counters for discarded SACK blocks: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=18f02545a9a16c9a89778b91a162ad16d510bb32
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci* TcpExtTCPSACKDiscard
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ciThis counter indicates how many SACK blocks are invalid. If the invalid
71062306a36Sopenharmony_ciSACK block is caused by ACK recording, the TCP stack will only ignore
71162306a36Sopenharmony_ciit and won't update this counter.
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci* TcpExtTCPDSACKIgnoredOld and TcpExtTCPDSACKIgnoredNoUndo
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ciWhen a DSACK block is invalid, one of these two counters would be
71662306a36Sopenharmony_ciupdated. Which counter will be updated depends on the undo_marker flag
71762306a36Sopenharmony_ciof the TCP socket. If the undo_marker is not set, the TCP stack isn't
71862306a36Sopenharmony_cilikely to re-transmit any packets, and we still receive an invalid
71962306a36Sopenharmony_ciDSACK block, the reason might be that the packet is duplicated in the
72062306a36Sopenharmony_cimiddle of the network. In such scenario, TcpExtTCPDSACKIgnoredNoUndo
72162306a36Sopenharmony_ciwill be updated. If the undo_marker is set, TcpExtTCPDSACKIgnoredOld
72262306a36Sopenharmony_ciwill be updated. As implied in its name, it might be an old packet.
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ciSACK shift
72562306a36Sopenharmony_ci==========
72662306a36Sopenharmony_ciThe linux networking stack stores data in sk_buff struct (skb for
72762306a36Sopenharmony_cishort). If a SACK block acrosses multiple skb, the TCP stack will try
72862306a36Sopenharmony_cito re-arrange data in these skb. E.g. if a SACK block acknowledges seq
72962306a36Sopenharmony_ci10 to 15, skb1 has seq 10 to 13, skb2 has seq 14 to 20. The seq 14 and
73062306a36Sopenharmony_ci15 in skb2 would be moved to skb1. This operation is 'shift'. If a
73162306a36Sopenharmony_ciSACK block acknowledges seq 10 to 20, skb1 has seq 10 to 13, skb2 has
73262306a36Sopenharmony_ciseq 14 to 20. All data in skb2 will be moved to skb1, and skb2 will be
73362306a36Sopenharmony_cidiscard, this operation is 'merge'.
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci* TcpExtTCPSackShifted
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ciA skb is shifted
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci* TcpExtTCPSackMerged
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ciA skb is merged
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci* TcpExtTCPSackShiftFallback
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ciA skb should be shifted or merged, but the TCP stack doesn't do it for
74662306a36Sopenharmony_cisome reasons.
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ciTCP out of order
74962306a36Sopenharmony_ci================
75062306a36Sopenharmony_ci* TcpExtTCPOFOQueue
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ciThe TCP layer receives an out of order packet and has enough memory
75362306a36Sopenharmony_cito queue it.
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci* TcpExtTCPOFODrop
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ciThe TCP layer receives an out of order packet but doesn't have enough
75862306a36Sopenharmony_cimemory, so drops it. Such packets won't be counted into
75962306a36Sopenharmony_ciTcpExtTCPOFOQueue.
76062306a36Sopenharmony_ci
76162306a36Sopenharmony_ci* TcpExtTCPOFOMerge
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ciThe received out of order packet has an overlay with the previous
76462306a36Sopenharmony_cipacket. the overlay part will be dropped. All of TcpExtTCPOFOMerge
76562306a36Sopenharmony_cipackets will also be counted into TcpExtTCPOFOQueue.
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ciTCP PAWS
76862306a36Sopenharmony_ci========
76962306a36Sopenharmony_ciPAWS (Protection Against Wrapped Sequence numbers) is an algorithm
77062306a36Sopenharmony_ciwhich is used to drop old packets. It depends on the TCP
77162306a36Sopenharmony_citimestamps. For detail information, please refer the `timestamp wiki`_
77262306a36Sopenharmony_ciand the `RFC of PAWS`_.
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci.. _RFC of PAWS: https://tools.ietf.org/html/rfc1323#page-17
77562306a36Sopenharmony_ci.. _timestamp wiki: https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_timestamps
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci* TcpExtPAWSActive
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ciPackets are dropped by PAWS in Syn-Sent status.
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci* TcpExtPAWSEstab
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ciPackets are dropped by PAWS in any status other than Syn-Sent.
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ciTCP ACK skip
78662306a36Sopenharmony_ci============
78762306a36Sopenharmony_ciIn some scenarios, kernel would avoid sending duplicate ACKs too
78862306a36Sopenharmony_cifrequently. Please find more details in the tcp_invalid_ratelimit
78962306a36Sopenharmony_cisection of the `sysctl document`_. When kernel decides to skip an ACK
79062306a36Sopenharmony_cidue to tcp_invalid_ratelimit, kernel would update one of below
79162306a36Sopenharmony_cicounters to indicate the ACK is skipped in which scenario. The ACK
79262306a36Sopenharmony_ciwould only be skipped if the received packet is either a SYN packet or
79362306a36Sopenharmony_ciit has no data.
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci.. _sysctl document: https://www.kernel.org/doc/Documentation/networking/ip-sysctl.rst
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci* TcpExtTCPACKSkippedSynRecv
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ciThe ACK is skipped in Syn-Recv status. The Syn-Recv status means the
80062306a36Sopenharmony_ciTCP stack receives a SYN and replies SYN+ACK. Now the TCP stack is
80162306a36Sopenharmony_ciwaiting for an ACK. Generally, the TCP stack doesn't need to send ACK
80262306a36Sopenharmony_ciin the Syn-Recv status. But in several scenarios, the TCP stack need
80362306a36Sopenharmony_cito send an ACK. E.g., the TCP stack receives the same SYN packet
80462306a36Sopenharmony_cirepeately, the received packet does not pass the PAWS check, or the
80562306a36Sopenharmony_cireceived packet sequence number is out of window. In these scenarios,
80662306a36Sopenharmony_cithe TCP stack needs to send ACK. If the ACk sending frequency is higher than
80762306a36Sopenharmony_citcp_invalid_ratelimit allows, the TCP stack will skip sending ACK and
80862306a36Sopenharmony_ciincrease TcpExtTCPACKSkippedSynRecv.
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci* TcpExtTCPACKSkippedPAWS
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ciThe ACK is skipped due to PAWS (Protect Against Wrapped Sequence
81462306a36Sopenharmony_cinumbers) check fails. If the PAWS check fails in Syn-Recv, Fin-Wait-2
81562306a36Sopenharmony_cior Time-Wait statuses, the skipped ACK would be counted to
81662306a36Sopenharmony_ciTcpExtTCPACKSkippedSynRecv, TcpExtTCPACKSkippedFinWait2 or
81762306a36Sopenharmony_ciTcpExtTCPACKSkippedTimeWait. In all other statuses, the skipped ACK
81862306a36Sopenharmony_ciwould be counted to TcpExtTCPACKSkippedPAWS.
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci* TcpExtTCPACKSkippedSeq
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ciThe sequence number is out of window and the timestamp passes the PAWS
82362306a36Sopenharmony_cicheck and the TCP status is not Syn-Recv, Fin-Wait-2, and Time-Wait.
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci* TcpExtTCPACKSkippedFinWait2
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ciThe ACK is skipped in Fin-Wait-2 status, the reason would be either
82862306a36Sopenharmony_ciPAWS check fails or the received sequence number is out of window.
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci* TcpExtTCPACKSkippedTimeWait
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ciThe ACK is skipped in Time-Wait status, the reason would be either
83362306a36Sopenharmony_ciPAWS check failed or the received sequence number is out of window.
83462306a36Sopenharmony_ci
83562306a36Sopenharmony_ci* TcpExtTCPACKSkippedChallenge
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ciThe ACK is skipped if the ACK is a challenge ACK. The RFC 5961 defines
83862306a36Sopenharmony_ci3 kind of challenge ACK, please refer `RFC 5961 section 3.2`_,
83962306a36Sopenharmony_ci`RFC 5961 section 4.2`_ and `RFC 5961 section 5.2`_. Besides these
84062306a36Sopenharmony_cithree scenarios, In some TCP status, the linux TCP stack would also
84162306a36Sopenharmony_cisend challenge ACKs if the ACK number is before the first
84262306a36Sopenharmony_ciunacknowledged number (more strict than `RFC 5961 section 5.2`_).
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci.. _RFC 5961 section 3.2: https://tools.ietf.org/html/rfc5961#page-7
84562306a36Sopenharmony_ci.. _RFC 5961 section 4.2: https://tools.ietf.org/html/rfc5961#page-9
84662306a36Sopenharmony_ci.. _RFC 5961 section 5.2: https://tools.ietf.org/html/rfc5961#page-11
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ciTCP receive window
84962306a36Sopenharmony_ci==================
85062306a36Sopenharmony_ci* TcpExtTCPWantZeroWindowAdv
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ciDepending on current memory usage, the TCP stack tries to set receive
85362306a36Sopenharmony_ciwindow to zero. But the receive window might still be a no-zero
85462306a36Sopenharmony_civalue. For example, if the previous window size is 10, and the TCP
85562306a36Sopenharmony_cistack receives 3 bytes, the current window size would be 7 even if the
85662306a36Sopenharmony_ciwindow size calculated by the memory usage is zero.
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci* TcpExtTCPToZeroWindowAdv
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ciThe TCP receive window is set to zero from a no-zero value.
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci* TcpExtTCPFromZeroWindowAdv
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ciThe TCP receive window is set to no-zero value from zero.
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ciDelayed ACK
86862306a36Sopenharmony_ci===========
86962306a36Sopenharmony_ciThe TCP Delayed ACK is a technique which is used for reducing the
87062306a36Sopenharmony_cipacket count in the network. For more details, please refer the
87162306a36Sopenharmony_ci`Delayed ACK wiki`_
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci.. _Delayed ACK wiki: https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci* TcpExtDelayedACKs
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ciA delayed ACK timer expires. The TCP stack will send a pure ACK packet
87862306a36Sopenharmony_ciand exit the delayed ACK mode.
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci* TcpExtDelayedACKLocked
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ciA delayed ACK timer expires, but the TCP stack can't send an ACK
88362306a36Sopenharmony_ciimmediately due to the socket is locked by a userspace program. The
88462306a36Sopenharmony_ciTCP stack will send a pure ACK later (after the userspace program
88562306a36Sopenharmony_ciunlock the socket). When the TCP stack sends the pure ACK later, the
88662306a36Sopenharmony_ciTCP stack will also update TcpExtDelayedACKs and exit the delayed ACK
88762306a36Sopenharmony_cimode.
88862306a36Sopenharmony_ci
88962306a36Sopenharmony_ci* TcpExtDelayedACKLost
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ciIt will be updated when the TCP stack receives a packet which has been
89262306a36Sopenharmony_ciACKed. A Delayed ACK loss might cause this issue, but it would also be
89362306a36Sopenharmony_citriggered by other reasons, such as a packet is duplicated in the
89462306a36Sopenharmony_cinetwork.
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ciTail Loss Probe (TLP)
89762306a36Sopenharmony_ci=====================
89862306a36Sopenharmony_ciTLP is an algorithm which is used to detect TCP packet loss. For more
89962306a36Sopenharmony_cidetails, please refer the `TLP paper`_.
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci.. _TLP paper: https://tools.ietf.org/html/draft-dukkipati-tcpm-tcp-loss-probe-01
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci* TcpExtTCPLossProbes
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ciA TLP probe packet is sent.
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci* TcpExtTCPLossProbeRecovery
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_ciA packet loss is detected and recovered by TLP.
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ciTCP Fast Open description
91262306a36Sopenharmony_ci=========================
91362306a36Sopenharmony_ciTCP Fast Open is a technology which allows data transfer before the
91462306a36Sopenharmony_ci3-way handshake complete. Please refer the `TCP Fast Open wiki`_ for a
91562306a36Sopenharmony_cigeneral description.
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci.. _TCP Fast Open wiki: https://en.wikipedia.org/wiki/TCP_Fast_Open
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci* TcpExtTCPFastOpenActive
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ciWhen the TCP stack receives an ACK packet in the SYN-SENT status, and
92262306a36Sopenharmony_cithe ACK packet acknowledges the data in the SYN packet, the TCP stack
92362306a36Sopenharmony_ciunderstand the TFO cookie is accepted by the other side, then it
92462306a36Sopenharmony_ciupdates this counter.
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci* TcpExtTCPFastOpenActiveFail
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ciThis counter indicates that the TCP stack initiated a TCP Fast Open,
92962306a36Sopenharmony_cibut it failed. This counter would be updated in three scenarios: (1)
93062306a36Sopenharmony_cithe other side doesn't acknowledge the data in the SYN packet. (2) The
93162306a36Sopenharmony_ciSYN packet which has the TFO cookie is timeout at least once. (3)
93262306a36Sopenharmony_ciafter the 3-way handshake, the retransmission timeout happens
93362306a36Sopenharmony_cinet.ipv4.tcp_retries1 times, because some middle-boxes may black-hole
93462306a36Sopenharmony_cifast open after the handshake.
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci* TcpExtTCPFastOpenPassive
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ciThis counter indicates how many times the TCP stack accepts the fast
93962306a36Sopenharmony_ciopen request.
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci* TcpExtTCPFastOpenPassiveFail
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ciThis counter indicates how many times the TCP stack rejects the fast
94462306a36Sopenharmony_ciopen request. It is caused by either the TFO cookie is invalid or the
94562306a36Sopenharmony_ciTCP stack finds an error during the socket creating process.
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci* TcpExtTCPFastOpenListenOverflow
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ciWhen the pending fast open request number is larger than
95062306a36Sopenharmony_cifastopenq->max_qlen, the TCP stack will reject the fast open request
95162306a36Sopenharmony_ciand update this counter. When this counter is updated, the TCP stack
95262306a36Sopenharmony_ciwon't update TcpExtTCPFastOpenPassive or
95362306a36Sopenharmony_ciTcpExtTCPFastOpenPassiveFail. The fastopenq->max_qlen is set by the
95462306a36Sopenharmony_ciTCP_FASTOPEN socket operation and it could not be larger than
95562306a36Sopenharmony_cinet.core.somaxconn. For example:
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_cisetsockopt(sfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci* TcpExtTCPFastOpenCookieReqd
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ciThis counter indicates how many times a client wants to request a TFO
96262306a36Sopenharmony_cicookie.
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ciSYN cookies
96562306a36Sopenharmony_ci===========
96662306a36Sopenharmony_ciSYN cookies are used to mitigate SYN flood, for details, please refer
96762306a36Sopenharmony_cithe `SYN cookies wiki`_.
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci.. _SYN cookies wiki: https://en.wikipedia.org/wiki/SYN_cookies
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci* TcpExtSyncookiesSent
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ciIt indicates how many SYN cookies are sent.
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci* TcpExtSyncookiesRecv
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ciHow many reply packets of the SYN cookies the TCP stack receives.
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci* TcpExtSyncookiesFailed
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ciThe MSS decoded from the SYN cookie is invalid. When this counter is
98262306a36Sopenharmony_ciupdated, the received packet won't be treated as a SYN cookie and the
98362306a36Sopenharmony_ciTcpExtSyncookiesRecv counter won't be updated.
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ciChallenge ACK
98662306a36Sopenharmony_ci=============
98762306a36Sopenharmony_ciFor details of challenge ACK, please refer the explanation of
98862306a36Sopenharmony_ciTcpExtTCPACKSkippedChallenge.
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci* TcpExtTCPChallengeACK
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ciThe number of challenge acks sent.
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci* TcpExtTCPSYNChallenge
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ciThe number of challenge acks sent in response to SYN packets. After
99762306a36Sopenharmony_ciupdates this counter, the TCP stack might send a challenge ACK and
99862306a36Sopenharmony_ciupdate the TcpExtTCPChallengeACK counter, or it might also skip to
99962306a36Sopenharmony_cisend the challenge and update the TcpExtTCPACKSkippedChallenge.
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ciprune
100262306a36Sopenharmony_ci=====
100362306a36Sopenharmony_ciWhen a socket is under memory pressure, the TCP stack will try to
100462306a36Sopenharmony_cireclaim memory from the receiving queue and out of order queue. One of
100562306a36Sopenharmony_cithe reclaiming method is 'collapse', which means allocate a big skb,
100662306a36Sopenharmony_cicopy the contiguous skbs to the single big skb, and free these
100762306a36Sopenharmony_cicontiguous skbs.
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci* TcpExtPruneCalled
101062306a36Sopenharmony_ci
101162306a36Sopenharmony_ciThe TCP stack tries to reclaim memory for a socket. After updates this
101262306a36Sopenharmony_cicounter, the TCP stack will try to collapse the out of order queue and
101362306a36Sopenharmony_cithe receiving queue. If the memory is still not enough, the TCP stack
101462306a36Sopenharmony_ciwill try to discard packets from the out of order queue (and update the
101562306a36Sopenharmony_ciTcpExtOfoPruned counter)
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci* TcpExtOfoPruned
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ciThe TCP stack tries to discard packet on the out of order queue.
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci* TcpExtRcvPruned
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ciAfter 'collapse' and discard packets from the out of order queue, if
102462306a36Sopenharmony_cithe actually used memory is still larger than the max allowed memory,
102562306a36Sopenharmony_cithis counter will be updated. It means the 'prune' fails.
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci* TcpExtTCPRcvCollapsed
102862306a36Sopenharmony_ci
102962306a36Sopenharmony_ciThis counter indicates how many skbs are freed during 'collapse'.
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ciexamples
103262306a36Sopenharmony_ci========
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ciping test
103562306a36Sopenharmony_ci---------
103662306a36Sopenharmony_ciRun the ping command against the public dns server 8.8.8.8::
103762306a36Sopenharmony_ci
103862306a36Sopenharmony_ci  nstatuser@nstat-a:~$ ping 8.8.8.8 -c 1
103962306a36Sopenharmony_ci  PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
104062306a36Sopenharmony_ci  64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=17.8 ms
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci  --- 8.8.8.8 ping statistics ---
104362306a36Sopenharmony_ci  1 packets transmitted, 1 received, 0% packet loss, time 0ms
104462306a36Sopenharmony_ci  rtt min/avg/max/mdev = 17.875/17.875/17.875/0.000 ms
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ciThe nstayt result::
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat
104962306a36Sopenharmony_ci  #kernel
105062306a36Sopenharmony_ci  IpInReceives                    1                  0.0
105162306a36Sopenharmony_ci  IpInDelivers                    1                  0.0
105262306a36Sopenharmony_ci  IpOutRequests                   1                  0.0
105362306a36Sopenharmony_ci  IcmpInMsgs                      1                  0.0
105462306a36Sopenharmony_ci  IcmpInEchoReps                  1                  0.0
105562306a36Sopenharmony_ci  IcmpOutMsgs                     1                  0.0
105662306a36Sopenharmony_ci  IcmpOutEchos                    1                  0.0
105762306a36Sopenharmony_ci  IcmpMsgInType0                  1                  0.0
105862306a36Sopenharmony_ci  IcmpMsgOutType8                 1                  0.0
105962306a36Sopenharmony_ci  IpExtInOctets                   84                 0.0
106062306a36Sopenharmony_ci  IpExtOutOctets                  84                 0.0
106162306a36Sopenharmony_ci  IpExtInNoECTPkts                1                  0.0
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ciThe Linux server sent an ICMP Echo packet, so IpOutRequests,
106462306a36Sopenharmony_ciIcmpOutMsgs, IcmpOutEchos and IcmpMsgOutType8 were increased 1. The
106562306a36Sopenharmony_ciserver got ICMP Echo Reply from 8.8.8.8, so IpInReceives, IcmpInMsgs,
106662306a36Sopenharmony_ciIcmpInEchoReps and IcmpMsgInType0 were increased 1. The ICMP Echo Reply
106762306a36Sopenharmony_ciwas passed to the ICMP layer via IP layer, so IpInDelivers was
106862306a36Sopenharmony_ciincreased 1. The default ping data size is 48, so an ICMP Echo packet
106962306a36Sopenharmony_ciand its corresponding Echo Reply packet are constructed by:
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci* 14 bytes MAC header
107262306a36Sopenharmony_ci* 20 bytes IP header
107362306a36Sopenharmony_ci* 16 bytes ICMP header
107462306a36Sopenharmony_ci* 48 bytes data (default value of the ping command)
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_ciSo the IpExtInOctets and IpExtOutOctets are 20+16+48=84.
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_citcp 3-way handshake
107962306a36Sopenharmony_ci-------------------
108062306a36Sopenharmony_ciOn server side, we run::
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lknv 0.0.0.0 9000
108362306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9000)
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ciOn client side, we run::
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -nv 192.168.122.251 9000
108862306a36Sopenharmony_ci  Connection to 192.168.122.251 9000 port [tcp/*] succeeded!
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ciThe server listened on tcp 9000 port, the client connected to it, they
109162306a36Sopenharmony_cicompleted the 3-way handshake.
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_ciOn server side, we can find below nstat output::
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat | grep -i tcp
109662306a36Sopenharmony_ci  TcpPassiveOpens                 1                  0.0
109762306a36Sopenharmony_ci  TcpInSegs                       2                  0.0
109862306a36Sopenharmony_ci  TcpOutSegs                      1                  0.0
109962306a36Sopenharmony_ci  TcpExtTCPPureAcks               1                  0.0
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ciOn client side, we can find below nstat output::
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat | grep -i tcp
110462306a36Sopenharmony_ci  TcpActiveOpens                  1                  0.0
110562306a36Sopenharmony_ci  TcpInSegs                       1                  0.0
110662306a36Sopenharmony_ci  TcpOutSegs                      2                  0.0
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ciWhen the server received the first SYN, it replied a SYN+ACK, and came into
110962306a36Sopenharmony_ciSYN-RCVD state, so TcpPassiveOpens increased 1. The server received
111062306a36Sopenharmony_ciSYN, sent SYN+ACK, received ACK, so server sent 1 packet, received 2
111162306a36Sopenharmony_cipackets, TcpInSegs increased 2, TcpOutSegs increased 1. The last ACK
111262306a36Sopenharmony_ciof the 3-way handshake is a pure ACK without data, so
111362306a36Sopenharmony_ciTcpExtTCPPureAcks increased 1.
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_ciWhen the client sent SYN, the client came into the SYN-SENT state, so
111662306a36Sopenharmony_ciTcpActiveOpens increased 1, the client sent SYN, received SYN+ACK, sent
111762306a36Sopenharmony_ciACK, so client sent 2 packets, received 1 packet, TcpInSegs increased
111862306a36Sopenharmony_ci1, TcpOutSegs increased 2.
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ciTCP normal traffic
112162306a36Sopenharmony_ci------------------
112262306a36Sopenharmony_ciRun nc on server::
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 0.0.0.0 9000
112562306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9000)
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ciRun nc on client::
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
113062306a36Sopenharmony_ci  Connection to nstat-b 9000 port [tcp/*] succeeded!
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ciInput a string in the nc client ('hello' in our example)::
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
113562306a36Sopenharmony_ci  Connection to nstat-b 9000 port [tcp/*] succeeded!
113662306a36Sopenharmony_ci  hello
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ciThe client side nstat output::
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat
114162306a36Sopenharmony_ci  #kernel
114262306a36Sopenharmony_ci  IpInReceives                    1                  0.0
114362306a36Sopenharmony_ci  IpInDelivers                    1                  0.0
114462306a36Sopenharmony_ci  IpOutRequests                   1                  0.0
114562306a36Sopenharmony_ci  TcpInSegs                       1                  0.0
114662306a36Sopenharmony_ci  TcpOutSegs                      1                  0.0
114762306a36Sopenharmony_ci  TcpExtTCPPureAcks               1                  0.0
114862306a36Sopenharmony_ci  TcpExtTCPOrigDataSent           1                  0.0
114962306a36Sopenharmony_ci  IpExtInOctets                   52                 0.0
115062306a36Sopenharmony_ci  IpExtOutOctets                  58                 0.0
115162306a36Sopenharmony_ci  IpExtInNoECTPkts                1                  0.0
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ciThe server side nstat output::
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat
115662306a36Sopenharmony_ci  #kernel
115762306a36Sopenharmony_ci  IpInReceives                    1                  0.0
115862306a36Sopenharmony_ci  IpInDelivers                    1                  0.0
115962306a36Sopenharmony_ci  IpOutRequests                   1                  0.0
116062306a36Sopenharmony_ci  TcpInSegs                       1                  0.0
116162306a36Sopenharmony_ci  TcpOutSegs                      1                  0.0
116262306a36Sopenharmony_ci  IpExtInOctets                   58                 0.0
116362306a36Sopenharmony_ci  IpExtOutOctets                  52                 0.0
116462306a36Sopenharmony_ci  IpExtInNoECTPkts                1                  0.0
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ciInput a string in nc client side again ('world' in our example)::
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
116962306a36Sopenharmony_ci  Connection to nstat-b 9000 port [tcp/*] succeeded!
117062306a36Sopenharmony_ci  hello
117162306a36Sopenharmony_ci  world
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ciClient side nstat output::
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat
117662306a36Sopenharmony_ci  #kernel
117762306a36Sopenharmony_ci  IpInReceives                    1                  0.0
117862306a36Sopenharmony_ci  IpInDelivers                    1                  0.0
117962306a36Sopenharmony_ci  IpOutRequests                   1                  0.0
118062306a36Sopenharmony_ci  TcpInSegs                       1                  0.0
118162306a36Sopenharmony_ci  TcpOutSegs                      1                  0.0
118262306a36Sopenharmony_ci  TcpExtTCPHPAcks                 1                  0.0
118362306a36Sopenharmony_ci  TcpExtTCPOrigDataSent           1                  0.0
118462306a36Sopenharmony_ci  IpExtInOctets                   52                 0.0
118562306a36Sopenharmony_ci  IpExtOutOctets                  58                 0.0
118662306a36Sopenharmony_ci  IpExtInNoECTPkts                1                  0.0
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ciServer side nstat output::
119062306a36Sopenharmony_ci
119162306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat
119262306a36Sopenharmony_ci  #kernel
119362306a36Sopenharmony_ci  IpInReceives                    1                  0.0
119462306a36Sopenharmony_ci  IpInDelivers                    1                  0.0
119562306a36Sopenharmony_ci  IpOutRequests                   1                  0.0
119662306a36Sopenharmony_ci  TcpInSegs                       1                  0.0
119762306a36Sopenharmony_ci  TcpOutSegs                      1                  0.0
119862306a36Sopenharmony_ci  TcpExtTCPHPHits                 1                  0.0
119962306a36Sopenharmony_ci  IpExtInOctets                   58                 0.0
120062306a36Sopenharmony_ci  IpExtOutOctets                  52                 0.0
120162306a36Sopenharmony_ci  IpExtInNoECTPkts                1                  0.0
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ciCompare the first client-side nstat and the second client-side nstat,
120462306a36Sopenharmony_ciwe could find one difference: the first one had a 'TcpExtTCPPureAcks',
120562306a36Sopenharmony_cibut the second one had a 'TcpExtTCPHPAcks'. The first server-side
120662306a36Sopenharmony_cinstat and the second server-side nstat had a difference too: the
120762306a36Sopenharmony_cisecond server-side nstat had a TcpExtTCPHPHits, but the first
120862306a36Sopenharmony_ciserver-side nstat didn't have it. The network traffic patterns were
120962306a36Sopenharmony_ciexactly the same: the client sent a packet to the server, the server
121062306a36Sopenharmony_cireplied an ACK. But kernel handled them in different ways. When the
121162306a36Sopenharmony_ciTCP window scale option is not used, kernel will try to enable fast
121262306a36Sopenharmony_cipath immediately when the connection comes into the established state,
121362306a36Sopenharmony_cibut if the TCP window scale option is used, kernel will disable the
121462306a36Sopenharmony_cifast path at first, and try to enable it after kernel receives
121562306a36Sopenharmony_cipackets. We could use the 'ss' command to verify whether the window
121662306a36Sopenharmony_ciscale option is used. e.g. run below command on either server or
121762306a36Sopenharmony_ciclient::
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci  nstatuser@nstat-a:~$ ss -o state established -i '( dport = :9000 or sport = :9000 )
122062306a36Sopenharmony_ci  Netid    Recv-Q     Send-Q            Local Address:Port             Peer Address:Port
122162306a36Sopenharmony_ci  tcp      0          0               192.168.122.250:40654         192.168.122.251:9000
122262306a36Sopenharmony_ci             ts sack cubic wscale:7,7 rto:204 rtt:0.98/0.49 mss:1448 pmtu:1500 rcvmss:536 advmss:1448 cwnd:10 bytes_acked:1 segs_out:2 segs_in:1 send 118.2Mbps lastsnd:46572 lastrcv:46572 lastack:46572 pacing_rate 236.4Mbps rcv_space:29200 rcv_ssthresh:29200 minrtt:0.98
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ciThe 'wscale:7,7' means both server and client set the window scale
122562306a36Sopenharmony_cioption to 7. Now we could explain the nstat output in our test:
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ciIn the first nstat output of client side, the client sent a packet, server
122862306a36Sopenharmony_cireply an ACK, when kernel handled this ACK, the fast path was not
122962306a36Sopenharmony_cienabled, so the ACK was counted into 'TcpExtTCPPureAcks'.
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ciIn the second nstat output of client side, the client sent a packet again,
123262306a36Sopenharmony_ciand received another ACK from the server, in this time, the fast path is
123362306a36Sopenharmony_cienabled, and the ACK was qualified for fast path, so it was handled by
123462306a36Sopenharmony_cithe fast path, so this ACK was counted into TcpExtTCPHPAcks.
123562306a36Sopenharmony_ci
123662306a36Sopenharmony_ciIn the first nstat output of server side, fast path was not enabled,
123762306a36Sopenharmony_ciso there was no 'TcpExtTCPHPHits'.
123862306a36Sopenharmony_ci
123962306a36Sopenharmony_ciIn the second nstat output of server side, the fast path was enabled,
124062306a36Sopenharmony_ciand the packet received from client qualified for fast path, so it
124162306a36Sopenharmony_ciwas counted into 'TcpExtTCPHPHits'.
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ciTcpExtTCPAbortOnClose
124462306a36Sopenharmony_ci---------------------
124562306a36Sopenharmony_ciOn the server side, we run below python script::
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci  import socket
124862306a36Sopenharmony_ci  import time
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci  port = 9000
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
125362306a36Sopenharmony_ci  s.bind(('0.0.0.0', port))
125462306a36Sopenharmony_ci  s.listen(1)
125562306a36Sopenharmony_ci  sock, addr = s.accept()
125662306a36Sopenharmony_ci  while True:
125762306a36Sopenharmony_ci      time.sleep(9999999)
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ciThis python script listen on 9000 port, but doesn't read anything from
126062306a36Sopenharmony_cithe connection.
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ciOn the client side, we send the string "hello" by nc::
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci  nstatuser@nstat-a:~$ echo "hello" | nc nstat-b 9000
126562306a36Sopenharmony_ci
126662306a36Sopenharmony_ciThen, we come back to the server side, the server has received the "hello"
126762306a36Sopenharmony_cipacket, and the TCP layer has acked this packet, but the application didn't
126862306a36Sopenharmony_ciread it yet. We type Ctrl-C to terminate the server script. Then we
126962306a36Sopenharmony_cicould find TcpExtTCPAbortOnClose increased 1 on the server side::
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat | grep -i abort
127262306a36Sopenharmony_ci  TcpExtTCPAbortOnClose           1                  0.0
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ciIf we run tcpdump on the server side, we could find the server sent a
127562306a36Sopenharmony_ciRST after we type Ctrl-C.
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ciTcpExtTCPAbortOnMemory and TcpExtTCPAbortOnTimeout
127862306a36Sopenharmony_ci---------------------------------------------------
127962306a36Sopenharmony_ciBelow is an example which let the orphan socket count be higher than
128062306a36Sopenharmony_cinet.ipv4.tcp_max_orphans.
128162306a36Sopenharmony_ciChange tcp_max_orphans to a smaller value on client::
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci  sudo bash -c "echo 10 > /proc/sys/net/ipv4/tcp_max_orphans"
128462306a36Sopenharmony_ci
128562306a36Sopenharmony_ciClient code (create 64 connection to server)::
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci  nstatuser@nstat-a:~$ cat client_orphan.py
128862306a36Sopenharmony_ci  import socket
128962306a36Sopenharmony_ci  import time
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci  server = 'nstat-b' # server address
129262306a36Sopenharmony_ci  port = 9000
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci  count = 64
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci  connection_list = []
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci  for i in range(64):
129962306a36Sopenharmony_ci      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
130062306a36Sopenharmony_ci      s.connect((server, port))
130162306a36Sopenharmony_ci      connection_list.append(s)
130262306a36Sopenharmony_ci      print("connection_count: %d" % len(connection_list))
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci  while True:
130562306a36Sopenharmony_ci      time.sleep(99999)
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ciServer code (accept 64 connection from client)::
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci  nstatuser@nstat-b:~$ cat server_orphan.py
131062306a36Sopenharmony_ci  import socket
131162306a36Sopenharmony_ci  import time
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci  port = 9000
131462306a36Sopenharmony_ci  count = 64
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
131762306a36Sopenharmony_ci  s.bind(('0.0.0.0', port))
131862306a36Sopenharmony_ci  s.listen(count)
131962306a36Sopenharmony_ci  connection_list = []
132062306a36Sopenharmony_ci  while True:
132162306a36Sopenharmony_ci      sock, addr = s.accept()
132262306a36Sopenharmony_ci      connection_list.append((sock, addr))
132362306a36Sopenharmony_ci      print("connection_count: %d" % len(connection_list))
132462306a36Sopenharmony_ci
132562306a36Sopenharmony_ciRun the python scripts on server and client.
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ciOn server::
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci  python3 server_orphan.py
133062306a36Sopenharmony_ci
133162306a36Sopenharmony_ciOn client::
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci  python3 client_orphan.py
133462306a36Sopenharmony_ci
133562306a36Sopenharmony_ciRun iptables on server::
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_ci  sudo iptables -A INPUT -i ens3 -p tcp --destination-port 9000 -j DROP
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ciType Ctrl-C on client, stop client_orphan.py.
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ciCheck TcpExtTCPAbortOnMemory on client::
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat | grep -i abort
134462306a36Sopenharmony_ci  TcpExtTCPAbortOnMemory          54                 0.0
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ciCheck orphaned socket count on client::
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci  nstatuser@nstat-a:~$ ss -s
134962306a36Sopenharmony_ci  Total: 131 (kernel 0)
135062306a36Sopenharmony_ci  TCP:   14 (estab 1, closed 0, orphaned 10, synrecv 0, timewait 0/0), ports 0
135162306a36Sopenharmony_ci
135262306a36Sopenharmony_ci  Transport Total     IP        IPv6
135362306a36Sopenharmony_ci  *         0         -         -
135462306a36Sopenharmony_ci  RAW       1         0         1
135562306a36Sopenharmony_ci  UDP       1         1         0
135662306a36Sopenharmony_ci  TCP       14        13        1
135762306a36Sopenharmony_ci  INET      16        14        2
135862306a36Sopenharmony_ci  FRAG      0         0         0
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ciThe explanation of the test: after run server_orphan.py and
136162306a36Sopenharmony_ciclient_orphan.py, we set up 64 connections between server and
136262306a36Sopenharmony_ciclient. Run the iptables command, the server will drop all packets from
136362306a36Sopenharmony_cithe client, type Ctrl-C on client_orphan.py, the system of the client
136462306a36Sopenharmony_ciwould try to close these connections, and before they are closed
136562306a36Sopenharmony_cigracefully, these connections became orphan sockets. As the iptables
136662306a36Sopenharmony_ciof the server blocked packets from the client, the server won't receive fin
136762306a36Sopenharmony_cifrom the client, so all connection on clients would be stuck on FIN_WAIT_1
136862306a36Sopenharmony_cistage, so they will keep as orphan sockets until timeout. We have echo
136962306a36Sopenharmony_ci10 to /proc/sys/net/ipv4/tcp_max_orphans, so the client system would
137062306a36Sopenharmony_cionly keep 10 orphan sockets, for all other orphan sockets, the client
137162306a36Sopenharmony_cisystem sent RST for them and delete them. We have 64 connections, so
137262306a36Sopenharmony_cithe 'ss -s' command shows the system has 10 orphan sockets, and the
137362306a36Sopenharmony_civalue of TcpExtTCPAbortOnMemory was 54.
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ciAn additional explanation about orphan socket count: You could find the
137662306a36Sopenharmony_ciexactly orphan socket count by the 'ss -s' command, but when kernel
137762306a36Sopenharmony_cidecide whither increases TcpExtTCPAbortOnMemory and sends RST, kernel
137862306a36Sopenharmony_cidoesn't always check the exactly orphan socket count. For increasing
137962306a36Sopenharmony_ciperformance, kernel checks an approximate count firstly, if the
138062306a36Sopenharmony_ciapproximate count is more than tcp_max_orphans, kernel checks the
138162306a36Sopenharmony_ciexact count again. So if the approximate count is less than
138262306a36Sopenharmony_citcp_max_orphans, but exactly count is more than tcp_max_orphans, you
138362306a36Sopenharmony_ciwould find TcpExtTCPAbortOnMemory is not increased at all. If
138462306a36Sopenharmony_citcp_max_orphans is large enough, it won't occur, but if you decrease
138562306a36Sopenharmony_citcp_max_orphans to a small value like our test, you might find this
138662306a36Sopenharmony_ciissue. So in our test, the client set up 64 connections although the
138762306a36Sopenharmony_citcp_max_orphans is 10. If the client only set up 11 connections, we
138862306a36Sopenharmony_cican't find the change of TcpExtTCPAbortOnMemory.
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ciContinue the previous test, we wait for several minutes. Because of the
139162306a36Sopenharmony_ciiptables on the server blocked the traffic, the server wouldn't receive
139262306a36Sopenharmony_cifin, and all the client's orphan sockets would timeout on the
139362306a36Sopenharmony_ciFIN_WAIT_1 state finally. So we wait for a few minutes, we could find
139462306a36Sopenharmony_ci10 timeout on the client::
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat | grep -i abort
139762306a36Sopenharmony_ci  TcpExtTCPAbortOnTimeout         10                 0.0
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ciTcpExtTCPAbortOnLinger
140062306a36Sopenharmony_ci----------------------
140162306a36Sopenharmony_ciThe server side code::
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci  nstatuser@nstat-b:~$ cat server_linger.py
140462306a36Sopenharmony_ci  import socket
140562306a36Sopenharmony_ci  import time
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci  port = 9000
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_ci  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
141062306a36Sopenharmony_ci  s.bind(('0.0.0.0', port))
141162306a36Sopenharmony_ci  s.listen(1)
141262306a36Sopenharmony_ci  sock, addr = s.accept()
141362306a36Sopenharmony_ci  while True:
141462306a36Sopenharmony_ci      time.sleep(9999999)
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ciThe client side code::
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_ci  nstatuser@nstat-a:~$ cat client_linger.py
141962306a36Sopenharmony_ci  import socket
142062306a36Sopenharmony_ci  import struct
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci  server = 'nstat-b' # server address
142362306a36Sopenharmony_ci  port = 9000
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
142662306a36Sopenharmony_ci  s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 10))
142762306a36Sopenharmony_ci  s.setsockopt(socket.SOL_TCP, socket.TCP_LINGER2, struct.pack('i', -1))
142862306a36Sopenharmony_ci  s.connect((server, port))
142962306a36Sopenharmony_ci  s.close()
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ciRun server_linger.py on server::
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_ci  nstatuser@nstat-b:~$ python3 server_linger.py
143462306a36Sopenharmony_ci
143562306a36Sopenharmony_ciRun client_linger.py on client::
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci  nstatuser@nstat-a:~$ python3 client_linger.py
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_ciAfter run client_linger.py, check the output of nstat::
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nstat | grep -i abort
144262306a36Sopenharmony_ci  TcpExtTCPAbortOnLinger          1                  0.0
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_ciTcpExtTCPRcvCoalesce
144562306a36Sopenharmony_ci--------------------
144662306a36Sopenharmony_ciOn the server, we run a program which listen on TCP port 9000, but
144762306a36Sopenharmony_cidoesn't read any data::
144862306a36Sopenharmony_ci
144962306a36Sopenharmony_ci  import socket
145062306a36Sopenharmony_ci  import time
145162306a36Sopenharmony_ci  port = 9000
145262306a36Sopenharmony_ci  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
145362306a36Sopenharmony_ci  s.bind(('0.0.0.0', port))
145462306a36Sopenharmony_ci  s.listen(1)
145562306a36Sopenharmony_ci  sock, addr = s.accept()
145662306a36Sopenharmony_ci  while True:
145762306a36Sopenharmony_ci      time.sleep(9999999)
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ciSave the above code as server_coalesce.py, and run::
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci  python3 server_coalesce.py
146262306a36Sopenharmony_ci
146362306a36Sopenharmony_ciOn the client, save below code as client_coalesce.py::
146462306a36Sopenharmony_ci
146562306a36Sopenharmony_ci  import socket
146662306a36Sopenharmony_ci  server = 'nstat-b'
146762306a36Sopenharmony_ci  port = 9000
146862306a36Sopenharmony_ci  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
146962306a36Sopenharmony_ci  s.connect((server, port))
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ciRun::
147262306a36Sopenharmony_ci
147362306a36Sopenharmony_ci  nstatuser@nstat-a:~$ python3 -i client_coalesce.py
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ciWe use '-i' to come into the interactive mode, then a packet::
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci  >>> s.send(b'foo')
147862306a36Sopenharmony_ci  3
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ciSend a packet again::
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci  >>> s.send(b'bar')
148362306a36Sopenharmony_ci  3
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ciOn the server, run nstat::
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci  ubuntu@nstat-b:~$ nstat
148862306a36Sopenharmony_ci  #kernel
148962306a36Sopenharmony_ci  IpInReceives                    2                  0.0
149062306a36Sopenharmony_ci  IpInDelivers                    2                  0.0
149162306a36Sopenharmony_ci  IpOutRequests                   2                  0.0
149262306a36Sopenharmony_ci  TcpInSegs                       2                  0.0
149362306a36Sopenharmony_ci  TcpOutSegs                      2                  0.0
149462306a36Sopenharmony_ci  TcpExtTCPRcvCoalesce            1                  0.0
149562306a36Sopenharmony_ci  IpExtInOctets                   110                0.0
149662306a36Sopenharmony_ci  IpExtOutOctets                  104                0.0
149762306a36Sopenharmony_ci  IpExtInNoECTPkts                2                  0.0
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ciThe client sent two packets, server didn't read any data. When
150062306a36Sopenharmony_cithe second packet arrived at server, the first packet was still in
150162306a36Sopenharmony_cithe receiving queue. So the TCP layer merged the two packets, and we
150262306a36Sopenharmony_cicould find the TcpExtTCPRcvCoalesce increased 1.
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ciTcpExtListenOverflows and TcpExtListenDrops
150562306a36Sopenharmony_ci-------------------------------------------
150662306a36Sopenharmony_ciOn server, run the nc command, listen on port 9000::
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 0.0.0.0 9000
150962306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9000)
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ciOn client, run 3 nc commands in different terminals::
151262306a36Sopenharmony_ci
151362306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
151462306a36Sopenharmony_ci  Connection to nstat-b 9000 port [tcp/*] succeeded!
151562306a36Sopenharmony_ci
151662306a36Sopenharmony_ciThe nc command only accepts 1 connection, and the accept queue length
151762306a36Sopenharmony_ciis 1. On current linux implementation, set queue length to n means the
151862306a36Sopenharmony_ciactual queue length is n+1. Now we create 3 connections, 1 is accepted
151962306a36Sopenharmony_ciby nc, 2 in accepted queue, so the accept queue is full.
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_ciBefore running the 4th nc, we clean the nstat history on the server::
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat -n
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ciRun the 4th nc on the client::
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_ciIf the nc server is running on kernel 4.10 or higher version, you
153062306a36Sopenharmony_ciwon't see the "Connection to ... succeeded!" string, because kernel
153162306a36Sopenharmony_ciwill drop the SYN if the accept queue is full. If the nc client is running
153262306a36Sopenharmony_cion an old kernel, you would see that the connection is succeeded,
153362306a36Sopenharmony_cibecause kernel would complete the 3 way handshake and keep the socket
153462306a36Sopenharmony_cion half open queue. I did the test on kernel 4.15. Below is the nstat
153562306a36Sopenharmony_cion the server::
153662306a36Sopenharmony_ci
153762306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat
153862306a36Sopenharmony_ci  #kernel
153962306a36Sopenharmony_ci  IpInReceives                    4                  0.0
154062306a36Sopenharmony_ci  IpInDelivers                    4                  0.0
154162306a36Sopenharmony_ci  TcpInSegs                       4                  0.0
154262306a36Sopenharmony_ci  TcpExtListenOverflows           4                  0.0
154362306a36Sopenharmony_ci  TcpExtListenDrops               4                  0.0
154462306a36Sopenharmony_ci  IpExtInOctets                   240                0.0
154562306a36Sopenharmony_ci  IpExtInNoECTPkts                4                  0.0
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_ciBoth TcpExtListenOverflows and TcpExtListenDrops were 4. If the time
154862306a36Sopenharmony_cibetween the 4th nc and the nstat was longer, the value of
154962306a36Sopenharmony_ciTcpExtListenOverflows and TcpExtListenDrops would be larger, because
155062306a36Sopenharmony_cithe SYN of the 4th nc was dropped, the client was retrying.
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ciIpInAddrErrors, IpExtInNoRoutes and IpOutNoRoutes
155362306a36Sopenharmony_ci-------------------------------------------------
155462306a36Sopenharmony_ciserver A IP address: 192.168.122.250
155562306a36Sopenharmony_ciserver B IP address: 192.168.122.251
155662306a36Sopenharmony_ciPrepare on server A, add a route to server B::
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ci  $ sudo ip route add 8.8.8.8/32 via 192.168.122.251
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ciPrepare on server B, disable send_redirects for all interfaces::
156162306a36Sopenharmony_ci
156262306a36Sopenharmony_ci  $ sudo sysctl -w net.ipv4.conf.all.send_redirects=0
156362306a36Sopenharmony_ci  $ sudo sysctl -w net.ipv4.conf.ens3.send_redirects=0
156462306a36Sopenharmony_ci  $ sudo sysctl -w net.ipv4.conf.lo.send_redirects=0
156562306a36Sopenharmony_ci  $ sudo sysctl -w net.ipv4.conf.default.send_redirects=0
156662306a36Sopenharmony_ci
156762306a36Sopenharmony_ciWe want to let sever A send a packet to 8.8.8.8, and route the packet
156862306a36Sopenharmony_cito server B. When server B receives such packet, it might send a ICMP
156962306a36Sopenharmony_ciRedirect message to server A, set send_redirects to 0 will disable
157062306a36Sopenharmony_cithis behavior.
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_ciFirst, generate InAddrErrors. On server B, we disable IP forwarding::
157362306a36Sopenharmony_ci
157462306a36Sopenharmony_ci  $ sudo sysctl -w net.ipv4.conf.all.forwarding=0
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_ciOn server A, we send packets to 8.8.8.8::
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_ci  $ nc -v 8.8.8.8 53
157962306a36Sopenharmony_ci
158062306a36Sopenharmony_ciOn server B, we check the output of nstat::
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci  $ nstat
158362306a36Sopenharmony_ci  #kernel
158462306a36Sopenharmony_ci  IpInReceives                    3                  0.0
158562306a36Sopenharmony_ci  IpInAddrErrors                  3                  0.0
158662306a36Sopenharmony_ci  IpExtInOctets                   180                0.0
158762306a36Sopenharmony_ci  IpExtInNoECTPkts                3                  0.0
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ciAs we have let server A route 8.8.8.8 to server B, and we disabled IP
159062306a36Sopenharmony_ciforwarding on server B, Server A sent packets to server B, then server B
159162306a36Sopenharmony_cidropped packets and increased IpInAddrErrors. As the nc command would
159262306a36Sopenharmony_cire-send the SYN packet if it didn't receive a SYN+ACK, we could find
159362306a36Sopenharmony_cimultiple IpInAddrErrors.
159462306a36Sopenharmony_ci
159562306a36Sopenharmony_ciSecond, generate IpExtInNoRoutes. On server B, we enable IP
159662306a36Sopenharmony_ciforwarding::
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci  $ sudo sysctl -w net.ipv4.conf.all.forwarding=1
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_ciCheck the route table of server B and remove the default route::
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci  $ ip route show
160362306a36Sopenharmony_ci  default via 192.168.122.1 dev ens3 proto static
160462306a36Sopenharmony_ci  192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.251
160562306a36Sopenharmony_ci  $ sudo ip route delete default via 192.168.122.1 dev ens3 proto static
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ciOn server A, we contact 8.8.8.8 again::
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci  $ nc -v 8.8.8.8 53
161062306a36Sopenharmony_ci  nc: connect to 8.8.8.8 port 53 (tcp) failed: Network is unreachable
161162306a36Sopenharmony_ci
161262306a36Sopenharmony_ciOn server B, run nstat::
161362306a36Sopenharmony_ci
161462306a36Sopenharmony_ci  $ nstat
161562306a36Sopenharmony_ci  #kernel
161662306a36Sopenharmony_ci  IpInReceives                    1                  0.0
161762306a36Sopenharmony_ci  IpOutRequests                   1                  0.0
161862306a36Sopenharmony_ci  IcmpOutMsgs                     1                  0.0
161962306a36Sopenharmony_ci  IcmpOutDestUnreachs             1                  0.0
162062306a36Sopenharmony_ci  IcmpMsgOutType3                 1                  0.0
162162306a36Sopenharmony_ci  IpExtInNoRoutes                 1                  0.0
162262306a36Sopenharmony_ci  IpExtInOctets                   60                 0.0
162362306a36Sopenharmony_ci  IpExtOutOctets                  88                 0.0
162462306a36Sopenharmony_ci  IpExtInNoECTPkts                1                  0.0
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ciWe enabled IP forwarding on server B, when server B received a packet
162762306a36Sopenharmony_ciwhich destination IP address is 8.8.8.8, server B will try to forward
162862306a36Sopenharmony_cithis packet. We have deleted the default route, there was no route for
162962306a36Sopenharmony_ci8.8.8.8, so server B increase IpExtInNoRoutes and sent the "ICMP
163062306a36Sopenharmony_ciDestination Unreachable" message to server A.
163162306a36Sopenharmony_ci
163262306a36Sopenharmony_ciThird, generate IpOutNoRoutes. Run ping command on server B::
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci  $ ping -c 1 8.8.8.8
163562306a36Sopenharmony_ci  connect: Network is unreachable
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_ciRun nstat on server B::
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci  $ nstat
164062306a36Sopenharmony_ci  #kernel
164162306a36Sopenharmony_ci  IpOutNoRoutes                   1                  0.0
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ciWe have deleted the default route on server B. Server B couldn't find
164462306a36Sopenharmony_cia route for the 8.8.8.8 IP address, so server B increased
164562306a36Sopenharmony_ciIpOutNoRoutes.
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_ciTcpExtTCPACKSkippedSynRecv
164862306a36Sopenharmony_ci--------------------------
164962306a36Sopenharmony_ciIn this test, we send 3 same SYN packets from client to server. The
165062306a36Sopenharmony_cifirst SYN will let server create a socket, set it to Syn-Recv status,
165162306a36Sopenharmony_ciand reply a SYN/ACK. The second SYN will let server reply the SYN/ACK
165262306a36Sopenharmony_ciagain, and record the reply time (the duplicate ACK reply time). The
165362306a36Sopenharmony_cithird SYN will let server check the previous duplicate ACK reply time,
165462306a36Sopenharmony_ciand decide to skip the duplicate ACK, then increase the
165562306a36Sopenharmony_ciTcpExtTCPACKSkippedSynRecv counter.
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ciRun tcpdump to capture a SYN packet::
165862306a36Sopenharmony_ci
165962306a36Sopenharmony_ci  nstatuser@nstat-a:~$ sudo tcpdump -c 1 -w /tmp/syn.pcap port 9000
166062306a36Sopenharmony_ci  tcpdump: listening on ens3, link-type EN10MB (Ethernet), capture size 262144 bytes
166162306a36Sopenharmony_ci
166262306a36Sopenharmony_ciOpen another terminal, run nc command::
166362306a36Sopenharmony_ci
166462306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc nstat-b 9000
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ciAs the nstat-b didn't listen on port 9000, it should reply a RST, and
166762306a36Sopenharmony_cithe nc command exited immediately. It was enough for the tcpdump
166862306a36Sopenharmony_cicommand to capture a SYN packet. A linux server might use hardware
166962306a36Sopenharmony_cioffload for the TCP checksum, so the checksum in the /tmp/syn.pcap
167062306a36Sopenharmony_cimight be not correct. We call tcprewrite to fix it::
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_ci  nstatuser@nstat-a:~$ tcprewrite --infile=/tmp/syn.pcap --outfile=/tmp/syn_fixcsum.pcap --fixcsum
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_ciOn nstat-b, we run nc to listen on port 9000::
167562306a36Sopenharmony_ci
167662306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 9000
167762306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9000)
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ciOn nstat-a, we blocked the packet from port 9000, or nstat-a would send
168062306a36Sopenharmony_ciRST to nstat-b::
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ci  nstatuser@nstat-a:~$ sudo iptables -A INPUT -p tcp --sport 9000 -j DROP
168362306a36Sopenharmony_ci
168462306a36Sopenharmony_ciSend 3 SYN repeatedly to nstat-b::
168562306a36Sopenharmony_ci
168662306a36Sopenharmony_ci  nstatuser@nstat-a:~$ for i in {1..3}; do sudo tcpreplay -i ens3 /tmp/syn_fixcsum.pcap; done
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ciCheck snmp counter on nstat-b::
168962306a36Sopenharmony_ci
169062306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat | grep -i skip
169162306a36Sopenharmony_ci  TcpExtTCPACKSkippedSynRecv      1                  0.0
169262306a36Sopenharmony_ci
169362306a36Sopenharmony_ciAs we expected, TcpExtTCPACKSkippedSynRecv is 1.
169462306a36Sopenharmony_ci
169562306a36Sopenharmony_ciTcpExtTCPACKSkippedPAWS
169662306a36Sopenharmony_ci-----------------------
169762306a36Sopenharmony_ciTo trigger PAWS, we could send an old SYN.
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ciOn nstat-b, let nc listen on port 9000::
170062306a36Sopenharmony_ci
170162306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 9000
170262306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9000)
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ciOn nstat-a, run tcpdump to capture a SYN::
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci  nstatuser@nstat-a:~$ sudo tcpdump -w /tmp/paws_pre.pcap -c 1 port 9000
170762306a36Sopenharmony_ci  tcpdump: listening on ens3, link-type EN10MB (Ethernet), capture size 262144 bytes
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ciOn nstat-a, run nc as a client to connect nstat-b::
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
171262306a36Sopenharmony_ci  Connection to nstat-b 9000 port [tcp/*] succeeded!
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ciNow the tcpdump has captured the SYN and exit. We should fix the
171562306a36Sopenharmony_cichecksum::
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci  nstatuser@nstat-a:~$ tcprewrite --infile /tmp/paws_pre.pcap --outfile /tmp/paws.pcap --fixcsum
171862306a36Sopenharmony_ci
171962306a36Sopenharmony_ciSend the SYN packet twice::
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci  nstatuser@nstat-a:~$ for i in {1..2}; do sudo tcpreplay -i ens3 /tmp/paws.pcap; done
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_ciOn nstat-b, check the snmp counter::
172462306a36Sopenharmony_ci
172562306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat | grep -i skip
172662306a36Sopenharmony_ci  TcpExtTCPACKSkippedPAWS         1                  0.0
172762306a36Sopenharmony_ci
172862306a36Sopenharmony_ciWe sent two SYN via tcpreplay, both of them would let PAWS check
172962306a36Sopenharmony_cifailed, the nstat-b replied an ACK for the first SYN, skipped the ACK
173062306a36Sopenharmony_cifor the second SYN, and updated TcpExtTCPACKSkippedPAWS.
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ciTcpExtTCPACKSkippedSeq
173362306a36Sopenharmony_ci----------------------
173462306a36Sopenharmony_ciTo trigger TcpExtTCPACKSkippedSeq, we send packets which have valid
173562306a36Sopenharmony_citimestamp (to pass PAWS check) but the sequence number is out of
173662306a36Sopenharmony_ciwindow. The linux TCP stack would avoid to skip if the packet has
173762306a36Sopenharmony_cidata, so we need a pure ACK packet. To generate such a packet, we
173862306a36Sopenharmony_cicould create two sockets: one on port 9000, another on port 9001. Then
173962306a36Sopenharmony_ciwe capture an ACK on port 9001, change the source/destination port
174062306a36Sopenharmony_cinumbers to match the port 9000 socket. Then we could trigger
174162306a36Sopenharmony_ciTcpExtTCPACKSkippedSeq via this packet.
174262306a36Sopenharmony_ci
174362306a36Sopenharmony_ciOn nstat-b, open two terminals, run two nc commands to listen on both
174462306a36Sopenharmony_ciport 9000 and port 9001::
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 9000
174762306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9000)
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 9001
175062306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9001)
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_ciOn nstat-a, run two nc clients::
175362306a36Sopenharmony_ci
175462306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9000
175562306a36Sopenharmony_ci  Connection to nstat-b 9000 port [tcp/*] succeeded!
175662306a36Sopenharmony_ci
175762306a36Sopenharmony_ci  nstatuser@nstat-a:~$ nc -v nstat-b 9001
175862306a36Sopenharmony_ci  Connection to nstat-b 9001 port [tcp/*] succeeded!
175962306a36Sopenharmony_ci
176062306a36Sopenharmony_ciOn nstat-a, run tcpdump to capture an ACK::
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci  nstatuser@nstat-a:~$ sudo tcpdump -w /tmp/seq_pre.pcap -c 1 dst port 9001
176362306a36Sopenharmony_ci  tcpdump: listening on ens3, link-type EN10MB (Ethernet), capture size 262144 bytes
176462306a36Sopenharmony_ci
176562306a36Sopenharmony_ciOn nstat-b, send a packet via the port 9001 socket. E.g. we sent a
176662306a36Sopenharmony_cistring 'foo' in our example::
176762306a36Sopenharmony_ci
176862306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nc -lkv 9001
176962306a36Sopenharmony_ci  Listening on [0.0.0.0] (family 0, port 9001)
177062306a36Sopenharmony_ci  Connection from nstat-a 42132 received!
177162306a36Sopenharmony_ci  foo
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_ciOn nstat-a, the tcpdump should have captured the ACK. We should check
177462306a36Sopenharmony_cithe source port numbers of the two nc clients::
177562306a36Sopenharmony_ci
177662306a36Sopenharmony_ci  nstatuser@nstat-a:~$ ss -ta '( dport = :9000 || dport = :9001 )' | tee
177762306a36Sopenharmony_ci  State  Recv-Q   Send-Q         Local Address:Port           Peer Address:Port
177862306a36Sopenharmony_ci  ESTAB  0        0            192.168.122.250:50208       192.168.122.251:9000
177962306a36Sopenharmony_ci  ESTAB  0        0            192.168.122.250:42132       192.168.122.251:9001
178062306a36Sopenharmony_ci
178162306a36Sopenharmony_ciRun tcprewrite, change port 9001 to port 9000, change port 42132 to
178262306a36Sopenharmony_ciport 50208::
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_ci  nstatuser@nstat-a:~$ tcprewrite --infile /tmp/seq_pre.pcap --outfile /tmp/seq.pcap -r 9001:9000 -r 42132:50208 --fixcsum
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_ciNow the /tmp/seq.pcap is the packet we need. Send it to nstat-b::
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci  nstatuser@nstat-a:~$ for i in {1..2}; do sudo tcpreplay -i ens3 /tmp/seq.pcap; done
178962306a36Sopenharmony_ci
179062306a36Sopenharmony_ciCheck TcpExtTCPACKSkippedSeq on nstat-b::
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci  nstatuser@nstat-b:~$ nstat | grep -i skip
179362306a36Sopenharmony_ci  TcpExtTCPACKSkippedSeq          1                  0.0
1794