summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2016-03-15 00:15:10 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2016-03-15 00:15:10 +0000
commitbf840a17070ef75e5eef3511bfee0f9eb1533c47 (patch)
tree685f2d528345ff2e8c2651d0934a849e415d495e
parentb5b7b142a7e0e74bdd8c497f6a14804e71654dfd (diff)
Notes
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_tcp.c16
-rw-r--r--sys/netinet/tcp_input.c29
-rw-r--r--sys/netinet/tcp_subr.c10
-rw-r--r--sys/netinet/tcp_syncache.c6
-rw-r--r--sys/netinet/tcp_timewait.c2
-rw-r--r--sys/netinet/tcp_usrreq.c2
-rw-r--r--sys/netinet/tcp_var.h14
7 files changed, 58 insertions, 21 deletions
diff --git a/contrib/bsnmp/snmp_mibII/mibII_tcp.c b/contrib/bsnmp/snmp_mibII/mibII_tcp.c
index c798bae1fa17..913a53736d23 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_tcp.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_tcp.c
@@ -47,6 +47,7 @@ struct tcp_index {
static uint64_t tcp_tick;
static uint64_t tcp_stats_tick;
static struct tcpstat tcpstat;
+static uint64_t tcps_states[TCP_NSTATES];
static struct xinpgen *xinpgen;
static size_t xinpgen_len;
static u_int tcp_total;
@@ -78,6 +79,17 @@ fetch_tcp_stats(void)
return (-1);
}
+ len = sizeof(tcps_states);
+ if (sysctlbyname("net.inet.tcp.states", &tcps_states, &len, NULL,
+ 0) == -1) {
+ syslog(LOG_ERR, "net.inet.tcp.states: %m");
+ return (-1);
+ }
+ if (len != sizeof(tcps_states)) {
+ syslog(LOG_ERR, "net.inet.tcp.states: wrong size");
+ return (-1);
+ }
+
tcp_stats_tick = get_ticks();
return (0);
@@ -231,8 +243,8 @@ op_tcp(struct snmp_context *ctx __unused, struct snmp_value *value,
break;
case LEAF_tcpCurrEstab:
- value->v.uint32 = tcpstat.tcps_states[TCPS_ESTABLISHED] +
- tcpstat.tcps_states[TCPS_CLOSE_WAIT];
+ value->v.uint32 = tcps_states[TCPS_ESTABLISHED] +
+ tcps_states[TCPS_CLOSE_WAIT];
break;
case LEAF_tcpInSegs:
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 102430dfe3c2..16be9cbc05b1 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -235,16 +235,39 @@ VNET_DEFINE(struct inpcbhead, tcb);
VNET_DEFINE(struct inpcbinfo, tcbinfo);
/*
- * TCP statistics are stored in an "array" of counter(9)s.
+ * TCP statistics are stored in an array of counter(9)s, which size matches
+ * size of struct tcpstat. TCP running connection count is a regular array.
*/
VNET_PCPUSTAT_DEFINE(struct tcpstat, tcpstat);
-VNET_PCPUSTAT_SYSINIT(tcpstat);
SYSCTL_VNET_PCPUSTAT(_net_inet_tcp, TCPCTL_STATS, stats, struct tcpstat,
tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)");
+VNET_DEFINE(counter_u64_t, tcps_states[TCP_NSTATES]);
+SYSCTL_COUNTER_U64_ARRAY(_net_inet_tcp, TCPCTL_STATES, states, CTLFLAG_RD |
+ CTLFLAG_VNET, &VNET_NAME(tcps_states), TCP_NSTATES,
+ "TCP connection counts by TCP state");
+
+static void
+tcp_vnet_init(const void *unused)
+{
+
+ COUNTER_ARRAY_ALLOC(VNET(tcps_states), TCP_NSTATES, M_WAITOK);
+ VNET_PCPUSTAT_ALLOC(tcpstat, M_WAITOK);
+}
+VNET_SYSINIT(tcp_vnet_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+ tcp_vnet_init, NULL);
#ifdef VIMAGE
-VNET_PCPUSTAT_SYSUNINIT(tcpstat);
+static void
+tcp_vnet_uninit(const void *unused)
+{
+
+ COUNTER_ARRAY_FREE(VNET(tcps_states), TCP_NSTATES);
+ VNET_PCPUSTAT_FREE(tcpstat);
+}
+VNET_SYSUNINIT(tcp_vnet_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+ tcp_vnet_uninit, NULL);
#endif /* VIMAGE */
+
/*
* Kernel module interface for updating tcpstat. The argument is an index
* into tcpstat treated as an array.
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index ff218ddc03e8..6635bb71dadf 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1542,7 +1542,7 @@ tcp_close(struct tcpcb *tp)
#endif
in_pcbdrop(inp);
TCPSTAT_INC(tcps_closed);
- TCPSTAT_DEC(tcps_states[tp->t_state]);
+ TCPSTATES_DEC(tp->t_state);
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
so = inp->inp_socket;
soisdisconnected(so);
@@ -1665,7 +1665,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
*/
if (req->oldptr == NULL) {
n = V_tcbinfo.ipi_count +
- TCPSTAT_FETCH(tcps_states[TCPS_SYN_RECEIVED]);
+ counter_u64_fetch(VNET(tcps_states)[TCPS_SYN_RECEIVED]);
n += imax(n / 8, 10);
req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xtcpcb);
return (0);
@@ -1682,7 +1682,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
n = V_tcbinfo.ipi_count;
INP_LIST_RUNLOCK(&V_tcbinfo);
- m = TCPSTAT_FETCH(tcps_states[TCPS_SYN_RECEIVED]);
+ m = counter_u64_fetch(VNET(tcps_states)[TCPS_SYN_RECEIVED]);
error = sysctl_wire_old_buffer(req, 2 * (sizeof xig)
+ (n + m) * sizeof(struct xtcpcb));
@@ -2986,8 +2986,8 @@ tcp_state_change(struct tcpcb *tp, int newstate)
int pstate = tp->t_state;
#endif
- TCPSTAT_DEC(tcps_states[tp->t_state]);
- TCPSTAT_INC(tcps_states[newstate]);
+ TCPSTATES_DEC(tp->t_state);
+ TCPSTATES_INC(newstate);
tp->t_state = newstate;
TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate);
}
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 0ff731833716..b898c498eb68 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -351,7 +351,7 @@ syncache_insert(struct syncache *sc, struct syncache_head *sch)
SCH_UNLOCK(sch);
- TCPSTAT_INC(tcps_states[TCPS_SYN_RECEIVED]);
+ TCPSTATES_INC(TCPS_SYN_RECEIVED);
TCPSTAT_INC(tcps_sc_added);
}
@@ -365,7 +365,7 @@ syncache_drop(struct syncache *sc, struct syncache_head *sch)
SCH_LOCK_ASSERT(sch);
- TCPSTAT_DEC(tcps_states[TCPS_SYN_RECEIVED]);
+ TCPSTATES_DEC(TCPS_SYN_RECEIVED);
TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
sch->sch_length--;
@@ -1003,7 +1003,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
* sonewconn->tcp_usr_attach in TCPS_CLOSED state, then
* syncache_socket() will change it to TCPS_SYN_RECEIVED.
*/
- TCPSTAT_DEC(tcps_states[TCPS_SYN_RECEIVED]);
+ TCPSTATES_DEC(TCPS_SYN_RECEIVED);
TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
sch->sch_length--;
#ifdef TCP_OFFLOAD
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index c98de24f29e9..ff36ce7e4668 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -660,7 +660,7 @@ tcp_tw_2msl_stop(struct tcptw *tw, int reuse)
if (!reuse)
uma_zfree(V_tcptw_zone, tw);
- TCPSTAT_DEC(tcps_states[TCPS_TIME_WAIT]);
+ TCPSTATES_DEC(TCPS_TIME_WAIT);
}
struct tcptw *
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 09493f048b12..6a3cde6ca0a2 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1883,7 +1883,7 @@ tcp_attach(struct socket *so)
tp->t_state = TCPS_CLOSED;
INP_WUNLOCK(inp);
INP_INFO_RUNLOCK(&V_tcbinfo);
- TCPSTAT_INC(tcps_states[TCPS_CLOSED]);
+ TCPSTATES_INC(TCPS_CLOSED);
return (0);
}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 2f238814bbb8..b28ee237fee9 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -588,9 +588,6 @@ struct tcpstat {
uint64_t tcps_sig_err_sigopt; /* No signature expected by socket */
uint64_t tcps_sig_err_nosigopt; /* No signature provided by segment */
- /* Running connection count. */
- uint64_t tcps_states[TCP_NSTATES];
-
uint64_t _pad[12]; /* 6 UTO, 6 TBD */
};
@@ -609,9 +606,6 @@ VNET_PCPUSTAT_DECLARE(struct tcpstat, tcpstat); /* tcp statistics */
#define TCPSTAT_ADD(name, val) \
VNET_PCPUSTAT_ADD(struct tcpstat, tcpstat, name, (val))
#define TCPSTAT_INC(name) TCPSTAT_ADD(name, 1)
-#define TCPSTAT_DEC(name) TCPSTAT_ADD(name, -1)
-#define TCPSTAT_FETCH(name) VNET_PCPUSTAT_FETCH(struct tcpstat, tcpstat, \
- name)
/*
* Kernel module consumers must use this accessor macro.
@@ -621,6 +615,13 @@ void kmod_tcpstat_inc(int statnum);
kmod_tcpstat_inc(offsetof(struct tcpstat, name) / sizeof(uint64_t))
/*
+ * Running TCP connection count by state.
+ */
+VNET_DECLARE(counter_u64_t, tcps_states[TCP_NSTATES]);
+#define TCPSTATES_INC(state) counter_u64_add(VNET(tcps_states)[state], 1)
+#define TCPSTATES_DEC(state) counter_u64_add(VNET(tcps_states)[state], -1)
+
+/*
* TCP specific helper hook point identifiers.
*/
#define HHOOK_TCP_EST_IN 0
@@ -678,6 +679,7 @@ struct xtcpcb {
#define TCPCTL_V6MSSDFLT 13 /* MSS default for IPv6 */
#define TCPCTL_SACK 14 /* Selective Acknowledgement,rfc 2018 */
#define TCPCTL_DROP 15 /* drop tcp connection */
+#define TCPCTL_STATES 16 /* connection counts by TCP state */
#ifdef _KERNEL
#ifdef SYSCTL_DECL