diff options
Diffstat (limited to 'freebsd/sys/netinet/tcp_reass.c')
-rw-r--r-- | freebsd/sys/netinet/tcp_reass.c | 80 |
1 files changed, 25 insertions, 55 deletions
diff --git a/freebsd/sys/netinet/tcp_reass.c b/freebsd/sys/netinet/tcp_reass.c index 2570a5f3..49184a5f 100644 --- a/freebsd/sys/netinet/tcp_reass.c +++ b/freebsd/sys/netinet/tcp_reass.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <rtems/bsd/sys/param.h> #include <sys/kernel.h> +#include <sys/eventhandler.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -51,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> #include <net/if.h> +#include <net/if_var.h> #include <net/route.h> #include <net/vnet.h> @@ -76,67 +78,46 @@ __FBSDID("$FreeBSD$"); #include <netinet/tcp_debug.h> #endif /* TCPDEBUG */ -static int tcp_reass_sysctl_qsize(SYSCTL_HANDLER_ARGS); - static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0, "TCP Segment Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_maxseg) = 0; -#define V_tcp_reass_maxseg VNET(tcp_reass_maxseg) -SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN, - &VNET_NAME(tcp_reass_maxseg), 0, +static int tcp_reass_maxseg = 0; +SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN, + &tcp_reass_maxseg, 0, "Global maximum number of TCP Segments in Reassembly Queue"); -SYSCTL_VNET_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, - (CTLTYPE_INT | CTLFLAG_RD), NULL, 0, &tcp_reass_sysctl_qsize, "I", +static uma_zone_t tcp_reass_zone; +SYSCTL_UMA_CUR(_net_inet_tcp_reass, OID_AUTO, cursegments, 0, + &tcp_reass_zone, "Global number of TCP Segments currently in Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_overflows) = 0; -#define V_tcp_reass_overflows VNET(tcp_reass_overflows) -SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, overflows, - CTLFLAG_RD, - &VNET_NAME(tcp_reass_overflows), 0, - "Global number of TCP Segment Reassembly Queue Overflows"); - -static VNET_DEFINE(uma_zone_t, tcp_reass_zone); -#define V_tcp_reass_zone VNET(tcp_reass_zone) - /* Initialize TCP reassembly queue */ static void tcp_reass_zone_change(void *tag) { /* Set the zone limit and read back the effective value. */ - V_tcp_reass_maxseg = nmbclusters / 16; - V_tcp_reass_maxseg = uma_zone_set_max(V_tcp_reass_zone, - V_tcp_reass_maxseg); + tcp_reass_maxseg = nmbclusters / 16; + tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, + tcp_reass_maxseg); } void -tcp_reass_init(void) +tcp_reass_global_init(void) { - V_tcp_reass_maxseg = nmbclusters / 16; + tcp_reass_maxseg = nmbclusters / 16; TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments", - &V_tcp_reass_maxseg); - V_tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), + &tcp_reass_maxseg); + tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); /* Set the zone limit and read back the effective value. */ - V_tcp_reass_maxseg = uma_zone_set_max(V_tcp_reass_zone, - V_tcp_reass_maxseg); + tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, + tcp_reass_maxseg); EVENTHANDLER_REGISTER(nmbclusters_change, tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY); } -#ifdef VIMAGE -void -tcp_reass_destroy(void) -{ - - uma_zdestroy(V_tcp_reass_zone); -} -#endif - void tcp_reass_flush(struct tcpcb *tp) { @@ -147,7 +128,7 @@ tcp_reass_flush(struct tcpcb *tp) while ((qe = LIST_FIRST(&tp->t_segq)) != NULL) { LIST_REMOVE(qe, tqe_q); m_freem(qe->tqe_m); - uma_zfree(V_tcp_reass_zone, qe); + uma_zfree(tcp_reass_zone, qe); tp->t_segqlen--; } @@ -156,15 +137,6 @@ tcp_reass_flush(struct tcpcb *tp) tp, tp->t_segqlen)); } -static int -tcp_reass_sysctl_qsize(SYSCTL_HANDLER_ARGS) -{ - int qsize; - - qsize = uma_zone_get_cur(V_tcp_reass_zone); - return (sysctl_handle_int(oidp, &qsize, 0, req)); -} - int tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) { @@ -209,15 +181,14 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) */ if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { - V_tcp_reass_overflows++; - TCPSTAT_INC(tcps_rcvmemdrop); - m_freem(m); + TCPSTAT_INC(tcps_rcvreassfull); *tlenp = 0; if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: queue limit reached, " "segment dropped\n", s, __func__); free(s, M_TCPLOG); } + m_freem(m); return (0); } @@ -228,7 +199,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * Use a temporary structure on the stack for the missing segment * when the zone is exhausted. Otherwise we may get stuck. */ - te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); + te = uma_zalloc(tcp_reass_zone, M_NOWAIT); if (te == NULL) { if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); @@ -279,7 +250,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); if (te != &tqs) - uma_zfree(V_tcp_reass_zone, te); + uma_zfree(tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data @@ -316,7 +287,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) nq = LIST_NEXT(q, tqe_q); LIST_REMOVE(q, tqe_q); m_freem(q->tqe_m); - uma_zfree(V_tcp_reass_zone, q); + uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } @@ -353,13 +324,12 @@ present: if (so->so_rcv.sb_state & SBS_CANTRCVMORE) m_freem(q->tqe_m); else - sbappendstream_locked(&so->so_rcv, q->tqe_m); + sbappendstream_locked(&so->so_rcv, q->tqe_m, 0); if (q != &tqs) - uma_zfree(V_tcp_reass_zone, q); + uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } while (q && q->tqe_th->th_seq == tp->rcv_nxt); - ND6_HINT(tp); sorwakeup_locked(so); return (flags); } |