aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorLawrence Stewart <lstewart@FreeBSD.org>2010-11-06 15:40:34 +0000
committerLawrence Stewart <lstewart@FreeBSD.org>2010-11-06 15:40:34 +0000
commit331999b64ffd6c24a7bd04173bfe8f8ba92ce7d2 (patch)
tree4d4ecb4db0d600f5907246fe7f682fd5f7491352 /sys
parent078b8c8551c632203de7d47660bcaf2a454b0a3f (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_reass.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index ec6854b12eac..7b5fc8e17b66 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -73,17 +73,20 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_debug.h>
#endif /* TCPDEBUG */
+static int tcp_reass_sysctl_maxseg(SYSCTL_HANDLER_ARGS);
+static int tcp_reass_sysctl_qsize(SYSCTL_HANDLER_ARGS);
+
SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0,
"TCP Segment Reassembly Queue");
static int tcp_reass_maxseg = 0;
-SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN,
- &tcp_reass_maxseg, 0,
+SYSCTL_PROC(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN,
+ &tcp_reass_maxseg, 0, &tcp_reass_sysctl_maxseg, "I",
"Global maximum number of TCP Segments in Reassembly Queue");
static int tcp_reass_qsize = 0;
-SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
- &tcp_reass_qsize, 0,
+SYSCTL_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
+ &tcp_reass_qsize, 0, &tcp_reass_sysctl_qsize, "I",
"Global number of TCP Segments currently in Reassembly Queue");
static int tcp_reass_maxqlen = 48;
@@ -133,7 +136,6 @@ tcp_reass_flush(struct tcpcb *tp)
m_freem(qe->tqe_m);
uma_zfree(tcp_reass_zone, qe);
tp->t_segqlen--;
- tcp_reass_qsize--;
}
KASSERT((tp->t_segqlen == 0),
@@ -141,6 +143,20 @@ tcp_reass_flush(struct tcpcb *tp)
tp, tp->t_segqlen));
}
+static int
+tcp_reass_sysctl_maxseg(SYSCTL_HANDLER_ARGS)
+{
+ tcp_reass_maxseg = uma_zone_get_max(tcp_reass_zone);
+ return (sysctl_handle_int(oidp, arg1, arg2, req));
+}
+
+static int
+tcp_reass_sysctl_qsize(SYSCTL_HANDLER_ARGS)
+{
+ tcp_reass_qsize = uma_zone_get_cur(tcp_reass_zone);
+ return (sysctl_handle_int(oidp, arg1, arg2, req));
+}
+
int
tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
{
@@ -170,12 +186,10 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
* Limit the number of segments in the reassembly queue to prevent
* holding on to too many segments (and thus running out of mbufs).
* Make sure to let the missing segment through which caused this
- * queue. Always keep one global queue entry spare to be able to
- * process the missing segment.
+ * queue.
*/
if (th->th_seq != tp->rcv_nxt &&
- (tcp_reass_qsize + 1 >= tcp_reass_maxseg ||
- tp->t_segqlen >= tcp_reass_maxqlen)) {
+ tp->t_segqlen >= tcp_reass_maxqlen) {
tcp_reass_overflows++;
tcpstat.tcps_rcvmemdrop++;
m_freem(m);
@@ -195,7 +209,6 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
return (0);
}
tp->t_segqlen++;
- tcp_reass_qsize++;
/*
* Find a segment which begins after this one does.
@@ -222,7 +235,6 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
m_freem(m);
uma_zfree(tcp_reass_zone, te);
tp->t_segqlen--;
- tcp_reass_qsize--;
/*
* Try to present any queued data
* at the left window edge to the user.
@@ -259,7 +271,6 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
m_freem(q->tqe_m);
uma_zfree(tcp_reass_zone, q);
tp->t_segqlen--;
- tcp_reass_qsize--;
q = nq;
}
@@ -296,7 +307,6 @@ present:
sbappendstream_locked(&so->so_rcv, q->tqe_m);
uma_zfree(tcp_reass_zone, q);
tp->t_segqlen--;
- tcp_reass_qsize--;
q = nq;
} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
ND6_HINT(tp);