View | Details | Raw Unified | Return to bug 64656 | Differences between
and this patch

Collapse All | Expand All

(-)sys/netinet/tcp_input.c (-9 / +61 lines)
Lines 57-62 Link Here
57
57
58
#include <machine/cpu.h>	/* before tcp_seq.h, for tcp_random18() */
58
#include <machine/cpu.h>	/* before tcp_seq.h, for tcp_random18() */
59
59
60
#include <vm/uma.h>
61
60
#include <net/if.h>
62
#include <net/if.h>
61
#include <net/route.h>
63
#include <net/route.h>
62
64
Lines 97-104 Link Here
97
99
98
#include <machine/in_cksum.h>
100
#include <machine/in_cksum.h>
99
101
100
MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
101
102
static const int tcprexmtthresh = 3;
102
static const int tcprexmtthresh = 3;
103
tcp_cc	tcp_ccgen;
103
tcp_cc	tcp_ccgen;
104
104
Lines 134-139 SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3 Link Here
134
    &tcp_do_rfc3390, 0,
134
    &tcp_do_rfc3390, 0,
135
    "Enable RFC 3390 (Increasing TCP's Initial Congestion Window)");
135
    "Enable RFC 3390 (Increasing TCP's Initial Congestion Window)");
136
136
137
SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0,
138
    "TCP Segment Reassembly Queue");
139
140
static int tcp_reass_maxseg = 0;
141
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN,
142
    &tcp_reass_maxseg, 0,
143
    "Global maximum number of TCP Segments in Reassembly Queue");
144
145
int tcp_reass_qsize = 0;
146
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
147
    &tcp_reass_qsize, 0,
148
    "Global number of TCP Segments currently in Reassembly Queue");
149
150
static int tcp_reass_overflows = 0;
151
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
152
    &tcp_reass_overflows, 0,
153
    "Global number of TCP Segment Reassembly Queue Overflows");
154
137
struct inpcbhead tcb;
155
struct inpcbhead tcb;
138
#define	tcb6	tcb  /* for KAME src sync over BSD*'s */
156
#define	tcb6	tcb  /* for KAME src sync over BSD*'s */
139
struct inpcbinfo tcbinfo;
157
struct inpcbinfo tcbinfo;
Lines 174-179 do { \ Link Here
174
	    (tp->t_flags & TF_RXWIN0SENT) == 0) &&			\
192
	    (tp->t_flags & TF_RXWIN0SENT) == 0) &&			\
175
	    (tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
193
	    (tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
176
194
195
/* Initialize TCP reassembly queue */
196
uma_zone_t	tcp_reass_zone;
197
void
198
tcp_reass_init()
199
{
200
	tcp_reass_maxseg = nmbclusters / 16;
201
	TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments",
202
	    &tcp_reass_maxseg);
203
	tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent),
204
	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
205
	uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg);
206
}
207
177
static int
208
static int
178
tcp_reass(tp, th, tlenp, m)
209
tcp_reass(tp, th, tlenp, m)
179
	register struct tcpcb *tp;
210
	register struct tcpcb *tp;
Lines 184-190 tcp_reass(tp, th, tlenp, m) Link Here
184
	struct tseg_qent *q;
215
	struct tseg_qent *q;
185
	struct tseg_qent *p = NULL;
216
	struct tseg_qent *p = NULL;
186
	struct tseg_qent *nq;
217
	struct tseg_qent *nq;
187
	struct tseg_qent *te;
218
	struct tseg_qent *te = NULL;
188
	struct socket *so = tp->t_inpcb->inp_socket;
219
	struct socket *so = tp->t_inpcb->inp_socket;
189
	int flags;
220
	int flags;
190
221
Lines 195-203 tcp_reass(tp, th, tlenp, m) Link Here
195
	if (th == 0)
226
	if (th == 0)
196
		goto present;
227
		goto present;
197
228
198
	/* Allocate a new queue entry. If we can't, just drop the pkt. XXX */
229
	/*
199
	MALLOC(te, struct tseg_qent *, sizeof (struct tseg_qent), M_TSEGQ,
230
	 * Limit the number of segments in the reassembly queue to prevent
200
	       M_NOWAIT);
231
	 * holding on to too many segments (and thus running out of mbufs).
232
	 * Make sure to let the missing segment through which caused this
233
	 * queue.  Always keep one global queue entry spare to be able to
234
	 * process the missing segment.
235
	 */
236
	if (th->th_seq != tp->rcv_nxt &&
237
	    tcp_reass_qsize + 1 >= tcp_reass_maxseg) {
238
		tcp_reass_overflows++;
239
		tcpstat.tcps_rcvmemdrop++;
240
		m_freem(m);
241
		return (0);
242
	}
243
	tcp_reass_qsize++;
244
245
	/*
246
	 * Allocate a new queue entry. If we can't, or hit the zone limit
247
	 * just drop the pkt.
248
	 */
249
	te = uma_zalloc(tcp_reass_zone, M_NOWAIT);
201
	if (te == NULL) {
250
	if (te == NULL) {
202
		tcpstat.tcps_rcvmemdrop++;
251
		tcpstat.tcps_rcvmemdrop++;
203
		m_freem(m);
252
		m_freem(m);
Lines 227-233 tcp_reass(tp, th, tlenp, m) Link Here
227
				tcpstat.tcps_rcvduppack++;
276
				tcpstat.tcps_rcvduppack++;
228
				tcpstat.tcps_rcvdupbyte += *tlenp;
277
				tcpstat.tcps_rcvdupbyte += *tlenp;
229
				m_freem(m);
278
				m_freem(m);
230
				FREE(te, M_TSEGQ);
279
				uma_zfree(tcp_reass_zone, te);
280
				tcp_reass_qsize--;
231
				/*
281
				/*
232
				 * Try to present any queued data
282
				 * Try to present any queued data
233
				 * at the left window edge to the user.
283
				 * at the left window edge to the user.
Lines 262-268 tcp_reass(tp, th, tlenp, m) Link Here
262
		nq = LIST_NEXT(q, tqe_q);
312
		nq = LIST_NEXT(q, tqe_q);
263
		LIST_REMOVE(q, tqe_q);
313
		LIST_REMOVE(q, tqe_q);
264
		m_freem(q->tqe_m);
314
		m_freem(q->tqe_m);
265
		FREE(q, M_TSEGQ);
315
		uma_zfree(tcp_reass_zone, q);
316
		tcp_reass_qsize--;
266
		q = nq;
317
		q = nq;
267
	}
318
	}
268
319
Lines 296-302 present: Link Here
296
			m_freem(q->tqe_m);
347
			m_freem(q->tqe_m);
297
		else
348
		else
298
			sbappendstream(&so->so_rcv, q->tqe_m);
349
			sbappendstream(&so->so_rcv, q->tqe_m);
299
		FREE(q, M_TSEGQ);
350
		uma_zfree(tcp_reass_zone, q);
351
		tcp_reass_qsize--;
300
		q = nq;
352
		q = nq;
301
	} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
353
	} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
302
	ND6_HINT(tp);
354
	ND6_HINT(tp);
(-)sys/netinet/tcp_subr.c (-2 / +5 lines)
Lines 286-291 tcp_init() Link Here
286
	tcp_timer_init();
286
	tcp_timer_init();
287
	syncache_init();
287
	syncache_init();
288
	tcp_hc_init();
288
	tcp_hc_init();
289
	tcp_reass_init();
289
}
290
}
290
291
291
/*
292
/*
Lines 708-714 tcp_discardcb(tp) Link Here
708
	while ((q = LIST_FIRST(&tp->t_segq)) != NULL) {
709
	while ((q = LIST_FIRST(&tp->t_segq)) != NULL) {
709
		LIST_REMOVE(q, tqe_q);
710
		LIST_REMOVE(q, tqe_q);
710
		m_freem(q->tqe_m);
711
		m_freem(q->tqe_m);
711
		FREE(q, M_TSEGQ);
712
		uma_zfree(tcp_reass_zone, q);
713
		tcp_reass_qsize--;
712
	}
714
	}
713
	inp->inp_ppcb = NULL;
715
	inp->inp_ppcb = NULL;
714
	tp->t_inpcb = NULL;
716
	tp->t_inpcb = NULL;
Lines 769-775 tcp_drain() Link Here
769
			            != NULL) {
771
			            != NULL) {
770
					LIST_REMOVE(te, tqe_q);
772
					LIST_REMOVE(te, tqe_q);
771
					m_freem(te->tqe_m);
773
					m_freem(te->tqe_m);
772
					FREE(te, M_TSEGQ);
774
					uma_zfree(tcp_reass_zone, te);
775
					tcp_reass_qsize--;
773
				}
776
				}
774
			}
777
			}
775
			INP_UNLOCK(inpb);
778
			INP_UNLOCK(inpb);
(-)sys/netinet/tcp_var.h (-3 / +3 lines)
Lines 54-62 struct tseg_qent { Link Here
54
	struct	mbuf	*tqe_m;		/* mbuf contains packet */
54
	struct	mbuf	*tqe_m;		/* mbuf contains packet */
55
};
55
};
56
LIST_HEAD(tsegqe_head, tseg_qent);
56
LIST_HEAD(tsegqe_head, tseg_qent);
57
#ifdef MALLOC_DECLARE
57
extern int	tcp_reass_qsize;
58
MALLOC_DECLARE(M_TSEGQ);
58
extern struct uma_zone	*tcp_reass_zone;
59
#endif
60
59
61
struct tcptemp {
60
struct tcptemp {
62
	u_char	tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
61
	u_char	tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
Lines 514-519 struct tcpcb * Link Here
514
int	 tcp_output(struct tcpcb *);
513
int	 tcp_output(struct tcpcb *);
515
struct inpcb *
514
struct inpcb *
516
	 tcp_quench(struct inpcb *, int);
515
	 tcp_quench(struct inpcb *, int);
516
void	 tcp_reass_init(void);
517
void	 tcp_respond(struct tcpcb *, void *,
517
void	 tcp_respond(struct tcpcb *, void *,
518
	    struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
518
	    struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
519
int	 tcp_twrespond(struct tcptw *, struct socket *, struct mbuf *, int);
519
int	 tcp_twrespond(struct tcptw *, struct socket *, struct mbuf *, int);

Return to bug 64656