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