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