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