The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/tcp_usrreq.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: tcp_usrreq.c,v 1.149.4.2 2009/09/26 18:34:29 snj 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 #include <sys/cdefs.h>
   98 __KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.149.4.2 2009/09/26 18:34:29 snj Exp $");
   99 
  100 #include "opt_inet.h"
  101 #include "opt_ipsec.h"
  102 #include "opt_tcp_debug.h"
  103 #include "opt_mbuftrace.h"
  104 #include "rnd.h"
  105 
  106 #include <sys/param.h>
  107 #include <sys/systm.h>
  108 #include <sys/kernel.h>
  109 #include <sys/malloc.h>
  110 #include <sys/mbuf.h>
  111 #include <sys/socket.h>
  112 #include <sys/socketvar.h>
  113 #include <sys/protosw.h>
  114 #include <sys/errno.h>
  115 #include <sys/stat.h>
  116 #include <sys/proc.h>
  117 #include <sys/domain.h>
  118 #include <sys/sysctl.h>
  119 #include <sys/kauth.h>
  120 #include <sys/uidinfo.h>
  121 
  122 #include <net/if.h>
  123 #include <net/route.h>
  124 
  125 #include <netinet/in.h>
  126 #include <netinet/in_systm.h>
  127 #include <netinet/in_var.h>
  128 #include <netinet/ip.h>
  129 #include <netinet/in_pcb.h>
  130 #include <netinet/ip_var.h>
  131 #include <netinet/in_offload.h>
  132 
  133 #ifdef INET6
  134 #ifndef INET
  135 #include <netinet/in.h>
  136 #endif
  137 #include <netinet/ip6.h>
  138 #include <netinet6/in6_pcb.h>
  139 #include <netinet6/ip6_var.h>
  140 #include <netinet6/scope6_var.h>
  141 #endif
  142 
  143 #include <netinet/tcp.h>
  144 #include <netinet/tcp_fsm.h>
  145 #include <netinet/tcp_seq.h>
  146 #include <netinet/tcp_timer.h>
  147 #include <netinet/tcp_var.h>
  148 #include <netinet/tcp_private.h>
  149 #include <netinet/tcp_congctl.h>
  150 #include <netinet/tcpip.h>
  151 #include <netinet/tcp_debug.h>
  152 
  153 #include "opt_tcp_space.h"
  154 
  155 #ifdef IPSEC
  156 #include <netinet6/ipsec.h>
  157 #endif /*IPSEC*/
  158 
  159 /*
  160  * TCP protocol interface to socket abstraction.
  161  */
  162 
  163 /*
  164  * Process a TCP user request for TCP tb.  If this is a send request
  165  * then m is the mbuf chain of send data.  If this is a timer expiration
  166  * (called from the software clock routine), then timertype tells which timer.
  167  */
  168 /*ARGSUSED*/
  169 int
  170 tcp_usrreq(struct socket *so, int req,
  171     struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l)
  172 {
  173         struct inpcb *inp;
  174 #ifdef INET6
  175         struct in6pcb *in6p;
  176 #endif
  177         struct tcpcb *tp = NULL;
  178         int s;
  179         int error = 0;
  180 #ifdef TCP_DEBUG
  181         int ostate = 0;
  182 #endif
  183         int family;     /* family of the socket */
  184 
  185         family = so->so_proto->pr_domain->dom_family;
  186 
  187         if (req == PRU_CONTROL) {
  188                 switch (family) {
  189 #ifdef INET
  190                 case PF_INET:
  191                         return (in_control(so, (long)m, (void *)nam,
  192                             (struct ifnet *)control, l));
  193 #endif
  194 #ifdef INET6
  195                 case PF_INET6:
  196                         return (in6_control(so, (long)m, (void *)nam,
  197                             (struct ifnet *)control, l));
  198 #endif
  199                 default:
  200                         return EAFNOSUPPORT;
  201                 }
  202         }
  203 
  204         s = splsoftnet();
  205 
  206         if (req == PRU_PURGEIF) {
  207                 mutex_enter(softnet_lock);
  208                 switch (family) {
  209 #ifdef INET
  210                 case PF_INET:
  211                         in_pcbpurgeif0(&tcbtable, (struct ifnet *)control);
  212                         in_purgeif((struct ifnet *)control);
  213                         in_pcbpurgeif(&tcbtable, (struct ifnet *)control);
  214                         break;
  215 #endif
  216 #ifdef INET6
  217                 case PF_INET6:
  218                         in6_pcbpurgeif0(&tcbtable, (struct ifnet *)control);
  219                         in6_purgeif((struct ifnet *)control);
  220                         in6_pcbpurgeif(&tcbtable, (struct ifnet *)control);
  221                         break;
  222 #endif
  223                 default:
  224                         mutex_exit(softnet_lock);
  225                         splx(s);
  226                         return (EAFNOSUPPORT);
  227                 }
  228                 mutex_exit(softnet_lock);
  229                 splx(s);
  230                 return (0);
  231         }
  232 
  233         if (req == PRU_ATTACH)
  234                 sosetlock(so);
  235 
  236         switch (family) {
  237 #ifdef INET
  238         case PF_INET:
  239                 inp = sotoinpcb(so);
  240 #ifdef INET6
  241                 in6p = NULL;
  242 #endif
  243                 break;
  244 #endif
  245 #ifdef INET6
  246         case PF_INET6:
  247                 inp = NULL;
  248                 in6p = sotoin6pcb(so);
  249                 break;
  250 #endif
  251         default:
  252                 splx(s);
  253                 return EAFNOSUPPORT;
  254         }
  255 
  256 #ifdef DIAGNOSTIC
  257 #ifdef INET6
  258         if (inp && in6p)
  259                 panic("tcp_usrreq: both inp and in6p set to non-NULL");
  260 #endif
  261         if (req != PRU_SEND && req != PRU_SENDOOB && control)
  262                 panic("tcp_usrreq: unexpected control mbuf");
  263 #endif
  264         /*
  265          * When a TCP is attached to a socket, then there will be
  266          * a (struct inpcb) pointed at by the socket, and this
  267          * structure will point at a subsidary (struct tcpcb).
  268          */
  269 #ifndef INET6
  270         if (inp == 0 && req != PRU_ATTACH)
  271 #else
  272         if ((inp == 0 && in6p == 0) && req != PRU_ATTACH)
  273 #endif
  274         {
  275                 error = EINVAL;
  276                 goto release;
  277         }
  278 #ifdef INET
  279         if (inp) {
  280                 tp = intotcpcb(inp);
  281                 /* WHAT IF TP IS 0? */
  282 #ifdef KPROF
  283                 tcp_acounts[tp->t_state][req]++;
  284 #endif
  285 #ifdef TCP_DEBUG
  286                 ostate = tp->t_state;
  287 #endif
  288         }
  289 #endif
  290 #ifdef INET6
  291         if (in6p) {
  292                 tp = in6totcpcb(in6p);
  293                 /* WHAT IF TP IS 0? */
  294 #ifdef KPROF
  295                 tcp_acounts[tp->t_state][req]++;
  296 #endif
  297 #ifdef TCP_DEBUG
  298                 ostate = tp->t_state;
  299 #endif
  300         }
  301 #endif
  302 
  303         switch (req) {
  304 
  305         /*
  306          * TCP attaches to socket via PRU_ATTACH, reserving space,
  307          * and an internet control block.
  308          */
  309         case PRU_ATTACH:
  310 #ifndef INET6
  311                 if (inp != 0)
  312 #else
  313                 if (inp != 0 || in6p != 0)
  314 #endif
  315                 {
  316                         error = EISCONN;
  317                         break;
  318                 }
  319                 error = tcp_attach(so);
  320                 if (error)
  321                         break;
  322                 if ((so->so_options & SO_LINGER) && so->so_linger == 0)
  323                         so->so_linger = TCP_LINGERTIME;
  324                 tp = sototcpcb(so);
  325                 break;
  326 
  327         /*
  328          * PRU_DETACH detaches the TCP protocol from the socket.
  329          */
  330         case PRU_DETACH:
  331                 tp = tcp_disconnect(tp);
  332                 break;
  333 
  334         /*
  335          * Give the socket an address.
  336          */
  337         case PRU_BIND:
  338                 switch (family) {
  339 #ifdef INET
  340                 case PF_INET:
  341                         error = in_pcbbind(inp, nam, l);
  342                         break;
  343 #endif
  344 #ifdef INET6
  345                 case PF_INET6:
  346                         error = in6_pcbbind(in6p, nam, l);
  347                         if (!error) {
  348                                 /* mapped addr case */
  349                                 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
  350                                         tp->t_family = AF_INET;
  351                                 else
  352                                         tp->t_family = AF_INET6;
  353                         }
  354                         break;
  355 #endif
  356                 }
  357                 break;
  358 
  359         /*
  360          * Prepare to accept connections.
  361          */
  362         case PRU_LISTEN:
  363 #ifdef INET
  364                 if (inp && inp->inp_lport == 0) {
  365                         error = in_pcbbind(inp, (struct mbuf *)0, l);
  366                         if (error)
  367                                 break;
  368                 }
  369 #endif
  370 #ifdef INET6
  371                 if (in6p && in6p->in6p_lport == 0) {
  372                         error = in6_pcbbind(in6p, (struct mbuf *)0,
  373                             (struct lwp *)0);
  374                         if (error)
  375                                 break;
  376                 }
  377 #endif
  378                 tp->t_state = TCPS_LISTEN;
  379                 break;
  380 
  381         /*
  382          * Initiate connection to peer.
  383          * Create a template for use in transmissions on this connection.
  384          * Enter SYN_SENT state, and mark socket as connecting.
  385          * Start keep-alive timer, and seed output sequence space.
  386          * Send initial segment on connection.
  387          */
  388         case PRU_CONNECT:
  389 #ifdef INET
  390                 if (inp) {
  391                         if (inp->inp_lport == 0) {
  392                                 error = in_pcbbind(inp, (struct mbuf *)0, l);
  393                                 if (error)
  394                                         break;
  395                         }
  396                         error = in_pcbconnect(inp, nam, l);
  397                 }
  398 #endif
  399 #ifdef INET6
  400                 if (in6p) {
  401                         if (in6p->in6p_lport == 0) {
  402                                 error = in6_pcbbind(in6p, (struct mbuf *)0,
  403                                     (struct lwp *)0);
  404                                 if (error)
  405                                         break;
  406                         }
  407                         error = in6_pcbconnect(in6p, nam, l);
  408                         if (!error) {
  409                                 /* mapped addr case */
  410                                 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr))
  411                                         tp->t_family = AF_INET;
  412                                 else
  413                                         tp->t_family = AF_INET6;
  414                         }
  415                 }
  416 #endif
  417                 if (error)
  418                         break;
  419                 tp->t_template = tcp_template(tp);
  420                 if (tp->t_template == 0) {
  421 #ifdef INET
  422                         if (inp)
  423                                 in_pcbdisconnect(inp);
  424 #endif
  425 #ifdef INET6
  426                         if (in6p)
  427                                 in6_pcbdisconnect(in6p);
  428 #endif
  429                         error = ENOBUFS;
  430                         break;
  431                 }
  432                 /*
  433                  * Compute window scaling to request.
  434                  * XXX: This should be moved to tcp_output().
  435                  */
  436                 while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
  437                     (TCP_MAXWIN << tp->request_r_scale) < sb_max)
  438                         tp->request_r_scale++;
  439                 soisconnecting(so);
  440                 TCP_STATINC(TCP_STAT_CONNATTEMPT);
  441                 tp->t_state = TCPS_SYN_SENT;
  442                 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
  443                 tp->iss = tcp_new_iss(tp, 0);
  444                 tcp_sendseqinit(tp);
  445                 error = tcp_output(tp);
  446                 break;
  447 
  448         /*
  449          * Create a TCP connection between two sockets.
  450          */
  451         case PRU_CONNECT2:
  452                 error = EOPNOTSUPP;
  453                 break;
  454 
  455         /*
  456          * Initiate disconnect from peer.
  457          * If connection never passed embryonic stage, just drop;
  458          * else if don't need to let data drain, then can just drop anyways,
  459          * else have to begin TCP shutdown process: mark socket disconnecting,
  460          * drain unread data, state switch to reflect user close, and
  461          * send segment (e.g. FIN) to peer.  Socket will be really disconnected
  462          * when peer sends FIN and acks ours.
  463          *
  464          * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
  465          */
  466         case PRU_DISCONNECT:
  467                 tp = tcp_disconnect(tp);
  468                 break;
  469 
  470         /*
  471          * Accept a connection.  Essentially all the work is
  472          * done at higher levels; just return the address
  473          * of the peer, storing through addr.
  474          */
  475         case PRU_ACCEPT:
  476 #ifdef INET
  477                 if (inp)
  478                         in_setpeeraddr(inp, nam);
  479 #endif
  480 #ifdef INET6
  481                 if (in6p)
  482                         in6_setpeeraddr(in6p, nam);
  483 #endif
  484                 break;
  485 
  486         /*
  487          * Mark the connection as being incapable of further output.
  488          */
  489         case PRU_SHUTDOWN:
  490                 socantsendmore(so);
  491                 tp = tcp_usrclosed(tp);
  492                 if (tp)
  493                         error = tcp_output(tp);
  494                 break;
  495 
  496         /*
  497          * After a receive, possibly send window update to peer.
  498          */
  499         case PRU_RCVD:
  500                 /*
  501                  * soreceive() calls this function when a user receives
  502                  * ancillary data on a listening socket. We don't call
  503                  * tcp_output in such a case, since there is no header
  504                  * template for a listening socket and hence the kernel
  505                  * will panic.
  506                  */
  507                 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) != 0)
  508                         (void) tcp_output(tp);
  509                 break;
  510 
  511         /*
  512          * Do a send by putting data in output queue and updating urgent
  513          * marker if URG set.  Possibly send more data.
  514          */
  515         case PRU_SEND:
  516                 if (control && control->m_len) {
  517                         m_freem(control);
  518                         m_freem(m);
  519                         error = EINVAL;
  520                         break;
  521                 }
  522                 sbappendstream(&so->so_snd, m);
  523                 error = tcp_output(tp);
  524                 break;
  525 
  526         /*
  527          * Abort the TCP.
  528          */
  529         case PRU_ABORT:
  530                 tp = tcp_drop(tp, ECONNABORTED);
  531                 break;
  532 
  533         case PRU_SENSE:
  534                 /*
  535                  * stat: don't bother with a blocksize.
  536                  */
  537                 splx(s);
  538                 return (0);
  539 
  540         case PRU_RCVOOB:
  541                 if (control && control->m_len) {
  542                         m_freem(control);
  543                         m_freem(m);
  544                         error = EINVAL;
  545                         break;
  546                 }
  547                 if ((so->so_oobmark == 0 &&
  548                     (so->so_state & SS_RCVATMARK) == 0) ||
  549                     so->so_options & SO_OOBINLINE ||
  550                     tp->t_oobflags & TCPOOB_HADDATA) {
  551                         error = EINVAL;
  552                         break;
  553                 }
  554                 if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
  555                         error = EWOULDBLOCK;
  556                         break;
  557                 }
  558                 m->m_len = 1;
  559                 *mtod(m, char *) = tp->t_iobc;
  560                 if (((long)nam & MSG_PEEK) == 0)
  561                         tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
  562                 break;
  563 
  564         case PRU_SENDOOB:
  565                 if (sbspace(&so->so_snd) < -512) {
  566                         m_freem(m);
  567                         error = ENOBUFS;
  568                         break;
  569                 }
  570                 /*
  571                  * According to RFC961 (Assigned Protocols),
  572                  * the urgent pointer points to the last octet
  573                  * of urgent data.  We continue, however,
  574                  * to consider it to indicate the first octet
  575                  * of data past the urgent section.
  576                  * Otherwise, snd_up should be one lower.
  577                  */
  578                 sbappendstream(&so->so_snd, m);
  579                 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
  580                 tp->t_force = 1;
  581                 error = tcp_output(tp);
  582                 tp->t_force = 0;
  583                 break;
  584 
  585         case PRU_SOCKADDR:
  586 #ifdef INET
  587                 if (inp)
  588                         in_setsockaddr(inp, nam);
  589 #endif
  590 #ifdef INET6
  591                 if (in6p)
  592                         in6_setsockaddr(in6p, nam);
  593 #endif
  594                 break;
  595 
  596         case PRU_PEERADDR:
  597 #ifdef INET
  598                 if (inp)
  599                         in_setpeeraddr(inp, nam);
  600 #endif
  601 #ifdef INET6
  602                 if (in6p)
  603                         in6_setpeeraddr(in6p, nam);
  604 #endif
  605                 break;
  606 
  607         default:
  608                 panic("tcp_usrreq");
  609         }
  610 #ifdef TCP_DEBUG
  611         if (tp && (so->so_options & SO_DEBUG))
  612                 tcp_trace(TA_USER, ostate, tp, NULL, req);
  613 #endif
  614 
  615 release:
  616         splx(s);
  617         return (error);
  618 }
  619 
  620 static void
  621 change_keepalive(struct socket *so, struct tcpcb *tp)
  622 {
  623         tp->t_maxidle = tp->t_keepcnt * tp->t_keepintvl;
  624         TCP_TIMER_DISARM(tp, TCPT_KEEP);
  625         TCP_TIMER_DISARM(tp, TCPT_2MSL);
  626 
  627         if (tp->t_state == TCPS_SYN_RECEIVED ||
  628             tp->t_state == TCPS_SYN_SENT) {
  629                 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
  630         } else if (so->so_options & SO_KEEPALIVE && 
  631             tp->t_state <= TCPS_CLOSE_WAIT) {
  632                 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepintvl);
  633         } else {
  634                 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle);
  635         }
  636 
  637         if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0))
  638                 TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
  639 }
  640 
  641 
  642 int
  643 tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
  644 {
  645         int error = 0, s;
  646         struct inpcb *inp;
  647 #ifdef INET6
  648         struct in6pcb *in6p;
  649 #endif
  650         struct tcpcb *tp;
  651         u_int ui;
  652         int family;     /* family of the socket */
  653         int level, optname, optval;
  654 
  655         level = sopt->sopt_level;
  656         optname = sopt->sopt_name;
  657 
  658         family = so->so_proto->pr_domain->dom_family;
  659 
  660         s = splsoftnet();
  661         switch (family) {
  662 #ifdef INET
  663         case PF_INET:
  664                 inp = sotoinpcb(so);
  665 #ifdef INET6
  666                 in6p = NULL;
  667 #endif
  668                 break;
  669 #endif
  670 #ifdef INET6
  671         case PF_INET6:
  672                 inp = NULL;
  673                 in6p = sotoin6pcb(so);
  674                 break;
  675 #endif
  676         default:
  677                 splx(s);
  678                 panic("%s: af %d", __func__, family);
  679         }
  680 #ifndef INET6
  681         if (inp == NULL)
  682 #else
  683         if (inp == NULL && in6p == NULL)
  684 #endif
  685         {
  686                 splx(s);
  687                 return (ECONNRESET);
  688         }
  689         if (level != IPPROTO_TCP) {
  690                 switch (family) {
  691 #ifdef INET
  692                 case PF_INET:
  693                         error = ip_ctloutput(op, so, sopt);
  694                         break;
  695 #endif
  696 #ifdef INET6
  697                 case PF_INET6:
  698                         error = ip6_ctloutput(op, so, sopt);
  699                         break;
  700 #endif
  701                 }
  702                 splx(s);
  703                 return (error);
  704         }
  705         if (inp)
  706                 tp = intotcpcb(inp);
  707 #ifdef INET6
  708         else if (in6p)
  709                 tp = in6totcpcb(in6p);
  710 #endif
  711         else
  712                 tp = NULL;
  713 
  714         switch (op) {
  715         case PRCO_SETOPT:
  716                 switch (optname) {
  717 #ifdef TCP_SIGNATURE
  718                 case TCP_MD5SIG:
  719                         error = sockopt_getint(sopt, &optval);
  720                         if (error)
  721                                 break;
  722                         if (optval > 0)
  723                                 tp->t_flags |= TF_SIGNATURE;
  724                         else
  725                                 tp->t_flags &= ~TF_SIGNATURE;
  726                         break;
  727 #endif /* TCP_SIGNATURE */
  728 
  729                 case TCP_NODELAY:
  730                         error = sockopt_getint(sopt, &optval);
  731                         if (error)
  732                                 break;
  733                         if (optval)
  734                                 tp->t_flags |= TF_NODELAY;
  735                         else
  736                                 tp->t_flags &= ~TF_NODELAY;
  737                         break;
  738 
  739                 case TCP_MAXSEG:
  740                         error = sockopt_getint(sopt, &optval);
  741                         if (error)
  742                                 break;
  743                         if (optval > 0 && optval <= tp->t_peermss)
  744                                 tp->t_peermss = optval; /* limit on send size */
  745                         else
  746                                 error = EINVAL;
  747                         break;
  748 #ifdef notyet
  749                 case TCP_CONGCTL:
  750                         /* XXX string overflow XXX */
  751                         error = tcp_congctl_select(tp, sopt->sopt_data);
  752                         break;
  753 #endif
  754 
  755                 case TCP_KEEPIDLE:
  756                         error = sockopt_get(sopt, &ui, sizeof(ui));
  757                         if (error)
  758                                 break;
  759                         if (ui > 0) {
  760                                 tp->t_keepidle = ui;
  761                                 change_keepalive(so, tp);
  762                         } else
  763                                 error = EINVAL;
  764                         break;
  765 
  766                 case TCP_KEEPINTVL:
  767                         error = sockopt_get(sopt, &ui, sizeof(ui));
  768                         if (error)
  769                                 break;
  770                         if (ui > 0) {
  771                                 tp->t_keepintvl = ui;
  772                                 change_keepalive(so, tp);
  773                         } else
  774                                 error = EINVAL;
  775                         break;
  776 
  777                 case TCP_KEEPCNT:
  778                         error = sockopt_get(sopt, &ui, sizeof(ui));
  779                         if (error)
  780                                 break;
  781                         if (ui > 0) {
  782                                 tp->t_keepcnt = ui;
  783                                 change_keepalive(so, tp);
  784                         } else
  785                                 error = EINVAL;
  786                         break;
  787 
  788                 case TCP_KEEPINIT:
  789                         error = sockopt_get(sopt, &ui, sizeof(ui));
  790                         if (error)
  791                                 break;
  792                         if (ui > 0) {
  793                                 tp->t_keepinit = ui;
  794                                 change_keepalive(so, tp);
  795                         } else
  796                                 error = EINVAL;
  797                         break;
  798 
  799                 default:
  800                         error = ENOPROTOOPT;
  801                         break;
  802                 }
  803                 break;
  804 
  805         case PRCO_GETOPT:
  806                 switch (optname) {
  807 #ifdef TCP_SIGNATURE
  808                 case TCP_MD5SIG:
  809                         optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
  810                         error = sockopt_set(sopt, &optval, sizeof(optval));
  811                         break;
  812 #endif
  813                 case TCP_NODELAY:
  814                         optval = tp->t_flags & TF_NODELAY;
  815                         error = sockopt_set(sopt, &optval, sizeof(optval));
  816                         break;
  817                 case TCP_MAXSEG:
  818                         optval = tp->t_peermss;
  819                         error = sockopt_set(sopt, &optval, sizeof(optval));
  820                         break;
  821 #ifdef notyet
  822                 case TCP_CONGCTL:
  823                         break;
  824 #endif
  825                 default:
  826                         error = ENOPROTOOPT;
  827                         break;
  828                 }
  829                 break;
  830         }
  831         splx(s);
  832         return (error);
  833 }
  834 
  835 #ifndef TCP_SENDSPACE
  836 #define TCP_SENDSPACE   1024*32
  837 #endif
  838 int     tcp_sendspace = TCP_SENDSPACE;
  839 #ifndef TCP_RECVSPACE
  840 #define TCP_RECVSPACE   1024*32
  841 #endif
  842 int     tcp_recvspace = TCP_RECVSPACE;
  843 
  844 /*
  845  * Attach TCP protocol to socket, allocating
  846  * internet protocol control block, tcp control block,
  847  * bufer space, and entering LISTEN state if to accept connections.
  848  */
  849 int
  850 tcp_attach(struct socket *so)
  851 {
  852         struct tcpcb *tp;
  853         struct inpcb *inp;
  854 #ifdef INET6
  855         struct in6pcb *in6p;
  856 #endif
  857         int error;
  858         int family;     /* family of the socket */
  859 
  860         family = so->so_proto->pr_domain->dom_family;
  861 
  862 #ifdef MBUFTRACE
  863         so->so_mowner = &tcp_sock_mowner;
  864         so->so_rcv.sb_mowner = &tcp_sock_rx_mowner;
  865         so->so_snd.sb_mowner = &tcp_sock_tx_mowner;
  866 #endif
  867         if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  868                 error = soreserve(so, tcp_sendspace, tcp_recvspace);
  869                 if (error)
  870                         return (error);
  871         }
  872 
  873         so->so_rcv.sb_flags |= SB_AUTOSIZE;
  874         so->so_snd.sb_flags |= SB_AUTOSIZE;
  875 
  876         switch (family) {
  877 #ifdef INET
  878         case PF_INET:
  879                 error = in_pcballoc(so, &tcbtable);
  880                 if (error)
  881                         return (error);
  882                 inp = sotoinpcb(so);
  883 #ifdef INET6
  884                 in6p = NULL;
  885 #endif
  886                 break;
  887 #endif
  888 #ifdef INET6
  889         case PF_INET6:
  890                 error = in6_pcballoc(so, &tcbtable);
  891                 if (error)
  892                         return (error);
  893                 inp = NULL;
  894                 in6p = sotoin6pcb(so);
  895                 break;
  896 #endif
  897         default:
  898                 return EAFNOSUPPORT;
  899         }
  900         if (inp)
  901                 tp = tcp_newtcpcb(family, (void *)inp);
  902 #ifdef INET6
  903         else if (in6p)
  904                 tp = tcp_newtcpcb(family, (void *)in6p);
  905 #endif
  906         else
  907                 tp = NULL;
  908 
  909         if (tp == 0) {
  910                 int nofd = so->so_state & SS_NOFDREF;   /* XXX */
  911 
  912                 so->so_state &= ~SS_NOFDREF;    /* don't free the socket yet */
  913 #ifdef INET
  914                 if (inp)
  915                         in_pcbdetach(inp);
  916 #endif
  917 #ifdef INET6
  918                 if (in6p)
  919                         in6_pcbdetach(in6p);
  920 #endif
  921                 so->so_state |= nofd;
  922                 return (ENOBUFS);
  923         }
  924         tp->t_state = TCPS_CLOSED;
  925         return (0);
  926 }
  927 
  928 /*
  929  * Initiate (or continue) disconnect.
  930  * If embryonic state, just send reset (once).
  931  * If in ``let data drain'' option and linger null, just drop.
  932  * Otherwise (hard), mark socket disconnecting and drop
  933  * current input data; switch states based on user close, and
  934  * send segment to peer (with FIN).
  935  */
  936 struct tcpcb *
  937 tcp_disconnect(struct tcpcb *tp)
  938 {
  939         struct socket *so;
  940 
  941         if (tp->t_inpcb)
  942                 so = tp->t_inpcb->inp_socket;
  943 #ifdef INET6
  944         else if (tp->t_in6pcb)
  945                 so = tp->t_in6pcb->in6p_socket;
  946 #endif
  947         else
  948                 so = NULL;
  949 
  950         if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
  951                 tp = tcp_close(tp);
  952         else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
  953                 tp = tcp_drop(tp, 0);
  954         else {
  955                 soisdisconnecting(so);
  956                 sbflush(&so->so_rcv);
  957                 tp = tcp_usrclosed(tp);
  958                 if (tp)
  959                         (void) tcp_output(tp);
  960         }
  961         return (tp);
  962 }
  963 
  964 /*
  965  * User issued close, and wish to trail through shutdown states:
  966  * if never received SYN, just forget it.  If got a SYN from peer,
  967  * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
  968  * If already got a FIN from peer, then almost done; go to LAST_ACK
  969  * state.  In all other cases, have already sent FIN to peer (e.g.
  970  * after PRU_SHUTDOWN), and just have to play tedious game waiting
  971  * for peer to send FIN or not respond to keep-alives, etc.
  972  * We can let the user exit from the close as soon as the FIN is acked.
  973  */
  974 struct tcpcb *
  975 tcp_usrclosed(struct tcpcb *tp)
  976 {
  977 
  978         switch (tp->t_state) {
  979 
  980         case TCPS_CLOSED:
  981         case TCPS_LISTEN:
  982         case TCPS_SYN_SENT:
  983                 tp->t_state = TCPS_CLOSED;
  984                 tp = tcp_close(tp);
  985                 break;
  986 
  987         case TCPS_SYN_RECEIVED:
  988         case TCPS_ESTABLISHED:
  989                 tp->t_state = TCPS_FIN_WAIT_1;
  990                 break;
  991 
  992         case TCPS_CLOSE_WAIT:
  993                 tp->t_state = TCPS_LAST_ACK;
  994                 break;
  995         }
  996         if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
  997                 struct socket *so;
  998                 if (tp->t_inpcb)
  999                         so = tp->t_inpcb->inp_socket;
 1000 #ifdef INET6
 1001                 else if (tp->t_in6pcb)
 1002                         so = tp->t_in6pcb->in6p_socket;
 1003 #endif
 1004                 else
 1005                         so = NULL;
 1006                 if (so)
 1007                         soisdisconnected(so);
 1008                 /*
 1009                  * If we are in FIN_WAIT_2, we arrived here because the
 1010                  * application did a shutdown of the send side.  Like the
 1011                  * case of a transition from FIN_WAIT_1 to FIN_WAIT_2 after
 1012                  * a full close, we start a timer to make sure sockets are
 1013                  * not left in FIN_WAIT_2 forever.
 1014                  */
 1015                 if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0))
 1016                         TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
 1017         }
 1018         return (tp);
 1019 }
 1020 
 1021 /*
 1022  * sysctl helper routine for net.inet.ip.mssdflt.  it can't be less
 1023  * than 32.
 1024  */
 1025 static int
 1026 sysctl_net_inet_tcp_mssdflt(SYSCTLFN_ARGS)
 1027 {
 1028         int error, mssdflt;
 1029         struct sysctlnode node;
 1030 
 1031         mssdflt = tcp_mssdflt;
 1032         node = *rnode;
 1033         node.sysctl_data = &mssdflt;
 1034         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1035         if (error || newp == NULL)
 1036                 return (error);
 1037 
 1038         if (mssdflt < 32)
 1039                 return (EINVAL);
 1040         tcp_mssdflt = mssdflt;
 1041 
 1042         return (0);
 1043 }
 1044 
 1045 /*
 1046  * sysctl helper routine for setting port related values under
 1047  * net.inet.ip and net.inet6.ip6.  does basic range checking and does
 1048  * additional checks for each type.  this code has placed in
 1049  * tcp_input.c since INET and INET6 both use the same tcp code.
 1050  *
 1051  * this helper is not static so that both inet and inet6 can use it.
 1052  */
 1053 int
 1054 sysctl_net_inet_ip_ports(SYSCTLFN_ARGS)
 1055 {
 1056         int error, tmp;
 1057         int apmin, apmax;
 1058 #ifndef IPNOPRIVPORTS
 1059         int lpmin, lpmax;
 1060 #endif /* IPNOPRIVPORTS */
 1061         struct sysctlnode node;
 1062 
 1063         if (namelen != 0)
 1064                 return (EINVAL);
 1065 
 1066         switch (name[-3]) {
 1067 #ifdef INET
 1068             case PF_INET:
 1069                 apmin = anonportmin;
 1070                 apmax = anonportmax;
 1071 #ifndef IPNOPRIVPORTS
 1072                 lpmin = lowportmin;
 1073                 lpmax = lowportmax;
 1074 #endif /* IPNOPRIVPORTS */
 1075                 break;
 1076 #endif /* INET */
 1077 #ifdef INET6
 1078             case PF_INET6:
 1079                 apmin = ip6_anonportmin;
 1080                 apmax = ip6_anonportmax;
 1081 #ifndef IPNOPRIVPORTS
 1082                 lpmin = ip6_lowportmin;
 1083                 lpmax = ip6_lowportmax;
 1084 #endif /* IPNOPRIVPORTS */
 1085                 break;
 1086 #endif /* INET6 */
 1087             default:
 1088                 return (EINVAL);
 1089         }
 1090 
 1091         /*
 1092          * insert temporary copy into node, perform lookup on
 1093          * temporary, then restore pointer
 1094          */
 1095         node = *rnode;
 1096         tmp = *(int*)rnode->sysctl_data;
 1097         node.sysctl_data = &tmp;
 1098         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1099         if (error || newp == NULL)
 1100                 return (error);
 1101 
 1102         /*
 1103          * simple port range check
 1104          */
 1105         if (tmp < 0 || tmp > 65535)
 1106                 return (EINVAL);
 1107 
 1108         /*
 1109          * per-node range checks
 1110          */
 1111         switch (rnode->sysctl_num) {
 1112         case IPCTL_ANONPORTMIN:
 1113                 if (tmp >= apmax)
 1114                         return (EINVAL);
 1115 #ifndef IPNOPRIVPORTS
 1116                 if (tmp < IPPORT_RESERVED)
 1117                         return (EINVAL);
 1118 #endif /* IPNOPRIVPORTS */
 1119                 break;
 1120 
 1121         case IPCTL_ANONPORTMAX:
 1122                 if (apmin >= tmp)
 1123                         return (EINVAL);
 1124 #ifndef IPNOPRIVPORTS
 1125                 if (tmp < IPPORT_RESERVED)
 1126                         return (EINVAL);
 1127 #endif /* IPNOPRIVPORTS */
 1128                 break;
 1129 
 1130 #ifndef IPNOPRIVPORTS
 1131         case IPCTL_LOWPORTMIN:
 1132                 if (tmp >= lpmax ||
 1133                     tmp > IPPORT_RESERVEDMAX ||
 1134                     tmp < IPPORT_RESERVEDMIN)
 1135                         return (EINVAL);
 1136                 break;
 1137 
 1138         case IPCTL_LOWPORTMAX:
 1139                 if (lpmin >= tmp ||
 1140                     tmp > IPPORT_RESERVEDMAX ||
 1141                     tmp < IPPORT_RESERVEDMIN)
 1142                         return (EINVAL);
 1143                 break;
 1144 #endif /* IPNOPRIVPORTS */
 1145 
 1146         default:
 1147                 return (EINVAL);
 1148         }
 1149 
 1150         *(int*)rnode->sysctl_data = tmp;
 1151 
 1152         return (0);
 1153 }
 1154 
 1155 /*
 1156  * The superuser can drop any connection.  Normal users can only drop
 1157  * their own connections.
 1158  */
 1159 static inline int
 1160 check_sockuid(struct socket *sockp, kauth_cred_t cred)
 1161 {
 1162         uid_t sockuid;
 1163 
 1164         sockuid = sockp->so_uidinfo->ui_uid;
 1165         if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) == 0 ||
 1166             sockuid == kauth_cred_getuid(cred) ||
 1167             sockuid == kauth_cred_geteuid(cred))
 1168                 return 0;
 1169         return EACCES;
 1170 }
 1171 
 1172 static inline int
 1173 copyout_uid(struct socket *sockp, void *oldp, size_t *oldlenp)
 1174 {
 1175         size_t sz;
 1176         int error;
 1177         uid_t uid;
 1178 
 1179         uid = sockp->so_uidinfo->ui_uid;
 1180         if (oldp) {
 1181                 sz = MIN(sizeof(uid), *oldlenp);
 1182                 error = copyout(&uid, oldp, sz);
 1183                 if (error)
 1184                         return error;
 1185         }
 1186         *oldlenp = sizeof(uid);
 1187         return 0;
 1188 }
 1189 
 1190 static inline int
 1191 inet4_ident_core(struct in_addr raddr, u_int rport,
 1192     struct in_addr laddr, u_int lport,
 1193     void *oldp, size_t *oldlenp,
 1194     struct lwp *l, int dodrop)
 1195 {
 1196         struct inpcb *inp;
 1197         struct socket *sockp;
 1198 
 1199         inp = in_pcblookup_connect(&tcbtable, raddr, rport, laddr, lport);
 1200         
 1201         if (inp == NULL || (sockp = inp->inp_socket) == NULL)
 1202                 return ESRCH;
 1203 
 1204         if (dodrop) {
 1205                 struct tcpcb *tp;
 1206                 
 1207                 if (inp == NULL || (tp = intotcpcb(inp)) == NULL ||
 1208                     (inp->inp_socket->so_options & SO_ACCEPTCONN) != 0)
 1209                         return ESRCH;
 1210                 
 1211                 if (check_sockuid(inp->inp_socket, l->l_cred) != 0)
 1212                         return EACCES;
 1213                 
 1214                 (void)tcp_drop(tp, ECONNABORTED);
 1215                 return 0;
 1216         }
 1217         else
 1218                 return copyout_uid(sockp, oldp, oldlenp);
 1219 }
 1220 
 1221 #ifdef INET6
 1222 static inline int
 1223 inet6_ident_core(struct in6_addr *raddr, u_int rport,
 1224     struct in6_addr *laddr, u_int lport,
 1225     void *oldp, size_t *oldlenp,
 1226     struct lwp *l, int dodrop)
 1227 {
 1228         struct in6pcb *in6p;
 1229         struct socket *sockp;
 1230 
 1231         in6p = in6_pcblookup_connect(&tcbtable, raddr, rport, laddr, lport, 0);
 1232 
 1233         if (in6p == NULL || (sockp = in6p->in6p_socket) == NULL)
 1234                 return ESRCH;
 1235         
 1236         if (dodrop) {
 1237                 struct tcpcb *tp;
 1238                 
 1239                 if (in6p == NULL || (tp = in6totcpcb(in6p)) == NULL ||
 1240                     (in6p->in6p_socket->so_options & SO_ACCEPTCONN) != 0)
 1241                         return ESRCH;
 1242 
 1243                 if (check_sockuid(in6p->in6p_socket, l->l_cred) != 0)
 1244                         return EACCES;
 1245 
 1246                 (void)tcp_drop(tp, ECONNABORTED);
 1247                 return 0;
 1248         }
 1249         else
 1250                 return copyout_uid(sockp, oldp, oldlenp);
 1251 }
 1252 #endif
 1253 
 1254 /*
 1255  * sysctl helper routine for the net.inet.tcp.drop and
 1256  * net.inet6.tcp6.drop nodes.
 1257  */
 1258 #define sysctl_net_inet_tcp_drop sysctl_net_inet_tcp_ident
 1259 
 1260 /*
 1261  * sysctl helper routine for the net.inet.tcp.ident and
 1262  * net.inet6.tcp6.ident nodes.  contains backwards compat code for the
 1263  * old way of looking up the ident information for ipv4 which involves
 1264  * stuffing the port/addr pairs into the mib lookup.
 1265  */
 1266 static int
 1267 sysctl_net_inet_tcp_ident(SYSCTLFN_ARGS)
 1268 {
 1269 #ifdef INET
 1270         struct sockaddr_in *si4[2];
 1271 #endif /* INET */
 1272 #ifdef INET6
 1273         struct sockaddr_in6 *si6[2];
 1274 #endif /* INET6 */
 1275         struct sockaddr_storage sa[2];
 1276         int error, pf, dodrop;
 1277 
 1278         dodrop = name[-1] == TCPCTL_DROP;
 1279         if (dodrop) {
 1280                 if (oldp != NULL || *oldlenp != 0)
 1281                         return EINVAL;
 1282                 if (newp == NULL)
 1283                         return EPERM;
 1284                 if (newlen < sizeof(sa))
 1285                         return ENOMEM;
 1286         }
 1287         if (namelen != 4 && namelen != 0)
 1288                 return EINVAL;
 1289         if (name[-2] != IPPROTO_TCP)
 1290                 return EINVAL;
 1291         pf = name[-3];
 1292 
 1293         /* old style lookup, ipv4 only */
 1294         if (namelen == 4) {
 1295 #ifdef INET
 1296                 struct in_addr laddr, raddr;
 1297                 u_int lport, rport;
 1298 
 1299                 if (pf != PF_INET)
 1300                         return EPROTONOSUPPORT;
 1301                 raddr.s_addr = (uint32_t)name[0];
 1302                 rport = (u_int)name[1];
 1303                 laddr.s_addr = (uint32_t)name[2];
 1304                 lport = (u_int)name[3];
 1305                 
 1306                 mutex_enter(softnet_lock);
 1307                 error = inet4_ident_core(raddr, rport, laddr, lport,
 1308                     oldp, oldlenp, l, dodrop);
 1309                 mutex_exit(softnet_lock);
 1310                 return error;
 1311 #else /* INET */
 1312                 return EINVAL;
 1313 #endif /* INET */
 1314         }
 1315 
 1316         if (newp == NULL || newlen != sizeof(sa))
 1317                 return EINVAL;
 1318         error = copyin(newp, &sa, newlen);
 1319         if (error)
 1320                 return error;
 1321 
 1322         /*
 1323          * requested families must match
 1324          */
 1325         if (pf != sa[0].ss_family || sa[0].ss_family != sa[1].ss_family)
 1326                 return EINVAL;
 1327 
 1328         switch (pf) {
 1329 #ifdef INET6
 1330         case PF_INET6:
 1331                 si6[0] = (struct sockaddr_in6*)&sa[0];
 1332                 si6[1] = (struct sockaddr_in6*)&sa[1];
 1333                 if (si6[0]->sin6_len != sizeof(*si6[0]) ||
 1334                     si6[1]->sin6_len != sizeof(*si6[1]))
 1335                         return EINVAL;
 1336 
 1337                 if (!IN6_IS_ADDR_V4MAPPED(&si6[0]->sin6_addr) &&
 1338                     !IN6_IS_ADDR_V4MAPPED(&si6[1]->sin6_addr)) {
 1339                         error = sa6_embedscope(si6[0], ip6_use_defzone);
 1340                         if (error)
 1341                                 return error;
 1342                         error = sa6_embedscope(si6[1], ip6_use_defzone);
 1343                         if (error)
 1344                                 return error;
 1345 
 1346                         mutex_enter(softnet_lock);
 1347                         error = inet6_ident_core(&si6[0]->sin6_addr,
 1348                             si6[0]->sin6_port, &si6[1]->sin6_addr,
 1349                             si6[1]->sin6_port, oldp, oldlenp, l, dodrop);
 1350                         mutex_exit(softnet_lock);
 1351                         return error;
 1352                 }
 1353 
 1354                 if (IN6_IS_ADDR_V4MAPPED(&si6[0]->sin6_addr) !=
 1355                     IN6_IS_ADDR_V4MAPPED(&si6[1]->sin6_addr))
 1356                         return EINVAL;
 1357 
 1358                 in6_sin6_2_sin_in_sock((struct sockaddr *)&sa[0]);
 1359                 in6_sin6_2_sin_in_sock((struct sockaddr *)&sa[1]);
 1360                 /*FALLTHROUGH*/
 1361 #endif /* INET6 */
 1362 #ifdef INET
 1363         case PF_INET:
 1364                 si4[0] = (struct sockaddr_in*)&sa[0];
 1365                 si4[1] = (struct sockaddr_in*)&sa[1];
 1366                 if (si4[0]->sin_len != sizeof(*si4[0]) ||
 1367                     si4[0]->sin_len != sizeof(*si4[1]))
 1368                         return EINVAL;
 1369         
 1370                 mutex_enter(softnet_lock);
 1371                 error = inet4_ident_core(si4[0]->sin_addr, si4[0]->sin_port,
 1372                     si4[1]->sin_addr, si4[1]->sin_port,
 1373                     oldp, oldlenp, l, dodrop);
 1374                 mutex_exit(softnet_lock);
 1375                 return error;
 1376 #endif /* INET */
 1377         default:
 1378                 return EPROTONOSUPPORT;
 1379         }
 1380 }
 1381 
 1382 /*
 1383  * sysctl helper for the inet and inet6 pcblists.  handles tcp/udp and
 1384  * inet/inet6, as well as raw pcbs for each.  specifically not
 1385  * declared static so that raw sockets and udp/udp6 can use it as
 1386  * well.
 1387  */
 1388 int
 1389 sysctl_inpcblist(SYSCTLFN_ARGS)
 1390 {
 1391 #ifdef INET
 1392         struct sockaddr_in *in;
 1393         const struct inpcb *inp;
 1394 #endif
 1395 #ifdef INET6
 1396         struct sockaddr_in6 *in6;
 1397         const struct in6pcb *in6p;
 1398 #endif
 1399         /*
 1400          * sysctl_data is const, but CIRCLEQ_FOREACH can't use a const
 1401          * struct inpcbtable pointer, so we have to discard const.  :-/
 1402          */
 1403         struct inpcbtable *pcbtbl = __UNCONST(rnode->sysctl_data);
 1404         const struct inpcb_hdr *inph;
 1405         struct tcpcb *tp;
 1406         struct kinfo_pcb pcb;
 1407         char *dp;
 1408         u_int op, arg;
 1409         size_t len, needed, elem_size, out_size;
 1410         int error, elem_count, pf, proto, pf2;
 1411 
 1412         if (namelen != 4)
 1413                 return (EINVAL);
 1414 
 1415         if (oldp != NULL) {
 1416                     len = *oldlenp;
 1417                     elem_size = name[2];
 1418                     elem_count = name[3];
 1419                     if (elem_size != sizeof(pcb))
 1420                             return EINVAL;
 1421         } else {
 1422                     len = 0;
 1423                     elem_count = INT_MAX;
 1424                     elem_size = sizeof(pcb);
 1425         }
 1426         error = 0;
 1427         dp = oldp;
 1428         op = name[0];
 1429         arg = name[1];
 1430         out_size = elem_size;
 1431         needed = 0;
 1432 
 1433         if (namelen == 1 && name[0] == CTL_QUERY)
 1434                 return (sysctl_query(SYSCTLFN_CALL(rnode)));
 1435 
 1436         if (name - oname != 4)
 1437                 return (EINVAL);
 1438 
 1439         pf = oname[1];
 1440         proto = oname[2];
 1441         pf2 = (oldp != NULL) ? pf : 0;
 1442 
 1443         mutex_enter(softnet_lock);
 1444 
 1445         CIRCLEQ_FOREACH(inph, &pcbtbl->inpt_queue, inph_queue) {
 1446 #ifdef INET
 1447                 inp = (const struct inpcb *)inph;
 1448 #endif
 1449 #ifdef INET6
 1450                 in6p = (const struct in6pcb *)inph;
 1451 #endif
 1452 
 1453                 if (inph->inph_af != pf)
 1454                         continue;
 1455 
 1456                 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
 1457                     KAUTH_REQ_NETWORK_SOCKET_CANSEE, inph->inph_socket, NULL,
 1458                     NULL) != 0)
 1459                         continue;
 1460 
 1461                 memset(&pcb, 0, sizeof(pcb));
 1462 
 1463                 pcb.ki_family = pf;
 1464                 pcb.ki_type = proto;
 1465 
 1466                 switch (pf2) {
 1467                 case 0:
 1468                         /* just probing for size */
 1469                         break;
 1470 #ifdef INET
 1471                 case PF_INET:
 1472                         pcb.ki_family = inp->inp_socket->so_proto->
 1473                             pr_domain->dom_family;
 1474                         pcb.ki_type = inp->inp_socket->so_proto->
 1475                             pr_type;
 1476                         pcb.ki_protocol = inp->inp_socket->so_proto->
 1477                             pr_protocol;
 1478                         pcb.ki_pflags = inp->inp_flags;
 1479 
 1480                         pcb.ki_sostate = inp->inp_socket->so_state;
 1481                         pcb.ki_prstate = inp->inp_state;
 1482                         if (proto == IPPROTO_TCP) {
 1483                                 tp = intotcpcb(inp);
 1484                                 pcb.ki_tstate = tp->t_state;
 1485                                 pcb.ki_tflags = tp->t_flags;
 1486                         }
 1487 
 1488                         pcb.ki_pcbaddr = PTRTOUINT64(inp);
 1489                         pcb.ki_ppcbaddr = PTRTOUINT64(inp->inp_ppcb);
 1490                         pcb.ki_sockaddr = PTRTOUINT64(inp->inp_socket);
 1491 
 1492                         pcb.ki_rcvq = inp->inp_socket->so_rcv.sb_cc;
 1493                         pcb.ki_sndq = inp->inp_socket->so_snd.sb_cc;
 1494 
 1495                         in = satosin(&pcb.ki_src);
 1496                         in->sin_len = sizeof(*in);
 1497                         in->sin_family = pf;
 1498                         in->sin_port = inp->inp_lport;
 1499                         in->sin_addr = inp->inp_laddr;
 1500                         if (pcb.ki_prstate >= INP_CONNECTED) {
 1501                                 in = satosin(&pcb.ki_dst);
 1502                                 in->sin_len = sizeof(*in);
 1503                                 in->sin_family = pf;
 1504                                 in->sin_port = inp->inp_fport;
 1505                                 in->sin_addr = inp->inp_faddr;
 1506                         }
 1507                         break;
 1508 #endif
 1509 #ifdef INET6
 1510                 case PF_INET6:
 1511                         pcb.ki_family = in6p->in6p_socket->so_proto->
 1512                             pr_domain->dom_family;
 1513                         pcb.ki_type = in6p->in6p_socket->so_proto->pr_type;
 1514                         pcb.ki_protocol = in6p->in6p_socket->so_proto->
 1515                             pr_protocol;
 1516                         pcb.ki_pflags = in6p->in6p_flags;
 1517 
 1518                         pcb.ki_sostate = in6p->in6p_socket->so_state;
 1519                         pcb.ki_prstate = in6p->in6p_state;
 1520                         if (proto == IPPROTO_TCP) {
 1521                                 tp = in6totcpcb(in6p);
 1522                                 pcb.ki_tstate = tp->t_state;
 1523                                 pcb.ki_tflags = tp->t_flags;
 1524                         }
 1525 
 1526                         pcb.ki_pcbaddr = PTRTOUINT64(in6p);
 1527                         pcb.ki_ppcbaddr = PTRTOUINT64(in6p->in6p_ppcb);
 1528                         pcb.ki_sockaddr = PTRTOUINT64(in6p->in6p_socket);
 1529 
 1530                         pcb.ki_rcvq = in6p->in6p_socket->so_rcv.sb_cc;
 1531                         pcb.ki_sndq = in6p->in6p_socket->so_snd.sb_cc;
 1532 
 1533                         in6 = satosin6(&pcb.ki_src);
 1534                         in6->sin6_len = sizeof(*in6);
 1535                         in6->sin6_family = pf;
 1536                         in6->sin6_port = in6p->in6p_lport;
 1537                         in6->sin6_flowinfo = in6p->in6p_flowinfo;
 1538                         in6->sin6_addr = in6p->in6p_laddr;
 1539                         in6->sin6_scope_id = 0; /* XXX? */
 1540 
 1541                         if (pcb.ki_prstate >= IN6P_CONNECTED) {
 1542                                 in6 = satosin6(&pcb.ki_dst);
 1543                                 in6->sin6_len = sizeof(*in6);
 1544                                 in6->sin6_family = pf;
 1545                                 in6->sin6_port = in6p->in6p_fport;
 1546                                 in6->sin6_flowinfo = in6p->in6p_flowinfo;
 1547                                 in6->sin6_addr = in6p->in6p_faddr;
 1548                                 in6->sin6_scope_id = 0; /* XXX? */
 1549                         }
 1550                         break;
 1551 #endif
 1552                 }
 1553 
 1554                 if (len >= elem_size && elem_count > 0) {
 1555                         error = copyout(&pcb, dp, out_size);
 1556                         if (error) {
 1557                                 mutex_exit(softnet_lock);
 1558                                 return (error);
 1559                         }
 1560                         dp += elem_size;
 1561                         len -= elem_size;
 1562                 }
 1563                 if (elem_count > 0) {
 1564                         needed += elem_size;
 1565                         if (elem_count != INT_MAX)
 1566                                 elem_count--;
 1567                 }
 1568         }
 1569 
 1570         *oldlenp = needed;
 1571         if (oldp == NULL)
 1572                 *oldlenp += PCB_SLOP * sizeof(struct kinfo_pcb);
 1573 
 1574         mutex_exit(softnet_lock);
 1575 
 1576         return (error);
 1577 }
 1578 
 1579 static int
 1580 sysctl_tcp_congctl(SYSCTLFN_ARGS)
 1581 {
 1582         struct sysctlnode node;
 1583         int error;
 1584         char newname[TCPCC_MAXLEN];
 1585 
 1586         strlcpy(newname, tcp_congctl_global_name, sizeof(newname) - 1);
 1587         
 1588         node = *rnode;
 1589         node.sysctl_data = newname;
 1590         node.sysctl_size = sizeof(newname);
 1591 
 1592         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1593         
 1594         if (error || 
 1595             newp == NULL ||
 1596             strncmp(newname, tcp_congctl_global_name, sizeof(newname)) == 0)
 1597                 return error;
 1598 
 1599         mutex_enter(softnet_lock);
 1600         error = tcp_congctl_select(NULL, newname);
 1601         mutex_exit(softnet_lock);
 1602 
 1603         return error;
 1604 }
 1605 
 1606 static int
 1607 sysctl_tcp_keep(SYSCTLFN_ARGS)
 1608 {  
 1609         int error;
 1610         u_int tmp;
 1611         struct sysctlnode node;
 1612 
 1613         node = *rnode;
 1614         tmp = *(u_int *)rnode->sysctl_data;
 1615         node.sysctl_data = &tmp;
 1616 
 1617         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1618         if (error || newp == NULL)
 1619                 return error;
 1620 
 1621         mutex_enter(softnet_lock);
 1622 
 1623         *(u_int *)rnode->sysctl_data = tmp;
 1624         tcp_tcpcb_template();   /* update the template */
 1625 
 1626         mutex_exit(softnet_lock);
 1627         return 0;
 1628 }
 1629 
 1630 static int
 1631 sysctl_net_inet_tcp_stats(SYSCTLFN_ARGS)
 1632 {
 1633 
 1634         return (NETSTAT_SYSCTL(tcpstat_percpu, TCP_NSTATS));
 1635 }
 1636 
 1637 /*
 1638  * this (second stage) setup routine is a replacement for tcp_sysctl()
 1639  * (which is currently used for ipv4 and ipv6)
 1640  */
 1641 static void
 1642 sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
 1643                            const char *tcpname)
 1644 {
 1645         const struct sysctlnode *sack_node;
 1646         const struct sysctlnode *abc_node;
 1647         const struct sysctlnode *ecn_node;
 1648         const struct sysctlnode *congctl_node;
 1649 #ifdef TCP_DEBUG
 1650         extern struct tcp_debug tcp_debug[TCP_NDEBUG];
 1651         extern int tcp_debx;
 1652 #endif
 1653 
 1654         sysctl_createv(clog, 0, NULL, NULL,
 1655                        CTLFLAG_PERMANENT,
 1656                        CTLTYPE_NODE, "net", NULL,
 1657                        NULL, 0, NULL, 0,
 1658                        CTL_NET, CTL_EOL);
 1659         sysctl_createv(clog, 0, NULL, NULL,
 1660                        CTLFLAG_PERMANENT,
 1661                        CTLTYPE_NODE, pfname, NULL,
 1662                        NULL, 0, NULL, 0,
 1663                        CTL_NET, pf, CTL_EOL);
 1664         sysctl_createv(clog, 0, NULL, NULL,
 1665                        CTLFLAG_PERMANENT,
 1666                        CTLTYPE_NODE, tcpname,
 1667                        SYSCTL_DESCR("TCP related settings"),
 1668                        NULL, 0, NULL, 0,
 1669                        CTL_NET, pf, IPPROTO_TCP, CTL_EOL);
 1670 
 1671         sysctl_createv(clog, 0, NULL, NULL,
 1672                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1673                        CTLTYPE_INT, "rfc1323",
 1674                        SYSCTL_DESCR("Enable RFC1323 TCP extensions"),
 1675                        NULL, 0, &tcp_do_rfc1323, 0,
 1676                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RFC1323, CTL_EOL);
 1677         sysctl_createv(clog, 0, NULL, NULL,
 1678                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1679                        CTLTYPE_INT, "sendspace",
 1680                        SYSCTL_DESCR("Default TCP send buffer size"),
 1681                        NULL, 0, &tcp_sendspace, 0,
 1682                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SENDSPACE, CTL_EOL);
 1683         sysctl_createv(clog, 0, NULL, NULL,
 1684                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1685                        CTLTYPE_INT, "recvspace",
 1686                        SYSCTL_DESCR("Default TCP receive buffer size"),
 1687                        NULL, 0, &tcp_recvspace, 0,
 1688                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RECVSPACE, CTL_EOL);
 1689         sysctl_createv(clog, 0, NULL, NULL,
 1690                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1691                        CTLTYPE_INT, "mssdflt",
 1692                        SYSCTL_DESCR("Default maximum segment size"),
 1693                        sysctl_net_inet_tcp_mssdflt, 0, &tcp_mssdflt, 0,
 1694                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSSDFLT, CTL_EOL);
 1695         sysctl_createv(clog, 0, NULL, NULL,
 1696                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1697                        CTLTYPE_INT, "minmss",
 1698                        SYSCTL_DESCR("Lower limit for TCP maximum segment size"),
 1699                        NULL, 0, &tcp_minmss, 0,
 1700                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1701         sysctl_createv(clog, 0, NULL, NULL,
 1702                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1703                        CTLTYPE_INT, "msl",
 1704                        SYSCTL_DESCR("Maximum Segment Life"),
 1705                        NULL, 0, &tcp_msl, 0,
 1706                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSL, CTL_EOL);
 1707         sysctl_createv(clog, 0, NULL, NULL,
 1708                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1709                        CTLTYPE_INT, "syn_cache_limit",
 1710                        SYSCTL_DESCR("Maximum number of entries in the TCP "
 1711                                     "compressed state engine"),
 1712                        NULL, 0, &tcp_syn_cache_limit, 0,
 1713                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_LIMIT,
 1714                        CTL_EOL);
 1715         sysctl_createv(clog, 0, NULL, NULL,
 1716                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1717                        CTLTYPE_INT, "syn_bucket_limit",
 1718                        SYSCTL_DESCR("Maximum number of entries per hash "
 1719                                     "bucket in the TCP compressed state "
 1720                                     "engine"),
 1721                        NULL, 0, &tcp_syn_bucket_limit, 0,
 1722                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_BUCKET_LIMIT,
 1723                        CTL_EOL);
 1724 #if 0 /* obsoleted */
 1725         sysctl_createv(clog, 0, NULL, NULL,
 1726                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1727                        CTLTYPE_INT, "syn_cache_interval",
 1728                        SYSCTL_DESCR("TCP compressed state engine's timer interval"),
 1729                        NULL, 0, &tcp_syn_cache_interval, 0,
 1730                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_INTER,
 1731                        CTL_EOL);
 1732 #endif
 1733         sysctl_createv(clog, 0, NULL, NULL,
 1734                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1735                        CTLTYPE_INT, "init_win",
 1736                        SYSCTL_DESCR("Initial TCP congestion window"),
 1737                        NULL, 0, &tcp_init_win, 0,
 1738                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN, CTL_EOL);
 1739         sysctl_createv(clog, 0, NULL, NULL,
 1740                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1741                        CTLTYPE_INT, "mss_ifmtu",
 1742                        SYSCTL_DESCR("Use interface MTU for calculating MSS"),
 1743                        NULL, 0, &tcp_mss_ifmtu, 0,
 1744                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSS_IFMTU, CTL_EOL);
 1745         sysctl_createv(clog, 0, NULL, &sack_node,
 1746                        CTLFLAG_PERMANENT,
 1747                        CTLTYPE_NODE, "sack",
 1748                        SYSCTL_DESCR("RFC2018 Selective ACKnowledgement tunables"),
 1749                        NULL, 0, NULL, 0,
 1750                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_EOL);
 1751 
 1752         /* Congctl subtree */
 1753         sysctl_createv(clog, 0, NULL, &congctl_node,
 1754                        CTLFLAG_PERMANENT,
 1755                        CTLTYPE_NODE, "congctl",
 1756                        SYSCTL_DESCR("TCP Congestion Control"),
 1757                        NULL, 0, NULL, 0,
 1758                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1759         sysctl_createv(clog, 0, &congctl_node, NULL,
 1760                        CTLFLAG_PERMANENT,
 1761                        CTLTYPE_STRING, "available",
 1762                        SYSCTL_DESCR("Available Congestion Control Mechanisms"),
 1763                        NULL, 0, &tcp_congctl_avail, 0, CTL_CREATE, CTL_EOL);
 1764         sysctl_createv(clog, 0, &congctl_node, NULL,
 1765                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1766                        CTLTYPE_STRING, "selected",
 1767                        SYSCTL_DESCR("Selected Congestion Control Mechanism"),
 1768                        sysctl_tcp_congctl, 0, NULL, TCPCC_MAXLEN,
 1769                        CTL_CREATE, CTL_EOL);
 1770 
 1771         sysctl_createv(clog, 0, NULL, NULL,
 1772                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1773                        CTLTYPE_INT, "win_scale",
 1774                        SYSCTL_DESCR("Use RFC1323 window scale options"),
 1775                        NULL, 0, &tcp_do_win_scale, 0,
 1776                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_WSCALE, CTL_EOL);
 1777         sysctl_createv(clog, 0, NULL, NULL,
 1778                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1779                        CTLTYPE_INT, "timestamps",
 1780                        SYSCTL_DESCR("Use RFC1323 time stamp options"),
 1781                        NULL, 0, &tcp_do_timestamps, 0,
 1782                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_TSTAMP, CTL_EOL);
 1783         sysctl_createv(clog, 0, NULL, NULL,
 1784                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1785                        CTLTYPE_INT, "compat_42",
 1786                        SYSCTL_DESCR("Enable workarounds for 4.2BSD TCP bugs"),
 1787                        NULL, 0, &tcp_compat_42, 0,
 1788                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_COMPAT_42, CTL_EOL);
 1789         sysctl_createv(clog, 0, NULL, NULL,
 1790                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1791                        CTLTYPE_INT, "cwm",
 1792                        SYSCTL_DESCR("Hughes/Touch/Heidemann Congestion Window "
 1793                                     "Monitoring"),
 1794                        NULL, 0, &tcp_cwm, 0,
 1795                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM, CTL_EOL);
 1796         sysctl_createv(clog, 0, NULL, NULL,
 1797                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1798                        CTLTYPE_INT, "cwm_burstsize",
 1799                        SYSCTL_DESCR("Congestion Window Monitoring allowed "
 1800                                     "burst count in packets"),
 1801                        NULL, 0, &tcp_cwm_burstsize, 0,
 1802                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM_BURSTSIZE,
 1803                        CTL_EOL);
 1804         sysctl_createv(clog, 0, NULL, NULL,
 1805                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1806                        CTLTYPE_INT, "ack_on_push",
 1807                        SYSCTL_DESCR("Immediately return ACK when PSH is "
 1808                                     "received"),
 1809                        NULL, 0, &tcp_ack_on_push, 0,
 1810                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_ACK_ON_PUSH, CTL_EOL);
 1811         sysctl_createv(clog, 0, NULL, NULL,
 1812                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1813                        CTLTYPE_INT, "keepidle",
 1814                        SYSCTL_DESCR("Allowed connection idle ticks before a "
 1815                                     "keepalive probe is sent"),
 1816                        sysctl_tcp_keep, 0, &tcp_keepidle, 0,
 1817                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPIDLE, CTL_EOL);
 1818         sysctl_createv(clog, 0, NULL, NULL,
 1819                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1820                        CTLTYPE_INT, "keepintvl",
 1821                        SYSCTL_DESCR("Ticks before next keepalive probe is sent"),
 1822                        sysctl_tcp_keep, 0, &tcp_keepintvl, 0,
 1823                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPINTVL, CTL_EOL);
 1824         sysctl_createv(clog, 0, NULL, NULL,
 1825                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1826                        CTLTYPE_INT, "keepcnt",
 1827                        SYSCTL_DESCR("Number of keepalive probes to send"),
 1828                        sysctl_tcp_keep, 0, &tcp_keepcnt, 0,
 1829                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPCNT, CTL_EOL);
 1830         sysctl_createv(clog, 0, NULL, NULL,
 1831                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
 1832                        CTLTYPE_INT, "slowhz",
 1833                        SYSCTL_DESCR("Keepalive ticks per second"),
 1834                        NULL, PR_SLOWHZ, NULL, 0,
 1835                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SLOWHZ, CTL_EOL);
 1836         sysctl_createv(clog, 0, NULL, NULL,
 1837                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1838                        CTLTYPE_INT, "log_refused",
 1839                        SYSCTL_DESCR("Log refused TCP connections"),
 1840                        NULL, 0, &tcp_log_refused, 0,
 1841                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOG_REFUSED, CTL_EOL);
 1842 #if 0 /* obsoleted */
 1843         sysctl_createv(clog, 0, NULL, NULL,
 1844                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1845                        CTLTYPE_INT, "rstratelimit", NULL,
 1846                        NULL, 0, &tcp_rst_ratelim, 0,
 1847                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTRATELIMIT, CTL_EOL);
 1848 #endif
 1849         sysctl_createv(clog, 0, NULL, NULL,
 1850                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1851                        CTLTYPE_INT, "rstppslimit",
 1852                        SYSCTL_DESCR("Maximum number of RST packets to send "
 1853                                     "per second"),
 1854                        NULL, 0, &tcp_rst_ppslim, 0,
 1855                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTPPSLIMIT, CTL_EOL);
 1856         sysctl_createv(clog, 0, NULL, NULL,
 1857                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1858                        CTLTYPE_INT, "delack_ticks",
 1859                        SYSCTL_DESCR("Number of ticks to delay sending an ACK"),
 1860                        NULL, 0, &tcp_delack_ticks, 0,
 1861                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_DELACK_TICKS, CTL_EOL);
 1862         sysctl_createv(clog, 0, NULL, NULL,
 1863                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1864                        CTLTYPE_INT, "init_win_local",
 1865                        SYSCTL_DESCR("Initial TCP window size (in segments)"),
 1866                        NULL, 0, &tcp_init_win_local, 0,
 1867                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN_LOCAL,
 1868                        CTL_EOL);
 1869         sysctl_createv(clog, 0, NULL, NULL,
 1870                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1871                        CTLTYPE_STRUCT, "ident",
 1872                        SYSCTL_DESCR("RFC1413 Identification Protocol lookups"),
 1873                        sysctl_net_inet_tcp_ident, 0, NULL, sizeof(uid_t),
 1874                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_IDENT, CTL_EOL);
 1875         sysctl_createv(clog, 0, NULL, NULL,
 1876                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1877                        CTLTYPE_INT, "do_loopback_cksum",
 1878                        SYSCTL_DESCR("Perform TCP checksum on loopback"),
 1879                        NULL, 0, &tcp_do_loopback_cksum, 0,
 1880                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOOPBACKCKSUM,
 1881                        CTL_EOL);
 1882         sysctl_createv(clog, 0, NULL, NULL,
 1883                        CTLFLAG_PERMANENT,
 1884                        CTLTYPE_STRUCT, "pcblist",
 1885                        SYSCTL_DESCR("TCP protocol control block list"),
 1886                        sysctl_inpcblist, 0, &tcbtable, 0,
 1887                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE,
 1888                        CTL_EOL);
 1889         sysctl_createv(clog, 0, NULL, NULL,
 1890                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1891                        CTLTYPE_INT, "keepinit",
 1892                        SYSCTL_DESCR("Ticks before initial tcp connection times out"),
 1893                        sysctl_tcp_keep, 0, &tcp_keepinit, 0,
 1894                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1895 
 1896         /* TCP socket buffers auto-sizing nodes */
 1897         sysctl_createv(clog, 0, NULL, NULL,
 1898                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1899                        CTLTYPE_INT, "recvbuf_auto",
 1900                        SYSCTL_DESCR("Enable automatic receive "
 1901                            "buffer sizing (experimental)"),
 1902                        NULL, 0, &tcp_do_autorcvbuf, 0,
 1903                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1904         sysctl_createv(clog, 0, NULL, NULL,
 1905                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1906                        CTLTYPE_INT, "recvbuf_inc",
 1907                        SYSCTL_DESCR("Incrementor step size of "
 1908                            "automatic receive buffer"),
 1909                        NULL, 0, &tcp_autorcvbuf_inc, 0,
 1910                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1911         sysctl_createv(clog, 0, NULL, NULL,
 1912                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1913                        CTLTYPE_INT, "recvbuf_max",
 1914                        SYSCTL_DESCR("Max size of automatic receive buffer"),
 1915                        NULL, 0, &tcp_autorcvbuf_max, 0,
 1916                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1917 
 1918         sysctl_createv(clog, 0, NULL, NULL,
 1919                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1920                        CTLTYPE_INT, "sendbuf_auto",
 1921                        SYSCTL_DESCR("Enable automatic send "
 1922                            "buffer sizing (experimental)"),
 1923                        NULL, 0, &tcp_do_autosndbuf, 0,
 1924                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1925         sysctl_createv(clog, 0, NULL, NULL,
 1926                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1927                        CTLTYPE_INT, "sendbuf_inc",
 1928                        SYSCTL_DESCR("Incrementor step size of "
 1929                            "automatic send buffer"),
 1930                        NULL, 0, &tcp_autosndbuf_inc, 0,
 1931                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1932         sysctl_createv(clog, 0, NULL, NULL,
 1933                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1934                        CTLTYPE_INT, "sendbuf_max",
 1935                        SYSCTL_DESCR("Max size of automatic send buffer"),
 1936                        NULL, 0, &tcp_autosndbuf_max, 0,
 1937                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1938 
 1939         /* ECN subtree */
 1940         sysctl_createv(clog, 0, NULL, &ecn_node,
 1941                        CTLFLAG_PERMANENT,
 1942                        CTLTYPE_NODE, "ecn",
 1943                        SYSCTL_DESCR("RFC3168 Explicit Congestion Notification"),
 1944                        NULL, 0, NULL, 0,
 1945                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 1946         sysctl_createv(clog, 0, &ecn_node, NULL,
 1947                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1948                        CTLTYPE_INT, "enable",
 1949                        SYSCTL_DESCR("Enable TCP Explicit Congestion "
 1950                            "Notification"),
 1951                        NULL, 0, &tcp_do_ecn, 0, CTL_CREATE, CTL_EOL);
 1952         sysctl_createv(clog, 0, &ecn_node, NULL,
 1953                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1954                        CTLTYPE_INT, "maxretries",
 1955                        SYSCTL_DESCR("Number of times to retry ECN setup "
 1956                                "before disabling ECN on the connection"),
 1957                        NULL, 0, &tcp_ecn_maxretries, 0, CTL_CREATE, CTL_EOL);
 1958         
 1959         /* SACK gets it's own little subtree. */
 1960         sysctl_createv(clog, 0, NULL, &sack_node,
 1961                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1962                        CTLTYPE_INT, "enable",
 1963                        SYSCTL_DESCR("Enable RFC2018 Selective ACKnowledgement"),
 1964                        NULL, 0, &tcp_do_sack, 0,
 1965                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
 1966         sysctl_createv(clog, 0, NULL, &sack_node,
 1967                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1968                        CTLTYPE_INT, "maxholes",
 1969                        SYSCTL_DESCR("Maximum number of TCP SACK holes allowed per connection"),
 1970                        NULL, 0, &tcp_sack_tp_maxholes, 0,
 1971                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
 1972         sysctl_createv(clog, 0, NULL, &sack_node,
 1973                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1974                        CTLTYPE_INT, "globalmaxholes",
 1975                        SYSCTL_DESCR("Global maximum number of TCP SACK holes"),
 1976                        NULL, 0, &tcp_sack_globalmaxholes, 0,
 1977                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
 1978         sysctl_createv(clog, 0, NULL, &sack_node,
 1979                        CTLFLAG_PERMANENT,
 1980                        CTLTYPE_INT, "globalholes",
 1981                        SYSCTL_DESCR("Global number of TCP SACK holes"),
 1982                        NULL, 0, &tcp_sack_globalholes, 0,
 1983                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_CREATE, CTL_EOL);
 1984 
 1985         sysctl_createv(clog, 0, NULL, NULL,
 1986                        CTLFLAG_PERMANENT,
 1987                        CTLTYPE_STRUCT, "stats",
 1988                        SYSCTL_DESCR("TCP statistics"),
 1989                        sysctl_net_inet_tcp_stats, 0, NULL, 0,
 1990                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_STATS,
 1991                        CTL_EOL);
 1992 #ifdef TCP_DEBUG
 1993         sysctl_createv(clog, 0, NULL, NULL,
 1994                        CTLFLAG_PERMANENT,
 1995                        CTLTYPE_STRUCT, "debug",
 1996                        SYSCTL_DESCR("TCP sockets debug information"),
 1997                        NULL, 0, &tcp_debug, sizeof(tcp_debug),
 1998                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_DEBUG,
 1999                        CTL_EOL);
 2000         sysctl_createv(clog, 0, NULL, NULL,
 2001                        CTLFLAG_PERMANENT,
 2002                        CTLTYPE_INT, "debx",
 2003                        SYSCTL_DESCR("Number of TCP debug sockets messages"),
 2004                        NULL, 0, &tcp_debx, sizeof(tcp_debx),
 2005                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_DEBX,
 2006                        CTL_EOL);
 2007 #endif
 2008         sysctl_createv(clog, 0, NULL, NULL,
 2009                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 2010                        CTLTYPE_STRUCT, "drop",
 2011                        SYSCTL_DESCR("TCP drop connection"),
 2012                        sysctl_net_inet_tcp_drop, 0, NULL, 0,
 2013                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_DROP, CTL_EOL);
 2014 #if NRND > 0
 2015         sysctl_createv(clog, 0, NULL, NULL,
 2016                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 2017                        CTLTYPE_INT, "iss_hash",
 2018                        SYSCTL_DESCR("Enable RFC 1948 ISS by cryptographic "
 2019                                     "hash computation"),
 2020                        NULL, 0, &tcp_do_rfc1948, sizeof(tcp_do_rfc1948),
 2021                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE,
 2022                        CTL_EOL);
 2023 #endif
 2024 
 2025         /* ABC subtree */
 2026 
 2027         sysctl_createv(clog, 0, NULL, &abc_node,
 2028                        CTLFLAG_PERMANENT, CTLTYPE_NODE, "abc",
 2029                        SYSCTL_DESCR("RFC3465 Appropriate Byte Counting (ABC)"),
 2030                        NULL, 0, NULL, 0,
 2031                        CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
 2032         sysctl_createv(clog, 0, &abc_node, NULL,
 2033                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 2034                        CTLTYPE_INT, "enable",
 2035                        SYSCTL_DESCR("Enable RFC3465 Appropriate Byte Counting"),
 2036                        NULL, 0, &tcp_do_abc, 0, CTL_CREATE, CTL_EOL);
 2037         sysctl_createv(clog, 0, &abc_node, NULL,
 2038                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 2039                        CTLTYPE_INT, "aggressive",
 2040                        SYSCTL_DESCR("1: L=2*SMSS 0: L=1*SMSS"),
 2041                        NULL, 0, &tcp_abc_aggressive, 0, CTL_CREATE, CTL_EOL);
 2042 }
 2043 
 2044 /*
 2045  * Sysctl for tcp variables.
 2046  */
 2047 #ifdef INET
 2048 SYSCTL_SETUP(sysctl_net_inet_tcp_setup, "sysctl net.inet.tcp subtree setup")
 2049 {
 2050 
 2051         sysctl_net_inet_tcp_setup2(clog, PF_INET, "inet", "tcp");
 2052 }
 2053 #endif /* INET */
 2054 
 2055 #ifdef INET6
 2056 SYSCTL_SETUP(sysctl_net_inet6_tcp6_setup, "sysctl net.inet6.tcp6 subtree setup")
 2057 {
 2058 
 2059         sysctl_net_inet_tcp_setup2(clog, PF_INET6, "inet6", "tcp6");
 2060 }
 2061 #endif /* INET6 */

Cache object: cf3107adbfe03046977ad60f156472d0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.