1 /* $NetBSD: tcp_usrreq.c,v 1.202 2014/11/10 18:52:51 maxv 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.202 2014/11/10 18:52:51 maxv 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 its 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