Print this page
    
OS-4018 lxbrand support TCP SO_REUSEPORT
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Cody Mello <cody.mello@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/inet/tcp/tcp.c
          +++ new/usr/src/uts/common/inet/tcp/tcp.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright (c) 2011, Joyent Inc. All rights reserved.
       24 + * Copyright 2015 Joyent, Inc.
  25   25   * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  26   26   * Copyright (c) 2013,2014 by Delphix. All rights reserved.
  27   27   * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  28   28   */
  29   29  /* Copyright (c) 1990 Mentat Inc. */
  30   30  
  31   31  #include <sys/types.h>
  32   32  #include <sys/stream.h>
  33   33  #include <sys/strsun.h>
  34   34  #include <sys/strsubr.h>
  35   35  #include <sys/stropts.h>
  36   36  #include <sys/strlog.h>
  37   37  #define _SUN_TPI_VERSION 2
  38   38  #include <sys/tihdr.h>
  39   39  #include <sys/timod.h>
  40   40  #include <sys/ddi.h>
  41   41  #include <sys/sunddi.h>
  42   42  #include <sys/suntpi.h>
  43   43  #include <sys/xti_inet.h>
  44   44  #include <sys/cmn_err.h>
  45   45  #include <sys/debug.h>
  46   46  #include <sys/sdt.h>
  47   47  #include <sys/vtrace.h>
  48   48  #include <sys/kmem.h>
  49   49  #include <sys/ethernet.h>
  50   50  #include <sys/cpuvar.h>
  51   51  #include <sys/dlpi.h>
  52   52  #include <sys/pattr.h>
  53   53  #include <sys/policy.h>
  54   54  #include <sys/priv.h>
  55   55  #include <sys/zone.h>
  56   56  #include <sys/sunldi.h>
  57   57  
  58   58  #include <sys/errno.h>
  59   59  #include <sys/signal.h>
  60   60  #include <sys/socket.h>
  61   61  #include <sys/socketvar.h>
  62   62  #include <sys/sockio.h>
  63   63  #include <sys/isa_defs.h>
  64   64  #include <sys/md5.h>
  65   65  #include <sys/random.h>
  66   66  #include <sys/uio.h>
  67   67  #include <sys/systm.h>
  68   68  #include <netinet/in.h>
  69   69  #include <netinet/tcp.h>
  70   70  #include <netinet/ip6.h>
  71   71  #include <netinet/icmp6.h>
  72   72  #include <net/if.h>
  73   73  #include <net/route.h>
  74   74  #include <inet/ipsec_impl.h>
  75   75  
  76   76  #include <inet/common.h>
  77   77  #include <inet/ip.h>
  78   78  #include <inet/ip_impl.h>
  79   79  #include <inet/ip6.h>
  80   80  #include <inet/ip_ndp.h>
  81   81  #include <inet/proto_set.h>
  82   82  #include <inet/mib2.h>
  83   83  #include <inet/optcom.h>
  84   84  #include <inet/snmpcom.h>
  85   85  #include <inet/kstatcom.h>
  86   86  #include <inet/tcp.h>
  87   87  #include <inet/tcp_impl.h>
  88   88  #include <inet/tcp_cluster.h>
  89   89  #include <inet/udp_impl.h>
  90   90  #include <net/pfkeyv2.h>
  91   91  #include <inet/ipdrop.h>
  92   92  
  93   93  #include <inet/ipclassifier.h>
  94   94  #include <inet/ip_ire.h>
  95   95  #include <inet/ip_ftable.h>
  96   96  #include <inet/ip_if.h>
  97   97  #include <inet/ipp_common.h>
  98   98  #include <inet/ip_rts.h>
  99   99  #include <inet/ip_netinfo.h>
 100  100  #include <sys/squeue_impl.h>
 101  101  #include <sys/squeue.h>
 102  102  #include <sys/tsol/label.h>
 103  103  #include <sys/tsol/tnet.h>
 104  104  #include <rpc/pmap_prot.h>
 105  105  #include <sys/callo.h>
 106  106  
 107  107  /*
 108  108   * TCP Notes: aka FireEngine Phase I (PSARC 2002/433)
 109  109   *
 110  110   * (Read the detailed design doc in PSARC case directory)
 111  111   *
 112  112   * The entire tcp state is contained in tcp_t and conn_t structure
 113  113   * which are allocated in tandem using ipcl_conn_create() and passing
 114  114   * IPCL_TCPCONN as a flag. We use 'conn_ref' and 'conn_lock' to protect
 115  115   * the references on the tcp_t. The tcp_t structure is never compressed
 116  116   * and packets always land on the correct TCP perimeter from the time
 117  117   * eager is created till the time tcp_t dies (as such the old mentat
 118  118   * TCP global queue is not used for detached state and no IPSEC checking
 119  119   * is required). The global queue is still allocated to send out resets
 120  120   * for connection which have no listeners and IP directly calls
 121  121   * tcp_xmit_listeners_reset() which does any policy check.
 122  122   *
 123  123   * Protection and Synchronisation mechanism:
 124  124   *
 125  125   * The tcp data structure does not use any kind of lock for protecting
 126  126   * its state but instead uses 'squeues' for mutual exclusion from various
 127  127   * read and write side threads. To access a tcp member, the thread should
 128  128   * always be behind squeue (via squeue_enter with flags as SQ_FILL, SQ_PROCESS,
 129  129   * or SQ_NODRAIN). Since the squeues allow a direct function call, caller
 130  130   * can pass any tcp function having prototype of edesc_t as argument
 131  131   * (different from traditional STREAMs model where packets come in only
 132  132   * designated entry points). The list of functions that can be directly
 133  133   * called via squeue are listed before the usual function prototype.
 134  134   *
 135  135   * Referencing:
 136  136   *
 137  137   * TCP is MT-Hot and we use a reference based scheme to make sure that the
 138  138   * tcp structure doesn't disappear when its needed. When the application
 139  139   * creates an outgoing connection or accepts an incoming connection, we
 140  140   * start out with 2 references on 'conn_ref'. One for TCP and one for IP.
 141  141   * The IP reference is just a symbolic reference since ip_tcpclose()
 142  142   * looks at tcp structure after tcp_close_output() returns which could
 143  143   * have dropped the last TCP reference. So as long as the connection is
 144  144   * in attached state i.e. !TCP_IS_DETACHED, we have 2 references on the
 145  145   * conn_t. The classifier puts its own reference when the connection is
 146  146   * inserted in listen or connected hash. Anytime a thread needs to enter
 147  147   * the tcp connection perimeter, it retrieves the conn/tcp from q->ptr
 148  148   * on write side or by doing a classify on read side and then puts a
 149  149   * reference on the conn before doing squeue_enter/tryenter/fill. For
 150  150   * read side, the classifier itself puts the reference under fanout lock
 151  151   * to make sure that tcp can't disappear before it gets processed. The
 152  152   * squeue will drop this reference automatically so the called function
 153  153   * doesn't have to do a DEC_REF.
 154  154   *
 155  155   * Opening a new connection:
 156  156   *
 157  157   * The outgoing connection open is pretty simple. tcp_open() does the
 158  158   * work in creating the conn/tcp structure and initializing it. The
 159  159   * squeue assignment is done based on the CPU the application
 160  160   * is running on. So for outbound connections, processing is always done
 161  161   * on application CPU which might be different from the incoming CPU
 162  162   * being interrupted by the NIC. An optimal way would be to figure out
 163  163   * the NIC <-> CPU binding at listen time, and assign the outgoing
 164  164   * connection to the squeue attached to the CPU that will be interrupted
 165  165   * for incoming packets (we know the NIC based on the bind IP address).
 166  166   * This might seem like a problem if more data is going out but the
 167  167   * fact is that in most cases the transmit is ACK driven transmit where
 168  168   * the outgoing data normally sits on TCP's xmit queue waiting to be
 169  169   * transmitted.
 170  170   *
 171  171   * Accepting a connection:
 172  172   *
 173  173   * This is a more interesting case because of various races involved in
 174  174   * establishing a eager in its own perimeter. Read the meta comment on
 175  175   * top of tcp_input_listener(). But briefly, the squeue is picked by
 176  176   * ip_fanout based on the ring or the sender (if loopback).
 177  177   *
 178  178   * Closing a connection:
 179  179   *
 180  180   * The close is fairly straight forward. tcp_close() calls tcp_close_output()
 181  181   * via squeue to do the close and mark the tcp as detached if the connection
 182  182   * was in state TCPS_ESTABLISHED or greater. In the later case, TCP keep its
 183  183   * reference but tcp_close() drop IP's reference always. So if tcp was
 184  184   * not killed, it is sitting in time_wait list with 2 reference - 1 for TCP
 185  185   * and 1 because it is in classifier's connected hash. This is the condition
 186  186   * we use to determine that its OK to clean up the tcp outside of squeue
 187  187   * when time wait expires (check the ref under fanout and conn_lock and
 188  188   * if it is 2, remove it from fanout hash and kill it).
 189  189   *
 190  190   * Although close just drops the necessary references and marks the
 191  191   * tcp_detached state, tcp_close needs to know the tcp_detached has been
 192  192   * set (under squeue) before letting the STREAM go away (because a
 193  193   * inbound packet might attempt to go up the STREAM while the close
 194  194   * has happened and tcp_detached is not set). So a special lock and
 195  195   * flag is used along with a condition variable (tcp_closelock, tcp_closed,
 196  196   * and tcp_closecv) to signal tcp_close that tcp_close_out() has marked
 197  197   * tcp_detached.
 198  198   *
 199  199   * Special provisions and fast paths:
 200  200   *
 201  201   * We make special provisions for sockfs by marking tcp_issocket
 202  202   * whenever we have only sockfs on top of TCP. This allows us to skip
 203  203   * putting the tcp in acceptor hash since a sockfs listener can never
 204  204   * become acceptor and also avoid allocating a tcp_t for acceptor STREAM
 205  205   * since eager has already been allocated and the accept now happens
 206  206   * on acceptor STREAM. There is a big blob of comment on top of
 207  207   * tcp_input_listener explaining the new accept. When socket is POP'd,
 208  208   * sockfs sends us an ioctl to mark the fact and we go back to old
 209  209   * behaviour. Once tcp_issocket is unset, its never set for the
 210  210   * life of that connection.
 211  211   *
 212  212   * IPsec notes :
 213  213   *
 214  214   * Since a packet is always executed on the correct TCP perimeter
 215  215   * all IPsec processing is defered to IP including checking new
 216  216   * connections and setting IPSEC policies for new connection. The
 217  217   * only exception is tcp_xmit_listeners_reset() which is called
 218  218   * directly from IP and needs to policy check to see if TH_RST
 219  219   * can be sent out.
 220  220   */
 221  221  
 222  222  /*
 223  223   * Values for squeue switch:
 224  224   * 1: SQ_NODRAIN
 225  225   * 2: SQ_PROCESS
 226  226   * 3: SQ_FILL
 227  227   */
 228  228  int tcp_squeue_wput = 2;        /* /etc/systems */
 229  229  int tcp_squeue_flag;
 230  230  
 231  231  /*
 232  232   * To prevent memory hog, limit the number of entries in tcp_free_list
 233  233   * to 1% of available memory / number of cpus
 234  234   */
 235  235  uint_t tcp_free_list_max_cnt = 0;
 236  236  
 237  237  #define TIDUSZ  4096    /* transport interface data unit size */
 238  238  
 239  239  /*
 240  240   * Size of acceptor hash list.  It has to be a power of 2 for hashing.
 241  241   */
 242  242  #define TCP_ACCEPTOR_FANOUT_SIZE                512
 243  243  
 244  244  #ifdef  _ILP32
 245  245  #define TCP_ACCEPTOR_HASH(accid)                                        \
 246  246                  (((uint_t)(accid) >> 8) & (TCP_ACCEPTOR_FANOUT_SIZE - 1))
 247  247  #else
 248  248  #define TCP_ACCEPTOR_HASH(accid)                                        \
 249  249                  ((uint_t)(accid) & (TCP_ACCEPTOR_FANOUT_SIZE - 1))
 250  250  #endif  /* _ILP32 */
 251  251  
 252  252  /*
 253  253   * Minimum number of connections which can be created per listener.  Used
 254  254   * when the listener connection count is in effect.
 255  255   */
 256  256  static uint32_t tcp_min_conn_listener = 2;
 257  257  
 258  258  uint32_t tcp_early_abort = 30;
 259  259  
 260  260  /* TCP Timer control structure */
 261  261  typedef struct tcpt_s {
 262  262          pfv_t   tcpt_pfv;       /* The routine we are to call */
 263  263          tcp_t   *tcpt_tcp;      /* The parameter we are to pass in */
 264  264  } tcpt_t;
 265  265  
 266  266  /*
 267  267   * Functions called directly via squeue having a prototype of edesc_t.
 268  268   */
 269  269  void            tcp_input_listener(void *arg, mblk_t *mp, void *arg2,
 270  270      ip_recv_attr_t *ira);
 271  271  void            tcp_input_data(void *arg, mblk_t *mp, void *arg2,
 272  272      ip_recv_attr_t *ira);
 273  273  static void     tcp_linger_interrupted(void *arg, mblk_t *mp, void *arg2,
 274  274      ip_recv_attr_t *dummy);
 275  275  
 276  276  
 277  277  /* Prototype for TCP functions */
 278  278  static void     tcp_random_init(void);
 279  279  int             tcp_random(void);
 280  280  static int      tcp_connect_ipv4(tcp_t *tcp, ipaddr_t *dstaddrp,
 281  281                      in_port_t dstport, uint_t srcid);
 282  282  static int      tcp_connect_ipv6(tcp_t *tcp, in6_addr_t *dstaddrp,
 283  283                      in_port_t dstport, uint32_t flowinfo,
 284  284                      uint_t srcid, uint32_t scope_id);
 285  285  static void     tcp_iss_init(tcp_t *tcp);
 286  286  static void     tcp_reinit(tcp_t *tcp);
 287  287  static void     tcp_reinit_values(tcp_t *tcp);
 288  288  
 289  289  static void     tcp_wsrv(queue_t *q);
 290  290  static void     tcp_update_lso(tcp_t *tcp, ip_xmit_attr_t *ixa);
 291  291  static void     tcp_update_zcopy(tcp_t *tcp);
 292  292  static void     tcp_notify(void *, ip_xmit_attr_t *, ixa_notify_type_t,
 293  293      ixa_notify_arg_t);
 294  294  static void     *tcp_stack_init(netstackid_t stackid, netstack_t *ns);
 295  295  static void     tcp_stack_fini(netstackid_t stackid, void *arg);
 296  296  
 297  297  static int      tcp_squeue_switch(int);
 298  298  
 299  299  static int      tcp_open(queue_t *, dev_t *, int, int, cred_t *, boolean_t);
 300  300  static int      tcp_openv4(queue_t *, dev_t *, int, int, cred_t *);
 301  301  static int      tcp_openv6(queue_t *, dev_t *, int, int, cred_t *);
 302  302  
 303  303  static void     tcp_squeue_add(squeue_t *);
 304  304  
 305  305  struct module_info tcp_rinfo =  {
 306  306          TCP_MOD_ID, TCP_MOD_NAME, 0, INFPSZ, TCP_RECV_HIWATER, TCP_RECV_LOWATER
 307  307  };
 308  308  
 309  309  static struct module_info tcp_winfo =  {
 310  310          TCP_MOD_ID, TCP_MOD_NAME, 0, INFPSZ, 127, 16
 311  311  };
 312  312  
 313  313  /*
 314  314   * Entry points for TCP as a device. The normal case which supports
 315  315   * the TCP functionality.
 316  316   * We have separate open functions for the /dev/tcp and /dev/tcp6 devices.
 317  317   */
 318  318  struct qinit tcp_rinitv4 = {
 319  319          NULL, (pfi_t)tcp_rsrv, tcp_openv4, tcp_tpi_close, NULL, &tcp_rinfo
 320  320  };
 321  321  
 322  322  struct qinit tcp_rinitv6 = {
 323  323          NULL, (pfi_t)tcp_rsrv, tcp_openv6, tcp_tpi_close, NULL, &tcp_rinfo
 324  324  };
 325  325  
 326  326  struct qinit tcp_winit = {
 327  327          (pfi_t)tcp_wput, (pfi_t)tcp_wsrv, NULL, NULL, NULL, &tcp_winfo
 328  328  };
 329  329  
 330  330  /* Initial entry point for TCP in socket mode. */
 331  331  struct qinit tcp_sock_winit = {
 332  332          (pfi_t)tcp_wput_sock, (pfi_t)tcp_wsrv, NULL, NULL, NULL, &tcp_winfo
 333  333  };
 334  334  
 335  335  /* TCP entry point during fallback */
 336  336  struct qinit tcp_fallback_sock_winit = {
 337  337          (pfi_t)tcp_wput_fallback, NULL, NULL, NULL, NULL, &tcp_winfo
 338  338  };
 339  339  
 340  340  /*
 341  341   * Entry points for TCP as a acceptor STREAM opened by sockfs when doing
 342  342   * an accept. Avoid allocating data structures since eager has already
 343  343   * been created.
 344  344   */
 345  345  struct qinit tcp_acceptor_rinit = {
 346  346          NULL, (pfi_t)tcp_rsrv, NULL, tcp_tpi_close_accept, NULL, &tcp_winfo
 347  347  };
 348  348  
 349  349  struct qinit tcp_acceptor_winit = {
 350  350          (pfi_t)tcp_tpi_accept, NULL, NULL, NULL, NULL, &tcp_winfo
 351  351  };
 352  352  
 353  353  /* For AF_INET aka /dev/tcp */
 354  354  struct streamtab tcpinfov4 = {
 355  355          &tcp_rinitv4, &tcp_winit
 356  356  };
 357  357  
 358  358  /* For AF_INET6 aka /dev/tcp6 */
 359  359  struct streamtab tcpinfov6 = {
 360  360          &tcp_rinitv6, &tcp_winit
 361  361  };
 362  362  
 363  363  /*
 364  364   * Following assumes TPI alignment requirements stay along 32 bit
 365  365   * boundaries
 366  366   */
 367  367  #define ROUNDUP32(x) \
 368  368          (((x) + (sizeof (int32_t) - 1)) & ~(sizeof (int32_t) - 1))
 369  369  
 370  370  /* Template for response to info request. */
 371  371  struct T_info_ack tcp_g_t_info_ack = {
 372  372          T_INFO_ACK,             /* PRIM_type */
 373  373          0,                      /* TSDU_size */
 374  374          T_INFINITE,             /* ETSDU_size */
 375  375          T_INVALID,              /* CDATA_size */
 376  376          T_INVALID,              /* DDATA_size */
 377  377          sizeof (sin_t),         /* ADDR_size */
 378  378          0,                      /* OPT_size - not initialized here */
 379  379          TIDUSZ,                 /* TIDU_size */
 380  380          T_COTS_ORD,             /* SERV_type */
 381  381          TCPS_IDLE,              /* CURRENT_state */
 382  382          (XPG4_1|EXPINLINE)      /* PROVIDER_flag */
 383  383  };
 384  384  
 385  385  struct T_info_ack tcp_g_t_info_ack_v6 = {
 386  386          T_INFO_ACK,             /* PRIM_type */
 387  387          0,                      /* TSDU_size */
 388  388          T_INFINITE,             /* ETSDU_size */
 389  389          T_INVALID,              /* CDATA_size */
 390  390          T_INVALID,              /* DDATA_size */
 391  391          sizeof (sin6_t),        /* ADDR_size */
 392  392          0,                      /* OPT_size - not initialized here */
 393  393          TIDUSZ,         /* TIDU_size */
 394  394          T_COTS_ORD,             /* SERV_type */
 395  395          TCPS_IDLE,              /* CURRENT_state */
 396  396          (XPG4_1|EXPINLINE)      /* PROVIDER_flag */
 397  397  };
 398  398  
 399  399  /*
 400  400   * TCP tunables related declarations. Definitions are in tcp_tunables.c
 401  401   */
 402  402  extern mod_prop_info_t tcp_propinfo_tbl[];
 403  403  extern int tcp_propinfo_count;
 404  404  
 405  405  #define IS_VMLOANED_MBLK(mp) \
 406  406          (((mp)->b_datap->db_struioflag & STRUIO_ZC) != 0)
 407  407  
 408  408  uint32_t do_tcpzcopy = 1;               /* 0: disable, 1: enable, 2: force */
 409  409  
 410  410  /*
 411  411   * Forces all connections to obey the value of the tcps_maxpsz_multiplier
 412  412   * tunable settable via NDD.  Otherwise, the per-connection behavior is
 413  413   * determined dynamically during tcp_set_destination(), which is the default.
 414  414   */
 415  415  boolean_t tcp_static_maxpsz = B_FALSE;
 416  416  
 417  417  /*
 418  418   * If the receive buffer size is changed, this function is called to update
 419  419   * the upper socket layer on the new delayed receive wake up threshold.
 420  420   */
 421  421  static void
 422  422  tcp_set_recv_threshold(tcp_t *tcp, uint32_t new_rcvthresh)
 423  423  {
 424  424          uint32_t default_threshold = SOCKET_RECVHIWATER >> 3;
 425  425  
 426  426          if (IPCL_IS_NONSTR(tcp->tcp_connp)) {
 427  427                  conn_t *connp = tcp->tcp_connp;
 428  428                  struct sock_proto_props sopp;
 429  429  
 430  430                  /*
 431  431                   * only increase rcvthresh upto default_threshold
 432  432                   */
 433  433                  if (new_rcvthresh > default_threshold)
 434  434                          new_rcvthresh = default_threshold;
 435  435  
 436  436                  sopp.sopp_flags = SOCKOPT_RCVTHRESH;
 437  437                  sopp.sopp_rcvthresh = new_rcvthresh;
 438  438  
 439  439                  (*connp->conn_upcalls->su_set_proto_props)
 440  440                      (connp->conn_upper_handle, &sopp);
 441  441          }
 442  442  }
 443  443  
 444  444  /*
 445  445   * Figure out the value of window scale opton.  Note that the rwnd is
 446  446   * ASSUMED to be rounded up to the nearest MSS before the calculation.
 447  447   * We cannot find the scale value and then do a round up of tcp_rwnd
 448  448   * because the scale value may not be correct after that.
 449  449   *
 450  450   * Set the compiler flag to make this function inline.
 451  451   */
 452  452  void
 453  453  tcp_set_ws_value(tcp_t *tcp)
 454  454  {
 455  455          int i;
 456  456          uint32_t rwnd = tcp->tcp_rwnd;
 457  457  
 458  458          for (i = 0; rwnd > TCP_MAXWIN && i < TCP_MAX_WINSHIFT;
 459  459              i++, rwnd >>= 1)
 460  460                  ;
 461  461          tcp->tcp_rcv_ws = i;
 462  462  }
 463  463  
 464  464  /*
 465  465   * Remove cached/latched IPsec references.
 466  466   */
 467  467  void
 468  468  tcp_ipsec_cleanup(tcp_t *tcp)
 469  469  {
 470  470          conn_t          *connp = tcp->tcp_connp;
 471  471  
 472  472          ASSERT(connp->conn_flags & IPCL_TCPCONN);
 473  473  
 474  474          if (connp->conn_latch != NULL) {
 475  475                  IPLATCH_REFRELE(connp->conn_latch);
 476  476                  connp->conn_latch = NULL;
 477  477          }
 478  478          if (connp->conn_latch_in_policy != NULL) {
 479  479                  IPPOL_REFRELE(connp->conn_latch_in_policy);
 480  480                  connp->conn_latch_in_policy = NULL;
 481  481          }
 482  482          if (connp->conn_latch_in_action != NULL) {
 483  483                  IPACT_REFRELE(connp->conn_latch_in_action);
 484  484                  connp->conn_latch_in_action = NULL;
 485  485          }
 486  486          if (connp->conn_policy != NULL) {
 487  487                  IPPH_REFRELE(connp->conn_policy, connp->conn_netstack);
 488  488                  connp->conn_policy = NULL;
 489  489          }
 490  490  }
 491  491  
 492  492  /*
 493  493   * Cleaup before placing on free list.
 494  494   * Disassociate from the netstack/tcp_stack_t since the freelist
 495  495   * is per squeue and not per netstack.
 496  496   */
 497  497  void
 498  498  tcp_cleanup(tcp_t *tcp)
 499  499  {
 500  500          mblk_t          *mp;
 501  501          conn_t          *connp = tcp->tcp_connp;
 502  502          tcp_stack_t     *tcps = tcp->tcp_tcps;
 503  503          netstack_t      *ns = tcps->tcps_netstack;
 504  504          mblk_t          *tcp_rsrv_mp;
 505  505  
 506  506          tcp_bind_hash_remove(tcp);
 507  507  
 508  508          /* Cleanup that which needs the netstack first */
 509  509          tcp_ipsec_cleanup(tcp);
 510  510          ixa_cleanup(connp->conn_ixa);
 511  511  
 512  512          if (connp->conn_ht_iphc != NULL) {
 513  513                  kmem_free(connp->conn_ht_iphc, connp->conn_ht_iphc_allocated);
 514  514                  connp->conn_ht_iphc = NULL;
 515  515                  connp->conn_ht_iphc_allocated = 0;
 516  516                  connp->conn_ht_iphc_len = 0;
 517  517                  connp->conn_ht_ulp = NULL;
 518  518                  connp->conn_ht_ulp_len = 0;
 519  519                  tcp->tcp_ipha = NULL;
 520  520                  tcp->tcp_ip6h = NULL;
 521  521                  tcp->tcp_tcpha = NULL;
 522  522          }
 523  523  
 524  524          /* We clear any IP_OPTIONS and extension headers */
 525  525          ip_pkt_free(&connp->conn_xmit_ipp);
 526  526  
 527  527          tcp_free(tcp);
 528  528  
 529  529          /*
 530  530           * Since we will bzero the entire structure, we need to
 531  531           * remove it and reinsert it in global hash list. We
 532  532           * know the walkers can't get to this conn because we
 533  533           * had set CONDEMNED flag earlier and checked reference
 534  534           * under conn_lock so walker won't pick it and when we
 535  535           * go the ipcl_globalhash_remove() below, no walker
 536  536           * can get to it.
 537  537           */
 538  538          ipcl_globalhash_remove(connp);
 539  539  
 540  540          /* Save some state */
 541  541          mp = tcp->tcp_timercache;
 542  542  
 543  543          tcp_rsrv_mp = tcp->tcp_rsrv_mp;
 544  544  
 545  545          if (connp->conn_cred != NULL) {
 546  546                  crfree(connp->conn_cred);
 547  547                  connp->conn_cred = NULL;
 548  548          }
 549  549          ipcl_conn_cleanup(connp);
 550  550          connp->conn_flags = IPCL_TCPCONN;
 551  551  
 552  552          /*
 553  553           * Now it is safe to decrement the reference counts.
 554  554           * This might be the last reference on the netstack
 555  555           * in which case it will cause the freeing of the IP Instance.
 556  556           */
 557  557          connp->conn_netstack = NULL;
 558  558          connp->conn_ixa->ixa_ipst = NULL;
 559  559          netstack_rele(ns);
 560  560          ASSERT(tcps != NULL);
 561  561          tcp->tcp_tcps = NULL;
 562  562  
 563  563          bzero(tcp, sizeof (tcp_t));
 564  564  
 565  565          /* restore the state */
 566  566          tcp->tcp_timercache = mp;
 567  567  
 568  568          tcp->tcp_rsrv_mp = tcp_rsrv_mp;
 569  569  
 570  570          tcp->tcp_connp = connp;
 571  571  
 572  572          ASSERT(connp->conn_tcp == tcp);
 573  573          ASSERT(connp->conn_flags & IPCL_TCPCONN);
 574  574          connp->conn_state_flags = CONN_INCIPIENT;
 575  575          ASSERT(connp->conn_proto == IPPROTO_TCP);
 576  576          ASSERT(connp->conn_ref == 1);
 577  577  }
 578  578  
 579  579  /*
 580  580   * Adapt to the information, such as rtt and rtt_sd, provided from the
 581  581   * DCE and IRE maintained by IP.
 582  582   *
 583  583   * Checks for multicast and broadcast destination address.
 584  584   * Returns zero if ok; an errno on failure.
 585  585   *
 586  586   * Note that the MSS calculation here is based on the info given in
 587  587   * the DCE and IRE.  We do not do any calculation based on TCP options.  They
 588  588   * will be handled in tcp_input_data() when TCP knows which options to use.
 589  589   *
 590  590   * Note on how TCP gets its parameters for a connection.
 591  591   *
 592  592   * When a tcp_t structure is allocated, it gets all the default parameters.
 593  593   * In tcp_set_destination(), it gets those metric parameters, like rtt, rtt_sd,
 594  594   * spipe, rpipe, ... from the route metrics.  Route metric overrides the
 595  595   * default.
 596  596   *
 597  597   * An incoming SYN with a multicast or broadcast destination address is dropped
 598  598   * in ip_fanout_v4/v6.
 599  599   *
 600  600   * An incoming SYN with a multicast or broadcast source address is always
 601  601   * dropped in tcp_set_destination, since IPDF_ALLOW_MCBC is not set in
 602  602   * conn_connect.
 603  603   * The same logic in tcp_set_destination also serves to
 604  604   * reject an attempt to connect to a broadcast or multicast (destination)
 605  605   * address.
 606  606   */
 607  607  int
 608  608  tcp_set_destination(tcp_t *tcp)
 609  609  {
 610  610          uint32_t        mss_max;
 611  611          uint32_t        mss;
 612  612          boolean_t       tcp_detached = TCP_IS_DETACHED(tcp);
 613  613          conn_t          *connp = tcp->tcp_connp;
 614  614          tcp_stack_t     *tcps = tcp->tcp_tcps;
 615  615          iulp_t          uinfo;
 616  616          int             error;
 617  617          uint32_t        flags;
 618  618  
 619  619          flags = IPDF_LSO | IPDF_ZCOPY;
 620  620          /*
 621  621           * Make sure we have a dce for the destination to avoid dce_ident
 622  622           * contention for connected sockets.
 623  623           */
 624  624          flags |= IPDF_UNIQUE_DCE;
 625  625  
 626  626          if (!tcps->tcps_ignore_path_mtu)
 627  627                  connp->conn_ixa->ixa_flags |= IXAF_PMTU_DISCOVERY;
 628  628  
 629  629          /* Use conn_lock to satify ASSERT; tcp is already serialized */
 630  630          mutex_enter(&connp->conn_lock);
 631  631          error = conn_connect(connp, &uinfo, flags);
 632  632          mutex_exit(&connp->conn_lock);
 633  633          if (error != 0)
 634  634                  return (error);
 635  635  
 636  636          error = tcp_build_hdrs(tcp);
 637  637          if (error != 0)
 638  638                  return (error);
 639  639  
 640  640          tcp->tcp_localnet = uinfo.iulp_localnet;
 641  641  
 642  642          if (uinfo.iulp_rtt != 0) {
 643  643                  clock_t rto;
 644  644  
 645  645                  tcp->tcp_rtt_sa = uinfo.iulp_rtt;
 646  646                  tcp->tcp_rtt_sd = uinfo.iulp_rtt_sd;
 647  647                  rto = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
 648  648                      tcps->tcps_rexmit_interval_extra +
 649  649                      (tcp->tcp_rtt_sa >> 5);
 650  650  
 651  651                  TCP_SET_RTO(tcp, rto);
 652  652          }
 653  653          if (uinfo.iulp_ssthresh != 0)
 654  654                  tcp->tcp_cwnd_ssthresh = uinfo.iulp_ssthresh;
 655  655          else
 656  656                  tcp->tcp_cwnd_ssthresh = TCP_MAX_LARGEWIN;
 657  657          if (uinfo.iulp_spipe > 0) {
 658  658                  connp->conn_sndbuf = MIN(uinfo.iulp_spipe,
 659  659                      tcps->tcps_max_buf);
 660  660                  if (tcps->tcps_snd_lowat_fraction != 0) {
 661  661                          connp->conn_sndlowat = connp->conn_sndbuf /
 662  662                              tcps->tcps_snd_lowat_fraction;
 663  663                  }
 664  664                  (void) tcp_maxpsz_set(tcp, B_TRUE);
 665  665          }
 666  666          /*
 667  667           * Note that up till now, acceptor always inherits receive
 668  668           * window from the listener.  But if there is a metrics
 669  669           * associated with a host, we should use that instead of
 670  670           * inheriting it from listener. Thus we need to pass this
 671  671           * info back to the caller.
 672  672           */
 673  673          if (uinfo.iulp_rpipe > 0) {
 674  674                  tcp->tcp_rwnd = MIN(uinfo.iulp_rpipe,
 675  675                      tcps->tcps_max_buf);
 676  676          }
 677  677  
 678  678          if (uinfo.iulp_rtomax > 0) {
 679  679                  tcp->tcp_second_timer_threshold =
 680  680                      uinfo.iulp_rtomax;
 681  681          }
 682  682  
 683  683          /*
 684  684           * Use the metric option settings, iulp_tstamp_ok and
 685  685           * iulp_wscale_ok, only for active open. What this means
 686  686           * is that if the other side uses timestamp or window
 687  687           * scale option, TCP will also use those options. That
 688  688           * is for passive open.  If the application sets a
 689  689           * large window, window scale is enabled regardless of
 690  690           * the value in iulp_wscale_ok.  This is the behavior
 691  691           * since 2.6.  So we keep it.
 692  692           * The only case left in passive open processing is the
 693  693           * check for SACK.
 694  694           * For ECN, it should probably be like SACK.  But the
 695  695           * current value is binary, so we treat it like the other
 696  696           * cases.  The metric only controls active open.For passive
 697  697           * open, the ndd param, tcp_ecn_permitted, controls the
 698  698           * behavior.
 699  699           */
 700  700          if (!tcp_detached) {
 701  701                  /*
 702  702                   * The if check means that the following can only
 703  703                   * be turned on by the metrics only IRE, but not off.
 704  704                   */
 705  705                  if (uinfo.iulp_tstamp_ok)
 706  706                          tcp->tcp_snd_ts_ok = B_TRUE;
 707  707                  if (uinfo.iulp_wscale_ok)
 708  708                          tcp->tcp_snd_ws_ok = B_TRUE;
 709  709                  if (uinfo.iulp_sack == 2)
 710  710                          tcp->tcp_snd_sack_ok = B_TRUE;
 711  711                  if (uinfo.iulp_ecn_ok)
 712  712                          tcp->tcp_ecn_ok = B_TRUE;
 713  713          } else {
 714  714                  /*
 715  715                   * Passive open.
 716  716                   *
 717  717                   * As above, the if check means that SACK can only be
 718  718                   * turned on by the metric only IRE.
 719  719                   */
 720  720                  if (uinfo.iulp_sack > 0) {
 721  721                          tcp->tcp_snd_sack_ok = B_TRUE;
 722  722                  }
 723  723          }
 724  724  
 725  725          /*
 726  726           * XXX Note that currently, iulp_mtu can be as small as 68
 727  727           * because of PMTUd.  So tcp_mss may go to negative if combined
 728  728           * length of all those options exceeds 28 bytes.  But because
 729  729           * of the tcp_mss_min check below, we may not have a problem if
 730  730           * tcp_mss_min is of a reasonable value.  The default is 1 so
 731  731           * the negative problem still exists.  And the check defeats PMTUd.
 732  732           * In fact, if PMTUd finds that the MSS should be smaller than
 733  733           * tcp_mss_min, TCP should turn off PMUTd and use the tcp_mss_min
 734  734           * value.
 735  735           *
 736  736           * We do not deal with that now.  All those problems related to
 737  737           * PMTUd will be fixed later.
 738  738           */
 739  739          ASSERT(uinfo.iulp_mtu != 0);
 740  740          mss = tcp->tcp_initial_pmtu = uinfo.iulp_mtu;
 741  741  
 742  742          /* Sanity check for MSS value. */
 743  743          if (connp->conn_ipversion == IPV4_VERSION)
 744  744                  mss_max = tcps->tcps_mss_max_ipv4;
 745  745          else
 746  746                  mss_max = tcps->tcps_mss_max_ipv6;
 747  747  
 748  748          if (tcp->tcp_ipsec_overhead == 0)
 749  749                  tcp->tcp_ipsec_overhead = conn_ipsec_length(connp);
 750  750  
 751  751          mss -= tcp->tcp_ipsec_overhead;
 752  752  
 753  753          if (mss < tcps->tcps_mss_min)
 754  754                  mss = tcps->tcps_mss_min;
 755  755          if (mss > mss_max)
 756  756                  mss = mss_max;
 757  757  
 758  758          /* Note that this is the maximum MSS, excluding all options. */
 759  759          tcp->tcp_mss = mss;
 760  760  
 761  761          /*
 762  762           * Update the tcp connection with LSO capability.
 763  763           */
 764  764          tcp_update_lso(tcp, connp->conn_ixa);
 765  765  
 766  766          /*
 767  767           * Initialize the ISS here now that we have the full connection ID.
 768  768           * The RFC 1948 method of initial sequence number generation requires
 769  769           * knowledge of the full connection ID before setting the ISS.
 770  770           */
 771  771          tcp_iss_init(tcp);
 772  772  
 773  773          tcp->tcp_loopback = (uinfo.iulp_loopback | uinfo.iulp_local);
 774  774  
 775  775          /*
 776  776           * Make sure that conn is not marked incipient
 777  777           * for incoming connections. A blind
 778  778           * removal of incipient flag is cheaper than
 779  779           * check and removal.
 780  780           */
 781  781          mutex_enter(&connp->conn_lock);
 782  782          connp->conn_state_flags &= ~CONN_INCIPIENT;
 783  783          mutex_exit(&connp->conn_lock);
 784  784          return (0);
 785  785  }
 786  786  
 787  787  /*
 788  788   * tcp_clean_death / tcp_close_detached must not be called more than once
 789  789   * on a tcp. Thus every function that potentially calls tcp_clean_death
 790  790   * must check for the tcp state before calling tcp_clean_death.
 791  791   * Eg. tcp_input_data, tcp_eager_kill, tcp_clean_death_wrapper,
 792  792   * tcp_timer_handler, all check for the tcp state.
 793  793   */
 794  794  /* ARGSUSED */
 795  795  void
 796  796  tcp_clean_death_wrapper(void *arg, mblk_t *mp, void *arg2,
 797  797      ip_recv_attr_t *dummy)
 798  798  {
 799  799          tcp_t   *tcp = ((conn_t *)arg)->conn_tcp;
 800  800  
 801  801          freemsg(mp);
 802  802          if (tcp->tcp_state > TCPS_BOUND)
 803  803                  (void) tcp_clean_death(((conn_t *)arg)->conn_tcp, ETIMEDOUT);
 804  804  }
 805  805  
 806  806  /*
 807  807   * We are dying for some reason.  Try to do it gracefully.  (May be called
 808  808   * as writer.)
 809  809   *
 810  810   * Return -1 if the structure was not cleaned up (if the cleanup had to be
 811  811   * done by a service procedure).
 812  812   * TBD - Should the return value distinguish between the tcp_t being
 813  813   * freed and it being reinitialized?
 814  814   */
 815  815  int
 816  816  tcp_clean_death(tcp_t *tcp, int err)
 817  817  {
 818  818          mblk_t  *mp;
 819  819          queue_t *q;
 820  820          conn_t  *connp = tcp->tcp_connp;
 821  821          tcp_stack_t     *tcps = tcp->tcp_tcps;
 822  822  
 823  823          if (tcp->tcp_fused)
 824  824                  tcp_unfuse(tcp);
 825  825  
 826  826          if (tcp->tcp_linger_tid != 0 &&
 827  827              TCP_TIMER_CANCEL(tcp, tcp->tcp_linger_tid) >= 0) {
 828  828                  tcp_stop_lingering(tcp);
 829  829          }
 830  830  
 831  831          ASSERT(tcp != NULL);
 832  832          ASSERT((connp->conn_family == AF_INET &&
 833  833              connp->conn_ipversion == IPV4_VERSION) ||
 834  834              (connp->conn_family == AF_INET6 &&
 835  835              (connp->conn_ipversion == IPV4_VERSION ||
 836  836              connp->conn_ipversion == IPV6_VERSION)));
 837  837  
 838  838          if (TCP_IS_DETACHED(tcp)) {
 839  839                  if (tcp->tcp_hard_binding) {
 840  840                          /*
 841  841                           * Its an eager that we are dealing with. We close the
 842  842                           * eager but in case a conn_ind has already gone to the
 843  843                           * listener, let tcp_accept_finish() send a discon_ind
 844  844                           * to the listener and drop the last reference. If the
 845  845                           * listener doesn't even know about the eager i.e. the
 846  846                           * conn_ind hasn't gone up, blow away the eager and drop
 847  847                           * the last reference as well. If the conn_ind has gone
 848  848                           * up, state should be BOUND. tcp_accept_finish
 849  849                           * will figure out that the connection has received a
 850  850                           * RST and will send a DISCON_IND to the application.
 851  851                           */
 852  852                          tcp_closei_local(tcp);
 853  853                          if (!tcp->tcp_tconnind_started) {
 854  854                                  CONN_DEC_REF(connp);
 855  855                          } else {
 856  856                                  tcp->tcp_state = TCPS_BOUND;
 857  857                                  DTRACE_TCP6(state__change, void, NULL,
 858  858                                      ip_xmit_attr_t *, connp->conn_ixa,
 859  859                                      void, NULL, tcp_t *, tcp, void, NULL,
 860  860                                      int32_t, TCPS_CLOSED);
 861  861                          }
 862  862                  } else {
 863  863                          tcp_close_detached(tcp);
 864  864                  }
 865  865                  return (0);
 866  866          }
 867  867  
 868  868          TCP_STAT(tcps, tcp_clean_death_nondetached);
 869  869  
 870  870          /*
 871  871           * The connection is dead.  Decrement listener connection counter if
 872  872           * necessary.
 873  873           */
 874  874          if (tcp->tcp_listen_cnt != NULL)
 875  875                  TCP_DECR_LISTEN_CNT(tcp);
 876  876  
 877  877          /*
 878  878           * When a connection is moved to TIME_WAIT state, the connection
 879  879           * counter is already decremented.  So no need to decrement here
 880  880           * again.  See SET_TIME_WAIT() macro.
 881  881           */
 882  882          if (tcp->tcp_state >= TCPS_ESTABLISHED &&
 883  883              tcp->tcp_state < TCPS_TIME_WAIT) {
 884  884                  TCPS_CONN_DEC(tcps);
 885  885          }
 886  886  
 887  887          q = connp->conn_rq;
 888  888  
 889  889          /* Trash all inbound data */
 890  890          if (!IPCL_IS_NONSTR(connp)) {
 891  891                  ASSERT(q != NULL);
 892  892                  flushq(q, FLUSHALL);
 893  893          }
 894  894  
 895  895          /*
 896  896           * If we are at least part way open and there is error
 897  897           * (err==0 implies no error)
 898  898           * notify our client by a T_DISCON_IND.
 899  899           */
 900  900          if ((tcp->tcp_state >= TCPS_SYN_SENT) && err) {
 901  901                  if (tcp->tcp_state >= TCPS_ESTABLISHED &&
 902  902                      !TCP_IS_SOCKET(tcp)) {
 903  903                          /*
 904  904                           * Send M_FLUSH according to TPI. Because sockets will
 905  905                           * (and must) ignore FLUSHR we do that only for TPI
 906  906                           * endpoints and sockets in STREAMS mode.
 907  907                           */
 908  908                          (void) putnextctl1(q, M_FLUSH, FLUSHR);
 909  909                  }
 910  910                  if (connp->conn_debug) {
 911  911                          (void) strlog(TCP_MOD_ID, 0, 1, SL_TRACE|SL_ERROR,
 912  912                              "tcp_clean_death: discon err %d", err);
 913  913                  }
 914  914                  if (IPCL_IS_NONSTR(connp)) {
 915  915                          /* Direct socket, use upcall */
 916  916                          (*connp->conn_upcalls->su_disconnected)(
 917  917                              connp->conn_upper_handle, tcp->tcp_connid, err);
 918  918                  } else {
 919  919                          mp = mi_tpi_discon_ind(NULL, err, 0);
 920  920                          if (mp != NULL) {
 921  921                                  putnext(q, mp);
 922  922                          } else {
 923  923                                  if (connp->conn_debug) {
 924  924                                          (void) strlog(TCP_MOD_ID, 0, 1,
 925  925                                              SL_ERROR|SL_TRACE,
 926  926                                              "tcp_clean_death, sending M_ERROR");
 927  927                                  }
 928  928                                  (void) putnextctl1(q, M_ERROR, EPROTO);
 929  929                          }
 930  930                  }
 931  931                  if (tcp->tcp_state <= TCPS_SYN_RCVD) {
 932  932                          /* SYN_SENT or SYN_RCVD */
 933  933                          TCPS_BUMP_MIB(tcps, tcpAttemptFails);
 934  934                  } else if (tcp->tcp_state <= TCPS_CLOSE_WAIT) {
 935  935                          /* ESTABLISHED or CLOSE_WAIT */
 936  936                          TCPS_BUMP_MIB(tcps, tcpEstabResets);
 937  937                  }
 938  938          }
 939  939  
 940  940          /*
 941  941           * ESTABLISHED non-STREAMS eagers are not 'detached' because
 942  942           * an upper handle is obtained when the SYN-ACK comes in. So it
 943  943           * should receive the 'disconnected' upcall, but tcp_reinit should
 944  944           * not be called since this is an eager.
 945  945           */
 946  946          if (tcp->tcp_listener != NULL && IPCL_IS_NONSTR(connp)) {
 947  947                  tcp_closei_local(tcp);
 948  948                  tcp->tcp_state = TCPS_BOUND;
 949  949                  DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
 950  950                      connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
 951  951                      int32_t, TCPS_CLOSED);
 952  952                  return (0);
 953  953          }
 954  954  
 955  955          tcp_reinit(tcp);
 956  956          if (IPCL_IS_NONSTR(connp))
 957  957                  (void) tcp_do_unbind(connp);
 958  958  
 959  959          return (-1);
 960  960  }
 961  961  
 962  962  /*
 963  963   * In case tcp is in the "lingering state" and waits for the SO_LINGER timeout
 964  964   * to expire, stop the wait and finish the close.
 965  965   */
 966  966  void
 967  967  tcp_stop_lingering(tcp_t *tcp)
 968  968  {
 969  969          clock_t delta = 0;
 970  970          tcp_stack_t     *tcps = tcp->tcp_tcps;
 971  971          conn_t          *connp = tcp->tcp_connp;
 972  972  
 973  973          tcp->tcp_linger_tid = 0;
 974  974          if (tcp->tcp_state > TCPS_LISTEN) {
 975  975                  tcp_acceptor_hash_remove(tcp);
 976  976                  mutex_enter(&tcp->tcp_non_sq_lock);
 977  977                  if (tcp->tcp_flow_stopped) {
 978  978                          tcp_clrqfull(tcp);
 979  979                  }
 980  980                  mutex_exit(&tcp->tcp_non_sq_lock);
 981  981  
 982  982                  if (tcp->tcp_timer_tid != 0) {
 983  983                          delta = TCP_TIMER_CANCEL(tcp, tcp->tcp_timer_tid);
 984  984                          tcp->tcp_timer_tid = 0;
 985  985                  }
 986  986                  /*
 987  987                   * Need to cancel those timers which will not be used when
 988  988                   * TCP is detached.  This has to be done before the conn_wq
 989  989                   * is cleared.
 990  990                   */
 991  991                  tcp_timers_stop(tcp);
 992  992  
 993  993                  tcp->tcp_detached = B_TRUE;
 994  994                  connp->conn_rq = NULL;
 995  995                  connp->conn_wq = NULL;
 996  996  
 997  997                  if (tcp->tcp_state == TCPS_TIME_WAIT) {
 998  998                          tcp_time_wait_append(tcp);
 999  999                          TCP_DBGSTAT(tcps, tcp_detach_time_wait);
1000 1000                          goto finish;
1001 1001                  }
1002 1002  
1003 1003                  /*
1004 1004                   * If delta is zero the timer event wasn't executed and was
1005 1005                   * successfully canceled. In this case we need to restart it
1006 1006                   * with the minimal delta possible.
1007 1007                   */
1008 1008                  if (delta >= 0) {
1009 1009                          tcp->tcp_timer_tid = TCP_TIMER(tcp, tcp_timer,
1010 1010                              delta ? delta : 1);
1011 1011                  }
1012 1012          } else {
1013 1013                  tcp_closei_local(tcp);
1014 1014                  CONN_DEC_REF(connp);
1015 1015          }
1016 1016  finish:
1017 1017          tcp->tcp_detached = B_TRUE;
1018 1018          connp->conn_rq = NULL;
1019 1019          connp->conn_wq = NULL;
1020 1020  
1021 1021          /* Signal closing thread that it can complete close */
1022 1022          mutex_enter(&tcp->tcp_closelock);
1023 1023          tcp->tcp_closed = 1;
1024 1024          cv_signal(&tcp->tcp_closecv);
1025 1025          mutex_exit(&tcp->tcp_closelock);
1026 1026  
1027 1027          /* If we have an upper handle (socket), release it */
1028 1028          if (IPCL_IS_NONSTR(connp)) {
1029 1029                  ASSERT(connp->conn_upper_handle != NULL);
1030 1030                  (*connp->conn_upcalls->su_closed)(connp->conn_upper_handle);
1031 1031                  connp->conn_upper_handle = NULL;
1032 1032                  connp->conn_upcalls = NULL;
1033 1033          }
1034 1034  }
1035 1035  
1036 1036  void
1037 1037  tcp_close_common(conn_t *connp, int flags)
1038 1038  {
1039 1039          tcp_t           *tcp = connp->conn_tcp;
1040 1040          mblk_t          *mp = &tcp->tcp_closemp;
1041 1041          boolean_t       conn_ioctl_cleanup_reqd = B_FALSE;
1042 1042          mblk_t          *bp;
1043 1043  
1044 1044          ASSERT(connp->conn_ref >= 2);
1045 1045  
1046 1046          /*
1047 1047           * Mark the conn as closing. ipsq_pending_mp_add will not
1048 1048           * add any mp to the pending mp list, after this conn has
1049 1049           * started closing.
1050 1050           */
1051 1051          mutex_enter(&connp->conn_lock);
1052 1052          connp->conn_state_flags |= CONN_CLOSING;
1053 1053          if (connp->conn_oper_pending_ill != NULL)
1054 1054                  conn_ioctl_cleanup_reqd = B_TRUE;
1055 1055          CONN_INC_REF_LOCKED(connp);
1056 1056          mutex_exit(&connp->conn_lock);
1057 1057          tcp->tcp_closeflags = (uint8_t)flags;
1058 1058          ASSERT(connp->conn_ref >= 3);
1059 1059  
1060 1060          /*
1061 1061           * tcp_closemp_used is used below without any protection of a lock
1062 1062           * as we don't expect any one else to use it concurrently at this
1063 1063           * point otherwise it would be a major defect.
1064 1064           */
1065 1065  
1066 1066          if (mp->b_prev == NULL)
1067 1067                  tcp->tcp_closemp_used = B_TRUE;
1068 1068          else
1069 1069                  cmn_err(CE_PANIC, "tcp_close: concurrent use of tcp_closemp: "
1070 1070                      "connp %p tcp %p\n", (void *)connp, (void *)tcp);
1071 1071  
1072 1072          TCP_DEBUG_GETPCSTACK(tcp->tcmp_stk, 15);
1073 1073  
1074 1074          /*
1075 1075           * Cleanup any queued ioctls here. This must be done before the wq/rq
1076 1076           * are re-written by tcp_close_output().
1077 1077           */
1078 1078          if (conn_ioctl_cleanup_reqd)
1079 1079                  conn_ioctl_cleanup(connp);
1080 1080  
1081 1081          /*
1082 1082           * As CONN_CLOSING is set, no further ioctls should be passed down to
1083 1083           * IP for this conn (see the guards in tcp_ioctl, tcp_wput_ioctl and
1084 1084           * tcp_wput_iocdata). If the ioctl was queued on an ipsq,
1085 1085           * conn_ioctl_cleanup should have found it and removed it. If the ioctl
1086 1086           * was still in flight at the time, we wait for it here. See comments
1087 1087           * for CONN_INC_IOCTLREF in ip.h for details.
1088 1088           */
1089 1089          mutex_enter(&connp->conn_lock);
1090 1090          while (connp->conn_ioctlref > 0)
1091 1091                  cv_wait(&connp->conn_cv, &connp->conn_lock);
1092 1092          ASSERT(connp->conn_ioctlref == 0);
1093 1093          ASSERT(connp->conn_oper_pending_ill == NULL);
1094 1094          mutex_exit(&connp->conn_lock);
1095 1095  
1096 1096          SQUEUE_ENTER_ONE(connp->conn_sqp, mp, tcp_close_output, connp,
1097 1097              NULL, tcp_squeue_flag, SQTAG_IP_TCP_CLOSE);
1098 1098  
1099 1099          /*
1100 1100           * For non-STREAMS sockets, the normal case is that the conn makes
1101 1101           * an upcall when it's finally closed, so there is no need to wait
1102 1102           * in the protocol. But in case of SO_LINGER the thread sleeps here
1103 1103           * so it can properly deal with the thread being interrupted.
1104 1104           */
1105 1105          if (IPCL_IS_NONSTR(connp) && connp->conn_linger == 0)
1106 1106                  goto nowait;
1107 1107  
1108 1108          mutex_enter(&tcp->tcp_closelock);
1109 1109          while (!tcp->tcp_closed) {
1110 1110                  if (!cv_wait_sig(&tcp->tcp_closecv, &tcp->tcp_closelock)) {
1111 1111                          /*
1112 1112                           * The cv_wait_sig() was interrupted. We now do the
1113 1113                           * following:
1114 1114                           *
1115 1115                           * 1) If the endpoint was lingering, we allow this
1116 1116                           * to be interrupted by cancelling the linger timeout
1117 1117                           * and closing normally.
1118 1118                           *
1119 1119                           * 2) Revert to calling cv_wait()
1120 1120                           *
1121 1121                           * We revert to using cv_wait() to avoid an
1122 1122                           * infinite loop which can occur if the calling
1123 1123                           * thread is higher priority than the squeue worker
1124 1124                           * thread and is bound to the same cpu.
1125 1125                           */
1126 1126                          if (connp->conn_linger && connp->conn_lingertime > 0) {
1127 1127                                  mutex_exit(&tcp->tcp_closelock);
1128 1128                                  /* Entering squeue, bump ref count. */
1129 1129                                  CONN_INC_REF(connp);
1130 1130                                  bp = allocb_wait(0, BPRI_HI, STR_NOSIG, NULL);
1131 1131                                  SQUEUE_ENTER_ONE(connp->conn_sqp, bp,
1132 1132                                      tcp_linger_interrupted, connp, NULL,
1133 1133                                      tcp_squeue_flag, SQTAG_IP_TCP_CLOSE);
1134 1134                                  mutex_enter(&tcp->tcp_closelock);
1135 1135                          }
1136 1136                          break;
1137 1137                  }
1138 1138          }
1139 1139          while (!tcp->tcp_closed)
1140 1140                  cv_wait(&tcp->tcp_closecv, &tcp->tcp_closelock);
1141 1141          mutex_exit(&tcp->tcp_closelock);
1142 1142  
1143 1143          /*
1144 1144           * In the case of listener streams that have eagers in the q or q0
1145 1145           * we wait for the eagers to drop their reference to us. conn_rq and
1146 1146           * conn_wq of the eagers point to our queues. By waiting for the
1147 1147           * refcnt to drop to 1, we are sure that the eagers have cleaned
1148 1148           * up their queue pointers and also dropped their references to us.
1149 1149           *
1150 1150           * For non-STREAMS sockets we do not have to wait here; the
1151 1151           * listener will instead make a su_closed upcall when the last
1152 1152           * reference is dropped.
1153 1153           */
1154 1154          if (tcp->tcp_wait_for_eagers && !IPCL_IS_NONSTR(connp)) {
1155 1155                  mutex_enter(&connp->conn_lock);
1156 1156                  while (connp->conn_ref != 1) {
1157 1157                          cv_wait(&connp->conn_cv, &connp->conn_lock);
1158 1158                  }
1159 1159                  mutex_exit(&connp->conn_lock);
1160 1160          }
1161 1161  
1162 1162  nowait:
1163 1163          connp->conn_cpid = NOPID;
1164 1164  }
1165 1165  
1166 1166  /*
1167 1167   * Called by tcp_close() routine via squeue when lingering is
1168 1168   * interrupted by a signal.
1169 1169   */
1170 1170  
1171 1171  /* ARGSUSED */
1172 1172  static void
1173 1173  tcp_linger_interrupted(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *dummy)
1174 1174  {
1175 1175          conn_t  *connp = (conn_t *)arg;
1176 1176          tcp_t   *tcp = connp->conn_tcp;
1177 1177  
1178 1178          freeb(mp);
1179 1179          if (tcp->tcp_linger_tid != 0 &&
1180 1180              TCP_TIMER_CANCEL(tcp, tcp->tcp_linger_tid) >= 0) {
1181 1181                  tcp_stop_lingering(tcp);
1182 1182                  tcp->tcp_client_errno = EINTR;
1183 1183          }
1184 1184  }
1185 1185  
1186 1186  /*
1187 1187   * Clean up the b_next and b_prev fields of every mblk pointed at by *mpp.
1188 1188   * Some stream heads get upset if they see these later on as anything but NULL.
1189 1189   */
1190 1190  void
1191 1191  tcp_close_mpp(mblk_t **mpp)
1192 1192  {
1193 1193          mblk_t  *mp;
1194 1194  
1195 1195          if ((mp = *mpp) != NULL) {
1196 1196                  do {
1197 1197                          mp->b_next = NULL;
1198 1198                          mp->b_prev = NULL;
1199 1199                  } while ((mp = mp->b_cont) != NULL);
1200 1200  
1201 1201                  mp = *mpp;
1202 1202                  *mpp = NULL;
1203 1203                  freemsg(mp);
1204 1204          }
1205 1205  }
1206 1206  
1207 1207  /* Do detached close. */
1208 1208  void
1209 1209  tcp_close_detached(tcp_t *tcp)
1210 1210  {
1211 1211          if (tcp->tcp_fused)
1212 1212                  tcp_unfuse(tcp);
1213 1213  
1214 1214          /*
1215 1215           * Clustering code serializes TCP disconnect callbacks and
1216 1216           * cluster tcp list walks by blocking a TCP disconnect callback
1217 1217           * if a cluster tcp list walk is in progress. This ensures
1218 1218           * accurate accounting of TCPs in the cluster code even though
1219 1219           * the TCP list walk itself is not atomic.
1220 1220           */
1221 1221          tcp_closei_local(tcp);
1222 1222          CONN_DEC_REF(tcp->tcp_connp);
1223 1223  }
1224 1224  
1225 1225  /*
1226 1226   * The tcp_t is going away. Remove it from all lists and set it
1227 1227   * to TCPS_CLOSED. The freeing up of memory is deferred until
1228 1228   * tcp_inactive. This is needed since a thread in tcp_rput might have
1229 1229   * done a CONN_INC_REF on this structure before it was removed from the
1230 1230   * hashes.
1231 1231   */
1232 1232  void
1233 1233  tcp_closei_local(tcp_t *tcp)
1234 1234  {
1235 1235          conn_t          *connp = tcp->tcp_connp;
1236 1236          tcp_stack_t     *tcps = tcp->tcp_tcps;
1237 1237          int32_t         oldstate;
1238 1238  
1239 1239          if (!TCP_IS_SOCKET(tcp))
1240 1240                  tcp_acceptor_hash_remove(tcp);
1241 1241  
1242 1242          TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
1243 1243          tcp->tcp_ibsegs = 0;
1244 1244          TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
1245 1245          tcp->tcp_obsegs = 0;
1246 1246  
1247 1247          /*
1248 1248           * This can be called via tcp_time_wait_processing() if TCP gets a
1249 1249           * SYN with sequence number outside the TIME-WAIT connection's
1250 1250           * window.  So we need to check for TIME-WAIT state here as the
1251 1251           * connection counter is already decremented.  See SET_TIME_WAIT()
1252 1252           * macro
1253 1253           */
1254 1254          if (tcp->tcp_state >= TCPS_ESTABLISHED &&
1255 1255              tcp->tcp_state < TCPS_TIME_WAIT) {
1256 1256                  TCPS_CONN_DEC(tcps);
1257 1257          }
1258 1258  
1259 1259          /*
1260 1260           * If we are an eager connection hanging off a listener that
1261 1261           * hasn't formally accepted the connection yet, get off his
1262 1262           * list and blow off any data that we have accumulated.
1263 1263           */
1264 1264          if (tcp->tcp_listener != NULL) {
1265 1265                  tcp_t   *listener = tcp->tcp_listener;
1266 1266                  mutex_enter(&listener->tcp_eager_lock);
1267 1267                  /*
1268 1268                   * tcp_tconnind_started == B_TRUE means that the
1269 1269                   * conn_ind has already gone to listener. At
1270 1270                   * this point, eager will be closed but we
1271 1271                   * leave it in listeners eager list so that
1272 1272                   * if listener decides to close without doing
1273 1273                   * accept, we can clean this up. In tcp_tli_accept
1274 1274                   * we take care of the case of accept on closed
1275 1275                   * eager.
1276 1276                   */
1277 1277                  if (!tcp->tcp_tconnind_started) {
1278 1278                          tcp_eager_unlink(tcp);
1279 1279                          mutex_exit(&listener->tcp_eager_lock);
1280 1280                          /*
1281 1281                           * We don't want to have any pointers to the
1282 1282                           * listener queue, after we have released our
1283 1283                           * reference on the listener
1284 1284                           */
1285 1285                          ASSERT(tcp->tcp_detached);
1286 1286                          connp->conn_rq = NULL;
1287 1287                          connp->conn_wq = NULL;
1288 1288                          CONN_DEC_REF(listener->tcp_connp);
1289 1289                  } else {
1290 1290                          mutex_exit(&listener->tcp_eager_lock);
1291 1291                  }
1292 1292          }
1293 1293  
1294 1294          /* Stop all the timers */
1295 1295          tcp_timers_stop(tcp);
1296 1296  
1297 1297          if (tcp->tcp_state == TCPS_LISTEN) {
1298 1298                  if (tcp->tcp_ip_addr_cache) {
1299 1299                          kmem_free((void *)tcp->tcp_ip_addr_cache,
1300 1300                              IP_ADDR_CACHE_SIZE * sizeof (ipaddr_t));
1301 1301                          tcp->tcp_ip_addr_cache = NULL;
1302 1302                  }
1303 1303          }
1304 1304  
1305 1305          /* Decrement listerner connection counter if necessary. */
1306 1306          if (tcp->tcp_listen_cnt != NULL)
1307 1307                  TCP_DECR_LISTEN_CNT(tcp);
1308 1308  
1309 1309          mutex_enter(&tcp->tcp_non_sq_lock);
1310 1310          if (tcp->tcp_flow_stopped)
1311 1311                  tcp_clrqfull(tcp);
1312 1312          mutex_exit(&tcp->tcp_non_sq_lock);
1313 1313  
1314 1314          tcp_bind_hash_remove(tcp);
1315 1315          /*
1316 1316           * If the tcp_time_wait_collector (which runs outside the squeue)
1317 1317           * is trying to remove this tcp from the time wait list, we will
1318 1318           * block in tcp_time_wait_remove while trying to acquire the
1319 1319           * tcp_time_wait_lock. The logic in tcp_time_wait_collector also
1320 1320           * requires the ipcl_hash_remove to be ordered after the
1321 1321           * tcp_time_wait_remove for the refcnt checks to work correctly.
1322 1322           */
1323 1323          if (tcp->tcp_state == TCPS_TIME_WAIT)
1324 1324                  (void) tcp_time_wait_remove(tcp, NULL);
1325 1325          CL_INET_DISCONNECT(connp);
1326 1326          ipcl_hash_remove(connp);
1327 1327          oldstate = tcp->tcp_state;
1328 1328          tcp->tcp_state = TCPS_CLOSED;
1329 1329          /* Need to probe before ixa_cleanup() is called */
1330 1330          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
1331 1331              connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
1332 1332              int32_t, oldstate);
1333 1333          ixa_cleanup(connp->conn_ixa);
1334 1334  
1335 1335          /*
1336 1336           * Mark the conn as CONDEMNED
1337 1337           */
1338 1338          mutex_enter(&connp->conn_lock);
1339 1339          connp->conn_state_flags |= CONN_CONDEMNED;
1340 1340          mutex_exit(&connp->conn_lock);
1341 1341  
1342 1342          ASSERT(tcp->tcp_time_wait_next == NULL);
1343 1343          ASSERT(tcp->tcp_time_wait_prev == NULL);
1344 1344          ASSERT(tcp->tcp_time_wait_expire == 0);
1345 1345  
1346 1346          tcp_ipsec_cleanup(tcp);
1347 1347  }
1348 1348  
1349 1349  /*
1350 1350   * tcp is dying (called from ipcl_conn_destroy and error cases).
1351 1351   * Free the tcp_t in either case.
1352 1352   */
1353 1353  void
1354 1354  tcp_free(tcp_t *tcp)
1355 1355  {
1356 1356          mblk_t          *mp;
1357 1357          conn_t          *connp = tcp->tcp_connp;
1358 1358  
1359 1359          ASSERT(tcp != NULL);
1360 1360          ASSERT(tcp->tcp_ptpahn == NULL && tcp->tcp_acceptor_hash == NULL);
1361 1361  
1362 1362          connp->conn_rq = NULL;
1363 1363          connp->conn_wq = NULL;
1364 1364  
1365 1365          tcp_close_mpp(&tcp->tcp_xmit_head);
1366 1366          tcp_close_mpp(&tcp->tcp_reass_head);
1367 1367          if (tcp->tcp_rcv_list != NULL) {
1368 1368                  /* Free b_next chain */
1369 1369                  tcp_close_mpp(&tcp->tcp_rcv_list);
1370 1370          }
1371 1371          if ((mp = tcp->tcp_urp_mp) != NULL) {
1372 1372                  freemsg(mp);
1373 1373          }
1374 1374          if ((mp = tcp->tcp_urp_mark_mp) != NULL) {
1375 1375                  freemsg(mp);
1376 1376          }
1377 1377  
1378 1378          if (tcp->tcp_fused_sigurg_mp != NULL) {
1379 1379                  ASSERT(!IPCL_IS_NONSTR(tcp->tcp_connp));
1380 1380                  freeb(tcp->tcp_fused_sigurg_mp);
1381 1381                  tcp->tcp_fused_sigurg_mp = NULL;
1382 1382          }
1383 1383  
1384 1384          if (tcp->tcp_ordrel_mp != NULL) {
1385 1385                  ASSERT(!IPCL_IS_NONSTR(tcp->tcp_connp));
1386 1386                  freeb(tcp->tcp_ordrel_mp);
1387 1387                  tcp->tcp_ordrel_mp = NULL;
1388 1388          }
1389 1389  
1390 1390          TCP_NOTSACK_REMOVE_ALL(tcp->tcp_notsack_list, tcp);
1391 1391          bzero(&tcp->tcp_sack_info, sizeof (tcp_sack_info_t));
1392 1392  
1393 1393          if (tcp->tcp_hopopts != NULL) {
1394 1394                  mi_free(tcp->tcp_hopopts);
1395 1395                  tcp->tcp_hopopts = NULL;
1396 1396                  tcp->tcp_hopoptslen = 0;
1397 1397          }
1398 1398          ASSERT(tcp->tcp_hopoptslen == 0);
1399 1399          if (tcp->tcp_dstopts != NULL) {
1400 1400                  mi_free(tcp->tcp_dstopts);
1401 1401                  tcp->tcp_dstopts = NULL;
1402 1402                  tcp->tcp_dstoptslen = 0;
1403 1403          }
1404 1404          ASSERT(tcp->tcp_dstoptslen == 0);
1405 1405          if (tcp->tcp_rthdrdstopts != NULL) {
1406 1406                  mi_free(tcp->tcp_rthdrdstopts);
1407 1407                  tcp->tcp_rthdrdstopts = NULL;
1408 1408                  tcp->tcp_rthdrdstoptslen = 0;
1409 1409          }
1410 1410          ASSERT(tcp->tcp_rthdrdstoptslen == 0);
1411 1411          if (tcp->tcp_rthdr != NULL) {
1412 1412                  mi_free(tcp->tcp_rthdr);
1413 1413                  tcp->tcp_rthdr = NULL;
1414 1414                  tcp->tcp_rthdrlen = 0;
1415 1415          }
  
    | 
      ↓ open down ↓ | 
    1381 lines elided | 
    
      ↑ open up ↑ | 
  
1416 1416          ASSERT(tcp->tcp_rthdrlen == 0);
1417 1417  
1418 1418          /*
1419 1419           * Following is really a blowing away a union.
1420 1420           * It happens to have exactly two members of identical size
1421 1421           * the following code is enough.
1422 1422           */
1423 1423          tcp_close_mpp(&tcp->tcp_conn.tcp_eager_conn_ind);
1424 1424  
1425 1425          /*
     1426 +         * Destroy any association with SO_REUSEPORT group.
     1427 +         */
     1428 +        if (tcp->tcp_rg_bind != NULL) {
     1429 +                /*
     1430 +                 * This is only necessary for connections which enabled
     1431 +                 * SO_REUSEPORT but were never bound.  Such connections should
     1432 +                 * be the one and only member of the tcp_rg_tp to which they
     1433 +                 * have been associated.
     1434 +                 */
     1435 +                VERIFY(tcp_rg_remove(tcp->tcp_rg_bind, tcp));
     1436 +                tcp_rg_destroy(tcp->tcp_rg_bind);
     1437 +                tcp->tcp_rg_bind = NULL;
     1438 +        }
     1439 +
     1440 +        /*
1426 1441           * If this is a non-STREAM socket still holding on to an upper
1427 1442           * handle, release it. As a result of fallback we might also see
1428 1443           * STREAMS based conns with upper handles, in which case there is
1429 1444           * nothing to do other than clearing the field.
1430 1445           */
1431 1446          if (connp->conn_upper_handle != NULL) {
1432 1447                  if (IPCL_IS_NONSTR(connp)) {
1433 1448                          (*connp->conn_upcalls->su_closed)(
1434 1449                              connp->conn_upper_handle);
1435 1450                          tcp->tcp_detached = B_TRUE;
1436 1451                  }
1437 1452                  connp->conn_upper_handle = NULL;
1438 1453                  connp->conn_upcalls = NULL;
1439 1454          }
1440 1455  }
1441 1456  
1442 1457  /*
1443 1458   * tcp_get_conn/tcp_free_conn
1444 1459   *
1445 1460   * tcp_get_conn is used to get a clean tcp connection structure.
1446 1461   * It tries to reuse the connections put on the freelist by the
1447 1462   * time_wait_collector failing which it goes to kmem_cache. This
1448 1463   * way has two benefits compared to just allocating from and
1449 1464   * freeing to kmem_cache.
1450 1465   * 1) The time_wait_collector can free (which includes the cleanup)
1451 1466   * outside the squeue. So when the interrupt comes, we have a clean
1452 1467   * connection sitting in the freelist. Obviously, this buys us
1453 1468   * performance.
1454 1469   *
1455 1470   * 2) Defence against DOS attack. Allocating a tcp/conn in tcp_input_listener
1456 1471   * has multiple disadvantages - tying up the squeue during alloc.
1457 1472   * But allocating the conn/tcp in IP land is also not the best since
1458 1473   * we can't check the 'q' and 'q0' which are protected by squeue and
1459 1474   * blindly allocate memory which might have to be freed here if we are
1460 1475   * not allowed to accept the connection. By using the freelist and
1461 1476   * putting the conn/tcp back in freelist, we don't pay a penalty for
1462 1477   * allocating memory without checking 'q/q0' and freeing it if we can't
1463 1478   * accept the connection.
1464 1479   *
1465 1480   * Care should be taken to put the conn back in the same squeue's freelist
1466 1481   * from which it was allocated. Best results are obtained if conn is
1467 1482   * allocated from listener's squeue and freed to the same. Time wait
1468 1483   * collector will free up the freelist is the connection ends up sitting
1469 1484   * there for too long.
1470 1485   */
1471 1486  void *
1472 1487  tcp_get_conn(void *arg, tcp_stack_t *tcps)
1473 1488  {
1474 1489          tcp_t                   *tcp = NULL;
1475 1490          conn_t                  *connp = NULL;
1476 1491          squeue_t                *sqp = (squeue_t *)arg;
1477 1492          tcp_squeue_priv_t       *tcp_time_wait;
1478 1493          netstack_t              *ns;
1479 1494          mblk_t                  *tcp_rsrv_mp = NULL;
1480 1495  
1481 1496          tcp_time_wait =
1482 1497              *((tcp_squeue_priv_t **)squeue_getprivate(sqp, SQPRIVATE_TCP));
1483 1498  
1484 1499          mutex_enter(&tcp_time_wait->tcp_time_wait_lock);
1485 1500          tcp = tcp_time_wait->tcp_free_list;
1486 1501          ASSERT((tcp != NULL) ^ (tcp_time_wait->tcp_free_list_cnt == 0));
1487 1502          if (tcp != NULL) {
1488 1503                  tcp_time_wait->tcp_free_list = tcp->tcp_time_wait_next;
1489 1504                  tcp_time_wait->tcp_free_list_cnt--;
1490 1505                  mutex_exit(&tcp_time_wait->tcp_time_wait_lock);
1491 1506                  tcp->tcp_time_wait_next = NULL;
1492 1507                  connp = tcp->tcp_connp;
1493 1508                  connp->conn_flags |= IPCL_REUSED;
1494 1509  
1495 1510                  ASSERT(tcp->tcp_tcps == NULL);
1496 1511                  ASSERT(connp->conn_netstack == NULL);
1497 1512                  ASSERT(tcp->tcp_rsrv_mp != NULL);
1498 1513                  ns = tcps->tcps_netstack;
1499 1514                  netstack_hold(ns);
1500 1515                  connp->conn_netstack = ns;
1501 1516                  connp->conn_ixa->ixa_ipst = ns->netstack_ip;
1502 1517                  tcp->tcp_tcps = tcps;
1503 1518                  ipcl_globalhash_insert(connp);
1504 1519  
1505 1520                  connp->conn_ixa->ixa_notify_cookie = tcp;
1506 1521                  ASSERT(connp->conn_ixa->ixa_notify == tcp_notify);
1507 1522                  connp->conn_recv = tcp_input_data;
1508 1523                  ASSERT(connp->conn_recvicmp == tcp_icmp_input);
1509 1524                  ASSERT(connp->conn_verifyicmp == tcp_verifyicmp);
1510 1525                  return ((void *)connp);
1511 1526          }
1512 1527          mutex_exit(&tcp_time_wait->tcp_time_wait_lock);
1513 1528          /*
1514 1529           * Pre-allocate the tcp_rsrv_mp. This mblk will not be freed until
1515 1530           * this conn_t/tcp_t is freed at ipcl_conn_destroy().
1516 1531           */
1517 1532          tcp_rsrv_mp = allocb(0, BPRI_HI);
1518 1533          if (tcp_rsrv_mp == NULL)
1519 1534                  return (NULL);
1520 1535  
1521 1536          if ((connp = ipcl_conn_create(IPCL_TCPCONN, KM_NOSLEEP,
1522 1537              tcps->tcps_netstack)) == NULL) {
1523 1538                  freeb(tcp_rsrv_mp);
1524 1539                  return (NULL);
1525 1540          }
1526 1541  
1527 1542          tcp = connp->conn_tcp;
1528 1543          tcp->tcp_rsrv_mp = tcp_rsrv_mp;
1529 1544          mutex_init(&tcp->tcp_rsrv_mp_lock, NULL, MUTEX_DEFAULT, NULL);
1530 1545  
1531 1546          tcp->tcp_tcps = tcps;
1532 1547  
1533 1548          connp->conn_recv = tcp_input_data;
1534 1549          connp->conn_recvicmp = tcp_icmp_input;
1535 1550          connp->conn_verifyicmp = tcp_verifyicmp;
1536 1551  
1537 1552          /*
1538 1553           * Register tcp_notify to listen to capability changes detected by IP.
1539 1554           * This upcall is made in the context of the call to conn_ip_output
1540 1555           * thus it is inside the squeue.
1541 1556           */
1542 1557          connp->conn_ixa->ixa_notify = tcp_notify;
1543 1558          connp->conn_ixa->ixa_notify_cookie = tcp;
1544 1559  
1545 1560          return ((void *)connp);
1546 1561  }
1547 1562  
1548 1563  /*
1549 1564   * Handle connect to IPv4 destinations, including connections for AF_INET6
1550 1565   * sockets connecting to IPv4 mapped IPv6 destinations.
1551 1566   * Returns zero if OK, a positive errno, or a negative TLI error.
1552 1567   */
1553 1568  static int
1554 1569  tcp_connect_ipv4(tcp_t *tcp, ipaddr_t *dstaddrp, in_port_t dstport,
1555 1570      uint_t srcid)
1556 1571  {
1557 1572          ipaddr_t        dstaddr = *dstaddrp;
1558 1573          uint16_t        lport;
1559 1574          conn_t          *connp = tcp->tcp_connp;
1560 1575          tcp_stack_t     *tcps = tcp->tcp_tcps;
1561 1576          int             error;
1562 1577  
1563 1578          ASSERT(connp->conn_ipversion == IPV4_VERSION);
1564 1579  
1565 1580          /* Check for attempt to connect to INADDR_ANY */
1566 1581          if (dstaddr == INADDR_ANY)  {
1567 1582                  /*
1568 1583                   * SunOS 4.x and 4.3 BSD allow an application
1569 1584                   * to connect a TCP socket to INADDR_ANY.
1570 1585                   * When they do this, the kernel picks the
1571 1586                   * address of one interface and uses it
1572 1587                   * instead.  The kernel usually ends up
1573 1588                   * picking the address of the loopback
1574 1589                   * interface.  This is an undocumented feature.
1575 1590                   * However, we provide the same thing here
1576 1591                   * in order to have source and binary
1577 1592                   * compatibility with SunOS 4.x.
1578 1593                   * Update the T_CONN_REQ (sin/sin6) since it is used to
1579 1594                   * generate the T_CONN_CON.
1580 1595                   */
1581 1596                  dstaddr = htonl(INADDR_LOOPBACK);
1582 1597                  *dstaddrp = dstaddr;
1583 1598          }
1584 1599  
1585 1600          /* Handle __sin6_src_id if socket not bound to an IP address */
1586 1601          if (srcid != 0 && connp->conn_laddr_v4 == INADDR_ANY) {
1587 1602                  if (!ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
1588 1603                      IPCL_ZONEID(connp), B_TRUE, tcps->tcps_netstack)) {
1589 1604                          /* Mismatch - conn_laddr_v6 would be v6 address. */
1590 1605                          return (EADDRNOTAVAIL);
1591 1606                  }
1592 1607                  connp->conn_saddr_v6 = connp->conn_laddr_v6;
1593 1608          }
1594 1609  
1595 1610          IN6_IPADDR_TO_V4MAPPED(dstaddr, &connp->conn_faddr_v6);
1596 1611          connp->conn_fport = dstport;
1597 1612  
1598 1613          /*
1599 1614           * At this point the remote destination address and remote port fields
1600 1615           * in the tcp-four-tuple have been filled in the tcp structure. Now we
1601 1616           * have to see which state tcp was in so we can take appropriate action.
1602 1617           */
1603 1618          if (tcp->tcp_state == TCPS_IDLE) {
1604 1619                  /*
1605 1620                   * We support a quick connect capability here, allowing
1606 1621                   * clients to transition directly from IDLE to SYN_SENT
1607 1622                   * tcp_bindi will pick an unused port, insert the connection
1608 1623                   * in the bind hash and transition to BOUND state.
1609 1624                   */
1610 1625                  lport = tcp_update_next_port(tcps->tcps_next_port_to_try,
1611 1626                      tcp, B_TRUE);
1612 1627                  lport = tcp_bindi(tcp, lport, &connp->conn_laddr_v6, 0, B_TRUE,
1613 1628                      B_FALSE, B_FALSE);
1614 1629                  if (lport == 0)
1615 1630                          return (-TNOADDR);
1616 1631          }
1617 1632  
1618 1633          /*
1619 1634           * Lookup the route to determine a source address and the uinfo.
1620 1635           * Setup TCP parameters based on the metrics/DCE.
1621 1636           */
1622 1637          error = tcp_set_destination(tcp);
1623 1638          if (error != 0)
1624 1639                  return (error);
1625 1640  
1626 1641          /*
1627 1642           * Don't let an endpoint connect to itself.
1628 1643           */
1629 1644          if (connp->conn_faddr_v4 == connp->conn_laddr_v4 &&
1630 1645              connp->conn_fport == connp->conn_lport)
1631 1646                  return (-TBADADDR);
1632 1647  
1633 1648          tcp->tcp_state = TCPS_SYN_SENT;
1634 1649  
1635 1650          return (ipcl_conn_insert_v4(connp));
1636 1651  }
1637 1652  
1638 1653  /*
1639 1654   * Handle connect to IPv6 destinations.
1640 1655   * Returns zero if OK, a positive errno, or a negative TLI error.
1641 1656   */
1642 1657  static int
1643 1658  tcp_connect_ipv6(tcp_t *tcp, in6_addr_t *dstaddrp, in_port_t dstport,
1644 1659      uint32_t flowinfo, uint_t srcid, uint32_t scope_id)
1645 1660  {
1646 1661          uint16_t        lport;
1647 1662          conn_t          *connp = tcp->tcp_connp;
1648 1663          tcp_stack_t     *tcps = tcp->tcp_tcps;
1649 1664          int             error;
1650 1665  
1651 1666          ASSERT(connp->conn_family == AF_INET6);
1652 1667  
1653 1668          /*
1654 1669           * If we're here, it means that the destination address is a native
1655 1670           * IPv6 address.  Return an error if conn_ipversion is not IPv6.  A
1656 1671           * reason why it might not be IPv6 is if the socket was bound to an
1657 1672           * IPv4-mapped IPv6 address.
1658 1673           */
1659 1674          if (connp->conn_ipversion != IPV6_VERSION)
1660 1675                  return (-TBADADDR);
1661 1676  
1662 1677          /*
1663 1678           * Interpret a zero destination to mean loopback.
1664 1679           * Update the T_CONN_REQ (sin/sin6) since it is used to
1665 1680           * generate the T_CONN_CON.
1666 1681           */
1667 1682          if (IN6_IS_ADDR_UNSPECIFIED(dstaddrp))
1668 1683                  *dstaddrp = ipv6_loopback;
1669 1684  
1670 1685          /* Handle __sin6_src_id if socket not bound to an IP address */
1671 1686          if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1672 1687                  if (!ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
1673 1688                      IPCL_ZONEID(connp), B_FALSE, tcps->tcps_netstack)) {
1674 1689                          /* Mismatch - conn_laddr_v6 would be v4-mapped. */
1675 1690                          return (EADDRNOTAVAIL);
1676 1691                  }
1677 1692                  connp->conn_saddr_v6 = connp->conn_laddr_v6;
1678 1693          }
1679 1694  
1680 1695          /*
1681 1696           * Take care of the scope_id now.
1682 1697           */
1683 1698          if (scope_id != 0 && IN6_IS_ADDR_LINKSCOPE(dstaddrp)) {
1684 1699                  connp->conn_ixa->ixa_flags |= IXAF_SCOPEID_SET;
1685 1700                  connp->conn_ixa->ixa_scopeid = scope_id;
1686 1701          } else {
1687 1702                  connp->conn_ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
1688 1703          }
1689 1704  
1690 1705          connp->conn_flowinfo = flowinfo;
1691 1706          connp->conn_faddr_v6 = *dstaddrp;
1692 1707          connp->conn_fport = dstport;
1693 1708  
1694 1709          /*
1695 1710           * At this point the remote destination address and remote port fields
1696 1711           * in the tcp-four-tuple have been filled in the tcp structure. Now we
1697 1712           * have to see which state tcp was in so we can take appropriate action.
1698 1713           */
1699 1714          if (tcp->tcp_state == TCPS_IDLE) {
1700 1715                  /*
1701 1716                   * We support a quick connect capability here, allowing
1702 1717                   * clients to transition directly from IDLE to SYN_SENT
1703 1718                   * tcp_bindi will pick an unused port, insert the connection
1704 1719                   * in the bind hash and transition to BOUND state.
1705 1720                   */
1706 1721                  lport = tcp_update_next_port(tcps->tcps_next_port_to_try,
1707 1722                      tcp, B_TRUE);
1708 1723                  lport = tcp_bindi(tcp, lport, &connp->conn_laddr_v6, 0, B_TRUE,
1709 1724                      B_FALSE, B_FALSE);
1710 1725                  if (lport == 0)
1711 1726                          return (-TNOADDR);
1712 1727          }
1713 1728  
1714 1729          /*
1715 1730           * Lookup the route to determine a source address and the uinfo.
1716 1731           * Setup TCP parameters based on the metrics/DCE.
1717 1732           */
1718 1733          error = tcp_set_destination(tcp);
1719 1734          if (error != 0)
1720 1735                  return (error);
1721 1736  
1722 1737          /*
1723 1738           * Don't let an endpoint connect to itself.
1724 1739           */
1725 1740          if (IN6_ARE_ADDR_EQUAL(&connp->conn_faddr_v6, &connp->conn_laddr_v6) &&
1726 1741              connp->conn_fport == connp->conn_lport)
1727 1742                  return (-TBADADDR);
1728 1743  
1729 1744          tcp->tcp_state = TCPS_SYN_SENT;
1730 1745  
1731 1746          return (ipcl_conn_insert_v6(connp));
1732 1747  }
1733 1748  
1734 1749  /*
1735 1750   * Disconnect
1736 1751   * Note that unlike other functions this returns a positive tli error
1737 1752   * when it fails; it never returns an errno.
1738 1753   */
1739 1754  static int
1740 1755  tcp_disconnect_common(tcp_t *tcp, t_scalar_t seqnum)
1741 1756  {
1742 1757          conn_t          *lconnp;
1743 1758          tcp_stack_t     *tcps = tcp->tcp_tcps;
1744 1759          conn_t          *connp = tcp->tcp_connp;
1745 1760  
1746 1761          /*
1747 1762           * Right now, upper modules pass down a T_DISCON_REQ to TCP,
1748 1763           * when the stream is in BOUND state. Do not send a reset,
1749 1764           * since the destination IP address is not valid, and it can
1750 1765           * be the initialized value of all zeros (broadcast address).
1751 1766           */
1752 1767          if (tcp->tcp_state <= TCPS_BOUND) {
1753 1768                  if (connp->conn_debug) {
1754 1769                          (void) strlog(TCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
1755 1770                              "tcp_disconnect: bad state, %d", tcp->tcp_state);
1756 1771                  }
1757 1772                  return (TOUTSTATE);
1758 1773          } else if (tcp->tcp_state >= TCPS_ESTABLISHED) {
1759 1774                  TCPS_CONN_DEC(tcps);
1760 1775          }
1761 1776  
1762 1777          if (seqnum == -1 || tcp->tcp_conn_req_max == 0) {
1763 1778  
1764 1779                  /*
1765 1780                   * According to TPI, for non-listeners, ignore seqnum
1766 1781                   * and disconnect.
1767 1782                   * Following interpretation of -1 seqnum is historical
1768 1783                   * and implied TPI ? (TPI only states that for T_CONN_IND,
1769 1784                   * a valid seqnum should not be -1).
1770 1785                   *
1771 1786                   *      -1 means disconnect everything
1772 1787                   *      regardless even on a listener.
1773 1788                   */
1774 1789  
1775 1790                  int old_state = tcp->tcp_state;
1776 1791                  ip_stack_t *ipst = tcps->tcps_netstack->netstack_ip;
1777 1792  
1778 1793                  /*
1779 1794                   * The connection can't be on the tcp_time_wait_head list
1780 1795                   * since it is not detached.
1781 1796                   */
1782 1797                  ASSERT(tcp->tcp_time_wait_next == NULL);
1783 1798                  ASSERT(tcp->tcp_time_wait_prev == NULL);
1784 1799                  ASSERT(tcp->tcp_time_wait_expire == 0);
1785 1800                  /*
1786 1801                   * If it used to be a listener, check to make sure no one else
1787 1802                   * has taken the port before switching back to LISTEN state.
1788 1803                   */
1789 1804                  if (connp->conn_ipversion == IPV4_VERSION) {
1790 1805                          lconnp = ipcl_lookup_listener_v4(connp->conn_lport,
1791 1806                              connp->conn_laddr_v4, IPCL_ZONEID(connp), ipst);
1792 1807                  } else {
1793 1808                          uint_t ifindex = 0;
1794 1809  
1795 1810                          if (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET)
1796 1811                                  ifindex = connp->conn_ixa->ixa_scopeid;
1797 1812  
1798 1813                          /* Allow conn_bound_if listeners? */
1799 1814                          lconnp = ipcl_lookup_listener_v6(connp->conn_lport,
1800 1815                              &connp->conn_laddr_v6, ifindex, IPCL_ZONEID(connp),
1801 1816                              ipst);
1802 1817                  }
1803 1818                  if (tcp->tcp_conn_req_max && lconnp == NULL) {
1804 1819                          tcp->tcp_state = TCPS_LISTEN;
1805 1820                          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
1806 1821                              connp->conn_ixa, void, NULL, tcp_t *, tcp, void,
1807 1822                              NULL, int32_t, old_state);
1808 1823                  } else if (old_state > TCPS_BOUND) {
1809 1824                          tcp->tcp_conn_req_max = 0;
1810 1825                          tcp->tcp_state = TCPS_BOUND;
1811 1826                          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
1812 1827                              connp->conn_ixa, void, NULL, tcp_t *, tcp, void,
1813 1828                              NULL, int32_t, old_state);
1814 1829  
1815 1830                          /*
1816 1831                           * If this end point is not going to become a listener,
1817 1832                           * decrement the listener connection count if
1818 1833                           * necessary.  Note that we do not do this if it is
1819 1834                           * going to be a listner (the above if case) since
1820 1835                           * then it may remove the counter struct.
1821 1836                           */
1822 1837                          if (tcp->tcp_listen_cnt != NULL)
1823 1838                                  TCP_DECR_LISTEN_CNT(tcp);
1824 1839                  }
1825 1840                  if (lconnp != NULL)
1826 1841                          CONN_DEC_REF(lconnp);
1827 1842                  switch (old_state) {
1828 1843                  case TCPS_SYN_SENT:
1829 1844                  case TCPS_SYN_RCVD:
1830 1845                          TCPS_BUMP_MIB(tcps, tcpAttemptFails);
1831 1846                          break;
1832 1847                  case TCPS_ESTABLISHED:
1833 1848                  case TCPS_CLOSE_WAIT:
1834 1849                          TCPS_BUMP_MIB(tcps, tcpEstabResets);
1835 1850                          break;
1836 1851                  }
1837 1852  
1838 1853                  if (tcp->tcp_fused)
1839 1854                          tcp_unfuse(tcp);
1840 1855  
1841 1856                  mutex_enter(&tcp->tcp_eager_lock);
1842 1857                  if ((tcp->tcp_conn_req_cnt_q0 != 0) ||
1843 1858                      (tcp->tcp_conn_req_cnt_q != 0)) {
1844 1859                          tcp_eager_cleanup(tcp, 0);
1845 1860                  }
1846 1861                  mutex_exit(&tcp->tcp_eager_lock);
1847 1862  
1848 1863                  tcp_xmit_ctl("tcp_disconnect", tcp, tcp->tcp_snxt,
1849 1864                      tcp->tcp_rnxt, TH_RST | TH_ACK);
1850 1865  
1851 1866                  tcp_reinit(tcp);
1852 1867  
1853 1868                  return (0);
1854 1869          } else if (!tcp_eager_blowoff(tcp, seqnum)) {
1855 1870                  return (TBADSEQ);
1856 1871          }
1857 1872          return (0);
1858 1873  }
1859 1874  
1860 1875  /*
1861 1876   * Our client hereby directs us to reject the connection request
1862 1877   * that tcp_input_listener() marked with 'seqnum'.  Rejection consists
1863 1878   * of sending the appropriate RST, not an ICMP error.
1864 1879   */
1865 1880  void
1866 1881  tcp_disconnect(tcp_t *tcp, mblk_t *mp)
1867 1882  {
1868 1883          t_scalar_t seqnum;
1869 1884          int     error;
1870 1885          conn_t  *connp = tcp->tcp_connp;
1871 1886  
1872 1887          ASSERT((uintptr_t)(mp->b_wptr - mp->b_rptr) <= (uintptr_t)INT_MAX);
1873 1888          if ((mp->b_wptr - mp->b_rptr) < sizeof (struct T_discon_req)) {
1874 1889                  tcp_err_ack(tcp, mp, TPROTO, 0);
1875 1890                  return;
1876 1891          }
1877 1892          seqnum = ((struct T_discon_req *)mp->b_rptr)->SEQ_number;
1878 1893          error = tcp_disconnect_common(tcp, seqnum);
1879 1894          if (error != 0)
1880 1895                  tcp_err_ack(tcp, mp, error, 0);
1881 1896          else {
1882 1897                  if (tcp->tcp_state >= TCPS_ESTABLISHED) {
1883 1898                          /* Send M_FLUSH according to TPI */
1884 1899                          (void) putnextctl1(connp->conn_rq, M_FLUSH, FLUSHRW);
1885 1900                  }
1886 1901                  mp = mi_tpi_ok_ack_alloc(mp);
1887 1902                  if (mp != NULL)
1888 1903                          putnext(connp->conn_rq, mp);
1889 1904          }
1890 1905  }
1891 1906  
1892 1907  /*
1893 1908   * Handle reinitialization of a tcp structure.
1894 1909   * Maintain "binding state" resetting the state to BOUND, LISTEN, or IDLE.
1895 1910   */
1896 1911  static void
1897 1912  tcp_reinit(tcp_t *tcp)
1898 1913  {
1899 1914          mblk_t          *mp;
1900 1915          tcp_stack_t     *tcps = tcp->tcp_tcps;
1901 1916          conn_t          *connp  = tcp->tcp_connp;
1902 1917          int32_t         oldstate;
1903 1918  
1904 1919          /* tcp_reinit should never be called for detached tcp_t's */
1905 1920          ASSERT(tcp->tcp_listener == NULL);
1906 1921          ASSERT((connp->conn_family == AF_INET &&
1907 1922              connp->conn_ipversion == IPV4_VERSION) ||
1908 1923              (connp->conn_family == AF_INET6 &&
1909 1924              (connp->conn_ipversion == IPV4_VERSION ||
1910 1925              connp->conn_ipversion == IPV6_VERSION)));
1911 1926  
1912 1927          /* Cancel outstanding timers */
1913 1928          tcp_timers_stop(tcp);
1914 1929  
1915 1930          /*
1916 1931           * Reset everything in the state vector, after updating global
1917 1932           * MIB data from instance counters.
1918 1933           */
1919 1934          TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
1920 1935          tcp->tcp_ibsegs = 0;
1921 1936          TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
1922 1937          tcp->tcp_obsegs = 0;
1923 1938  
1924 1939          tcp_close_mpp(&tcp->tcp_xmit_head);
1925 1940          if (tcp->tcp_snd_zcopy_aware)
1926 1941                  tcp_zcopy_notify(tcp);
1927 1942          tcp->tcp_xmit_last = tcp->tcp_xmit_tail = NULL;
1928 1943          tcp->tcp_unsent = tcp->tcp_xmit_tail_unsent = 0;
1929 1944          mutex_enter(&tcp->tcp_non_sq_lock);
1930 1945          if (tcp->tcp_flow_stopped &&
1931 1946              TCP_UNSENT_BYTES(tcp) <= connp->conn_sndlowat) {
1932 1947                  tcp_clrqfull(tcp);
1933 1948          }
1934 1949          mutex_exit(&tcp->tcp_non_sq_lock);
1935 1950          tcp_close_mpp(&tcp->tcp_reass_head);
1936 1951          tcp->tcp_reass_tail = NULL;
1937 1952          if (tcp->tcp_rcv_list != NULL) {
1938 1953                  /* Free b_next chain */
1939 1954                  tcp_close_mpp(&tcp->tcp_rcv_list);
1940 1955                  tcp->tcp_rcv_last_head = NULL;
1941 1956                  tcp->tcp_rcv_last_tail = NULL;
1942 1957                  tcp->tcp_rcv_cnt = 0;
1943 1958          }
1944 1959          tcp->tcp_rcv_last_tail = NULL;
1945 1960  
1946 1961          if ((mp = tcp->tcp_urp_mp) != NULL) {
1947 1962                  freemsg(mp);
1948 1963                  tcp->tcp_urp_mp = NULL;
1949 1964          }
1950 1965          if ((mp = tcp->tcp_urp_mark_mp) != NULL) {
1951 1966                  freemsg(mp);
1952 1967                  tcp->tcp_urp_mark_mp = NULL;
1953 1968          }
1954 1969          if (tcp->tcp_fused_sigurg_mp != NULL) {
1955 1970                  ASSERT(!IPCL_IS_NONSTR(tcp->tcp_connp));
1956 1971                  freeb(tcp->tcp_fused_sigurg_mp);
1957 1972                  tcp->tcp_fused_sigurg_mp = NULL;
1958 1973          }
1959 1974          if (tcp->tcp_ordrel_mp != NULL) {
1960 1975                  ASSERT(!IPCL_IS_NONSTR(tcp->tcp_connp));
1961 1976                  freeb(tcp->tcp_ordrel_mp);
1962 1977                  tcp->tcp_ordrel_mp = NULL;
1963 1978          }
1964 1979  
1965 1980          /*
1966 1981           * Following is a union with two members which are
1967 1982           * identical types and size so the following cleanup
1968 1983           * is enough.
1969 1984           */
1970 1985          tcp_close_mpp(&tcp->tcp_conn.tcp_eager_conn_ind);
1971 1986  
1972 1987          CL_INET_DISCONNECT(connp);
1973 1988  
1974 1989          /*
1975 1990           * The connection can't be on the tcp_time_wait_head list
1976 1991           * since it is not detached.
1977 1992           */
1978 1993          ASSERT(tcp->tcp_time_wait_next == NULL);
1979 1994          ASSERT(tcp->tcp_time_wait_prev == NULL);
1980 1995          ASSERT(tcp->tcp_time_wait_expire == 0);
1981 1996  
1982 1997          /*
1983 1998           * Reset/preserve other values
1984 1999           */
1985 2000          tcp_reinit_values(tcp);
1986 2001          ipcl_hash_remove(connp);
1987 2002          /* Note that ixa_cred gets cleared in ixa_cleanup */
1988 2003          ixa_cleanup(connp->conn_ixa);
1989 2004          tcp_ipsec_cleanup(tcp);
1990 2005  
1991 2006          connp->conn_laddr_v6 = connp->conn_bound_addr_v6;
1992 2007          connp->conn_saddr_v6 = connp->conn_bound_addr_v6;
1993 2008          oldstate = tcp->tcp_state;
1994 2009  
1995 2010          if (tcp->tcp_conn_req_max != 0) {
1996 2011                  /*
1997 2012                   * This is the case when a TLI program uses the same
1998 2013                   * transport end point to accept a connection.  This
1999 2014                   * makes the TCP both a listener and acceptor.  When
2000 2015                   * this connection is closed, we need to set the state
2001 2016                   * back to TCPS_LISTEN.  Make sure that the eager list
2002 2017                   * is reinitialized.
2003 2018                   *
2004 2019                   * Note that this stream is still bound to the four
2005 2020                   * tuples of the previous connection in IP.  If a new
2006 2021                   * SYN with different foreign address comes in, IP will
2007 2022                   * not find it and will send it to the global queue.  In
2008 2023                   * the global queue, TCP will do a tcp_lookup_listener()
2009 2024                   * to find this stream.  This works because this stream
2010 2025                   * is only removed from connected hash.
2011 2026                   *
2012 2027                   */
2013 2028                  tcp->tcp_state = TCPS_LISTEN;
2014 2029                  tcp->tcp_eager_next_q0 = tcp->tcp_eager_prev_q0 = tcp;
2015 2030                  tcp->tcp_eager_next_drop_q0 = tcp;
2016 2031                  tcp->tcp_eager_prev_drop_q0 = tcp;
2017 2032                  /*
2018 2033                   * Initially set conn_recv to tcp_input_listener_unbound to try
2019 2034                   * to pick a good squeue for the listener when the first SYN
2020 2035                   * arrives. tcp_input_listener_unbound sets it to
2021 2036                   * tcp_input_listener on that first SYN.
2022 2037                   */
2023 2038                  connp->conn_recv = tcp_input_listener_unbound;
2024 2039  
2025 2040                  connp->conn_proto = IPPROTO_TCP;
2026 2041                  connp->conn_faddr_v6 = ipv6_all_zeros;
2027 2042                  connp->conn_fport = 0;
2028 2043  
2029 2044                  (void) ipcl_bind_insert(connp);
2030 2045          } else {
2031 2046                  tcp->tcp_state = TCPS_BOUND;
2032 2047          }
2033 2048  
2034 2049          /*
2035 2050           * Initialize to default values
2036 2051           */
2037 2052          tcp_init_values(tcp, NULL);
2038 2053  
2039 2054          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
2040 2055              connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
2041 2056              int32_t, oldstate);
2042 2057  
2043 2058          ASSERT(tcp->tcp_ptpbhn != NULL);
2044 2059          tcp->tcp_rwnd = connp->conn_rcvbuf;
2045 2060          tcp->tcp_mss = connp->conn_ipversion != IPV4_VERSION ?
2046 2061              tcps->tcps_mss_def_ipv6 : tcps->tcps_mss_def_ipv4;
  
    | 
      ↓ open down ↓ | 
    611 lines elided | 
    
      ↑ open up ↑ | 
  
2047 2062  }
2048 2063  
2049 2064  /*
2050 2065   * Force values to zero that need be zero.
2051 2066   * Do not touch values asociated with the BOUND or LISTEN state
2052 2067   * since the connection will end up in that state after the reinit.
2053 2068   * NOTE: tcp_reinit_values MUST have a line for each field in the tcp_t
2054 2069   * structure!
2055 2070   */
2056 2071  static void
2057      -tcp_reinit_values(tcp)
2058      -        tcp_t *tcp;
     2072 +tcp_reinit_values(tcp_t *tcp)
2059 2073  {
2060 2074          tcp_stack_t     *tcps = tcp->tcp_tcps;
2061 2075          conn_t          *connp = tcp->tcp_connp;
2062 2076  
2063 2077  #ifndef lint
2064 2078  #define DONTCARE(x)
2065 2079  #define PRESERVE(x)
2066 2080  #else
2067 2081  #define DONTCARE(x)     ((x) = (x))
2068 2082  #define PRESERVE(x)     ((x) = (x))
2069 2083  #endif  /* lint */
2070 2084  
2071 2085          PRESERVE(tcp->tcp_bind_hash_port);
2072 2086          PRESERVE(tcp->tcp_bind_hash);
2073 2087          PRESERVE(tcp->tcp_ptpbhn);
2074 2088          PRESERVE(tcp->tcp_acceptor_hash);
2075 2089          PRESERVE(tcp->tcp_ptpahn);
2076 2090  
2077 2091          /* Should be ASSERT NULL on these with new code! */
2078 2092          ASSERT(tcp->tcp_time_wait_next == NULL);
2079 2093          ASSERT(tcp->tcp_time_wait_prev == NULL);
2080 2094          ASSERT(tcp->tcp_time_wait_expire == 0);
2081 2095          PRESERVE(tcp->tcp_state);
2082 2096          PRESERVE(connp->conn_rq);
2083 2097          PRESERVE(connp->conn_wq);
2084 2098  
2085 2099          ASSERT(tcp->tcp_xmit_head == NULL);
2086 2100          ASSERT(tcp->tcp_xmit_last == NULL);
2087 2101          ASSERT(tcp->tcp_unsent == 0);
2088 2102          ASSERT(tcp->tcp_xmit_tail == NULL);
2089 2103          ASSERT(tcp->tcp_xmit_tail_unsent == 0);
2090 2104  
2091 2105          tcp->tcp_snxt = 0;                      /* Displayed in mib */
2092 2106          tcp->tcp_suna = 0;                      /* Displayed in mib */
2093 2107          tcp->tcp_swnd = 0;
2094 2108          DONTCARE(tcp->tcp_cwnd);        /* Init in tcp_process_options */
2095 2109  
2096 2110          ASSERT(tcp->tcp_ibsegs == 0);
2097 2111          ASSERT(tcp->tcp_obsegs == 0);
2098 2112  
2099 2113          if (connp->conn_ht_iphc != NULL) {
2100 2114                  kmem_free(connp->conn_ht_iphc, connp->conn_ht_iphc_allocated);
2101 2115                  connp->conn_ht_iphc = NULL;
2102 2116                  connp->conn_ht_iphc_allocated = 0;
2103 2117                  connp->conn_ht_iphc_len = 0;
2104 2118                  connp->conn_ht_ulp = NULL;
2105 2119                  connp->conn_ht_ulp_len = 0;
2106 2120                  tcp->tcp_ipha = NULL;
2107 2121                  tcp->tcp_ip6h = NULL;
2108 2122                  tcp->tcp_tcpha = NULL;
2109 2123          }
2110 2124  
2111 2125          /* We clear any IP_OPTIONS and extension headers */
2112 2126          ip_pkt_free(&connp->conn_xmit_ipp);
2113 2127  
2114 2128          DONTCARE(tcp->tcp_naglim);              /* Init in tcp_init_values */
2115 2129          DONTCARE(tcp->tcp_ipha);
2116 2130          DONTCARE(tcp->tcp_ip6h);
2117 2131          DONTCARE(tcp->tcp_tcpha);
2118 2132          tcp->tcp_valid_bits = 0;
2119 2133  
2120 2134          DONTCARE(tcp->tcp_timer_backoff);       /* Init in tcp_init_values */
2121 2135          DONTCARE(tcp->tcp_last_recv_time);      /* Init in tcp_init_values */
2122 2136          tcp->tcp_last_rcv_lbolt = 0;
2123 2137  
2124 2138          tcp->tcp_init_cwnd = 0;
2125 2139  
2126 2140          tcp->tcp_urp_last_valid = 0;
2127 2141          tcp->tcp_hard_binding = 0;
2128 2142  
2129 2143          tcp->tcp_fin_acked = 0;
2130 2144          tcp->tcp_fin_rcvd = 0;
2131 2145          tcp->tcp_fin_sent = 0;
2132 2146          tcp->tcp_ordrel_done = 0;
2133 2147  
2134 2148          tcp->tcp_detached = 0;
2135 2149  
2136 2150          tcp->tcp_snd_ws_ok = B_FALSE;
2137 2151          tcp->tcp_snd_ts_ok = B_FALSE;
2138 2152          tcp->tcp_zero_win_probe = 0;
2139 2153  
2140 2154          tcp->tcp_loopback = 0;
2141 2155          tcp->tcp_localnet = 0;
2142 2156          tcp->tcp_syn_defense = 0;
2143 2157          tcp->tcp_set_timer = 0;
2144 2158  
2145 2159          tcp->tcp_active_open = 0;
2146 2160          tcp->tcp_rexmit = B_FALSE;
2147 2161          tcp->tcp_xmit_zc_clean = B_FALSE;
2148 2162  
2149 2163          tcp->tcp_snd_sack_ok = B_FALSE;
2150 2164          tcp->tcp_hwcksum = B_FALSE;
2151 2165  
2152 2166          DONTCARE(tcp->tcp_maxpsz_multiplier);   /* Init in tcp_init_values */
2153 2167  
2154 2168          tcp->tcp_conn_def_q0 = 0;
2155 2169          tcp->tcp_ip_forward_progress = B_FALSE;
2156 2170          tcp->tcp_ecn_ok = B_FALSE;
2157 2171  
2158 2172          tcp->tcp_cwr = B_FALSE;
2159 2173          tcp->tcp_ecn_echo_on = B_FALSE;
2160 2174          tcp->tcp_is_wnd_shrnk = B_FALSE;
2161 2175  
2162 2176          TCP_NOTSACK_REMOVE_ALL(tcp->tcp_notsack_list, tcp);
2163 2177          bzero(&tcp->tcp_sack_info, sizeof (tcp_sack_info_t));
2164 2178  
2165 2179          tcp->tcp_rcv_ws = 0;
2166 2180          tcp->tcp_snd_ws = 0;
2167 2181          tcp->tcp_ts_recent = 0;
2168 2182          tcp->tcp_rnxt = 0;                      /* Displayed in mib */
2169 2183          DONTCARE(tcp->tcp_rwnd);                /* Set in tcp_reinit() */
2170 2184          tcp->tcp_initial_pmtu = 0;
2171 2185  
2172 2186          ASSERT(tcp->tcp_reass_head == NULL);
2173 2187          ASSERT(tcp->tcp_reass_tail == NULL);
2174 2188  
2175 2189          tcp->tcp_cwnd_cnt = 0;
2176 2190  
2177 2191          ASSERT(tcp->tcp_rcv_list == NULL);
2178 2192          ASSERT(tcp->tcp_rcv_last_head == NULL);
2179 2193          ASSERT(tcp->tcp_rcv_last_tail == NULL);
2180 2194          ASSERT(tcp->tcp_rcv_cnt == 0);
2181 2195  
2182 2196          DONTCARE(tcp->tcp_cwnd_ssthresh); /* Init in tcp_set_destination */
2183 2197          DONTCARE(tcp->tcp_cwnd_max);            /* Init in tcp_init_values */
2184 2198          tcp->tcp_csuna = 0;
2185 2199  
2186 2200          tcp->tcp_rto = 0;                       /* Displayed in MIB */
2187 2201          DONTCARE(tcp->tcp_rtt_sa);              /* Init in tcp_init_values */
2188 2202          DONTCARE(tcp->tcp_rtt_sd);              /* Init in tcp_init_values */
2189 2203          tcp->tcp_rtt_update = 0;
2190 2204  
2191 2205          DONTCARE(tcp->tcp_swl1); /* Init in case TCPS_LISTEN/TCPS_SYN_SENT */
2192 2206          DONTCARE(tcp->tcp_swl2); /* Init in case TCPS_LISTEN/TCPS_SYN_SENT */
2193 2207  
2194 2208          tcp->tcp_rack = 0;                      /* Displayed in mib */
2195 2209          tcp->tcp_rack_cnt = 0;
2196 2210          tcp->tcp_rack_cur_max = 0;
2197 2211          tcp->tcp_rack_abs_max = 0;
2198 2212  
2199 2213          tcp->tcp_max_swnd = 0;
2200 2214  
2201 2215          ASSERT(tcp->tcp_listener == NULL);
2202 2216  
2203 2217          DONTCARE(tcp->tcp_irs);                 /* tcp_valid_bits cleared */
2204 2218          DONTCARE(tcp->tcp_iss);                 /* tcp_valid_bits cleared */
2205 2219          DONTCARE(tcp->tcp_fss);                 /* tcp_valid_bits cleared */
2206 2220          DONTCARE(tcp->tcp_urg);                 /* tcp_valid_bits cleared */
2207 2221  
2208 2222          ASSERT(tcp->tcp_conn_req_cnt_q == 0);
2209 2223          ASSERT(tcp->tcp_conn_req_cnt_q0 == 0);
2210 2224          PRESERVE(tcp->tcp_conn_req_max);
2211 2225          PRESERVE(tcp->tcp_conn_req_seqnum);
2212 2226  
2213 2227          DONTCARE(tcp->tcp_first_timer_threshold); /* Init in tcp_init_values */
2214 2228          DONTCARE(tcp->tcp_second_timer_threshold); /* Init in tcp_init_values */
2215 2229          DONTCARE(tcp->tcp_first_ctimer_threshold); /* Init in tcp_init_values */
2216 2230          DONTCARE(tcp->tcp_second_ctimer_threshold); /* in tcp_init_values */
2217 2231  
2218 2232          DONTCARE(tcp->tcp_urp_last);    /* tcp_urp_last_valid is cleared */
2219 2233          ASSERT(tcp->tcp_urp_mp == NULL);
2220 2234          ASSERT(tcp->tcp_urp_mark_mp == NULL);
2221 2235          ASSERT(tcp->tcp_fused_sigurg_mp == NULL);
2222 2236  
2223 2237          ASSERT(tcp->tcp_eager_next_q == NULL);
2224 2238          ASSERT(tcp->tcp_eager_last_q == NULL);
2225 2239          ASSERT((tcp->tcp_eager_next_q0 == NULL &&
2226 2240              tcp->tcp_eager_prev_q0 == NULL) ||
2227 2241              tcp->tcp_eager_next_q0 == tcp->tcp_eager_prev_q0);
2228 2242          ASSERT(tcp->tcp_conn.tcp_eager_conn_ind == NULL);
2229 2243  
2230 2244          ASSERT((tcp->tcp_eager_next_drop_q0 == NULL &&
2231 2245              tcp->tcp_eager_prev_drop_q0 == NULL) ||
2232 2246              tcp->tcp_eager_next_drop_q0 == tcp->tcp_eager_prev_drop_q0);
2233 2247  
2234 2248          DONTCARE(tcp->tcp_ka_rinterval);        /* Init in tcp_init_values */
2235 2249          DONTCARE(tcp->tcp_ka_abort_thres);      /* Init in tcp_init_values */
2236 2250          DONTCARE(tcp->tcp_ka_cnt);              /* Init in tcp_init_values */
2237 2251  
2238 2252          tcp->tcp_client_errno = 0;
2239 2253  
2240 2254          DONTCARE(connp->conn_sum);              /* Init in tcp_init_values */
2241 2255  
2242 2256          connp->conn_faddr_v6 = ipv6_all_zeros;  /* Displayed in MIB */
2243 2257  
2244 2258          PRESERVE(connp->conn_bound_addr_v6);
2245 2259          tcp->tcp_last_sent_len = 0;
2246 2260          tcp->tcp_dupack_cnt = 0;
2247 2261  
2248 2262          connp->conn_fport = 0;                  /* Displayed in MIB */
2249 2263          PRESERVE(connp->conn_lport);
2250 2264  
2251 2265          PRESERVE(tcp->tcp_acceptor_lockp);
2252 2266  
2253 2267          ASSERT(tcp->tcp_ordrel_mp == NULL);
2254 2268          PRESERVE(tcp->tcp_acceptor_id);
2255 2269          DONTCARE(tcp->tcp_ipsec_overhead);
2256 2270  
2257 2271          PRESERVE(connp->conn_family);
2258 2272          /* Remove any remnants of mapped address binding */
2259 2273          if (connp->conn_family == AF_INET6) {
2260 2274                  connp->conn_ipversion = IPV6_VERSION;
2261 2275                  tcp->tcp_mss = tcps->tcps_mss_def_ipv6;
2262 2276          } else {
2263 2277                  connp->conn_ipversion = IPV4_VERSION;
2264 2278                  tcp->tcp_mss = tcps->tcps_mss_def_ipv4;
2265 2279          }
2266 2280  
2267 2281          connp->conn_bound_if = 0;
2268 2282          connp->conn_recv_ancillary.crb_all = 0;
2269 2283          tcp->tcp_recvifindex = 0;
2270 2284          tcp->tcp_recvhops = 0;
2271 2285          tcp->tcp_closed = 0;
2272 2286          if (tcp->tcp_hopopts != NULL) {
2273 2287                  mi_free(tcp->tcp_hopopts);
2274 2288                  tcp->tcp_hopopts = NULL;
2275 2289                  tcp->tcp_hopoptslen = 0;
2276 2290          }
2277 2291          ASSERT(tcp->tcp_hopoptslen == 0);
2278 2292          if (tcp->tcp_dstopts != NULL) {
2279 2293                  mi_free(tcp->tcp_dstopts);
2280 2294                  tcp->tcp_dstopts = NULL;
2281 2295                  tcp->tcp_dstoptslen = 0;
2282 2296          }
2283 2297          ASSERT(tcp->tcp_dstoptslen == 0);
2284 2298          if (tcp->tcp_rthdrdstopts != NULL) {
2285 2299                  mi_free(tcp->tcp_rthdrdstopts);
2286 2300                  tcp->tcp_rthdrdstopts = NULL;
2287 2301                  tcp->tcp_rthdrdstoptslen = 0;
2288 2302          }
2289 2303          ASSERT(tcp->tcp_rthdrdstoptslen == 0);
2290 2304          if (tcp->tcp_rthdr != NULL) {
2291 2305                  mi_free(tcp->tcp_rthdr);
2292 2306                  tcp->tcp_rthdr = NULL;
2293 2307                  tcp->tcp_rthdrlen = 0;
2294 2308          }
2295 2309          ASSERT(tcp->tcp_rthdrlen == 0);
2296 2310  
2297 2311          /* Reset fusion-related fields */
2298 2312          tcp->tcp_fused = B_FALSE;
2299 2313          tcp->tcp_unfusable = B_FALSE;
2300 2314          tcp->tcp_fused_sigurg = B_FALSE;
2301 2315          tcp->tcp_loopback_peer = NULL;
2302 2316  
2303 2317          tcp->tcp_lso = B_FALSE;
2304 2318  
2305 2319          tcp->tcp_in_ack_unsent = 0;
2306 2320          tcp->tcp_cork = B_FALSE;
2307 2321          tcp->tcp_tconnind_started = B_FALSE;
2308 2322  
2309 2323          PRESERVE(tcp->tcp_squeue_bytes);
2310 2324  
2311 2325          tcp->tcp_closemp_used = B_FALSE;
2312 2326  
2313 2327          PRESERVE(tcp->tcp_rsrv_mp);
2314 2328          PRESERVE(tcp->tcp_rsrv_mp_lock);
2315 2329  
2316 2330  #ifdef DEBUG
2317 2331          DONTCARE(tcp->tcmp_stk[0]);
2318 2332  #endif
2319 2333  
2320 2334          PRESERVE(tcp->tcp_connid);
2321 2335  
2322 2336          ASSERT(tcp->tcp_listen_cnt == NULL);
2323 2337          ASSERT(tcp->tcp_reass_tid == 0);
2324 2338  
2325 2339  #undef  DONTCARE
2326 2340  #undef  PRESERVE
2327 2341  }
2328 2342  
2329 2343  /*
2330 2344   * Initialize the various fields in tcp_t.  If parent (the listener) is non
2331 2345   * NULL, certain values will be inheritted from it.
2332 2346   */
2333 2347  void
2334 2348  tcp_init_values(tcp_t *tcp, tcp_t *parent)
2335 2349  {
2336 2350          tcp_stack_t     *tcps = tcp->tcp_tcps;
2337 2351          conn_t          *connp = tcp->tcp_connp;
2338 2352          clock_t         rto;
2339 2353  
2340 2354          ASSERT((connp->conn_family == AF_INET &&
2341 2355              connp->conn_ipversion == IPV4_VERSION) ||
2342 2356              (connp->conn_family == AF_INET6 &&
2343 2357              (connp->conn_ipversion == IPV4_VERSION ||
2344 2358              connp->conn_ipversion == IPV6_VERSION)));
2345 2359  
2346 2360          if (parent == NULL) {
2347 2361                  tcp->tcp_naglim = tcps->tcps_naglim_def;
2348 2362  
2349 2363                  tcp->tcp_rto_initial = tcps->tcps_rexmit_interval_initial;
2350 2364                  tcp->tcp_rto_min = tcps->tcps_rexmit_interval_min;
2351 2365                  tcp->tcp_rto_max = tcps->tcps_rexmit_interval_max;
2352 2366  
2353 2367                  tcp->tcp_first_ctimer_threshold =
2354 2368                      tcps->tcps_ip_notify_cinterval;
2355 2369                  tcp->tcp_second_ctimer_threshold =
2356 2370                      tcps->tcps_ip_abort_cinterval;
2357 2371                  tcp->tcp_first_timer_threshold = tcps->tcps_ip_notify_interval;
2358 2372                  tcp->tcp_second_timer_threshold = tcps->tcps_ip_abort_interval;
2359 2373  
2360 2374                  tcp->tcp_fin_wait_2_flush_interval =
2361 2375                      tcps->tcps_fin_wait_2_flush_interval;
2362 2376  
2363 2377                  tcp->tcp_ka_interval = tcps->tcps_keepalive_interval;
2364 2378                  tcp->tcp_ka_abort_thres = tcps->tcps_keepalive_abort_interval;
2365 2379                  tcp->tcp_ka_cnt = 0;
2366 2380                  tcp->tcp_ka_rinterval = 0;
2367 2381  
2368 2382                  /*
2369 2383                   * Default value of tcp_init_cwnd is 0, so no need to set here
2370 2384                   * if parent is NULL.  But we need to inherit it from parent.
2371 2385                   */
2372 2386          } else {
2373 2387                  /* Inherit various TCP parameters from the parent. */
2374 2388                  tcp->tcp_naglim = parent->tcp_naglim;
2375 2389  
2376 2390                  tcp->tcp_rto_initial = parent->tcp_rto_initial;
2377 2391                  tcp->tcp_rto_min = parent->tcp_rto_min;
2378 2392                  tcp->tcp_rto_max = parent->tcp_rto_max;
2379 2393  
2380 2394                  tcp->tcp_first_ctimer_threshold =
2381 2395                      parent->tcp_first_ctimer_threshold;
2382 2396                  tcp->tcp_second_ctimer_threshold =
2383 2397                      parent->tcp_second_ctimer_threshold;
2384 2398                  tcp->tcp_first_timer_threshold =
2385 2399                      parent->tcp_first_timer_threshold;
2386 2400                  tcp->tcp_second_timer_threshold =
2387 2401                      parent->tcp_second_timer_threshold;
2388 2402  
2389 2403                  tcp->tcp_fin_wait_2_flush_interval =
2390 2404                      parent->tcp_fin_wait_2_flush_interval;
2391 2405  
2392 2406                  tcp->tcp_ka_interval = parent->tcp_ka_interval;
2393 2407                  tcp->tcp_ka_abort_thres = parent->tcp_ka_abort_thres;
2394 2408                  tcp->tcp_ka_cnt = parent->tcp_ka_cnt;
2395 2409                  tcp->tcp_ka_rinterval = parent->tcp_ka_rinterval;
2396 2410  
2397 2411                  tcp->tcp_init_cwnd = parent->tcp_init_cwnd;
2398 2412          }
2399 2413  
2400 2414          /*
2401 2415           * Initialize tcp_rtt_sa and tcp_rtt_sd so that the calculated RTO
2402 2416           * will be close to tcp_rexmit_interval_initial.  By doing this, we
2403 2417           * allow the algorithm to adjust slowly to large fluctuations of RTT
2404 2418           * during first few transmissions of a connection as seen in slow
2405 2419           * links.
2406 2420           */
2407 2421          tcp->tcp_rtt_sa = tcp->tcp_rto_initial << 2;
2408 2422          tcp->tcp_rtt_sd = tcp->tcp_rto_initial >> 1;
2409 2423          rto = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
2410 2424              tcps->tcps_rexmit_interval_extra + (tcp->tcp_rtt_sa >> 5) +
2411 2425              tcps->tcps_conn_grace_period;
2412 2426          TCP_SET_RTO(tcp, rto);
2413 2427  
2414 2428          tcp->tcp_timer_backoff = 0;
2415 2429          tcp->tcp_ms_we_have_waited = 0;
2416 2430          tcp->tcp_last_recv_time = ddi_get_lbolt();
2417 2431          tcp->tcp_cwnd_max = tcps->tcps_cwnd_max_;
2418 2432          tcp->tcp_cwnd_ssthresh = TCP_MAX_LARGEWIN;
2419 2433  
2420 2434          tcp->tcp_maxpsz_multiplier = tcps->tcps_maxpsz_multiplier;
2421 2435  
2422 2436          /* NOTE:  ISS is now set in tcp_set_destination(). */
2423 2437  
2424 2438          /* Reset fusion-related fields */
2425 2439          tcp->tcp_fused = B_FALSE;
2426 2440          tcp->tcp_unfusable = B_FALSE;
2427 2441          tcp->tcp_fused_sigurg = B_FALSE;
2428 2442          tcp->tcp_loopback_peer = NULL;
2429 2443  
2430 2444          /* We rebuild the header template on the next connect/conn_request */
2431 2445  
2432 2446          connp->conn_mlp_type = mlptSingle;
2433 2447  
2434 2448          /*
2435 2449           * Init the window scale to the max so tcp_rwnd_set() won't pare
2436 2450           * down tcp_rwnd. tcp_set_destination() will set the right value later.
2437 2451           */
2438 2452          tcp->tcp_rcv_ws = TCP_MAX_WINSHIFT;
2439 2453          tcp->tcp_rwnd = connp->conn_rcvbuf;
2440 2454  
2441 2455          tcp->tcp_cork = B_FALSE;
2442 2456          /*
2443 2457           * Init the tcp_debug option if it wasn't already set.  This value
2444 2458           * determines whether TCP
2445 2459           * calls strlog() to print out debug messages.  Doing this
2446 2460           * initialization here means that this value is not inherited thru
2447 2461           * tcp_reinit().
2448 2462           */
2449 2463          if (!connp->conn_debug)
2450 2464                  connp->conn_debug = tcps->tcps_dbg;
2451 2465  }
2452 2466  
2453 2467  /*
2454 2468   * Update the TCP connection according to change of PMTU.
2455 2469   *
2456 2470   * Path MTU might have changed by either increase or decrease, so need to
2457 2471   * adjust the MSS based on the value of ixa_pmtu. No need to handle tiny
2458 2472   * or negative MSS, since tcp_mss_set() will do it.
2459 2473   */
2460 2474  void
2461 2475  tcp_update_pmtu(tcp_t *tcp, boolean_t decrease_only)
2462 2476  {
2463 2477          uint32_t        pmtu;
2464 2478          int32_t         mss;
2465 2479          conn_t          *connp = tcp->tcp_connp;
2466 2480          ip_xmit_attr_t  *ixa = connp->conn_ixa;
2467 2481          iaflags_t       ixaflags;
2468 2482  
2469 2483          if (tcp->tcp_tcps->tcps_ignore_path_mtu)
2470 2484                  return;
2471 2485  
2472 2486          if (tcp->tcp_state < TCPS_ESTABLISHED)
2473 2487                  return;
2474 2488  
2475 2489          /*
2476 2490           * Always call ip_get_pmtu() to make sure that IP has updated
2477 2491           * ixa_flags properly.
2478 2492           */
2479 2493          pmtu = ip_get_pmtu(ixa);
2480 2494          ixaflags = ixa->ixa_flags;
2481 2495  
2482 2496          /*
2483 2497           * Calculate the MSS by decreasing the PMTU by conn_ht_iphc_len and
2484 2498           * IPsec overhead if applied. Make sure to use the most recent
2485 2499           * IPsec information.
2486 2500           */
2487 2501          mss = pmtu - connp->conn_ht_iphc_len - conn_ipsec_length(connp);
2488 2502  
2489 2503          /*
2490 2504           * Nothing to change, so just return.
2491 2505           */
2492 2506          if (mss == tcp->tcp_mss)
2493 2507                  return;
2494 2508  
2495 2509          /*
2496 2510           * Currently, for ICMP errors, only PMTU decrease is handled.
2497 2511           */
2498 2512          if (mss > tcp->tcp_mss && decrease_only)
2499 2513                  return;
2500 2514  
2501 2515          DTRACE_PROBE2(tcp_update_pmtu, int32_t, tcp->tcp_mss, uint32_t, mss);
2502 2516  
2503 2517          /*
2504 2518           * Update ixa_fragsize and ixa_pmtu.
2505 2519           */
2506 2520          ixa->ixa_fragsize = ixa->ixa_pmtu = pmtu;
2507 2521  
2508 2522          /*
2509 2523           * Adjust MSS and all relevant variables.
2510 2524           */
2511 2525          tcp_mss_set(tcp, mss);
2512 2526  
2513 2527          /*
2514 2528           * If the PMTU is below the min size maintained by IP, then ip_get_pmtu
2515 2529           * has set IXAF_PMTU_TOO_SMALL and cleared IXAF_PMTU_IPV4_DF. Since TCP
2516 2530           * has a (potentially different) min size we do the same. Make sure to
2517 2531           * clear IXAF_DONTFRAG, which is used by IP to decide whether to
2518 2532           * fragment the packet.
2519 2533           *
2520 2534           * LSO over IPv6 can not be fragmented. So need to disable LSO
2521 2535           * when IPv6 fragmentation is needed.
2522 2536           */
2523 2537          if (mss < tcp->tcp_tcps->tcps_mss_min)
2524 2538                  ixaflags |= IXAF_PMTU_TOO_SMALL;
2525 2539  
2526 2540          if (ixaflags & IXAF_PMTU_TOO_SMALL)
2527 2541                  ixaflags &= ~(IXAF_DONTFRAG | IXAF_PMTU_IPV4_DF);
2528 2542  
2529 2543          if ((connp->conn_ipversion == IPV4_VERSION) &&
2530 2544              !(ixaflags & IXAF_PMTU_IPV4_DF)) {
2531 2545                  tcp->tcp_ipha->ipha_fragment_offset_and_flags = 0;
2532 2546          }
2533 2547          ixa->ixa_flags = ixaflags;
2534 2548  }
2535 2549  
2536 2550  int
2537 2551  tcp_maxpsz_set(tcp_t *tcp, boolean_t set_maxblk)
2538 2552  {
2539 2553          conn_t  *connp = tcp->tcp_connp;
2540 2554          queue_t *q = connp->conn_rq;
2541 2555          int32_t mss = tcp->tcp_mss;
2542 2556          int     maxpsz;
2543 2557  
2544 2558          if (TCP_IS_DETACHED(tcp))
2545 2559                  return (mss);
2546 2560          if (tcp->tcp_fused) {
2547 2561                  maxpsz = tcp_fuse_maxpsz(tcp);
2548 2562                  mss = INFPSZ;
2549 2563          } else if (tcp->tcp_maxpsz_multiplier == 0) {
2550 2564                  /*
2551 2565                   * Set the sd_qn_maxpsz according to the socket send buffer
2552 2566                   * size, and sd_maxblk to INFPSZ (-1).  This will essentially
2553 2567                   * instruct the stream head to copyin user data into contiguous
2554 2568                   * kernel-allocated buffers without breaking it up into smaller
2555 2569                   * chunks.  We round up the buffer size to the nearest SMSS.
2556 2570                   */
2557 2571                  maxpsz = MSS_ROUNDUP(connp->conn_sndbuf, mss);
2558 2572                  mss = INFPSZ;
2559 2573          } else {
2560 2574                  /*
2561 2575                   * Set sd_qn_maxpsz to approx half the (receivers) buffer
2562 2576                   * (and a multiple of the mss).  This instructs the stream
2563 2577                   * head to break down larger than SMSS writes into SMSS-
2564 2578                   * size mblks, up to tcp_maxpsz_multiplier mblks at a time.
2565 2579                   */
2566 2580                  maxpsz = tcp->tcp_maxpsz_multiplier * mss;
2567 2581                  if (maxpsz > connp->conn_sndbuf / 2) {
2568 2582                          maxpsz = connp->conn_sndbuf / 2;
2569 2583                          /* Round up to nearest mss */
2570 2584                          maxpsz = MSS_ROUNDUP(maxpsz, mss);
2571 2585                  }
2572 2586          }
2573 2587  
2574 2588          (void) proto_set_maxpsz(q, connp, maxpsz);
2575 2589          if (!(IPCL_IS_NONSTR(connp)))
2576 2590                  connp->conn_wq->q_maxpsz = maxpsz;
2577 2591          if (set_maxblk)
2578 2592                  (void) proto_set_tx_maxblk(q, connp, mss);
2579 2593          return (mss);
2580 2594  }
2581 2595  
2582 2596  /* For /dev/tcp aka AF_INET open */
2583 2597  static int
2584 2598  tcp_openv4(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
2585 2599  {
2586 2600          return (tcp_open(q, devp, flag, sflag, credp, B_FALSE));
2587 2601  }
2588 2602  
2589 2603  /* For /dev/tcp6 aka AF_INET6 open */
2590 2604  static int
2591 2605  tcp_openv6(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
2592 2606  {
2593 2607          return (tcp_open(q, devp, flag, sflag, credp, B_TRUE));
2594 2608  }
2595 2609  
2596 2610  conn_t *
2597 2611  tcp_create_common(cred_t *credp, boolean_t isv6, boolean_t issocket,
2598 2612      int *errorp)
2599 2613  {
2600 2614          tcp_t           *tcp = NULL;
2601 2615          conn_t          *connp;
2602 2616          zoneid_t        zoneid;
2603 2617          tcp_stack_t     *tcps;
2604 2618          squeue_t        *sqp;
2605 2619  
2606 2620          ASSERT(errorp != NULL);
2607 2621          /*
2608 2622           * Find the proper zoneid and netstack.
2609 2623           */
2610 2624          /*
2611 2625           * Special case for install: miniroot needs to be able to
2612 2626           * access files via NFS as though it were always in the
2613 2627           * global zone.
2614 2628           */
2615 2629          if (credp == kcred && nfs_global_client_only != 0) {
2616 2630                  zoneid = GLOBAL_ZONEID;
2617 2631                  tcps = netstack_find_by_stackid(GLOBAL_NETSTACKID)->
2618 2632                      netstack_tcp;
2619 2633                  ASSERT(tcps != NULL);
2620 2634          } else {
2621 2635                  netstack_t *ns;
2622 2636                  int err;
2623 2637  
2624 2638                  if ((err = secpolicy_basic_net_access(credp)) != 0) {
2625 2639                          *errorp = err;
2626 2640                          return (NULL);
2627 2641                  }
2628 2642  
2629 2643                  ns = netstack_find_by_cred(credp);
2630 2644                  ASSERT(ns != NULL);
2631 2645                  tcps = ns->netstack_tcp;
2632 2646                  ASSERT(tcps != NULL);
2633 2647  
2634 2648                  /*
2635 2649                   * For exclusive stacks we set the zoneid to zero
2636 2650                   * to make TCP operate as if in the global zone.
2637 2651                   */
2638 2652                  if (tcps->tcps_netstack->netstack_stackid !=
2639 2653                      GLOBAL_NETSTACKID)
2640 2654                          zoneid = GLOBAL_ZONEID;
2641 2655                  else
2642 2656                          zoneid = crgetzoneid(credp);
2643 2657          }
2644 2658  
2645 2659          sqp = IP_SQUEUE_GET((uint_t)gethrtime());
2646 2660          connp = (conn_t *)tcp_get_conn(sqp, tcps);
2647 2661          /*
2648 2662           * Both tcp_get_conn and netstack_find_by_cred incremented refcnt,
2649 2663           * so we drop it by one.
2650 2664           */
2651 2665          netstack_rele(tcps->tcps_netstack);
2652 2666          if (connp == NULL) {
2653 2667                  *errorp = ENOSR;
2654 2668                  return (NULL);
2655 2669          }
2656 2670          ASSERT(connp->conn_ixa->ixa_protocol == connp->conn_proto);
2657 2671  
2658 2672          connp->conn_sqp = sqp;
2659 2673          connp->conn_initial_sqp = connp->conn_sqp;
2660 2674          connp->conn_ixa->ixa_sqp = connp->conn_sqp;
2661 2675          tcp = connp->conn_tcp;
2662 2676  
2663 2677          /*
2664 2678           * Besides asking IP to set the checksum for us, have conn_ip_output
2665 2679           * to do the following checks when necessary:
2666 2680           *
2667 2681           * IXAF_VERIFY_SOURCE: drop packets when our outer source goes invalid
2668 2682           * IXAF_VERIFY_PMTU: verify PMTU changes
2669 2683           * IXAF_VERIFY_LSO: verify LSO capability changes
2670 2684           */
2671 2685          connp->conn_ixa->ixa_flags |= IXAF_SET_ULP_CKSUM | IXAF_VERIFY_SOURCE |
2672 2686              IXAF_VERIFY_PMTU | IXAF_VERIFY_LSO;
2673 2687  
2674 2688          if (!tcps->tcps_dev_flow_ctl)
2675 2689                  connp->conn_ixa->ixa_flags |= IXAF_NO_DEV_FLOW_CTL;
2676 2690  
2677 2691          if (isv6) {
2678 2692                  connp->conn_ixa->ixa_src_preferences = IPV6_PREFER_SRC_DEFAULT;
2679 2693                  connp->conn_ipversion = IPV6_VERSION;
2680 2694                  connp->conn_family = AF_INET6;
2681 2695                  tcp->tcp_mss = tcps->tcps_mss_def_ipv6;
2682 2696                  connp->conn_default_ttl = tcps->tcps_ipv6_hoplimit;
2683 2697          } else {
2684 2698                  connp->conn_ipversion = IPV4_VERSION;
2685 2699                  connp->conn_family = AF_INET;
2686 2700                  tcp->tcp_mss = tcps->tcps_mss_def_ipv4;
2687 2701                  connp->conn_default_ttl = tcps->tcps_ipv4_ttl;
2688 2702          }
2689 2703          connp->conn_xmit_ipp.ipp_unicast_hops = connp->conn_default_ttl;
2690 2704  
2691 2705          crhold(credp);
2692 2706          connp->conn_cred = credp;
2693 2707          connp->conn_cpid = curproc->p_pid;
2694 2708          connp->conn_open_time = ddi_get_lbolt64();
2695 2709  
2696 2710          /* Cache things in the ixa without any refhold */
2697 2711          ASSERT(!(connp->conn_ixa->ixa_free_flags & IXA_FREE_CRED));
2698 2712          connp->conn_ixa->ixa_cred = credp;
2699 2713          connp->conn_ixa->ixa_cpid = connp->conn_cpid;
2700 2714  
2701 2715          connp->conn_zoneid = zoneid;
2702 2716          /* conn_allzones can not be set this early, hence no IPCL_ZONEID */
2703 2717          connp->conn_ixa->ixa_zoneid = zoneid;
2704 2718          connp->conn_mlp_type = mlptSingle;
2705 2719          ASSERT(connp->conn_netstack == tcps->tcps_netstack);
2706 2720          ASSERT(tcp->tcp_tcps == tcps);
2707 2721  
2708 2722          /*
2709 2723           * If the caller has the process-wide flag set, then default to MAC
2710 2724           * exempt mode.  This allows read-down to unlabeled hosts.
2711 2725           */
2712 2726          if (getpflags(NET_MAC_AWARE, credp) != 0)
2713 2727                  connp->conn_mac_mode = CONN_MAC_AWARE;
2714 2728  
2715 2729          connp->conn_zone_is_global = (crgetzoneid(credp) == GLOBAL_ZONEID);
2716 2730  
2717 2731          if (issocket) {
2718 2732                  tcp->tcp_issocket = 1;
2719 2733          }
2720 2734  
2721 2735          connp->conn_rcvbuf = tcps->tcps_recv_hiwat;
2722 2736          connp->conn_sndbuf = tcps->tcps_xmit_hiwat;
2723 2737          if (tcps->tcps_snd_lowat_fraction != 0) {
2724 2738                  connp->conn_sndlowat = connp->conn_sndbuf /
2725 2739                      tcps->tcps_snd_lowat_fraction;
2726 2740          } else {
2727 2741                  connp->conn_sndlowat = tcps->tcps_xmit_lowat;
2728 2742          }
2729 2743          connp->conn_so_type = SOCK_STREAM;
2730 2744          connp->conn_wroff = connp->conn_ht_iphc_allocated +
2731 2745              tcps->tcps_wroff_xtra;
2732 2746  
2733 2747          SOCK_CONNID_INIT(tcp->tcp_connid);
2734 2748          /* DTrace ignores this - it isn't a tcp:::state-change */
2735 2749          tcp->tcp_state = TCPS_IDLE;
2736 2750          tcp_init_values(tcp, NULL);
2737 2751          return (connp);
2738 2752  }
2739 2753  
2740 2754  static int
2741 2755  tcp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp,
2742 2756      boolean_t isv6)
2743 2757  {
2744 2758          tcp_t           *tcp = NULL;
2745 2759          conn_t          *connp = NULL;
2746 2760          int             err;
2747 2761          vmem_t          *minor_arena = NULL;
2748 2762          dev_t           conn_dev;
2749 2763          boolean_t       issocket;
2750 2764  
2751 2765          if (q->q_ptr != NULL)
2752 2766                  return (0);
2753 2767  
2754 2768          if (sflag == MODOPEN)
2755 2769                  return (EINVAL);
2756 2770  
2757 2771          if ((ip_minor_arena_la != NULL) && (flag & SO_SOCKSTR) &&
2758 2772              ((conn_dev = inet_minor_alloc(ip_minor_arena_la)) != 0)) {
2759 2773                  minor_arena = ip_minor_arena_la;
2760 2774          } else {
2761 2775                  /*
2762 2776                   * Either minor numbers in the large arena were exhausted
2763 2777                   * or a non socket application is doing the open.
2764 2778                   * Try to allocate from the small arena.
2765 2779                   */
2766 2780                  if ((conn_dev = inet_minor_alloc(ip_minor_arena_sa)) == 0) {
2767 2781                          return (EBUSY);
2768 2782                  }
2769 2783                  minor_arena = ip_minor_arena_sa;
2770 2784          }
2771 2785  
2772 2786          ASSERT(minor_arena != NULL);
2773 2787  
2774 2788          *devp = makedevice(getmajor(*devp), (minor_t)conn_dev);
2775 2789  
2776 2790          if (flag & SO_FALLBACK) {
2777 2791                  /*
2778 2792                   * Non streams socket needs a stream to fallback to
2779 2793                   */
2780 2794                  RD(q)->q_ptr = (void *)conn_dev;
2781 2795                  WR(q)->q_qinfo = &tcp_fallback_sock_winit;
2782 2796                  WR(q)->q_ptr = (void *)minor_arena;
2783 2797                  qprocson(q);
2784 2798                  return (0);
2785 2799          } else if (flag & SO_ACCEPTOR) {
2786 2800                  q->q_qinfo = &tcp_acceptor_rinit;
2787 2801                  /*
2788 2802                   * the conn_dev and minor_arena will be subsequently used by
2789 2803                   * tcp_tli_accept() and tcp_tpi_close_accept() to figure out
2790 2804                   * the minor device number for this connection from the q_ptr.
2791 2805                   */
2792 2806                  RD(q)->q_ptr = (void *)conn_dev;
2793 2807                  WR(q)->q_qinfo = &tcp_acceptor_winit;
2794 2808                  WR(q)->q_ptr = (void *)minor_arena;
2795 2809                  qprocson(q);
2796 2810                  return (0);
2797 2811          }
2798 2812  
2799 2813          issocket = flag & SO_SOCKSTR;
2800 2814          connp = tcp_create_common(credp, isv6, issocket, &err);
2801 2815  
2802 2816          if (connp == NULL) {
2803 2817                  inet_minor_free(minor_arena, conn_dev);
2804 2818                  q->q_ptr = WR(q)->q_ptr = NULL;
2805 2819                  return (err);
2806 2820          }
2807 2821  
2808 2822          connp->conn_rq = q;
2809 2823          connp->conn_wq = WR(q);
2810 2824          q->q_ptr = WR(q)->q_ptr = connp;
2811 2825  
2812 2826          connp->conn_dev = conn_dev;
2813 2827          connp->conn_minor_arena = minor_arena;
2814 2828  
2815 2829          ASSERT(q->q_qinfo == &tcp_rinitv4 || q->q_qinfo == &tcp_rinitv6);
2816 2830          ASSERT(WR(q)->q_qinfo == &tcp_winit);
2817 2831  
2818 2832          tcp = connp->conn_tcp;
2819 2833  
2820 2834          if (issocket) {
2821 2835                  WR(q)->q_qinfo = &tcp_sock_winit;
2822 2836          } else {
2823 2837  #ifdef  _ILP32
2824 2838                  tcp->tcp_acceptor_id = (t_uscalar_t)RD(q);
2825 2839  #else
2826 2840                  tcp->tcp_acceptor_id = conn_dev;
2827 2841  #endif  /* _ILP32 */
2828 2842                  tcp_acceptor_hash_insert(tcp->tcp_acceptor_id, tcp);
2829 2843          }
2830 2844  
2831 2845          /*
2832 2846           * Put the ref for TCP. Ref for IP was already put
2833 2847           * by ipcl_conn_create. Also Make the conn_t globally
2834 2848           * visible to walkers
2835 2849           */
2836 2850          mutex_enter(&connp->conn_lock);
2837 2851          CONN_INC_REF_LOCKED(connp);
2838 2852          ASSERT(connp->conn_ref == 2);
2839 2853          connp->conn_state_flags &= ~CONN_INCIPIENT;
2840 2854          mutex_exit(&connp->conn_lock);
2841 2855  
2842 2856          qprocson(q);
2843 2857          return (0);
2844 2858  }
2845 2859  
2846 2860  /*
2847 2861   * Build/update the tcp header template (in conn_ht_iphc) based on
2848 2862   * conn_xmit_ipp. The headers include ip6_t, any extension
2849 2863   * headers, and the maximum size tcp header (to avoid reallocation
2850 2864   * on the fly for additional tcp options).
2851 2865   *
2852 2866   * Assumes the caller has already set conn_{faddr,laddr,fport,lport,flowinfo}.
2853 2867   * Returns failure if can't allocate memory.
2854 2868   */
2855 2869  int
2856 2870  tcp_build_hdrs(tcp_t *tcp)
2857 2871  {
2858 2872          tcp_stack_t     *tcps = tcp->tcp_tcps;
2859 2873          conn_t          *connp = tcp->tcp_connp;
2860 2874          char            buf[TCP_MAX_HDR_LENGTH];
2861 2875          uint_t          buflen;
2862 2876          uint_t          ulplen = TCP_MIN_HEADER_LENGTH;
2863 2877          uint_t          extralen = TCP_MAX_TCP_OPTIONS_LENGTH;
2864 2878          tcpha_t         *tcpha;
2865 2879          uint32_t        cksum;
2866 2880          int             error;
2867 2881  
2868 2882          /*
2869 2883           * We might be called after the connection is set up, and we might
2870 2884           * have TS options already in the TCP header. Thus we  save any
2871 2885           * existing tcp header.
2872 2886           */
2873 2887          buflen = connp->conn_ht_ulp_len;
2874 2888          if (buflen != 0) {
2875 2889                  bcopy(connp->conn_ht_ulp, buf, buflen);
2876 2890                  extralen -= buflen - ulplen;
2877 2891                  ulplen = buflen;
2878 2892          }
2879 2893  
2880 2894          /* Grab lock to satisfy ASSERT; TCP is serialized using squeue */
2881 2895          mutex_enter(&connp->conn_lock);
2882 2896          error = conn_build_hdr_template(connp, ulplen, extralen,
2883 2897              &connp->conn_laddr_v6, &connp->conn_faddr_v6, connp->conn_flowinfo);
2884 2898          mutex_exit(&connp->conn_lock);
2885 2899          if (error != 0)
2886 2900                  return (error);
2887 2901  
2888 2902          /*
2889 2903           * Any routing header/option has been massaged. The checksum difference
2890 2904           * is stored in conn_sum for later use.
2891 2905           */
2892 2906          tcpha = (tcpha_t *)connp->conn_ht_ulp;
2893 2907          tcp->tcp_tcpha = tcpha;
2894 2908  
2895 2909          /* restore any old tcp header */
2896 2910          if (buflen != 0) {
2897 2911                  bcopy(buf, connp->conn_ht_ulp, buflen);
2898 2912          } else {
2899 2913                  tcpha->tha_sum = 0;
2900 2914                  tcpha->tha_urp = 0;
2901 2915                  tcpha->tha_ack = 0;
2902 2916                  tcpha->tha_offset_and_reserved = (5 << 4);
2903 2917                  tcpha->tha_lport = connp->conn_lport;
2904 2918                  tcpha->tha_fport = connp->conn_fport;
2905 2919          }
2906 2920  
2907 2921          /*
2908 2922           * IP wants our header length in the checksum field to
2909 2923           * allow it to perform a single pseudo-header+checksum
2910 2924           * calculation on behalf of TCP.
2911 2925           * Include the adjustment for a source route once IP_OPTIONS is set.
2912 2926           */
2913 2927          cksum = sizeof (tcpha_t) + connp->conn_sum;
2914 2928          cksum = (cksum >> 16) + (cksum & 0xFFFF);
2915 2929          ASSERT(cksum < 0x10000);
2916 2930          tcpha->tha_sum = htons(cksum);
2917 2931  
2918 2932          if (connp->conn_ipversion == IPV4_VERSION)
2919 2933                  tcp->tcp_ipha = (ipha_t *)connp->conn_ht_iphc;
2920 2934          else
2921 2935                  tcp->tcp_ip6h = (ip6_t *)connp->conn_ht_iphc;
2922 2936  
2923 2937          if (connp->conn_ht_iphc_allocated + tcps->tcps_wroff_xtra >
2924 2938              connp->conn_wroff) {
2925 2939                  connp->conn_wroff = connp->conn_ht_iphc_allocated +
2926 2940                      tcps->tcps_wroff_xtra;
2927 2941                  (void) proto_set_tx_wroff(connp->conn_rq, connp,
2928 2942                      connp->conn_wroff);
2929 2943          }
2930 2944          return (0);
2931 2945  }
2932 2946  
2933 2947  /*
2934 2948   * tcp_rwnd_set() is called to adjust the receive window to a desired value.
2935 2949   * We do not allow the receive window to shrink.  After setting rwnd,
2936 2950   * set the flow control hiwat of the stream.
2937 2951   *
2938 2952   * This function is called in 2 cases:
2939 2953   *
2940 2954   * 1) Before data transfer begins, in tcp_input_listener() for accepting a
2941 2955   *    connection (passive open) and in tcp_input_data() for active connect.
2942 2956   *    This is called after tcp_mss_set() when the desired MSS value is known.
2943 2957   *    This makes sure that our window size is a mutiple of the other side's
2944 2958   *    MSS.
2945 2959   * 2) Handling SO_RCVBUF option.
2946 2960   *
2947 2961   * It is ASSUMED that the requested size is a multiple of the current MSS.
2948 2962   *
2949 2963   * XXX - Should allow a lower rwnd than tcp_recv_hiwat_minmss * mss if the
2950 2964   * user requests so.
2951 2965   */
2952 2966  int
2953 2967  tcp_rwnd_set(tcp_t *tcp, uint32_t rwnd)
2954 2968  {
2955 2969          uint32_t        mss = tcp->tcp_mss;
2956 2970          uint32_t        old_max_rwnd;
2957 2971          uint32_t        max_transmittable_rwnd;
2958 2972          boolean_t       tcp_detached = TCP_IS_DETACHED(tcp);
2959 2973          tcp_stack_t     *tcps = tcp->tcp_tcps;
2960 2974          conn_t          *connp = tcp->tcp_connp;
2961 2975  
2962 2976          /*
2963 2977           * Insist on a receive window that is at least
2964 2978           * tcp_recv_hiwat_minmss * MSS (default 4 * MSS) to avoid
2965 2979           * funny TCP interactions of Nagle algorithm, SWS avoidance
2966 2980           * and delayed acknowledgement.
2967 2981           */
2968 2982          rwnd = MAX(rwnd, tcps->tcps_recv_hiwat_minmss * mss);
2969 2983  
2970 2984          if (tcp->tcp_fused) {
2971 2985                  size_t sth_hiwat;
2972 2986                  tcp_t *peer_tcp = tcp->tcp_loopback_peer;
2973 2987  
2974 2988                  ASSERT(peer_tcp != NULL);
2975 2989                  sth_hiwat = tcp_fuse_set_rcv_hiwat(tcp, rwnd);
2976 2990                  if (!tcp_detached) {
2977 2991                          (void) proto_set_rx_hiwat(connp->conn_rq, connp,
2978 2992                              sth_hiwat);
2979 2993                          tcp_set_recv_threshold(tcp, sth_hiwat >> 3);
2980 2994                  }
2981 2995  
2982 2996                  /* Caller could have changed tcp_rwnd; update tha_win */
2983 2997                  if (tcp->tcp_tcpha != NULL) {
2984 2998                          tcp->tcp_tcpha->tha_win =
2985 2999                              htons(tcp->tcp_rwnd >> tcp->tcp_rcv_ws);
2986 3000                  }
2987 3001                  if ((tcp->tcp_rcv_ws > 0) && rwnd > tcp->tcp_cwnd_max)
2988 3002                          tcp->tcp_cwnd_max = rwnd;
2989 3003  
2990 3004                  /*
2991 3005                   * In the fusion case, the maxpsz stream head value of
2992 3006                   * our peer is set according to its send buffer size
2993 3007                   * and our receive buffer size; since the latter may
2994 3008                   * have changed we need to update the peer's maxpsz.
2995 3009                   */
2996 3010                  (void) tcp_maxpsz_set(peer_tcp, B_TRUE);
2997 3011                  return (sth_hiwat);
2998 3012          }
2999 3013  
3000 3014          if (tcp_detached)
3001 3015                  old_max_rwnd = tcp->tcp_rwnd;
3002 3016          else
3003 3017                  old_max_rwnd = connp->conn_rcvbuf;
3004 3018  
3005 3019  
3006 3020          /*
3007 3021           * If window size info has already been exchanged, TCP should not
3008 3022           * shrink the window.  Shrinking window is doable if done carefully.
3009 3023           * We may add that support later.  But so far there is not a real
3010 3024           * need to do that.
3011 3025           */
3012 3026          if (rwnd < old_max_rwnd && tcp->tcp_state > TCPS_SYN_SENT) {
3013 3027                  /* MSS may have changed, do a round up again. */
3014 3028                  rwnd = MSS_ROUNDUP(old_max_rwnd, mss);
3015 3029          }
3016 3030  
3017 3031          /*
3018 3032           * tcp_rcv_ws starts with TCP_MAX_WINSHIFT so the following check
3019 3033           * can be applied even before the window scale option is decided.
3020 3034           */
3021 3035          max_transmittable_rwnd = TCP_MAXWIN << tcp->tcp_rcv_ws;
3022 3036          if (rwnd > max_transmittable_rwnd) {
3023 3037                  rwnd = max_transmittable_rwnd -
3024 3038                      (max_transmittable_rwnd % mss);
3025 3039                  if (rwnd < mss)
3026 3040                          rwnd = max_transmittable_rwnd;
3027 3041                  /*
3028 3042                   * If we're over the limit we may have to back down tcp_rwnd.
3029 3043                   * The increment below won't work for us. So we set all three
3030 3044                   * here and the increment below will have no effect.
3031 3045                   */
3032 3046                  tcp->tcp_rwnd = old_max_rwnd = rwnd;
3033 3047          }
3034 3048          if (tcp->tcp_localnet) {
3035 3049                  tcp->tcp_rack_abs_max =
3036 3050                      MIN(tcps->tcps_local_dacks_max, rwnd / mss / 2);
3037 3051          } else {
3038 3052                  /*
3039 3053                   * For a remote host on a different subnet (through a router),
3040 3054                   * we ack every other packet to be conforming to RFC1122.
3041 3055                   * tcp_deferred_acks_max is default to 2.
3042 3056                   */
3043 3057                  tcp->tcp_rack_abs_max =
3044 3058                      MIN(tcps->tcps_deferred_acks_max, rwnd / mss / 2);
3045 3059          }
3046 3060          if (tcp->tcp_rack_cur_max > tcp->tcp_rack_abs_max)
3047 3061                  tcp->tcp_rack_cur_max = tcp->tcp_rack_abs_max;
3048 3062          else
3049 3063                  tcp->tcp_rack_cur_max = 0;
3050 3064          /*
3051 3065           * Increment the current rwnd by the amount the maximum grew (we
3052 3066           * can not overwrite it since we might be in the middle of a
3053 3067           * connection.)
3054 3068           */
3055 3069          tcp->tcp_rwnd += rwnd - old_max_rwnd;
3056 3070          connp->conn_rcvbuf = rwnd;
3057 3071  
3058 3072          /* Are we already connected? */
3059 3073          if (tcp->tcp_tcpha != NULL) {
3060 3074                  tcp->tcp_tcpha->tha_win =
3061 3075                      htons(tcp->tcp_rwnd >> tcp->tcp_rcv_ws);
3062 3076          }
3063 3077  
3064 3078          if ((tcp->tcp_rcv_ws > 0) && rwnd > tcp->tcp_cwnd_max)
3065 3079                  tcp->tcp_cwnd_max = rwnd;
3066 3080  
3067 3081          if (tcp_detached)
3068 3082                  return (rwnd);
3069 3083  
3070 3084          tcp_set_recv_threshold(tcp, rwnd >> 3);
3071 3085  
3072 3086          (void) proto_set_rx_hiwat(connp->conn_rq, connp, rwnd);
3073 3087          return (rwnd);
3074 3088  }
3075 3089  
3076 3090  int
3077 3091  tcp_do_unbind(conn_t *connp)
3078 3092  {
3079 3093          tcp_t *tcp = connp->conn_tcp;
3080 3094          int32_t oldstate;
3081 3095  
3082 3096          switch (tcp->tcp_state) {
3083 3097          case TCPS_BOUND:
3084 3098          case TCPS_LISTEN:
3085 3099                  break;
3086 3100          default:
3087 3101                  return (-TOUTSTATE);
3088 3102          }
3089 3103  
3090 3104          /*
3091 3105           * Need to clean up all the eagers since after the unbind, segments
3092 3106           * will no longer be delivered to this listener stream.
3093 3107           */
3094 3108          mutex_enter(&tcp->tcp_eager_lock);
3095 3109          if (tcp->tcp_conn_req_cnt_q0 != 0 || tcp->tcp_conn_req_cnt_q != 0) {
3096 3110                  tcp_eager_cleanup(tcp, 0);
3097 3111          }
3098 3112          mutex_exit(&tcp->tcp_eager_lock);
3099 3113  
3100 3114          /* Clean up the listener connection counter if necessary. */
3101 3115          if (tcp->tcp_listen_cnt != NULL)
3102 3116                  TCP_DECR_LISTEN_CNT(tcp);
3103 3117          connp->conn_laddr_v6 = ipv6_all_zeros;
3104 3118          connp->conn_saddr_v6 = ipv6_all_zeros;
3105 3119          tcp_bind_hash_remove(tcp);
3106 3120          oldstate = tcp->tcp_state;
3107 3121          tcp->tcp_state = TCPS_IDLE;
3108 3122          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
3109 3123              connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
3110 3124              int32_t, oldstate);
3111 3125  
3112 3126          ip_unbind(connp);
3113 3127          bzero(&connp->conn_ports, sizeof (connp->conn_ports));
3114 3128  
3115 3129          return (0);
3116 3130  }
3117 3131  
3118 3132  /*
3119 3133   * Collect protocol properties to send to the upper handle.
3120 3134   */
3121 3135  void
3122 3136  tcp_get_proto_props(tcp_t *tcp, struct sock_proto_props *sopp)
3123 3137  {
3124 3138          conn_t *connp = tcp->tcp_connp;
3125 3139  
3126 3140          sopp->sopp_flags = SOCKOPT_RCVHIWAT | SOCKOPT_MAXBLK | SOCKOPT_WROFF;
3127 3141          sopp->sopp_maxblk = tcp_maxpsz_set(tcp, B_FALSE);
3128 3142  
3129 3143          sopp->sopp_rxhiwat = tcp->tcp_fused ?
3130 3144              tcp_fuse_set_rcv_hiwat(tcp, connp->conn_rcvbuf) :
3131 3145              connp->conn_rcvbuf;
3132 3146          /*
3133 3147           * Determine what write offset value to use depending on SACK and
3134 3148           * whether the endpoint is fused or not.
3135 3149           */
3136 3150          if (tcp->tcp_fused) {
3137 3151                  ASSERT(tcp->tcp_loopback);
3138 3152                  ASSERT(tcp->tcp_loopback_peer != NULL);
3139 3153                  /*
3140 3154                   * For fused tcp loopback, set the stream head's write
3141 3155                   * offset value to zero since we won't be needing any room
3142 3156                   * for TCP/IP headers.  This would also improve performance
3143 3157                   * since it would reduce the amount of work done by kmem.
3144 3158                   * Non-fused tcp loopback case is handled separately below.
3145 3159                   */
3146 3160                  sopp->sopp_wroff = 0;
3147 3161                  /*
3148 3162                   * Update the peer's transmit parameters according to
3149 3163                   * our recently calculated high water mark value.
3150 3164                   */
3151 3165                  (void) tcp_maxpsz_set(tcp->tcp_loopback_peer, B_TRUE);
3152 3166          } else if (tcp->tcp_snd_sack_ok) {
3153 3167                  sopp->sopp_wroff = connp->conn_ht_iphc_allocated +
3154 3168                      (tcp->tcp_loopback ? 0 : tcp->tcp_tcps->tcps_wroff_xtra);
3155 3169          } else {
3156 3170                  sopp->sopp_wroff = connp->conn_ht_iphc_len +
3157 3171                      (tcp->tcp_loopback ? 0 : tcp->tcp_tcps->tcps_wroff_xtra);
3158 3172          }
3159 3173  
3160 3174          if (tcp->tcp_loopback) {
3161 3175                  sopp->sopp_flags |= SOCKOPT_LOOPBACK;
3162 3176                  sopp->sopp_loopback = B_TRUE;
3163 3177          }
3164 3178  }
3165 3179  
3166 3180  /*
3167 3181   * Check the usability of ZEROCOPY. It's instead checking the flag set by IP.
3168 3182   */
3169 3183  boolean_t
3170 3184  tcp_zcopy_check(tcp_t *tcp)
3171 3185  {
3172 3186          conn_t          *connp = tcp->tcp_connp;
3173 3187          ip_xmit_attr_t  *ixa = connp->conn_ixa;
3174 3188          boolean_t       zc_enabled = B_FALSE;
3175 3189          tcp_stack_t     *tcps = tcp->tcp_tcps;
3176 3190  
3177 3191          if (do_tcpzcopy == 2)
3178 3192                  zc_enabled = B_TRUE;
3179 3193          else if ((do_tcpzcopy == 1) && (ixa->ixa_flags & IXAF_ZCOPY_CAPAB))
3180 3194                  zc_enabled = B_TRUE;
3181 3195  
3182 3196          tcp->tcp_snd_zcopy_on = zc_enabled;
3183 3197          if (!TCP_IS_DETACHED(tcp)) {
3184 3198                  if (zc_enabled) {
3185 3199                          ixa->ixa_flags |= IXAF_VERIFY_ZCOPY;
3186 3200                          (void) proto_set_tx_copyopt(connp->conn_rq, connp,
3187 3201                              ZCVMSAFE);
3188 3202                          TCP_STAT(tcps, tcp_zcopy_on);
3189 3203                  } else {
3190 3204                          ixa->ixa_flags &= ~IXAF_VERIFY_ZCOPY;
3191 3205                          (void) proto_set_tx_copyopt(connp->conn_rq, connp,
3192 3206                              ZCVMUNSAFE);
3193 3207                          TCP_STAT(tcps, tcp_zcopy_off);
3194 3208                  }
3195 3209          }
3196 3210          return (zc_enabled);
3197 3211  }
3198 3212  
3199 3213  /*
3200 3214   * Backoff from a zero-copy message by copying data to a new allocated
3201 3215   * message and freeing the original desballoca'ed segmapped message.
3202 3216   *
3203 3217   * This function is called by following two callers:
3204 3218   * 1. tcp_timer: fix_xmitlist is set to B_TRUE, because it's safe to free
3205 3219   *    the origial desballoca'ed message and notify sockfs. This is in re-
3206 3220   *    transmit state.
3207 3221   * 2. tcp_output: fix_xmitlist is set to B_FALSE. Flag STRUIO_ZCNOTIFY need
3208 3222   *    to be copied to new message.
3209 3223   */
3210 3224  mblk_t *
3211 3225  tcp_zcopy_backoff(tcp_t *tcp, mblk_t *bp, boolean_t fix_xmitlist)
3212 3226  {
3213 3227          mblk_t          *nbp;
3214 3228          mblk_t          *head = NULL;
3215 3229          mblk_t          *tail = NULL;
3216 3230          tcp_stack_t     *tcps = tcp->tcp_tcps;
3217 3231  
3218 3232          ASSERT(bp != NULL);
3219 3233          while (bp != NULL) {
3220 3234                  if (IS_VMLOANED_MBLK(bp)) {
3221 3235                          TCP_STAT(tcps, tcp_zcopy_backoff);
3222 3236                          if ((nbp = copyb(bp)) == NULL) {
3223 3237                                  tcp->tcp_xmit_zc_clean = B_FALSE;
3224 3238                                  if (tail != NULL)
3225 3239                                          tail->b_cont = bp;
3226 3240                                  return ((head == NULL) ? bp : head);
3227 3241                          }
3228 3242  
3229 3243                          if (bp->b_datap->db_struioflag & STRUIO_ZCNOTIFY) {
3230 3244                                  if (fix_xmitlist)
3231 3245                                          tcp_zcopy_notify(tcp);
3232 3246                                  else
3233 3247                                          nbp->b_datap->db_struioflag |=
3234 3248                                              STRUIO_ZCNOTIFY;
3235 3249                          }
3236 3250                          nbp->b_cont = bp->b_cont;
3237 3251  
3238 3252                          /*
3239 3253                           * Copy saved information and adjust tcp_xmit_tail
3240 3254                           * if needed.
3241 3255                           */
3242 3256                          if (fix_xmitlist) {
3243 3257                                  nbp->b_prev = bp->b_prev;
3244 3258                                  nbp->b_next = bp->b_next;
3245 3259  
3246 3260                                  if (tcp->tcp_xmit_tail == bp)
3247 3261                                          tcp->tcp_xmit_tail = nbp;
3248 3262                          }
3249 3263  
3250 3264                          /* Free the original message. */
3251 3265                          bp->b_prev = NULL;
3252 3266                          bp->b_next = NULL;
3253 3267                          freeb(bp);
3254 3268  
3255 3269                          bp = nbp;
3256 3270                  }
3257 3271  
3258 3272                  if (head == NULL) {
3259 3273                          head = bp;
3260 3274                  }
3261 3275                  if (tail == NULL) {
3262 3276                          tail = bp;
3263 3277                  } else {
3264 3278                          tail->b_cont = bp;
3265 3279                          tail = bp;
3266 3280                  }
3267 3281  
3268 3282                  /* Move forward. */
3269 3283                  bp = bp->b_cont;
3270 3284          }
3271 3285  
3272 3286          if (fix_xmitlist) {
3273 3287                  tcp->tcp_xmit_last = tail;
3274 3288                  tcp->tcp_xmit_zc_clean = B_TRUE;
3275 3289          }
3276 3290  
3277 3291          return (head);
3278 3292  }
3279 3293  
3280 3294  void
3281 3295  tcp_zcopy_notify(tcp_t *tcp)
3282 3296  {
3283 3297          struct stdata   *stp;
3284 3298          conn_t          *connp;
3285 3299  
3286 3300          if (tcp->tcp_detached)
3287 3301                  return;
3288 3302          connp = tcp->tcp_connp;
3289 3303          if (IPCL_IS_NONSTR(connp)) {
3290 3304                  (*connp->conn_upcalls->su_zcopy_notify)
3291 3305                      (connp->conn_upper_handle);
3292 3306                  return;
3293 3307          }
3294 3308          stp = STREAM(connp->conn_rq);
3295 3309          mutex_enter(&stp->sd_lock);
3296 3310          stp->sd_flag |= STZCNOTIFY;
3297 3311          cv_broadcast(&stp->sd_zcopy_wait);
3298 3312          mutex_exit(&stp->sd_lock);
3299 3313  }
3300 3314  
3301 3315  /*
3302 3316   * Update the TCP connection according to change of LSO capability.
3303 3317   */
3304 3318  static void
3305 3319  tcp_update_lso(tcp_t *tcp, ip_xmit_attr_t *ixa)
3306 3320  {
3307 3321          /*
3308 3322           * We check against IPv4 header length to preserve the old behavior
3309 3323           * of only enabling LSO when there are no IP options.
3310 3324           * But this restriction might not be necessary at all. Before removing
3311 3325           * it, need to verify how LSO is handled for source routing case, with
3312 3326           * which IP does software checksum.
3313 3327           *
3314 3328           * For IPv6, whenever any extension header is needed, LSO is supressed.
3315 3329           */
3316 3330          if (ixa->ixa_ip_hdr_length != ((ixa->ixa_flags & IXAF_IS_IPV4) ?
3317 3331              IP_SIMPLE_HDR_LENGTH : IPV6_HDR_LEN))
3318 3332                  return;
3319 3333  
3320 3334          /*
3321 3335           * Either the LSO capability newly became usable, or it has changed.
3322 3336           */
3323 3337          if (ixa->ixa_flags & IXAF_LSO_CAPAB) {
3324 3338                  ill_lso_capab_t *lsoc = &ixa->ixa_lso_capab;
3325 3339  
3326 3340                  ASSERT(lsoc->ill_lso_max > 0);
3327 3341                  tcp->tcp_lso_max = MIN(TCP_MAX_LSO_LENGTH, lsoc->ill_lso_max);
3328 3342  
3329 3343                  DTRACE_PROBE3(tcp_update_lso, boolean_t, tcp->tcp_lso,
3330 3344                      boolean_t, B_TRUE, uint32_t, tcp->tcp_lso_max);
3331 3345  
3332 3346                  /*
3333 3347                   * If LSO to be enabled, notify the STREAM header with larger
3334 3348                   * data block.
3335 3349                   */
3336 3350                  if (!tcp->tcp_lso)
3337 3351                          tcp->tcp_maxpsz_multiplier = 0;
3338 3352  
3339 3353                  tcp->tcp_lso = B_TRUE;
3340 3354                  TCP_STAT(tcp->tcp_tcps, tcp_lso_enabled);
3341 3355          } else { /* LSO capability is not usable any more. */
3342 3356                  DTRACE_PROBE3(tcp_update_lso, boolean_t, tcp->tcp_lso,
3343 3357                      boolean_t, B_FALSE, uint32_t, tcp->tcp_lso_max);
3344 3358  
3345 3359                  /*
3346 3360                   * If LSO to be disabled, notify the STREAM header with smaller
3347 3361                   * data block. And need to restore fragsize to PMTU.
3348 3362                   */
3349 3363                  if (tcp->tcp_lso) {
3350 3364                          tcp->tcp_maxpsz_multiplier =
3351 3365                              tcp->tcp_tcps->tcps_maxpsz_multiplier;
3352 3366                          ixa->ixa_fragsize = ixa->ixa_pmtu;
3353 3367                          tcp->tcp_lso = B_FALSE;
3354 3368                          TCP_STAT(tcp->tcp_tcps, tcp_lso_disabled);
3355 3369                  }
3356 3370          }
3357 3371  
3358 3372          (void) tcp_maxpsz_set(tcp, B_TRUE);
3359 3373  }
3360 3374  
3361 3375  /*
3362 3376   * Update the TCP connection according to change of ZEROCOPY capability.
3363 3377   */
3364 3378  static void
3365 3379  tcp_update_zcopy(tcp_t *tcp)
3366 3380  {
3367 3381          conn_t          *connp = tcp->tcp_connp;
3368 3382          tcp_stack_t     *tcps = tcp->tcp_tcps;
3369 3383  
3370 3384          if (tcp->tcp_snd_zcopy_on) {
3371 3385                  tcp->tcp_snd_zcopy_on = B_FALSE;
3372 3386                  if (!TCP_IS_DETACHED(tcp)) {
3373 3387                          (void) proto_set_tx_copyopt(connp->conn_rq, connp,
3374 3388                              ZCVMUNSAFE);
3375 3389                          TCP_STAT(tcps, tcp_zcopy_off);
3376 3390                  }
3377 3391          } else {
3378 3392                  tcp->tcp_snd_zcopy_on = B_TRUE;
3379 3393                  if (!TCP_IS_DETACHED(tcp)) {
3380 3394                          (void) proto_set_tx_copyopt(connp->conn_rq, connp,
3381 3395                              ZCVMSAFE);
3382 3396                          TCP_STAT(tcps, tcp_zcopy_on);
3383 3397                  }
3384 3398          }
3385 3399  }
3386 3400  
3387 3401  /*
3388 3402   * Notify function registered with ip_xmit_attr_t. It's called in the squeue
3389 3403   * so it's safe to update the TCP connection.
3390 3404   */
3391 3405  /* ARGSUSED1 */
3392 3406  static void
3393 3407  tcp_notify(void *arg, ip_xmit_attr_t *ixa, ixa_notify_type_t ntype,
3394 3408      ixa_notify_arg_t narg)
3395 3409  {
3396 3410          tcp_t           *tcp = (tcp_t *)arg;
3397 3411          conn_t          *connp = tcp->tcp_connp;
3398 3412  
3399 3413          switch (ntype) {
3400 3414          case IXAN_LSO:
3401 3415                  tcp_update_lso(tcp, connp->conn_ixa);
3402 3416                  break;
3403 3417          case IXAN_PMTU:
3404 3418                  tcp_update_pmtu(tcp, B_FALSE);
3405 3419                  break;
3406 3420          case IXAN_ZCOPY:
3407 3421                  tcp_update_zcopy(tcp);
3408 3422                  break;
3409 3423          default:
3410 3424                  break;
3411 3425          }
3412 3426  }
3413 3427  
3414 3428  /*
3415 3429   * The TCP write service routine should never be called...
3416 3430   */
3417 3431  /* ARGSUSED */
3418 3432  static void
3419 3433  tcp_wsrv(queue_t *q)
3420 3434  {
3421 3435          tcp_stack_t     *tcps = Q_TO_TCP(q)->tcp_tcps;
3422 3436  
3423 3437          TCP_STAT(tcps, tcp_wsrv_called);
3424 3438  }
3425 3439  
3426 3440  /*
3427 3441   * Hash list lookup routine for tcp_t structures.
3428 3442   * Returns with a CONN_INC_REF tcp structure. Caller must do a CONN_DEC_REF.
3429 3443   */
3430 3444  tcp_t *
3431 3445  tcp_acceptor_hash_lookup(t_uscalar_t id, tcp_stack_t *tcps)
3432 3446  {
3433 3447          tf_t    *tf;
3434 3448          tcp_t   *tcp;
3435 3449  
3436 3450          tf = &tcps->tcps_acceptor_fanout[TCP_ACCEPTOR_HASH(id)];
3437 3451          mutex_enter(&tf->tf_lock);
3438 3452          for (tcp = tf->tf_tcp; tcp != NULL;
3439 3453              tcp = tcp->tcp_acceptor_hash) {
3440 3454                  if (tcp->tcp_acceptor_id == id) {
3441 3455                          CONN_INC_REF(tcp->tcp_connp);
3442 3456                          mutex_exit(&tf->tf_lock);
3443 3457                          return (tcp);
3444 3458                  }
3445 3459          }
3446 3460          mutex_exit(&tf->tf_lock);
3447 3461          return (NULL);
3448 3462  }
3449 3463  
3450 3464  /*
3451 3465   * Hash list insertion routine for tcp_t structures.
3452 3466   */
3453 3467  void
3454 3468  tcp_acceptor_hash_insert(t_uscalar_t id, tcp_t *tcp)
3455 3469  {
3456 3470          tf_t    *tf;
3457 3471          tcp_t   **tcpp;
3458 3472          tcp_t   *tcpnext;
3459 3473          tcp_stack_t     *tcps = tcp->tcp_tcps;
3460 3474  
3461 3475          tf = &tcps->tcps_acceptor_fanout[TCP_ACCEPTOR_HASH(id)];
3462 3476  
3463 3477          if (tcp->tcp_ptpahn != NULL)
3464 3478                  tcp_acceptor_hash_remove(tcp);
3465 3479          tcpp = &tf->tf_tcp;
3466 3480          mutex_enter(&tf->tf_lock);
3467 3481          tcpnext = tcpp[0];
3468 3482          if (tcpnext)
3469 3483                  tcpnext->tcp_ptpahn = &tcp->tcp_acceptor_hash;
3470 3484          tcp->tcp_acceptor_hash = tcpnext;
3471 3485          tcp->tcp_ptpahn = tcpp;
3472 3486          tcpp[0] = tcp;
3473 3487          tcp->tcp_acceptor_lockp = &tf->tf_lock; /* For tcp_*_hash_remove */
3474 3488          mutex_exit(&tf->tf_lock);
3475 3489  }
3476 3490  
3477 3491  /*
3478 3492   * Hash list removal routine for tcp_t structures.
3479 3493   */
3480 3494  void
3481 3495  tcp_acceptor_hash_remove(tcp_t *tcp)
3482 3496  {
3483 3497          tcp_t   *tcpnext;
3484 3498          kmutex_t *lockp;
3485 3499  
3486 3500          /*
3487 3501           * Extract the lock pointer in case there are concurrent
3488 3502           * hash_remove's for this instance.
3489 3503           */
3490 3504          lockp = tcp->tcp_acceptor_lockp;
3491 3505  
3492 3506          if (tcp->tcp_ptpahn == NULL)
3493 3507                  return;
3494 3508  
3495 3509          ASSERT(lockp != NULL);
3496 3510          mutex_enter(lockp);
3497 3511          if (tcp->tcp_ptpahn) {
3498 3512                  tcpnext = tcp->tcp_acceptor_hash;
3499 3513                  if (tcpnext) {
3500 3514                          tcpnext->tcp_ptpahn = tcp->tcp_ptpahn;
3501 3515                          tcp->tcp_acceptor_hash = NULL;
3502 3516                  }
3503 3517                  *tcp->tcp_ptpahn = tcpnext;
3504 3518                  tcp->tcp_ptpahn = NULL;
3505 3519          }
3506 3520          mutex_exit(lockp);
3507 3521          tcp->tcp_acceptor_lockp = NULL;
3508 3522  }
3509 3523  
3510 3524  /*
3511 3525   * Type three generator adapted from the random() function in 4.4 BSD:
3512 3526   */
3513 3527  
3514 3528  /*
3515 3529   * Copyright (c) 1983, 1993
3516 3530   *      The Regents of the University of California.  All rights reserved.
3517 3531   *
3518 3532   * Redistribution and use in source and binary forms, with or without
3519 3533   * modification, are permitted provided that the following conditions
3520 3534   * are met:
3521 3535   * 1. Redistributions of source code must retain the above copyright
3522 3536   *    notice, this list of conditions and the following disclaimer.
3523 3537   * 2. Redistributions in binary form must reproduce the above copyright
3524 3538   *    notice, this list of conditions and the following disclaimer in the
3525 3539   *    documentation and/or other materials provided with the distribution.
3526 3540   * 3. All advertising materials mentioning features or use of this software
3527 3541   *    must display the following acknowledgement:
3528 3542   *      This product includes software developed by the University of
3529 3543   *      California, Berkeley and its contributors.
3530 3544   * 4. Neither the name of the University nor the names of its contributors
3531 3545   *    may be used to endorse or promote products derived from this software
3532 3546   *    without specific prior written permission.
3533 3547   *
3534 3548   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3535 3549   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3536 3550   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3537 3551   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3538 3552   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3539 3553   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3540 3554   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3541 3555   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3542 3556   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3543 3557   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3544 3558   * SUCH DAMAGE.
3545 3559   */
3546 3560  
3547 3561  /* Type 3 -- x**31 + x**3 + 1 */
3548 3562  #define DEG_3           31
3549 3563  #define SEP_3           3
3550 3564  
3551 3565  
3552 3566  /* Protected by tcp_random_lock */
3553 3567  static int tcp_randtbl[DEG_3 + 1];
3554 3568  
3555 3569  static int *tcp_random_fptr = &tcp_randtbl[SEP_3 + 1];
3556 3570  static int *tcp_random_rptr = &tcp_randtbl[1];
3557 3571  
3558 3572  static int *tcp_random_state = &tcp_randtbl[1];
3559 3573  static int *tcp_random_end_ptr = &tcp_randtbl[DEG_3 + 1];
3560 3574  
3561 3575  kmutex_t tcp_random_lock;
3562 3576  
3563 3577  void
3564 3578  tcp_random_init(void)
3565 3579  {
3566 3580          int i;
3567 3581          hrtime_t hrt;
3568 3582          time_t wallclock;
3569 3583          uint64_t result;
3570 3584  
3571 3585          /*
3572 3586           * Use high-res timer and current time for seed.  Gethrtime() returns
3573 3587           * a longlong, which may contain resolution down to nanoseconds.
3574 3588           * The current time will either be a 32-bit or a 64-bit quantity.
3575 3589           * XOR the two together in a 64-bit result variable.
3576 3590           * Convert the result to a 32-bit value by multiplying the high-order
3577 3591           * 32-bits by the low-order 32-bits.
3578 3592           */
3579 3593  
3580 3594          hrt = gethrtime();
3581 3595          (void) drv_getparm(TIME, &wallclock);
3582 3596          result = (uint64_t)wallclock ^ (uint64_t)hrt;
3583 3597          mutex_enter(&tcp_random_lock);
3584 3598          tcp_random_state[0] = ((result >> 32) & 0xffffffff) *
3585 3599              (result & 0xffffffff);
3586 3600  
3587 3601          for (i = 1; i < DEG_3; i++)
3588 3602                  tcp_random_state[i] = 1103515245 * tcp_random_state[i - 1]
3589 3603                      + 12345;
3590 3604          tcp_random_fptr = &tcp_random_state[SEP_3];
3591 3605          tcp_random_rptr = &tcp_random_state[0];
3592 3606          mutex_exit(&tcp_random_lock);
3593 3607          for (i = 0; i < 10 * DEG_3; i++)
3594 3608                  (void) tcp_random();
3595 3609  }
3596 3610  
3597 3611  /*
3598 3612   * tcp_random: Return a random number in the range [1 - (128K + 1)].
3599 3613   * This range is selected to be approximately centered on TCP_ISS / 2,
3600 3614   * and easy to compute. We get this value by generating a 32-bit random
3601 3615   * number, selecting out the high-order 17 bits, and then adding one so
3602 3616   * that we never return zero.
3603 3617   */
3604 3618  int
3605 3619  tcp_random(void)
3606 3620  {
3607 3621          int i;
3608 3622  
3609 3623          mutex_enter(&tcp_random_lock);
3610 3624          *tcp_random_fptr += *tcp_random_rptr;
3611 3625  
3612 3626          /*
3613 3627           * The high-order bits are more random than the low-order bits,
3614 3628           * so we select out the high-order 17 bits and add one so that
3615 3629           * we never return zero.
3616 3630           */
3617 3631          i = ((*tcp_random_fptr >> 15) & 0x1ffff) + 1;
3618 3632          if (++tcp_random_fptr >= tcp_random_end_ptr) {
3619 3633                  tcp_random_fptr = tcp_random_state;
3620 3634                  ++tcp_random_rptr;
3621 3635          } else if (++tcp_random_rptr >= tcp_random_end_ptr)
3622 3636                  tcp_random_rptr = tcp_random_state;
3623 3637  
3624 3638          mutex_exit(&tcp_random_lock);
3625 3639          return (i);
3626 3640  }
3627 3641  
3628 3642  /*
3629 3643   * Split this function out so that if the secret changes, I'm okay.
3630 3644   *
3631 3645   * Initialize the tcp_iss_cookie and tcp_iss_key.
3632 3646   */
3633 3647  
3634 3648  #define PASSWD_SIZE 16  /* MUST be multiple of 4 */
3635 3649  
3636 3650  void
3637 3651  tcp_iss_key_init(uint8_t *phrase, int len, tcp_stack_t *tcps)
3638 3652  {
3639 3653          struct {
3640 3654                  int32_t current_time;
3641 3655                  uint32_t randnum;
3642 3656                  uint16_t pad;
3643 3657                  uint8_t ether[6];
3644 3658                  uint8_t passwd[PASSWD_SIZE];
3645 3659          } tcp_iss_cookie;
3646 3660          time_t t;
3647 3661  
3648 3662          /*
3649 3663           * Start with the current absolute time.
3650 3664           */
3651 3665          (void) drv_getparm(TIME, &t);
3652 3666          tcp_iss_cookie.current_time = t;
3653 3667  
3654 3668          /*
3655 3669           * XXX - Need a more random number per RFC 1750, not this crap.
3656 3670           * OTOH, if what follows is pretty random, then I'm in better shape.
3657 3671           */
3658 3672          tcp_iss_cookie.randnum = (uint32_t)(gethrtime() + tcp_random());
3659 3673          tcp_iss_cookie.pad = 0x365c;  /* Picked from HMAC pad values. */
3660 3674  
3661 3675          /*
3662 3676           * The cpu_type_info is pretty non-random.  Ugggh.  It does serve
3663 3677           * as a good template.
3664 3678           */
3665 3679          bcopy(&cpu_list->cpu_type_info, &tcp_iss_cookie.passwd,
3666 3680              min(PASSWD_SIZE, sizeof (cpu_list->cpu_type_info)));
3667 3681  
3668 3682          /*
3669 3683           * The pass-phrase.  Normally this is supplied by user-called NDD.
3670 3684           */
3671 3685          bcopy(phrase, &tcp_iss_cookie.passwd, min(PASSWD_SIZE, len));
3672 3686  
3673 3687          /*
3674 3688           * See 4010593 if this section becomes a problem again,
3675 3689           * but the local ethernet address is useful here.
3676 3690           */
3677 3691          (void) localetheraddr(NULL,
3678 3692              (struct ether_addr *)&tcp_iss_cookie.ether);
3679 3693  
3680 3694          /*
3681 3695           * Hash 'em all together.  The MD5Final is called per-connection.
3682 3696           */
3683 3697          mutex_enter(&tcps->tcps_iss_key_lock);
3684 3698          MD5Init(&tcps->tcps_iss_key);
3685 3699          MD5Update(&tcps->tcps_iss_key, (uchar_t *)&tcp_iss_cookie,
3686 3700              sizeof (tcp_iss_cookie));
3687 3701          mutex_exit(&tcps->tcps_iss_key_lock);
3688 3702  }
3689 3703  
3690 3704  /*
3691 3705   * Called by IP when IP is loaded into the kernel
3692 3706   */
3693 3707  void
3694 3708  tcp_ddi_g_init(void)
3695 3709  {
3696 3710          tcp_timercache = kmem_cache_create("tcp_timercache",
3697 3711              sizeof (tcp_timer_t) + sizeof (mblk_t), 0,
3698 3712              NULL, NULL, NULL, NULL, NULL, 0);
3699 3713  
3700 3714          tcp_notsack_blk_cache = kmem_cache_create("tcp_notsack_blk_cache",
3701 3715              sizeof (notsack_blk_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
3702 3716  
3703 3717          mutex_init(&tcp_random_lock, NULL, MUTEX_DEFAULT, NULL);
3704 3718  
3705 3719          /* Initialize the random number generator */
3706 3720          tcp_random_init();
3707 3721  
3708 3722          /* A single callback independently of how many netstacks we have */
3709 3723          ip_squeue_init(tcp_squeue_add);
3710 3724  
3711 3725          tcp_g_kstat = tcp_g_kstat_init(&tcp_g_statistics);
3712 3726  
3713 3727          tcp_squeue_flag = tcp_squeue_switch(tcp_squeue_wput);
3714 3728  
3715 3729          /*
3716 3730           * We want to be informed each time a stack is created or
3717 3731           * destroyed in the kernel, so we can maintain the
3718 3732           * set of tcp_stack_t's.
3719 3733           */
3720 3734          netstack_register(NS_TCP, tcp_stack_init, NULL, tcp_stack_fini);
3721 3735  }
3722 3736  
3723 3737  
3724 3738  #define INET_NAME       "ip"
3725 3739  
3726 3740  /*
3727 3741   * Initialize the TCP stack instance.
3728 3742   */
3729 3743  static void *
3730 3744  tcp_stack_init(netstackid_t stackid, netstack_t *ns)
3731 3745  {
3732 3746          tcp_stack_t     *tcps;
3733 3747          int             i;
3734 3748          int             error = 0;
3735 3749          major_t         major;
3736 3750          size_t          arrsz;
3737 3751  
3738 3752          tcps = (tcp_stack_t *)kmem_zalloc(sizeof (*tcps), KM_SLEEP);
3739 3753          tcps->tcps_netstack = ns;
3740 3754  
3741 3755          /* Initialize locks */
3742 3756          mutex_init(&tcps->tcps_iss_key_lock, NULL, MUTEX_DEFAULT, NULL);
3743 3757          mutex_init(&tcps->tcps_epriv_port_lock, NULL, MUTEX_DEFAULT, NULL);
3744 3758  
3745 3759          tcps->tcps_g_num_epriv_ports = TCP_NUM_EPRIV_PORTS;
3746 3760          tcps->tcps_g_epriv_ports[0] = ULP_DEF_EPRIV_PORT1;
3747 3761          tcps->tcps_g_epriv_ports[1] = ULP_DEF_EPRIV_PORT2;
3748 3762          tcps->tcps_min_anonpriv_port = 512;
3749 3763  
3750 3764          tcps->tcps_bind_fanout = kmem_zalloc(sizeof (tf_t) *
3751 3765              TCP_BIND_FANOUT_SIZE, KM_SLEEP);
3752 3766          tcps->tcps_acceptor_fanout = kmem_zalloc(sizeof (tf_t) *
3753 3767              TCP_ACCEPTOR_FANOUT_SIZE, KM_SLEEP);
3754 3768  
3755 3769          for (i = 0; i < TCP_BIND_FANOUT_SIZE; i++) {
3756 3770                  mutex_init(&tcps->tcps_bind_fanout[i].tf_lock, NULL,
3757 3771                      MUTEX_DEFAULT, NULL);
3758 3772          }
3759 3773  
3760 3774          for (i = 0; i < TCP_ACCEPTOR_FANOUT_SIZE; i++) {
3761 3775                  mutex_init(&tcps->tcps_acceptor_fanout[i].tf_lock, NULL,
3762 3776                      MUTEX_DEFAULT, NULL);
3763 3777          }
3764 3778  
3765 3779          /* TCP's IPsec code calls the packet dropper. */
3766 3780          ip_drop_register(&tcps->tcps_dropper, "TCP IPsec policy enforcement");
3767 3781  
3768 3782          arrsz = tcp_propinfo_count * sizeof (mod_prop_info_t);
3769 3783          tcps->tcps_propinfo_tbl = (mod_prop_info_t *)kmem_alloc(arrsz,
3770 3784              KM_SLEEP);
3771 3785          bcopy(tcp_propinfo_tbl, tcps->tcps_propinfo_tbl, arrsz);
3772 3786  
3773 3787          /*
3774 3788           * Note: To really walk the device tree you need the devinfo
3775 3789           * pointer to your device which is only available after probe/attach.
3776 3790           * The following is safe only because it uses ddi_root_node()
3777 3791           */
3778 3792          tcp_max_optsize = optcom_max_optsize(tcp_opt_obj.odb_opt_des_arr,
3779 3793              tcp_opt_obj.odb_opt_arr_cnt);
3780 3794  
3781 3795          /*
3782 3796           * Initialize RFC 1948 secret values.  This will probably be reset once
3783 3797           * by the boot scripts.
3784 3798           *
3785 3799           * Use NULL name, as the name is caught by the new lockstats.
3786 3800           *
3787 3801           * Initialize with some random, non-guessable string, like the global
3788 3802           * T_INFO_ACK.
3789 3803           */
3790 3804  
3791 3805          tcp_iss_key_init((uint8_t *)&tcp_g_t_info_ack,
3792 3806              sizeof (tcp_g_t_info_ack), tcps);
3793 3807  
3794 3808          tcps->tcps_kstat = tcp_kstat2_init(stackid);
3795 3809          tcps->tcps_mibkp = tcp_kstat_init(stackid);
3796 3810  
3797 3811          major = mod_name_to_major(INET_NAME);
3798 3812          error = ldi_ident_from_major(major, &tcps->tcps_ldi_ident);
3799 3813          ASSERT(error == 0);
3800 3814          tcps->tcps_ixa_cleanup_mp = allocb_wait(0, BPRI_MED, STR_NOSIG, NULL);
3801 3815          ASSERT(tcps->tcps_ixa_cleanup_mp != NULL);
3802 3816          cv_init(&tcps->tcps_ixa_cleanup_ready_cv, NULL, CV_DEFAULT, NULL);
3803 3817          cv_init(&tcps->tcps_ixa_cleanup_done_cv, NULL, CV_DEFAULT, NULL);
3804 3818          mutex_init(&tcps->tcps_ixa_cleanup_lock, NULL, MUTEX_DEFAULT, NULL);
3805 3819  
3806 3820          mutex_init(&tcps->tcps_reclaim_lock, NULL, MUTEX_DEFAULT, NULL);
3807 3821          tcps->tcps_reclaim = B_FALSE;
3808 3822          tcps->tcps_reclaim_tid = 0;
3809 3823          tcps->tcps_reclaim_period = tcps->tcps_rexmit_interval_max;
3810 3824  
3811 3825          /*
3812 3826           * ncpus is the current number of CPUs, which can be bigger than
3813 3827           * boot_ncpus.  But we don't want to use ncpus to allocate all the
3814 3828           * tcp_stats_cpu_t at system boot up time since it will be 1.  While
3815 3829           * we handle adding CPU in tcp_cpu_update(), it will be slow if
3816 3830           * there are many CPUs as we will be adding them 1 by 1.
3817 3831           *
3818 3832           * Note that tcps_sc_cnt never decreases and the tcps_sc[x] pointers
3819 3833           * are not freed until the stack is going away.  So there is no need
3820 3834           * to grab a lock to access the per CPU tcps_sc[x] pointer.
3821 3835           */
3822 3836          mutex_enter(&cpu_lock);
3823 3837          tcps->tcps_sc_cnt = MAX(ncpus, boot_ncpus);
3824 3838          mutex_exit(&cpu_lock);
3825 3839          tcps->tcps_sc = kmem_zalloc(max_ncpus  * sizeof (tcp_stats_cpu_t *),
3826 3840              KM_SLEEP);
3827 3841          for (i = 0; i < tcps->tcps_sc_cnt; i++) {
3828 3842                  tcps->tcps_sc[i] = kmem_zalloc(sizeof (tcp_stats_cpu_t),
3829 3843                      KM_SLEEP);
3830 3844          }
3831 3845  
3832 3846          mutex_init(&tcps->tcps_listener_conf_lock, NULL, MUTEX_DEFAULT, NULL);
3833 3847          list_create(&tcps->tcps_listener_conf, sizeof (tcp_listener_t),
3834 3848              offsetof(tcp_listener_t, tl_link));
3835 3849  
3836 3850          return (tcps);
3837 3851  }
3838 3852  
3839 3853  /*
3840 3854   * Called when the IP module is about to be unloaded.
3841 3855   */
3842 3856  void
3843 3857  tcp_ddi_g_destroy(void)
3844 3858  {
3845 3859          tcp_g_kstat_fini(tcp_g_kstat);
3846 3860          tcp_g_kstat = NULL;
3847 3861          bzero(&tcp_g_statistics, sizeof (tcp_g_statistics));
3848 3862  
3849 3863          mutex_destroy(&tcp_random_lock);
3850 3864  
3851 3865          kmem_cache_destroy(tcp_timercache);
3852 3866          kmem_cache_destroy(tcp_notsack_blk_cache);
3853 3867  
3854 3868          netstack_unregister(NS_TCP);
3855 3869  }
3856 3870  
3857 3871  /*
3858 3872   * Free the TCP stack instance.
3859 3873   */
3860 3874  static void
3861 3875  tcp_stack_fini(netstackid_t stackid, void *arg)
3862 3876  {
3863 3877          tcp_stack_t *tcps = (tcp_stack_t *)arg;
3864 3878          int i;
3865 3879  
3866 3880          freeb(tcps->tcps_ixa_cleanup_mp);
3867 3881          tcps->tcps_ixa_cleanup_mp = NULL;
3868 3882          cv_destroy(&tcps->tcps_ixa_cleanup_ready_cv);
3869 3883          cv_destroy(&tcps->tcps_ixa_cleanup_done_cv);
3870 3884          mutex_destroy(&tcps->tcps_ixa_cleanup_lock);
3871 3885  
3872 3886          /*
3873 3887           * Set tcps_reclaim to false tells tcp_reclaim_timer() not to restart
3874 3888           * the timer.
3875 3889           */
3876 3890          mutex_enter(&tcps->tcps_reclaim_lock);
3877 3891          tcps->tcps_reclaim = B_FALSE;
3878 3892          mutex_exit(&tcps->tcps_reclaim_lock);
3879 3893          if (tcps->tcps_reclaim_tid != 0)
3880 3894                  (void) untimeout(tcps->tcps_reclaim_tid);
3881 3895          mutex_destroy(&tcps->tcps_reclaim_lock);
3882 3896  
3883 3897          tcp_listener_conf_cleanup(tcps);
3884 3898  
3885 3899          for (i = 0; i < tcps->tcps_sc_cnt; i++)
3886 3900                  kmem_free(tcps->tcps_sc[i], sizeof (tcp_stats_cpu_t));
3887 3901          kmem_free(tcps->tcps_sc, max_ncpus * sizeof (tcp_stats_cpu_t *));
3888 3902  
3889 3903          kmem_free(tcps->tcps_propinfo_tbl,
3890 3904              tcp_propinfo_count * sizeof (mod_prop_info_t));
3891 3905          tcps->tcps_propinfo_tbl = NULL;
3892 3906  
3893 3907          for (i = 0; i < TCP_BIND_FANOUT_SIZE; i++) {
3894 3908                  ASSERT(tcps->tcps_bind_fanout[i].tf_tcp == NULL);
3895 3909                  mutex_destroy(&tcps->tcps_bind_fanout[i].tf_lock);
3896 3910          }
3897 3911  
3898 3912          for (i = 0; i < TCP_ACCEPTOR_FANOUT_SIZE; i++) {
3899 3913                  ASSERT(tcps->tcps_acceptor_fanout[i].tf_tcp == NULL);
3900 3914                  mutex_destroy(&tcps->tcps_acceptor_fanout[i].tf_lock);
3901 3915          }
3902 3916  
3903 3917          kmem_free(tcps->tcps_bind_fanout, sizeof (tf_t) * TCP_BIND_FANOUT_SIZE);
3904 3918          tcps->tcps_bind_fanout = NULL;
3905 3919  
3906 3920          kmem_free(tcps->tcps_acceptor_fanout, sizeof (tf_t) *
3907 3921              TCP_ACCEPTOR_FANOUT_SIZE);
3908 3922          tcps->tcps_acceptor_fanout = NULL;
3909 3923  
3910 3924          mutex_destroy(&tcps->tcps_iss_key_lock);
3911 3925          mutex_destroy(&tcps->tcps_epriv_port_lock);
3912 3926  
3913 3927          ip_drop_unregister(&tcps->tcps_dropper);
3914 3928  
3915 3929          tcp_kstat2_fini(stackid, tcps->tcps_kstat);
3916 3930          tcps->tcps_kstat = NULL;
3917 3931  
3918 3932          tcp_kstat_fini(stackid, tcps->tcps_mibkp);
3919 3933          tcps->tcps_mibkp = NULL;
3920 3934  
3921 3935          ldi_ident_release(tcps->tcps_ldi_ident);
3922 3936          kmem_free(tcps, sizeof (*tcps));
3923 3937  }
3924 3938  
3925 3939  /*
3926 3940   * Generate ISS, taking into account NDD changes may happen halfway through.
3927 3941   * (If the iss is not zero, set it.)
3928 3942   */
3929 3943  
3930 3944  static void
3931 3945  tcp_iss_init(tcp_t *tcp)
3932 3946  {
3933 3947          MD5_CTX context;
3934 3948          struct { uint32_t ports; in6_addr_t src; in6_addr_t dst; } arg;
3935 3949          uint32_t answer[4];
3936 3950          tcp_stack_t     *tcps = tcp->tcp_tcps;
3937 3951          conn_t          *connp = tcp->tcp_connp;
3938 3952  
3939 3953          tcps->tcps_iss_incr_extra += (tcps->tcps_iss_incr >> 1);
3940 3954          tcp->tcp_iss = tcps->tcps_iss_incr_extra;
3941 3955          switch (tcps->tcps_strong_iss) {
3942 3956          case 2:
3943 3957                  mutex_enter(&tcps->tcps_iss_key_lock);
3944 3958                  context = tcps->tcps_iss_key;
3945 3959                  mutex_exit(&tcps->tcps_iss_key_lock);
3946 3960                  arg.ports = connp->conn_ports;
3947 3961                  arg.src = connp->conn_laddr_v6;
3948 3962                  arg.dst = connp->conn_faddr_v6;
3949 3963                  MD5Update(&context, (uchar_t *)&arg, sizeof (arg));
3950 3964                  MD5Final((uchar_t *)answer, &context);
3951 3965                  tcp->tcp_iss += answer[0] ^ answer[1] ^ answer[2] ^ answer[3];
3952 3966                  /*
3953 3967                   * Now that we've hashed into a unique per-connection sequence
3954 3968                   * space, add a random increment per strong_iss == 1.  So I
3955 3969                   * guess we'll have to...
3956 3970                   */
3957 3971                  /* FALLTHRU */
3958 3972          case 1:
3959 3973                  tcp->tcp_iss += (gethrtime() >> ISS_NSEC_SHT) + tcp_random();
3960 3974                  break;
3961 3975          default:
3962 3976                  tcp->tcp_iss += (uint32_t)gethrestime_sec() *
3963 3977                      tcps->tcps_iss_incr;
3964 3978                  break;
3965 3979          }
3966 3980          tcp->tcp_valid_bits = TCP_ISS_VALID;
3967 3981          tcp->tcp_fss = tcp->tcp_iss - 1;
3968 3982          tcp->tcp_suna = tcp->tcp_iss;
3969 3983          tcp->tcp_snxt = tcp->tcp_iss + 1;
3970 3984          tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
3971 3985          tcp->tcp_csuna = tcp->tcp_snxt;
3972 3986  }
3973 3987  
3974 3988  /*
3975 3989   * tcp_{set,clr}qfull() functions are used to either set or clear QFULL
3976 3990   * on the specified backing STREAMS q. Note, the caller may make the
3977 3991   * decision to call based on the tcp_t.tcp_flow_stopped value which
3978 3992   * when check outside the q's lock is only an advisory check ...
3979 3993   */
3980 3994  void
3981 3995  tcp_setqfull(tcp_t *tcp)
3982 3996  {
3983 3997          tcp_stack_t     *tcps = tcp->tcp_tcps;
3984 3998          conn_t  *connp = tcp->tcp_connp;
3985 3999  
3986 4000          if (tcp->tcp_closed)
3987 4001                  return;
3988 4002  
3989 4003          conn_setqfull(connp, &tcp->tcp_flow_stopped);
3990 4004          if (tcp->tcp_flow_stopped)
3991 4005                  TCP_STAT(tcps, tcp_flwctl_on);
3992 4006  }
3993 4007  
3994 4008  void
3995 4009  tcp_clrqfull(tcp_t *tcp)
3996 4010  {
3997 4011          conn_t  *connp = tcp->tcp_connp;
3998 4012  
3999 4013          if (tcp->tcp_closed)
4000 4014                  return;
4001 4015          conn_clrqfull(connp, &tcp->tcp_flow_stopped);
4002 4016  }
4003 4017  
4004 4018  static int
4005 4019  tcp_squeue_switch(int val)
4006 4020  {
4007 4021          int rval = SQ_FILL;
4008 4022  
4009 4023          switch (val) {
4010 4024          case 1:
4011 4025                  rval = SQ_NODRAIN;
4012 4026                  break;
4013 4027          case 2:
4014 4028                  rval = SQ_PROCESS;
4015 4029                  break;
4016 4030          default:
4017 4031                  break;
4018 4032          }
4019 4033          return (rval);
4020 4034  }
4021 4035  
4022 4036  /*
4023 4037   * This is called once for each squeue - globally for all stack
4024 4038   * instances.
4025 4039   */
4026 4040  static void
4027 4041  tcp_squeue_add(squeue_t *sqp)
4028 4042  {
4029 4043          tcp_squeue_priv_t *tcp_time_wait = kmem_zalloc(
4030 4044              sizeof (tcp_squeue_priv_t), KM_SLEEP);
4031 4045  
4032 4046          *squeue_getprivate(sqp, SQPRIVATE_TCP) = (intptr_t)tcp_time_wait;
4033 4047          if (tcp_free_list_max_cnt == 0) {
4034 4048                  int tcp_ncpus = ((boot_max_ncpus == -1) ?
4035 4049                      max_ncpus : boot_max_ncpus);
4036 4050  
4037 4051                  /*
4038 4052                   * Limit number of entries to 1% of availble memory / tcp_ncpus
4039 4053                   */
4040 4054                  tcp_free_list_max_cnt = (freemem * PAGESIZE) /
4041 4055                      (tcp_ncpus * sizeof (tcp_t) * 100);
4042 4056          }
4043 4057          tcp_time_wait->tcp_free_list_cnt = 0;
4044 4058  }
4045 4059  /*
4046 4060   * Return unix error is tli error is TSYSERR, otherwise return a negative
4047 4061   * tli error.
4048 4062   */
4049 4063  int
4050 4064  tcp_do_bind(conn_t *connp, struct sockaddr *sa, socklen_t len, cred_t *cr,
4051 4065      boolean_t bind_to_req_port_only)
4052 4066  {
4053 4067          int error;
4054 4068          tcp_t *tcp = connp->conn_tcp;
4055 4069  
4056 4070          if (tcp->tcp_state >= TCPS_BOUND) {
4057 4071                  if (connp->conn_debug) {
4058 4072                          (void) strlog(TCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
4059 4073                              "tcp_bind: bad state, %d", tcp->tcp_state);
4060 4074                  }
4061 4075                  return (-TOUTSTATE);
4062 4076          }
4063 4077  
4064 4078          error = tcp_bind_check(connp, sa, len, cr, bind_to_req_port_only);
4065 4079          if (error != 0)
4066 4080                  return (error);
4067 4081  
4068 4082          ASSERT(tcp->tcp_state == TCPS_BOUND);
4069 4083          tcp->tcp_conn_req_max = 0;
4070 4084          return (0);
4071 4085  }
4072 4086  
4073 4087  /*
4074 4088   * If the return value from this function is positive, it's a UNIX error.
4075 4089   * Otherwise, if it's negative, then the absolute value is a TLI error.
4076 4090   * the TPI routine tcp_tpi_connect() is a wrapper function for this.
4077 4091   */
4078 4092  int
4079 4093  tcp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
4080 4094      cred_t *cr, pid_t pid)
4081 4095  {
4082 4096          tcp_t           *tcp = connp->conn_tcp;
4083 4097          sin_t           *sin = (sin_t *)sa;
4084 4098          sin6_t          *sin6 = (sin6_t *)sa;
4085 4099          ipaddr_t        *dstaddrp;
4086 4100          in_port_t       dstport;
4087 4101          uint_t          srcid;
4088 4102          int             error;
4089 4103          uint32_t        mss;
4090 4104          mblk_t          *syn_mp;
4091 4105          tcp_stack_t     *tcps = tcp->tcp_tcps;
4092 4106          int32_t         oldstate;
4093 4107          ip_xmit_attr_t  *ixa = connp->conn_ixa;
4094 4108  
4095 4109          oldstate = tcp->tcp_state;
4096 4110  
4097 4111          switch (len) {
4098 4112          default:
4099 4113                  /*
4100 4114                   * Should never happen
4101 4115                   */
4102 4116                  return (EINVAL);
4103 4117  
4104 4118          case sizeof (sin_t):
4105 4119                  sin = (sin_t *)sa;
4106 4120                  if (sin->sin_port == 0) {
4107 4121                          return (-TBADADDR);
4108 4122                  }
4109 4123                  if (connp->conn_ipv6_v6only) {
4110 4124                          return (EAFNOSUPPORT);
4111 4125                  }
4112 4126                  break;
4113 4127  
4114 4128          case sizeof (sin6_t):
4115 4129                  sin6 = (sin6_t *)sa;
4116 4130                  if (sin6->sin6_port == 0) {
4117 4131                          return (-TBADADDR);
4118 4132                  }
4119 4133                  break;
4120 4134          }
4121 4135          /*
4122 4136           * If we're connecting to an IPv4-mapped IPv6 address, we need to
4123 4137           * make sure that the conn_ipversion is IPV4_VERSION.  We
4124 4138           * need to this before we call tcp_bindi() so that the port lookup
4125 4139           * code will look for ports in the correct port space (IPv4 and
4126 4140           * IPv6 have separate port spaces).
4127 4141           */
4128 4142          if (connp->conn_family == AF_INET6 &&
4129 4143              connp->conn_ipversion == IPV6_VERSION &&
4130 4144              IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
4131 4145                  if (connp->conn_ipv6_v6only)
4132 4146                          return (EADDRNOTAVAIL);
4133 4147  
4134 4148                  connp->conn_ipversion = IPV4_VERSION;
4135 4149          }
4136 4150  
4137 4151          switch (tcp->tcp_state) {
4138 4152          case TCPS_LISTEN:
4139 4153                  /*
4140 4154                   * Listening sockets are not allowed to issue connect().
4141 4155                   */
4142 4156                  if (IPCL_IS_NONSTR(connp))
4143 4157                          return (EOPNOTSUPP);
4144 4158                  /* FALLTHRU */
4145 4159          case TCPS_IDLE:
4146 4160                  /*
4147 4161                   * We support quick connect, refer to comments in
4148 4162                   * tcp_connect_*()
4149 4163                   */
4150 4164                  /* FALLTHRU */
4151 4165          case TCPS_BOUND:
4152 4166                  break;
4153 4167          default:
4154 4168                  return (-TOUTSTATE);
4155 4169          }
4156 4170  
4157 4171          /*
4158 4172           * We update our cred/cpid based on the caller of connect
4159 4173           */
4160 4174          if (connp->conn_cred != cr) {
4161 4175                  crhold(cr);
4162 4176                  crfree(connp->conn_cred);
4163 4177                  connp->conn_cred = cr;
4164 4178          }
4165 4179          connp->conn_cpid = pid;
4166 4180  
4167 4181          /* Cache things in the ixa without any refhold */
4168 4182          ASSERT(!(ixa->ixa_free_flags & IXA_FREE_CRED));
4169 4183          ixa->ixa_cred = cr;
4170 4184          ixa->ixa_cpid = pid;
4171 4185          if (is_system_labeled()) {
4172 4186                  /* We need to restart with a label based on the cred */
4173 4187                  ip_xmit_attr_restore_tsl(ixa, ixa->ixa_cred);
4174 4188          }
4175 4189  
4176 4190          if (connp->conn_family == AF_INET6) {
4177 4191                  if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
4178 4192                          error = tcp_connect_ipv6(tcp, &sin6->sin6_addr,
4179 4193                              sin6->sin6_port, sin6->sin6_flowinfo,
4180 4194                              sin6->__sin6_src_id, sin6->sin6_scope_id);
4181 4195                  } else {
4182 4196                          /*
4183 4197                           * Destination adress is mapped IPv6 address.
4184 4198                           * Source bound address should be unspecified or
4185 4199                           * IPv6 mapped address as well.
4186 4200                           */
4187 4201                          if (!IN6_IS_ADDR_UNSPECIFIED(
4188 4202                              &connp->conn_bound_addr_v6) &&
4189 4203                              !IN6_IS_ADDR_V4MAPPED(&connp->conn_bound_addr_v6)) {
4190 4204                                  return (EADDRNOTAVAIL);
4191 4205                          }
4192 4206                          dstaddrp = &V4_PART_OF_V6((sin6->sin6_addr));
4193 4207                          dstport = sin6->sin6_port;
4194 4208                          srcid = sin6->__sin6_src_id;
4195 4209                          error = tcp_connect_ipv4(tcp, dstaddrp, dstport,
4196 4210                              srcid);
4197 4211                  }
4198 4212          } else {
4199 4213                  dstaddrp = &sin->sin_addr.s_addr;
4200 4214                  dstport = sin->sin_port;
4201 4215                  srcid = 0;
4202 4216                  error = tcp_connect_ipv4(tcp, dstaddrp, dstport, srcid);
4203 4217          }
4204 4218  
4205 4219          if (error != 0)
4206 4220                  goto connect_failed;
4207 4221  
4208 4222          CL_INET_CONNECT(connp, B_TRUE, error);
4209 4223          if (error != 0)
4210 4224                  goto connect_failed;
4211 4225  
4212 4226          /* connect succeeded */
4213 4227          TCPS_BUMP_MIB(tcps, tcpActiveOpens);
4214 4228          tcp->tcp_active_open = 1;
4215 4229  
4216 4230          /*
4217 4231           * tcp_set_destination() does not adjust for TCP/IP header length.
4218 4232           */
4219 4233          mss = tcp->tcp_mss - connp->conn_ht_iphc_len;
4220 4234  
4221 4235          /*
4222 4236           * Just make sure our rwnd is at least rcvbuf * MSS large, and round up
4223 4237           * to the nearest MSS.
4224 4238           *
4225 4239           * We do the round up here because we need to get the interface MTU
4226 4240           * first before we can do the round up.
4227 4241           */
4228 4242          tcp->tcp_rwnd = connp->conn_rcvbuf;
4229 4243          tcp->tcp_rwnd = MAX(MSS_ROUNDUP(tcp->tcp_rwnd, mss),
4230 4244              tcps->tcps_recv_hiwat_minmss * mss);
4231 4245          connp->conn_rcvbuf = tcp->tcp_rwnd;
4232 4246          tcp_set_ws_value(tcp);
4233 4247          tcp->tcp_tcpha->tha_win = htons(tcp->tcp_rwnd >> tcp->tcp_rcv_ws);
4234 4248          if (tcp->tcp_rcv_ws > 0 || tcps->tcps_wscale_always)
4235 4249                  tcp->tcp_snd_ws_ok = B_TRUE;
4236 4250  
4237 4251          /*
4238 4252           * Set tcp_snd_ts_ok to true
4239 4253           * so that tcp_xmit_mp will
4240 4254           * include the timestamp
4241 4255           * option in the SYN segment.
4242 4256           */
4243 4257          if (tcps->tcps_tstamp_always ||
4244 4258              (tcp->tcp_rcv_ws && tcps->tcps_tstamp_if_wscale)) {
4245 4259                  tcp->tcp_snd_ts_ok = B_TRUE;
4246 4260          }
4247 4261  
4248 4262          /*
4249 4263           * Note that tcp_snd_sack_ok can be set in tcp_set_destination() if
4250 4264           * the SACK metric is set.  So here we just check the per stack SACK
4251 4265           * permitted param.
4252 4266           */
4253 4267          if (tcps->tcps_sack_permitted == 2) {
4254 4268                  ASSERT(tcp->tcp_num_sack_blk == 0);
4255 4269                  ASSERT(tcp->tcp_notsack_list == NULL);
4256 4270                  tcp->tcp_snd_sack_ok = B_TRUE;
4257 4271          }
4258 4272  
4259 4273          /*
4260 4274           * Should we use ECN?  Note that the current
4261 4275           * default value (SunOS 5.9) of tcp_ecn_permitted
4262 4276           * is 1.  The reason for doing this is that there
4263 4277           * are equipments out there that will drop ECN
4264 4278           * enabled IP packets.  Setting it to 1 avoids
4265 4279           * compatibility problems.
4266 4280           */
4267 4281          if (tcps->tcps_ecn_permitted == 2)
4268 4282                  tcp->tcp_ecn_ok = B_TRUE;
4269 4283  
4270 4284          /* Trace change from BOUND -> SYN_SENT here */
4271 4285          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
4272 4286              connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
4273 4287              int32_t, TCPS_BOUND);
4274 4288  
4275 4289          TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
4276 4290          syn_mp = tcp_xmit_mp(tcp, NULL, 0, NULL, NULL,
4277 4291              tcp->tcp_iss, B_FALSE, NULL, B_FALSE);
4278 4292          if (syn_mp != NULL) {
4279 4293                  /*
4280 4294                   * We must bump the generation before sending the syn
4281 4295                   * to ensure that we use the right generation in case
4282 4296                   * this thread issues a "connected" up call.
4283 4297                   */
4284 4298                  SOCK_CONNID_BUMP(tcp->tcp_connid);
4285 4299                  /*
4286 4300                   * DTrace sending the first SYN as a
4287 4301                   * tcp:::connect-request event.
4288 4302                   */
4289 4303                  DTRACE_TCP5(connect__request, mblk_t *, NULL,
4290 4304                      ip_xmit_attr_t *, connp->conn_ixa,
4291 4305                      void_ip_t *, syn_mp->b_rptr, tcp_t *, tcp,
4292 4306                      tcph_t *,
4293 4307                      &syn_mp->b_rptr[connp->conn_ixa->ixa_ip_hdr_length]);
4294 4308                  tcp_send_data(tcp, syn_mp);
4295 4309          }
4296 4310  
4297 4311          if (tcp->tcp_conn.tcp_opts_conn_req != NULL)
4298 4312                  tcp_close_mpp(&tcp->tcp_conn.tcp_opts_conn_req);
4299 4313          return (0);
4300 4314  
4301 4315  connect_failed:
4302 4316          connp->conn_faddr_v6 = ipv6_all_zeros;
4303 4317          connp->conn_fport = 0;
4304 4318          tcp->tcp_state = oldstate;
4305 4319          if (tcp->tcp_conn.tcp_opts_conn_req != NULL)
4306 4320                  tcp_close_mpp(&tcp->tcp_conn.tcp_opts_conn_req);
4307 4321          return (error);
4308 4322  }
4309 4323  
4310 4324  int
4311 4325  tcp_do_listen(conn_t *connp, struct sockaddr *sa, socklen_t len,
4312 4326      int backlog, cred_t *cr, boolean_t bind_to_req_port_only)
4313 4327  {
4314 4328          tcp_t           *tcp = connp->conn_tcp;
4315 4329          int             error = 0;
4316 4330          tcp_stack_t     *tcps = tcp->tcp_tcps;
4317 4331          int32_t         oldstate;
4318 4332  
4319 4333          /* All Solaris components should pass a cred for this operation. */
4320 4334          ASSERT(cr != NULL);
4321 4335  
4322 4336          if (tcp->tcp_state >= TCPS_BOUND) {
4323 4337                  if ((tcp->tcp_state == TCPS_BOUND ||
4324 4338                      tcp->tcp_state == TCPS_LISTEN) && backlog > 0) {
4325 4339                          /*
4326 4340                           * Handle listen() increasing backlog.
4327 4341                           * This is more "liberal" then what the TPI spec
4328 4342                           * requires but is needed to avoid a t_unbind
4329 4343                           * when handling listen() since the port number
4330 4344                           * might be "stolen" between the unbind and bind.
4331 4345                           */
4332 4346                          goto do_listen;
4333 4347                  }
4334 4348                  if (connp->conn_debug) {
4335 4349                          (void) strlog(TCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
4336 4350                              "tcp_listen: bad state, %d", tcp->tcp_state);
4337 4351                  }
4338 4352                  return (-TOUTSTATE);
4339 4353          } else {
4340 4354                  if (sa == NULL) {
4341 4355                          sin6_t  addr;
4342 4356                          sin_t *sin;
4343 4357                          sin6_t *sin6;
4344 4358  
4345 4359                          ASSERT(IPCL_IS_NONSTR(connp));
4346 4360                          /* Do an implicit bind: Request for a generic port. */
4347 4361                          if (connp->conn_family == AF_INET) {
4348 4362                                  len = sizeof (sin_t);
4349 4363                                  sin = (sin_t *)&addr;
4350 4364                                  *sin = sin_null;
4351 4365                                  sin->sin_family = AF_INET;
4352 4366                          } else {
4353 4367                                  ASSERT(connp->conn_family == AF_INET6);
4354 4368                                  len = sizeof (sin6_t);
4355 4369                                  sin6 = (sin6_t *)&addr;
4356 4370                                  *sin6 = sin6_null;
4357 4371                                  sin6->sin6_family = AF_INET6;
4358 4372                          }
4359 4373                          sa = (struct sockaddr *)&addr;
4360 4374                  }
4361 4375  
4362 4376                  error = tcp_bind_check(connp, sa, len, cr,
4363 4377                      bind_to_req_port_only);
4364 4378                  if (error)
4365 4379                          return (error);
4366 4380                  /* Fall through and do the fanout insertion */
4367 4381          }
4368 4382  
4369 4383  do_listen:
4370 4384          ASSERT(tcp->tcp_state == TCPS_BOUND || tcp->tcp_state == TCPS_LISTEN);
4371 4385          tcp->tcp_conn_req_max = backlog;
4372 4386          if (tcp->tcp_conn_req_max) {
4373 4387                  if (tcp->tcp_conn_req_max < tcps->tcps_conn_req_min)
4374 4388                          tcp->tcp_conn_req_max = tcps->tcps_conn_req_min;
4375 4389                  if (tcp->tcp_conn_req_max > tcps->tcps_conn_req_max_q)
4376 4390                          tcp->tcp_conn_req_max = tcps->tcps_conn_req_max_q;
4377 4391                  /*
4378 4392                   * If this is a listener, do not reset the eager list
4379 4393                   * and other stuffs.  Note that we don't check if the
4380 4394                   * existing eager list meets the new tcp_conn_req_max
4381 4395                   * requirement.
4382 4396                   */
4383 4397                  if (tcp->tcp_state != TCPS_LISTEN) {
4384 4398                          tcp->tcp_state = TCPS_LISTEN;
4385 4399                          DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
4386 4400                              connp->conn_ixa, void, NULL, tcp_t *, tcp,
4387 4401                              void, NULL, int32_t, TCPS_BOUND);
4388 4402                          /* Initialize the chain. Don't need the eager_lock */
4389 4403                          tcp->tcp_eager_next_q0 = tcp->tcp_eager_prev_q0 = tcp;
4390 4404                          tcp->tcp_eager_next_drop_q0 = tcp;
4391 4405                          tcp->tcp_eager_prev_drop_q0 = tcp;
4392 4406                          tcp->tcp_second_ctimer_threshold =
4393 4407                              tcps->tcps_ip_abort_linterval;
4394 4408                  }
4395 4409          }
4396 4410  
4397 4411          /*
4398 4412           * We need to make sure that the conn_recv is set to a non-null
4399 4413           * value before we insert the conn into the classifier table.
4400 4414           * This is to avoid a race with an incoming packet which does an
4401 4415           * ipcl_classify().
4402 4416           * We initially set it to tcp_input_listener_unbound to try to
4403 4417           * pick a good squeue for the listener when the first SYN arrives.
4404 4418           * tcp_input_listener_unbound sets it to tcp_input_listener on that
4405 4419           * first SYN.
4406 4420           */
4407 4421          connp->conn_recv = tcp_input_listener_unbound;
4408 4422  
4409 4423          /* Insert the listener in the classifier table */
4410 4424          error = ip_laddr_fanout_insert(connp);
4411 4425          if (error != 0) {
4412 4426                  /* Undo the bind - release the port number */
4413 4427                  oldstate = tcp->tcp_state;
4414 4428                  tcp->tcp_state = TCPS_IDLE;
4415 4429                  DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
4416 4430                      connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
4417 4431                      int32_t, oldstate);
4418 4432                  connp->conn_bound_addr_v6 = ipv6_all_zeros;
4419 4433  
4420 4434                  connp->conn_laddr_v6 = ipv6_all_zeros;
4421 4435                  connp->conn_saddr_v6 = ipv6_all_zeros;
4422 4436                  connp->conn_ports = 0;
4423 4437  
4424 4438                  if (connp->conn_anon_port) {
4425 4439                          zone_t          *zone;
4426 4440  
4427 4441                          zone = crgetzone(cr);
4428 4442                          connp->conn_anon_port = B_FALSE;
4429 4443                          (void) tsol_mlp_anon(zone, connp->conn_mlp_type,
4430 4444                              connp->conn_proto, connp->conn_lport, B_FALSE);
4431 4445                  }
4432 4446                  connp->conn_mlp_type = mlptSingle;
4433 4447  
4434 4448                  tcp_bind_hash_remove(tcp);
4435 4449                  return (error);
4436 4450          } else {
4437 4451                  /*
4438 4452                   * If there is a connection limit, allocate and initialize
4439 4453                   * the counter struct.  Note that since listen can be called
4440 4454                   * multiple times, the struct may have been allready allocated.
4441 4455                   */
4442 4456                  if (!list_is_empty(&tcps->tcps_listener_conf) &&
4443 4457                      tcp->tcp_listen_cnt == NULL) {
4444 4458                          tcp_listen_cnt_t *tlc;
4445 4459                          uint32_t ratio;
4446 4460  
4447 4461                          ratio = tcp_find_listener_conf(tcps,
4448 4462                              ntohs(connp->conn_lport));
4449 4463                          if (ratio != 0) {
4450 4464                                  uint32_t mem_ratio, tot_buf;
4451 4465  
4452 4466                                  tlc = kmem_alloc(sizeof (tcp_listen_cnt_t),
4453 4467                                      KM_SLEEP);
4454 4468                                  /*
4455 4469                                   * Calculate the connection limit based on
4456 4470                                   * the configured ratio and maxusers.  Maxusers
4457 4471                                   * are calculated based on memory size,
4458 4472                                   * ~ 1 user per MB.  Note that the conn_rcvbuf
4459 4473                                   * and conn_sndbuf may change after a
4460 4474                                   * connection is accepted.  So what we have
4461 4475                                   * is only an approximation.
4462 4476                                   */
4463 4477                                  if ((tot_buf = connp->conn_rcvbuf +
4464 4478                                      connp->conn_sndbuf) < MB) {
4465 4479                                          mem_ratio = MB / tot_buf;
4466 4480                                          tlc->tlc_max = maxusers / ratio *
4467 4481                                              mem_ratio;
4468 4482                                  } else {
4469 4483                                          mem_ratio = tot_buf / MB;
4470 4484                                          tlc->tlc_max = maxusers / ratio /
4471 4485                                              mem_ratio;
4472 4486                                  }
4473 4487                                  /* At least we should allow two connections! */
4474 4488                                  if (tlc->tlc_max <= tcp_min_conn_listener)
4475 4489                                          tlc->tlc_max = tcp_min_conn_listener;
4476 4490                                  tlc->tlc_cnt = 1;
4477 4491                                  tlc->tlc_drop = 0;
4478 4492                                  tcp->tcp_listen_cnt = tlc;
4479 4493                          }
4480 4494                  }
4481 4495          }
4482 4496          return (error);
4483 4497  }
  
    | 
      ↓ open down ↓ | 
    2415 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX