1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 24 * Copyright (c) 2013 by Delphix. All rights reserved. 25 */ 26 /* Copyright (c) 1990 Mentat Inc. */ 27 28 #include <inet/ip.h> 29 #include <inet/ip6.h> 30 #include <inet/udp_impl.h> 31 #include <sys/sunddi.h> 32 33 static int 34 udp_set_buf_prop(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo, 35 const char *ifname, const void *pval, uint_t flags) 36 { 37 return (mod_set_buf_prop(stack->netstack_udp->us_propinfo_tbl, stack, 38 cr, pinfo, ifname, pval, flags)); 39 } 40 41 static int 42 udp_get_buf_prop(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname, 43 void *val, uint_t psize, uint_t flags) 44 { 45 return (mod_get_buf_prop(stack->netstack_udp->us_propinfo_tbl, stack, 46 pinfo, ifname, val, psize, flags)); 47 } 48 49 /* 50 * Special checkers for smallest/largest anonymous port so they don't 51 * ever happen to be (largest < smallest). 52 */ 53 /* ARGSUSED */ 54 static int 55 udp_smallest_anon_set(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo, 56 const char *ifname, const void *pval, uint_t flags) 57 { 58 unsigned long new_value; 59 udp_stack_t *us = stack->netstack_udp; 60 int err; 61 62 if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0) 63 return (err); 64 /* mod_uint32_value() + pinfo guarantees we're in UDP port range. */ 65 if (new_value > us->us_largest_anon_port) 66 return (ERANGE); 67 pinfo->prop_cur_uval = (uint32_t)new_value; 68 return (0); 69 } 70 71 /* ARGSUSED */ 72 static int 73 udp_largest_anon_set(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo, 74 const char *ifname, const void *pval, uint_t flags) 75 { 76 unsigned long new_value; 77 udp_stack_t *us = stack->netstack_udp; 78 int err; 79 80 if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0) 81 return (err); 82 /* mod_uint32_value() + pinfo guarantees we're in UDP port range. */ 83 if (new_value < us->us_smallest_anon_port) 84 return (ERANGE); 85 pinfo->prop_cur_uval = (uint32_t)new_value; 86 return (0); 87 } 88 89 /* 90 * All of these are alterable, within the min/max values given, at run time. 91 * 92 * Note: All those tunables which do not start with "_" are Committed and 93 * therefore are public. See PSARC 2010/080. 94 */ 95 mod_prop_info_t udp_propinfo_tbl[] = { 96 /* tunable - 0 */ 97 { "_wroff_extra", MOD_PROTO_UDP, 98 mod_set_uint32, mod_get_uint32, 99 {{0, 256, 32}}, {32} }, 100 101 { "_ipv4_ttl", MOD_PROTO_UDP, 102 mod_set_uint32, mod_get_uint32, 103 {{1, 255, 255}}, {255} }, 104 105 { "_ipv6_hoplimit", MOD_PROTO_UDP, 106 mod_set_uint32, mod_get_uint32, 107 {{0, IPV6_MAX_HOPS, IPV6_DEFAULT_HOPS}}, {IPV6_DEFAULT_HOPS} }, 108 109 { "smallest_nonpriv_port", MOD_PROTO_UDP, 110 mod_set_uint32, mod_get_uint32, 111 {{1024, (32 * 1024), 1024}}, {1024} }, 112 113 { "_do_checksum", MOD_PROTO_UDP, 114 mod_set_boolean, mod_get_boolean, 115 {.mpi_bval = B_TRUE}, {B_TRUE} }, 116 117 { "smallest_anon_port", MOD_PROTO_UDP, 118 udp_smallest_anon_set, mod_get_uint32, 119 {{1024, ULP_MAX_PORT, (32 * 1024)}}, {(32 * 1024)} }, 120 121 { "largest_anon_port", MOD_PROTO_UDP, 122 udp_largest_anon_set, mod_get_uint32, 123 {{1024, ULP_MAX_PORT, ULP_MAX_PORT}}, {ULP_MAX_PORT} }, 124 125 { "send_buf", MOD_PROTO_UDP, 126 udp_set_buf_prop, udp_get_buf_prop, 127 {{UDP_XMIT_LOWATER, ULP_MAX_BUF, UDP_XMIT_HIWATER}}, 128 {UDP_XMIT_HIWATER} }, 129 130 { "_xmit_lowat", MOD_PROTO_UDP, 131 mod_set_uint32, mod_get_uint32, 132 {{0, ULP_MAX_BUF, UDP_XMIT_LOWATER}}, 133 {UDP_XMIT_LOWATER} }, 134 135 { "recv_buf", MOD_PROTO_UDP, 136 udp_set_buf_prop, udp_get_buf_prop, 137 {{UDP_RECV_LOWATER, ULP_MAX_BUF, UDP_RECV_HIWATER}}, 138 {UDP_RECV_HIWATER} }, 139 140 /* tunable - 10 */ 141 { "max_buf", MOD_PROTO_UDP, 142 mod_set_uint32, mod_get_uint32, 143 {{65536, ULP_MAX_BUF, 2*1024*1024}}, {2*1024*1024} }, 144 145 { "_pmtu_discovery", MOD_PROTO_UDP, 146 mod_set_boolean, mod_get_boolean, 147 {.mpi_bval = B_FALSE}, {B_FALSE} }, 148 149 { "_sendto_ignerr", MOD_PROTO_UDP, 150 mod_set_boolean, mod_get_boolean, 151 {.mpi_bval = B_FALSE}, {B_FALSE} }, 152 153 { "extra_priv_ports", MOD_PROTO_UDP, 154 mod_set_extra_privports, mod_get_extra_privports, 155 {{1, ULP_MAX_PORT, 0}}, {0} }, 156 157 { "?", MOD_PROTO_UDP, NULL, mod_get_allprop, {{0,0,0}}, {0} }, 158 159 { NULL, 0, NULL, NULL, {{0,0,0}}, {0} } 160 }; 161 162 int udp_propinfo_count = A_CNT(udp_propinfo_tbl);