1 /* $NetBSD: tcp_usrreq.c,v 1.224 2019/02/05 04:48:47 mrg 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.224 2019/02/05 04:48:47 mrg 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 m_freem(m); 1153 m_freem(control); 1154 return error; 1155 } 1156 1157 ostate = tcp_debug_capture(tp, PRU_SENDOOB); 1158 1159 s = splsoftnet(); 1160 if (sbspace_oob(&so->so_snd) == 0) { 1161 m_freem(m); 1162 m_freem(control); 1163 splx(s); 1164 return ENOBUFS; 1165 } 1166 /* 1167 * According to RFC961 (Assigned Protocols), 1168 * the urgent pointer points to the last octet 1169 * of urgent data. We continue, however, 1170 * to consider it to indicate the first octet 1171 * of data past the urgent section. 1172 * Otherwise, snd_up should be one lower. 1173 */ 1174 sbappendstream(&so->so_snd, m); 1175 tp->snd_up = tp->snd_una + so->so_snd.sb_cc; 1176 tp->t_force = 1; 1177 error = tcp_output(tp); 1178 tp->t_force = 0; 1179 tcp_debug_trace(so, tp, ostate, PRU_SENDOOB); 1180 splx(s); 1181 m_freem(control); 1182 1183 return error; 1184 } 1185 1186 static int 1187 tcp_purgeif(struct socket *so, struct ifnet *ifp) 1188 { 1189 int s; 1190 int error = 0; 1191 1192 s = splsoftnet(); 1193 1194 mutex_enter(softnet_lock); 1195 switch (so->so_proto->pr_domain->dom_family) { 1196 case PF_INET: 1197 in_pcbpurgeif0(&tcbtable, ifp); 1198 #ifdef NET_MPSAFE 1199 mutex_exit(softnet_lock); 1200 #endif 1201 in_purgeif(ifp); 1202 #ifdef NET_MPSAFE 1203 mutex_enter(softnet_lock); 1204 #endif 1205 in_pcbpurgeif(&tcbtable, ifp); 1206 break; 1207 #ifdef INET6 1208 case PF_INET6: 1209 in6_pcbpurgeif0(&tcbtable, ifp); 1210 #ifdef NET_MPSAFE 1211 mutex_exit(softnet_lock); 1212 #endif 1213 in6_purgeif(ifp); 1214 #ifdef NET_MPSAFE 1215 mutex_enter(softnet_lock); 1216 #endif 1217 in6_pcbpurgeif(&tcbtable, ifp); 1218 break; 1219 #endif 1220 default: 1221 error = EAFNOSUPPORT; 1222 break; 1223 } 1224 mutex_exit(softnet_lock); 1225 splx(s); 1226 1227 return error; 1228 } 1229 1230 /* 1231 * Initiate (or continue) disconnect. 1232 * If embryonic state, just send reset (once). 1233 * If in ``let data drain'' option and linger null, just drop. 1234 * Otherwise (hard), mark socket disconnecting and drop 1235 * current input data; switch states based on user close, and 1236 * send segment to peer (with FIN). 1237 */ 1238 struct tcpcb * 1239 tcp_disconnect1(struct tcpcb *tp) 1240 { 1241 struct socket *so; 1242 1243 if (tp->t_inpcb) 1244 so = tp->t_inpcb->inp_socket; 1245 #ifdef INET6 1246 else if (tp->t_in6pcb) 1247 so = tp->t_in6pcb->in6p_socket; 1248 #endif 1249 else 1250 so = NULL; 1251 1252 if (TCPS_HAVEESTABLISHED(tp->t_state) == 0) 1253 tp = tcp_close(tp); 1254 else if ((so->so_options & SO_LINGER) && so->so_linger == 0) 1255 tp = tcp_drop(tp, 0); 1256 else { 1257 soisdisconnecting(so); 1258 sbflush(&so->so_rcv); 1259 tp = tcp_usrclosed(tp); 1260 if (tp) 1261 (void) tcp_output(tp); 1262 } 1263 return tp; 1264 } 1265 1266 /* 1267 * User issued close, and wish to trail through shutdown states: 1268 * if never received SYN, just forget it. If got a SYN from peer, 1269 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 1270 * If already got a FIN from peer, then almost done; go to LAST_ACK 1271 * state. In all other cases, have already sent FIN to peer (e.g. 1272 * after PRU_SHUTDOWN), and just have to play tedious game waiting 1273 * for peer to send FIN or not respond to keep-alives, etc. 1274 * We can let the user exit from the close as soon as the FIN is acked. 1275 */ 1276 struct tcpcb * 1277 tcp_usrclosed(struct tcpcb *tp) 1278 { 1279 1280 switch (tp->t_state) { 1281 1282 case TCPS_CLOSED: 1283 case TCPS_LISTEN: 1284 case TCPS_SYN_SENT: 1285 tp->t_state = TCPS_CLOSED; 1286 tp = tcp_close(tp); 1287 break; 1288 1289 case TCPS_SYN_RECEIVED: 1290 case TCPS_ESTABLISHED: 1291 tp->t_state = TCPS_FIN_WAIT_1; 1292 break; 1293 1294 case TCPS_CLOSE_WAIT: 1295 tp->t_state = TCPS_LAST_ACK; 1296 break; 1297 } 1298 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) { 1299 struct socket *so; 1300 if (tp->t_inpcb) 1301 so = tp->t_inpcb->inp_socket; 1302 #ifdef INET6 1303 else if (tp->t_in6pcb) 1304 so = tp->t_in6pcb->in6p_socket; 1305 #endif 1306 else 1307 so = NULL; 1308 if (so) 1309 soisdisconnected(so); 1310 /* 1311 * If we are in FIN_WAIT_2, we arrived here because the 1312 * application did a shutdown of the send side. Like the 1313 * case of a transition from FIN_WAIT_1 to FIN_WAIT_2 after 1314 * a full close, we start a timer to make sure sockets are 1315 * not left in FIN_WAIT_2 forever. 1316 */ 1317 if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0)) 1318 TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle); 1319 else if (tp->t_state == TCPS_TIME_WAIT 1320 && ((tp->t_inpcb 1321 && (tcp4_vtw_enable & 1) 1322 && vtw_add(AF_INET, tp)) 1323 || 1324 (tp->t_in6pcb 1325 && (tcp6_vtw_enable & 1) 1326 && vtw_add(AF_INET6, tp)))) { 1327 tp = 0; 1328 } 1329 } 1330 return tp; 1331 } 1332 1333 /* 1334 * sysctl helper routine for net.inet.ip.mssdflt. it can't be less 1335 * than 32. 1336 */ 1337 static int 1338 sysctl_net_inet_tcp_mssdflt(SYSCTLFN_ARGS) 1339 { 1340 int error, mssdflt; 1341 struct sysctlnode node; 1342 1343 mssdflt = tcp_mssdflt; 1344 node = *rnode; 1345 node.sysctl_data = &mssdflt; 1346 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1347 if (error || newp == NULL) 1348 return error; 1349 1350 if (mssdflt < 32) 1351 return EINVAL; 1352 tcp_mssdflt = mssdflt; 1353 1354 mutex_enter(softnet_lock); 1355 tcp_tcpcb_template(); 1356 mutex_exit(softnet_lock); 1357 1358 return 0; 1359 } 1360 1361 /* 1362 * sysctl helper for TCP CB template update 1363 */ 1364 static int 1365 sysctl_update_tcpcb_template(SYSCTLFN_ARGS) 1366 { 1367 int t, error; 1368 struct sysctlnode node; 1369 1370 /* follow procedures in sysctl(9) manpage */ 1371 t = *(int *)rnode->sysctl_data; 1372 node = *rnode; 1373 node.sysctl_data = &t; 1374 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1375 if (error || newp == NULL) 1376 return error; 1377 1378 if (t < 0) 1379 return EINVAL; 1380 1381 *(int *)rnode->sysctl_data = t; 1382 1383 mutex_enter(softnet_lock); 1384 tcp_tcpcb_template(); 1385 mutex_exit(softnet_lock); 1386 1387 return 0; 1388 } 1389 1390 /* 1391 * sysctl helper routine for setting port related values under 1392 * net.inet.ip and net.inet6.ip6. does basic range checking and does 1393 * additional checks for each type. this code has placed in 1394 * tcp_input.c since INET and INET6 both use the same tcp code. 1395 * 1396 * this helper is not static so that both inet and inet6 can use it. 1397 */ 1398 int 1399 sysctl_net_inet_ip_ports(SYSCTLFN_ARGS) 1400 { 1401 int error, tmp; 1402 int apmin, apmax; 1403 #ifndef IPNOPRIVPORTS 1404 int lpmin, lpmax; 1405 #endif /* IPNOPRIVPORTS */ 1406 struct sysctlnode node; 1407 1408 if (namelen != 0) 1409 return EINVAL; 1410 1411 switch (name[-3]) { 1412 case PF_INET: 1413 apmin = anonportmin; 1414 apmax = anonportmax; 1415 #ifndef IPNOPRIVPORTS 1416 lpmin = lowportmin; 1417 lpmax = lowportmax; 1418 #endif /* IPNOPRIVPORTS */ 1419 break; 1420 #ifdef INET6 1421 case PF_INET6: 1422 apmin = ip6_anonportmin; 1423 apmax = ip6_anonportmax; 1424 #ifndef IPNOPRIVPORTS 1425 lpmin = ip6_lowportmin; 1426 lpmax = ip6_lowportmax; 1427 #endif /* IPNOPRIVPORTS */ 1428 break; 1429 #endif /* INET6 */ 1430 default: 1431 return EINVAL; 1432 } 1433 1434 /* 1435 * insert temporary copy into node, perform lookup on 1436 * temporary, then restore pointer 1437 */ 1438 node = *rnode; 1439 tmp = *(int*)rnode->sysctl_data; 1440 node.sysctl_data = &tmp; 1441 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1442 if (error || newp == NULL) 1443 return error; 1444 1445 /* 1446 * simple port range check 1447 */ 1448 if (tmp < 0 || tmp > 65535) 1449 return EINVAL; 1450 1451 /* 1452 * per-node range checks 1453 */ 1454 switch (rnode->sysctl_num) { 1455 case IPCTL_ANONPORTMIN: 1456 case IPV6CTL_ANONPORTMIN: 1457 if (tmp >= apmax) 1458 return EINVAL; 1459 #ifndef IPNOPRIVPORTS 1460 if (tmp < IPPORT_RESERVED) 1461 return EINVAL; 1462 #endif /* IPNOPRIVPORTS */ 1463 break; 1464 1465 case IPCTL_ANONPORTMAX: 1466 case IPV6CTL_ANONPORTMAX: 1467 if (apmin >= tmp) 1468 return EINVAL; 1469 #ifndef IPNOPRIVPORTS 1470 if (tmp < IPPORT_RESERVED) 1471 return EINVAL; 1472 #endif /* IPNOPRIVPORTS */ 1473 break; 1474 1475 #ifndef IPNOPRIVPORTS 1476 case IPCTL_LOWPORTMIN: 1477 case IPV6CTL_LOWPORTMIN: 1478 if (tmp >= lpmax || 1479 tmp > IPPORT_RESERVEDMAX || 1480 tmp < IPPORT_RESERVEDMIN) 1481 return EINVAL; 1482 break; 1483 1484 case IPCTL_LOWPORTMAX: 1485 case IPV6CTL_LOWPORTMAX: 1486 if (lpmin >= tmp || 1487 tmp > IPPORT_RESERVEDMAX || 1488 tmp < IPPORT_RESERVEDMIN) 1489 return EINVAL; 1490 break; 1491 #endif /* IPNOPRIVPORTS */ 1492 1493 default: 1494 return EINVAL; 1495 } 1496 1497 *(int*)rnode->sysctl_data = tmp; 1498 1499 return 0; 1500 } 1501 1502 static inline int 1503 copyout_uid(struct socket *sockp, void *oldp, size_t *oldlenp) 1504 { 1505 if (oldp) { 1506 size_t sz; 1507 uid_t uid; 1508 int error; 1509 1510 if (sockp->so_cred == NULL) 1511 return EPERM; 1512 1513 uid = kauth_cred_geteuid(sockp->so_cred); 1514 sz = MIN(sizeof(uid), *oldlenp); 1515 if ((error = copyout(&uid, oldp, sz)) != 0) 1516 return error; 1517 } 1518 *oldlenp = sizeof(uid_t); 1519 return 0; 1520 } 1521 1522 static inline int 1523 inet4_ident_core(struct in_addr raddr, u_int rport, 1524 struct in_addr laddr, u_int lport, 1525 void *oldp, size_t *oldlenp, 1526 struct lwp *l, int dodrop) 1527 { 1528 struct inpcb *inp; 1529 struct socket *sockp; 1530 1531 inp = in_pcblookup_connect(&tcbtable, raddr, rport, laddr, lport, 0); 1532 1533 if (inp == NULL || (sockp = inp->inp_socket) == NULL) 1534 return ESRCH; 1535 1536 if (dodrop) { 1537 struct tcpcb *tp; 1538 int error; 1539 1540 if (inp == NULL || (tp = intotcpcb(inp)) == NULL || 1541 (inp->inp_socket->so_options & SO_ACCEPTCONN) != 0) 1542 return ESRCH; 1543 1544 error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET, 1545 KAUTH_REQ_NETWORK_SOCKET_DROP, inp->inp_socket, tp, NULL); 1546 if (error) 1547 return error; 1548 1549 (void)tcp_drop(tp, ECONNABORTED); 1550 return 0; 1551 } 1552 1553 return copyout_uid(sockp, oldp, oldlenp); 1554 } 1555 1556 #ifdef INET6 1557 static inline int 1558 inet6_ident_core(struct in6_addr *raddr, u_int rport, 1559 struct in6_addr *laddr, u_int lport, 1560 void *oldp, size_t *oldlenp, 1561 struct lwp *l, int dodrop) 1562 { 1563 struct in6pcb *in6p; 1564 struct socket *sockp; 1565 1566 in6p = in6_pcblookup_connect(&tcbtable, raddr, rport, laddr, lport, 0, 0); 1567 1568 if (in6p == NULL || (sockp = in6p->in6p_socket) == NULL) 1569 return ESRCH; 1570 1571 if (dodrop) { 1572 struct tcpcb *tp; 1573 int error; 1574 1575 if (in6p == NULL || (tp = in6totcpcb(in6p)) == NULL || 1576 (in6p->in6p_socket->so_options & SO_ACCEPTCONN) != 0) 1577 return ESRCH; 1578 1579 error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET, 1580 KAUTH_REQ_NETWORK_SOCKET_DROP, in6p->in6p_socket, tp, NULL); 1581 if (error) 1582 return error; 1583 1584 (void)tcp_drop(tp, ECONNABORTED); 1585 return 0; 1586 } 1587 1588 return copyout_uid(sockp, oldp, oldlenp); 1589 } 1590 #endif 1591 1592 /* 1593 * sysctl helper routine for the net.inet.tcp.drop and 1594 * net.inet6.tcp6.drop nodes. 1595 */ 1596 #define sysctl_net_inet_tcp_drop sysctl_net_inet_tcp_ident 1597 1598 /* 1599 * sysctl helper routine for the net.inet.tcp.ident and 1600 * net.inet6.tcp6.ident nodes. contains backwards compat code for the 1601 * old way of looking up the ident information for ipv4 which involves 1602 * stuffing the port/addr pairs into the mib lookup. 1603 */ 1604 static int 1605 sysctl_net_inet_tcp_ident(SYSCTLFN_ARGS) 1606 { 1607 struct sockaddr_in *si4[2]; 1608 #ifdef INET6 1609 struct sockaddr_in6 *si6[2]; 1610 #endif 1611 struct sockaddr_storage sa[2]; 1612 int error, pf, dodrop; 1613 1614 dodrop = name[-1] == TCPCTL_DROP; 1615 if (dodrop) { 1616 if (oldp != NULL || *oldlenp != 0) 1617 return EINVAL; 1618 if (newp == NULL) 1619 return EPERM; 1620 if (newlen < sizeof(sa)) 1621 return ENOMEM; 1622 } 1623 if (namelen != 4 && namelen != 0) 1624 return EINVAL; 1625 if (name[-2] != IPPROTO_TCP) 1626 return EINVAL; 1627 pf = name[-3]; 1628 1629 /* old style lookup, ipv4 only */ 1630 if (namelen == 4) { 1631 struct in_addr laddr, raddr; 1632 u_int lport, rport; 1633 1634 if (pf != PF_INET) 1635 return EPROTONOSUPPORT; 1636 raddr.s_addr = (uint32_t)name[0]; 1637 rport = (u_int)name[1]; 1638 laddr.s_addr = (uint32_t)name[2]; 1639 lport = (u_int)name[3]; 1640 1641 mutex_enter(softnet_lock); 1642 error = inet4_ident_core(raddr, rport, laddr, lport, 1643 oldp, oldlenp, l, dodrop); 1644 mutex_exit(softnet_lock); 1645 return error; 1646 } 1647 1648 if (newp == NULL || newlen != sizeof(sa)) 1649 return EINVAL; 1650 error = copyin(newp, &sa, newlen); 1651 if (error) 1652 return error; 1653 1654 /* 1655 * requested families must match 1656 */ 1657 if (pf != sa[0].ss_family || sa[0].ss_family != sa[1].ss_family) 1658 return EINVAL; 1659 1660 switch (pf) { 1661 #ifdef INET6 1662 case PF_INET6: 1663 si6[0] = (struct sockaddr_in6*)&sa[0]; 1664 si6[1] = (struct sockaddr_in6*)&sa[1]; 1665 if (si6[0]->sin6_len != sizeof(*si6[0]) || 1666 si6[1]->sin6_len != sizeof(*si6[1])) 1667 return EINVAL; 1668 1669 if (!IN6_IS_ADDR_V4MAPPED(&si6[0]->sin6_addr) && 1670 !IN6_IS_ADDR_V4MAPPED(&si6[1]->sin6_addr)) { 1671 error = sa6_embedscope(si6[0], ip6_use_defzone); 1672 if (error) 1673 return error; 1674 error = sa6_embedscope(si6[1], ip6_use_defzone); 1675 if (error) 1676 return error; 1677 1678 mutex_enter(softnet_lock); 1679 error = inet6_ident_core(&si6[0]->sin6_addr, 1680 si6[0]->sin6_port, &si6[1]->sin6_addr, 1681 si6[1]->sin6_port, oldp, oldlenp, l, dodrop); 1682 mutex_exit(softnet_lock); 1683 return error; 1684 } 1685 1686 if (IN6_IS_ADDR_V4MAPPED(&si6[0]->sin6_addr) != 1687 IN6_IS_ADDR_V4MAPPED(&si6[1]->sin6_addr)) 1688 return EINVAL; 1689 1690 in6_sin6_2_sin_in_sock((struct sockaddr *)&sa[0]); 1691 in6_sin6_2_sin_in_sock((struct sockaddr *)&sa[1]); 1692 #endif /* INET6 */ 1693 /*FALLTHROUGH*/ 1694 case PF_INET: 1695 si4[0] = (struct sockaddr_in*)&sa[0]; 1696 si4[1] = (struct sockaddr_in*)&sa[1]; 1697 if (si4[0]->sin_len != sizeof(*si4[0]) || 1698 si4[0]->sin_len != sizeof(*si4[1])) 1699 return EINVAL; 1700 1701 mutex_enter(softnet_lock); 1702 error = inet4_ident_core(si4[0]->sin_addr, si4[0]->sin_port, 1703 si4[1]->sin_addr, si4[1]->sin_port, 1704 oldp, oldlenp, l, dodrop); 1705 mutex_exit(softnet_lock); 1706 return error; 1707 default: 1708 return EPROTONOSUPPORT; 1709 } 1710 } 1711 1712 /* 1713 * sysctl helper for the inet and inet6 pcblists. handles tcp/udp and 1714 * inet/inet6, as well as raw pcbs for each. specifically not 1715 * declared static so that raw sockets and udp/udp6 can use it as 1716 * well. 1717 */ 1718 int 1719 sysctl_inpcblist(SYSCTLFN_ARGS) 1720 { 1721 const bool allowaddr = get_expose_address(curproc); 1722 struct sockaddr_in *in; 1723 const struct inpcb *inp; 1724 #ifdef INET6 1725 struct sockaddr_in6 *in6; 1726 const struct in6pcb *in6p; 1727 #endif 1728 struct inpcbtable *pcbtbl = __UNCONST(rnode->sysctl_data); 1729 const struct inpcb_hdr *inph; 1730 struct tcpcb *tp; 1731 struct kinfo_pcb pcb; 1732 char *dp; 1733 size_t len, needed, elem_size, out_size; 1734 int error, elem_count, pf, proto, pf2; 1735 1736 if (namelen != 4) 1737 return EINVAL; 1738 1739 if (oldp != NULL) { 1740 len = *oldlenp; 1741 elem_size = name[2]; 1742 elem_count = name[3]; 1743 if (elem_size != sizeof(pcb)) 1744 return EINVAL; 1745 } else { 1746 len = 0; 1747 elem_count = INT_MAX; 1748 elem_size = sizeof(pcb); 1749 } 1750 error = 0; 1751 dp = oldp; 1752 out_size = elem_size; 1753 needed = 0; 1754 1755 if (namelen == 1 && name[0] == CTL_QUERY) 1756 return (sysctl_query(SYSCTLFN_CALL(rnode))); 1757 1758 if (name - oname != 4) 1759 return EINVAL; 1760 1761 pf = oname[1]; 1762 proto = oname[2]; 1763 pf2 = (oldp != NULL) ? pf : 0; 1764 1765 mutex_enter(softnet_lock); 1766 1767 TAILQ_FOREACH(inph, &pcbtbl->inpt_queue, inph_queue) { 1768 inp = (const struct inpcb *)inph; 1769 #ifdef INET6 1770 in6p = (const struct in6pcb *)inph; 1771 #endif 1772 1773 if (inph->inph_af != pf) 1774 continue; 1775 1776 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET, 1777 KAUTH_REQ_NETWORK_SOCKET_CANSEE, inph->inph_socket, NULL, 1778 NULL) != 0) 1779 continue; 1780 1781 memset(&pcb, 0, sizeof(pcb)); 1782 1783 pcb.ki_family = pf; 1784 pcb.ki_type = proto; 1785 1786 switch (pf2) { 1787 case 0: 1788 /* just probing for size */ 1789 break; 1790 case PF_INET: 1791 pcb.ki_family = inp->inp_socket->so_proto-> 1792 pr_domain->dom_family; 1793 pcb.ki_type = inp->inp_socket->so_proto-> 1794 pr_type; 1795 pcb.ki_protocol = inp->inp_socket->so_proto-> 1796 pr_protocol; 1797 pcb.ki_pflags = inp->inp_flags; 1798 1799 pcb.ki_sostate = inp->inp_socket->so_state; 1800 pcb.ki_prstate = inp->inp_state; 1801 if (proto == IPPROTO_TCP) { 1802 tp = intotcpcb(inp); 1803 pcb.ki_tstate = tp->t_state; 1804 pcb.ki_tflags = tp->t_flags; 1805 } 1806 1807 COND_SET_VALUE(pcb.ki_pcbaddr, 1808 PTRTOUINT64(inp), allowaddr); 1809 COND_SET_VALUE(pcb.ki_ppcbaddr, 1810 PTRTOUINT64(inp->inp_ppcb), allowaddr); 1811 COND_SET_VALUE(pcb.ki_sockaddr, 1812 PTRTOUINT64(inp->inp_socket), allowaddr); 1813 1814 pcb.ki_rcvq = inp->inp_socket->so_rcv.sb_cc; 1815 pcb.ki_sndq = inp->inp_socket->so_snd.sb_cc; 1816 1817 in = satosin(&pcb.ki_src); 1818 in->sin_len = sizeof(*in); 1819 in->sin_family = pf; 1820 in->sin_port = inp->inp_lport; 1821 in->sin_addr = inp->inp_laddr; 1822 if (pcb.ki_prstate >= INP_CONNECTED) { 1823 in = satosin(&pcb.ki_dst); 1824 in->sin_len = sizeof(*in); 1825 in->sin_family = pf; 1826 in->sin_port = inp->inp_fport; 1827 in->sin_addr = inp->inp_faddr; 1828 } 1829 break; 1830 #ifdef INET6 1831 case PF_INET6: 1832 pcb.ki_family = in6p->in6p_socket->so_proto-> 1833 pr_domain->dom_family; 1834 pcb.ki_type = in6p->in6p_socket->so_proto->pr_type; 1835 pcb.ki_protocol = in6p->in6p_socket->so_proto-> 1836 pr_protocol; 1837 pcb.ki_pflags = in6p->in6p_flags; 1838 1839 pcb.ki_sostate = in6p->in6p_socket->so_state; 1840 pcb.ki_prstate = in6p->in6p_state; 1841 if (proto == IPPROTO_TCP) { 1842 tp = in6totcpcb(in6p); 1843 pcb.ki_tstate = tp->t_state; 1844 pcb.ki_tflags = tp->t_flags; 1845 } 1846 1847 COND_SET_VALUE(pcb.ki_pcbaddr, 1848 PTRTOUINT64(in6p), allowaddr); 1849 COND_SET_VALUE(pcb.ki_ppcbaddr, 1850 PTRTOUINT64(in6p->in6p_ppcb), allowaddr); 1851 COND_SET_VALUE(pcb.ki_sockaddr, 1852 PTRTOUINT64(in6p->in6p_socket), allowaddr); 1853 1854 pcb.ki_rcvq = in6p->in6p_socket->so_rcv.sb_cc; 1855 pcb.ki_sndq = in6p->in6p_socket->so_snd.sb_cc; 1856 1857 in6 = satosin6(&pcb.ki_src); 1858 in6->sin6_len = sizeof(*in6); 1859 in6->sin6_family = pf; 1860 in6->sin6_port = in6p->in6p_lport; 1861 in6->sin6_flowinfo = in6p->in6p_flowinfo; 1862 in6->sin6_addr = in6p->in6p_laddr; 1863 in6->sin6_scope_id = 0; /* XXX? */ 1864 1865 if (pcb.ki_prstate >= IN6P_CONNECTED) { 1866 in6 = satosin6(&pcb.ki_dst); 1867 in6->sin6_len = sizeof(*in6); 1868 in6->sin6_family = pf; 1869 in6->sin6_port = in6p->in6p_fport; 1870 in6->sin6_flowinfo = in6p->in6p_flowinfo; 1871 in6->sin6_addr = in6p->in6p_faddr; 1872 in6->sin6_scope_id = 0; /* XXX? */ 1873 } 1874 break; 1875 #endif 1876 } 1877 1878 if (len >= elem_size && elem_count > 0) { 1879 error = copyout(&pcb, dp, out_size); 1880 if (error) { 1881 mutex_exit(softnet_lock); 1882 return error; 1883 } 1884 dp += elem_size; 1885 len -= elem_size; 1886 } 1887 needed += elem_size; 1888 if (elem_count > 0 && elem_count != INT_MAX) 1889 elem_count--; 1890 } 1891 1892 *oldlenp = needed; 1893 if (oldp == NULL) 1894 *oldlenp += PCB_SLOP * sizeof(struct kinfo_pcb); 1895 1896 mutex_exit(softnet_lock); 1897 1898 return error; 1899 } 1900 1901 static int 1902 sysctl_tcp_congctl(SYSCTLFN_ARGS) 1903 { 1904 struct sysctlnode node; 1905 int error; 1906 char newname[TCPCC_MAXLEN]; 1907 1908 strlcpy(newname, tcp_congctl_global_name, sizeof(newname) - 1); 1909 1910 node = *rnode; 1911 node.sysctl_data = newname; 1912 node.sysctl_size = sizeof(newname); 1913 1914 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1915 1916 if (error || 1917 newp == NULL || 1918 strncmp(newname, tcp_congctl_global_name, sizeof(newname)) == 0) 1919 return error; 1920 1921 mutex_enter(softnet_lock); 1922 error = tcp_congctl_select(NULL, newname); 1923 mutex_exit(softnet_lock); 1924 1925 return error; 1926 } 1927 1928 static int 1929 sysctl_tcp_init_win(SYSCTLFN_ARGS) 1930 { 1931 int error; 1932 u_int iw; 1933 struct sysctlnode node; 1934 1935 iw = *(u_int *)rnode->sysctl_data; 1936 node = *rnode; 1937 node.sysctl_data = &iw; 1938 node.sysctl_size = sizeof(iw); 1939 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1940 if (error || newp == NULL) 1941 return error; 1942 1943 if (iw >= __arraycount(tcp_init_win_max)) 1944 return EINVAL; 1945 *(u_int *)rnode->sysctl_data = iw; 1946 return 0; 1947 } 1948 1949 static int 1950 sysctl_tcp_keep(SYSCTLFN_ARGS) 1951 { 1952 int error; 1953 u_int tmp; 1954 struct sysctlnode node; 1955 1956 node = *rnode; 1957 tmp = *(u_int *)rnode->sysctl_data; 1958 node.sysctl_data = &tmp; 1959 1960 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1961 if (error || newp == NULL) 1962 return error; 1963 1964 mutex_enter(softnet_lock); 1965 1966 *(u_int *)rnode->sysctl_data = tmp; 1967 tcp_tcpcb_template(); /* update the template */ 1968 1969 mutex_exit(softnet_lock); 1970 return 0; 1971 } 1972 1973 static int 1974 sysctl_net_inet_tcp_stats(SYSCTLFN_ARGS) 1975 { 1976 1977 return (NETSTAT_SYSCTL(tcpstat_percpu, TCP_NSTATS)); 1978 } 1979 1980 /* 1981 * this (second stage) setup routine is a replacement for tcp_sysctl() 1982 * (which is currently used for ipv4 and ipv6) 1983 */ 1984 static void 1985 sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname, 1986 const char *tcpname) 1987 { 1988 const struct sysctlnode *sack_node; 1989 const struct sysctlnode *abc_node; 1990 const struct sysctlnode *ecn_node; 1991 const struct sysctlnode *congctl_node; 1992 const struct sysctlnode *mslt_node; 1993 const struct sysctlnode *vtw_node; 1994 #ifdef TCP_DEBUG 1995 extern struct tcp_debug tcp_debug[TCP_NDEBUG]; 1996 extern int tcp_debx; 1997 #endif 1998 1999 sysctl_createv(clog, 0, NULL, NULL, 2000 CTLFLAG_PERMANENT, 2001 CTLTYPE_NODE, pfname, NULL, 2002 NULL, 0, NULL, 0, 2003 CTL_NET, pf, CTL_EOL); 2004 sysctl_createv(clog, 0, NULL, NULL, 2005 CTLFLAG_PERMANENT, 2006 CTLTYPE_NODE, tcpname, 2007 SYSCTL_DESCR("TCP related settings"), 2008 NULL, 0, NULL, 0, 2009 CTL_NET, pf, IPPROTO_TCP, CTL_EOL); 2010 2011 sysctl_createv(clog, 0, NULL, NULL, 2012 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2013 CTLTYPE_INT, "rfc1323", 2014 SYSCTL_DESCR("Enable RFC1323 TCP extensions"), 2015 sysctl_update_tcpcb_template, 0, &tcp_do_rfc1323, 0, 2016 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RFC1323, CTL_EOL); 2017 sysctl_createv(clog, 0, NULL, NULL, 2018 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2019 CTLTYPE_INT, "sendspace", 2020 SYSCTL_DESCR("Default TCP send buffer size"), 2021 NULL, 0, &tcp_sendspace, 0, 2022 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SENDSPACE, CTL_EOL); 2023 sysctl_createv(clog, 0, NULL, NULL, 2024 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2025 CTLTYPE_INT, "recvspace", 2026 SYSCTL_DESCR("Default TCP receive buffer size"), 2027 NULL, 0, &tcp_recvspace, 0, 2028 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RECVSPACE, CTL_EOL); 2029 sysctl_createv(clog, 0, NULL, NULL, 2030 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2031 CTLTYPE_INT, "mssdflt", 2032 SYSCTL_DESCR("Default maximum segment size"), 2033 sysctl_net_inet_tcp_mssdflt, 0, &tcp_mssdflt, 0, 2034 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSSDFLT, CTL_EOL); 2035 sysctl_createv(clog, 0, NULL, NULL, 2036 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2037 CTLTYPE_INT, "minmss", 2038 SYSCTL_DESCR("Lower limit for TCP maximum segment size"), 2039 NULL, 0, &tcp_minmss, 0, 2040 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2041 sysctl_createv(clog, 0, NULL, NULL, 2042 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2043 CTLTYPE_INT, "msl", 2044 SYSCTL_DESCR("Maximum Segment Life"), 2045 NULL, 0, &tcp_msl, 0, 2046 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSL, CTL_EOL); 2047 sysctl_createv(clog, 0, NULL, NULL, 2048 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2049 CTLTYPE_INT, "syn_cache_limit", 2050 SYSCTL_DESCR("Maximum number of entries in the TCP " 2051 "compressed state engine"), 2052 NULL, 0, &tcp_syn_cache_limit, 0, 2053 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_LIMIT, 2054 CTL_EOL); 2055 sysctl_createv(clog, 0, NULL, NULL, 2056 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2057 CTLTYPE_INT, "syn_bucket_limit", 2058 SYSCTL_DESCR("Maximum number of entries per hash " 2059 "bucket in the TCP compressed state " 2060 "engine"), 2061 NULL, 0, &tcp_syn_bucket_limit, 0, 2062 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_BUCKET_LIMIT, 2063 CTL_EOL); 2064 #if 0 /* obsoleted */ 2065 sysctl_createv(clog, 0, NULL, NULL, 2066 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2067 CTLTYPE_INT, "syn_cache_interval", 2068 SYSCTL_DESCR("TCP compressed state engine's timer interval"), 2069 NULL, 0, &tcp_syn_cache_interval, 0, 2070 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_INTER, 2071 CTL_EOL); 2072 #endif 2073 sysctl_createv(clog, 0, NULL, NULL, 2074 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2075 CTLTYPE_INT, "init_win", 2076 SYSCTL_DESCR("Initial TCP congestion window"), 2077 sysctl_tcp_init_win, 0, &tcp_init_win, 0, 2078 CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN, CTL_EOL); 2079 sysctl_createv(clog, 0, NULL, NULL, 2080 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2081 CTLTYPE_INT, "mss_ifmtu", 2082 SYSCTL_DESCR("Use interface MTU for calculating MSS"), 2083 NULL, 0, &tcp_mss_ifmtu, 0, 2084 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSS_IFMTU, CTL_EOL); 2085 sysctl_createv(clog, 0, NULL, &sack_node, 2086 CTLFLAG_PERMANENT, 2087 CTLTYPE_NODE, "sack", 2088 SYSCTL_DESCR("RFC2018 Selective ACKnowledgement tunables"), 2089 NULL, 0, NULL, 0, 2090 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_EOL); 2091 2092 /* Congctl subtree */ 2093 sysctl_createv(clog, 0, NULL, &congctl_node, 2094 CTLFLAG_PERMANENT, 2095 CTLTYPE_NODE, "congctl", 2096 SYSCTL_DESCR("TCP Congestion Control"), 2097 NULL, 0, NULL, 0, 2098 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2099 sysctl_createv(clog, 0, &congctl_node, NULL, 2100 CTLFLAG_PERMANENT, 2101 CTLTYPE_STRING, "available", 2102 SYSCTL_DESCR("Available Congestion Control Mechanisms"), 2103 NULL, 0, tcp_congctl_avail, 0, CTL_CREATE, CTL_EOL); 2104 sysctl_createv(clog, 0, &congctl_node, NULL, 2105 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2106 CTLTYPE_STRING, "selected", 2107 SYSCTL_DESCR("Selected Congestion Control Mechanism"), 2108 sysctl_tcp_congctl, 0, NULL, TCPCC_MAXLEN, 2109 CTL_CREATE, CTL_EOL); 2110 2111 sysctl_createv(clog, 0, NULL, NULL, 2112 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2113 CTLTYPE_INT, "win_scale", 2114 SYSCTL_DESCR("Use RFC1323 window scale options"), 2115 sysctl_update_tcpcb_template, 0, &tcp_do_win_scale, 0, 2116 CTL_NET, pf, IPPROTO_TCP, TCPCTL_WSCALE, CTL_EOL); 2117 sysctl_createv(clog, 0, NULL, NULL, 2118 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2119 CTLTYPE_INT, "timestamps", 2120 SYSCTL_DESCR("Use RFC1323 time stamp options"), 2121 sysctl_update_tcpcb_template, 0, &tcp_do_timestamps, 0, 2122 CTL_NET, pf, IPPROTO_TCP, TCPCTL_TSTAMP, CTL_EOL); 2123 sysctl_createv(clog, 0, NULL, NULL, 2124 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2125 CTLTYPE_INT, "cwm", 2126 SYSCTL_DESCR("Hughes/Touch/Heidemann Congestion Window " 2127 "Monitoring"), 2128 NULL, 0, &tcp_cwm, 0, 2129 CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM, CTL_EOL); 2130 sysctl_createv(clog, 0, NULL, NULL, 2131 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2132 CTLTYPE_INT, "cwm_burstsize", 2133 SYSCTL_DESCR("Congestion Window Monitoring allowed " 2134 "burst count in packets"), 2135 NULL, 0, &tcp_cwm_burstsize, 0, 2136 CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM_BURSTSIZE, 2137 CTL_EOL); 2138 sysctl_createv(clog, 0, NULL, NULL, 2139 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2140 CTLTYPE_INT, "ack_on_push", 2141 SYSCTL_DESCR("Immediately return ACK when PSH is " 2142 "received"), 2143 NULL, 0, &tcp_ack_on_push, 0, 2144 CTL_NET, pf, IPPROTO_TCP, TCPCTL_ACK_ON_PUSH, CTL_EOL); 2145 sysctl_createv(clog, 0, NULL, NULL, 2146 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2147 CTLTYPE_INT, "keepidle", 2148 SYSCTL_DESCR("Allowed connection idle ticks before a " 2149 "keepalive probe is sent"), 2150 sysctl_tcp_keep, 0, &tcp_keepidle, 0, 2151 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPIDLE, CTL_EOL); 2152 sysctl_createv(clog, 0, NULL, NULL, 2153 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2154 CTLTYPE_INT, "keepintvl", 2155 SYSCTL_DESCR("Ticks before next keepalive probe is sent"), 2156 sysctl_tcp_keep, 0, &tcp_keepintvl, 0, 2157 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPINTVL, CTL_EOL); 2158 sysctl_createv(clog, 0, NULL, NULL, 2159 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2160 CTLTYPE_INT, "keepcnt", 2161 SYSCTL_DESCR("Number of keepalive probes to send"), 2162 sysctl_tcp_keep, 0, &tcp_keepcnt, 0, 2163 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPCNT, CTL_EOL); 2164 sysctl_createv(clog, 0, NULL, NULL, 2165 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 2166 CTLTYPE_INT, "slowhz", 2167 SYSCTL_DESCR("Keepalive ticks per second"), 2168 NULL, PR_SLOWHZ, NULL, 0, 2169 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SLOWHZ, CTL_EOL); 2170 sysctl_createv(clog, 0, NULL, NULL, 2171 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2172 CTLTYPE_INT, "log_refused", 2173 SYSCTL_DESCR("Log refused TCP connections"), 2174 NULL, 0, &tcp_log_refused, 0, 2175 CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOG_REFUSED, CTL_EOL); 2176 #if 0 /* obsoleted */ 2177 sysctl_createv(clog, 0, NULL, NULL, 2178 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2179 CTLTYPE_INT, "rstratelimit", NULL, 2180 NULL, 0, &tcp_rst_ratelim, 0, 2181 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTRATELIMIT, CTL_EOL); 2182 #endif 2183 sysctl_createv(clog, 0, NULL, NULL, 2184 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2185 CTLTYPE_INT, "rstppslimit", 2186 SYSCTL_DESCR("Maximum number of RST packets to send " 2187 "per second"), 2188 NULL, 0, &tcp_rst_ppslim, 0, 2189 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTPPSLIMIT, CTL_EOL); 2190 sysctl_createv(clog, 0, NULL, NULL, 2191 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2192 CTLTYPE_INT, "delack_ticks", 2193 SYSCTL_DESCR("Number of ticks to delay sending an ACK"), 2194 NULL, 0, &tcp_delack_ticks, 0, 2195 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DELACK_TICKS, CTL_EOL); 2196 sysctl_createv(clog, 0, NULL, NULL, 2197 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2198 CTLTYPE_INT, "init_win_local", 2199 SYSCTL_DESCR("Initial TCP window size (in segments)"), 2200 sysctl_tcp_init_win, 0, &tcp_init_win_local, 0, 2201 CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN_LOCAL, 2202 CTL_EOL); 2203 sysctl_createv(clog, 0, NULL, NULL, 2204 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2205 CTLTYPE_STRUCT, "ident", 2206 SYSCTL_DESCR("RFC1413 Identification Protocol lookups"), 2207 sysctl_net_inet_tcp_ident, 0, NULL, sizeof(uid_t), 2208 CTL_NET, pf, IPPROTO_TCP, TCPCTL_IDENT, CTL_EOL); 2209 sysctl_createv(clog, 0, NULL, NULL, 2210 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2211 CTLTYPE_INT, "do_loopback_cksum", 2212 SYSCTL_DESCR("Perform TCP checksum on loopback"), 2213 NULL, 0, &tcp_do_loopback_cksum, 0, 2214 CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOOPBACKCKSUM, 2215 CTL_EOL); 2216 sysctl_createv(clog, 0, NULL, NULL, 2217 CTLFLAG_PERMANENT, 2218 CTLTYPE_STRUCT, "pcblist", 2219 SYSCTL_DESCR("TCP protocol control block list"), 2220 sysctl_inpcblist, 0, &tcbtable, 0, 2221 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, 2222 CTL_EOL); 2223 sysctl_createv(clog, 0, NULL, NULL, 2224 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2225 CTLTYPE_INT, "keepinit", 2226 SYSCTL_DESCR("Ticks before initial tcp connection times out"), 2227 sysctl_tcp_keep, 0, &tcp_keepinit, 0, 2228 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2229 2230 /* TCP socket buffers auto-sizing nodes */ 2231 sysctl_createv(clog, 0, NULL, NULL, 2232 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2233 CTLTYPE_INT, "recvbuf_auto", 2234 SYSCTL_DESCR("Enable automatic receive " 2235 "buffer sizing (experimental)"), 2236 NULL, 0, &tcp_do_autorcvbuf, 0, 2237 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2238 sysctl_createv(clog, 0, NULL, NULL, 2239 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2240 CTLTYPE_INT, "recvbuf_inc", 2241 SYSCTL_DESCR("Incrementor step size of " 2242 "automatic receive buffer"), 2243 NULL, 0, &tcp_autorcvbuf_inc, 0, 2244 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2245 sysctl_createv(clog, 0, NULL, NULL, 2246 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2247 CTLTYPE_INT, "recvbuf_max", 2248 SYSCTL_DESCR("Max size of automatic receive buffer"), 2249 NULL, 0, &tcp_autorcvbuf_max, 0, 2250 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2251 2252 sysctl_createv(clog, 0, NULL, NULL, 2253 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2254 CTLTYPE_INT, "sendbuf_auto", 2255 SYSCTL_DESCR("Enable automatic send " 2256 "buffer sizing (experimental)"), 2257 NULL, 0, &tcp_do_autosndbuf, 0, 2258 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2259 sysctl_createv(clog, 0, NULL, NULL, 2260 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2261 CTLTYPE_INT, "sendbuf_inc", 2262 SYSCTL_DESCR("Incrementor step size of " 2263 "automatic send buffer"), 2264 NULL, 0, &tcp_autosndbuf_inc, 0, 2265 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2266 sysctl_createv(clog, 0, NULL, NULL, 2267 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2268 CTLTYPE_INT, "sendbuf_max", 2269 SYSCTL_DESCR("Max size of automatic send buffer"), 2270 NULL, 0, &tcp_autosndbuf_max, 0, 2271 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2272 2273 /* ECN subtree */ 2274 sysctl_createv(clog, 0, NULL, &ecn_node, 2275 CTLFLAG_PERMANENT, 2276 CTLTYPE_NODE, "ecn", 2277 SYSCTL_DESCR("RFC3168 Explicit Congestion Notification"), 2278 NULL, 0, NULL, 0, 2279 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2280 sysctl_createv(clog, 0, &ecn_node, NULL, 2281 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2282 CTLTYPE_INT, "enable", 2283 SYSCTL_DESCR("Enable TCP Explicit Congestion " 2284 "Notification"), 2285 NULL, 0, &tcp_do_ecn, 0, CTL_CREATE, CTL_EOL); 2286 sysctl_createv(clog, 0, &ecn_node, NULL, 2287 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2288 CTLTYPE_INT, "maxretries", 2289 SYSCTL_DESCR("Number of times to retry ECN setup " 2290 "before disabling ECN on the connection"), 2291 NULL, 0, &tcp_ecn_maxretries, 0, CTL_CREATE, CTL_EOL); 2292 2293 /* SACK gets its own little subtree. */ 2294 sysctl_createv(clog, 0, NULL, &sack_node, 2295 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2296 CTLTYPE_INT, "enable", 2297 SYSCTL_DESCR("Enable RFC2018 Selective ACKnowledgement"), 2298 NULL, 0, &tcp_do_sack, 0, 2299 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL); 2300 sysctl_createv(clog, 0, NULL, &sack_node, 2301 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2302 CTLTYPE_INT, "maxholes", 2303 SYSCTL_DESCR("Maximum number of TCP SACK holes allowed per connection"), 2304 NULL, 0, &tcp_sack_tp_maxholes, 0, 2305 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL); 2306 sysctl_createv(clog, 0, NULL, &sack_node, 2307 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2308 CTLTYPE_INT, "globalmaxholes", 2309 SYSCTL_DESCR("Global maximum number of TCP SACK holes"), 2310 NULL, 0, &tcp_sack_globalmaxholes, 0, 2311 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL); 2312 sysctl_createv(clog, 0, NULL, &sack_node, 2313 CTLFLAG_PERMANENT, 2314 CTLTYPE_INT, "globalholes", 2315 SYSCTL_DESCR("Global number of TCP SACK holes"), 2316 NULL, 0, &tcp_sack_globalholes, 0, 2317 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL); 2318 2319 sysctl_createv(clog, 0, NULL, NULL, 2320 CTLFLAG_PERMANENT, 2321 CTLTYPE_STRUCT, "stats", 2322 SYSCTL_DESCR("TCP statistics"), 2323 sysctl_net_inet_tcp_stats, 0, NULL, 0, 2324 CTL_NET, pf, IPPROTO_TCP, TCPCTL_STATS, 2325 CTL_EOL); 2326 sysctl_createv(clog, 0, NULL, NULL, 2327 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2328 CTLTYPE_INT, "local_by_rtt", 2329 SYSCTL_DESCR("Use RTT estimator to decide which hosts " 2330 "are local"), 2331 NULL, 0, &tcp_rttlocal, 0, 2332 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2333 #ifdef TCP_DEBUG 2334 sysctl_createv(clog, 0, NULL, NULL, 2335 CTLFLAG_PERMANENT, 2336 CTLTYPE_STRUCT, "debug", 2337 SYSCTL_DESCR("TCP sockets debug information"), 2338 NULL, 0, &tcp_debug, sizeof(tcp_debug), 2339 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DEBUG, 2340 CTL_EOL); 2341 sysctl_createv(clog, 0, NULL, NULL, 2342 CTLFLAG_PERMANENT, 2343 CTLTYPE_INT, "debx", 2344 SYSCTL_DESCR("Number of TCP debug sockets messages"), 2345 NULL, 0, &tcp_debx, sizeof(tcp_debx), 2346 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DEBX, 2347 CTL_EOL); 2348 #endif 2349 sysctl_createv(clog, 0, NULL, NULL, 2350 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2351 CTLTYPE_STRUCT, "drop", 2352 SYSCTL_DESCR("TCP drop connection"), 2353 sysctl_net_inet_tcp_drop, 0, NULL, 0, 2354 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DROP, CTL_EOL); 2355 sysctl_createv(clog, 0, NULL, NULL, 2356 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2357 CTLTYPE_INT, "iss_hash", 2358 SYSCTL_DESCR("Enable RFC 1948 ISS by cryptographic " 2359 "hash computation"), 2360 NULL, 0, &tcp_do_rfc1948, sizeof(tcp_do_rfc1948), 2361 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, 2362 CTL_EOL); 2363 2364 /* ABC subtree */ 2365 2366 sysctl_createv(clog, 0, NULL, &abc_node, 2367 CTLFLAG_PERMANENT, CTLTYPE_NODE, "abc", 2368 SYSCTL_DESCR("RFC3465 Appropriate Byte Counting (ABC)"), 2369 NULL, 0, NULL, 0, 2370 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2371 sysctl_createv(clog, 0, &abc_node, NULL, 2372 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2373 CTLTYPE_INT, "enable", 2374 SYSCTL_DESCR("Enable RFC3465 Appropriate Byte Counting"), 2375 NULL, 0, &tcp_do_abc, 0, CTL_CREATE, CTL_EOL); 2376 sysctl_createv(clog, 0, &abc_node, NULL, 2377 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2378 CTLTYPE_INT, "aggressive", 2379 SYSCTL_DESCR("1: L=2*SMSS 0: L=1*SMSS"), 2380 NULL, 0, &tcp_abc_aggressive, 0, CTL_CREATE, CTL_EOL); 2381 2382 /* MSL tuning subtree */ 2383 2384 sysctl_createv(clog, 0, NULL, &mslt_node, 2385 CTLFLAG_PERMANENT, CTLTYPE_NODE, "mslt", 2386 SYSCTL_DESCR("MSL Tuning for TIME_WAIT truncation"), 2387 NULL, 0, NULL, 0, 2388 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2389 sysctl_createv(clog, 0, &mslt_node, NULL, 2390 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2391 CTLTYPE_INT, "enable", 2392 SYSCTL_DESCR("Enable TIME_WAIT truncation"), 2393 NULL, 0, &tcp_msl_enable, 0, CTL_CREATE, CTL_EOL); 2394 sysctl_createv(clog, 0, &mslt_node, NULL, 2395 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2396 CTLTYPE_INT, "loopback", 2397 SYSCTL_DESCR("MSL value to use for loopback connections"), 2398 NULL, 0, &tcp_msl_loop, 0, CTL_CREATE, CTL_EOL); 2399 sysctl_createv(clog, 0, &mslt_node, NULL, 2400 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2401 CTLTYPE_INT, "local", 2402 SYSCTL_DESCR("MSL value to use for local connections"), 2403 NULL, 0, &tcp_msl_local, 0, CTL_CREATE, CTL_EOL); 2404 sysctl_createv(clog, 0, &mslt_node, NULL, 2405 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2406 CTLTYPE_INT, "remote", 2407 SYSCTL_DESCR("MSL value to use for remote connections"), 2408 NULL, 0, &tcp_msl_remote, 0, CTL_CREATE, CTL_EOL); 2409 sysctl_createv(clog, 0, &mslt_node, NULL, 2410 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2411 CTLTYPE_INT, "remote_threshold", 2412 SYSCTL_DESCR("RTT estimate value to promote local to remote"), 2413 NULL, 0, &tcp_msl_remote_threshold, 0, CTL_CREATE, CTL_EOL); 2414 2415 /* vestigial TIME_WAIT tuning subtree */ 2416 2417 sysctl_createv(clog, 0, NULL, &vtw_node, 2418 CTLFLAG_PERMANENT, CTLTYPE_NODE, "vtw", 2419 SYSCTL_DESCR("Tuning for Vestigial TIME_WAIT"), 2420 NULL, 0, NULL, 0, 2421 CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL); 2422 sysctl_createv(clog, 0, &vtw_node, NULL, 2423 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2424 CTLTYPE_INT, "enable", 2425 SYSCTL_DESCR("Enable Vestigial TIME_WAIT"), 2426 sysctl_tcp_vtw_enable, 0, 2427 (pf == AF_INET) ? &tcp4_vtw_enable : &tcp6_vtw_enable, 2428 0, CTL_CREATE, CTL_EOL); 2429 sysctl_createv(clog, 0, &vtw_node, NULL, 2430 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 2431 CTLTYPE_INT, "entries", 2432 SYSCTL_DESCR("Maximum number of vestigial TIME_WAIT entries"), 2433 NULL, 0, &tcp_vtw_entries, 0, CTL_CREATE, CTL_EOL); 2434 } 2435 2436 void 2437 tcp_usrreq_init(void) 2438 { 2439 2440 sysctl_net_inet_tcp_setup2(NULL, PF_INET, "inet", "tcp"); 2441 #ifdef INET6 2442 sysctl_net_inet_tcp_setup2(NULL, PF_INET6, "inet6", "tcp6"); 2443 #endif 2444 } 2445 2446 PR_WRAP_USRREQS(tcp) 2447 #define tcp_attach tcp_attach_wrapper 2448 #define tcp_detach tcp_detach_wrapper 2449 #define tcp_accept tcp_accept_wrapper 2450 #define tcp_bind tcp_bind_wrapper 2451 #define tcp_listen tcp_listen_wrapper 2452 #define tcp_connect tcp_connect_wrapper 2453 #define tcp_connect2 tcp_connect2_wrapper 2454 #define tcp_disconnect tcp_disconnect_wrapper 2455 #define tcp_shutdown tcp_shutdown_wrapper 2456 #define tcp_abort tcp_abort_wrapper 2457 #define tcp_ioctl tcp_ioctl_wrapper 2458 #define tcp_stat tcp_stat_wrapper 2459 #define tcp_peeraddr tcp_peeraddr_wrapper 2460 #define tcp_sockaddr tcp_sockaddr_wrapper 2461 #define tcp_rcvd tcp_rcvd_wrapper 2462 #define tcp_recvoob tcp_recvoob_wrapper 2463 #define tcp_send tcp_send_wrapper 2464 #define tcp_sendoob tcp_sendoob_wrapper 2465 #define tcp_purgeif tcp_purgeif_wrapper 2466 2467 const struct pr_usrreqs tcp_usrreqs = { 2468 .pr_attach = tcp_attach, 2469 .pr_detach = tcp_detach, 2470 .pr_accept = tcp_accept, 2471 .pr_bind = tcp_bind, 2472 .pr_listen = tcp_listen, 2473 .pr_connect = tcp_connect, 2474 .pr_connect2 = tcp_connect2, 2475 .pr_disconnect = tcp_disconnect, 2476 .pr_shutdown = tcp_shutdown, 2477 .pr_abort = tcp_abort, 2478 .pr_ioctl = tcp_ioctl, 2479 .pr_stat = tcp_stat, 2480 .pr_peeraddr = tcp_peeraddr, 2481 .pr_sockaddr = tcp_sockaddr, 2482 .pr_rcvd = tcp_rcvd, 2483 .pr_recvoob = tcp_recvoob, 2484 .pr_send = tcp_send, 2485 .pr_sendoob = tcp_sendoob, 2486 .pr_purgeif = tcp_purgeif, 2487 }; 2488