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