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);

Reply via email to