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