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