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