Print this page
    
XXXX adding PID information to netstat output
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/inet/tcp/tcp_stats.c
          +++ new/usr/src/uts/common/inet/tcp/tcp_stats.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
  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  /*
  
    | ↓ open down ↓ | 22 lines elided | ↑ open up ↑ | 
  23   23   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2011, Joyent Inc. All rights reserved.
  25   25   */
  26   26  
  27   27  #include <sys/types.h>
  28   28  #include <sys/tihdr.h>
  29   29  #include <sys/policy.h>
  30   30  #include <sys/tsol/tnet.h>
  31   31  #include <sys/kstat.h>
  32   32  
       33 +#include <sys/strsun.h>
       34 +#include <sys/stropts.h>
       35 +#include <sys/strsubr.h>
       36 +#include <sys/socket.h>
       37 +#include <sys/socketvar.h>
       38 +#include <sys/uio.h>
       39 +
  33   40  #include <inet/common.h>
  34   41  #include <inet/ip.h>
  35   42  #include <inet/tcp.h>
  36   43  #include <inet/tcp_impl.h>
  37   44  #include <inet/tcp_stats.h>
  38   45  #include <inet/kstatcom.h>
  39   46  #include <inet/snmpcom.h>
  40   47  
  41   48  static int      tcp_kstat_update(kstat_t *, int);
  42   49  static int      tcp_kstat2_update(kstat_t *, int);
  43   50  static void     tcp_sum_mib(tcp_stack_t *, mib2_tcp_t *);
  44   51  
  45   52  static void     tcp_add_mib(mib2_tcp_t *, mib2_tcp_t *);
  46   53  static void     tcp_add_stats(tcp_stat_counter_t *, tcp_stat_t *);
  47   54  static void     tcp_clr_stats(tcp_stat_t *);
  48   55  
  49   56  tcp_g_stat_t    tcp_g_statistics;
  50   57  kstat_t         *tcp_g_kstat;
  51   58  
  52   59  /* Translate TCP state to MIB2 TCP state. */
  53   60  static int
  54   61  tcp_snmp_state(tcp_t *tcp)
  55   62  {
  56   63          if (tcp == NULL)
  57   64                  return (0);
  58   65  
  59   66          switch (tcp->tcp_state) {
  60   67          case TCPS_CLOSED:
  61   68          case TCPS_IDLE: /* RFC1213 doesn't have analogue for IDLE & BOUND */
  62   69          case TCPS_BOUND:
  63   70                  return (MIB2_TCP_closed);
  64   71          case TCPS_LISTEN:
  65   72                  return (MIB2_TCP_listen);
  66   73          case TCPS_SYN_SENT:
  67   74                  return (MIB2_TCP_synSent);
  68   75          case TCPS_SYN_RCVD:
  69   76                  return (MIB2_TCP_synReceived);
  70   77          case TCPS_ESTABLISHED:
  71   78                  return (MIB2_TCP_established);
  72   79          case TCPS_CLOSE_WAIT:
  73   80                  return (MIB2_TCP_closeWait);
  74   81          case TCPS_FIN_WAIT_1:
  75   82                  return (MIB2_TCP_finWait1);
  76   83          case TCPS_CLOSING:
  77   84                  return (MIB2_TCP_closing);
  78   85          case TCPS_LAST_ACK:
  79   86                  return (MIB2_TCP_lastAck);
  80   87          case TCPS_FIN_WAIT_2:
  81   88                  return (MIB2_TCP_finWait2);
  82   89          case TCPS_TIME_WAIT:
  83   90                  return (MIB2_TCP_timeWait);
  84   91          default:
  85   92                  return (0);
  86   93          }
  87   94  }
  88   95  
  89   96  /*
  
    | ↓ open down ↓ | 47 lines elided | ↑ open up ↑ | 
  90   97   * Return SNMP stuff in buffer in mpdata.
  91   98   */
  92   99  mblk_t *
  93  100  tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
  94  101  {
  95  102          mblk_t                  *mpdata;
  96  103          mblk_t                  *mp_conn_ctl = NULL;
  97  104          mblk_t                  *mp_conn_tail;
  98  105          mblk_t                  *mp_attr_ctl = NULL;
  99  106          mblk_t                  *mp_attr_tail;
      107 +        mblk_t                  *mp_pidnode_ctl = NULL;
      108 +        mblk_t                  *mp_pidnode_tail;
 100  109          mblk_t                  *mp6_conn_ctl = NULL;
 101  110          mblk_t                  *mp6_conn_tail;
 102  111          mblk_t                  *mp6_attr_ctl = NULL;
 103  112          mblk_t                  *mp6_attr_tail;
      113 +        mblk_t                  *mp6_pidnode_ctl = NULL;
      114 +        mblk_t                  *mp6_pidnode_tail;
 104  115          struct opthdr           *optp;
 105  116          mib2_tcpConnEntry_t     tce;
 106  117          mib2_tcp6ConnEntry_t    tce6;
 107  118          mib2_transportMLPEntry_t mlp;
 108  119          connf_t                 *connfp;
 109  120          int                     i;
 110  121          boolean_t               ispriv;
 111  122          zoneid_t                zoneid;
 112  123          int                     v4_conn_idx;
 113  124          int                     v6_conn_idx;
 114  125          conn_t                  *connp = Q_TO_CONN(q);
 115  126          tcp_stack_t             *tcps;
 116  127          ip_stack_t              *ipst;
 117  128          mblk_t                  *mp2ctl;
 118  129          mib2_tcp_t              tcp_mib;
 119  130          size_t                  tcp_mib_size, tce_size, tce6_size;
  
    | ↓ open down ↓ | 6 lines elided | ↑ open up ↑ | 
 120  131  
 121  132          /*
 122  133           * make a copy of the original message
 123  134           */
 124  135          mp2ctl = copymsg(mpctl);
 125  136  
 126  137          if (mpctl == NULL ||
 127  138              (mpdata = mpctl->b_cont) == NULL ||
 128  139              (mp_conn_ctl = copymsg(mpctl)) == NULL ||
 129  140              (mp_attr_ctl = copymsg(mpctl)) == NULL ||
      141 +            (mp_pidnode_ctl = copymsg(mpctl)) == NULL ||
 130  142              (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
 131      -            (mp6_attr_ctl = copymsg(mpctl)) == NULL) {
      143 +            (mp6_attr_ctl = copymsg(mpctl)) == NULL ||
      144 +            (mp6_pidnode_ctl = copymsg(mpctl)) == NULL) {
 132  145                  freemsg(mp_conn_ctl);
 133  146                  freemsg(mp_attr_ctl);
      147 +                freemsg(mp_pidnode_ctl);
 134  148                  freemsg(mp6_conn_ctl);
 135  149                  freemsg(mp6_attr_ctl);
      150 +                freemsg(mp6_pidnode_ctl);
 136  151                  freemsg(mpctl);
 137  152                  freemsg(mp2ctl);
 138  153                  return (NULL);
 139  154          }
 140  155  
 141  156          ipst = connp->conn_netstack->netstack_ip;
 142  157          tcps = connp->conn_netstack->netstack_tcp;
 143  158  
 144  159          if (legacy_req) {
 145  160                  tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
 146  161                  tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
 147  162                  tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
 148  163          } else {
 149  164                  tcp_mib_size = sizeof (mib2_tcp_t);
 150  165                  tce_size = sizeof (mib2_tcpConnEntry_t);
 151  166                  tce6_size = sizeof (mib2_tcp6ConnEntry_t);
 152  167          }
 153  168  
 154  169          bzero(&tcp_mib, sizeof (tcp_mib));
 155  170  
 156  171          /* build table of connections -- need count in fixed part */
 157  172          SET_MIB(tcp_mib.tcpRtoAlgorithm, 4);   /* vanj */
 158  173          SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
  
    | ↓ open down ↓ | 13 lines elided | ↑ open up ↑ | 
 159  174          SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
 160  175          SET_MIB(tcp_mib.tcpMaxConn, -1);
 161  176          SET_MIB(tcp_mib.tcpCurrEstab, 0);
 162  177  
 163  178          ispriv =
 164  179              secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
 165  180          zoneid = Q_TO_CONN(q)->conn_zoneid;
 166  181  
 167  182          v4_conn_idx = v6_conn_idx = 0;
 168  183          mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
      184 +        mp_pidnode_tail = mp6_pidnode_tail = NULL;
 169  185  
 170  186          for (i = 0; i < CONN_G_HASH_SIZE; i++) {
 171  187                  ipst = tcps->tcps_netstack->netstack_ip;
 172  188  
 173  189                  connfp = &ipst->ips_ipcl_globalhash_fanout[i];
 174  190  
 175  191                  connp = NULL;
 176  192  
 177  193                  while ((connp =
 178  194                      ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
 179  195                          tcp_t *tcp;
 180  196                          boolean_t needattr;
 181  197  
 182  198                          if (connp->conn_zoneid != zoneid)
 183  199                                  continue;       /* not in this zone */
 184  200  
 185  201                          tcp = connp->conn_tcp;
 186  202                          TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
 187  203                          tcp->tcp_ibsegs = 0;
 188  204                          TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
 189  205                          tcp->tcp_obsegs = 0;
 190  206  
 191  207                          tce6.tcp6ConnState = tce.tcpConnState =
 192  208                              tcp_snmp_state(tcp);
 193  209                          if (tce.tcpConnState == MIB2_TCP_established ||
 194  210                              tce.tcpConnState == MIB2_TCP_closeWait)
 195  211                                  BUMP_MIB(&tcp_mib, tcpCurrEstab);
 196  212  
 197  213                          needattr = B_FALSE;
 198  214                          bzero(&mlp, sizeof (mlp));
 199  215                          if (connp->conn_mlp_type != mlptSingle) {
 200  216                                  if (connp->conn_mlp_type == mlptShared ||
 201  217                                      connp->conn_mlp_type == mlptBoth)
 202  218                                          mlp.tme_flags |= MIB2_TMEF_SHARED;
 203  219                                  if (connp->conn_mlp_type == mlptPrivate ||
 204  220                                      connp->conn_mlp_type == mlptBoth)
 205  221                                          mlp.tme_flags |= MIB2_TMEF_PRIVATE;
 206  222                                  needattr = B_TRUE;
 207  223                          }
 208  224                          if (connp->conn_anon_mlp) {
 209  225                                  mlp.tme_flags |= MIB2_TMEF_ANONMLP;
 210  226                                  needattr = B_TRUE;
 211  227                          }
 212  228                          switch (connp->conn_mac_mode) {
 213  229                          case CONN_MAC_DEFAULT:
 214  230                                  break;
 215  231                          case CONN_MAC_AWARE:
 216  232                                  mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
 217  233                                  needattr = B_TRUE;
 218  234                                  break;
 219  235                          case CONN_MAC_IMPLICIT:
 220  236                                  mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
 221  237                                  needattr = B_TRUE;
 222  238                                  break;
 223  239                          }
 224  240                          if (connp->conn_ixa->ixa_tsl != NULL) {
 225  241                                  ts_label_t *tsl;
 226  242  
 227  243                                  tsl = connp->conn_ixa->ixa_tsl;
 228  244                                  mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
 229  245                                  mlp.tme_doi = label2doi(tsl);
 230  246                                  mlp.tme_label = *label2bslabel(tsl);
 231  247                                  needattr = B_TRUE;
 232  248                          }
 233  249  
 234  250                          /* Create a message to report on IPv6 entries */
 235  251                          if (connp->conn_ipversion == IPV6_VERSION) {
 236  252                          tce6.tcp6ConnLocalAddress = connp->conn_laddr_v6;
 237  253                          tce6.tcp6ConnRemAddress = connp->conn_faddr_v6;
 238  254                          tce6.tcp6ConnLocalPort = ntohs(connp->conn_lport);
 239  255                          tce6.tcp6ConnRemPort = ntohs(connp->conn_fport);
 240  256                          if (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET) {
 241  257                                  tce6.tcp6ConnIfIndex =
 242  258                                      connp->conn_ixa->ixa_scopeid;
 243  259                          } else {
 244  260                                  tce6.tcp6ConnIfIndex = connp->conn_bound_if;
 245  261                          }
 246  262                          /* Don't want just anybody seeing these... */
 247  263                          if (ispriv) {
 248  264                                  tce6.tcp6ConnEntryInfo.ce_snxt =
 249  265                                      tcp->tcp_snxt;
 250  266                                  tce6.tcp6ConnEntryInfo.ce_suna =
 251  267                                      tcp->tcp_suna;
 252  268                                  tce6.tcp6ConnEntryInfo.ce_rnxt =
 253  269                                      tcp->tcp_rnxt;
 254  270                                  tce6.tcp6ConnEntryInfo.ce_rack =
 255  271                                      tcp->tcp_rack;
 256  272                          } else {
 257  273                                  /*
 258  274                                   * Netstat, unfortunately, uses this to
 259  275                                   * get send/receive queue sizes.  How to fix?
 260  276                                   * Why not compute the difference only?
 261  277                                   */
 262  278                                  tce6.tcp6ConnEntryInfo.ce_snxt =
 263  279                                      tcp->tcp_snxt - tcp->tcp_suna;
 264  280                                  tce6.tcp6ConnEntryInfo.ce_suna = 0;
 265  281                                  tce6.tcp6ConnEntryInfo.ce_rnxt =
 266  282                                      tcp->tcp_rnxt - tcp->tcp_rack;
 267  283                                  tce6.tcp6ConnEntryInfo.ce_rack = 0;
 268  284                          }
 269  285  
 270  286                          tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
 271  287                          tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
 272  288                          tce6.tcp6ConnEntryInfo.ce_rto =  tcp->tcp_rto;
 273  289                          tce6.tcp6ConnEntryInfo.ce_mss =  tcp->tcp_mss;
  
    | ↓ open down ↓ | 95 lines elided | ↑ open up ↑ | 
 274  290                          tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
 275  291  
 276  292                          tce6.tcp6ConnCreationProcess =
 277  293                              (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
 278  294                              connp->conn_cpid;
 279  295                          tce6.tcp6ConnCreationTime = connp->conn_open_time;
 280  296  
 281  297                          (void) snmp_append_data2(mp6_conn_ctl->b_cont,
 282  298                              &mp6_conn_tail, (char *)&tce6, tce6_size);
 283  299  
      300 +                        (void) snmp_append_data2(mp6_pidnode_ctl->b_cont,
      301 +                            &mp6_pidnode_tail, (char *)&tce6, tce6_size);
      302 +
      303 +                        (void) snmp_append_mblk2(mp6_pidnode_ctl->b_cont,
      304 +                            &mp6_pidnode_tail, conn_get_pid_mblk(connp));
      305 +
 284  306                          mlp.tme_connidx = v6_conn_idx++;
 285  307                          if (needattr)
 286  308                                  (void) snmp_append_data2(mp6_attr_ctl->b_cont,
 287  309                                      &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
 288  310                          }
 289  311                          /*
 290  312                           * Create an IPv4 table entry for IPv4 entries and also
 291  313                           * for IPv6 entries which are bound to in6addr_any
 292  314                           * but don't have IPV6_V6ONLY set.
 293  315                           * (i.e. anything an IPv4 peer could connect to)
 294  316                           */
 295  317                          if (connp->conn_ipversion == IPV4_VERSION ||
 296  318                              (tcp->tcp_state <= TCPS_LISTEN &&
 297  319                              !connp->conn_ipv6_v6only &&
 298  320                              IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
 299  321                                  if (connp->conn_ipversion == IPV6_VERSION) {
 300  322                                          tce.tcpConnRemAddress = INADDR_ANY;
 301  323                                          tce.tcpConnLocalAddress = INADDR_ANY;
 302  324                                  } else {
 303  325                                          tce.tcpConnRemAddress =
 304  326                                              connp->conn_faddr_v4;
 305  327                                          tce.tcpConnLocalAddress =
 306  328                                              connp->conn_laddr_v4;
 307  329                                  }
 308  330                                  tce.tcpConnLocalPort = ntohs(connp->conn_lport);
 309  331                                  tce.tcpConnRemPort = ntohs(connp->conn_fport);
 310  332                                  /* Don't want just anybody seeing these... */
 311  333                                  if (ispriv) {
 312  334                                          tce.tcpConnEntryInfo.ce_snxt =
 313  335                                              tcp->tcp_snxt;
 314  336                                          tce.tcpConnEntryInfo.ce_suna =
 315  337                                              tcp->tcp_suna;
 316  338                                          tce.tcpConnEntryInfo.ce_rnxt =
 317  339                                              tcp->tcp_rnxt;
 318  340                                          tce.tcpConnEntryInfo.ce_rack =
 319  341                                              tcp->tcp_rack;
 320  342                                  } else {
 321  343                                          /*
 322  344                                           * Netstat, unfortunately, uses this to
 323  345                                           * get send/receive queue sizes.  How
 324  346                                           * to fix?
 325  347                                           * Why not compute the difference only?
 326  348                                           */
 327  349                                          tce.tcpConnEntryInfo.ce_snxt =
 328  350                                              tcp->tcp_snxt - tcp->tcp_suna;
 329  351                                          tce.tcpConnEntryInfo.ce_suna = 0;
 330  352                                          tce.tcpConnEntryInfo.ce_rnxt =
 331  353                                              tcp->tcp_rnxt - tcp->tcp_rack;
 332  354                                          tce.tcpConnEntryInfo.ce_rack = 0;
 333  355                                  }
 334  356  
 335  357                                  tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
 336  358                                  tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
 337  359                                  tce.tcpConnEntryInfo.ce_rto =  tcp->tcp_rto;
 338  360                                  tce.tcpConnEntryInfo.ce_mss =  tcp->tcp_mss;
 339  361                                  tce.tcpConnEntryInfo.ce_state =
 340  362                                      tcp->tcp_state;
  
    | ↓ open down ↓ | 47 lines elided | ↑ open up ↑ | 
 341  363  
 342  364                                  tce.tcpConnCreationProcess =
 343  365                                      (connp->conn_cpid < 0) ?
 344  366                                      MIB2_UNKNOWN_PROCESS :
 345  367                                      connp->conn_cpid;
 346  368                                  tce.tcpConnCreationTime = connp->conn_open_time;
 347  369  
 348  370                                  (void) snmp_append_data2(mp_conn_ctl->b_cont,
 349  371                                      &mp_conn_tail, (char *)&tce, tce_size);
 350  372  
      373 +                                (void) snmp_append_data2(mp_pidnode_ctl->b_cont,
      374 +                                    &mp_pidnode_tail, (char *)&tce, tce_size);
      375 +
      376 +                                (void) snmp_append_mblk2(mp_pidnode_ctl->b_cont,
      377 +                                    &mp_pidnode_tail, conn_get_pid_mblk(connp));
      378 +
 351  379                                  mlp.tme_connidx = v4_conn_idx++;
 352  380                                  if (needattr)
 353  381                                          (void) snmp_append_data2(
 354  382                                              mp_attr_ctl->b_cont,
 355  383                                              &mp_attr_tail, (char *)&mlp,
 356  384                                              sizeof (mlp));
 357  385                          }
 358  386                  }
 359  387          }
 360  388  
 361  389          tcp_sum_mib(tcps, &tcp_mib);
 362  390  
 363  391          /* Fixed length structure for IPv4 and IPv6 counters */
 364  392          SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
 365  393          SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
 366  394  
 367  395          /*
 368  396           * Synchronize 32- and 64-bit counters.  Note that tcpInSegs and
 369  397           * tcpOutSegs are not updated anywhere in TCP.  The new 64 bits
 370  398           * counters are used.  Hence the old counters' values in tcp_sc_mib
 371  399           * are always 0.
 372  400           */
 373  401          SYNC32_MIB(&tcp_mib, tcpInSegs, tcpHCInSegs);
 374  402          SYNC32_MIB(&tcp_mib, tcpOutSegs, tcpHCOutSegs);
 375  403  
 376  404          optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
 377  405          optp->level = MIB2_TCP;
 378  406          optp->name = 0;
 379  407          (void) snmp_append_data(mpdata, (char *)&tcp_mib, tcp_mib_size);
 380  408          optp->len = msgdsize(mpdata);
 381  409          qreply(q, mpctl);
 382  410  
 383  411          /* table of connections... */
 384  412          optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
 385  413              sizeof (struct T_optmgmt_ack)];
 386  414          optp->level = MIB2_TCP;
 387  415          optp->name = MIB2_TCP_CONN;
 388  416          optp->len = msgdsize(mp_conn_ctl->b_cont);
 389  417          qreply(q, mp_conn_ctl);
 390  418  
 391  419          /* table of MLP attributes... */
 392  420          optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
 393  421              sizeof (struct T_optmgmt_ack)];
 394  422          optp->level = MIB2_TCP;
 395  423          optp->name = EXPER_XPORT_MLP;
 396  424          optp->len = msgdsize(mp_attr_ctl->b_cont);
 397  425          if (optp->len == 0)
 398  426                  freemsg(mp_attr_ctl);
 399  427          else
 400  428                  qreply(q, mp_attr_ctl);
 401  429  
 402  430          /* table of IPv6 connections... */
 403  431          optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
 404  432              sizeof (struct T_optmgmt_ack)];
 405  433          optp->level = MIB2_TCP6;
 406  434          optp->name = MIB2_TCP6_CONN;
 407  435          optp->len = msgdsize(mp6_conn_ctl->b_cont);
 408  436          qreply(q, mp6_conn_ctl);
 409  437  
  
    | ↓ open down ↓ | 49 lines elided | ↑ open up ↑ | 
 410  438          /* table of IPv6 MLP attributes... */
 411  439          optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
 412  440              sizeof (struct T_optmgmt_ack)];
 413  441          optp->level = MIB2_TCP6;
 414  442          optp->name = EXPER_XPORT_MLP;
 415  443          optp->len = msgdsize(mp6_attr_ctl->b_cont);
 416  444          if (optp->len == 0)
 417  445                  freemsg(mp6_attr_ctl);
 418  446          else
 419  447                  qreply(q, mp6_attr_ctl);
      448 +
      449 +        /* table of EXPER_XPORT_PROC_INFO  ipv4 */
      450 +        optp = (struct opthdr *)&mp_pidnode_ctl->b_rptr[
      451 +            sizeof (struct T_optmgmt_ack)];
      452 +        optp->level = MIB2_TCP;
      453 +        optp->name = EXPER_XPORT_PROC_INFO;
      454 +        optp->len = msgdsize(mp_pidnode_ctl->b_cont);
      455 +        if (optp->len == 0)
      456 +                freemsg(mp_pidnode_ctl);
      457 +        else
      458 +                qreply(q, mp_pidnode_ctl);
      459 +
      460 +        /* table of EXPER_XPORT_PROC_INFO  ipv6 */
      461 +        optp = (struct opthdr *)&mp6_pidnode_ctl->b_rptr[
      462 +            sizeof (struct T_optmgmt_ack)];
      463 +        optp->level = MIB2_TCP6;
      464 +        optp->name = EXPER_XPORT_PROC_INFO;
      465 +        optp->len = msgdsize(mp6_pidnode_ctl->b_cont);
      466 +        if (optp->len == 0)
      467 +                freemsg(mp6_pidnode_ctl);
      468 +        else
      469 +                qreply(q, mp6_pidnode_ctl);
      470 +
 420  471          return (mp2ctl);
 421  472  }
 422  473  
 423  474  /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests  */
 424  475  /* ARGSUSED */
 425  476  int
 426  477  tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
 427  478  {
 428  479          mib2_tcpConnEntry_t     *tce = (mib2_tcpConnEntry_t *)ptr;
 429  480  
 430  481          switch (level) {
 431  482          case MIB2_TCP:
 432  483                  switch (name) {
 433  484                  case 13:
 434  485                          if (tce->tcpConnState != MIB2_TCP_deleteTCB)
 435  486                                  return (0);
 436  487                          /* TODO: delete entry defined by tce */
 437  488                          return (1);
 438  489                  default:
 439  490                          return (0);
 440  491                  }
 441  492          default:
 442  493                  return (1);
 443  494          }
 444  495  }
 445  496  
 446  497  /*
 447  498   * TCP Kstats implementation
 448  499   */
 449  500  void *
 450  501  tcp_kstat_init(netstackid_t stackid)
 451  502  {
 452  503          kstat_t *ksp;
 453  504  
 454  505          tcp_named_kstat_t template = {
 455  506                  { "rtoAlgorithm",       KSTAT_DATA_INT32, 0 },
 456  507                  { "rtoMin",             KSTAT_DATA_INT32, 0 },
 457  508                  { "rtoMax",             KSTAT_DATA_INT32, 0 },
 458  509                  { "maxConn",            KSTAT_DATA_INT32, 0 },
 459  510                  { "activeOpens",        KSTAT_DATA_UINT32, 0 },
 460  511                  { "passiveOpens",       KSTAT_DATA_UINT32, 0 },
 461  512                  { "attemptFails",       KSTAT_DATA_UINT32, 0 },
 462  513                  { "estabResets",        KSTAT_DATA_UINT32, 0 },
 463  514                  { "currEstab",          KSTAT_DATA_UINT32, 0 },
 464  515                  { "inSegs",             KSTAT_DATA_UINT64, 0 },
 465  516                  { "outSegs",            KSTAT_DATA_UINT64, 0 },
 466  517                  { "retransSegs",        KSTAT_DATA_UINT32, 0 },
 467  518                  { "connTableSize",      KSTAT_DATA_INT32, 0 },
 468  519                  { "outRsts",            KSTAT_DATA_UINT32, 0 },
 469  520                  { "outDataSegs",        KSTAT_DATA_UINT32, 0 },
 470  521                  { "outDataBytes",       KSTAT_DATA_UINT32, 0 },
 471  522                  { "retransBytes",       KSTAT_DATA_UINT32, 0 },
 472  523                  { "outAck",             KSTAT_DATA_UINT32, 0 },
 473  524                  { "outAckDelayed",      KSTAT_DATA_UINT32, 0 },
 474  525                  { "outUrg",             KSTAT_DATA_UINT32, 0 },
 475  526                  { "outWinUpdate",       KSTAT_DATA_UINT32, 0 },
 476  527                  { "outWinProbe",        KSTAT_DATA_UINT32, 0 },
 477  528                  { "outControl",         KSTAT_DATA_UINT32, 0 },
 478  529                  { "outFastRetrans",     KSTAT_DATA_UINT32, 0 },
 479  530                  { "inAckSegs",          KSTAT_DATA_UINT32, 0 },
 480  531                  { "inAckBytes",         KSTAT_DATA_UINT32, 0 },
 481  532                  { "inDupAck",           KSTAT_DATA_UINT32, 0 },
 482  533                  { "inAckUnsent",        KSTAT_DATA_UINT32, 0 },
 483  534                  { "inDataInorderSegs",  KSTAT_DATA_UINT32, 0 },
 484  535                  { "inDataInorderBytes", KSTAT_DATA_UINT32, 0 },
 485  536                  { "inDataUnorderSegs",  KSTAT_DATA_UINT32, 0 },
 486  537                  { "inDataUnorderBytes", KSTAT_DATA_UINT32, 0 },
 487  538                  { "inDataDupSegs",      KSTAT_DATA_UINT32, 0 },
 488  539                  { "inDataDupBytes",     KSTAT_DATA_UINT32, 0 },
 489  540                  { "inDataPartDupSegs",  KSTAT_DATA_UINT32, 0 },
 490  541                  { "inDataPartDupBytes", KSTAT_DATA_UINT32, 0 },
 491  542                  { "inDataPastWinSegs",  KSTAT_DATA_UINT32, 0 },
 492  543                  { "inDataPastWinBytes", KSTAT_DATA_UINT32, 0 },
 493  544                  { "inWinProbe",         KSTAT_DATA_UINT32, 0 },
 494  545                  { "inWinUpdate",        KSTAT_DATA_UINT32, 0 },
 495  546                  { "inClosed",           KSTAT_DATA_UINT32, 0 },
 496  547                  { "rttUpdate",          KSTAT_DATA_UINT32, 0 },
 497  548                  { "rttNoUpdate",        KSTAT_DATA_UINT32, 0 },
 498  549                  { "timRetrans",         KSTAT_DATA_UINT32, 0 },
 499  550                  { "timRetransDrop",     KSTAT_DATA_UINT32, 0 },
 500  551                  { "timKeepalive",       KSTAT_DATA_UINT32, 0 },
 501  552                  { "timKeepaliveProbe",  KSTAT_DATA_UINT32, 0 },
 502  553                  { "timKeepaliveDrop",   KSTAT_DATA_UINT32, 0 },
 503  554                  { "listenDrop",         KSTAT_DATA_UINT32, 0 },
 504  555                  { "listenDropQ0",       KSTAT_DATA_UINT32, 0 },
 505  556                  { "halfOpenDrop",       KSTAT_DATA_UINT32, 0 },
 506  557                  { "outSackRetransSegs", KSTAT_DATA_UINT32, 0 },
 507  558                  { "connTableSize6",     KSTAT_DATA_INT32, 0 }
 508  559          };
 509  560  
 510  561          ksp = kstat_create_netstack(TCP_MOD_NAME, stackid, TCP_MOD_NAME, "mib2",
 511  562              KSTAT_TYPE_NAMED, NUM_OF_FIELDS(tcp_named_kstat_t), 0, stackid);
 512  563  
 513  564          if (ksp == NULL)
 514  565                  return (NULL);
 515  566  
 516  567          template.rtoAlgorithm.value.ui32 = 4;
 517  568          template.maxConn.value.i32 = -1;
 518  569  
 519  570          bcopy(&template, ksp->ks_data, sizeof (template));
 520  571          ksp->ks_update = tcp_kstat_update;
 521  572          ksp->ks_private = (void *)(uintptr_t)stackid;
 522  573  
 523  574          /*
 524  575           * If this is an exclusive netstack for a local zone, the global zone
 525  576           * should still be able to read the kstat.
 526  577           */
 527  578          if (stackid != GLOBAL_NETSTACKID)
 528  579                  kstat_zone_add(ksp, GLOBAL_ZONEID);
 529  580  
 530  581          kstat_install(ksp);
 531  582          return (ksp);
 532  583  }
 533  584  
 534  585  void
 535  586  tcp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
 536  587  {
 537  588          if (ksp != NULL) {
 538  589                  ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
 539  590                  kstat_delete_netstack(ksp, stackid);
 540  591          }
 541  592  }
 542  593  
 543  594  static int
 544  595  tcp_kstat_update(kstat_t *kp, int rw)
 545  596  {
 546  597          tcp_named_kstat_t *tcpkp;
 547  598          tcp_t           *tcp;
 548  599          connf_t         *connfp;
 549  600          conn_t          *connp;
 550  601          int             i;
 551  602          netstackid_t    stackid = (netstackid_t)(uintptr_t)kp->ks_private;
 552  603          netstack_t      *ns;
 553  604          tcp_stack_t     *tcps;
 554  605          ip_stack_t      *ipst;
 555  606          mib2_tcp_t      tcp_mib;
 556  607  
 557  608          if (rw == KSTAT_WRITE)
 558  609                  return (EACCES);
 559  610  
 560  611          ns = netstack_find_by_stackid(stackid);
 561  612          if (ns == NULL)
 562  613                  return (-1);
 563  614          tcps = ns->netstack_tcp;
 564  615          if (tcps == NULL) {
 565  616                  netstack_rele(ns);
 566  617                  return (-1);
 567  618          }
 568  619  
 569  620          tcpkp = (tcp_named_kstat_t *)kp->ks_data;
 570  621  
 571  622          tcpkp->currEstab.value.ui32 = 0;
 572  623          tcpkp->rtoMin.value.ui32 = tcps->tcps_rexmit_interval_min;
 573  624          tcpkp->rtoMax.value.ui32 = tcps->tcps_rexmit_interval_max;
 574  625  
 575  626          ipst = ns->netstack_ip;
 576  627  
 577  628          for (i = 0; i < CONN_G_HASH_SIZE; i++) {
 578  629                  connfp = &ipst->ips_ipcl_globalhash_fanout[i];
 579  630                  connp = NULL;
 580  631                  while ((connp =
 581  632                      ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
 582  633                          tcp = connp->conn_tcp;
 583  634                          switch (tcp_snmp_state(tcp)) {
 584  635                          case MIB2_TCP_established:
 585  636                          case MIB2_TCP_closeWait:
 586  637                                  tcpkp->currEstab.value.ui32++;
 587  638                                  break;
 588  639                          }
 589  640                  }
 590  641          }
 591  642          bzero(&tcp_mib, sizeof (tcp_mib));
 592  643          tcp_sum_mib(tcps, &tcp_mib);
 593  644  
 594  645          /* Fixed length structure for IPv4 and IPv6 counters */
 595  646          SET_MIB(tcp_mib.tcpConnTableSize, sizeof (mib2_tcpConnEntry_t));
 596  647          SET_MIB(tcp_mib.tcp6ConnTableSize, sizeof (mib2_tcp6ConnEntry_t));
 597  648  
 598  649          tcpkp->activeOpens.value.ui32 = tcp_mib.tcpActiveOpens;
 599  650          tcpkp->passiveOpens.value.ui32 = tcp_mib.tcpPassiveOpens;
 600  651          tcpkp->attemptFails.value.ui32 = tcp_mib.tcpAttemptFails;
 601  652          tcpkp->estabResets.value.ui32 = tcp_mib.tcpEstabResets;
 602  653          tcpkp->inSegs.value.ui64 = tcp_mib.tcpHCInSegs;
 603  654          tcpkp->outSegs.value.ui64 = tcp_mib.tcpHCOutSegs;
 604  655          tcpkp->retransSegs.value.ui32 = tcp_mib.tcpRetransSegs;
 605  656          tcpkp->connTableSize.value.i32 = tcp_mib.tcpConnTableSize;
 606  657          tcpkp->outRsts.value.ui32 = tcp_mib.tcpOutRsts;
 607  658          tcpkp->outDataSegs.value.ui32 = tcp_mib.tcpOutDataSegs;
 608  659          tcpkp->outDataBytes.value.ui32 = tcp_mib.tcpOutDataBytes;
 609  660          tcpkp->retransBytes.value.ui32 = tcp_mib.tcpRetransBytes;
 610  661          tcpkp->outAck.value.ui32 = tcp_mib.tcpOutAck;
 611  662          tcpkp->outAckDelayed.value.ui32 = tcp_mib.tcpOutAckDelayed;
 612  663          tcpkp->outUrg.value.ui32 = tcp_mib.tcpOutUrg;
 613  664          tcpkp->outWinUpdate.value.ui32 = tcp_mib.tcpOutWinUpdate;
 614  665          tcpkp->outWinProbe.value.ui32 = tcp_mib.tcpOutWinProbe;
 615  666          tcpkp->outControl.value.ui32 = tcp_mib.tcpOutControl;
 616  667          tcpkp->outFastRetrans.value.ui32 = tcp_mib.tcpOutFastRetrans;
 617  668          tcpkp->inAckSegs.value.ui32 = tcp_mib.tcpInAckSegs;
 618  669          tcpkp->inAckBytes.value.ui32 = tcp_mib.tcpInAckBytes;
 619  670          tcpkp->inDupAck.value.ui32 = tcp_mib.tcpInDupAck;
 620  671          tcpkp->inAckUnsent.value.ui32 = tcp_mib.tcpInAckUnsent;
 621  672          tcpkp->inDataInorderSegs.value.ui32 = tcp_mib.tcpInDataInorderSegs;
 622  673          tcpkp->inDataInorderBytes.value.ui32 = tcp_mib.tcpInDataInorderBytes;
 623  674          tcpkp->inDataUnorderSegs.value.ui32 = tcp_mib.tcpInDataUnorderSegs;
 624  675          tcpkp->inDataUnorderBytes.value.ui32 = tcp_mib.tcpInDataUnorderBytes;
 625  676          tcpkp->inDataDupSegs.value.ui32 = tcp_mib.tcpInDataDupSegs;
 626  677          tcpkp->inDataDupBytes.value.ui32 = tcp_mib.tcpInDataDupBytes;
 627  678          tcpkp->inDataPartDupSegs.value.ui32 = tcp_mib.tcpInDataPartDupSegs;
 628  679          tcpkp->inDataPartDupBytes.value.ui32 = tcp_mib.tcpInDataPartDupBytes;
 629  680          tcpkp->inDataPastWinSegs.value.ui32 = tcp_mib.tcpInDataPastWinSegs;
 630  681          tcpkp->inDataPastWinBytes.value.ui32 = tcp_mib.tcpInDataPastWinBytes;
 631  682          tcpkp->inWinProbe.value.ui32 = tcp_mib.tcpInWinProbe;
 632  683          tcpkp->inWinUpdate.value.ui32 = tcp_mib.tcpInWinUpdate;
 633  684          tcpkp->inClosed.value.ui32 = tcp_mib.tcpInClosed;
 634  685          tcpkp->rttNoUpdate.value.ui32 = tcp_mib.tcpRttNoUpdate;
 635  686          tcpkp->rttUpdate.value.ui32 = tcp_mib.tcpRttUpdate;
 636  687          tcpkp->timRetrans.value.ui32 = tcp_mib.tcpTimRetrans;
 637  688          tcpkp->timRetransDrop.value.ui32 = tcp_mib.tcpTimRetransDrop;
 638  689          tcpkp->timKeepalive.value.ui32 = tcp_mib.tcpTimKeepalive;
 639  690          tcpkp->timKeepaliveProbe.value.ui32 = tcp_mib.tcpTimKeepaliveProbe;
 640  691          tcpkp->timKeepaliveDrop.value.ui32 = tcp_mib.tcpTimKeepaliveDrop;
 641  692          tcpkp->listenDrop.value.ui32 = tcp_mib.tcpListenDrop;
 642  693          tcpkp->listenDropQ0.value.ui32 = tcp_mib.tcpListenDropQ0;
 643  694          tcpkp->halfOpenDrop.value.ui32 = tcp_mib.tcpHalfOpenDrop;
 644  695          tcpkp->outSackRetransSegs.value.ui32 = tcp_mib.tcpOutSackRetransSegs;
 645  696          tcpkp->connTableSize6.value.i32 = tcp_mib.tcp6ConnTableSize;
 646  697  
 647  698          netstack_rele(ns);
 648  699          return (0);
 649  700  }
 650  701  
 651  702  /*
 652  703   * kstats related to squeues i.e. not per IP instance
 653  704   */
 654  705  void *
 655  706  tcp_g_kstat_init(tcp_g_stat_t *tcp_g_statp)
 656  707  {
 657  708          kstat_t *ksp;
 658  709  
 659  710          tcp_g_stat_t template = {
 660  711                  { "tcp_timermp_alloced",        KSTAT_DATA_UINT64 },
 661  712                  { "tcp_timermp_allocfail",      KSTAT_DATA_UINT64 },
 662  713                  { "tcp_timermp_allocdblfail",   KSTAT_DATA_UINT64 },
 663  714                  { "tcp_freelist_cleanup",       KSTAT_DATA_UINT64 },
 664  715          };
 665  716  
 666  717          ksp = kstat_create(TCP_MOD_NAME, 0, "tcpstat_g", "net",
 667  718              KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t),
 668  719              KSTAT_FLAG_VIRTUAL);
 669  720  
 670  721          if (ksp == NULL)
 671  722                  return (NULL);
 672  723  
 673  724          bcopy(&template, tcp_g_statp, sizeof (template));
 674  725          ksp->ks_data = (void *)tcp_g_statp;
 675  726  
 676  727          kstat_install(ksp);
 677  728          return (ksp);
 678  729  }
 679  730  
 680  731  void
 681  732  tcp_g_kstat_fini(kstat_t *ksp)
 682  733  {
 683  734          if (ksp != NULL) {
 684  735                  kstat_delete(ksp);
 685  736          }
 686  737  }
 687  738  
 688  739  void *
 689  740  tcp_kstat2_init(netstackid_t stackid)
 690  741  {
 691  742          kstat_t *ksp;
 692  743  
 693  744          tcp_stat_t template = {
 694  745                  { "tcp_time_wait_syn_success",  KSTAT_DATA_UINT64, 0 },
 695  746                  { "tcp_clean_death_nondetached",        KSTAT_DATA_UINT64, 0 },
 696  747                  { "tcp_eager_blowoff_q",        KSTAT_DATA_UINT64, 0 },
 697  748                  { "tcp_eager_blowoff_q0",       KSTAT_DATA_UINT64, 0 },
 698  749                  { "tcp_no_listener",            KSTAT_DATA_UINT64, 0 },
 699  750                  { "tcp_listendrop",             KSTAT_DATA_UINT64, 0 },
 700  751                  { "tcp_listendropq0",           KSTAT_DATA_UINT64, 0 },
 701  752                  { "tcp_wsrv_called",            KSTAT_DATA_UINT64, 0 },
 702  753                  { "tcp_flwctl_on",              KSTAT_DATA_UINT64, 0 },
 703  754                  { "tcp_timer_fire_early",       KSTAT_DATA_UINT64, 0 },
 704  755                  { "tcp_timer_fire_miss",        KSTAT_DATA_UINT64, 0 },
 705  756                  { "tcp_zcopy_on",               KSTAT_DATA_UINT64, 0 },
 706  757                  { "tcp_zcopy_off",              KSTAT_DATA_UINT64, 0 },
 707  758                  { "tcp_zcopy_backoff",          KSTAT_DATA_UINT64, 0 },
 708  759                  { "tcp_fusion_flowctl",         KSTAT_DATA_UINT64, 0 },
 709  760                  { "tcp_fusion_backenabled",     KSTAT_DATA_UINT64, 0 },
 710  761                  { "tcp_fusion_urg",             KSTAT_DATA_UINT64, 0 },
 711  762                  { "tcp_fusion_putnext",         KSTAT_DATA_UINT64, 0 },
 712  763                  { "tcp_fusion_unfusable",       KSTAT_DATA_UINT64, 0 },
 713  764                  { "tcp_fusion_aborted",         KSTAT_DATA_UINT64, 0 },
 714  765                  { "tcp_fusion_unqualified",     KSTAT_DATA_UINT64, 0 },
 715  766                  { "tcp_fusion_rrw_busy",        KSTAT_DATA_UINT64, 0 },
 716  767                  { "tcp_fusion_rrw_msgcnt",      KSTAT_DATA_UINT64, 0 },
 717  768                  { "tcp_fusion_rrw_plugged",     KSTAT_DATA_UINT64, 0 },
 718  769                  { "tcp_in_ack_unsent_drop",     KSTAT_DATA_UINT64, 0 },
 719  770                  { "tcp_sock_fallback",          KSTAT_DATA_UINT64, 0 },
 720  771                  { "tcp_lso_enabled",            KSTAT_DATA_UINT64, 0 },
 721  772                  { "tcp_lso_disabled",           KSTAT_DATA_UINT64, 0 },
 722  773                  { "tcp_lso_times",              KSTAT_DATA_UINT64, 0 },
 723  774                  { "tcp_lso_pkt_out",            KSTAT_DATA_UINT64, 0 },
 724  775                  { "tcp_listen_cnt_drop",        KSTAT_DATA_UINT64, 0 },
 725  776                  { "tcp_listen_mem_drop",        KSTAT_DATA_UINT64, 0 },
 726  777                  { "tcp_zwin_mem_drop",          KSTAT_DATA_UINT64, 0 },
 727  778                  { "tcp_zwin_ack_syn",           KSTAT_DATA_UINT64, 0 },
 728  779                  { "tcp_rst_unsent",             KSTAT_DATA_UINT64, 0 },
 729  780                  { "tcp_reclaim_cnt",            KSTAT_DATA_UINT64, 0 },
 730  781                  { "tcp_reass_timeout",          KSTAT_DATA_UINT64, 0 },
 731  782  #ifdef TCP_DEBUG_COUNTER
 732  783                  { "tcp_time_wait",              KSTAT_DATA_UINT64, 0 },
 733  784                  { "tcp_rput_time_wait",         KSTAT_DATA_UINT64, 0 },
 734  785                  { "tcp_detach_time_wait",       KSTAT_DATA_UINT64, 0 },
 735  786                  { "tcp_timeout_calls",          KSTAT_DATA_UINT64, 0 },
 736  787                  { "tcp_timeout_cached_alloc",   KSTAT_DATA_UINT64, 0 },
 737  788                  { "tcp_timeout_cancel_reqs",    KSTAT_DATA_UINT64, 0 },
 738  789                  { "tcp_timeout_canceled",       KSTAT_DATA_UINT64, 0 },
 739  790                  { "tcp_timermp_freed",          KSTAT_DATA_UINT64, 0 },
 740  791                  { "tcp_push_timer_cnt",         KSTAT_DATA_UINT64, 0 },
 741  792                  { "tcp_ack_timer_cnt",          KSTAT_DATA_UINT64, 0 },
 742  793  #endif
 743  794          };
 744  795  
 745  796          ksp = kstat_create_netstack(TCP_MOD_NAME, stackid, "tcpstat", "net",
 746  797              KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t), 0,
 747  798              stackid);
 748  799  
 749  800          if (ksp == NULL)
 750  801                  return (NULL);
 751  802  
 752  803          bcopy(&template, ksp->ks_data, sizeof (template));
 753  804          ksp->ks_private = (void *)(uintptr_t)stackid;
 754  805          ksp->ks_update = tcp_kstat2_update;
 755  806  
 756  807          /*
 757  808           * If this is an exclusive netstack for a local zone, the global zone
 758  809           * should still be able to read the kstat.
 759  810           */
 760  811          if (stackid != GLOBAL_NETSTACKID)
 761  812                  kstat_zone_add(ksp, GLOBAL_ZONEID);
 762  813  
 763  814          kstat_install(ksp);
 764  815          return (ksp);
 765  816  }
 766  817  
 767  818  void
 768  819  tcp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
 769  820  {
 770  821          if (ksp != NULL) {
 771  822                  ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
 772  823                  kstat_delete_netstack(ksp, stackid);
 773  824          }
 774  825  }
 775  826  
 776  827  /*
 777  828   * Sum up all per CPU tcp_stat_t kstat counters.
 778  829   */
 779  830  static int
 780  831  tcp_kstat2_update(kstat_t *kp, int rw)
 781  832  {
 782  833          netstackid_t    stackid = (netstackid_t)(uintptr_t)kp->ks_private;
 783  834          netstack_t      *ns;
 784  835          tcp_stack_t     *tcps;
 785  836          tcp_stat_t      *stats;
 786  837          int             i;
 787  838          int             cnt;
 788  839  
 789  840          if (rw == KSTAT_WRITE)
 790  841                  return (EACCES);
 791  842  
 792  843          ns = netstack_find_by_stackid(stackid);
 793  844          if (ns == NULL)
 794  845                  return (-1);
 795  846          tcps = ns->netstack_tcp;
 796  847          if (tcps == NULL) {
 797  848                  netstack_rele(ns);
 798  849                  return (-1);
 799  850          }
 800  851  
 801  852          stats = (tcp_stat_t *)kp->ks_data;
 802  853          tcp_clr_stats(stats);
 803  854  
 804  855          /*
 805  856           * tcps_sc_cnt may change in the middle of the loop.  It is better
 806  857           * to get its value first.
 807  858           */
 808  859          cnt = tcps->tcps_sc_cnt;
 809  860          for (i = 0; i < cnt; i++)
 810  861                  tcp_add_stats(&tcps->tcps_sc[i]->tcp_sc_stats, stats);
 811  862  
 812  863          netstack_rele(ns);
 813  864          return (0);
 814  865  }
 815  866  
 816  867  /*
 817  868   * To add stats from one mib2_tcp_t to another.  Static fields are not added.
 818  869   * The caller should set them up propertly.
 819  870   */
 820  871  static void
 821  872  tcp_add_mib(mib2_tcp_t *from, mib2_tcp_t *to)
 822  873  {
 823  874          to->tcpActiveOpens += from->tcpActiveOpens;
 824  875          to->tcpPassiveOpens += from->tcpPassiveOpens;
 825  876          to->tcpAttemptFails += from->tcpAttemptFails;
 826  877          to->tcpEstabResets += from->tcpEstabResets;
 827  878          to->tcpInSegs += from->tcpInSegs;
 828  879          to->tcpOutSegs += from->tcpOutSegs;
 829  880          to->tcpRetransSegs += from->tcpRetransSegs;
 830  881          to->tcpOutRsts += from->tcpOutRsts;
 831  882  
 832  883          to->tcpOutDataSegs += from->tcpOutDataSegs;
 833  884          to->tcpOutDataBytes += from->tcpOutDataBytes;
 834  885          to->tcpRetransBytes += from->tcpRetransBytes;
 835  886          to->tcpOutAck += from->tcpOutAck;
 836  887          to->tcpOutAckDelayed += from->tcpOutAckDelayed;
 837  888          to->tcpOutUrg += from->tcpOutUrg;
 838  889          to->tcpOutWinUpdate += from->tcpOutWinUpdate;
 839  890          to->tcpOutWinProbe += from->tcpOutWinProbe;
 840  891          to->tcpOutControl += from->tcpOutControl;
 841  892          to->tcpOutFastRetrans += from->tcpOutFastRetrans;
 842  893  
 843  894          to->tcpInAckBytes += from->tcpInAckBytes;
 844  895          to->tcpInDupAck += from->tcpInDupAck;
 845  896          to->tcpInAckUnsent += from->tcpInAckUnsent;
 846  897          to->tcpInDataInorderSegs += from->tcpInDataInorderSegs;
 847  898          to->tcpInDataInorderBytes += from->tcpInDataInorderBytes;
 848  899          to->tcpInDataUnorderSegs += from->tcpInDataUnorderSegs;
 849  900          to->tcpInDataUnorderBytes += from->tcpInDataUnorderBytes;
 850  901          to->tcpInDataDupSegs += from->tcpInDataDupSegs;
 851  902          to->tcpInDataDupBytes += from->tcpInDataDupBytes;
 852  903          to->tcpInDataPartDupSegs += from->tcpInDataPartDupSegs;
 853  904          to->tcpInDataPartDupBytes += from->tcpInDataPartDupBytes;
 854  905          to->tcpInDataPastWinSegs += from->tcpInDataPastWinSegs;
 855  906          to->tcpInDataPastWinBytes += from->tcpInDataPastWinBytes;
 856  907          to->tcpInWinProbe += from->tcpInWinProbe;
 857  908          to->tcpInWinUpdate += from->tcpInWinUpdate;
 858  909          to->tcpInClosed += from->tcpInClosed;
 859  910  
 860  911          to->tcpRttNoUpdate += from->tcpRttNoUpdate;
 861  912          to->tcpRttUpdate += from->tcpRttUpdate;
 862  913          to->tcpTimRetrans += from->tcpTimRetrans;
 863  914          to->tcpTimRetransDrop += from->tcpTimRetransDrop;
 864  915          to->tcpTimKeepalive += from->tcpTimKeepalive;
 865  916          to->tcpTimKeepaliveProbe += from->tcpTimKeepaliveProbe;
 866  917          to->tcpTimKeepaliveDrop += from->tcpTimKeepaliveDrop;
 867  918          to->tcpListenDrop += from->tcpListenDrop;
 868  919          to->tcpListenDropQ0 += from->tcpListenDropQ0;
 869  920          to->tcpHalfOpenDrop += from->tcpHalfOpenDrop;
 870  921          to->tcpOutSackRetransSegs += from->tcpOutSackRetransSegs;
 871  922          to->tcpHCInSegs += from->tcpHCInSegs;
 872  923          to->tcpHCOutSegs += from->tcpHCOutSegs;
 873  924  }
 874  925  
 875  926  /*
 876  927   * To sum up all MIB2 stats for a tcp_stack_t from all per CPU stats.  The
 877  928   * caller should initialize the target mib2_tcp_t properly as this function
 878  929   * just adds up all the per CPU stats.
 879  930   */
 880  931  static void
 881  932  tcp_sum_mib(tcp_stack_t *tcps, mib2_tcp_t *tcp_mib)
 882  933  {
 883  934          int i;
 884  935          int cnt;
 885  936  
 886  937          /*
 887  938           * tcps_sc_cnt may change in the middle of the loop.  It is better
 888  939           * to get its value first.
 889  940           */
 890  941          cnt = tcps->tcps_sc_cnt;
 891  942          for (i = 0; i < cnt; i++)
 892  943                  tcp_add_mib(&tcps->tcps_sc[i]->tcp_sc_mib, tcp_mib);
 893  944  }
 894  945  
 895  946  /*
 896  947   * To set all tcp_stat_t counters to 0.
 897  948   */
 898  949  static void
 899  950  tcp_clr_stats(tcp_stat_t *stats)
 900  951  {
 901  952          stats->tcp_time_wait_syn_success.value.ui64 = 0;
 902  953          stats->tcp_clean_death_nondetached.value.ui64 = 0;
 903  954          stats->tcp_eager_blowoff_q.value.ui64 = 0;
 904  955          stats->tcp_eager_blowoff_q0.value.ui64 = 0;
 905  956          stats->tcp_no_listener.value.ui64 = 0;
 906  957          stats->tcp_listendrop.value.ui64 = 0;
 907  958          stats->tcp_listendropq0.value.ui64 = 0;
 908  959          stats->tcp_wsrv_called.value.ui64 = 0;
 909  960          stats->tcp_flwctl_on.value.ui64 = 0;
 910  961          stats->tcp_timer_fire_early.value.ui64 = 0;
 911  962          stats->tcp_timer_fire_miss.value.ui64 = 0;
 912  963          stats->tcp_zcopy_on.value.ui64 = 0;
 913  964          stats->tcp_zcopy_off.value.ui64 = 0;
 914  965          stats->tcp_zcopy_backoff.value.ui64 = 0;
 915  966          stats->tcp_fusion_flowctl.value.ui64 = 0;
 916  967          stats->tcp_fusion_backenabled.value.ui64 = 0;
 917  968          stats->tcp_fusion_urg.value.ui64 = 0;
 918  969          stats->tcp_fusion_putnext.value.ui64 = 0;
 919  970          stats->tcp_fusion_unfusable.value.ui64 = 0;
 920  971          stats->tcp_fusion_aborted.value.ui64 = 0;
 921  972          stats->tcp_fusion_unqualified.value.ui64 = 0;
 922  973          stats->tcp_fusion_rrw_busy.value.ui64 = 0;
 923  974          stats->tcp_fusion_rrw_msgcnt.value.ui64 = 0;
 924  975          stats->tcp_fusion_rrw_plugged.value.ui64 = 0;
 925  976          stats->tcp_in_ack_unsent_drop.value.ui64 = 0;
 926  977          stats->tcp_sock_fallback.value.ui64 = 0;
 927  978          stats->tcp_lso_enabled.value.ui64 = 0;
 928  979          stats->tcp_lso_disabled.value.ui64 = 0;
 929  980          stats->tcp_lso_times.value.ui64 = 0;
 930  981          stats->tcp_lso_pkt_out.value.ui64 = 0;
 931  982          stats->tcp_listen_cnt_drop.value.ui64 = 0;
 932  983          stats->tcp_listen_mem_drop.value.ui64 = 0;
 933  984          stats->tcp_zwin_mem_drop.value.ui64 = 0;
 934  985          stats->tcp_zwin_ack_syn.value.ui64 = 0;
 935  986          stats->tcp_rst_unsent.value.ui64 = 0;
 936  987          stats->tcp_reclaim_cnt.value.ui64 = 0;
 937  988          stats->tcp_reass_timeout.value.ui64 = 0;
 938  989  
 939  990  #ifdef TCP_DEBUG_COUNTER
 940  991          stats->tcp_time_wait.value.ui64 = 0;
 941  992          stats->tcp_rput_time_wait.value.ui64 = 0;
 942  993          stats->tcp_detach_time_wait.value.ui64 = 0;
 943  994          stats->tcp_timeout_calls.value.ui64 = 0;
 944  995          stats->tcp_timeout_cached_alloc.value.ui64 = 0;
 945  996          stats->tcp_timeout_cancel_reqs.value.ui64 = 0;
 946  997          stats->tcp_timeout_canceled.value.ui64 = 0;
 947  998          stats->tcp_timermp_freed.value.ui64 = 0;
 948  999          stats->tcp_push_timer_cnt.value.ui64 = 0;
 949 1000          stats->tcp_ack_timer_cnt.value.ui64 = 0;
 950 1001  #endif
 951 1002  }
 952 1003  
 953 1004  /*
 954 1005   * To add counters from the per CPU tcp_stat_counter_t to the stack
 955 1006   * tcp_stat_t.
 956 1007   */
 957 1008  static void
 958 1009  tcp_add_stats(tcp_stat_counter_t *from, tcp_stat_t *to)
 959 1010  {
 960 1011          to->tcp_time_wait_syn_success.value.ui64 +=
 961 1012              from->tcp_time_wait_syn_success;
 962 1013          to->tcp_clean_death_nondetached.value.ui64 +=
 963 1014              from->tcp_clean_death_nondetached;
 964 1015          to->tcp_eager_blowoff_q.value.ui64 +=
 965 1016              from->tcp_eager_blowoff_q;
 966 1017          to->tcp_eager_blowoff_q0.value.ui64 +=
 967 1018              from->tcp_eager_blowoff_q0;
 968 1019          to->tcp_no_listener.value.ui64 +=
 969 1020              from->tcp_no_listener;
 970 1021          to->tcp_listendrop.value.ui64 +=
 971 1022              from->tcp_listendrop;
 972 1023          to->tcp_listendropq0.value.ui64 +=
 973 1024              from->tcp_listendropq0;
 974 1025          to->tcp_wsrv_called.value.ui64 +=
 975 1026              from->tcp_wsrv_called;
 976 1027          to->tcp_flwctl_on.value.ui64 +=
 977 1028              from->tcp_flwctl_on;
 978 1029          to->tcp_timer_fire_early.value.ui64 +=
 979 1030              from->tcp_timer_fire_early;
 980 1031          to->tcp_timer_fire_miss.value.ui64 +=
 981 1032              from->tcp_timer_fire_miss;
 982 1033          to->tcp_zcopy_on.value.ui64 +=
 983 1034              from->tcp_zcopy_on;
 984 1035          to->tcp_zcopy_off.value.ui64 +=
 985 1036              from->tcp_zcopy_off;
 986 1037          to->tcp_zcopy_backoff.value.ui64 +=
 987 1038              from->tcp_zcopy_backoff;
 988 1039          to->tcp_fusion_flowctl.value.ui64 +=
 989 1040              from->tcp_fusion_flowctl;
 990 1041          to->tcp_fusion_backenabled.value.ui64 +=
 991 1042              from->tcp_fusion_backenabled;
 992 1043          to->tcp_fusion_urg.value.ui64 +=
 993 1044              from->tcp_fusion_urg;
 994 1045          to->tcp_fusion_putnext.value.ui64 +=
 995 1046              from->tcp_fusion_putnext;
 996 1047          to->tcp_fusion_unfusable.value.ui64 +=
 997 1048              from->tcp_fusion_unfusable;
 998 1049          to->tcp_fusion_aborted.value.ui64 +=
 999 1050              from->tcp_fusion_aborted;
1000 1051          to->tcp_fusion_unqualified.value.ui64 +=
1001 1052              from->tcp_fusion_unqualified;
1002 1053          to->tcp_fusion_rrw_busy.value.ui64 +=
1003 1054              from->tcp_fusion_rrw_busy;
1004 1055          to->tcp_fusion_rrw_msgcnt.value.ui64 +=
1005 1056              from->tcp_fusion_rrw_msgcnt;
1006 1057          to->tcp_fusion_rrw_plugged.value.ui64 +=
1007 1058              from->tcp_fusion_rrw_plugged;
1008 1059          to->tcp_in_ack_unsent_drop.value.ui64 +=
1009 1060              from->tcp_in_ack_unsent_drop;
1010 1061          to->tcp_sock_fallback.value.ui64 +=
1011 1062              from->tcp_sock_fallback;
1012 1063          to->tcp_lso_enabled.value.ui64 +=
1013 1064              from->tcp_lso_enabled;
1014 1065          to->tcp_lso_disabled.value.ui64 +=
1015 1066              from->tcp_lso_disabled;
1016 1067          to->tcp_lso_times.value.ui64 +=
1017 1068              from->tcp_lso_times;
1018 1069          to->tcp_lso_pkt_out.value.ui64 +=
1019 1070              from->tcp_lso_pkt_out;
1020 1071          to->tcp_listen_cnt_drop.value.ui64 +=
1021 1072              from->tcp_listen_cnt_drop;
1022 1073          to->tcp_listen_mem_drop.value.ui64 +=
1023 1074              from->tcp_listen_mem_drop;
1024 1075          to->tcp_zwin_mem_drop.value.ui64 +=
1025 1076              from->tcp_zwin_mem_drop;
1026 1077          to->tcp_zwin_ack_syn.value.ui64 +=
1027 1078              from->tcp_zwin_ack_syn;
1028 1079          to->tcp_rst_unsent.value.ui64 +=
1029 1080              from->tcp_rst_unsent;
1030 1081          to->tcp_reclaim_cnt.value.ui64 +=
1031 1082              from->tcp_reclaim_cnt;
1032 1083          to->tcp_reass_timeout.value.ui64 +=
1033 1084              from->tcp_reass_timeout;
1034 1085  
1035 1086  #ifdef TCP_DEBUG_COUNTER
1036 1087          to->tcp_time_wait.value.ui64 +=
1037 1088              from->tcp_time_wait;
1038 1089          to->tcp_rput_time_wait.value.ui64 +=
1039 1090              from->tcp_rput_time_wait;
1040 1091          to->tcp_detach_time_wait.value.ui64 +=
1041 1092              from->tcp_detach_time_wait;
1042 1093          to->tcp_timeout_calls.value.ui64 +=
1043 1094              from->tcp_timeout_calls;
1044 1095          to->tcp_timeout_cached_alloc.value.ui64 +=
1045 1096              from->tcp_timeout_cached_alloc;
1046 1097          to->tcp_timeout_cancel_reqs.value.ui64 +=
1047 1098              from->tcp_timeout_cancel_reqs;
1048 1099          to->tcp_timeout_canceled.value.ui64 +=
1049 1100              from->tcp_timeout_canceled;
1050 1101          to->tcp_timermp_freed.value.ui64 +=
1051 1102              from->tcp_timermp_freed;
1052 1103          to->tcp_push_timer_cnt.value.ui64 +=
1053 1104              from->tcp_push_timer_cnt;
1054 1105          to->tcp_ack_timer_cnt.value.ui64 +=
1055 1106              from->tcp_ack_timer_cnt;
1056 1107  #endif
1057 1108  }
  
    | ↓ open down ↓ | 628 lines elided | ↑ open up ↑ | 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX