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