xref: /illumos-gate/usr/src/uts/common/inet/ip/ip_tunables.c (revision c56b380c394069fe4abc1010960870ca8b2726a8)
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 (c) 2013 by Delphix. All rights reserved.
24  */
25 /* Copyright (c) 1990 Mentat Inc. */
26 
27 #include <inet/ip.h>
28 #include <inet/ip6.h>
29 #include <inet/ip_if.h>
30 #include <inet/ip_ire.h>
31 #include <inet/ipclassifier.h>
32 #include <inet/ip_impl.h>
33 #include <inet/tunables.h>
34 #include <sys/sunddi.h>
35 #include <sys/policy.h>
36 
37 /* How long, in seconds, we allow frags to hang around. */
38 #define	IP_REASM_TIMEOUT	15
39 #define	IPV6_REASM_TIMEOUT	60
40 
41 /*
42  * Set ip{,6}_forwarding values. If the value is being set on an ill,
43  * find the ill and set the value on it. On the other hand if we are modifying
44  * global property, modify the global value and set the value on all the ills.
45  */
46 /* ARGSUSED */
47 static int
48 ip_set_forwarding(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
49     const char *ifname, const void* pval, uint_t flags)
50 {
51 	char			*end;
52 	unsigned long		new_value;
53 	boolean_t		per_ill, isv6;
54 	ill_walk_context_t	ctx;
55 	ill_t			*ill;
56 	ip_stack_t		*ipst = stack->netstack_ip;
57 
58 	if (flags & MOD_PROP_DEFAULT) {
59 		new_value = pinfo->prop_def_bval;
60 	} else {
61 		if (ddi_strtoul(pval, &end, 10, &new_value) != 0 ||
62 		    *end != '\0')
63 			return (EINVAL);
64 		if (new_value != B_TRUE && new_value != B_FALSE)
65 			return (EINVAL);
66 	}
67 
68 	per_ill = (ifname != NULL && ifname[0] != '\0');
69 	/*
70 	 * if it's not per ill then set the global property and bring all the
71 	 * ills up to date with the new global value.
72 	 */
73 	if (!per_ill)
74 		pinfo->prop_cur_bval = (new_value == 1 ? B_TRUE : B_FALSE);
75 
76 	isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6 ? B_TRUE : B_FALSE);
77 	rw_enter(&ipst->ips_ill_g_lock, RW_READER);
78 	if (isv6)
79 		ill = ILL_START_WALK_V6(&ctx, ipst);
80 	else
81 		ill = ILL_START_WALK_V4(&ctx, ipst);
82 
83 	for (; ill != NULL; ill = ill_next(&ctx, ill)) {
84 		/*
85 		 * if the property needs to be set on a particular
86 		 * interface, look for that interface.
87 		 */
88 		if (per_ill && strcmp(ifname, ill->ill_name) != 0)
89 			continue;
90 		(void) ill_forward_set(ill, new_value != 0);
91 	}
92 	rw_exit(&ipst->ips_ill_g_lock);
93 
94 	return (0);
95 }
96 
97 static int
98 ip_get_forwarding(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
99     void *pval, uint_t pr_size, uint_t flags)
100 {
101 	boolean_t		value;
102 	ill_walk_context_t	ctx;
103 	ill_t			*ill;
104 	ip_stack_t		*ipst = stack->netstack_ip;
105 	boolean_t		get_def = (flags & MOD_PROP_DEFAULT);
106 	boolean_t		get_perm = (flags & MOD_PROP_PERM);
107 	boolean_t		isv6;
108 	size_t			nbytes = 0;
109 
110 	if (get_perm) {
111 		nbytes = snprintf(pval, pr_size, "%d", MOD_PROP_PERM_RW);
112 		goto ret;
113 	} else if (get_def) {
114 		nbytes = snprintf(pval, pr_size, "%d", pinfo->prop_def_bval);
115 		goto ret;
116 	}
117 
118 	/*
119 	 * if per interface value is not asked for return the current
120 	 * global value
121 	 */
122 	if (ifname == NULL || ifname[0] == '\0') {
123 		nbytes = snprintf(pval, pr_size, "%d", pinfo->prop_cur_bval);
124 		goto ret;
125 	}
126 
127 	isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6 ? B_TRUE : B_FALSE);
128 	rw_enter(&ipst->ips_ill_g_lock, RW_READER);
129 	if (isv6)
130 		ill = ILL_START_WALK_V6(&ctx, ipst);
131 	else
132 		ill = ILL_START_WALK_V4(&ctx, ipst);
133 	for (; ill != NULL; ill = ill_next(&ctx, ill)) {
134 		/*
135 		 * if the property needs to be obtained on a particular
136 		 * interface, look for that interface.
137 		 */
138 		if (strcmp(ifname, ill->ill_name) == 0)
139 			break;
140 	}
141 	if (ill == NULL) {
142 		rw_exit(&ipst->ips_ill_g_lock);
143 		return (ENXIO);
144 	}
145 	value = ((ill->ill_flags & ILLF_ROUTER) ? B_TRUE : B_FALSE);
146 	rw_exit(&ipst->ips_ill_g_lock);
147 	nbytes = snprintf(pval, pr_size, "%d", value);
148 ret:
149 	if (nbytes >= pr_size)
150 		return (ENOBUFS);
151 	return (0);
152 }
153 
154 /*
155  * `ip_debug' is a global variable. So, we will be modifying the global
156  * variable here.
157  */
158 /* ARGSUSED */
159 int
160 ip_set_debug(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
161     const char *ifname, const void* pval, uint_t flags)
162 {
163 	unsigned long	new_value;
164 	int		err;
165 
166 	if (cr != NULL && secpolicy_net_config(cr, B_FALSE) != 0)
167 		return (EPERM);
168 
169 	if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
170 		return (err);
171 	ip_debug = (uint32_t)new_value;
172 	return (0);
173 }
174 
175 /*
176  * ip_debug is a global property. For default, permission and value range
177  * we retrieve the value from `pinfo'. However for the current value we
178  * retrieve the value from the global variable `ip_debug'
179  */
180 /* ARGSUSED */
181 int
182 ip_get_debug(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
183     void *pval, uint_t psize, uint_t flags)
184 {
185 	boolean_t	get_def = (flags & MOD_PROP_DEFAULT);
186 	boolean_t	get_perm = (flags & MOD_PROP_PERM);
187 	boolean_t	get_range = (flags & MOD_PROP_POSSIBLE);
188 	size_t		nbytes;
189 
190 	bzero(pval, psize);
191 	if (get_perm)
192 		nbytes = snprintf(pval, psize, "%u", MOD_PROP_PERM_RW);
193 	else if (get_range)
194 		nbytes = snprintf(pval, psize, "%u-%u",
195 		    pinfo->prop_min_uval, pinfo->prop_max_uval);
196 	else if (get_def)
197 		nbytes = snprintf(pval, psize, "%u", pinfo->prop_def_uval);
198 	else
199 		nbytes = snprintf(pval, psize, "%u", ip_debug);
200 	if (nbytes >= psize)
201 		return (ENOBUFS);
202 	return (0);
203 }
204 
205 /*
206  * Set the CGTP (multirouting) filtering status. If the status is changed
207  * from active to transparent or from transparent to active, forward the
208  * new status to the filtering module (if loaded).
209  */
210 /* ARGSUSED */
211 static int
212 ip_set_cgtp_filter(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
213     const char *ifname, const void* pval, uint_t flags)
214 {
215 	unsigned long	new_value;
216 	ip_stack_t	*ipst = stack->netstack_ip;
217 	char		*end;
218 
219 	if (flags & MOD_PROP_DEFAULT) {
220 		new_value = pinfo->prop_def_bval;
221 	} else {
222 		if (ddi_strtoul(pval, &end, 10, &new_value) != 0 ||
223 		    *end != '\0' || new_value > 1) {
224 			return (EINVAL);
225 		}
226 	}
227 	if (!pinfo->prop_cur_bval && new_value) {
228 		cmn_err(CE_NOTE, "IP: enabling CGTP filtering%s",
229 		    ipst->ips_ip_cgtp_filter_ops == NULL ?
230 		    " (module not loaded)" : "");
231 	}
232 	if (pinfo->prop_cur_bval && !new_value) {
233 		cmn_err(CE_NOTE, "IP: disabling CGTP filtering%s",
234 		    ipst->ips_ip_cgtp_filter_ops == NULL ?
235 		    " (module not loaded)" : "");
236 	}
237 	if (ipst->ips_ip_cgtp_filter_ops != NULL) {
238 		int	res;
239 		netstackid_t stackid = ipst->ips_netstack->netstack_stackid;
240 
241 		res = ipst->ips_ip_cgtp_filter_ops->cfo_change_state(stackid,
242 		    new_value);
243 		if (res)
244 			return (res);
245 	}
246 	pinfo->prop_cur_bval = (new_value == 1 ? B_TRUE : B_FALSE);
247 	ill_set_inputfn_all(ipst);
248 	return (0);
249 }
250 
251 /*
252  * Retrieve the default MTU or min-max MTU range for a given interface.
253  *
254  *  -- ill_max_frag value tells us the maximum MTU that can be handled by the
255  *     datalink. This value is advertised by the driver via DLPI messages
256  *     (DL_NOTE_SDU_SIZE/DL_INFO_ACK).
257  *
258  *  -- ill_current_frag for the most link-types will be same as ill_max_frag
259  *     to begin with. However it is dynamically computed for some link-types
260  *     like tunnels, based on the tunnel PMTU.
261  *
262  *  -- ill_mtu is the user set MTU using SIOCSLIFMTU and must lie between
263  *     (IPV6_MIN_MTU/IP_MIN_MTU) and ill_max_frag.
264  *
265  *  -- ill_user_mtu is set by in.ndpd using SIOCSLIFLNKINFO and must lie between
266  *     (IPV6_MIN_MTU/IP_MIN_MTU) and ill_max_frag.
267  */
268 int
269 ip_get_mtu(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
270     void *pval, uint_t psize, uint_t flags)
271 {
272 	ill_walk_context_t	ctx;
273 	ill_t			*ill;
274 	ip_stack_t		*ipst = stack->netstack_ip;
275 	boolean_t		isv6;
276 	uint32_t		max_mtu, def_mtu;
277 	size_t			nbytes = 0;
278 
279 	if (!(flags & (MOD_PROP_DEFAULT|MOD_PROP_POSSIBLE)))
280 		return (ENOTSUP);
281 
282 	if (ifname == NULL || ifname[0] == '\0')
283 		return (ENOTSUP);
284 
285 	isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6 ? B_TRUE : B_FALSE);
286 	rw_enter(&ipst->ips_ill_g_lock, RW_READER);
287 	if (isv6)
288 		ill = ILL_START_WALK_V6(&ctx, ipst);
289 	else
290 		ill = ILL_START_WALK_V4(&ctx, ipst);
291 	for (; ill != NULL; ill = ill_next(&ctx, ill)) {
292 		if (strcmp(ifname, ill->ill_name) == 0)
293 			break;
294 	}
295 	if (ill == NULL) {
296 		rw_exit(&ipst->ips_ill_g_lock);
297 		return (ENXIO);
298 	}
299 	max_mtu = ill->ill_max_frag;
300 	def_mtu = ill->ill_current_frag;
301 	rw_exit(&ipst->ips_ill_g_lock);
302 
303 	if (flags & MOD_PROP_DEFAULT) {
304 		nbytes = snprintf(pval, psize, "%u", def_mtu);
305 	} else if (flags & MOD_PROP_POSSIBLE) {
306 		uint32_t	min_mtu;
307 
308 		min_mtu = isv6 ? IPV6_MIN_MTU : IP_MIN_MTU;
309 		nbytes = snprintf(pval, psize, "%u-%u", min_mtu, max_mtu);
310 	} else {
311 		return (ENOTSUP);
312 	}
313 
314 	if (nbytes >= psize)
315 		return (ENOBUFS);
316 	return (0);
317 }
318 
319 /*
320  * See the comments for ip[6]_strict_src_multihoming for an explanation
321  * of the semanitcs.
322  */
323 void
324 ip_set_src_multihoming_common(ulong_t new_value, ulong_t old_value,
325     boolean_t isv6, ip_stack_t *ipst)
326 {
327 	if (isv6)
328 		ipst->ips_ipv6_strict_src_multihoming = new_value;
329 	else
330 		ipst->ips_ip_strict_src_multihoming = new_value;
331 	if (new_value != old_value) {
332 		if (!isv6) {
333 			if (old_value == 0) {
334 				ire_walk_v4(ip_ire_rebind_walker, NULL,
335 				    ALL_ZONES, ipst);
336 			} else if (new_value == 0) {
337 				ire_walk_v4(ip_ire_unbind_walker, NULL,
338 				    ALL_ZONES, ipst);
339 			}
340 			ipcl_walk(conn_ire_revalidate, (void *)B_FALSE, ipst);
341 		} else {
342 			if (old_value == 0) {
343 				ire_walk_v6(ip_ire_rebind_walker, NULL,
344 				    ALL_ZONES, ipst);
345 			} else if (new_value == 0) {
346 				ire_walk_v6(ip_ire_unbind_walker, NULL,
347 				    ALL_ZONES, ipst);
348 			}
349 			ipcl_walk(conn_ire_revalidate, (void *)B_TRUE, ipst);
350 		}
351 	}
352 }
353 
354 /* ARGSUSED */
355 static int
356 ip_set_src_multihoming(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
357     const char *ifname, const void* pval, uint_t flags)
358 {
359 	unsigned long	new_value, old_value;
360 	boolean_t	isv6;
361 	ip_stack_t	*ipst = stack->netstack_ip;
362 	int		err;
363 
364 	old_value = pinfo->prop_cur_uval;
365 
366 	if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
367 		return (err);
368 	pinfo->prop_cur_uval = new_value;
369 	isv6 = (strcmp(pinfo->mpi_name, "ip6_strict_src_multihoming") == 0);
370 	ip_set_src_multihoming_common(new_value, old_value, isv6, ipst);
371 	return (0);
372 }
373 
374 
375 /* ARGSUSED */
376 static int
377 ip_set_hostmodel(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
378     const char *ifname, const void* pval, uint_t flags)
379 {
380 	ip_hostmodel_t	new_value, old_value;
381 	ip_stack_t	*ipst = stack->netstack_ip;
382 	uint32_t	old_src_multihoming;
383 	int		err;
384 	ulong_t		tmp;
385 	boolean_t	isv6;
386 
387 	old_value = pinfo->prop_cur_uval;
388 
389 	if ((err = mod_uint32_value(pval, pinfo, flags, &tmp)) != 0)
390 		return (err);
391 	new_value = tmp;
392 	pinfo->prop_cur_uval = new_value;
393 
394 	switch (old_value) {
395 	case IP_WEAK_ES:
396 		old_src_multihoming = 0;
397 		break;
398 	case IP_SRC_PRI_ES:
399 		old_src_multihoming = 1;
400 		break;
401 	case IP_STRONG_ES:
402 		old_src_multihoming = 2;
403 		break;
404 	default:
405 		ASSERT(0);
406 		old_src_multihoming = IP_MAXVAL_ES;
407 		break;
408 	}
409 	/*
410 	 * Changes to src_multihoming may require ire's to be rebound/unbound,
411 	 * and also require generation number resets. Changes to dst_multihoming
412 	 * require a simple reset of the value.
413 	 */
414 	isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6);
415 	if (new_value != old_value) {
416 		switch (new_value) {
417 		case IP_WEAK_ES:
418 			ip_set_src_multihoming_common(0, old_src_multihoming,
419 			    isv6, ipst);
420 			if (isv6)
421 				ipst->ips_ipv6_strict_dst_multihoming = 0;
422 			else
423 				ipst->ips_ip_strict_dst_multihoming = 0;
424 			break;
425 		case IP_SRC_PRI_ES:
426 			ip_set_src_multihoming_common(1, old_src_multihoming,
427 			    isv6, ipst);
428 			if (isv6)
429 				ipst->ips_ipv6_strict_dst_multihoming = 0;
430 			else
431 				ipst->ips_ip_strict_dst_multihoming = 0;
432 			break;
433 		case IP_STRONG_ES:
434 			ip_set_src_multihoming_common(2, old_src_multihoming,
435 			    isv6, ipst);
436 			if (isv6)
437 				ipst->ips_ipv6_strict_dst_multihoming = 1;
438 			else
439 				ipst->ips_ip_strict_dst_multihoming = 1;
440 			break;
441 		default:
442 			return (EINVAL);
443 		}
444 	}
445 	return (0);
446 }
447 
448 /* ARGSUSED */
449 int
450 ip_get_hostmodel(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
451     void *pval, uint_t psize, uint_t flags)
452 {
453 	boolean_t	isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6);
454 	ip_stack_t	*ipst = stack->netstack_ip;
455 	ip_hostmodel_t	hostmodel;
456 
457 	if (psize < sizeof (hostmodel))
458 		return (ENOBUFS);
459 	bzero(pval, psize);
460 	if (!isv6) {
461 		if (ipst->ips_ip_strict_src_multihoming == 0 &&
462 		    ipst->ips_ip_strict_dst_multihoming == 0)
463 			hostmodel = IP_WEAK_ES;
464 		else if (ipst->ips_ip_strict_src_multihoming == 1 &&
465 		    ipst->ips_ip_strict_dst_multihoming == 0)
466 			hostmodel = IP_SRC_PRI_ES;
467 		else if (ipst->ips_ip_strict_src_multihoming == 2 &&
468 		    ipst->ips_ip_strict_dst_multihoming == 1)
469 			hostmodel = IP_STRONG_ES;
470 		else
471 			hostmodel = IP_MAXVAL_ES;
472 	} else {
473 		if (ipst->ips_ipv6_strict_src_multihoming == 0 &&
474 		    ipst->ips_ipv6_strict_dst_multihoming == 0)
475 			hostmodel = IP_WEAK_ES;
476 		else if (ipst->ips_ipv6_strict_src_multihoming == 1 &&
477 		    ipst->ips_ipv6_strict_dst_multihoming == 0)
478 			hostmodel = IP_SRC_PRI_ES;
479 		else if (ipst->ips_ipv6_strict_src_multihoming == 2 &&
480 		    ipst->ips_ipv6_strict_dst_multihoming == 1)
481 			hostmodel = IP_STRONG_ES;
482 		else
483 			hostmodel = IP_MAXVAL_ES;
484 	}
485 	bcopy(&hostmodel, pval, sizeof (hostmodel));
486 	return (0);
487 }
488 
489 /*
490  * All of these are alterable, within the min/max values given, at run time.
491  *
492  * Note: All those tunables which do not start with "_" are Committed and
493  * therefore are public. See PSARC 2010/080.
494  */
495 mod_prop_info_t ip_propinfo_tbl[] = {
496 	/* tunable - 0 */
497 	{ "_respond_to_address_mask_broadcast", MOD_PROTO_IP,
498 	    mod_set_boolean, mod_get_boolean,
499 	    {B_FALSE}, {B_FALSE} },
500 
501 	{ "_respond_to_echo_broadcast", MOD_PROTO_IP,
502 	    mod_set_boolean, mod_get_boolean,
503 	    {B_TRUE},  {B_TRUE} },
504 
505 	{ "_respond_to_echo_multicast", MOD_PROTO_IPV4,
506 	    mod_set_boolean, mod_get_boolean,
507 	    {B_TRUE}, {B_TRUE} },
508 
509 	{ "_respond_to_timestamp", MOD_PROTO_IP,
510 	    mod_set_boolean, mod_get_boolean,
511 	    {B_FALSE}, {B_FALSE} },
512 
513 	{ "_respond_to_timestamp_broadcast", MOD_PROTO_IP,
514 	    mod_set_boolean, mod_get_boolean,
515 	    {B_FALSE}, {B_FALSE} },
516 
517 	{ "_send_redirects", MOD_PROTO_IPV4,
518 	    mod_set_boolean, mod_get_boolean,
519 	    {B_TRUE}, {B_TRUE} },
520 
521 	{ "_forward_directed_broadcasts", MOD_PROTO_IP,
522 	    mod_set_boolean, mod_get_boolean,
523 	    {B_FALSE}, {B_FALSE} },
524 
525 	{ "_mrtdebug", MOD_PROTO_IP,
526 	    mod_set_uint32, mod_get_uint32,
527 	    {0, 10, 0}, {0} },
528 
529 	{ "_ire_reclaim_fraction", MOD_PROTO_IP,
530 	    mod_set_uint32, mod_get_uint32,
531 	    {1, 8, 3}, {3} },
532 
533 	{ "_nce_reclaim_fraction", MOD_PROTO_IP,
534 	    mod_set_uint32, mod_get_uint32,
535 	    {1, 8, 3}, {3} },
536 
537 	/* tunable - 10 */
538 	{ "_dce_reclaim_fraction", MOD_PROTO_IP,
539 	    mod_set_uint32, mod_get_uint32,
540 	    {1, 8, 3}, {3} },
541 
542 	{ "ttl", MOD_PROTO_IPV4,
543 	    mod_set_uint32, mod_get_uint32,
544 	    {1, 255, 255}, {255} },
545 
546 	{ "_forward_src_routed", MOD_PROTO_IPV4,
547 	    mod_set_boolean, mod_get_boolean,
548 	    {B_FALSE}, {B_FALSE} },
549 
550 	{ "_wroff_extra", MOD_PROTO_IP,
551 	    mod_set_uint32, mod_get_uint32,
552 	    {0, 256, 32}, {32} },
553 
554 	/* following tunable is in seconds - a deviant! */
555 	{ "_pathmtu_interval", MOD_PROTO_IP,
556 	    mod_set_uint32, mod_get_uint32,
557 	    {2, 999999999, 60*20}, {60*20} },
558 
559 	{ "_icmp_return_data_bytes", MOD_PROTO_IPV4,
560 	    mod_set_uint32, mod_get_uint32,
561 	    {8, 65536, 64}, {64} },
562 
563 	{ "_path_mtu_discovery", MOD_PROTO_IP,
564 	    mod_set_boolean, mod_get_boolean,
565 	    {B_TRUE}, {B_TRUE} },
566 
567 	{ "_pmtu_min", MOD_PROTO_IP,
568 	    mod_set_uint32, mod_get_uint32,
569 	    {68, 65535, 576}, {576} },
570 
571 	{ "_ignore_redirect", MOD_PROTO_IPV4,
572 	    mod_set_boolean, mod_get_boolean,
573 	    {B_FALSE}, {B_FALSE} },
574 
575 	{ "_arp_icmp_error", MOD_PROTO_IP,
576 	    mod_set_boolean, mod_get_boolean,
577 	    {B_FALSE}, {B_FALSE} },
578 
579 	/* tunable - 20 */
580 	{ "_broadcast_ttl", MOD_PROTO_IP,
581 	    mod_set_uint32, mod_get_uint32,
582 	    {1, 254, 1}, {1} },
583 
584 	{ "_icmp_err_interval", MOD_PROTO_IP,
585 	    mod_set_uint32, mod_get_uint32,
586 	    {0, 99999, 100}, {100} },
587 
588 	{ "_icmp_err_burst", MOD_PROTO_IP,
589 	    mod_set_uint32, mod_get_uint32,
590 	    {1, 99999, 10}, {10} },
591 
592 	{ "_reass_queue_bytes", MOD_PROTO_IP,
593 	    mod_set_uint32, mod_get_uint32,
594 	    {0, 999999999, 1000000}, {1000000} },
595 
596 	/*
597 	 * See comments for ip_strict_src_multihoming for an explanation
598 	 * of the semantics of ip_strict_dst_multihoming
599 	 */
600 	{ "_strict_dst_multihoming", MOD_PROTO_IPV4,
601 	    mod_set_uint32, mod_get_uint32,
602 	    {0, 1, 0}, {0} },
603 
604 	{ "_addrs_per_if", MOD_PROTO_IP,
605 	    mod_set_uint32, mod_get_uint32,
606 	    {1, MAX_ADDRS_PER_IF, 256}, {256} },
607 
608 	{ "_ipsec_override_persocket_policy", MOD_PROTO_IP,
609 	    mod_set_boolean, mod_get_boolean,
610 	    {B_FALSE}, {B_FALSE} },
611 
612 	{ "_icmp_accept_clear_messages", MOD_PROTO_IP,
613 	    mod_set_boolean, mod_get_boolean,
614 	    {B_TRUE}, {B_TRUE} },
615 
616 	{ "_igmp_accept_clear_messages", MOD_PROTO_IP,
617 	    mod_set_boolean, mod_get_boolean,
618 	    {B_TRUE}, {B_TRUE} },
619 
620 	{ "_ndp_delay_first_probe_time", MOD_PROTO_IP,
621 	    mod_set_uint32, mod_get_uint32,
622 	    {2, 999999999, ND_DELAY_FIRST_PROBE_TIME},
623 	    {ND_DELAY_FIRST_PROBE_TIME} },
624 
625 	/* tunable - 30 */
626 	{ "_ndp_max_unicast_solicit", MOD_PROTO_IP,
627 	    mod_set_uint32, mod_get_uint32,
628 	    {1, 999999999, ND_MAX_UNICAST_SOLICIT}, {ND_MAX_UNICAST_SOLICIT} },
629 
630 	{ "hoplimit", MOD_PROTO_IPV6,
631 	    mod_set_uint32, mod_get_uint32,
632 	    {1, 255, IPV6_MAX_HOPS}, {IPV6_MAX_HOPS} },
633 
634 	{ "_icmp_return_data_bytes", MOD_PROTO_IPV6,
635 	    mod_set_uint32, mod_get_uint32,
636 	    {8, IPV6_MIN_MTU, IPV6_MIN_MTU}, {IPV6_MIN_MTU} },
637 
638 	{ "_forward_src_routed", MOD_PROTO_IPV6,
639 	    mod_set_boolean, mod_get_boolean,
640 	    {B_FALSE}, {B_FALSE} },
641 
642 	{ "_respond_to_echo_multicast", MOD_PROTO_IPV6,
643 	    mod_set_boolean, mod_get_boolean,
644 	    {B_TRUE}, {B_TRUE} },
645 
646 	{ "_send_redirects", MOD_PROTO_IPV6,
647 	    mod_set_boolean, mod_get_boolean,
648 	    {B_TRUE}, {B_TRUE} },
649 
650 	{ "_ignore_redirect", MOD_PROTO_IPV6,
651 	    mod_set_boolean, mod_get_boolean,
652 	    {B_FALSE}, {B_FALSE} },
653 
654 	/*
655 	 * See comments for ip6_strict_src_multihoming for an explanation
656 	 * of the semantics of ip6_strict_dst_multihoming
657 	 */
658 	{ "_strict_dst_multihoming", MOD_PROTO_IPV6,
659 	    mod_set_uint32, mod_get_uint32,
660 	    {0, 1, 0}, {0} },
661 
662 	{ "_src_check", MOD_PROTO_IP,
663 	    mod_set_uint32, mod_get_uint32,
664 	    {0, 2, 2}, {2} },
665 
666 	{ "_ipsec_policy_log_interval", MOD_PROTO_IP,
667 	    mod_set_uint32, mod_get_uint32,
668 	    {0, 999999, 1000}, {1000} },
669 
670 	/* tunable - 40 */
671 	{ "_pim_accept_clear_messages", MOD_PROTO_IP,
672 	    mod_set_boolean, mod_get_boolean,
673 	    {B_TRUE}, {B_TRUE} },
674 
675 	{ "_ndp_unsolicit_interval", MOD_PROTO_IP,
676 	    mod_set_uint32, mod_get_uint32,
677 	    {1000, 20000, 2000}, {2000} },
678 
679 	{ "_ndp_unsolicit_count", MOD_PROTO_IP,
680 	    mod_set_uint32, mod_get_uint32,
681 	    {1, 20, 3}, {3} },
682 
683 	{ "_ignore_home_address_opt", MOD_PROTO_IPV6,
684 	    mod_set_boolean, mod_get_boolean,
685 	    {B_TRUE}, {B_TRUE} },
686 
687 	{ "_policy_mask", MOD_PROTO_IP,
688 	    mod_set_uint32, mod_get_uint32,
689 	    {0, 15, 0}, {0} },
690 
691 	{ "_ecmp_behavior", MOD_PROTO_IP,
692 	    mod_set_uint32, mod_get_uint32,
693 	    {0, 2, 2}, {2} },
694 
695 	{ "_multirt_ttl", MOD_PROTO_IP,
696 	    mod_set_uint32, mod_get_uint32,
697 	    {0, 255, 1}, {1} },
698 
699 	/* following tunable is in seconds - a deviant */
700 	{ "_ire_badcnt_lifetime", MOD_PROTO_IP,
701 	    mod_set_uint32, mod_get_uint32,
702 	    {0, 3600, 60}, {60} },
703 
704 	{ "_max_temp_idle", MOD_PROTO_IP,
705 	    mod_set_uint32, mod_get_uint32,
706 	    {0, 999999, 60*60*24}, {60*60*24} },
707 
708 	{ "_max_temp_defend", MOD_PROTO_IP,
709 	    mod_set_uint32, mod_get_uint32,
710 	    {0, 1000, 1}, {1} },
711 
712 	/* tunable - 50 */
713 	/*
714 	 * when a conflict of an active address is detected,
715 	 * defend up to ip_max_defend times, within any
716 	 * ip_defend_interval span.
717 	 */
718 	{ "_max_defend", MOD_PROTO_IP,
719 	    mod_set_uint32, mod_get_uint32,
720 	    {0, 1000, 3}, {3} },
721 
722 	{ "_defend_interval", MOD_PROTO_IP,
723 	    mod_set_uint32, mod_get_uint32,
724 	    {0, 999999, 30}, {30} },
725 
726 	{ "_dup_recovery", MOD_PROTO_IP,
727 	    mod_set_uint32, mod_get_uint32,
728 	    {0, 3600000, 300000}, {300000} },
729 
730 	{ "_restrict_interzone_loopback", MOD_PROTO_IP,
731 	    mod_set_boolean, mod_get_boolean,
732 	    {B_TRUE}, {B_TRUE} },
733 
734 	{ "_lso_outbound", MOD_PROTO_IP,
735 	    mod_set_boolean, mod_get_boolean,
736 	    {B_TRUE}, {B_TRUE} },
737 
738 	{ "_igmp_max_version", MOD_PROTO_IP,
739 	    mod_set_uint32, mod_get_uint32,
740 	    {IGMP_V1_ROUTER, IGMP_V3_ROUTER, IGMP_V3_ROUTER},
741 	    {IGMP_V3_ROUTER} },
742 
743 	{ "_mld_max_version", MOD_PROTO_IP,
744 	    mod_set_uint32, mod_get_uint32,
745 	    {MLD_V1_ROUTER, MLD_V2_ROUTER, MLD_V2_ROUTER}, {MLD_V2_ROUTER} },
746 
747 	{ "forwarding", MOD_PROTO_IPV4,
748 	    ip_set_forwarding, ip_get_forwarding,
749 	    {IP_FORWARD_NEVER}, {IP_FORWARD_NEVER} },
750 
751 	{ "forwarding", MOD_PROTO_IPV6,
752 	    ip_set_forwarding, ip_get_forwarding,
753 	    {IP_FORWARD_NEVER}, {IP_FORWARD_NEVER} },
754 
755 	{ "_reasm_timeout", MOD_PROTO_IPV4,
756 	    mod_set_uint32, mod_get_uint32,
757 	    {5, 255, IP_REASM_TIMEOUT},
758 	    {IP_REASM_TIMEOUT} },
759 
760 	/* tunable - 60 */
761 	{ "_reasm_timeout", MOD_PROTO_IPV6,
762 	    mod_set_uint32, mod_get_uint32,
763 	    {5, 255, IPV6_REASM_TIMEOUT},
764 	    {IPV6_REASM_TIMEOUT} },
765 
766 	{ "_cgtp_filter", MOD_PROTO_IP,
767 	    ip_set_cgtp_filter, mod_get_boolean,
768 	    {B_FALSE}, {B_FALSE} },
769 
770 	/* delay before sending first probe: */
771 	{ "_arp_probe_delay", MOD_PROTO_IP,
772 	    mod_set_uint32, mod_get_uint32,
773 	    {0, 20000, 1000}, {1000} },
774 
775 	{ "_arp_fastprobe_delay", MOD_PROTO_IP,
776 	    mod_set_uint32, mod_get_uint32,
777 	    {0, 20000, 100}, {100} },
778 
779 	/* interval at which DAD probes are sent: */
780 	{ "_arp_probe_interval", MOD_PROTO_IP,
781 	    mod_set_uint32, mod_get_uint32,
782 	    {10, 20000, 1500}, {1500} },
783 
784 	{ "_arp_fastprobe_interval", MOD_PROTO_IP,
785 	    mod_set_uint32, mod_get_uint32,
786 	    {10, 20000, 150}, {150} },
787 
788 	{ "_arp_probe_count", MOD_PROTO_IP,
789 	    mod_set_uint32, mod_get_uint32,
790 	    {0, 20, 3}, {3} },
791 
792 	{ "_arp_fastprobe_count", MOD_PROTO_IP,
793 	    mod_set_uint32, mod_get_uint32,
794 	    {0, 20, 3}, {3} },
795 
796 	{ "_dad_announce_interval", MOD_PROTO_IPV4,
797 	    mod_set_uint32, mod_get_uint32,
798 	    {0, 3600000, 15000}, {15000} },
799 
800 	{ "_dad_announce_interval", MOD_PROTO_IPV6,
801 	    mod_set_uint32, mod_get_uint32,
802 	    {0, 3600000, 15000}, {15000} },
803 
804 	/* tunable - 70 */
805 	/*
806 	 * Rate limiting parameters for DAD defense used in
807 	 * ill_defend_rate_limit():
808 	 * defend_rate : pkts/hour permitted
809 	 * defend_interval : time that can elapse before we send out a
810 	 *			DAD defense.
811 	 * defend_period: denominator for defend_rate (in seconds).
812 	 */
813 	{ "_arp_defend_interval", MOD_PROTO_IP,
814 	    mod_set_uint32, mod_get_uint32,
815 	    {0, 3600000, 300000}, {300000} },
816 
817 	{ "_arp_defend_rate", MOD_PROTO_IP,
818 	    mod_set_uint32, mod_get_uint32,
819 	    {0, 20000, 100}, {100} },
820 
821 	{ "_ndp_defend_interval", MOD_PROTO_IP,
822 	    mod_set_uint32, mod_get_uint32,
823 	    {0, 3600000, 300000}, {300000} },
824 
825 	{ "_ndp_defend_rate", MOD_PROTO_IP,
826 	    mod_set_uint32, mod_get_uint32,
827 	    {0, 20000, 100}, {100} },
828 
829 	{ "_arp_defend_period", MOD_PROTO_IP,
830 	    mod_set_uint32, mod_get_uint32,
831 	    {5, 86400, 3600}, {3600} },
832 
833 	{ "_ndp_defend_period", MOD_PROTO_IP,
834 	    mod_set_uint32, mod_get_uint32,
835 	    {5, 86400, 3600}, {3600} },
836 
837 	{ "_icmp_return_pmtu", MOD_PROTO_IPV4,
838 	    mod_set_boolean, mod_get_boolean,
839 	    {B_TRUE}, {B_TRUE} },
840 
841 	{ "_icmp_return_pmtu", MOD_PROTO_IPV6,
842 	    mod_set_boolean, mod_get_boolean,
843 	    {B_TRUE}, {B_TRUE} },
844 
845 	/*
846 	 * publish count/interval values used to announce local addresses
847 	 * for IPv4, IPv6.
848 	 */
849 	{ "_arp_publish_count", MOD_PROTO_IP,
850 	    mod_set_uint32, mod_get_uint32,
851 	    {1, 20, 5}, {5} },
852 
853 	{ "_arp_publish_interval", MOD_PROTO_IP,
854 	    mod_set_uint32, mod_get_uint32,
855 	    {1000, 20000, 2000}, {2000} },
856 
857 	/* tunable - 80 */
858 	/*
859 	 * The ip*strict_src_multihoming and ip*strict_dst_multihoming provide
860 	 * a range of choices for setting strong/weak/preferred end-system
861 	 * behavior. The semantics for setting these are:
862 	 *
863 	 * ip*_strict_dst_multihoming = 0
864 	 *    weak end system model for managing ip destination addresses.
865 	 *    A packet with IP dst D1 that's received on interface I1 will be
866 	 *    accepted as long as D1 is one of the local addresses on
867 	 *    the machine, even if D1 is not configured on I1.
868 	 * ip*strict_dst_multihioming = 1
869 	 *    strong end system model for managing ip destination addresses.
870 	 *    A packet with IP dst D1 that's received on interface I1 will be
871 	 *    accepted if, and only if, D1 is configured on I1.
872 	 *
873 	 * ip*strict_src_multihoming = 0
874 	 *    Source agnostic route selection for outgoing packets: the
875 	 *    outgoing interface for a packet will be computed using
876 	 *    default algorithms for route selection, where the route
877 	 *    with the longest matching prefix is chosen for the output
878 	 *    unless other route selection constraints are explicitly
879 	 *    specified during routing table lookup.  This may result
880 	 *    in packet being sent out on interface I2 with source
881 	 *    address S1, even though S1 is not a configured address on I2.
882 	 * ip*strict_src_multihoming = 1
883 	 *    Preferred source aware route selection for outgoing packets: for
884 	 *    a packet with source S2, destination D2, the route selection
885 	 *    algorithm will first attempt to find a route for the destination
886 	 *    that goes out through an interface where S2 is
887 	 *    configured. If such a route cannot be found, then the
888 	 *    best-matching route for D2 will be selected.
889 	 * ip*strict_src_multihoming = 2
890 	 *    Source aware route selection for outgoing packets: a packet will
891 	 *    be sent out on an interface I2 only if the src address S2 of the
892 	 *    packet is a configured address on I2. In conjunction with
893 	 *    the setting 'ip_strict_dst_multihoming == 1', this will result in
894 	 *    the implementation of Strong ES as defined in Section 3.3.4.2 of
895 	 *    RFC 1122
896 	 */
897 	{ "_strict_src_multihoming", MOD_PROTO_IPV4,
898 	    ip_set_src_multihoming, mod_get_uint32,
899 	    {0, 2, 0}, {0} },
900 
901 	{ "_strict_src_multihoming", MOD_PROTO_IPV6,
902 	    ip_set_src_multihoming, mod_get_uint32,
903 	    {0, 2, 0}, {0} },
904 
905 #ifdef DEBUG
906 	{ "_drop_inbound_icmpv6", MOD_PROTO_IPV6,
907 	    mod_set_boolean, mod_get_boolean,
908 	    {B_FALSE}, {B_FALSE} },
909 #else
910 	{ "", 0, NULL, NULL, {0}, {0} },
911 #endif
912 	{ "mtu", MOD_PROTO_IPV4, NULL, ip_get_mtu, {0}, {0} },
913 
914 	{ "mtu", MOD_PROTO_IPV6, NULL, ip_get_mtu, {0}, {0} },
915 
916 	/*
917 	 * The following entry is a placeholder for `ip_debug' global
918 	 * variable. Within these callback functions, we will be
919 	 * setting/getting the global variable
920 	 */
921 	{ "_debug", MOD_PROTO_IP,
922 	    ip_set_debug, ip_get_debug,
923 	    {0, 20, 0}, {0} },
924 
925 	{ "hostmodel", MOD_PROTO_IPV4, ip_set_hostmodel, ip_get_hostmodel,
926 	    {IP_WEAK_ES, IP_STRONG_ES, IP_WEAK_ES}, {IP_WEAK_ES} },
927 
928 	{ "hostmodel", MOD_PROTO_IPV6, ip_set_hostmodel, ip_get_hostmodel,
929 	    {IP_WEAK_ES, IP_STRONG_ES, IP_WEAK_ES}, {IP_WEAK_ES} },
930 
931 	{ "?", MOD_PROTO_IP, NULL, mod_get_allprop, {0}, {0} },
932 
933 	{ NULL, 0, NULL, NULL, {0}, {0} }
934 };
935 
936 int ip_propinfo_count = A_CNT(ip_propinfo_tbl);
937