Print this page
DLPX-25998 TCP congestion control is inadequate
Reviewed at: http://reviews.delphix.com/r/34808/
@@ -18,11 +18,11 @@
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
*/
/*
* This file contains routines that are used to modify/retrieve protocol or
* interface property values. It also holds all the supported properties for
@@ -38,10 +38,12 @@
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <strings.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/sockio.h>
#include <assert.h>
#include <libdllink.h>
@@ -65,11 +67,12 @@
* a given property.
*/
static ipadm_pd_getf_t i_ipadm_get_prop, i_ipadm_get_ifprop_flags,
i_ipadm_get_mtu, i_ipadm_get_metric,
i_ipadm_get_usesrc, i_ipadm_get_forwarding,
- i_ipadm_get_ecnsack, i_ipadm_get_hostmodel;
+ i_ipadm_get_ecnsack, i_ipadm_get_hostmodel,
+ i_ipadm_get_cc;
/*
* Callback function to set property values. These functions translate the
* values to a format suitable for kernel consumption, allocates the necessary
* ioctl buffers and then invokes ioctl().
@@ -151,10 +154,13 @@
/* possible values for TCP properties `ecn' and `sack' */
static const char *ecn_sack_vals[] = {"never", "passive", "active", NULL};
/* Supported TCP protocol properties */
static ipadm_prop_desc_t ipadm_tcp_prop_table[] = {
+ { "congestion_control", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
+ i_ipadm_set_prop, i_ipadm_get_cc, i_ipadm_get_prop },
+
{ "ecn", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack },
{ "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP,
IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
@@ -810,10 +816,46 @@
}
return (status);
}
+/*
+ * Retrieves the list of possible congestion control algorithms by enumerating
+ * the modules in /kernel/cc.
+ */
+/* ARGSUSED */
+ipadm_status_t
+i_ipadm_get_cc(ipadm_handle_t iph, const void *arg, ipadm_prop_desc_t *pdp,
+ char *buf, uint_t *bufsize, uint_t proto, uint_t valtype)
+{
+ DIR *dir;
+ struct dirent *ent;
+ boolean_t first = B_TRUE;
+ uint_t bytes = 0;
+
+ assert(valtype == MOD_PROP_POSSIBLE);
+
+ /* We assume that all platforms have the same algorithms installed. */
+ if ((dir = opendir("/kernel/cc")) != NULL) {
+ while ((ent = readdir(dir)) != NULL) {
+ /* By convention, modules are named cc_<algo>. */
+ if (strstr(ent->d_name, "cc_") != NULL) {
+ bytes += snprintf(buf + bytes,
+ bytes < *bufsize ? *bufsize - bytes : 0,
+ "%s%s", first ? "" : ",", ent->d_name + 3);
+ first = B_FALSE;
+ }
+ }
+ (void) closedir(dir);
+ }
+ if (bytes >= *bufsize) {
+ *bufsize = bytes + 1;
+ return (IPADM_NO_BUFS);
+ }
+ return (IPADM_SUCCESS);
+}
+
/* ARGSUSED */
static ipadm_status_t
i_ipadm_get_forwarding(ipadm_handle_t iph, const void *arg,
ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto,
uint_t valtype)