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