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