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);