diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2013-07-22 23:23:27 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2013-07-22 23:23:31 +0000 |
commit | ae90c942d8ffba880f1197d0fae961027144b251 (patch) | |
tree | f07d045010f504821f9a4ae5189f88adbc20882f | |
parent | ba5ba26a63657a8c15a464fc0a0c34a36a59a854 (diff) | |
parent | 7256a34efe9df75b638b9e812912ef7c5c68e208 (diff) | |
download | illumos-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.c | 15 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_tunables.c | 45 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp/udp.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp/udp_tunables.c | 45 |
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, |