summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-07-22 23:23:27 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2013-07-22 23:23:31 +0000
commitae90c942d8ffba880f1197d0fae961027144b251 (patch)
treef07d045010f504821f9a4ae5189f88adbc20882f
parentba5ba26a63657a8c15a464fc0a0c34a36a59a854 (diff)
parent7256a34efe9df75b638b9e812912ef7c5c68e208 (diff)
downloadillumos-joyent-ae90c942d8ffba880f1197d0fae961027144b251.tar.gz
[illumos-gate merge]
commit 7256a34efe9df75b638b9e812912ef7c5c68e208 3895 {tcp,udp}_{largest,smallest}_anon_port should reality-check
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_bind.c15
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_tunables.c45
-rw-r--r--usr/src/uts/common/inet/udp/udp.c16
-rw-r--r--usr/src/uts/common/inet/udp/udp_tunables.c45
4 files changed, 107 insertions, 14 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp_bind.c b/usr/src/uts/common/inet/tcp/tcp_bind.c
index 83a517e20c..c6df39b91e 100644
--- a/usr/src/uts/common/inet/tcp/tcp_bind.c
+++ b/usr/src/uts/common/inet/tcp/tcp_bind.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013, Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -212,7 +212,7 @@ tcp_bind_hash_remove(tcp_t *tcp)
in_port_t
tcp_update_next_port(in_port_t port, const tcp_t *tcp, boolean_t random)
{
- int i;
+ int i, bump;
boolean_t restart = B_FALSE;
tcp_stack_t *tcps = tcp->tcp_tcps;
@@ -230,9 +230,14 @@ tcp_update_next_port(in_port_t port, const tcp_t *tcp, boolean_t random)
*/
if ((port < tcps->tcps_smallest_anon_port) ||
(port > tcps->tcps_largest_anon_port)) {
- port = tcps->tcps_smallest_anon_port +
- port % (tcps->tcps_largest_anon_port -
- tcps->tcps_smallest_anon_port);
+ if (tcps->tcps_smallest_anon_port ==
+ tcps->tcps_largest_anon_port) {
+ bump = 0;
+ } else {
+ bump = port % (tcps->tcps_largest_anon_port -
+ tcps->tcps_smallest_anon_port);
+ }
+ port = tcps->tcps_smallest_anon_port + bump;
}
}
diff --git a/usr/src/uts/common/inet/tcp/tcp_tunables.c b/usr/src/uts/common/inet/tcp/tcp_tunables.c
index 36bab57964..346903c577 100644
--- a/usr/src/uts/common/inet/tcp/tcp_tunables.c
+++ b/usr/src/uts/common/inet/tcp/tcp_tunables.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -188,6 +189,46 @@ tcp_listener_conf_del(void *cbarg, cred_t *cr, mod_prop_info_t *pinfo,
}
/*
+ * Special checkers for smallest/largest anonymous port so they don't
+ * ever happen to be (largest < smallest).
+ */
+/* ARGSUSED */
+static int
+tcp_smallest_anon_set(void *cbarg, cred_t *cr, mod_prop_info_t *pinfo,
+ const char *ifname, const void *pval, uint_t flags)
+{
+ unsigned long new_value;
+ tcp_stack_t *tcps = (tcp_stack_t *)cbarg;
+ int err;
+
+ if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
+ return (err);
+ /* mod_uint32_value() + pinfo guarantees we're in TCP port range. */
+ if ((uint32_t)new_value > tcps->tcps_largest_anon_port)
+ return (ERANGE);
+ pinfo->prop_cur_uval = (uint32_t)new_value;
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+tcp_largest_anon_set(void *cbarg, cred_t *cr, mod_prop_info_t *pinfo,
+ const char *ifname, const void *pval, uint_t flags)
+{
+ unsigned long new_value;
+ tcp_stack_t *tcps = (tcp_stack_t *)cbarg;
+ int err;
+
+ if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
+ return (err);
+ /* mod_uint32_value() + pinfo guarantees we're in TCP port range. */
+ if ((uint32_t)new_value < tcps->tcps_smallest_anon_port)
+ return (ERANGE);
+ pinfo->prop_cur_uval = (uint32_t)new_value;
+ return (0);
+}
+
+/*
* All of these are alterable, within the min/max values given, at run time.
*
* Note: All those tunables which do not start with "_" are Committed and
@@ -308,11 +349,11 @@ mod_prop_info_t tcp_propinfo_tbl[] = {
{B_FALSE}, {B_FALSE} },
{ "smallest_anon_port", MOD_PROTO_TCP,
- mod_set_uint32, mod_get_uint32,
+ tcp_smallest_anon_set, mod_get_uint32,
{1024, ULP_MAX_PORT, 32*1024}, {32*1024} },
{ "largest_anon_port", MOD_PROTO_TCP,
- mod_set_uint32, mod_get_uint32,
+ tcp_largest_anon_set, mod_get_uint32,
{1024, ULP_MAX_PORT, ULP_MAX_PORT},
{ULP_MAX_PORT} },
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 7e501323d3..e6dfd3efe9 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013, Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -2522,7 +2522,7 @@ udp_tpi_unbind(queue_t *q, mblk_t *mp)
static in_port_t
udp_update_next_port(udp_t *udp, in_port_t port, boolean_t random)
{
- int i;
+ int i, bump;
in_port_t nextport;
boolean_t restart = B_FALSE;
udp_stack_t *us = udp->udp_us;
@@ -2541,9 +2541,15 @@ udp_update_next_port(udp_t *udp, in_port_t port, boolean_t random)
*/
if ((port < us->us_smallest_anon_port) ||
(port > us->us_largest_anon_port)) {
- port = us->us_smallest_anon_port +
- port % (us->us_largest_anon_port -
- us->us_smallest_anon_port);
+ if (us->us_smallest_anon_port ==
+ us->us_largest_anon_port) {
+ bump = 0;
+ } else {
+ bump = port % (us->us_largest_anon_port -
+ us->us_smallest_anon_port);
+ }
+
+ port = us->us_smallest_anon_port + bump;
}
}
diff --git a/usr/src/uts/common/inet/udp/udp_tunables.c b/usr/src/uts/common/inet/udp/udp_tunables.c
index 182cc10718..917dddf62f 100644
--- a/usr/src/uts/common/inet/udp/udp_tunables.c
+++ b/usr/src/uts/common/inet/udp/udp_tunables.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -29,6 +30,46 @@
#include <sys/sunddi.h>
/*
+ * Special checkers for smallest/largest anonymous port so they don't
+ * ever happen to be (largest < smallest).
+ */
+/* ARGSUSED */
+static int
+udp_smallest_anon_set(void *cbarg, cred_t *cr, mod_prop_info_t *pinfo,
+ const char *ifname, const void *pval, uint_t flags)
+{
+ unsigned long new_value;
+ udp_stack_t *us = (udp_stack_t *)cbarg;
+ int err;
+
+ if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
+ return (err);
+ /* mod_uint32_value() + pinfo guarantees we're in UDP port range. */
+ if (new_value > us->us_largest_anon_port)
+ return (ERANGE);
+ pinfo->prop_cur_uval = (uint32_t)new_value;
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+udp_largest_anon_set(void *cbarg, cred_t *cr, mod_prop_info_t *pinfo,
+ const char *ifname, const void *pval, uint_t flags)
+{
+ unsigned long new_value;
+ udp_stack_t *us = (udp_stack_t *)cbarg;
+ int err;
+
+ if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
+ return (err);
+ /* mod_uint32_value() + pinfo guarantees we're in UDP port range. */
+ if (new_value < us->us_smallest_anon_port)
+ return (ERANGE);
+ pinfo->prop_cur_uval = (uint32_t)new_value;
+ return (0);
+}
+
+/*
* All of these are alterable, within the min/max values given, at run time.
*
* Note: All those tunables which do not start with "_" are Committed and
@@ -57,11 +98,11 @@ mod_prop_info_t udp_propinfo_tbl[] = {
{B_TRUE}, {B_TRUE} },
{ "smallest_anon_port", MOD_PROTO_UDP,
- mod_set_uint32, mod_get_uint32,
+ udp_smallest_anon_set, mod_get_uint32,
{1024, ULP_MAX_PORT, (32 * 1024)}, {(32 * 1024)} },
{ "largest_anon_port", MOD_PROTO_UDP,
- mod_set_uint32, mod_get_uint32,
+ udp_largest_anon_set, mod_get_uint32,
{1024, ULP_MAX_PORT, ULP_MAX_PORT}, {ULP_MAX_PORT} },
{ "send_maxbuf", MOD_PROTO_UDP,