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