tcp_usrreq.c revision 1.233 1 /* $NetBSD: tcp_usrreq.c,v 1.233 2022/10/28 05:18:39 ozaki-r Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*-
33 * Copyright (c) 1997, 1998, 2005, 2006 The NetBSD Foundation, Inc.
34 * All rights reserved.
35 *
36 * This code is derived from software contributed to The NetBSD Foundation
37 * by Jason R. Thorpe and Kevin M. Lahey of the Numerical Aerospace Simulation
38 * Facility, NASA Ames Research Center.
39 * This code is derived from software contributed to The NetBSD Foundation
40 * by Charles M. Hannum.
41 * This code is derived from software contributed to The NetBSD Foundation
42 * by Rui Paulo.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
54 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
57 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63 * POSSIBILITY OF SUCH DAMAGE.
64 */
65
66 /*
67 * Copyright (c) 1982, 1986, 1988, 1993, 1995
68 * The Regents of the University of California. All rights reserved.
69 *
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
72 * are met:
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. Neither the name of the University nor the names of its contributors
79 * may be used to endorse or promote products derived from this software
80 * without specific prior written permission.
81 *
82 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
83 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
86 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
88 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
90 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
92 * SUCH DAMAGE.
93 *
94 * @(#)tcp_usrreq.c 8.5 (Berkeley) 6/21/95
95 */
96
97 /*
98 * TCP protocol interface to socket abstraction.
99 */
100
101 #include <sys/cdefs.h>
102 __KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.233 2022/10/28 05:18:39 ozaki-r Exp $");
103
104 #ifdef _KERNEL_OPT
105 #include "opt_inet.h"
106 #include "opt_tcp_debug.h"
107 #include "opt_mbuftrace.h"
108 #include "opt_tcp_space.h"
109 #include "opt_net_mpsafe.h"
110 #endif
111
112 #include <sys/param.h>
113 #include <sys/systm.h>
114 #include <sys/kernel.h>
115 #include <sys/mbuf.h>
116 #include <sys/socket.h>
117 #include <sys/socketvar.h>
118 #include <sys/protosw.h>
119 #include <sys/errno.h>
120 #include <sys/stat.h>
121 #include <sys/proc.h>
122 #include <sys/domain.h>
123 #include <sys/sysctl.h>
124 #include <sys/kauth.h>
125 #include <sys/kernel.h>
126 #include <sys/uidinfo.h>
127
128 #include <net/if.h>
129
130 #include <netinet/in.h>
131 #include <netinet/in_systm.h>
132 #include <netinet/in_var.h>
133 #include <netinet/ip.h>
134 #include <netinet/in_pcb.h>
135 #include <netinet/ip_var.h>
136 #include <netinet/in_offload.h>
137
138 #ifdef INET6
139 #include <netinet/ip6.h>
140 #include <netinet6/in6_pcb.h>
141 #include <netinet6/ip6_var.h>
142 #include <netinet6/scope6_var.h>
143 #endif
144
145 #include <netinet/tcp.h>
146 #include <netinet/tcp_fsm.h>
147 #include <netinet/tcp_seq.h>
148 #include <netinet/tcp_timer.h>
149 #include <netinet/tcp_var.h>
150 #include <netinet/tcp_private.h>
151 #include <netinet/tcp_congctl.h>
152 #include <netinet/tcp_debug.h>
153 #include <netinet/tcp_vtw.h>
154 #include <netinet/tcp_syncache.h>
155
156 static int
157 tcp_debug_capture(struct tcpcb *tp, int req)
158 {
159 #ifdef TCP_DEBUG
160 return tp->t_state;
161 #endif
162 return 0;
163 }
164
165 static inline void
166 tcp_debug_trace(struct socket *so, struct tcpcb *tp, int ostate, int req)
167 {
168 #ifdef TCP_DEBUG
169 if (tp && (so->so_options & SO_DEBUG))
170 tcp_trace(TA_USER, ostate, tp, NULL, req);
171 #endif
172 }
173
174 static void
175 change_keepalive(struct socket *so, struct tcpcb *tp)
176 {
177 tp->t_maxidle = tp->t_keepcnt * MIN(tp->t_keepintvl,
178 TCP_TIMER_MAXTICKS / tp->t_keepcnt);
179 TCP_TIMER_DISARM(tp, TCPT_KEEP);
180 TCP_TIMER_DISARM(tp, TCPT_2MSL);
181
182 if (tp->t_state == TCPS_SYN_RECEIVED ||
183 tp->t_state == TCPS_SYN_SENT) {
184 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
185 } else if (so->so_options & SO_KEEPALIVE &&
186 tp->t_state <= TCPS_CLOSE_WAIT) {
187 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepintvl);
188 } else {
189 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle);
190 }
191
192 if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0))
193 TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
194 }
195
196 /*
197 * Export TCP internal state information via a struct tcp_info, based on the
198 * Linux 2.6 API. Not ABI compatible as our constants are mapped differently
199 * (TCP state machine, etc). We export all information using FreeBSD-native
200 * constants -- for example, the numeric values for tcpi_state will differ
201 * from Linux.
202 */
203 static void
204 tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
205 {
206
207 bzero(ti, sizeof(*ti));
208
209 ti->tcpi_state = tp->t_state;
210 if ((tp->t_flags & TF_REQ_TSTMP) && (tp->t_flags & TF_RCVD_TSTMP))
211 ti->tcpi_options |= TCPI_OPT_TIMESTAMPS;
212 if (tp->t_flags & TF_SACK_PERMIT)
213 ti->tcpi_options |= TCPI_OPT_SACK;
214 if ((tp->t_flags & TF_REQ_SCALE) && (tp->t_flags & TF_RCVD_SCALE)) {
215 ti->tcpi_options |= TCPI_OPT_WSCALE;
216 ti->tcpi_snd_wscale = tp->snd_scale;
217 ti->tcpi_rcv_wscale = tp->rcv_scale;
218 }
219 if (tp->t_flags & TF_ECN_PERMIT) {
220 ti->tcpi_options |= TCPI_OPT_ECN;
221 }
222
223 ti->tcpi_rto = tp->t_rxtcur * tick;
224 ti->tcpi_last_data_recv = (long)(getticks() -
225 (int)tp->t_rcvtime) * tick;
226 ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick / PR_SLOWHZ)
227 >> (TCP_RTT_SHIFT + 2);
228 ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick / PR_SLOWHZ)
229 >> (TCP_RTTVAR_SHIFT + 2);
230
231 ti->tcpi_snd_ssthresh = tp->snd_ssthresh;
232 /* Linux API wants these in # of segments, apparently */
233 ti->tcpi_snd_cwnd = tp->snd_cwnd / tp->t_segsz;
234 ti->tcpi_snd_wnd = tp->snd_wnd / tp->t_segsz;
235
236 /*
237 * FreeBSD-specific extension fields for tcp_info.
238 */
239 ti->tcpi_rcv_space = tp->rcv_wnd;
240 ti->tcpi_rcv_nxt = tp->rcv_nxt;
241 ti->tcpi_snd_bwnd = 0; /* Unused, kept for compat. */
242 ti->tcpi_snd_nxt = tp->snd_nxt;
243 ti->tcpi_snd_mss = tp->t_segsz;
244 ti->tcpi_rcv_mss = tp->t_segsz;
245 #ifdef TF_TOE
246 if (tp->t_flags & TF_TOE)
247 ti->tcpi_options |= TCPI_OPT_TOE;
248 #endif
249 /* From the redundant department of redundancies... */
250 ti->__tcpi_retransmits = ti->__tcpi_retrans =
251 ti->tcpi_snd_rexmitpack = tp->t_sndrexmitpack;
252
253 ti->tcpi_rcv_ooopack = tp->t_rcvoopack;
254 ti->tcpi_snd_zerowin = tp->t_sndzerowin;
255 }
256
257 int
258 tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
259 {
260 int error = 0, s;
261 struct inpcb *inp;
262 struct tcpcb *tp;
263 struct tcp_info ti;
264 u_int ui;
265 int family; /* family of the socket */
266 int level, optname, optval;
267
268 level = sopt->sopt_level;
269 optname = sopt->sopt_name;
270
271 family = so->so_proto->pr_domain->dom_family;
272
273 s = splsoftnet();
274 inp = sotoinpcb(so);
275 if (level != IPPROTO_TCP) {
276 switch (family) {
277 case PF_INET:
278 error = ip_ctloutput(op, so, sopt);
279 break;
280 #ifdef INET6
281 case PF_INET6:
282 error = ip6_ctloutput(op, so, sopt);
283 break;
284 #endif
285 }
286 splx(s);
287 return error;
288 }
289 tp = intotcpcb(inp);
290
291 switch (op) {
292 case PRCO_SETOPT:
293 switch (optname) {
294 #ifdef TCP_SIGNATURE
295 case TCP_MD5SIG:
296 error = sockopt_getint(sopt, &optval);
297 if (error)
298 break;
299 if (optval > 0)
300 tp->t_flags |= TF_SIGNATURE;
301 else
302 tp->t_flags &= ~TF_SIGNATURE;
303 break;
304 #endif /* TCP_SIGNATURE */
305
306 case TCP_NODELAY:
307 error = sockopt_getint(sopt, &optval);
308 if (error)
309 break;
310 if (optval)
311 tp->t_flags |= TF_NODELAY;
312 else
313 tp->t_flags &= ~TF_NODELAY;
314 break;
315
316 case TCP_MAXSEG:
317 error = sockopt_getint(sopt, &optval);
318 if (error)
319 break;
320 if (optval > 0 && optval <= tp->t_peermss)
321 tp->t_peermss = optval; /* limit on send size */
322 else
323 error = EINVAL;
324 break;
325 #ifdef notyet
326 case TCP_CONGCTL:
327 /* XXX string overflow XXX */
328 error = tcp_congctl_select(tp, sopt->sopt_data);
329 break;
330 #endif
331
332 case TCP_KEEPIDLE:
333 error = sockopt_get(sopt, &ui, sizeof(ui));
334 if (error)
335 break;
336 if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
337 tp->t_keepidle = ui;
338 change_keepalive(so, tp);
339 } else
340 error = EINVAL;
341 break;
342
343 case TCP_KEEPINTVL:
344 error = sockopt_get(sopt, &ui, sizeof(ui));
345 if (error)
346 break;
347 if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
348 tp->t_keepintvl = ui;
349 change_keepalive(so, tp);
350 } else
351 error = EINVAL;
352 break;
353
354 case TCP_KEEPCNT:
355 error = sockopt_get(sopt, &ui, sizeof(ui));
356 if (error)
357 break;
358 if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
359 tp->t_keepcnt = ui;
360 change_keepalive(so, tp);
361 } else
362 error = EINVAL;
363 break;
364
365 case TCP_KEEPINIT:
366 error = sockopt_get(sopt, &ui, sizeof(ui));
367 if (error)
368 break;
369 if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
370 tp->t_keepinit = ui;
371 change_keepalive(so, tp);
372 } else
373 error = EINVAL;
374 break;
375
376 default:
377 error = ENOPROTOOPT;
378 break;
379 }
380 break;
381
382 case PRCO_GETOPT:
383 switch (optname) {
384 #ifdef TCP_SIGNATURE
385 case TCP_MD5SIG:
386 optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
387 goto setval;
388 #endif
389 case TCP_NODELAY:
390 optval = tp->t_flags & TF_NODELAY;
391 goto setval;
392 case TCP_MAXSEG:
393 optval = tp->t_peermss;
394 goto setval;
395 case TCP_INFO:
396 tcp_fill_info(tp, &ti);
397 error = sockopt_set(sopt, &ti, sizeof ti);
398 break;
399 #ifdef notyet
400 case TCP_CONGCTL:
401 break;
402 #endif
403 case TCP_KEEPIDLE:
404 optval = tp->t_keepidle;
405 goto setval;
406 case TCP_KEEPINTVL:
407 optval = tp->t_keepintvl;
408 goto setval;
409 case TCP_KEEPCNT:
410 optval = tp->t_keepcnt;
411 goto setval;
412 case TCP_KEEPINIT:
413 optval = tp->t_keepinit;
414 setval: error = sockopt_set(sopt, &optval, sizeof(optval));
415 break;
416 default:
417 error = ENOPROTOOPT;
418 break;
419 }
420 break;
421 }
422 splx(s);
423 return error;
424 }
425
426 #ifndef TCP_SENDSPACE
427 #define TCP_SENDSPACE 1024*32
428 #endif
429 int tcp_sendspace = TCP_SENDSPACE;
430 #ifndef TCP_RECVSPACE
431 #define TCP_RECVSPACE 1024*32
432 #endif
433 int tcp_recvspace = TCP_RECVSPACE;
434
435 /*
436 * tcp_attach: attach TCP protocol to socket, allocating internet protocol
437 * control block, TCP control block, buffer space and entering LISTEN state
438 * if to accept connections.
439 */
440 static int
441 tcp_attach(struct socket *so, int proto)
442 {
443 struct tcpcb *tp;
444 struct inpcb *inp;
445 int s, error, family;
446
447 /* Assign the lock (must happen even if we will error out). */
448 s = splsoftnet();
449 sosetlock(so);
450 KASSERT(solocked(so));
451 KASSERT(sotoinpcb(so) == NULL);
452
453 inp = sotoinpcb(so);
454 KASSERT(inp == NULL);
455
456 family = soaf(so);
457
458 #ifdef MBUFTRACE
459 so->so_mowner = &tcp_sock_mowner;
460 so->so_rcv.sb_mowner = &tcp_sock_rx_mowner;
461 so->so_snd.sb_mowner = &tcp_sock_tx_mowner;
462 #endif
463 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
464 error = soreserve(so, tcp_sendspace, tcp_recvspace);
465 if (error)
466 goto out;
467 }
468
469 so->so_rcv.sb_flags |= SB_AUTOSIZE;
470 so->so_snd.sb_flags |= SB_AUTOSIZE;
471
472 error = in_pcballoc(so, &tcbtable);
473 if (error)
474 goto out;
475 inp = sotoinpcb(so);
476
477 tp = tcp_newtcpcb(family, inp);
478 if (tp == NULL) {
479 int nofd = so->so_state & SS_NOFDREF; /* XXX */
480
481 so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
482 in_pcbdetach(inp);
483 so->so_state |= nofd;
484 error = ENOBUFS;
485 goto out;
486 }
487 tp->t_state = TCPS_CLOSED;
488 if ((so->so_options & SO_LINGER) && so->so_linger == 0) {
489 so->so_linger = TCP_LINGERTIME;
490 }
491 out:
492 KASSERT(solocked(so));
493 splx(s);
494 return error;
495 }
496
497 static void
498 tcp_detach(struct socket *so)
499 {
500 struct inpcb *inp;
501 struct tcpcb *tp;
502 int s;
503
504 inp = sotoinpcb(so);
505 tp = intotcpcb(inp);
506
507 s = splsoftnet();
508 (void)tcp_disconnect1(tp);
509 splx(s);
510 }
511
512 static int
513 tcp_accept(struct socket *so, struct sockaddr *nam)
514 {
515 struct inpcb *inp;
516 struct tcpcb *tp;
517 int ostate = 0;
518 int s;
519
520 inp = sotoinpcb(so);
521 tp = intotcpcb(inp);
522
523 ostate = tcp_debug_capture(tp, PRU_ACCEPT);
524
525 /*
526 * Accept a connection. Essentially all the work is
527 * done at higher levels; just return the address
528 * of the peer, storing through addr.
529 */
530 s = splsoftnet();
531 if (inp->inp_af == AF_INET) {
532 in_setpeeraddr(inp, (struct sockaddr_in *)nam);
533 }
534 #ifdef INET6
535 else if (inp->inp_af == AF_INET6) {
536 in6_setpeeraddr(inp, (struct sockaddr_in6 *)nam);
537 }
538 #endif
539 tcp_debug_trace(so, tp, ostate, PRU_ACCEPT);
540 splx(s);
541
542 return 0;
543 }
544
545 static int
546 tcp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
547 {
548 struct inpcb *inp = NULL;
549 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
550 #ifdef INET6
551 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
552 #endif /* INET6 */
553 struct tcpcb *tp;
554 int s;
555 int error = 0;
556 int ostate = 0;
557
558 inp = sotoinpcb(so);
559 tp = intotcpcb(inp);
560
561 ostate = tcp_debug_capture(tp, PRU_BIND);
562
563 /*
564 * Give the socket an address.
565 */
566 s = splsoftnet();
567 switch (so->so_proto->pr_domain->dom_family) {
568 case PF_INET:
569 error = in_pcbbind(inp, sin, l);
570 break;
571 #ifdef INET6
572 case PF_INET6:
573 error = in6_pcbbind(inp, sin6, l);
574 if (!error) {
575 /* mapped addr case */
576 if (IN6_IS_ADDR_V4MAPPED(&inp->inp_laddr6))
577 tp->t_family = AF_INET;
578 else
579 tp->t_family = AF_INET6;
580 }
581 break;
582 #endif
583 }
584 tcp_debug_trace(so, tp, ostate, PRU_BIND);
585 splx(s);
586
587 return error;
588 }
589
590 static int
591 tcp_listen(struct socket *so, struct lwp *l)
592 {
593 struct inpcb *inp;
594 struct tcpcb *tp;
595 int error = 0;
596 int ostate = 0;
597 int s;
598
599 inp = sotoinpcb(so);
600 tp = intotcpcb(inp);
601
602 ostate = tcp_debug_capture(tp, PRU_LISTEN);
603
604 /*
605 * Prepare to accept connections.
606 */
607 s = splsoftnet();
608 if (inp->inp_af == AF_INET && inp->inp_lport == 0) {
609 error = in_pcbbind(inp, NULL, l);
610 if (error)
611 goto release;
612 }
613 #ifdef INET6
614 if (inp->inp_af == AF_INET6 && inp->inp_lport == 0) {
615 error = in6_pcbbind(inp, NULL, l);
616 if (error)
617 goto release;
618 }
619 #endif
620 tp->t_state = TCPS_LISTEN;
621
622 release:
623 tcp_debug_trace(so, tp, ostate, PRU_LISTEN);
624 splx(s);
625
626 return error;
627 }
628
629 static int
630 tcp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
631 {
632 struct inpcb *inp;
633 struct tcpcb *tp;
634 int s;
635 int error = 0;
636 int ostate = 0;
637
638 inp = sotoinpcb(so);
639 tp = intotcpcb(inp);
640
641 ostate = tcp_debug_capture(tp, PRU_CONNECT);
642
643 /*
644 * Initiate connection to peer.
645 * Create a template for use in transmissions on this connection.
646 * Enter SYN_SENT state, and mark socket as connecting.
647 * Start keep-alive timer, and seed output sequence space.
648 * Send initial segment on connection.
649 */
650 s = splsoftnet();
651
652 if (inp->inp_af == AF_INET) {
653 if (inp->inp_lport == 0) {
654 error = in_pcbbind(inp, NULL, l);
655 if (error)
656 goto release;
657 }
658 error = in_pcbconnect(inp, (struct sockaddr_in *)nam, l);
659 }
660 #ifdef INET6
661 if (inp->inp_af == AF_INET6) {
662 if (inp->inp_lport == 0) {
663 error = in6_pcbbind(inp, NULL, l);
664 if (error)
665 goto release;
666 }
667 error = in6_pcbconnect(inp, (struct sockaddr_in6 *)nam, l);
668 if (!error) {
669 /* mapped addr case */
670 if (IN6_IS_ADDR_V4MAPPED(&inp->inp_faddr6))
671 tp->t_family = AF_INET;
672 else
673 tp->t_family = AF_INET6;
674 }
675 }
676 #endif
677 if (error)
678 goto release;
679 tp->t_template = tcp_template(tp);
680 if (tp->t_template == 0) {
681 if (inp->inp_af == AF_INET)
682 in_pcbdisconnect(inp);
683 #ifdef INET6
684 else if (inp->inp_af == AF_INET6)
685 in6_pcbdisconnect(inp);
686 #endif
687 error = ENOBUFS;
688 goto release;
689 }
690 /*
691 * Compute window scaling to request.
692 * XXX: This should be moved to tcp_output().
693 */
694 while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
695 (TCP_MAXWIN << tp->request_r_scale) < sb_max)
696 tp->request_r_scale++;
697 soisconnecting(so);
698 TCP_STATINC(TCP_STAT_CONNATTEMPT);
699 tp->t_state = TCPS_SYN_SENT;
700 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
701 tp->iss = tcp_new_iss(tp);
702 tcp_sendseqinit(tp);
703 error = tcp_output(tp);
704
705 release:
706 tcp_debug_trace(so, tp, ostate, PRU_CONNECT);
707 splx(s);
708
709 return error;
710 }
711
712 static int
713 tcp_connect2(struct socket *so, struct socket *so2)
714 {
715 struct inpcb *inp;
716 struct tcpcb *tp;
717 int ostate = 0;
718
719 KASSERT(solocked(so));
720
721 inp = sotoinpcb(so);
722 tp = intotcpcb(inp);
723
724 ostate = tcp_debug_capture(tp, PRU_CONNECT2);
725
726 tcp_debug_trace(so, tp, ostate, PRU_CONNECT2);
727
728 return EOPNOTSUPP;
729 }
730
731 static int
732 tcp_disconnect(struct socket *so)
733 {
734 struct inpcb *inp;
735 struct tcpcb *tp;
736 int error = 0;
737 int ostate = 0;
738 int s;
739
740 inp = sotoinpcb(so);
741 tp = intotcpcb(inp);
742
743 ostate = tcp_debug_capture(tp, PRU_DISCONNECT);
744
745 /*
746 * Initiate disconnect from peer.
747 * If connection never passed embryonic stage, just drop;
748 * else if don't need to let data drain, then can just drop anyways,
749 * else have to begin TCP shutdown process: mark socket disconnecting,
750 * drain unread data, state switch to reflect user close, and
751 * send segment (e.g. FIN) to peer. Socket will be really disconnected
752 * when peer sends FIN and acks ours.
753 *
754 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
755 */
756 s = splsoftnet();
757 tp = tcp_disconnect1(tp);
758 tcp_debug_trace(so, tp, ostate, PRU_DISCONNECT);
759 splx(s);
760
761 return error;
762 }
763
764 static int
765 tcp_shutdown(struct socket *so)
766 {
767 struct inpcb *inp;
768 struct tcpcb *tp;
769 int error = 0;
770 int ostate = 0;
771 int s;
772
773 inp = sotoinpcb(so);
774 tp = intotcpcb(inp);
775
776 ostate = tcp_debug_capture(tp, PRU_SHUTDOWN);
777 /*
778 * Mark the connection as being incapable of further output.
779 */
780 s = splsoftnet();
781 socantsendmore(so);
782 tp = tcp_usrclosed(tp);
783 if (tp)
784 error = tcp_output(tp);
785 tcp_debug_trace(so, tp, ostate, PRU_SHUTDOWN);
786 splx(s);
787
788 return error;
789 }
790
791 static int
792 tcp_abort(struct socket *so)
793 {
794 struct inpcb *inp;
795 struct tcpcb *tp;
796 int error = 0;
797 int ostate = 0;
798 int s;
799
800 inp = sotoinpcb(so);
801 tp = intotcpcb(inp);
802
803 ostate = tcp_debug_capture(tp, PRU_ABORT);
804
805 /*
806 * Abort the TCP.
807 */
808 s = splsoftnet();
809 tp = tcp_drop(tp, ECONNABORTED);
810 tcp_debug_trace(so, tp, ostate, PRU_ABORT);
811 splx(s);
812
813 return error;
814 }
815
816 static int
817 tcp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
818 {
819 switch (so->so_proto->pr_domain->dom_family) {
820 case PF_INET:
821 return in_control(so, cmd, nam, ifp);
822 #ifdef INET6
823 case PF_INET6:
824 return in6_control(so, cmd, nam, ifp);
825 #endif
826 default:
827 return EAFNOSUPPORT;
828 }
829 }
830
831 static int
832 tcp_stat(struct socket *so, struct stat *ub)
833 {
834 KASSERT(solocked(so));
835
836 /* stat: don't bother with a blocksize. */
837 return 0;
838 }
839
840 static int
841 tcp_peeraddr(struct socket *so, struct sockaddr *nam)
842 {
843 struct inpcb *inp;
844 struct tcpcb *tp;
845 int ostate = 0;
846 int s;
847
848 inp = sotoinpcb(so);
849 tp = intotcpcb(inp);
850
851 ostate = tcp_debug_capture(tp, PRU_PEERADDR);
852
853 s = splsoftnet();
854 if (inp->inp_af == AF_INET) {
855 in_setpeeraddr(inp, (struct sockaddr_in *)nam);
856 }
857 #ifdef INET6
858 else if (inp->inp_af == AF_INET6) {
859 in6_setpeeraddr(inp, (struct sockaddr_in6 *)nam);
860 }
861 #endif
862 tcp_debug_trace(so, tp, ostate, PRU_PEERADDR);
863 splx(s);
864
865 return 0;
866 }
867
868 static int
869 tcp_sockaddr(struct socket *so, struct sockaddr *nam)
870 {
871 struct inpcb *inp;
872 struct tcpcb *tp;
873 int ostate = 0;
874 int s;
875
876 inp = sotoinpcb(so);
877 tp = intotcpcb(inp);
878
879 ostate = tcp_debug_capture(tp, PRU_SOCKADDR);
880
881 s = splsoftnet();
882 if (inp->inp_af == AF_INET) {
883 in_setsockaddr(inp, (struct sockaddr_in *)nam);
884 }
885 #ifdef INET6
886 if (inp->inp_af == AF_INET6) {
887 in6_setsockaddr(inp, (struct sockaddr_in6 *)nam);
888 }
889 #endif
890 tcp_debug_trace(so, tp, ostate, PRU_SOCKADDR);
891 splx(s);
892
893 return 0;
894 }
895
896 static int
897 tcp_rcvd(struct socket *so, int flags, struct lwp *l)
898 {
899 struct inpcb *inp;
900 struct tcpcb *tp;
901 int ostate = 0;
902 int s;
903
904 inp = sotoinpcb(so);
905 tp = intotcpcb(inp);
906
907 ostate = tcp_debug_capture(tp, PRU_RCVD);
908
909 /*
910 * After a receive, possibly send window update to peer.
911 *
912 * soreceive() calls this function when a user receives
913 * ancillary data on a listening socket. We don't call
914 * tcp_output in such a case, since there is no header
915 * template for a listening socket and hence the kernel
916 * will panic.
917 */
918 s = splsoftnet();
919 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) != 0)
920 (void) tcp_output(tp);
921 splx(s);
922
923 tcp_debug_trace(so, tp, ostate, PRU_RCVD);
924
925 return 0;
926 }
927
928 static int
929 tcp_recvoob(struct socket *so, struct mbuf *m, int flags)
930 {
931 struct inpcb *inp;
932 struct tcpcb *tp;
933 int ostate = 0;
934 int s;
935
936 inp = sotoinpcb(so);
937 tp = intotcpcb(inp);
938
939 ostate = tcp_debug_capture(tp, PRU_RCVOOB);
940
941 s = splsoftnet();
942 if ((so->so_oobmark == 0 &&
943 (so->so_state & SS_RCVATMARK) == 0) ||
944 so->so_options & SO_OOBINLINE ||
945 tp->t_oobflags & TCPOOB_HADDATA) {
946 splx(s);
947 return EINVAL;
948 }
949
950 if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
951 splx(s);
952 return EWOULDBLOCK;
953 }
954
955 m->m_len = 1;
956 *mtod(m, char *) = tp->t_iobc;
957 if ((flags & MSG_PEEK) == 0) {
958 tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
959 so->so_state &= ~SS_POLLRDBAND;
960 }
961
962 tcp_debug_trace(so, tp, ostate, PRU_RCVOOB);
963 splx(s);
964
965 return 0;
966 }
967
968 static int
969 tcp_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
970 struct mbuf *control, struct lwp *l)
971 {
972 struct inpcb *inp;
973 struct tcpcb *tp;
974 int ostate = 0;
975 int error = 0;
976 int s;
977
978 inp = sotoinpcb(so);
979 tp = intotcpcb(inp);
980
981 ostate = tcp_debug_capture(tp, PRU_SEND);
982
983 /*
984 * Do a send by putting data in output queue and updating urgent
985 * marker if URG set. Possibly send more data.
986 */
987 s = splsoftnet();
988 if (control && control->m_len) {
989 m_freem(control);
990 m_freem(m);
991 tcp_debug_trace(so, tp, ostate, PRU_SEND);
992 splx(s);
993 return EINVAL;
994 }
995
996 sbappendstream(&so->so_snd, m);
997 error = tcp_output(tp);
998 tcp_debug_trace(so, tp, ostate, PRU_SEND);
999 splx(s);
1000
1001 return error;
1002 }
1003
1004 static int
1005 tcp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
1006 {
1007 struct inpcb *inp = NULL;
1008 struct tcpcb *tp = NULL;
1009 int ostate = 0;
1010 int error = 0;
1011 int s;
1012
1013 inp = sotoinpcb(so);
1014 tp = intotcpcb(inp);
1015 if (tp->t_template == NULL) {
1016 /*
1017 * XXX FreeBSD appears to open the connection
1018 * automagically in this case, but the socket address
1019 * isn't passed through here so we can't do that.
1020 */
1021 m_freem(m);
1022 m_freem(control);
1023 return ENOTCONN;
1024 }
1025
1026 ostate = tcp_debug_capture(tp, PRU_SENDOOB);
1027
1028 s = splsoftnet();
1029 if (sbspace_oob(&so->so_snd) == 0) {
1030 m_freem(m);
1031 m_freem(control);
1032 splx(s);
1033 return ENOBUFS;
1034 }
1035 /*
1036 * According to RFC961 (Assigned Protocols),
1037 * the urgent pointer points to the last octet
1038 * of urgent data. We continue, however,
1039 * to consider it to indicate the first octet
1040 * of data past the urgent section.
1041 * Otherwise, snd_up should be one lower.
1042 */
1043 sbappendstream(&so->so_snd, m);
1044 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
1045 tp->t_force = 1;
1046 error = tcp_output(tp);
1047 tp->t_force = 0;
1048 tcp_debug_trace(so, tp, ostate, PRU_SENDOOB);
1049 splx(s);
1050 m_freem(control);
1051
1052 return error;
1053 }
1054
1055 static int
1056 tcp_purgeif(struct socket *so, struct ifnet *ifp)
1057 {
1058 int s;
1059 int error = 0;
1060
1061 s = splsoftnet();
1062
1063 mutex_enter(softnet_lock);
1064 switch (so->so_proto->pr_domain->dom_family) {
1065 case PF_INET:
1066 in_pcbpurgeif0(&tcbtable, ifp);
1067 #ifdef NET_MPSAFE
1068 mutex_exit(softnet_lock);
1069 #endif
1070 in_purgeif(ifp);
1071 #ifdef NET_MPSAFE
1072 mutex_enter(softnet_lock);
1073 #endif
1074 in_pcbpurgeif(&tcbtable, ifp);
1075 break;
1076 #ifdef INET6
1077 case PF_INET6:
1078 in6_pcbpurgeif0(&tcbtable, ifp);
1079 #ifdef NET_MPSAFE
1080 mutex_exit(softnet_lock);
1081 #endif
1082 in6_purgeif(ifp);
1083 #ifdef NET_MPSAFE
1084 mutex_enter(softnet_lock);
1085 #endif
1086 in6_pcbpurgeif(&tcbtable, ifp);
1087 break;
1088 #endif
1089 default:
1090 error = EAFNOSUPPORT;
1091 break;
1092 }
1093 mutex_exit(softnet_lock);
1094 splx(s);
1095
1096 return error;
1097 }
1098
1099 /*
1100 * Initiate (or continue) disconnect.
1101 * If embryonic state, just send reset (once).
1102 * If in ``let data drain'' option and linger null, just drop.
1103 * Otherwise (hard), mark socket disconnecting and drop
1104 * current input data; switch states based on user close, and
1105 * send segment to peer (with FIN).
1106 */
1107 struct tcpcb *
1108 tcp_disconnect1(struct tcpcb *tp)
1109 {
1110 struct socket *so;
1111
1112 so = tp->t_inpcb->inp_socket;
1113
1114 if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
1115 tp = tcp_close(tp);
1116 else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
1117 tp = tcp_drop(tp, 0);
1118 else {
1119 soisdisconnecting(so);
1120 sbflush(&so->so_rcv);
1121 tp = tcp_usrclosed(tp);
1122 if (tp)
1123 (void) tcp_output(tp);
1124 }
1125 return tp;
1126 }
1127
1128 /*
1129 * User issued close, and wish to trail through shutdown states:
1130 * if never received SYN, just forget it. If got a SYN from peer,
1131 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
1132 * If already got a FIN from peer, then almost done; go to LAST_ACK
1133 * state. In all other cases, have already sent FIN to peer (e.g.
1134 * after PRU_SHUTDOWN), and just have to play tedious game waiting
1135 * for peer to send FIN or not respond to keep-alives, etc.
1136 * We can let the user exit from the close as soon as the FIN is acked.
1137 */
1138 struct tcpcb *
1139 tcp_usrclosed(struct tcpcb *tp)
1140 {
1141
1142 switch (tp->t_state) {
1143
1144 case TCPS_CLOSED:
1145 case TCPS_LISTEN:
1146 case TCPS_SYN_SENT:
1147 tp->t_state = TCPS_CLOSED;
1148 tp = tcp_close(tp);
1149 break;
1150
1151 case TCPS_SYN_RECEIVED:
1152 case TCPS_ESTABLISHED:
1153 tp->t_state = TCPS_FIN_WAIT_1;
1154 break;
1155
1156 case TCPS_CLOSE_WAIT:
1157 tp->t_state = TCPS_LAST_ACK;
1158 break;
1159 }
1160 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
1161 struct socket *so = tp->t_inpcb->inp_socket;
1162 if (so)
1163 soisdisconnected(so);
1164 /*
1165 * If we are in FIN_WAIT_2, we arrived here because the
1166 * application did a shutdown of the send side. Like the
1167 * case of a transition from FIN_WAIT_1 to FIN_WAIT_2 after
1168 * a full close, we start a timer to make sure sockets are
1169 * not left in FIN_WAIT_2 forever.
1170 */
1171 if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0))
1172 TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
1173 else if (tp->t_state == TCPS_TIME_WAIT
1174 && ((tp->t_inpcb->inp_af == AF_INET
1175 && (tcp4_vtw_enable & 1)
1176 && vtw_add(AF_INET, tp))
1177 ||
1178 (tp->t_inpcb->inp_af == AF_INET6
1179 && (tcp6_vtw_enable & 1)
1180 && vtw_add(AF_INET6, tp)))) {
1181 tp = 0;
1182 }
1183 }
1184 return tp;
1185 }
1186
1187 /*
1188 * sysctl helper routine for net.inet.ip.mssdflt. it can't be less
1189 * than 32.
1190 */
1191 static int
1192 sysctl_net_inet_tcp_mssdflt(SYSCTLFN_ARGS)
1193 {
1194 int error, mssdflt;
1195 struct sysctlnode node;
1196
1197 mssdflt = tcp_mssdflt;
1198 node = *rnode;
1199 node.sysctl_data = &mssdflt;
1200 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1201 if (error || newp == NULL)
1202 return error;
1203
1204 if (mssdflt < 32)
1205 return EINVAL;
1206 tcp_mssdflt = mssdflt;
1207
1208 mutex_enter(softnet_lock);
1209 tcp_tcpcb_template();
1210 mutex_exit(softnet_lock);
1211
1212 return 0;
1213 }
1214
1215 /*
1216 * sysctl helper for TCP CB template update
1217 */
1218 static int
1219 sysctl_update_tcpcb_template(SYSCTLFN_ARGS)
1220 {
1221 int t, error;
1222 struct sysctlnode node;
1223
1224 /* follow procedures in sysctl(9) manpage */
1225 t = *(int *)rnode->sysctl_data;
1226 node = *rnode;
1227 node.sysctl_data = &t;
1228 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1229 if (error || newp == NULL)
1230 return error;
1231
1232 if (t < 0)
1233 return EINVAL;
1234
1235 *(int *)rnode->sysctl_data = t;
1236
1237 mutex_enter(softnet_lock);
1238 tcp_tcpcb_template();
1239 mutex_exit(softnet_lock);
1240
1241 return 0;
1242 }
1243
1244 /*
1245 * sysctl helper routine for setting port related values under
1246 * net.inet.ip and net.inet6.ip6. does basic range checking and does
1247 * additional checks for each type. this code has placed in
1248 * tcp_input.c since INET and INET6 both use the same tcp code.
1249 *
1250 * this helper is not static so that both inet and inet6 can use it.
1251 */
1252 int
1253 sysctl_net_inet_ip_ports(SYSCTLFN_ARGS)
1254 {
1255 int error, tmp;
1256 int apmin, apmax;
1257 #ifndef IPNOPRIVPORTS
1258 int lpmin, lpmax;
1259 #endif /* IPNOPRIVPORTS */
1260 struct sysctlnode node;
1261
1262 if (namelen != 0)
1263 return EINVAL;
1264
1265 switch (name[-3]) {
1266 case PF_INET:
1267 apmin = anonportmin;
1268 apmax = anonportmax;
1269 #ifndef IPNOPRIVPORTS
1270 lpmin = lowportmin;
1271 lpmax = lowportmax;
1272 #endif /* IPNOPRIVPORTS */
1273 break;
1274 #ifdef INET6
1275 case PF_INET6:
1276 apmin = ip6_anonportmin;
1277 apmax = ip6_anonportmax;
1278 #ifndef IPNOPRIVPORTS
1279 lpmin = ip6_lowportmin;
1280 lpmax = ip6_lowportmax;
1281 #endif /* IPNOPRIVPORTS */
1282 break;
1283 #endif /* INET6 */
1284 default:
1285 return EINVAL;
1286 }
1287
1288 /*
1289 * insert temporary copy into node, perform lookup on
1290 * temporary, then restore pointer
1291 */
1292 node = *rnode;
1293 tmp = *(int*)rnode->sysctl_data;
1294 node.sysctl_data = &tmp;
1295 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1296 if (error || newp == NULL)
1297 return error;
1298
1299 /*
1300 * simple port range check
1301 */
1302 if (tmp < 0 || tmp > 65535)
1303 return EINVAL;
1304
1305 /*
1306 * per-node range checks
1307 */
1308 switch (rnode->sysctl_num) {
1309 case IPCTL_ANONPORTMIN:
1310 case IPV6CTL_ANONPORTMIN:
1311 if (tmp >= apmax)
1312 return EINVAL;
1313 #ifndef IPNOPRIVPORTS
1314 if (tmp < IPPORT_RESERVED)
1315 return EINVAL;
1316 #endif /* IPNOPRIVPORTS */
1317 break;
1318
1319 case IPCTL_ANONPORTMAX:
1320 case IPV6CTL_ANONPORTMAX:
1321 if (apmin >= tmp)
1322 return EINVAL;
1323 #ifndef IPNOPRIVPORTS
1324 if (tmp < IPPORT_RESERVED)
1325 return EINVAL;
1326 #endif /* IPNOPRIVPORTS */
1327 break;
1328
1329 #ifndef IPNOPRIVPORTS
1330 case IPCTL_LOWPORTMIN:
1331 case IPV6CTL_LOWPORTMIN:
1332 if (tmp >= lpmax ||
1333 tmp > IPPORT_RESERVEDMAX ||
1334 tmp < IPPORT_RESERVEDMIN)
1335 return EINVAL;
1336 break;
1337
1338 case IPCTL_LOWPORTMAX:
1339 case IPV6CTL_LOWPORTMAX:
1340 if (lpmin >= tmp ||
1341 tmp > IPPORT_RESERVEDMAX ||
1342 tmp < IPPORT_RESERVEDMIN)
1343 return EINVAL;
1344 break;
1345 #endif /* IPNOPRIVPORTS */
1346
1347 default:
1348 return EINVAL;
1349 }
1350
1351 *(int*)rnode->sysctl_data = tmp;
1352
1353 return 0;
1354 }
1355
1356 static inline int
1357 copyout_uid(struct socket *sockp, void *oldp, size_t *oldlenp)
1358 {
1359 if (oldp) {
1360 size_t sz;
1361 uid_t uid;
1362 int error;
1363
1364 if (sockp->so_cred == NULL)
1365 return EPERM;
1366
1367 uid = kauth_cred_geteuid(sockp->so_cred);
1368 sz = MIN(sizeof(uid), *oldlenp);
1369 if ((error = copyout(&uid, oldp, sz)) != 0)
1370 return error;
1371 }
1372 *oldlenp = sizeof(uid_t);
1373 return 0;
1374 }
1375
1376 static inline int
1377 inet4_ident_core(struct in_addr raddr, u_int rport,
1378 struct in_addr laddr, u_int lport,
1379 void *oldp, size_t *oldlenp,
1380 struct lwp *l, int dodrop)
1381 {
1382 struct inpcb *inp;
1383 struct socket *sockp;
1384
1385 inp = in_pcblookup_connect(&tcbtable, raddr, rport, laddr, lport, 0);
1386
1387 if (inp == NULL || (sockp = inp->inp_socket) == NULL)
1388 return ESRCH;
1389
1390 if (dodrop) {
1391 struct tcpcb *tp;
1392 int error;
1393
1394 if (inp == NULL || (tp = intotcpcb(inp)) == NULL ||
1395 (inp->inp_socket->so_options & SO_ACCEPTCONN) != 0)
1396 return ESRCH;
1397
1398 error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
1399 KAUTH_REQ_NETWORK_SOCKET_DROP, inp->inp_socket, tp, NULL);
1400 if (error)
1401 return error;
1402
1403 (void)tcp_drop(tp, ECONNABORTED);
1404 return 0;
1405 }
1406
1407 return copyout_uid(sockp, oldp, oldlenp);
1408 }
1409
1410 #ifdef INET6
1411 static inline int
1412 inet6_ident_core(struct in6_addr *raddr, u_int rport,
1413 struct in6_addr *laddr, u_int lport,
1414 void *oldp, size_t *oldlenp,
1415 struct lwp *l, int dodrop)
1416 {
1417 struct inpcb *inp;
1418 struct socket *sockp;
1419
1420 inp = in6_pcblookup_connect(&tcbtable, raddr, rport, laddr, lport, 0, 0);
1421
1422 if (inp == NULL || (sockp = inp->inp_socket) == NULL)
1423 return ESRCH;
1424
1425 if (dodrop) {
1426 struct tcpcb *tp;
1427 int error;
1428
1429 if (inp == NULL || (tp = intotcpcb(inp)) == NULL ||
1430 (inp->inp_socket->so_options & SO_ACCEPTCONN) != 0)
1431 return ESRCH;
1432
1433 error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
1434 KAUTH_REQ_NETWORK_SOCKET_DROP, inp->inp_socket, tp, NULL);
1435 if (error)
1436 return error;
1437
1438 (void)tcp_drop(tp, ECONNABORTED);
1439 return 0;
1440 }
1441
1442 return copyout_uid(sockp, oldp, oldlenp);
1443 }
1444 #endif
1445
1446 /*
1447 * sysctl helper routine for the net.inet.tcp.drop and
1448 * net.inet6.tcp6.drop nodes.
1449 */
1450 #define sysctl_net_inet_tcp_drop sysctl_net_inet_tcp_ident
1451
1452 /*
1453 * sysctl helper routine for the net.inet.tcp.ident and
1454 * net.inet6.tcp6.ident nodes. contains backwards compat code for the
1455 * old way of looking up the ident information for ipv4 which involves
1456 * stuffing the port/addr pairs into the mib lookup.
1457 */
1458 static int
1459 sysctl_net_inet_tcp_ident(SYSCTLFN_ARGS)
1460 {
1461 struct sockaddr_in *si4[2];
1462 #ifdef INET6
1463 struct sockaddr_in6 *si6[2];
1464 #endif
1465 struct sockaddr_storage sa[2];
1466 int error, pf, dodrop;
1467
1468 dodrop = name[-1] == TCPCTL_DROP;
1469 if (dodrop) {
1470 if (oldp != NULL || *oldlenp != 0)
1471 return EINVAL;
1472 if (newp == NULL)
1473 return EPERM;
1474 if (newlen < sizeof(sa))
1475 return ENOMEM;
1476 }
1477 if (namelen != 4 && namelen != 0)
1478 return EINVAL;
1479 if (name[-2] != IPPROTO_TCP)
1480 return EINVAL;
1481 pf = name[-3];
1482
1483 /* old style lookup, ipv4 only */
1484 if (namelen == 4) {
1485 struct in_addr laddr, raddr;
1486 u_int lport, rport;
1487
1488 if (pf != PF_INET)
1489 return EPROTONOSUPPORT;
1490 raddr.s_addr = (uint32_t)name[0];
1491 rport = (u_int)name[1];
1492 laddr.s_addr = (uint32_t)name[2];
1493 lport = (u_int)name[3];
1494
1495 mutex_enter(softnet_lock);
1496 error = inet4_ident_core(raddr, rport, laddr, lport,
1497 oldp, oldlenp, l, dodrop);
1498 mutex_exit(softnet_lock);
1499 return error;
1500 }
1501
1502 if (newp == NULL || newlen != sizeof(sa))
1503 return EINVAL;
1504 error = copyin(newp, &sa, newlen);
1505 if (error)
1506 return error;
1507
1508 /*
1509 * requested families must match
1510 */
1511 if (pf != sa[0].ss_family || sa[0].ss_family != sa[1].ss_family)
1512 return EINVAL;
1513
1514 switch (pf) {
1515 #ifdef INET6
1516 case PF_INET6:
1517 si6[0] = (struct sockaddr_in6*)&sa[0];
1518 si6[1] = (struct sockaddr_in6*)&sa[1];
1519 if (si6[0]->sin6_len != sizeof(*si6[0]) ||
1520 si6[1]->sin6_len != sizeof(*si6[1]))
1521 return EINVAL;
1522
1523 if (!IN6_IS_ADDR_V4MAPPED(&si6[0]->sin6_addr) &&
1524 !IN6_IS_ADDR_V4MAPPED(&si6[1]->sin6_addr)) {
1525 error = sa6_embedscope(si6[0], ip6_use_defzone);
1526 if (error)
1527 return error;
1528 error = sa6_embedscope(si6[1], ip6_use_defzone);
1529 if (error)
1530 return error;
1531
1532 mutex_enter(softnet_lock);
1533 error = inet6_ident_core(&si6[0]->sin6_addr,
1534 si6[0]->sin6_port, &si6[1]->sin6_addr,
1535 si6[1]->sin6_port, oldp, oldlenp, l, dodrop);
1536 mutex_exit(softnet_lock);
1537 return error;
1538 }
1539
1540 if (IN6_IS_ADDR_V4MAPPED(&si6[0]->sin6_addr) !=
1541 IN6_IS_ADDR_V4MAPPED(&si6[1]->sin6_addr))
1542 return EINVAL;
1543
1544 in6_sin6_2_sin_in_sock((struct sockaddr *)&sa[0]);
1545 in6_sin6_2_sin_in_sock((struct sockaddr *)&sa[1]);
1546 #endif /* INET6 */
1547 /*FALLTHROUGH*/
1548 case PF_INET:
1549 si4[0] = (struct sockaddr_in*)&sa[0];
1550 si4[1] = (struct sockaddr_in*)&sa[1];
1551 if (si4[0]->sin_len != sizeof(*si4[0]) ||
1552 si4[0]->sin_len != sizeof(*si4[1]))
1553 return EINVAL;
1554
1555 mutex_enter(softnet_lock);
1556 error = inet4_ident_core(si4[0]->sin_addr, si4[0]->sin_port,
1557 si4[1]->sin_addr, si4[1]->sin_port,
1558 oldp, oldlenp, l, dodrop);
1559 mutex_exit(softnet_lock);
1560 return error;
1561 default:
1562 return EPROTONOSUPPORT;
1563 }
1564 }
1565
1566 /*
1567 * sysctl helper for the inet and inet6 pcblists. handles tcp/udp and
1568 * inet/inet6, as well as raw pcbs for each. specifically not
1569 * declared static so that raw sockets and udp/udp6 can use it as
1570 * well.
1571 */
1572 int
1573 sysctl_inpcblist(SYSCTLFN_ARGS)
1574 {
1575 const bool allowaddr = get_expose_address(curproc);
1576 struct sockaddr_in *in;
1577 const struct inpcb *inp;
1578 #ifdef INET6
1579 struct sockaddr_in6 *in6;
1580 #endif
1581 struct inpcbtable *pcbtbl = __UNCONST(rnode->sysctl_data);
1582 struct tcpcb *tp;
1583 struct kinfo_pcb pcb;
1584 char *dp;
1585 size_t len, needed, elem_size, out_size;
1586 int error, elem_count, pf, proto, pf2;
1587
1588 if (namelen != 4)
1589 return EINVAL;
1590
1591 if (oldp != NULL) {
1592 len = *oldlenp;
1593 elem_size = name[2];
1594 elem_count = name[3];
1595 if (elem_size != sizeof(pcb))
1596 return EINVAL;
1597 } else {
1598 len = 0;
1599 elem_count = INT_MAX;
1600 elem_size = sizeof(pcb);
1601 }
1602 error = 0;
1603 dp = oldp;
1604 out_size = elem_size;
1605 needed = 0;
1606
1607 if (namelen == 1 && name[0] == CTL_QUERY)
1608 return (sysctl_query(SYSCTLFN_CALL(rnode)));
1609
1610 if (name - oname != 4)
1611 return EINVAL;
1612
1613 pf = oname[1];
1614 proto = oname[2];
1615 pf2 = (oldp != NULL) ? pf : 0;
1616
1617 mutex_enter(softnet_lock);
1618
1619 TAILQ_FOREACH(inp, &pcbtbl->inpt_queue, inp_queue) {
1620 if (inp->inp_af != pf)
1621 continue;
1622
1623 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
1624 KAUTH_REQ_NETWORK_SOCKET_CANSEE, inp->inp_socket, NULL,
1625 NULL) != 0)
1626 continue;
1627
1628 memset(&pcb, 0, sizeof(pcb));
1629
1630 pcb.ki_family = pf;
1631 pcb.ki_type = proto;
1632
1633 switch (pf2) {
1634 case 0:
1635 /* just probing for size */
1636 break;
1637 case PF_INET:
1638 pcb.ki_family = inp->inp_socket->so_proto->
1639 pr_domain->dom_family;
1640 pcb.ki_type = inp->inp_socket->so_proto->
1641 pr_type;
1642 pcb.ki_protocol = inp->inp_socket->so_proto->
1643 pr_protocol;
1644 pcb.ki_pflags = inp->inp_flags;
1645
1646 pcb.ki_sostate = inp->inp_socket->so_state;
1647 pcb.ki_prstate = inp->inp_state;
1648 if (proto == IPPROTO_TCP) {
1649 tp = intotcpcb(inp);
1650 pcb.ki_tstate = tp->t_state;
1651 pcb.ki_tflags = tp->t_flags;
1652 }
1653
1654 COND_SET_VALUE(pcb.ki_pcbaddr,
1655 PTRTOUINT64(inp), allowaddr);
1656 COND_SET_VALUE(pcb.ki_ppcbaddr,
1657 PTRTOUINT64(inp->inp_ppcb), allowaddr);
1658 COND_SET_VALUE(pcb.ki_sockaddr,
1659 PTRTOUINT64(inp->inp_socket), allowaddr);
1660
1661 pcb.ki_rcvq = inp->inp_socket->so_rcv.sb_cc;
1662 pcb.ki_sndq = inp->inp_socket->so_snd.sb_cc;
1663
1664 in = satosin(&pcb.ki_src);
1665 in->sin_len = sizeof(*in);
1666 in->sin_family = pf;
1667 in->sin_port = inp->inp_lport;
1668 in->sin_addr = inp->inp_laddr;
1669 if (pcb.ki_prstate >= INP_CONNECTED) {
1670 in = satosin(&pcb.ki_dst);
1671 in->sin_len = sizeof(*in);
1672 in->sin_family = pf;
1673 in->sin_port = inp->inp_fport;
1674 in->sin_addr = inp->inp_faddr;
1675 }
1676 break;
1677 #ifdef INET6
1678 case PF_INET6:
1679 pcb.ki_family = inp->inp_socket->so_proto->
1680 pr_domain->dom_family;
1681 pcb.ki_type = inp->inp_socket->so_proto->pr_type;
1682 pcb.ki_protocol = inp->inp_socket->so_proto->
1683 pr_protocol;
1684 pcb.ki_pflags = inp->inp_flags;
1685
1686 pcb.ki_sostate = inp->inp_socket->so_state;
1687 pcb.ki_prstate = inp->inp_state;
1688 if (proto == IPPROTO_TCP) {
1689 tp = intotcpcb(inp);
1690 pcb.ki_tstate = tp->t_state;
1691 pcb.ki_tflags = tp->t_flags;
1692 }
1693
1694 COND_SET_VALUE(pcb.ki_pcbaddr,
1695 PTRTOUINT64(inp), allowaddr);
1696 COND_SET_VALUE(pcb.ki_ppcbaddr,
1697 PTRTOUINT64(inp->inp_ppcb), allowaddr);
1698 COND_SET_VALUE(pcb.ki_sockaddr,
1699 PTRTOUINT64(inp->inp_socket), allowaddr);
1700
1701 pcb.ki_rcvq = inp->inp_socket->so_rcv.sb_cc;
1702 pcb.ki_sndq = inp->inp_socket->so_snd.sb_cc;
1703
1704 in6 = satosin6(&pcb.ki_src);
1705 in6->sin6_len = sizeof(*in6);
1706 in6->sin6_family = pf;
1707 in6->sin6_port = inp->inp_lport;
1708 in6->sin6_flowinfo = inp->inp_flowinfo;
1709 in6->sin6_addr = inp->inp_laddr6;
1710 in6->sin6_scope_id = 0; /* XXX? */
1711
1712 if (pcb.ki_prstate >= INP_CONNECTED) {
1713 in6 = satosin6(&pcb.ki_dst);
1714 in6->sin6_len = sizeof(*in6);
1715 in6->sin6_family = pf;
1716 in6->sin6_port = inp->inp_fport;
1717 in6->sin6_flowinfo = inp->inp_flowinfo;
1718 in6->sin6_addr = inp->inp_faddr6;
1719 in6->sin6_scope_id = 0; /* XXX? */
1720 }
1721 break;
1722 #endif
1723 }
1724
1725 if (len >= elem_size && elem_count > 0) {
1726 error = copyout(&pcb, dp, out_size);
1727 if (error) {
1728 mutex_exit(softnet_lock);
1729 return error;
1730 }
1731 dp += elem_size;
1732 len -= elem_size;
1733 }
1734 needed += elem_size;
1735 if (elem_count > 0 && elem_count != INT_MAX)
1736 elem_count--;
1737 }
1738
1739 *oldlenp = needed;
1740 if (oldp == NULL)
1741 *oldlenp += PCB_SLOP * sizeof(struct kinfo_pcb);
1742
1743 mutex_exit(softnet_lock);
1744
1745 return error;
1746 }
1747
1748 static int
1749 sysctl_tcp_congctl(SYSCTLFN_ARGS)
1750 {
1751 struct sysctlnode node;
1752 int error;
1753 char newname[TCPCC_MAXLEN];
1754
1755 strlcpy(newname, tcp_congctl_global_name, sizeof(newname) - 1);
1756
1757 node = *rnode;
1758 node.sysctl_data = newname;
1759 node.sysctl_size = sizeof(newname);
1760
1761 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1762
1763 if (error ||
1764 newp == NULL ||
1765 strncmp(newname, tcp_congctl_global_name, sizeof(newname)) == 0)
1766 return error;
1767
1768 mutex_enter(softnet_lock);
1769 error = tcp_congctl_select(NULL, newname);
1770 mutex_exit(softnet_lock);
1771
1772 return error;
1773 }
1774
1775 static int
1776 sysctl_tcp_init_win(SYSCTLFN_ARGS)
1777 {
1778 int error;
1779 u_int iw;
1780 struct sysctlnode node;
1781
1782 iw = *(u_int *)rnode->sysctl_data;
1783 node = *rnode;
1784 node.sysctl_data = &iw;
1785 node.sysctl_size = sizeof(iw);
1786 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1787 if (error || newp == NULL)
1788 return error;
1789
1790 if (iw >= __arraycount(tcp_init_win_max))
1791 return EINVAL;
1792 *(u_int *)rnode->sysctl_data = iw;
1793 return 0;
1794 }
1795
1796 static int
1797 sysctl_tcp_keep(SYSCTLFN_ARGS)
1798 {
1799 int error;
1800 u_int tmp;
1801 struct sysctlnode node;
1802
1803 node = *rnode;
1804 tmp = *(u_int *)rnode->sysctl_data;
1805 node.sysctl_data = &tmp;
1806
1807 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1808 if (error || newp == NULL)
1809 return error;
1810
1811 if (!(tmp > 0 && tmp <= TCP_TIMER_MAXTICKS))
1812 return EINVAL;
1813
1814 mutex_enter(softnet_lock);
1815
1816 *(u_int *)rnode->sysctl_data = tmp;
1817 tcp_tcpcb_template(); /* update the template */
1818
1819 mutex_exit(softnet_lock);
1820 return 0;
1821 }
1822
1823 static int
1824 sysctl_net_inet_tcp_stats(SYSCTLFN_ARGS)
1825 {
1826
1827 return (NETSTAT_SYSCTL(tcpstat_percpu, TCP_NSTATS));
1828 }
1829
1830 /*
1831 * this (second stage) setup routine is a replacement for tcp_sysctl()
1832 * (which is currently used for ipv4 and ipv6)
1833 */
1834 static void
1835 sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
1836 const char *tcpname)
1837 {
1838 const struct sysctlnode *sack_node;
1839 const struct sysctlnode *abc_node;
1840 const struct sysctlnode *ecn_node;
1841 const struct sysctlnode *congctl_node;
1842 const struct sysctlnode *mslt_node;
1843 const struct sysctlnode *vtw_node;
1844 #ifdef TCP_DEBUG
1845 extern struct tcp_debug tcp_debug[TCP_NDEBUG];
1846 extern int tcp_debx;
1847 #endif
1848
1849 sysctl_createv(clog, 0, NULL, NULL,
1850 CTLFLAG_PERMANENT,
1851 CTLTYPE_NODE, pfname, NULL,
1852 NULL, 0, NULL, 0,
1853 CTL_NET, pf, CTL_EOL);
1854 sysctl_createv(clog, 0, NULL, NULL,
1855 CTLFLAG_PERMANENT,
1856 CTLTYPE_NODE, tcpname,
1857 SYSCTL_DESCR("TCP related settings"),
1858 NULL, 0, NULL, 0,
1859 CTL_NET, pf, IPPROTO_TCP, CTL_EOL);
1860
1861 sysctl_createv(clog, 0, NULL, NULL,
1862 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1863 CTLTYPE_INT, "rfc1323",
1864 SYSCTL_DESCR("Enable RFC1323 TCP extensions"),
1865 sysctl_update_tcpcb_template, 0, &tcp_do_rfc1323, 0,
1866 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RFC1323, CTL_EOL);
1867 sysctl_createv(clog, 0, NULL, NULL,
1868 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1869 CTLTYPE_INT, "sendspace",
1870 SYSCTL_DESCR("Default TCP send buffer size"),
1871 NULL, 0, &tcp_sendspace, 0,
1872 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SENDSPACE, CTL_EOL);
1873 sysctl_createv(clog, 0, NULL, NULL,
1874 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1875 CTLTYPE_INT, "recvspace",
1876 SYSCTL_DESCR("Default TCP receive buffer size"),
1877 NULL, 0, &tcp_recvspace, 0,
1878 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RECVSPACE, CTL_EOL);
1879 sysctl_createv(clog, 0, NULL, NULL,
1880 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1881 CTLTYPE_INT, "mssdflt",
1882 SYSCTL_DESCR("Default maximum segment size"),
1883 sysctl_net_inet_tcp_mssdflt, 0, &tcp_mssdflt, 0,
1884 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSSDFLT, CTL_EOL);
1885 sysctl_createv(clog, 0, NULL, NULL,
1886 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1887 CTLTYPE_INT, "minmss",
1888 SYSCTL_DESCR("Lower limit for TCP maximum segment size"),
1889 NULL, 0, &tcp_minmss, 0,
1890 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
1891 sysctl_createv(clog, 0, NULL, NULL,
1892 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1893 CTLTYPE_INT, "msl",
1894 SYSCTL_DESCR("Maximum Segment Life"),
1895 NULL, 0, &tcp_msl, 0,
1896 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSL, CTL_EOL);
1897 sysctl_createv(clog, 0, NULL, NULL,
1898 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1899 CTLTYPE_INT, "syn_cache_limit",
1900 SYSCTL_DESCR("Maximum number of entries in the TCP "
1901 "compressed state engine"),
1902 NULL, 0, &tcp_syn_cache_limit, 0,
1903 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_LIMIT,
1904 CTL_EOL);
1905 sysctl_createv(clog, 0, NULL, NULL,
1906 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1907 CTLTYPE_INT, "syn_bucket_limit",
1908 SYSCTL_DESCR("Maximum number of entries per hash "
1909 "bucket in the TCP compressed state "
1910 "engine"),
1911 NULL, 0, &tcp_syn_bucket_limit, 0,
1912 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_BUCKET_LIMIT,
1913 CTL_EOL);
1914 #if 0 /* obsoleted */
1915 sysctl_createv(clog, 0, NULL, NULL,
1916 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1917 CTLTYPE_INT, "syn_cache_interval",
1918 SYSCTL_DESCR("TCP compressed state engine's timer interval"),
1919 NULL, 0, &tcp_syn_cache_interval, 0,
1920 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_INTER,
1921 CTL_EOL);
1922 #endif
1923 sysctl_createv(clog, 0, NULL, NULL,
1924 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1925 CTLTYPE_INT, "init_win",
1926 SYSCTL_DESCR("Initial TCP congestion window"),
1927 sysctl_tcp_init_win, 0, &tcp_init_win, 0,
1928 CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN, CTL_EOL);
1929 sysctl_createv(clog, 0, NULL, NULL,
1930 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1931 CTLTYPE_INT, "mss_ifmtu",
1932 SYSCTL_DESCR("Use interface MTU for calculating MSS"),
1933 NULL, 0, &tcp_mss_ifmtu, 0,
1934 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSS_IFMTU, CTL_EOL);
1935 sysctl_createv(clog, 0, NULL, &sack_node,
1936 CTLFLAG_PERMANENT,
1937 CTLTYPE_NODE, "sack",
1938 SYSCTL_DESCR("RFC2018 Selective ACKnowledgement tunables"),
1939 NULL, 0, NULL, 0,
1940 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_EOL);
1941
1942 /* Congctl subtree */
1943 sysctl_createv(clog, 0, NULL, &congctl_node,
1944 CTLFLAG_PERMANENT,
1945 CTLTYPE_NODE, "congctl",
1946 SYSCTL_DESCR("TCP Congestion Control"),
1947 NULL, 0, NULL, 0,
1948 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
1949 sysctl_createv(clog, 0, &congctl_node, NULL,
1950 CTLFLAG_PERMANENT,
1951 CTLTYPE_STRING, "available",
1952 SYSCTL_DESCR("Available Congestion Control Mechanisms"),
1953 NULL, 0, tcp_congctl_avail, 0, CTL_CREATE, CTL_EOL);
1954 sysctl_createv(clog, 0, &congctl_node, NULL,
1955 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1956 CTLTYPE_STRING, "selected",
1957 SYSCTL_DESCR("Selected Congestion Control Mechanism"),
1958 sysctl_tcp_congctl, 0, NULL, TCPCC_MAXLEN,
1959 CTL_CREATE, CTL_EOL);
1960
1961 sysctl_createv(clog, 0, NULL, NULL,
1962 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1963 CTLTYPE_INT, "win_scale",
1964 SYSCTL_DESCR("Use RFC1323 window scale options"),
1965 sysctl_update_tcpcb_template, 0, &tcp_do_win_scale, 0,
1966 CTL_NET, pf, IPPROTO_TCP, TCPCTL_WSCALE, CTL_EOL);
1967 sysctl_createv(clog, 0, NULL, NULL,
1968 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1969 CTLTYPE_INT, "timestamps",
1970 SYSCTL_DESCR("Use RFC1323 time stamp options"),
1971 sysctl_update_tcpcb_template, 0, &tcp_do_timestamps, 0,
1972 CTL_NET, pf, IPPROTO_TCP, TCPCTL_TSTAMP, CTL_EOL);
1973 sysctl_createv(clog, 0, NULL, NULL,
1974 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1975 CTLTYPE_INT, "cwm",
1976 SYSCTL_DESCR("Hughes/Touch/Heidemann Congestion Window "
1977 "Monitoring"),
1978 NULL, 0, &tcp_cwm, 0,
1979 CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM, CTL_EOL);
1980 sysctl_createv(clog, 0, NULL, NULL,
1981 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1982 CTLTYPE_INT, "cwm_burstsize",
1983 SYSCTL_DESCR("Congestion Window Monitoring allowed "
1984 "burst count in packets"),
1985 NULL, 0, &tcp_cwm_burstsize, 0,
1986 CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM_BURSTSIZE,
1987 CTL_EOL);
1988 sysctl_createv(clog, 0, NULL, NULL,
1989 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1990 CTLTYPE_INT, "ack_on_push",
1991 SYSCTL_DESCR("Immediately return ACK when PSH is "
1992 "received"),
1993 NULL, 0, &tcp_ack_on_push, 0,
1994 CTL_NET, pf, IPPROTO_TCP, TCPCTL_ACK_ON_PUSH, CTL_EOL);
1995 sysctl_createv(clog, 0, NULL, NULL,
1996 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1997 CTLTYPE_INT, "keepidle",
1998 SYSCTL_DESCR("Allowed connection idle ticks before a "
1999 "keepalive probe is sent"),
2000 sysctl_tcp_keep, 0, &tcp_keepidle, 0,
2001 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPIDLE, CTL_EOL);
2002 sysctl_createv(clog, 0, NULL, NULL,
2003 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2004 CTLTYPE_INT, "keepintvl",
2005 SYSCTL_DESCR("Ticks before next keepalive probe is sent"),
2006 sysctl_tcp_keep, 0, &tcp_keepintvl, 0,
2007 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPINTVL, CTL_EOL);
2008 sysctl_createv(clog, 0, NULL, NULL,
2009 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2010 CTLTYPE_INT, "keepcnt",
2011 SYSCTL_DESCR("Number of keepalive probes to send"),
2012 sysctl_tcp_keep, 0, &tcp_keepcnt, 0,
2013 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPCNT, CTL_EOL);
2014 sysctl_createv(clog, 0, NULL, NULL,
2015 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
2016 CTLTYPE_INT, "slowhz",
2017 SYSCTL_DESCR("Keepalive ticks per second"),
2018 NULL, PR_SLOWHZ, NULL, 0,
2019 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SLOWHZ, CTL_EOL);
2020 sysctl_createv(clog, 0, NULL, NULL,
2021 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2022 CTLTYPE_INT, "log_refused",
2023 SYSCTL_DESCR("Log refused TCP connections"),
2024 NULL, 0, &tcp_log_refused, 0,
2025 CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOG_REFUSED, CTL_EOL);
2026 #if 0 /* obsoleted */
2027 sysctl_createv(clog, 0, NULL, NULL,
2028 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2029 CTLTYPE_INT, "rstratelimit", NULL,
2030 NULL, 0, &tcp_rst_ratelim, 0,
2031 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTRATELIMIT, CTL_EOL);
2032 #endif
2033 sysctl_createv(clog, 0, NULL, NULL,
2034 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2035 CTLTYPE_INT, "rstppslimit",
2036 SYSCTL_DESCR("Maximum number of RST packets to send "
2037 "per second"),
2038 NULL, 0, &tcp_rst_ppslim, 0,
2039 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTPPSLIMIT, CTL_EOL);
2040 sysctl_createv(clog, 0, NULL, NULL,
2041 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2042 CTLTYPE_INT, "delack_ticks",
2043 SYSCTL_DESCR("Number of ticks to delay sending an ACK"),
2044 NULL, 0, &tcp_delack_ticks, 0,
2045 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DELACK_TICKS, CTL_EOL);
2046 sysctl_createv(clog, 0, NULL, NULL,
2047 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2048 CTLTYPE_INT, "init_win_local",
2049 SYSCTL_DESCR("Initial TCP window size (in segments)"),
2050 sysctl_tcp_init_win, 0, &tcp_init_win_local, 0,
2051 CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN_LOCAL,
2052 CTL_EOL);
2053 sysctl_createv(clog, 0, NULL, NULL,
2054 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2055 CTLTYPE_STRUCT, "ident",
2056 SYSCTL_DESCR("RFC1413 Identification Protocol lookups"),
2057 sysctl_net_inet_tcp_ident, 0, NULL, sizeof(uid_t),
2058 CTL_NET, pf, IPPROTO_TCP, TCPCTL_IDENT, CTL_EOL);
2059 sysctl_createv(clog, 0, NULL, NULL,
2060 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2061 CTLTYPE_INT, "do_loopback_cksum",
2062 SYSCTL_DESCR("Perform TCP checksum on loopback"),
2063 NULL, 0, &tcp_do_loopback_cksum, 0,
2064 CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOOPBACKCKSUM,
2065 CTL_EOL);
2066 sysctl_createv(clog, 0, NULL, NULL,
2067 CTLFLAG_PERMANENT,
2068 CTLTYPE_STRUCT, "pcblist",
2069 SYSCTL_DESCR("TCP protocol control block list"),
2070 sysctl_inpcblist, 0, &tcbtable, 0,
2071 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE,
2072 CTL_EOL);
2073 sysctl_createv(clog, 0, NULL, NULL,
2074 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2075 CTLTYPE_INT, "keepinit",
2076 SYSCTL_DESCR("Ticks before initial tcp connection times out"),
2077 sysctl_tcp_keep, 0, &tcp_keepinit, 0,
2078 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2079
2080 /* TCP socket buffers auto-sizing nodes */
2081 sysctl_createv(clog, 0, NULL, NULL,
2082 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2083 CTLTYPE_INT, "recvbuf_auto",
2084 SYSCTL_DESCR("Enable automatic receive "
2085 "buffer sizing (experimental)"),
2086 NULL, 0, &tcp_do_autorcvbuf, 0,
2087 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2088 sysctl_createv(clog, 0, NULL, NULL,
2089 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2090 CTLTYPE_INT, "recvbuf_inc",
2091 SYSCTL_DESCR("Incrementor step size of "
2092 "automatic receive buffer"),
2093 NULL, 0, &tcp_autorcvbuf_inc, 0,
2094 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2095 sysctl_createv(clog, 0, NULL, NULL,
2096 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2097 CTLTYPE_INT, "recvbuf_max",
2098 SYSCTL_DESCR("Max size of automatic receive buffer"),
2099 NULL, 0, &tcp_autorcvbuf_max, 0,
2100 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2101
2102 sysctl_createv(clog, 0, NULL, NULL,
2103 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2104 CTLTYPE_INT, "sendbuf_auto",
2105 SYSCTL_DESCR("Enable automatic send "
2106 "buffer sizing (experimental)"),
2107 NULL, 0, &tcp_do_autosndbuf, 0,
2108 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2109 sysctl_createv(clog, 0, NULL, NULL,
2110 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2111 CTLTYPE_INT, "sendbuf_inc",
2112 SYSCTL_DESCR("Incrementor step size of "
2113 "automatic send buffer"),
2114 NULL, 0, &tcp_autosndbuf_inc, 0,
2115 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2116 sysctl_createv(clog, 0, NULL, NULL,
2117 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2118 CTLTYPE_INT, "sendbuf_max",
2119 SYSCTL_DESCR("Max size of automatic send buffer"),
2120 NULL, 0, &tcp_autosndbuf_max, 0,
2121 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2122
2123 /* ECN subtree */
2124 sysctl_createv(clog, 0, NULL, &ecn_node,
2125 CTLFLAG_PERMANENT,
2126 CTLTYPE_NODE, "ecn",
2127 SYSCTL_DESCR("RFC3168 Explicit Congestion Notification"),
2128 NULL, 0, NULL, 0,
2129 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2130 sysctl_createv(clog, 0, &ecn_node, NULL,
2131 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2132 CTLTYPE_INT, "enable",
2133 SYSCTL_DESCR("Enable TCP Explicit Congestion "
2134 "Notification"),
2135 NULL, 0, &tcp_do_ecn, 0, CTL_CREATE, CTL_EOL);
2136 sysctl_createv(clog, 0, &ecn_node, NULL,
2137 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2138 CTLTYPE_INT, "maxretries",
2139 SYSCTL_DESCR("Number of times to retry ECN setup "
2140 "before disabling ECN on the connection"),
2141 NULL, 0, &tcp_ecn_maxretries, 0, CTL_CREATE, CTL_EOL);
2142
2143 /* SACK gets its own little subtree. */
2144 sysctl_createv(clog, 0, NULL, &sack_node,
2145 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2146 CTLTYPE_INT, "enable",
2147 SYSCTL_DESCR("Enable RFC2018 Selective ACKnowledgement"),
2148 NULL, 0, &tcp_do_sack, 0,
2149 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
2150 sysctl_createv(clog, 0, NULL, &sack_node,
2151 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2152 CTLTYPE_INT, "maxholes",
2153 SYSCTL_DESCR("Maximum number of TCP SACK holes allowed per connection"),
2154 NULL, 0, &tcp_sack_tp_maxholes, 0,
2155 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
2156 sysctl_createv(clog, 0, NULL, &sack_node,
2157 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2158 CTLTYPE_INT, "globalmaxholes",
2159 SYSCTL_DESCR("Global maximum number of TCP SACK holes"),
2160 NULL, 0, &tcp_sack_globalmaxholes, 0,
2161 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
2162 sysctl_createv(clog, 0, NULL, &sack_node,
2163 CTLFLAG_PERMANENT,
2164 CTLTYPE_INT, "globalholes",
2165 SYSCTL_DESCR("Global number of TCP SACK holes"),
2166 NULL, 0, &tcp_sack_globalholes, 0,
2167 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
2168
2169 sysctl_createv(clog, 0, NULL, NULL,
2170 CTLFLAG_PERMANENT,
2171 CTLTYPE_STRUCT, "stats",
2172 SYSCTL_DESCR("TCP statistics"),
2173 sysctl_net_inet_tcp_stats, 0, NULL, 0,
2174 CTL_NET, pf, IPPROTO_TCP, TCPCTL_STATS,
2175 CTL_EOL);
2176 sysctl_createv(clog, 0, NULL, NULL,
2177 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2178 CTLTYPE_INT, "local_by_rtt",
2179 SYSCTL_DESCR("Use RTT estimator to decide which hosts "
2180 "are local"),
2181 NULL, 0, &tcp_rttlocal, 0,
2182 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2183 #ifdef TCP_DEBUG
2184 sysctl_createv(clog, 0, NULL, NULL,
2185 CTLFLAG_PERMANENT,
2186 CTLTYPE_STRUCT, "debug",
2187 SYSCTL_DESCR("TCP sockets debug information"),
2188 NULL, 0, &tcp_debug, sizeof(tcp_debug),
2189 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DEBUG,
2190 CTL_EOL);
2191 sysctl_createv(clog, 0, NULL, NULL,
2192 CTLFLAG_PERMANENT,
2193 CTLTYPE_INT, "debx",
2194 SYSCTL_DESCR("Number of TCP debug sockets messages"),
2195 NULL, 0, &tcp_debx, sizeof(tcp_debx),
2196 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DEBX,
2197 CTL_EOL);
2198 #endif
2199 sysctl_createv(clog, 0, NULL, NULL,
2200 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2201 CTLTYPE_STRUCT, "drop",
2202 SYSCTL_DESCR("TCP drop connection"),
2203 sysctl_net_inet_tcp_drop, 0, NULL, 0,
2204 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DROP, CTL_EOL);
2205 sysctl_createv(clog, 0, NULL, NULL,
2206 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2207 CTLTYPE_INT, "iss_hash",
2208 SYSCTL_DESCR("Enable RFC 1948 ISS by cryptographic "
2209 "hash computation"),
2210 NULL, 0, &tcp_do_rfc1948, sizeof(tcp_do_rfc1948),
2211 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE,
2212 CTL_EOL);
2213
2214 /* ABC subtree */
2215
2216 sysctl_createv(clog, 0, NULL, &abc_node,
2217 CTLFLAG_PERMANENT, CTLTYPE_NODE, "abc",
2218 SYSCTL_DESCR("RFC3465 Appropriate Byte Counting (ABC)"),
2219 NULL, 0, NULL, 0,
2220 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2221 sysctl_createv(clog, 0, &abc_node, NULL,
2222 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2223 CTLTYPE_INT, "enable",
2224 SYSCTL_DESCR("Enable RFC3465 Appropriate Byte Counting"),
2225 NULL, 0, &tcp_do_abc, 0, CTL_CREATE, CTL_EOL);
2226 sysctl_createv(clog, 0, &abc_node, NULL,
2227 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2228 CTLTYPE_INT, "aggressive",
2229 SYSCTL_DESCR("1: L=2*SMSS 0: L=1*SMSS"),
2230 NULL, 0, &tcp_abc_aggressive, 0, CTL_CREATE, CTL_EOL);
2231
2232 /* MSL tuning subtree */
2233
2234 sysctl_createv(clog, 0, NULL, &mslt_node,
2235 CTLFLAG_PERMANENT, CTLTYPE_NODE, "mslt",
2236 SYSCTL_DESCR("MSL Tuning for TIME_WAIT truncation"),
2237 NULL, 0, NULL, 0,
2238 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2239 sysctl_createv(clog, 0, &mslt_node, NULL,
2240 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2241 CTLTYPE_INT, "enable",
2242 SYSCTL_DESCR("Enable TIME_WAIT truncation"),
2243 NULL, 0, &tcp_msl_enable, 0, CTL_CREATE, CTL_EOL);
2244 sysctl_createv(clog, 0, &mslt_node, NULL,
2245 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2246 CTLTYPE_INT, "loopback",
2247 SYSCTL_DESCR("MSL value to use for loopback connections"),
2248 NULL, 0, &tcp_msl_loop, 0, CTL_CREATE, CTL_EOL);
2249 sysctl_createv(clog, 0, &mslt_node, NULL,
2250 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2251 CTLTYPE_INT, "local",
2252 SYSCTL_DESCR("MSL value to use for local connections"),
2253 NULL, 0, &tcp_msl_local, 0, CTL_CREATE, CTL_EOL);
2254 sysctl_createv(clog, 0, &mslt_node, NULL,
2255 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2256 CTLTYPE_INT, "remote",
2257 SYSCTL_DESCR("MSL value to use for remote connections"),
2258 NULL, 0, &tcp_msl_remote, 0, CTL_CREATE, CTL_EOL);
2259 sysctl_createv(clog, 0, &mslt_node, NULL,
2260 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2261 CTLTYPE_INT, "remote_threshold",
2262 SYSCTL_DESCR("RTT estimate value to promote local to remote"),
2263 NULL, 0, &tcp_msl_remote_threshold, 0, CTL_CREATE, CTL_EOL);
2264
2265 /* vestigial TIME_WAIT tuning subtree */
2266
2267 sysctl_createv(clog, 0, NULL, &vtw_node,
2268 CTLFLAG_PERMANENT, CTLTYPE_NODE, "vtw",
2269 SYSCTL_DESCR("Tuning for Vestigial TIME_WAIT"),
2270 NULL, 0, NULL, 0,
2271 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
2272 sysctl_createv(clog, 0, &vtw_node, NULL,
2273 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2274 CTLTYPE_INT, "enable",
2275 SYSCTL_DESCR("Enable Vestigial TIME_WAIT"),
2276 sysctl_tcp_vtw_enable, 0,
2277 (pf == AF_INET) ? &tcp4_vtw_enable : &tcp6_vtw_enable,
2278 0, CTL_CREATE, CTL_EOL);
2279 sysctl_createv(clog, 0, &vtw_node, NULL,
2280 CTLFLAG_PERMANENT|CTLFLAG_READONLY,
2281 CTLTYPE_INT, "entries",
2282 SYSCTL_DESCR("Maximum number of vestigial TIME_WAIT entries"),
2283 NULL, 0, &tcp_vtw_entries, 0, CTL_CREATE, CTL_EOL);
2284 }
2285
2286 void
2287 tcp_usrreq_init(void)
2288 {
2289
2290 sysctl_net_inet_tcp_setup2(NULL, PF_INET, "inet", "tcp");
2291 #ifdef INET6
2292 sysctl_net_inet_tcp_setup2(NULL, PF_INET6, "inet6", "tcp6");
2293 #endif
2294 }
2295
2296 PR_WRAP_USRREQS(tcp)
2297 #define tcp_attach tcp_attach_wrapper
2298 #define tcp_detach tcp_detach_wrapper
2299 #define tcp_accept tcp_accept_wrapper
2300 #define tcp_bind tcp_bind_wrapper
2301 #define tcp_listen tcp_listen_wrapper
2302 #define tcp_connect tcp_connect_wrapper
2303 #define tcp_connect2 tcp_connect2_wrapper
2304 #define tcp_disconnect tcp_disconnect_wrapper
2305 #define tcp_shutdown tcp_shutdown_wrapper
2306 #define tcp_abort tcp_abort_wrapper
2307 #define tcp_ioctl tcp_ioctl_wrapper
2308 #define tcp_stat tcp_stat_wrapper
2309 #define tcp_peeraddr tcp_peeraddr_wrapper
2310 #define tcp_sockaddr tcp_sockaddr_wrapper
2311 #define tcp_rcvd tcp_rcvd_wrapper
2312 #define tcp_recvoob tcp_recvoob_wrapper
2313 #define tcp_send tcp_send_wrapper
2314 #define tcp_sendoob tcp_sendoob_wrapper
2315 #define tcp_purgeif tcp_purgeif_wrapper
2316
2317 const struct pr_usrreqs tcp_usrreqs = {
2318 .pr_attach = tcp_attach,
2319 .pr_detach = tcp_detach,
2320 .pr_accept = tcp_accept,
2321 .pr_bind = tcp_bind,
2322 .pr_listen = tcp_listen,
2323 .pr_connect = tcp_connect,
2324 .pr_connect2 = tcp_connect2,
2325 .pr_disconnect = tcp_disconnect,
2326 .pr_shutdown = tcp_shutdown,
2327 .pr_abort = tcp_abort,
2328 .pr_ioctl = tcp_ioctl,
2329 .pr_stat = tcp_stat,
2330 .pr_peeraddr = tcp_peeraddr,
2331 .pr_sockaddr = tcp_sockaddr,
2332 .pr_rcvd = tcp_rcvd,
2333 .pr_recvoob = tcp_recvoob,
2334 .pr_send = tcp_send,
2335 .pr_sendoob = tcp_sendoob,
2336 .pr_purgeif = tcp_purgeif,
2337 };
2338