Mercurial > illumos > illumos-gate
changeset 14084:9919574e3322
3895 {tcp,udp}_{largest,smallest}_anon_port should reality-check
Reviewed by: Marcel Telka <marcel@telka.sk>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Garrett D'Amore <garrett@damore.org>
author | Dan McDonald <danmcd@nexenta.com> |
---|---|
date | Thu, 18 Jul 2013 22:44:14 -0400 |
parents | eac51815a73b |
children | c1602d3adc9b |
files | usr/src/uts/common/inet/tcp/tcp_bind.c usr/src/uts/common/inet/tcp/tcp_tunables.c usr/src/uts/common/inet/udp/udp.c usr/src/uts/common/inet/udp/udp_tunables.c |
diffstat | 4 files changed, 107 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/tcp/tcp_bind.c Thu Jul 18 15:18:41 2013 -0400 +++ b/usr/src/uts/common/inet/tcp/tcp_bind.c Thu Jul 18 22:44:14 2013 -0400 @@ -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 @@ 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 @@ */ 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; } }
--- a/usr/src/uts/common/inet/tcp/tcp_tunables.c Thu Jul 18 15:18:41 2013 -0400 +++ b/usr/src/uts/common/inet/tcp/tcp_tunables.c Thu Jul 18 22:44:14 2013 -0400 @@ -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 @@ } /* + * 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 @@ {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} },
--- a/usr/src/uts/common/inet/udp/udp.c Thu Jul 18 15:18:41 2013 -0400 +++ b/usr/src/uts/common/inet/udp/udp.c Thu Jul 18 22:44:14 2013 -0400 @@ -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 @@ 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 @@ */ 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; } }
--- a/usr/src/uts/common/inet/udp/udp_tunables.c Thu Jul 18 15:18:41 2013 -0400 +++ b/usr/src/uts/common/inet/udp/udp_tunables.c Thu Jul 18 22:44:14 2013 -0400 @@ -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 @@ {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,