This is a patch which adds instruments to the TCP MTU probing. It breaks
netstat -s because it extends the line length of /proc/net/netstat past 1024
characters, so it is not safe to apply. I'm sending it for reference only at
this point.
-John
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -260,6 +260,12 @@ enum
LINUX_MIB_TCPABORTONLINGER, /* TCPAbortOnLinger */
LINUX_MIB_TCPABORTFAILED, /* TCPAbortFailed */
LINUX_MIB_TCPMEMORYPRESSURES, /* TCPMemoryPressures */
+ LINUX_MIB_TCPMTUPROBESTALLS, /* TCPMTUProbeStalls */
+ LINUX_MIB_TCPMTUPROBEFAILS, /* TCPMTUProbeFails */
+ LINUX_MIB_TCPMTUPROBESUCCEEDS, /* TCPMTUProbeSucceeds */
+ LINUX_MIB_TCPMTUPROBEINCONCLUSIVES, /* TCPMTUProbeInconclusives */
+ LINUX_MIB_TCPMTUBLACKHOLEENABLES, /* TCPMTUBlackholeEnables */
+ LINUX_MIB_TCPMTUBLACKHOLEREDUCTIONS, /* TCPMTUBlackholeReductions */
__LINUX_MIB_MAX
};
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -242,6 +242,12 @@ static const struct snmp_mib snmp4_net_l
SNMP_MIB_ITEM("TCPAbortOnLinger", LINUX_MIB_TCPABORTONLINGER),
SNMP_MIB_ITEM("TCPAbortFailed", LINUX_MIB_TCPABORTFAILED),
SNMP_MIB_ITEM("TCPMemoryPressures", LINUX_MIB_TCPMEMORYPRESSURES),
+ SNMP_MIB_ITEM("TCPMTUProbeStalls", LINUX_MIB_TCPMTUPROBESTALLS),
+ SNMP_MIB_ITEM("TCPMTUProbeFails", LINUX_MIB_TCPMTUPROBEFAILS),
+ SNMP_MIB_ITEM("TCPMTUProbeSucceeds", LINUX_MIB_TCPMTUPROBESUCCEEDS),
+ SNMP_MIB_ITEM("TCPMTUProbeInconclusives", LINUX_MIB_TCPMTUPROBEINCONCLUSIVES),
+ SNMP_MIB_ITEM("TCPMTUBlackholeEnables", LINUX_MIB_TCPMTUBLACKHOLEENABLES),
+ SNMP_MIB_ITEM("TCPMTUBlackholeReductions", LINUX_MIB_TCPMTUBLACKHOLEREDUCTIONS),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1894,6 +1894,7 @@ static void tcp_mtup_probe_failed(struct
{
struct inet_connection_sock *icsk = inet_csk(sk);
+ NET_INC_STATS_BH(LINUX_MIB_TCPMTUPROBEFAILS);
icsk->icsk_mtup.search_high = icsk->icsk_mtup.probe_size - 1;
icsk->icsk_mtup.probe_size = 0;
}
@@ -1903,6 +1904,7 @@ static void tcp_mtup_probe_success(struc
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
+ NET_INC_STATS_BH(LINUX_MIB_TCPMTUPROBESUCCEEDS);
/* FIXME: breaks with very large cwnd */
tp->prior_ssthresh = tcp_current_ssthresh(sk);
tp->snd_cwnd = tp->snd_cwnd *
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1270,6 +1270,7 @@ static int tcp_write_xmit(struct sock *s
/* Do MTU probing. */
if ((result = tcp_mtu_probe(sk)) == 0) {
+ NET_INC_STATS_BH(LINUX_MIB_TCPMTUPROBESTALLS);
return 0;
} else if (result > 0) {
sent_pkts = 1;
@@ -1651,6 +1652,7 @@ int tcp_retransmit_skb(struct sock *sk,
/* Inconslusive MTU probe */
if (icsk->icsk_mtup.probe_size) {
+ NET_INC_STATS_BH(LINUX_MIB_TCPMTUPROBEINCONCLUSIVES);
icsk->icsk_mtup.probe_size = 0;
}
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -133,9 +133,11 @@ static int tcp_write_timeout(struct sock
/* Black hole detection */
if (sysctl_tcp_mtu_probing) {
if (!icsk->icsk_mtup.enabled) {
+ NET_INC_STATS_BH(LINUX_MIB_TCPMTUBLACKHOLEENABLES);
icsk->icsk_mtup.enabled = 1;
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
} else {
+ NET_INC_STATS_BH(LINUX_MIB_TCPMTUBLACKHOLEREDUCTIONS);
mss = min(sysctl_tcp_base_mss,
tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low)/2);
mss = max(mss, 68 - tp->tcp_header_len);