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