Print this page
DLPX-25998 TCP congestion control is inadequate
Reviewed at: http://reviews.delphix.com/r/34808/

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libipadm/common/ipadm_prop.c
          +++ new/usr/src/lib/libipadm/common/ipadm_prop.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  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   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright (c) 2013 by Delphix. All rights reserved.
       23 + * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27   27   * This file contains routines that are used to modify/retrieve protocol or
  28   28   * interface property values. It also holds all the supported properties for
  29   29   * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
  30   30   * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP.
  31   31   *
  32   32   * This file also contains walkers, which walks through the property table and
  33   33   * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
  34   34   * property in the table.
  35   35   */
  36   36  
  37   37  #include <unistd.h>
  38   38  #include <errno.h>
  39   39  #include <ctype.h>
  40   40  #include <fcntl.h>
  41   41  #include <strings.h>
  42   42  #include <stdlib.h>
       43 +#include <sys/types.h>
       44 +#include <dirent.h>
  43   45  #include <netinet/in.h>
  44   46  #include <arpa/inet.h>
  45   47  #include <sys/sockio.h>
  46   48  #include <assert.h>
  47   49  #include <libdllink.h>
  48   50  #include <zone.h>
  49   51  #include "libipadm_impl.h"
  50   52  #include <inet/tunables.h>
  51   53  
  52   54  #define IPADM_NONESTR           "none"
↓ open down ↓ 7 lines elided ↑ open up ↑
  60   62  /*
  61   63   * Callback functions to retrieve property values from the kernel. These
  62   64   * functions, when required, translate the values from the kernel to a format
  63   65   * suitable for printing. For example: boolean values will be translated
  64   66   * to on/off. They also retrieve DEFAULT, PERM and POSSIBLE values for
  65   67   * a given property.
  66   68   */
  67   69  static ipadm_pd_getf_t  i_ipadm_get_prop, i_ipadm_get_ifprop_flags,
  68   70                          i_ipadm_get_mtu, i_ipadm_get_metric,
  69   71                          i_ipadm_get_usesrc, i_ipadm_get_forwarding,
  70      -                        i_ipadm_get_ecnsack, i_ipadm_get_hostmodel;
       72 +                        i_ipadm_get_ecnsack, i_ipadm_get_hostmodel,
       73 +                        i_ipadm_get_cc;
  71   74  
  72   75  /*
  73   76   * Callback function to set property values. These functions translate the
  74   77   * values to a format suitable for kernel consumption, allocates the necessary
  75   78   * ioctl buffers and then invokes ioctl().
  76   79   */
  77   80  static ipadm_pd_setf_t  i_ipadm_set_prop, i_ipadm_set_mtu,
  78   81                          i_ipadm_set_ifprop_flags,
  79   82                          i_ipadm_set_metric, i_ipadm_set_usesrc,
  80   83                          i_ipadm_set_forwarding, i_ipadm_set_eprivport,
↓ open down ↓ 65 lines elided ↑ open up ↑
 146  149              i_ipadm_get_hostmodel },
 147  150  
 148  151          { NULL, NULL, 0, 0, 0, NULL, NULL, NULL }
 149  152  };
 150  153  
 151  154  /* possible values for TCP properties `ecn' and `sack' */
 152  155  static const char *ecn_sack_vals[] = {"never", "passive", "active", NULL};
 153  156  
 154  157  /* Supported TCP protocol properties */
 155  158  static ipadm_prop_desc_t ipadm_tcp_prop_table[] = {
      159 +        { "congestion_control", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
      160 +            i_ipadm_set_prop, i_ipadm_get_cc, i_ipadm_get_prop },
      161 +
 156  162          { "ecn", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 157  163              i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack },
 158  164  
 159  165          { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP,
 160  166              IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
 161  167              i_ipadm_get_prop },
 162  168  
 163  169          { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 164  170              i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
 165  171  
↓ open down ↓ 639 lines elided ↑ open up ↑
 805  811          }
 806  812          if (nbytes >= *bufsize) {
 807  813                  /* insufficient buffer space */
 808  814                  *bufsize = nbytes + 1;
 809  815                  return (IPADM_NO_BUFS);
 810  816          }
 811  817  
 812  818          return (status);
 813  819  }
 814  820  
      821 +/*
      822 + * Retrieves the list of possible congestion control algorithms by enumerating
      823 + * the modules in /kernel/cc.
      824 + */
      825 +/* ARGSUSED */
      826 +ipadm_status_t
      827 +i_ipadm_get_cc(ipadm_handle_t iph, const void *arg, ipadm_prop_desc_t *pdp,
      828 +    char *buf, uint_t *bufsize, uint_t proto, uint_t valtype)
      829 +{
      830 +        DIR *dir;
      831 +        struct dirent *ent;
      832 +        boolean_t first = B_TRUE;
      833 +        uint_t bytes = 0;
      834 +
      835 +        assert(valtype == MOD_PROP_POSSIBLE);
      836 +
      837 +        /* We assume that all platforms have the same algorithms installed. */
      838 +        if ((dir = opendir("/kernel/cc")) != NULL) {
      839 +                while ((ent = readdir(dir)) != NULL) {
      840 +                        /* By convention, modules are named cc_<algo>. */
      841 +                        if (strstr(ent->d_name, "cc_") != NULL) {
      842 +                                bytes += snprintf(buf + bytes,
      843 +                                    bytes < *bufsize ? *bufsize - bytes : 0,
      844 +                                    "%s%s", first ? "" : ",", ent->d_name + 3);
      845 +                                first = B_FALSE;
      846 +                        }
      847 +                }
      848 +                (void) closedir(dir);
      849 +        }
      850 +        if (bytes >= *bufsize) {
      851 +                *bufsize = bytes + 1;
      852 +                return (IPADM_NO_BUFS);
      853 +        }
      854 +        return (IPADM_SUCCESS);
      855 +}
      856 +
 815  857  /* ARGSUSED */
 816  858  static ipadm_status_t
 817  859  i_ipadm_get_forwarding(ipadm_handle_t iph, const void *arg,
 818  860      ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto,
 819  861      uint_t valtype)
 820  862  {
 821  863          const char      *ifname = arg;
 822  864          ipadm_status_t  status = IPADM_SUCCESS;
 823  865  
 824  866          /*
↓ open down ↓ 1133 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX