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) 2012, Joyent, Inc. All rights reserved.
24 * Copyright (c) 2013 by Delphix. All rights reserved.
25 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
26 */
27 /* Copyright (c) 1990 Mentat Inc. */
28
29 #include <inet/ip.h>
30 #include <inet/ip6.h>
31 #include <inet/ip_if.h>
32 #include <inet/ip_ire.h>
33 #include <inet/ipclassifier.h>
34 #include <inet/ip_impl.h>
35 #include <inet/tunables.h>
36 #include <sys/sunddi.h>
37 #include <sys/policy.h>
38
39 /* How long, in seconds, we allow frags to hang around. */
40 #define IP_REASM_TIMEOUT 15
41 #define IPV6_REASM_TIMEOUT 60
42
43 /*
44 * Set ip{,6}_forwarding values. If the value is being set on an ill,
45 * find the ill and set the value on it. On the other hand if we are modifying
46 * global property, modify the global value and set the value on all the ills.
47 */
48 /* ARGSUSED */
49 static int
50 ip_set_forwarding(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
51 const char *ifname, const void* pval, uint_t flags)
52 {
53 char *end;
54 unsigned long new_value;
55 boolean_t per_ill, isv6;
56 ill_walk_context_t ctx;
57 ill_t *ill;
58 ip_stack_t *ipst = stack->netstack_ip;
59
60 if (flags & MOD_PROP_DEFAULT) {
61 new_value = pinfo->prop_def_bval;
62 } else {
63 if (ddi_strtoul(pval, &end, 10, &new_value) != 0 ||
64 *end != '\0')
65 return (EINVAL);
66 if (new_value != B_TRUE && new_value != B_FALSE)
67 return (EINVAL);
68 }
69
70 per_ill = (ifname != NULL && ifname[0] != '\0');
71 /*
72 * if it's not per ill then set the global property and bring all the
73 * ills up to date with the new global value.
74 */
75 if (!per_ill)
76 pinfo->prop_cur_bval = (new_value == 1 ? B_TRUE : B_FALSE);
77
78 isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6 ? B_TRUE : B_FALSE);
79 rw_enter(&ipst->ips_ill_g_lock, RW_READER);
80 if (isv6)
81 ill = ILL_START_WALK_V6(&ctx, ipst);
82 else
83 ill = ILL_START_WALK_V4(&ctx, ipst);
84
85 for (; ill != NULL; ill = ill_next(&ctx, ill)) {
86 /*
87 * if the property needs to be set on a particular
88 * interface, look for that interface.
89 */
90 if (per_ill && strcmp(ifname, ill->ill_name) != 0)
91 continue;
92 (void) ill_forward_set(ill, new_value != 0);
93 }
94 rw_exit(&ipst->ips_ill_g_lock);
95
96 return (0);
97 }
98
99 static int
100 ip_get_forwarding(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
101 void *pval, uint_t pr_size, uint_t flags)
102 {
103 boolean_t value;
104 ill_walk_context_t ctx;
105 ill_t *ill;
106 ip_stack_t *ipst = stack->netstack_ip;
107 boolean_t get_def = (flags & MOD_PROP_DEFAULT);
108 boolean_t get_perm = (flags & MOD_PROP_PERM);
109 boolean_t isv6;
110 size_t nbytes = 0;
111
112 if (get_perm) {
113 nbytes = snprintf(pval, pr_size, "%d", MOD_PROP_PERM_RW);
114 goto ret;
115 } else if (get_def) {
116 nbytes = snprintf(pval, pr_size, "%d", pinfo->prop_def_bval);
117 goto ret;
118 }
119
120 /*
121 * if per interface value is not asked for return the current
122 * global value
123 */
124 if (ifname == NULL || ifname[0] == '\0') {
125 nbytes = snprintf(pval, pr_size, "%d", pinfo->prop_cur_bval);
126 goto ret;
127 }
128
129 isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6 ? B_TRUE : B_FALSE);
130 rw_enter(&ipst->ips_ill_g_lock, RW_READER);
131 if (isv6)
132 ill = ILL_START_WALK_V6(&ctx, ipst);
133 else
134 ill = ILL_START_WALK_V4(&ctx, ipst);
135 for (; ill != NULL; ill = ill_next(&ctx, ill)) {
136 /*
137 * if the property needs to be obtained on a particular
138 * interface, look for that interface.
139 */
140 if (strcmp(ifname, ill->ill_name) == 0)
141 break;
142 }
143 if (ill == NULL) {
144 rw_exit(&ipst->ips_ill_g_lock);
145 return (ENXIO);
146 }
147 value = ((ill->ill_flags & ILLF_ROUTER) ? B_TRUE : B_FALSE);
148 rw_exit(&ipst->ips_ill_g_lock);
149 nbytes = snprintf(pval, pr_size, "%d", value);
150 ret:
151 if (nbytes >= pr_size)
152 return (ENOBUFS);
153 return (0);
154 }
155
156 /*
157 * `ip_debug' is a global variable. So, we will be modifying the global
158 * variable here.
159 */
160 /* ARGSUSED */
161 int
162 ip_set_debug(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
163 const char *ifname, const void* pval, uint_t flags)
164 {
165 unsigned long new_value;
166 int err;
167
168 if (cr != NULL && secpolicy_net_config(cr, B_FALSE) != 0)
169 return (EPERM);
170
171 if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
172 return (err);
173 ip_debug = (uint32_t)new_value;
174 return (0);
175 }
176
177 /*
178 * ip_debug is a global property. For default, permission and value range
179 * we retrieve the value from `pinfo'. However for the current value we
180 * retrieve the value from the global variable `ip_debug'
181 */
182 /* ARGSUSED */
183 int
184 ip_get_debug(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
185 void *pval, uint_t psize, uint_t flags)
186 {
187 boolean_t get_def = (flags & MOD_PROP_DEFAULT);
188 boolean_t get_perm = (flags & MOD_PROP_PERM);
189 boolean_t get_range = (flags & MOD_PROP_POSSIBLE);
190 size_t nbytes;
191
192 bzero(pval, psize);
193 if (get_perm)
194 nbytes = snprintf(pval, psize, "%u", MOD_PROP_PERM_RW);
195 else if (get_range)
196 nbytes = snprintf(pval, psize, "%u-%u",
197 pinfo->prop_min_uval, pinfo->prop_max_uval);
198 else if (get_def)
199 nbytes = snprintf(pval, psize, "%u", pinfo->prop_def_uval);
200 else
201 nbytes = snprintf(pval, psize, "%u", ip_debug);
202 if (nbytes >= psize)
203 return (ENOBUFS);
204 return (0);
205 }
206
207 /*
208 * Set the CGTP (multirouting) filtering status. If the status is changed
209 * from active to transparent or from transparent to active, forward the
210 * new status to the filtering module (if loaded).
211 */
212 /* ARGSUSED */
213 static int
214 ip_set_cgtp_filter(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
215 const char *ifname, const void* pval, uint_t flags)
216 {
217 unsigned long new_value;
218 ip_stack_t *ipst = stack->netstack_ip;
219 char *end;
220
221 if (flags & MOD_PROP_DEFAULT) {
222 new_value = pinfo->prop_def_bval;
223 } else {
224 if (ddi_strtoul(pval, &end, 10, &new_value) != 0 ||
225 *end != '\0' || new_value > 1) {
226 return (EINVAL);
227 }
228 }
229 if (!pinfo->prop_cur_bval && new_value) {
230 cmn_err(CE_NOTE, "IP: enabling CGTP filtering%s",
231 ipst->ips_ip_cgtp_filter_ops == NULL ?
232 " (module not loaded)" : "");
233 }
234 if (pinfo->prop_cur_bval && !new_value) {
235 cmn_err(CE_NOTE, "IP: disabling CGTP filtering%s",
236 ipst->ips_ip_cgtp_filter_ops == NULL ?
237 " (module not loaded)" : "");
238 }
239 if (ipst->ips_ip_cgtp_filter_ops != NULL) {
240 int res;
241 netstackid_t stackid = ipst->ips_netstack->netstack_stackid;
242
243 res = ipst->ips_ip_cgtp_filter_ops->cfo_change_state(stackid,
244 new_value);
245 if (res)
246 return (res);
247 }
248 pinfo->prop_cur_bval = (new_value == 1 ? B_TRUE : B_FALSE);
249 ill_set_inputfn_all(ipst);
250 return (0);
251 }
252
253 /*
254 * Retrieve the default MTU or min-max MTU range for a given interface.
255 *
256 * -- ill_max_frag value tells us the maximum MTU that can be handled by the
257 * datalink. This value is advertised by the driver via DLPI messages
258 * (DL_NOTE_SDU_SIZE/DL_INFO_ACK).
259 *
260 * -- ill_current_frag for the most link-types will be same as ill_max_frag
261 * to begin with. However it is dynamically computed for some link-types
262 * like tunnels, based on the tunnel PMTU.
263 *
264 * -- ill_mtu is the user set MTU using SIOCSLIFMTU and must lie between
265 * (IPV6_MIN_MTU/IP_MIN_MTU) and ill_max_frag.
266 *
267 * -- ill_user_mtu is set by in.ndpd using SIOCSLIFLNKINFO and must lie between
268 * (IPV6_MIN_MTU/IP_MIN_MTU) and ill_max_frag.
269 */
270 int
271 ip_get_mtu(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
272 void *pval, uint_t psize, uint_t flags)
273 {
274 ill_walk_context_t ctx;
275 ill_t *ill;
276 ip_stack_t *ipst = stack->netstack_ip;
277 boolean_t isv6;
278 uint32_t max_mtu, def_mtu;
279 size_t nbytes = 0;
280
281 if (!(flags & (MOD_PROP_DEFAULT|MOD_PROP_POSSIBLE)))
282 return (ENOTSUP);
283
284 if (ifname == NULL || ifname[0] == '\0')
285 return (ENOTSUP);
286
287 isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6 ? B_TRUE : B_FALSE);
288 rw_enter(&ipst->ips_ill_g_lock, RW_READER);
289 if (isv6)
290 ill = ILL_START_WALK_V6(&ctx, ipst);
291 else
292 ill = ILL_START_WALK_V4(&ctx, ipst);
293 for (; ill != NULL; ill = ill_next(&ctx, ill)) {
294 if (strcmp(ifname, ill->ill_name) == 0)
295 break;
296 }
297 if (ill == NULL) {
298 rw_exit(&ipst->ips_ill_g_lock);
299 return (ENXIO);
300 }
301 max_mtu = ill->ill_max_frag;
302 def_mtu = ill->ill_current_frag;
303 rw_exit(&ipst->ips_ill_g_lock);
304
305 if (flags & MOD_PROP_DEFAULT) {
306 nbytes = snprintf(pval, psize, "%u", def_mtu);
307 } else if (flags & MOD_PROP_POSSIBLE) {
308 uint32_t min_mtu;
309
310 min_mtu = isv6 ? IPV6_MIN_MTU : IP_MIN_MTU;
311 nbytes = snprintf(pval, psize, "%u-%u", min_mtu, max_mtu);
312 } else {
313 return (ENOTSUP);
314 }
315
316 if (nbytes >= psize)
317 return (ENOBUFS);
318 return (0);
319 }
320
321 /*
322 * See the comments for ip[6]_strict_src_multihoming for an explanation
323 * of the semanitcs.
324 */
325 void
326 ip_set_src_multihoming_common(ulong_t new_value, ulong_t old_value,
327 boolean_t isv6, ip_stack_t *ipst)
328 {
329 if (isv6)
330 ipst->ips_ipv6_strict_src_multihoming = new_value;
331 else
332 ipst->ips_ip_strict_src_multihoming = new_value;
333 if (new_value != old_value) {
334 if (!isv6) {
335 if (old_value == 0) {
336 ire_walk_v4(ip_ire_rebind_walker, NULL,
337 ALL_ZONES, ipst);
338 } else if (new_value == 0) {
339 ire_walk_v4(ip_ire_unbind_walker, NULL,
340 ALL_ZONES, ipst);
341 }
342 ipcl_walk(conn_ire_revalidate, (void *)B_FALSE, ipst);
343 } else {
344 if (old_value == 0) {
345 ire_walk_v6(ip_ire_rebind_walker, NULL,
346 ALL_ZONES, ipst);
347 } else if (new_value == 0) {
348 ire_walk_v6(ip_ire_unbind_walker, NULL,
349 ALL_ZONES, ipst);
350 }
351 ipcl_walk(conn_ire_revalidate, (void *)B_TRUE, ipst);
352 }
353 }
354 }
355
356 /* ARGSUSED */
357 static int
358 ip_set_src_multihoming(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
359 const char *ifname, const void* pval, uint_t flags)
360 {
361 unsigned long new_value, old_value;
362 boolean_t isv6;
363 ip_stack_t *ipst = stack->netstack_ip;
364 int err;
365
366 old_value = pinfo->prop_cur_uval;
367
368 if ((err = mod_uint32_value(pval, pinfo, flags, &new_value)) != 0)
369 return (err);
370 pinfo->prop_cur_uval = new_value;
371 isv6 = (strcmp(pinfo->mpi_name, "ip6_strict_src_multihoming") == 0);
372 ip_set_src_multihoming_common(new_value, old_value, isv6, ipst);
373 return (0);
374 }
375
376
377 /* ARGSUSED */
378 static int
379 ip_set_hostmodel(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
380 const char *ifname, const void* pval, uint_t flags)
381 {
382 ip_hostmodel_t new_value, old_value;
383 ip_stack_t *ipst = stack->netstack_ip;
384 uint32_t old_src_multihoming;
385 int err;
386 ulong_t tmp;
387 boolean_t isv6;
388
389 old_value = pinfo->prop_cur_uval;
390
391 if ((err = mod_uint32_value(pval, pinfo, flags, &tmp)) != 0)
392 return (err);
393 new_value = tmp;
394 pinfo->prop_cur_uval = new_value;
395
396 switch (old_value) {
397 case IP_WEAK_ES:
398 old_src_multihoming = 0;
399 break;
400 case IP_SRC_PRI_ES:
401 old_src_multihoming = 1;
402 break;
403 case IP_STRONG_ES:
404 old_src_multihoming = 2;
405 break;
406 default:
407 ASSERT(0);
408 old_src_multihoming = IP_MAXVAL_ES;
409 break;
410 }
411 /*
412 * Changes to src_multihoming may require ire's to be rebound/unbound,
413 * and also require generation number resets. Changes to dst_multihoming
414 * require a simple reset of the value.
415 */
416 isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6);
417 if (new_value != old_value) {
418 switch (new_value) {
419 case IP_WEAK_ES:
420 ip_set_src_multihoming_common(0, old_src_multihoming,
421 isv6, ipst);
422 if (isv6)
423 ipst->ips_ipv6_strict_dst_multihoming = 0;
424 else
425 ipst->ips_ip_strict_dst_multihoming = 0;
426 break;
427 case IP_SRC_PRI_ES:
428 ip_set_src_multihoming_common(1, old_src_multihoming,
429 isv6, ipst);
430 if (isv6)
431 ipst->ips_ipv6_strict_dst_multihoming = 0;
432 else
433 ipst->ips_ip_strict_dst_multihoming = 0;
434 break;
435 case IP_STRONG_ES:
436 ip_set_src_multihoming_common(2, old_src_multihoming,
437 isv6, ipst);
438 if (isv6)
439 ipst->ips_ipv6_strict_dst_multihoming = 1;
440 else
441 ipst->ips_ip_strict_dst_multihoming = 1;
442 break;
443 default:
444 return (EINVAL);
445 }
446 }
447 return (0);
448 }
449
450 /* ARGSUSED */
451 int
452 ip_get_hostmodel(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
453 void *pval, uint_t psize, uint_t flags)
454 {
455 boolean_t isv6 = (pinfo->mpi_proto == MOD_PROTO_IPV6);
456 ip_stack_t *ipst = stack->netstack_ip;
457 ip_hostmodel_t hostmodel;
458
459 if (psize < sizeof (hostmodel))
460 return (ENOBUFS);
461 bzero(pval, psize);
462 if (!isv6) {
463 if (ipst->ips_ip_strict_src_multihoming == 0 &&
464 ipst->ips_ip_strict_dst_multihoming == 0)
465 hostmodel = IP_WEAK_ES;
466 else if (ipst->ips_ip_strict_src_multihoming == 1 &&
467 ipst->ips_ip_strict_dst_multihoming == 0)
468 hostmodel = IP_SRC_PRI_ES;
469 else if (ipst->ips_ip_strict_src_multihoming == 2 &&
470 ipst->ips_ip_strict_dst_multihoming == 1)
471 hostmodel = IP_STRONG_ES;
472 else
473 hostmodel = IP_MAXVAL_ES;
474 } else {
475 if (ipst->ips_ipv6_strict_src_multihoming == 0 &&
476 ipst->ips_ipv6_strict_dst_multihoming == 0)
477 hostmodel = IP_WEAK_ES;
478 else if (ipst->ips_ipv6_strict_src_multihoming == 1 &&
479 ipst->ips_ipv6_strict_dst_multihoming == 0)
480 hostmodel = IP_SRC_PRI_ES;
481 else if (ipst->ips_ipv6_strict_src_multihoming == 2 &&
482 ipst->ips_ipv6_strict_dst_multihoming == 1)
483 hostmodel = IP_STRONG_ES;
484 else
485 hostmodel = IP_MAXVAL_ES;
486 }
487 bcopy(&hostmodel, pval, sizeof (hostmodel));
488 return (0);
489 }
490
491 /*
492 * All of these are alterable, within the min/max values given, at run time.
493 *
494 * Note: All those tunables which do not start with "_" are Committed and
495 * therefore are public. See PSARC 2010/080.
496 */
497 mod_prop_info_t ip_propinfo_tbl[] = {
498 /* tunable - 0 */
499 { "_respond_to_address_mask_broadcast", MOD_PROTO_IP,
500 mod_set_boolean, mod_get_boolean,
501 {B_FALSE}, {B_FALSE} },
502
503 { "_respond_to_echo_broadcast", MOD_PROTO_IP,
504 mod_set_boolean, mod_get_boolean,
505 {B_TRUE}, {B_TRUE} },
506
507 { "_respond_to_echo_multicast", MOD_PROTO_IPV4,
508 mod_set_boolean, mod_get_boolean,
509 {B_TRUE}, {B_TRUE} },
510
511 { "_respond_to_timestamp", MOD_PROTO_IP,
512 mod_set_boolean, mod_get_boolean,
513 {B_FALSE}, {B_FALSE} },
514
515 { "_respond_to_timestamp_broadcast", MOD_PROTO_IP,
516 mod_set_boolean, mod_get_boolean,
517 {B_FALSE}, {B_FALSE} },
518
519 { "_send_redirects", MOD_PROTO_IPV4,
520 mod_set_boolean, mod_get_boolean,
521 {B_TRUE}, {B_TRUE} },
522
523 { "_forward_directed_broadcasts", MOD_PROTO_IP,
524 mod_set_boolean, mod_get_boolean,
525 {B_FALSE}, {B_FALSE} },
526
527 { "_mrtdebug", MOD_PROTO_IP,
528 mod_set_uint32, mod_get_uint32,
529 {0, 10, 0}, {0} },
530
531 { "_ire_reclaim_fraction", MOD_PROTO_IP,
532 mod_set_uint32, mod_get_uint32,
533 {1, 8, 3}, {3} },
534
535 { "_nce_reclaim_fraction", MOD_PROTO_IP,
536 mod_set_uint32, mod_get_uint32,
537 {1, 8, 3}, {3} },
538
539 /* tunable - 10 */
540 { "_dce_reclaim_fraction", MOD_PROTO_IP,
541 mod_set_uint32, mod_get_uint32,
542 {1, 8, 3}, {3} },
543
544 { "ttl", MOD_PROTO_IPV4,
545 mod_set_uint32, mod_get_uint32,
546 {1, 255, 255}, {255} },
547
548 { "_forward_src_routed", MOD_PROTO_IPV4,
549 mod_set_boolean, mod_get_boolean,
550 {B_FALSE}, {B_FALSE} },
551
552 { "_wroff_extra", MOD_PROTO_IP,
553 mod_set_uint32, mod_get_uint32,
554 {0, 256, 32}, {32} },
555
556 /* following tunable is in seconds - a deviant! */
557 { "_pathmtu_interval", MOD_PROTO_IP,
558 mod_set_uint32, mod_get_uint32,
559 {2, 999999999, 60*20}, {60*20} },
560
561 { "_icmp_return_data_bytes", MOD_PROTO_IPV4,
562 mod_set_uint32, mod_get_uint32,
563 {8, 65536, 64}, {64} },
564
565 { "_path_mtu_discovery", MOD_PROTO_IP,
566 mod_set_boolean, mod_get_boolean,
567 {B_TRUE}, {B_TRUE} },
568
569 { "_pmtu_min", MOD_PROTO_IP,
570 mod_set_uint32, mod_get_uint32,
571 {68, 65535, 576}, {576} },
572
573 { "_ignore_redirect", MOD_PROTO_IPV4,
574 mod_set_boolean, mod_get_boolean,
575 {B_FALSE}, {B_FALSE} },
576
577 { "_arp_icmp_error", MOD_PROTO_IP,
578 mod_set_boolean, mod_get_boolean,
579 {B_FALSE}, {B_FALSE} },
580
581 /* tunable - 20 */
582 { "_broadcast_ttl", MOD_PROTO_IP,
583 mod_set_uint32, mod_get_uint32,
584 {1, 254, 1}, {1} },
585
586 { "_icmp_err_interval", MOD_PROTO_IP,
587 mod_set_uint32, mod_get_uint32,
588 {0, 99999, 100}, {100} },
589
590 { "_icmp_err_burst", MOD_PROTO_IP,
591 mod_set_uint32, mod_get_uint32,
592 {1, 99999, 10}, {10} },
593
594 { "_reass_queue_bytes", MOD_PROTO_IP,
595 mod_set_uint32, mod_get_uint32,
596 {0, 999999999, 1000000}, {1000000} },
597
598 /*
599 * See comments for ip_strict_src_multihoming for an explanation
600 * of the semantics of ip_strict_dst_multihoming
601 */
602 { "_strict_dst_multihoming", MOD_PROTO_IPV4,
603 mod_set_uint32, mod_get_uint32,
604 {0, 1, 0}, {0} },
605
606 { "_addrs_per_if", MOD_PROTO_IP,
607 mod_set_uint32, mod_get_uint32,
608 {1, MAX_ADDRS_PER_IF, 256}, {256} },
609
610 { "_ipsec_override_persocket_policy", MOD_PROTO_IP,
611 mod_set_boolean, mod_get_boolean,
612 {B_FALSE}, {B_FALSE} },
613
614 { "_icmp_accept_clear_messages", MOD_PROTO_IP,
615 mod_set_boolean, mod_get_boolean,
616 {B_TRUE}, {B_TRUE} },
617
618 { "_igmp_accept_clear_messages", MOD_PROTO_IP,
619 mod_set_boolean, mod_get_boolean,
620 {B_TRUE}, {B_TRUE} },
621
622 { "_ndp_delay_first_probe_time", MOD_PROTO_IP,
623 mod_set_uint32, mod_get_uint32,
624 {2, 999999999, ND_DELAY_FIRST_PROBE_TIME},
625 {ND_DELAY_FIRST_PROBE_TIME} },
626
627 /* tunable - 30 */
628 { "_ndp_max_unicast_solicit", MOD_PROTO_IP,
629 mod_set_uint32, mod_get_uint32,
630 {1, 999999999, ND_MAX_UNICAST_SOLICIT}, {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 {B_FALSE}, {B_FALSE} },
643
644 { "_respond_to_echo_multicast", MOD_PROTO_IPV6,
645 mod_set_boolean, mod_get_boolean,
646 {B_TRUE}, {B_TRUE} },
647
648 { "_send_redirects", MOD_PROTO_IPV6,
649 mod_set_boolean, mod_get_boolean,
650 {B_TRUE}, {B_TRUE} },
651
652 { "_ignore_redirect", MOD_PROTO_IPV6,
653 mod_set_boolean, mod_get_boolean,
654 {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 {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 {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 {B_TRUE}, {B_TRUE} },
735
736 { "_lso_outbound", MOD_PROTO_IP,
737 mod_set_boolean, mod_get_boolean,
738 {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 {IP_FORWARD_NEVER}, {IP_FORWARD_NEVER} },
752
753 { "forwarding", MOD_PROTO_IPV6,
754 ip_set_forwarding, ip_get_forwarding,
755 {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 {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 {B_TRUE}, {B_TRUE} },
842
843 { "_icmp_return_pmtu", MOD_PROTO_IPV6,
844 mod_set_boolean, mod_get_boolean,
845 {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 {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);