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