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             {B_FALSE}, {B_FALSE} },
 501 
 502         { "_respond_to_echo_broadcast", MOD_PROTO_IP,
 503             mod_set_boolean, mod_get_boolean,
 504             {B_TRUE},  {B_TRUE} },
 505 
 506         { "_respond_to_echo_multicast", MOD_PROTO_IPV4,
 507             mod_set_boolean, mod_get_boolean,
 508             {B_TRUE}, {B_TRUE} },
 509 
 510         { "_respond_to_timestamp", MOD_PROTO_IP,
 511             mod_set_boolean, mod_get_boolean,
 512             {B_FALSE}, {B_FALSE} },
 513 
 514         { "_respond_to_timestamp_broadcast", MOD_PROTO_IP,
 515             mod_set_boolean, mod_get_boolean,
 516             {B_FALSE}, {B_FALSE} },
 517 
 518         { "_send_redirects", MOD_PROTO_IPV4,
 519             mod_set_boolean, mod_get_boolean,
 520             {B_TRUE}, {B_TRUE} },
 521 
 522         { "_forward_directed_broadcasts", MOD_PROTO_IP,
 523             mod_set_boolean, mod_get_boolean,
 524             {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             {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             {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             {B_FALSE}, {B_FALSE} },
 575 
 576         { "_arp_icmp_error", MOD_PROTO_IP,
 577             mod_set_boolean, mod_get_boolean,
 578             {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             {B_FALSE}, {B_FALSE} },
 612 
 613         { "_icmp_accept_clear_messages", MOD_PROTO_IP,
 614             mod_set_boolean, mod_get_boolean,
 615             {B_TRUE}, {B_TRUE} },
 616 
 617         { "_igmp_accept_clear_messages", MOD_PROTO_IP,
 618             mod_set_boolean, mod_get_boolean,
 619             {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}, {ND_MAX_UNICAST_SOLICIT} },
 630 
 631         { "hoplimit", MOD_PROTO_IPV6,
 632             mod_set_uint32, mod_get_uint32,
 633             {1, 255, IPV6_MAX_HOPS}, {IPV6_MAX_HOPS} },
 634 
 635         { "_icmp_return_data_bytes", MOD_PROTO_IPV6,
 636             mod_set_uint32, mod_get_uint32,
 637             {8, IPV6_MIN_MTU, IPV6_MIN_MTU}, {IPV6_MIN_MTU} },
 638 
 639         { "_forward_src_routed", MOD_PROTO_IPV6,
 640             mod_set_boolean, mod_get_boolean,
 641             {B_FALSE}, {B_FALSE} },
 642 
 643         { "_respond_to_echo_multicast", MOD_PROTO_IPV6,
 644             mod_set_boolean, mod_get_boolean,
 645             {B_TRUE}, {B_TRUE} },
 646 
 647         { "_send_redirects", MOD_PROTO_IPV6,
 648             mod_set_boolean, mod_get_boolean,
 649             {B_TRUE}, {B_TRUE} },
 650 
 651         { "_ignore_redirect", MOD_PROTO_IPV6,
 652             mod_set_boolean, mod_get_boolean,
 653             {B_FALSE}, {B_FALSE} },
 654 
 655         /*
 656          * See comments for ip6_strict_src_multihoming for an explanation
 657          * of the semantics of ip6_strict_dst_multihoming
 658          */
 659         { "_strict_dst_multihoming", MOD_PROTO_IPV6,
 660             mod_set_uint32, mod_get_uint32,
 661             {0, 1, 0}, {0} },
 662 
 663         { "_src_check", MOD_PROTO_IP,
 664             mod_set_uint32, mod_get_uint32,
 665             {0, 2, 2}, {2} },
 666 
 667         { "_ipsec_policy_log_interval", MOD_PROTO_IP,
 668             mod_set_uint32, mod_get_uint32,
 669             {0, 999999, 0}, {0} },
 670 
 671         /* tunable - 40 */
 672         { "_pim_accept_clear_messages", MOD_PROTO_IP,
 673             mod_set_boolean, mod_get_boolean,
 674             {B_TRUE}, {B_TRUE} },
 675 
 676         { "_ndp_unsolicit_interval", MOD_PROTO_IP,
 677             mod_set_uint32, mod_get_uint32,
 678             {1000, 20000, 2000}, {2000} },
 679 
 680         { "_ndp_unsolicit_count", MOD_PROTO_IP,
 681             mod_set_uint32, mod_get_uint32,
 682             {1, 20, 3}, {3} },
 683 
 684         { "_ignore_home_address_opt", MOD_PROTO_IPV6,
 685             mod_set_boolean, mod_get_boolean,
 686             {B_TRUE}, {B_TRUE} },
 687 
 688         { "_policy_mask", MOD_PROTO_IP,
 689             mod_set_uint32, mod_get_uint32,
 690             {0, 15, 0}, {0} },
 691 
 692         { "_ecmp_behavior", MOD_PROTO_IP,
 693             mod_set_uint32, mod_get_uint32,
 694             {0, 2, 2}, {2} },
 695 
 696         { "_multirt_ttl", MOD_PROTO_IP,
 697             mod_set_uint32, mod_get_uint32,
 698             {0, 255, 1}, {1} },
 699 
 700         /* following tunable is in seconds - a deviant */
 701         { "_ire_badcnt_lifetime", MOD_PROTO_IP,
 702             mod_set_uint32, mod_get_uint32,
 703             {0, 3600, 60}, {60} },
 704 
 705         { "_max_temp_idle", MOD_PROTO_IP,
 706             mod_set_uint32, mod_get_uint32,
 707             {0, 999999, 60*60*24}, {60*60*24} },
 708 
 709         { "_max_temp_defend", MOD_PROTO_IP,
 710             mod_set_uint32, mod_get_uint32,
 711             {0, 1000, 1}, {1} },
 712 
 713         /* tunable - 50 */
 714         /*
 715          * when a conflict of an active address is detected,
 716          * defend up to ip_max_defend times, within any
 717          * ip_defend_interval span.
 718          */
 719         { "_max_defend", MOD_PROTO_IP,
 720             mod_set_uint32, mod_get_uint32,
 721             {0, 1000, 3}, {3} },
 722 
 723         { "_defend_interval", MOD_PROTO_IP,
 724             mod_set_uint32, mod_get_uint32,
 725             {0, 999999, 30}, {30} },
 726 
 727         { "_dup_recovery", MOD_PROTO_IP,
 728             mod_set_uint32, mod_get_uint32,
 729             {0, 3600000, 300000}, {300000} },
 730 
 731         { "_restrict_interzone_loopback", MOD_PROTO_IP,
 732             mod_set_boolean, mod_get_boolean,
 733             {B_TRUE}, {B_TRUE} },
 734 
 735         { "_lso_outbound", MOD_PROTO_IP,
 736             mod_set_boolean, mod_get_boolean,
 737             {B_TRUE}, {B_TRUE} },
 738 
 739         { "_igmp_max_version", MOD_PROTO_IP,
 740             mod_set_uint32, mod_get_uint32,
 741             {IGMP_V1_ROUTER, IGMP_V3_ROUTER, IGMP_V3_ROUTER},
 742             {IGMP_V3_ROUTER} },
 743 
 744         { "_mld_max_version", MOD_PROTO_IP,
 745             mod_set_uint32, mod_get_uint32,
 746             {MLD_V1_ROUTER, MLD_V2_ROUTER, MLD_V2_ROUTER}, {MLD_V2_ROUTER} },
 747 
 748         { "forwarding", MOD_PROTO_IPV4,
 749             ip_set_forwarding, ip_get_forwarding,
 750             {IP_FORWARD_NEVER}, {IP_FORWARD_NEVER} },
 751 
 752         { "forwarding", MOD_PROTO_IPV6,
 753             ip_set_forwarding, ip_get_forwarding,
 754             {IP_FORWARD_NEVER}, {IP_FORWARD_NEVER} },
 755 
 756         { "_reasm_timeout", MOD_PROTO_IPV4,
 757             mod_set_uint32, mod_get_uint32,
 758             {5, 255, IP_REASM_TIMEOUT},
 759             {IP_REASM_TIMEOUT} },
 760 
 761         /* tunable - 60 */
 762         { "_reasm_timeout", MOD_PROTO_IPV6,
 763             mod_set_uint32, mod_get_uint32,
 764             {5, 255, IPV6_REASM_TIMEOUT},
 765             {IPV6_REASM_TIMEOUT} },
 766 
 767         { "_cgtp_filter", MOD_PROTO_IP,
 768             ip_set_cgtp_filter, mod_get_boolean,
 769             {B_FALSE}, {B_FALSE} },
 770 
 771         /* delay before sending first probe: */
 772         { "_arp_probe_delay", MOD_PROTO_IP,
 773             mod_set_uint32, mod_get_uint32,
 774             {0, 20000, 1000}, {1000} },
 775 
 776         { "_arp_fastprobe_delay", MOD_PROTO_IP,
 777             mod_set_uint32, mod_get_uint32,
 778             {0, 20000, 100}, {100} },
 779 
 780         /* interval at which DAD probes are sent: */
 781         { "_arp_probe_interval", MOD_PROTO_IP,
 782             mod_set_uint32, mod_get_uint32,
 783             {10, 20000, 1500}, {1500} },
 784 
 785         { "_arp_fastprobe_interval", MOD_PROTO_IP,
 786             mod_set_uint32, mod_get_uint32,
 787             {10, 20000, 150}, {150} },
 788 
 789         { "_arp_probe_count", MOD_PROTO_IP,
 790             mod_set_uint32, mod_get_uint32,
 791             {0, 20, 3}, {3} },
 792 
 793         { "_arp_fastprobe_count", MOD_PROTO_IP,
 794             mod_set_uint32, mod_get_uint32,
 795             {0, 20, 3}, {3} },
 796 
 797         { "_dad_announce_interval", MOD_PROTO_IPV4,
 798             mod_set_uint32, mod_get_uint32,
 799             {0, 3600000, 15000}, {15000} },
 800 
 801         { "_dad_announce_interval", MOD_PROTO_IPV6,
 802             mod_set_uint32, mod_get_uint32,
 803             {0, 3600000, 15000}, {15000} },
 804 
 805         /* tunable - 70 */
 806         /*
 807          * Rate limiting parameters for DAD defense used in
 808          * ill_defend_rate_limit():
 809          * defend_rate : pkts/hour permitted
 810          * defend_interval : time that can elapse before we send out a
 811          *                      DAD defense.
 812          * defend_period: denominator for defend_rate (in seconds).
 813          */
 814         { "_arp_defend_interval", MOD_PROTO_IP,
 815             mod_set_uint32, mod_get_uint32,
 816             {0, 3600000, 300000}, {300000} },
 817 
 818         { "_arp_defend_rate", MOD_PROTO_IP,
 819             mod_set_uint32, mod_get_uint32,
 820             {0, 20000, 100}, {100} },
 821 
 822         { "_ndp_defend_interval", MOD_PROTO_IP,
 823             mod_set_uint32, mod_get_uint32,
 824             {0, 3600000, 300000}, {300000} },
 825 
 826         { "_ndp_defend_rate", MOD_PROTO_IP,
 827             mod_set_uint32, mod_get_uint32,
 828             {0, 20000, 100}, {100} },
 829 
 830         { "_arp_defend_period", MOD_PROTO_IP,
 831             mod_set_uint32, mod_get_uint32,
 832             {5, 86400, 3600}, {3600} },
 833 
 834         { "_ndp_defend_period", MOD_PROTO_IP,
 835             mod_set_uint32, mod_get_uint32,
 836             {5, 86400, 3600}, {3600} },
 837 
 838         { "_icmp_return_pmtu", MOD_PROTO_IPV4,
 839             mod_set_boolean, mod_get_boolean,
 840             {B_TRUE}, {B_TRUE} },
 841 
 842         { "_icmp_return_pmtu", MOD_PROTO_IPV6,
 843             mod_set_boolean, mod_get_boolean,
 844             {B_TRUE}, {B_TRUE} },
 845 
 846         /*
 847          * publish count/interval values used to announce local addresses
 848          * for IPv4, IPv6.
 849          */
 850         { "_arp_publish_count", MOD_PROTO_IP,
 851             mod_set_uint32, mod_get_uint32,
 852             {1, 20, 5}, {5} },
 853 
 854         { "_arp_publish_interval", MOD_PROTO_IP,
 855             mod_set_uint32, mod_get_uint32,
 856             {1000, 20000, 2000}, {2000} },
 857 
 858         /* tunable - 80 */
 859         /*
 860          * The ip*strict_src_multihoming and ip*strict_dst_multihoming provide
 861          * a range of choices for setting strong/weak/preferred end-system
 862          * behavior. The semantics for setting these are:
 863          *
 864          * ip*_strict_dst_multihoming = 0
 865          *    weak end system model for managing ip destination addresses.
 866          *    A packet with IP dst D1 that's received on interface I1 will be
 867          *    accepted as long as D1 is one of the local addresses on
 868          *    the machine, even if D1 is not configured on I1.
 869          * ip*strict_dst_multihioming = 1
 870          *    strong end system model for managing ip destination addresses.
 871          *    A packet with IP dst D1 that's received on interface I1 will be
 872          *    accepted if, and only if, D1 is configured on I1.
 873          *
 874          * ip*strict_src_multihoming = 0
 875          *    Source agnostic route selection for outgoing packets: the
 876          *    outgoing interface for a packet will be computed using
 877          *    default algorithms for route selection, where the route
 878          *    with the longest matching prefix is chosen for the output
 879          *    unless other route selection constraints are explicitly
 880          *    specified during routing table lookup.  This may result
 881          *    in packet being sent out on interface I2 with source
 882          *    address S1, even though S1 is not a configured address on I2.
 883          * ip*strict_src_multihoming = 1
 884          *    Preferred source aware route selection for outgoing packets: for
 885          *    a packet with source S2, destination D2, the route selection
 886          *    algorithm will first attempt to find a route for the destination
 887          *    that goes out through an interface where S2 is
 888          *    configured. If such a route cannot be found, then the
 889          *    best-matching route for D2 will be selected.
 890          * ip*strict_src_multihoming = 2
 891          *    Source aware route selection for outgoing packets: a packet will
 892          *    be sent out on an interface I2 only if the src address S2 of the
 893          *    packet is a configured address on I2. In conjunction with
 894          *    the setting 'ip_strict_dst_multihoming == 1', this will result in
 895          *    the implementation of Strong ES as defined in Section 3.3.4.2 of
 896          *    RFC 1122
 897          */
 898         { "_strict_src_multihoming", MOD_PROTO_IPV4,
 899             ip_set_src_multihoming, mod_get_uint32,
 900             {0, 2, 0}, {0} },
 901 
 902         { "_strict_src_multihoming", MOD_PROTO_IPV6,
 903             ip_set_src_multihoming, mod_get_uint32,
 904             {0, 2, 0}, {0} },
 905 
 906 #ifdef DEBUG
 907         { "_drop_inbound_icmpv6", MOD_PROTO_IPV6,
 908             mod_set_boolean, mod_get_boolean,
 909             {B_FALSE}, {B_FALSE} },
 910 #else
 911         { "", 0, NULL, NULL, {0}, {0} },
 912 #endif
 913 
 914         { "_dce_reclaim_threshold", MOD_PROTO_IP,
 915             mod_set_uint32, mod_get_uint32,
 916             {1, 100000, 32}, {32} },
 917 
 918         { "mtu", MOD_PROTO_IPV4, NULL, ip_get_mtu, {0}, {0} },
 919 
 920         { "mtu", MOD_PROTO_IPV6, NULL, ip_get_mtu, {0}, {0} },
 921 
 922         /*
 923          * The following entry is a placeholder for `ip_debug' global
 924          * variable. Within these callback functions, we will be
 925          * setting/getting the global variable
 926          */
 927         { "_debug", MOD_PROTO_IP,
 928             ip_set_debug, ip_get_debug,
 929             {0, 20, 0}, {0} },
 930 
 931         { "hostmodel", MOD_PROTO_IPV4, ip_set_hostmodel, ip_get_hostmodel,
 932             {IP_WEAK_ES, IP_STRONG_ES, IP_WEAK_ES}, {IP_WEAK_ES} },
 933 
 934         { "hostmodel", MOD_PROTO_IPV6, ip_set_hostmodel, ip_get_hostmodel,
 935             {IP_WEAK_ES, IP_STRONG_ES, IP_WEAK_ES}, {IP_WEAK_ES} },
 936 
 937         { "?", MOD_PROTO_IP, NULL, mod_get_allprop, {0}, {0} },
 938 
 939         { NULL, 0, NULL, NULL, {0}, {0} }
 940 };
 941 
 942 int ip_propinfo_count = A_CNT(ip_propinfo_tbl);