Print this page
    
dccp: properties
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/inet/ip/ip_if.c
          +++ new/usr/src/uts/common/inet/ip/ip_if.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 1990 Mentat Inc.
  24   24   */
  25   25  
  26   26  /*
  27   27   * This file contains the interface control functions for IP.
  28   28   */
  29   29  
  30   30  #include <sys/types.h>
  31   31  #include <sys/stream.h>
  32   32  #include <sys/dlpi.h>
  33   33  #include <sys/stropts.h>
  34   34  #include <sys/strsun.h>
  35   35  #include <sys/sysmacros.h>
  36   36  #include <sys/strsubr.h>
  37   37  #include <sys/strlog.h>
  38   38  #include <sys/ddi.h>
  39   39  #include <sys/sunddi.h>
  40   40  #include <sys/cmn_err.h>
  41   41  #include <sys/kstat.h>
  42   42  #include <sys/debug.h>
  43   43  #include <sys/zone.h>
  44   44  #include <sys/sunldi.h>
  45   45  #include <sys/file.h>
  46   46  #include <sys/bitmap.h>
  47   47  #include <sys/cpuvar.h>
  48   48  #include <sys/time.h>
  49   49  #include <sys/ctype.h>
  50   50  #include <sys/kmem.h>
  51   51  #include <sys/systm.h>
  52   52  #include <sys/param.h>
  53   53  #include <sys/socket.h>
  54   54  #include <sys/isa_defs.h>
  55   55  #include <net/if.h>
  56   56  #include <net/if_arp.h>
  57   57  #include <net/if_types.h>
  58   58  #include <net/if_dl.h>
  59   59  #include <net/route.h>
  60   60  #include <sys/sockio.h>
  61   61  #include <netinet/in.h>
  62   62  #include <netinet/ip6.h>
  63   63  #include <netinet/icmp6.h>
  64   64  #include <netinet/igmp_var.h>
  65   65  #include <sys/policy.h>
  66   66  #include <sys/ethernet.h>
  67   67  #include <sys/callb.h>
  68   68  #include <sys/md5.h>
  69   69  
  70   70  #include <inet/common.h>   /* for various inet/mi.h and inet/nd.h needs */
  71   71  #include <inet/mi.h>
  72   72  #include <inet/nd.h>
  73   73  #include <inet/tunables.h>
  74   74  #include <inet/arp.h>
  75   75  #include <inet/ip_arp.h>
  76   76  #include <inet/mib2.h>
  77   77  #include <inet/ip.h>
  78   78  #include <inet/ip6.h>
  79   79  #include <inet/ip6_asp.h>
  80   80  #include <inet/tcp.h>
  81   81  #include <inet/ip_multi.h>
  82   82  #include <inet/ip_ire.h>
  83   83  #include <inet/ip_ftable.h>
  84   84  #include <inet/ip_rts.h>
  85   85  #include <inet/ip_ndp.h>
  86   86  #include <inet/ip_if.h>
  87   87  #include <inet/ip_impl.h>
  88   88  #include <inet/sctp_ip.h>
  89   89  #include <inet/ip_netinfo.h>
  90   90  #include <inet/ilb_ip.h>
  91   91  
  92   92  #include <netinet/igmp.h>
  93   93  #include <inet/ip_listutils.h>
  94   94  #include <inet/ipclassifier.h>
  95   95  #include <sys/mac_client.h>
  96   96  #include <sys/dld.h>
  
    | 
      ↓ open down ↓ | 
    96 lines elided | 
    
      ↑ open up ↑ | 
  
  97   97  #include <sys/mac_flow.h>
  98   98  
  99   99  #include <sys/systeminfo.h>
 100  100  #include <sys/bootconf.h>
 101  101  
 102  102  #include <sys/tsol/tndb.h>
 103  103  #include <sys/tsol/tnet.h>
 104  104  
 105  105  #include <inet/rawip_impl.h> /* needed for icmp_stack_t */
 106  106  #include <inet/udp_impl.h> /* needed for udp_stack_t */
      107 +#include <inet/dccp/dccp_stack.h> /* needed for dccp_stack_t */
 107  108  
 108  109  /* The character which tells where the ill_name ends */
 109  110  #define IPIF_SEPARATOR_CHAR     ':'
 110  111  
 111  112  /* IP ioctl function table entry */
 112  113  typedef struct ipft_s {
 113  114          int     ipft_cmd;
 114  115          pfi_t   ipft_pfi;
 115  116          int     ipft_min_size;
 116  117          int     ipft_flags;
 117  118  } ipft_t;
 118  119  #define IPFT_F_NO_REPLY         0x1     /* IP ioctl does not expect any reply */
 119  120  #define IPFT_F_SELF_REPLY       0x2     /* ioctl callee does the ioctl reply */
 120  121  
 121  122  static int      nd_ill_forward_get(queue_t *, mblk_t *, caddr_t, cred_t *);
 122  123  static int      nd_ill_forward_set(queue_t *q, mblk_t *mp,
 123  124                      char *value, caddr_t cp, cred_t *ioc_cr);
 124  125  
 125  126  static boolean_t ill_is_quiescent(ill_t *);
 126  127  static boolean_t ip_addr_ok_v4(ipaddr_t addr, ipaddr_t subnet_mask);
 127  128  static ip_m_t   *ip_m_lookup(t_uscalar_t mac_type);
 128  129  static int      ip_sioctl_addr_tail(ipif_t *ipif, sin_t *sin, queue_t *q,
 129  130      mblk_t *mp, boolean_t need_up);
 130  131  static int      ip_sioctl_dstaddr_tail(ipif_t *ipif, sin_t *sin, queue_t *q,
 131  132      mblk_t *mp, boolean_t need_up);
 132  133  static int      ip_sioctl_slifzone_tail(ipif_t *ipif, zoneid_t zoneid,
 133  134      queue_t *q, mblk_t *mp, boolean_t need_up);
 134  135  static int      ip_sioctl_flags_tail(ipif_t *ipif, uint64_t flags, queue_t *q,
 135  136      mblk_t *mp);
 136  137  static int      ip_sioctl_netmask_tail(ipif_t *ipif, sin_t *sin, queue_t *q,
 137  138      mblk_t *mp);
 138  139  static int      ip_sioctl_subnet_tail(ipif_t *ipif, in6_addr_t, in6_addr_t,
 139  140      queue_t *q, mblk_t *mp, boolean_t need_up);
 140  141  static int      ip_sioctl_plink_ipmod(ipsq_t *ipsq, queue_t *q, mblk_t *mp,
 141  142      int ioccmd, struct linkblk *li);
 142  143  static ipaddr_t ip_subnet_mask(ipaddr_t addr, ipif_t **, ip_stack_t *);
 143  144  static void     ip_wput_ioctl(queue_t *q, mblk_t *mp);
 144  145  static void     ipsq_flush(ill_t *ill);
 145  146  
 146  147  static  int     ip_sioctl_token_tail(ipif_t *ipif, sin6_t *sin6, int addrlen,
 147  148      queue_t *q, mblk_t *mp, boolean_t need_up);
 148  149  static void     ipsq_delete(ipsq_t *);
 149  150  
 150  151  static ipif_t   *ipif_allocate(ill_t *ill, int id, uint_t ire_type,
 151  152      boolean_t initialize, boolean_t insert, int *errorp);
 152  153  static ire_t    **ipif_create_bcast_ires(ipif_t *ipif, ire_t **irep);
 153  154  static void     ipif_delete_bcast_ires(ipif_t *ipif);
 154  155  static int      ipif_add_ires_v4(ipif_t *, boolean_t);
 155  156  static boolean_t ipif_comp_multi(ipif_t *old_ipif, ipif_t *new_ipif,
 156  157                      boolean_t isv6);
 157  158  static int      ipif_logical_down(ipif_t *ipif, queue_t *q, mblk_t *mp);
 158  159  static void     ipif_free(ipif_t *ipif);
 159  160  static void     ipif_free_tail(ipif_t *ipif);
 160  161  static void     ipif_set_default(ipif_t *ipif);
 161  162  static int      ipif_set_values(queue_t *q, mblk_t *mp,
 162  163      char *interf_name, uint_t *ppa);
 163  164  static int      ipif_set_values_tail(ill_t *ill, ipif_t *ipif, mblk_t *mp,
 164  165      queue_t *q);
 165  166  static ipif_t   *ipif_lookup_on_name(char *name, size_t namelen,
 166  167      boolean_t do_alloc, boolean_t *exists, boolean_t isv6, zoneid_t zoneid,
 167  168      ip_stack_t *);
 168  169  static ipif_t   *ipif_lookup_on_name_async(char *name, size_t namelen,
 169  170      boolean_t isv6, zoneid_t zoneid, queue_t *q, mblk_t *mp, ipsq_func_t func,
 170  171      int *error, ip_stack_t *);
 171  172  
 172  173  static int      ill_alloc_ppa(ill_if_t *, ill_t *);
 173  174  static void     ill_delete_interface_type(ill_if_t *);
 174  175  static int      ill_dl_up(ill_t *ill, ipif_t *ipif, mblk_t *mp, queue_t *q);
 175  176  static void     ill_dl_down(ill_t *ill);
 176  177  static void     ill_down(ill_t *ill);
 177  178  static void     ill_down_ipifs(ill_t *, boolean_t);
 178  179  static void     ill_free_mib(ill_t *ill);
 179  180  static void     ill_glist_delete(ill_t *);
 180  181  static void     ill_phyint_reinit(ill_t *ill);
 181  182  static void     ill_set_nce_router_flags(ill_t *, boolean_t);
 182  183  static void     ill_set_phys_addr_tail(ipsq_t *, queue_t *, mblk_t *, void *);
 183  184  static void     ill_replumb_tail(ipsq_t *, queue_t *, mblk_t *, void *);
 184  185  
 185  186  static ip_v6intfid_func_t ip_ether_v6intfid, ip_ib_v6intfid;
 186  187  static ip_v6intfid_func_t ip_ipv4_v6intfid, ip_ipv6_v6intfid;
 187  188  static ip_v6intfid_func_t ip_ipmp_v6intfid, ip_nodef_v6intfid;
 188  189  static ip_v6intfid_func_t ip_ipv4_v6destintfid, ip_ipv6_v6destintfid;
 189  190  static ip_v4mapinfo_func_t ip_ether_v4_mapping;
 190  191  static ip_v6mapinfo_func_t ip_ether_v6_mapping;
 191  192  static ip_v4mapinfo_func_t ip_ib_v4_mapping;
 192  193  static ip_v6mapinfo_func_t ip_ib_v6_mapping;
 193  194  static ip_v4mapinfo_func_t ip_mbcast_mapping;
 194  195  static void     ip_cgtp_bcast_add(ire_t *, ip_stack_t *);
 195  196  static void     ip_cgtp_bcast_delete(ire_t *, ip_stack_t *);
 196  197  static void     phyint_free(phyint_t *);
 197  198  
 198  199  static void ill_capability_dispatch(ill_t *, mblk_t *, dl_capability_sub_t *);
 199  200  static void ill_capability_id_ack(ill_t *, mblk_t *, dl_capability_sub_t *);
 200  201  static void ill_capability_vrrp_ack(ill_t *, mblk_t *, dl_capability_sub_t *);
 201  202  static void ill_capability_hcksum_ack(ill_t *, mblk_t *, dl_capability_sub_t *);
 202  203  static void ill_capability_hcksum_reset_fill(ill_t *, mblk_t *);
 203  204  static void ill_capability_zerocopy_ack(ill_t *, mblk_t *,
 204  205      dl_capability_sub_t *);
 205  206  static void ill_capability_zerocopy_reset_fill(ill_t *, mblk_t *);
 206  207  static void     ill_capability_dld_reset_fill(ill_t *, mblk_t *);
 207  208  static void     ill_capability_dld_ack(ill_t *, mblk_t *,
 208  209                      dl_capability_sub_t *);
 209  210  static void     ill_capability_dld_enable(ill_t *);
 210  211  static void     ill_capability_ack_thr(void *);
 211  212  static void     ill_capability_lso_enable(ill_t *);
 212  213  
 213  214  static ill_t    *ill_prev_usesrc(ill_t *);
 214  215  static int      ill_relink_usesrc_ills(ill_t *, ill_t *, uint_t);
 215  216  static void     ill_disband_usesrc_group(ill_t *);
 216  217  static void     ip_sioctl_garp_reply(mblk_t *, ill_t *, void *, int);
 217  218  
 218  219  #ifdef DEBUG
 219  220  static  void    ill_trace_cleanup(const ill_t *);
 220  221  static  void    ipif_trace_cleanup(const ipif_t *);
 221  222  #endif
 222  223  
 223  224  static  void    ill_dlpi_clear_deferred(ill_t *ill);
 224  225  
 225  226  /*
 226  227   * if we go over the memory footprint limit more than once in this msec
 227  228   * interval, we'll start pruning aggressively.
 228  229   */
 229  230  int ip_min_frag_prune_time = 0;
 230  231  
 231  232  static ipft_t   ip_ioctl_ftbl[] = {
 232  233          { IP_IOC_IRE_DELETE, ip_ire_delete, sizeof (ipid_t), 0 },
 233  234          { IP_IOC_IRE_DELETE_NO_REPLY, ip_ire_delete, sizeof (ipid_t),
 234  235                  IPFT_F_NO_REPLY },
 235  236          { IP_IOC_RTS_REQUEST, ip_rts_request, 0, IPFT_F_SELF_REPLY },
 236  237          { 0 }
 237  238  };
 238  239  
 239  240  /* Simple ICMP IP Header Template */
 240  241  static ipha_t icmp_ipha = {
 241  242          IP_SIMPLE_HDR_VERSION, 0, 0, 0, 0, 0, IPPROTO_ICMP
 242  243  };
 243  244  
 244  245  static uchar_t  ip_six_byte_all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 245  246  
 246  247  static ip_m_t   ip_m_tbl[] = {
 247  248          { DL_ETHER, IFT_ETHER, ETHERTYPE_IP, ETHERTYPE_IPV6,
 248  249              ip_ether_v4_mapping, ip_ether_v6_mapping, ip_ether_v6intfid,
 249  250              ip_nodef_v6intfid },
 250  251          { DL_CSMACD, IFT_ISO88023, ETHERTYPE_IP, ETHERTYPE_IPV6,
 251  252              ip_ether_v4_mapping, ip_ether_v6_mapping, ip_nodef_v6intfid,
 252  253              ip_nodef_v6intfid },
 253  254          { DL_TPB, IFT_ISO88024, ETHERTYPE_IP, ETHERTYPE_IPV6,
 254  255              ip_ether_v4_mapping, ip_ether_v6_mapping, ip_nodef_v6intfid,
 255  256              ip_nodef_v6intfid },
 256  257          { DL_TPR, IFT_ISO88025, ETHERTYPE_IP, ETHERTYPE_IPV6,
 257  258              ip_ether_v4_mapping, ip_ether_v6_mapping, ip_nodef_v6intfid,
 258  259              ip_nodef_v6intfid },
 259  260          { DL_FDDI, IFT_FDDI, ETHERTYPE_IP, ETHERTYPE_IPV6,
 260  261              ip_ether_v4_mapping, ip_ether_v6_mapping, ip_ether_v6intfid,
 261  262              ip_nodef_v6intfid },
 262  263          { DL_IB, IFT_IB, ETHERTYPE_IP, ETHERTYPE_IPV6,
 263  264              ip_ib_v4_mapping, ip_ib_v6_mapping, ip_ib_v6intfid,
 264  265              ip_nodef_v6intfid },
 265  266          { DL_IPV4, IFT_IPV4, IPPROTO_ENCAP, IPPROTO_IPV6,
 266  267              ip_mbcast_mapping, ip_mbcast_mapping, ip_ipv4_v6intfid,
 267  268              ip_ipv4_v6destintfid },
 268  269          { DL_IPV6, IFT_IPV6, IPPROTO_ENCAP, IPPROTO_IPV6,
 269  270              ip_mbcast_mapping, ip_mbcast_mapping, ip_ipv6_v6intfid,
 270  271              ip_ipv6_v6destintfid },
 271  272          { DL_6TO4, IFT_6TO4, IPPROTO_ENCAP, IPPROTO_IPV6,
 272  273              ip_mbcast_mapping, ip_mbcast_mapping, ip_ipv4_v6intfid,
 273  274              ip_nodef_v6intfid },
 274  275          { SUNW_DL_VNI, IFT_OTHER, ETHERTYPE_IP, ETHERTYPE_IPV6,
 275  276              NULL, NULL, ip_nodef_v6intfid, ip_nodef_v6intfid },
 276  277          { SUNW_DL_IPMP, IFT_OTHER, ETHERTYPE_IP, ETHERTYPE_IPV6,
 277  278              NULL, NULL, ip_ipmp_v6intfid, ip_nodef_v6intfid },
 278  279          { DL_OTHER, IFT_OTHER, ETHERTYPE_IP, ETHERTYPE_IPV6,
 279  280              ip_ether_v4_mapping, ip_ether_v6_mapping, ip_nodef_v6intfid,
 280  281              ip_nodef_v6intfid }
 281  282  };
 282  283  
 283  284  static ill_t    ill_null;               /* Empty ILL for init. */
 284  285  char    ipif_loopback_name[] = "lo0";
 285  286  
 286  287  /* These are used by all IP network modules. */
 287  288  sin6_t  sin6_null;      /* Zero address for quick clears */
 288  289  sin_t   sin_null;       /* Zero address for quick clears */
 289  290  
 290  291  /* When set search for unused ipif_seqid */
 291  292  static ipif_t   ipif_zero;
 292  293  
 293  294  /*
 294  295   * ppa arena is created after these many
 295  296   * interfaces have been plumbed.
 296  297   */
 297  298  uint_t  ill_no_arena = 12;      /* Setable in /etc/system */
 298  299  
 299  300  /*
 300  301   * Allocate per-interface mibs.
 301  302   * Returns true if ok. False otherwise.
 302  303   *  ipsq  may not yet be allocated (loopback case ).
 303  304   */
 304  305  static boolean_t
 305  306  ill_allocate_mibs(ill_t *ill)
 306  307  {
 307  308          /* Already allocated? */
 308  309          if (ill->ill_ip_mib != NULL) {
 309  310                  if (ill->ill_isv6)
 310  311                          ASSERT(ill->ill_icmp6_mib != NULL);
 311  312                  return (B_TRUE);
 312  313          }
 313  314  
 314  315          ill->ill_ip_mib = kmem_zalloc(sizeof (*ill->ill_ip_mib),
 315  316              KM_NOSLEEP);
 316  317          if (ill->ill_ip_mib == NULL) {
 317  318                  return (B_FALSE);
 318  319          }
 319  320  
 320  321          /* Setup static information */
 321  322          SET_MIB(ill->ill_ip_mib->ipIfStatsEntrySize,
 322  323              sizeof (mib2_ipIfStatsEntry_t));
 323  324          if (ill->ill_isv6) {
 324  325                  ill->ill_ip_mib->ipIfStatsIPVersion = MIB2_INETADDRESSTYPE_ipv6;
 325  326                  SET_MIB(ill->ill_ip_mib->ipIfStatsAddrEntrySize,
 326  327                      sizeof (mib2_ipv6AddrEntry_t));
 327  328                  SET_MIB(ill->ill_ip_mib->ipIfStatsRouteEntrySize,
 328  329                      sizeof (mib2_ipv6RouteEntry_t));
 329  330                  SET_MIB(ill->ill_ip_mib->ipIfStatsNetToMediaEntrySize,
 330  331                      sizeof (mib2_ipv6NetToMediaEntry_t));
 331  332                  SET_MIB(ill->ill_ip_mib->ipIfStatsMemberEntrySize,
 332  333                      sizeof (ipv6_member_t));
 333  334                  SET_MIB(ill->ill_ip_mib->ipIfStatsGroupSourceEntrySize,
 334  335                      sizeof (ipv6_grpsrc_t));
 335  336          } else {
 336  337                  ill->ill_ip_mib->ipIfStatsIPVersion = MIB2_INETADDRESSTYPE_ipv4;
 337  338                  SET_MIB(ill->ill_ip_mib->ipIfStatsAddrEntrySize,
 338  339                      sizeof (mib2_ipAddrEntry_t));
 339  340                  SET_MIB(ill->ill_ip_mib->ipIfStatsRouteEntrySize,
 340  341                      sizeof (mib2_ipRouteEntry_t));
 341  342                  SET_MIB(ill->ill_ip_mib->ipIfStatsNetToMediaEntrySize,
 342  343                      sizeof (mib2_ipNetToMediaEntry_t));
 343  344                  SET_MIB(ill->ill_ip_mib->ipIfStatsMemberEntrySize,
 344  345                      sizeof (ip_member_t));
 345  346                  SET_MIB(ill->ill_ip_mib->ipIfStatsGroupSourceEntrySize,
 346  347                      sizeof (ip_grpsrc_t));
 347  348  
 348  349                  /*
 349  350                   * For a v4 ill, we are done at this point, because per ill
 350  351                   * icmp mibs are only used for v6.
 351  352                   */
 352  353                  return (B_TRUE);
 353  354          }
 354  355  
 355  356          ill->ill_icmp6_mib = kmem_zalloc(sizeof (*ill->ill_icmp6_mib),
 356  357              KM_NOSLEEP);
 357  358          if (ill->ill_icmp6_mib == NULL) {
 358  359                  kmem_free(ill->ill_ip_mib, sizeof (*ill->ill_ip_mib));
 359  360                  ill->ill_ip_mib = NULL;
 360  361                  return (B_FALSE);
 361  362          }
 362  363          /* static icmp info */
 363  364          ill->ill_icmp6_mib->ipv6IfIcmpEntrySize =
 364  365              sizeof (mib2_ipv6IfIcmpEntry_t);
 365  366          /*
 366  367           * The ipIfStatsIfindex and ipv6IfIcmpIndex will be assigned later
 367  368           * after the phyint merge occurs in ipif_set_values -> ill_glist_insert
 368  369           * -> ill_phyint_reinit
 369  370           */
 370  371          return (B_TRUE);
 371  372  }
 372  373  
 373  374  /*
 374  375   * Completely vaporize a lower level tap and all associated interfaces.
 375  376   * ill_delete is called only out of ip_close when the device control
 376  377   * stream is being closed.
 377  378   */
 378  379  void
 379  380  ill_delete(ill_t *ill)
 380  381  {
 381  382          ipif_t  *ipif;
 382  383          ill_t   *prev_ill;
 383  384          ip_stack_t      *ipst = ill->ill_ipst;
 384  385  
 385  386          /*
 386  387           * ill_delete may be forcibly entering the ipsq. The previous
 387  388           * ioctl may not have completed and may need to be aborted.
 388  389           * ipsq_flush takes care of it. If we don't need to enter the
 389  390           * the ipsq forcibly, the 2nd invocation of ipsq_flush in
 390  391           * ill_delete_tail is sufficient.
 391  392           */
 392  393          ipsq_flush(ill);
 393  394  
 394  395          /*
 395  396           * Nuke all interfaces.  ipif_free will take down the interface,
 396  397           * remove it from the list, and free the data structure.
 397  398           * Walk down the ipif list and remove the logical interfaces
 398  399           * first before removing the main ipif. We can't unplumb
 399  400           * zeroth interface first in the case of IPv6 as update_conn_ill
 400  401           * -> ip_ll_multireq de-references ill_ipif for checking
 401  402           * POINTOPOINT.
 402  403           *
 403  404           * If ill_ipif was not properly initialized (i.e low on memory),
 404  405           * then no interfaces to clean up. In this case just clean up the
 405  406           * ill.
 406  407           */
 407  408          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next)
 408  409                  ipif_free(ipif);
 409  410  
 410  411          /*
 411  412           * clean out all the nce_t entries that depend on this
 412  413           * ill for the ill_phys_addr.
 413  414           */
 414  415          nce_flush(ill, B_TRUE);
 415  416  
 416  417          /* Clean up msgs on pending upcalls for mrouted */
 417  418          reset_mrt_ill(ill);
 418  419  
 419  420          update_conn_ill(ill, ipst);
 420  421  
 421  422          /*
 422  423           * Remove multicast references added as a result of calls to
 423  424           * ip_join_allmulti().
 424  425           */
 425  426          ip_purge_allmulti(ill);
 426  427  
 427  428          /*
 428  429           * If the ill being deleted is under IPMP, boot it out of the illgrp.
 429  430           */
 430  431          if (IS_UNDER_IPMP(ill))
 431  432                  ipmp_ill_leave_illgrp(ill);
 432  433  
 433  434          /*
 434  435           * ill_down will arrange to blow off any IRE's dependent on this
 435  436           * ILL, and shut down fragmentation reassembly.
 436  437           */
 437  438          ill_down(ill);
 438  439  
 439  440          /* Let SCTP know, so that it can remove this from its list. */
 440  441          sctp_update_ill(ill, SCTP_ILL_REMOVE);
 441  442  
 442  443          /*
 443  444           * Walk all CONNs that can have a reference on an ire or nce for this
 444  445           * ill (we actually walk all that now have stale references).
 445  446           */
 446  447          ipcl_walk(conn_ixa_cleanup, (void *)B_TRUE, ipst);
 447  448  
 448  449          /* With IPv6 we have dce_ifindex. Cleanup for neatness */
 449  450          if (ill->ill_isv6)
 450  451                  dce_cleanup(ill->ill_phyint->phyint_ifindex, ipst);
 451  452  
 452  453          /*
 453  454           * If an address on this ILL is being used as a source address then
 454  455           * clear out the pointers in other ILLs that point to this ILL.
 455  456           */
 456  457          rw_enter(&ipst->ips_ill_g_usesrc_lock, RW_WRITER);
 457  458          if (ill->ill_usesrc_grp_next != NULL) {
 458  459                  if (ill->ill_usesrc_ifindex == 0) { /* usesrc ILL ? */
 459  460                          ill_disband_usesrc_group(ill);
 460  461                  } else {        /* consumer of the usesrc ILL */
 461  462                          prev_ill = ill_prev_usesrc(ill);
 462  463                          prev_ill->ill_usesrc_grp_next =
 463  464                              ill->ill_usesrc_grp_next;
 464  465                  }
 465  466          }
 466  467          rw_exit(&ipst->ips_ill_g_usesrc_lock);
 467  468  }
 468  469  
 469  470  static void
 470  471  ipif_non_duplicate(ipif_t *ipif)
 471  472  {
 472  473          ill_t *ill = ipif->ipif_ill;
 473  474          mutex_enter(&ill->ill_lock);
 474  475          if (ipif->ipif_flags & IPIF_DUPLICATE) {
 475  476                  ipif->ipif_flags &= ~IPIF_DUPLICATE;
 476  477                  ASSERT(ill->ill_ipif_dup_count > 0);
 477  478                  ill->ill_ipif_dup_count--;
 478  479          }
 479  480          mutex_exit(&ill->ill_lock);
 480  481  }
 481  482  
 482  483  /*
 483  484   * ill_delete_tail is called from ip_modclose after all references
 484  485   * to the closing ill are gone. The wait is done in ip_modclose
 485  486   */
 486  487  void
 487  488  ill_delete_tail(ill_t *ill)
 488  489  {
 489  490          mblk_t  **mpp;
 490  491          ipif_t  *ipif;
 491  492          ip_stack_t *ipst = ill->ill_ipst;
 492  493  
 493  494          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
 494  495                  ipif_non_duplicate(ipif);
 495  496                  (void) ipif_down_tail(ipif);
 496  497          }
 497  498  
 498  499          ASSERT(ill->ill_ipif_dup_count == 0);
 499  500  
 500  501          /*
 501  502           * If polling capability is enabled (which signifies direct
 502  503           * upcall into IP and driver has ill saved as a handle),
 503  504           * we need to make sure that unbind has completed before we
 504  505           * let the ill disappear and driver no longer has any reference
 505  506           * to this ill.
 506  507           */
 507  508          mutex_enter(&ill->ill_lock);
 508  509          while (ill->ill_state_flags & ILL_DL_UNBIND_IN_PROGRESS)
 509  510                  cv_wait(&ill->ill_cv, &ill->ill_lock);
 510  511          mutex_exit(&ill->ill_lock);
 511  512          ASSERT(!(ill->ill_capabilities &
 512  513              (ILL_CAPAB_DLD | ILL_CAPAB_DLD_POLL | ILL_CAPAB_DLD_DIRECT)));
 513  514  
 514  515          if (ill->ill_net_type != IRE_LOOPBACK)
 515  516                  qprocsoff(ill->ill_rq);
 516  517  
 517  518          /*
 518  519           * We do an ipsq_flush once again now. New messages could have
 519  520           * landed up from below (M_ERROR or M_HANGUP). Similarly ioctls
 520  521           * could also have landed up if an ioctl thread had looked up
 521  522           * the ill before we set the ILL_CONDEMNED flag, but not yet
 522  523           * enqueued the ioctl when we did the ipsq_flush last time.
 523  524           */
 524  525          ipsq_flush(ill);
 525  526  
 526  527          /*
 527  528           * Free capabilities.
 528  529           */
 529  530          if (ill->ill_hcksum_capab != NULL) {
 530  531                  kmem_free(ill->ill_hcksum_capab, sizeof (ill_hcksum_capab_t));
 531  532                  ill->ill_hcksum_capab = NULL;
 532  533          }
 533  534  
 534  535          if (ill->ill_zerocopy_capab != NULL) {
 535  536                  kmem_free(ill->ill_zerocopy_capab,
 536  537                      sizeof (ill_zerocopy_capab_t));
 537  538                  ill->ill_zerocopy_capab = NULL;
 538  539          }
 539  540  
 540  541          if (ill->ill_lso_capab != NULL) {
 541  542                  kmem_free(ill->ill_lso_capab, sizeof (ill_lso_capab_t));
 542  543                  ill->ill_lso_capab = NULL;
 543  544          }
 544  545  
 545  546          if (ill->ill_dld_capab != NULL) {
 546  547                  kmem_free(ill->ill_dld_capab, sizeof (ill_dld_capab_t));
 547  548                  ill->ill_dld_capab = NULL;
 548  549          }
 549  550  
 550  551          /* Clean up ill_allowed_ips* related state */
 551  552          if (ill->ill_allowed_ips != NULL) {
 552  553                  ASSERT(ill->ill_allowed_ips_cnt > 0);
 553  554                  kmem_free(ill->ill_allowed_ips,
 554  555                      ill->ill_allowed_ips_cnt * sizeof (in6_addr_t));
 555  556                  ill->ill_allowed_ips = NULL;
 556  557                  ill->ill_allowed_ips_cnt = 0;
 557  558          }
 558  559  
 559  560          while (ill->ill_ipif != NULL)
 560  561                  ipif_free_tail(ill->ill_ipif);
 561  562  
 562  563          /*
 563  564           * We have removed all references to ilm from conn and the ones joined
 564  565           * within the kernel.
 565  566           *
 566  567           * We don't walk conns, mrts and ires because
 567  568           *
 568  569           * 1) update_conn_ill and reset_mrt_ill cleans up conns and mrts.
 569  570           * 2) ill_down ->ill_downi walks all the ires and cleans up
 570  571           *    ill references.
 571  572           */
 572  573  
 573  574          /*
 574  575           * If this ill is an IPMP meta-interface, blow away the illgrp.  This
 575  576           * is safe to do because the illgrp has already been unlinked from the
 576  577           * group by I_PUNLINK, and thus SIOCSLIFGROUPNAME cannot find it.
 577  578           */
 578  579          if (IS_IPMP(ill)) {
 579  580                  ipmp_illgrp_destroy(ill->ill_grp);
 580  581                  ill->ill_grp = NULL;
 581  582          }
 582  583  
 583  584          if (ill->ill_mphysaddr_list != NULL) {
 584  585                  multiphysaddr_t *mpa, *tmpa;
 585  586  
 586  587                  mpa = ill->ill_mphysaddr_list;
 587  588                  ill->ill_mphysaddr_list = NULL;
 588  589                  while (mpa) {
 589  590                          tmpa = mpa->mpa_next;
 590  591                          kmem_free(mpa, sizeof (*mpa));
 591  592                          mpa = tmpa;
 592  593                  }
 593  594          }
 594  595          /*
 595  596           * Take us out of the list of ILLs. ill_glist_delete -> phyint_free
 596  597           * could free the phyint. No more reference to the phyint after this
 597  598           * point.
 598  599           */
 599  600          (void) ill_glist_delete(ill);
 600  601  
 601  602          if (ill->ill_frag_ptr != NULL) {
 602  603                  uint_t count;
 603  604  
 604  605                  for (count = 0; count < ILL_FRAG_HASH_TBL_COUNT; count++) {
 605  606                          mutex_destroy(&ill->ill_frag_hash_tbl[count].ipfb_lock);
 606  607                  }
 607  608                  mi_free(ill->ill_frag_ptr);
 608  609                  ill->ill_frag_ptr = NULL;
 609  610                  ill->ill_frag_hash_tbl = NULL;
 610  611          }
 611  612  
 612  613          freemsg(ill->ill_nd_lla_mp);
 613  614          /* Free all retained control messages. */
 614  615          mpp = &ill->ill_first_mp_to_free;
 615  616          do {
 616  617                  while (mpp[0]) {
 617  618                          mblk_t  *mp;
 618  619                          mblk_t  *mp1;
 619  620  
 620  621                          mp = mpp[0];
 621  622                          mpp[0] = mp->b_next;
 622  623                          for (mp1 = mp; mp1 != NULL; mp1 = mp1->b_cont) {
 623  624                                  mp1->b_next = NULL;
 624  625                                  mp1->b_prev = NULL;
 625  626                          }
 626  627                          freemsg(mp);
 627  628                  }
 628  629          } while (mpp++ != &ill->ill_last_mp_to_free);
 629  630  
 630  631          ill_free_mib(ill);
 631  632  
 632  633  #ifdef DEBUG
 633  634          ill_trace_cleanup(ill);
 634  635  #endif
 635  636  
 636  637          /* The default multicast interface might have changed */
 637  638          ire_increment_multicast_generation(ipst, ill->ill_isv6);
 638  639  
 639  640          /* Drop refcnt here */
 640  641          netstack_rele(ill->ill_ipst->ips_netstack);
 641  642          ill->ill_ipst = NULL;
 642  643  }
 643  644  
 644  645  static void
 645  646  ill_free_mib(ill_t *ill)
 646  647  {
 647  648          ip_stack_t *ipst = ill->ill_ipst;
 648  649  
 649  650          /*
 650  651           * MIB statistics must not be lost, so when an interface
 651  652           * goes away the counter values will be added to the global
 652  653           * MIBs.
 653  654           */
 654  655          if (ill->ill_ip_mib != NULL) {
 655  656                  if (ill->ill_isv6) {
 656  657                          ip_mib2_add_ip_stats(&ipst->ips_ip6_mib,
 657  658                              ill->ill_ip_mib);
 658  659                  } else {
 659  660                          ip_mib2_add_ip_stats(&ipst->ips_ip_mib,
 660  661                              ill->ill_ip_mib);
 661  662                  }
 662  663  
 663  664                  kmem_free(ill->ill_ip_mib, sizeof (*ill->ill_ip_mib));
 664  665                  ill->ill_ip_mib = NULL;
 665  666          }
 666  667          if (ill->ill_icmp6_mib != NULL) {
 667  668                  ip_mib2_add_icmp6_stats(&ipst->ips_icmp6_mib,
 668  669                      ill->ill_icmp6_mib);
 669  670                  kmem_free(ill->ill_icmp6_mib, sizeof (*ill->ill_icmp6_mib));
 670  671                  ill->ill_icmp6_mib = NULL;
 671  672          }
 672  673  }
 673  674  
 674  675  /*
 675  676   * Concatenate together a physical address and a sap.
 676  677   *
 677  678   * Sap_lengths are interpreted as follows:
 678  679   *   sap_length == 0    ==>     no sap
 679  680   *   sap_length > 0     ==>     sap is at the head of the dlpi address
 680  681   *   sap_length < 0     ==>     sap is at the tail of the dlpi address
 681  682   */
 682  683  static void
 683  684  ill_dlur_copy_address(uchar_t *phys_src, uint_t phys_length,
 684  685      t_scalar_t sap_src, t_scalar_t sap_length, uchar_t *dst)
 685  686  {
 686  687          uint16_t sap_addr = (uint16_t)sap_src;
 687  688  
 688  689          if (sap_length == 0) {
 689  690                  if (phys_src == NULL)
 690  691                          bzero(dst, phys_length);
 691  692                  else
 692  693                          bcopy(phys_src, dst, phys_length);
 693  694          } else if (sap_length < 0) {
 694  695                  if (phys_src == NULL)
 695  696                          bzero(dst, phys_length);
 696  697                  else
 697  698                          bcopy(phys_src, dst, phys_length);
 698  699                  bcopy(&sap_addr, (char *)dst + phys_length, sizeof (sap_addr));
 699  700          } else {
 700  701                  bcopy(&sap_addr, dst, sizeof (sap_addr));
 701  702                  if (phys_src == NULL)
 702  703                          bzero((char *)dst + sap_length, phys_length);
 703  704                  else
 704  705                          bcopy(phys_src, (char *)dst + sap_length, phys_length);
 705  706          }
 706  707  }
 707  708  
 708  709  /*
 709  710   * Generate a dl_unitdata_req mblk for the device and address given.
 710  711   * addr_length is the length of the physical portion of the address.
 711  712   * If addr is NULL include an all zero address of the specified length.
 712  713   * TRUE? In any case, addr_length is taken to be the entire length of the
 713  714   * dlpi address, including the absolute value of sap_length.
 714  715   */
 715  716  mblk_t *
 716  717  ill_dlur_gen(uchar_t *addr, uint_t addr_length, t_uscalar_t sap,
 717  718                  t_scalar_t sap_length)
 718  719  {
 719  720          dl_unitdata_req_t *dlur;
 720  721          mblk_t  *mp;
 721  722          t_scalar_t      abs_sap_length;         /* absolute value */
 722  723  
 723  724          abs_sap_length = ABS(sap_length);
 724  725          mp = ip_dlpi_alloc(sizeof (*dlur) + addr_length + abs_sap_length,
 725  726              DL_UNITDATA_REQ);
 726  727          if (mp == NULL)
 727  728                  return (NULL);
 728  729          dlur = (dl_unitdata_req_t *)mp->b_rptr;
 729  730          /* HACK: accomodate incompatible DLPI drivers */
 730  731          if (addr_length == 8)
 731  732                  addr_length = 6;
 732  733          dlur->dl_dest_addr_length = addr_length + abs_sap_length;
 733  734          dlur->dl_dest_addr_offset = sizeof (*dlur);
 734  735          dlur->dl_priority.dl_min = 0;
 735  736          dlur->dl_priority.dl_max = 0;
 736  737          ill_dlur_copy_address(addr, addr_length, sap, sap_length,
 737  738              (uchar_t *)&dlur[1]);
 738  739          return (mp);
 739  740  }
 740  741  
 741  742  /*
 742  743   * Add the pending mp to the list. There can be only 1 pending mp
 743  744   * in the list. Any exclusive ioctl that needs to wait for a response
 744  745   * from another module or driver needs to use this function to set
 745  746   * the ipx_pending_mp to the ioctl mblk and wait for the response from
 746  747   * the other module/driver. This is also used while waiting for the
 747  748   * ipif/ill/ire refcnts to drop to zero in bringing down an ipif.
 748  749   */
 749  750  boolean_t
 750  751  ipsq_pending_mp_add(conn_t *connp, ipif_t *ipif, queue_t *q, mblk_t *add_mp,
 751  752      int waitfor)
 752  753  {
 753  754          ipxop_t *ipx = ipif->ipif_ill->ill_phyint->phyint_ipsq->ipsq_xop;
 754  755  
 755  756          ASSERT(IAM_WRITER_IPIF(ipif));
 756  757          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
 757  758          ASSERT((add_mp->b_next == NULL) && (add_mp->b_prev == NULL));
 758  759          ASSERT(ipx->ipx_pending_mp == NULL);
 759  760          /*
 760  761           * The caller may be using a different ipif than the one passed into
 761  762           * ipsq_current_start() (e.g., suppose an ioctl that came in on the V4
 762  763           * ill needs to wait for the V6 ill to quiesce).  So we can't ASSERT
 763  764           * that `ipx_current_ipif == ipif'.
 764  765           */
 765  766          ASSERT(ipx->ipx_current_ipif != NULL);
 766  767  
 767  768          /*
 768  769           * M_IOCDATA from ioctls, M_ERROR/M_HANGUP/M_PROTO/M_PCPROTO from the
 769  770           * driver.
 770  771           */
 771  772          ASSERT((DB_TYPE(add_mp) == M_IOCDATA) || (DB_TYPE(add_mp) == M_ERROR) ||
 772  773              (DB_TYPE(add_mp) == M_HANGUP) || (DB_TYPE(add_mp) == M_PROTO) ||
 773  774              (DB_TYPE(add_mp) == M_PCPROTO));
 774  775  
 775  776          if (connp != NULL) {
 776  777                  ASSERT(MUTEX_HELD(&connp->conn_lock));
 777  778                  /*
 778  779                   * Return error if the conn has started closing. The conn
 779  780                   * could have finished cleaning up the pending mp list,
 780  781                   * If so we should not add another mp to the list negating
 781  782                   * the cleanup.
 782  783                   */
 783  784                  if (connp->conn_state_flags & CONN_CLOSING)
 784  785                          return (B_FALSE);
 785  786          }
 786  787          mutex_enter(&ipx->ipx_lock);
 787  788          ipx->ipx_pending_ipif = ipif;
 788  789          /*
 789  790           * Note down the queue in b_queue. This will be returned by
 790  791           * ipsq_pending_mp_get. Caller will then use these values to restart
 791  792           * the processing
 792  793           */
 793  794          add_mp->b_next = NULL;
 794  795          add_mp->b_queue = q;
 795  796          ipx->ipx_pending_mp = add_mp;
 796  797          ipx->ipx_waitfor = waitfor;
 797  798          mutex_exit(&ipx->ipx_lock);
 798  799  
 799  800          if (connp != NULL)
 800  801                  connp->conn_oper_pending_ill = ipif->ipif_ill;
 801  802  
 802  803          return (B_TRUE);
 803  804  }
 804  805  
 805  806  /*
 806  807   * Retrieve the ipx_pending_mp and return it. There can be only 1 mp
 807  808   * queued in the list.
 808  809   */
 809  810  mblk_t *
 810  811  ipsq_pending_mp_get(ipsq_t *ipsq, conn_t **connpp)
 811  812  {
 812  813          mblk_t  *curr = NULL;
 813  814          ipxop_t *ipx = ipsq->ipsq_xop;
 814  815  
 815  816          *connpp = NULL;
 816  817          mutex_enter(&ipx->ipx_lock);
 817  818          if (ipx->ipx_pending_mp == NULL) {
 818  819                  mutex_exit(&ipx->ipx_lock);
 819  820                  return (NULL);
 820  821          }
 821  822  
 822  823          /* There can be only 1 such excl message */
 823  824          curr = ipx->ipx_pending_mp;
 824  825          ASSERT(curr->b_next == NULL);
 825  826          ipx->ipx_pending_ipif = NULL;
 826  827          ipx->ipx_pending_mp = NULL;
 827  828          ipx->ipx_waitfor = 0;
 828  829          mutex_exit(&ipx->ipx_lock);
 829  830  
 830  831          if (CONN_Q(curr->b_queue)) {
 831  832                  /*
 832  833                   * This mp did a refhold on the conn, at the start of the ioctl.
 833  834                   * So we can safely return a pointer to the conn to the caller.
 834  835                   */
 835  836                  *connpp = Q_TO_CONN(curr->b_queue);
 836  837          } else {
 837  838                  *connpp = NULL;
 838  839          }
 839  840          curr->b_next = NULL;
 840  841          curr->b_prev = NULL;
 841  842          return (curr);
 842  843  }
 843  844  
 844  845  /*
 845  846   * Cleanup the ioctl mp queued in ipx_pending_mp
 846  847   * - Called in the ill_delete path
 847  848   * - Called in the M_ERROR or M_HANGUP path on the ill.
 848  849   * - Called in the conn close path.
 849  850   *
 850  851   * Returns success on finding the pending mblk associated with the ioctl or
 851  852   * exclusive operation in progress, failure otherwise.
 852  853   */
 853  854  boolean_t
 854  855  ipsq_pending_mp_cleanup(ill_t *ill, conn_t *connp)
 855  856  {
 856  857          mblk_t  *mp;
 857  858          ipxop_t *ipx;
 858  859          queue_t *q;
 859  860          ipif_t  *ipif;
 860  861          int     cmd;
 861  862  
 862  863          ASSERT(IAM_WRITER_ILL(ill));
 863  864          ipx = ill->ill_phyint->phyint_ipsq->ipsq_xop;
 864  865  
 865  866          mutex_enter(&ipx->ipx_lock);
 866  867          mp = ipx->ipx_pending_mp;
 867  868          if (connp != NULL) {
 868  869                  if (mp == NULL || mp->b_queue != CONNP_TO_WQ(connp)) {
 869  870                          /*
 870  871                           * Nothing to clean since the conn that is closing
 871  872                           * does not have a matching pending mblk in
 872  873                           * ipx_pending_mp.
 873  874                           */
 874  875                          mutex_exit(&ipx->ipx_lock);
 875  876                          return (B_FALSE);
 876  877                  }
 877  878          } else {
 878  879                  /*
 879  880                   * A non-zero ill_error signifies we are called in the
 880  881                   * M_ERROR or M_HANGUP path and we need to unconditionally
 881  882                   * abort any current ioctl and do the corresponding cleanup.
 882  883                   * A zero ill_error means we are in the ill_delete path and
 883  884                   * we do the cleanup only if there is a pending mp.
 884  885                   */
 885  886                  if (mp == NULL && ill->ill_error == 0) {
 886  887                          mutex_exit(&ipx->ipx_lock);
 887  888                          return (B_FALSE);
 888  889                  }
 889  890          }
 890  891  
 891  892          /* Now remove from the ipx_pending_mp */
 892  893          ipx->ipx_pending_mp = NULL;
 893  894          ipif = ipx->ipx_pending_ipif;
 894  895          ipx->ipx_pending_ipif = NULL;
 895  896          ipx->ipx_waitfor = 0;
 896  897          ipx->ipx_current_ipif = NULL;
 897  898          cmd = ipx->ipx_current_ioctl;
 898  899          ipx->ipx_current_ioctl = 0;
 899  900          ipx->ipx_current_done = B_TRUE;
 900  901          mutex_exit(&ipx->ipx_lock);
 901  902  
 902  903          if (mp == NULL)
 903  904                  return (B_FALSE);
 904  905  
 905  906          q = mp->b_queue;
 906  907          mp->b_next = NULL;
 907  908          mp->b_prev = NULL;
 908  909          mp->b_queue = NULL;
 909  910  
 910  911          if (DB_TYPE(mp) == M_IOCTL || DB_TYPE(mp) == M_IOCDATA) {
 911  912                  DTRACE_PROBE4(ipif__ioctl,
 912  913                      char *, "ipsq_pending_mp_cleanup",
 913  914                      int, cmd, ill_t *, ipif == NULL ? NULL : ipif->ipif_ill,
 914  915                      ipif_t *, ipif);
 915  916                  if (connp == NULL) {
 916  917                          ip_ioctl_finish(q, mp, ENXIO, NO_COPYOUT, NULL);
 917  918                  } else {
 918  919                          ip_ioctl_finish(q, mp, ENXIO, CONN_CLOSE, NULL);
 919  920                          mutex_enter(&ipif->ipif_ill->ill_lock);
 920  921                          ipif->ipif_state_flags &= ~IPIF_CHANGING;
 921  922                          mutex_exit(&ipif->ipif_ill->ill_lock);
 922  923                  }
 923  924          } else {
 924  925                  inet_freemsg(mp);
 925  926          }
 926  927          return (B_TRUE);
 927  928  }
 928  929  
 929  930  /*
 930  931   * Called in the conn close path and ill delete path
 931  932   */
 932  933  static void
 933  934  ipsq_xopq_mp_cleanup(ill_t *ill, conn_t *connp)
 934  935  {
 935  936          ipsq_t  *ipsq;
 936  937          mblk_t  *prev;
 937  938          mblk_t  *curr;
 938  939          mblk_t  *next;
 939  940          queue_t *wq, *rq = NULL;
 940  941          mblk_t  *tmp_list = NULL;
 941  942  
 942  943          ASSERT(IAM_WRITER_ILL(ill));
 943  944          if (connp != NULL)
 944  945                  wq = CONNP_TO_WQ(connp);
 945  946          else
 946  947                  wq = ill->ill_wq;
 947  948  
 948  949          /*
 949  950           * In the case of lo0 being unplumbed, ill_wq will be NULL. Guard
 950  951           * against this here.
 951  952           */
 952  953          if (wq != NULL)
 953  954                  rq = RD(wq);
 954  955  
 955  956          ipsq = ill->ill_phyint->phyint_ipsq;
 956  957          /*
 957  958           * Cleanup the ioctl mp's queued in ipsq_xopq_pending_mp if any.
 958  959           * In the case of ioctl from a conn, there can be only 1 mp
 959  960           * queued on the ipsq. If an ill is being unplumbed flush all
 960  961           * the messages.
 961  962           */
 962  963          mutex_enter(&ipsq->ipsq_lock);
 963  964          for (prev = NULL, curr = ipsq->ipsq_xopq_mphead; curr != NULL;
 964  965              curr = next) {
 965  966                  next = curr->b_next;
 966  967                  if (connp == NULL ||
 967  968                      (curr->b_queue == wq || curr->b_queue == rq)) {
 968  969                          /* Unlink the mblk from the pending mp list */
 969  970                          if (prev != NULL) {
 970  971                                  prev->b_next = curr->b_next;
 971  972                          } else {
 972  973                                  ASSERT(ipsq->ipsq_xopq_mphead == curr);
 973  974                                  ipsq->ipsq_xopq_mphead = curr->b_next;
 974  975                          }
 975  976                          if (ipsq->ipsq_xopq_mptail == curr)
 976  977                                  ipsq->ipsq_xopq_mptail = prev;
 977  978                          /*
 978  979                           * Create a temporary list and release the ipsq lock
 979  980                           * New elements are added to the head of the tmp_list
 980  981                           */
 981  982                          curr->b_next = tmp_list;
 982  983                          tmp_list = curr;
 983  984                  } else {
 984  985                          prev = curr;
 985  986                  }
 986  987          }
 987  988          mutex_exit(&ipsq->ipsq_lock);
 988  989  
 989  990          while (tmp_list != NULL) {
 990  991                  curr = tmp_list;
 991  992                  tmp_list = curr->b_next;
 992  993                  curr->b_next = NULL;
 993  994                  curr->b_prev = NULL;
 994  995                  wq = curr->b_queue;
 995  996                  curr->b_queue = NULL;
 996  997                  if (DB_TYPE(curr) == M_IOCTL || DB_TYPE(curr) == M_IOCDATA) {
 997  998                          DTRACE_PROBE4(ipif__ioctl,
 998  999                              char *, "ipsq_xopq_mp_cleanup",
 999 1000                              int, 0, ill_t *, NULL, ipif_t *, NULL);
1000 1001                          ip_ioctl_finish(wq, curr, ENXIO, connp != NULL ?
1001 1002                              CONN_CLOSE : NO_COPYOUT, NULL);
1002 1003                  } else {
1003 1004                          /*
1004 1005                           * IP-MT XXX In the case of TLI/XTI bind / optmgmt
1005 1006                           * this can't be just inet_freemsg. we have to
1006 1007                           * restart it otherwise the thread will be stuck.
1007 1008                           */
1008 1009                          inet_freemsg(curr);
1009 1010                  }
1010 1011          }
1011 1012  }
1012 1013  
1013 1014  /*
1014 1015   * This conn has started closing. Cleanup any pending ioctl from this conn.
1015 1016   * STREAMS ensures that there can be at most 1 active ioctl on a stream.
1016 1017   */
1017 1018  void
1018 1019  conn_ioctl_cleanup(conn_t *connp)
1019 1020  {
1020 1021          ipsq_t  *ipsq;
1021 1022          ill_t   *ill;
1022 1023          boolean_t refheld;
1023 1024  
1024 1025          /*
1025 1026           * Check for a queued ioctl. If the ioctl has not yet started, the mp
1026 1027           * is pending in the list headed by ipsq_xopq_head. If the ioctl has
1027 1028           * started the mp could be present in ipx_pending_mp. Note that if
1028 1029           * conn_oper_pending_ill is NULL, the ioctl may still be in flight and
1029 1030           * not yet queued anywhere. In this case, the conn close code will wait
1030 1031           * until the conn_ref is dropped. If the stream was a tcp stream, then
1031 1032           * tcp_close will wait first until all ioctls have completed for this
1032 1033           * conn.
1033 1034           */
1034 1035          mutex_enter(&connp->conn_lock);
1035 1036          ill = connp->conn_oper_pending_ill;
1036 1037          if (ill == NULL) {
1037 1038                  mutex_exit(&connp->conn_lock);
1038 1039                  return;
1039 1040          }
1040 1041  
1041 1042          /*
1042 1043           * We may not be able to refhold the ill if the ill/ipif
1043 1044           * is changing. But we need to make sure that the ill will
1044 1045           * not vanish. So we just bump up the ill_waiter count.
1045 1046           */
1046 1047          refheld = ill_waiter_inc(ill);
1047 1048          mutex_exit(&connp->conn_lock);
1048 1049          if (refheld) {
1049 1050                  if (ipsq_enter(ill, B_TRUE, NEW_OP)) {
1050 1051                          ill_waiter_dcr(ill);
1051 1052                          /*
1052 1053                           * Check whether this ioctl has started and is
1053 1054                           * pending. If it is not found there then check
1054 1055                           * whether this ioctl has not even started and is in
1055 1056                           * the ipsq_xopq list.
1056 1057                           */
1057 1058                          if (!ipsq_pending_mp_cleanup(ill, connp))
1058 1059                                  ipsq_xopq_mp_cleanup(ill, connp);
1059 1060                          ipsq = ill->ill_phyint->phyint_ipsq;
1060 1061                          ipsq_exit(ipsq);
1061 1062                          return;
1062 1063                  }
1063 1064          }
1064 1065  
1065 1066          /*
1066 1067           * The ill is also closing and we could not bump up the
1067 1068           * ill_waiter_count or we could not enter the ipsq. Leave
1068 1069           * the cleanup to ill_delete
1069 1070           */
1070 1071          mutex_enter(&connp->conn_lock);
1071 1072          while (connp->conn_oper_pending_ill != NULL)
1072 1073                  cv_wait(&connp->conn_refcv, &connp->conn_lock);
1073 1074          mutex_exit(&connp->conn_lock);
1074 1075          if (refheld)
1075 1076                  ill_waiter_dcr(ill);
1076 1077  }
1077 1078  
1078 1079  /*
1079 1080   * ipcl_walk function for cleaning up conn_*_ill fields.
1080 1081   * Note that we leave ixa_multicast_ifindex, conn_incoming_ifindex, and
1081 1082   * conn_bound_if in place. We prefer dropping
1082 1083   * packets instead of sending them out the wrong interface, or accepting
1083 1084   * packets from the wrong ifindex.
1084 1085   */
1085 1086  static void
1086 1087  conn_cleanup_ill(conn_t *connp, caddr_t arg)
1087 1088  {
1088 1089          ill_t   *ill = (ill_t *)arg;
1089 1090  
1090 1091          mutex_enter(&connp->conn_lock);
1091 1092          if (connp->conn_dhcpinit_ill == ill) {
1092 1093                  connp->conn_dhcpinit_ill = NULL;
1093 1094                  ASSERT(ill->ill_dhcpinit != 0);
1094 1095                  atomic_dec_32(&ill->ill_dhcpinit);
1095 1096                  ill_set_inputfn(ill);
1096 1097          }
1097 1098          mutex_exit(&connp->conn_lock);
1098 1099  }
1099 1100  
1100 1101  static int
1101 1102  ill_down_ipifs_tail(ill_t *ill)
1102 1103  {
1103 1104          ipif_t  *ipif;
1104 1105          int err;
1105 1106  
1106 1107          ASSERT(IAM_WRITER_ILL(ill));
1107 1108          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
1108 1109                  ipif_non_duplicate(ipif);
1109 1110                  /*
1110 1111                   * ipif_down_tail will call arp_ll_down on the last ipif
1111 1112                   * and typically return EINPROGRESS when the DL_UNBIND is sent.
1112 1113                   */
1113 1114                  if ((err = ipif_down_tail(ipif)) != 0)
1114 1115                          return (err);
1115 1116          }
1116 1117          return (0);
1117 1118  }
1118 1119  
1119 1120  /* ARGSUSED */
1120 1121  void
1121 1122  ipif_all_down_tail(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
1122 1123  {
1123 1124          ASSERT(IAM_WRITER_IPSQ(ipsq));
1124 1125          (void) ill_down_ipifs_tail(q->q_ptr);
1125 1126          freemsg(mp);
1126 1127          ipsq_current_finish(ipsq);
1127 1128  }
1128 1129  
1129 1130  /*
1130 1131   * ill_down_start is called when we want to down this ill and bring it up again
1131 1132   * It is called when we receive an M_ERROR / M_HANGUP. In this case we shut down
1132 1133   * all interfaces, but don't tear down any plumbing.
1133 1134   */
1134 1135  boolean_t
1135 1136  ill_down_start(queue_t *q, mblk_t *mp)
1136 1137  {
1137 1138          ill_t   *ill = q->q_ptr;
1138 1139          ipif_t  *ipif;
1139 1140  
1140 1141          ASSERT(IAM_WRITER_ILL(ill));
1141 1142          /*
1142 1143           * It is possible that some ioctl is already in progress while we
1143 1144           * received the M_ERROR / M_HANGUP in which case, we need to abort
1144 1145           * the ioctl. ill_down_start() is being processed as CUR_OP rather
1145 1146           * than as NEW_OP since the cause of the M_ERROR / M_HANGUP may prevent
1146 1147           * the in progress ioctl from ever completing.
1147 1148           *
1148 1149           * The thread that started the ioctl (if any) must have returned,
1149 1150           * since we are now executing as writer. After the 2 calls below,
1150 1151           * the state of the ipsq and the ill would reflect no trace of any
1151 1152           * pending operation. Subsequently if there is any response to the
1152 1153           * original ioctl from the driver, it would be discarded as an
1153 1154           * unsolicited message from the driver.
1154 1155           */
1155 1156          (void) ipsq_pending_mp_cleanup(ill, NULL);
1156 1157          ill_dlpi_clear_deferred(ill);
1157 1158  
1158 1159          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next)
1159 1160                  (void) ipif_down(ipif, NULL, NULL);
1160 1161  
1161 1162          ill_down(ill);
1162 1163  
1163 1164          /*
1164 1165           * Walk all CONNs that can have a reference on an ire or nce for this
1165 1166           * ill (we actually walk all that now have stale references).
1166 1167           */
1167 1168          ipcl_walk(conn_ixa_cleanup, (void *)B_TRUE, ill->ill_ipst);
1168 1169  
1169 1170          /* With IPv6 we have dce_ifindex. Cleanup for neatness */
1170 1171          if (ill->ill_isv6)
1171 1172                  dce_cleanup(ill->ill_phyint->phyint_ifindex, ill->ill_ipst);
1172 1173  
1173 1174          ipsq_current_start(ill->ill_phyint->phyint_ipsq, ill->ill_ipif, 0);
1174 1175  
1175 1176          /*
1176 1177           * Atomically test and add the pending mp if references are active.
1177 1178           */
1178 1179          mutex_enter(&ill->ill_lock);
1179 1180          if (!ill_is_quiescent(ill)) {
1180 1181                  /* call cannot fail since `conn_t *' argument is NULL */
1181 1182                  (void) ipsq_pending_mp_add(NULL, ill->ill_ipif, ill->ill_rq,
1182 1183                      mp, ILL_DOWN);
1183 1184                  mutex_exit(&ill->ill_lock);
1184 1185                  return (B_FALSE);
1185 1186          }
1186 1187          mutex_exit(&ill->ill_lock);
1187 1188          return (B_TRUE);
1188 1189  }
1189 1190  
1190 1191  static void
1191 1192  ill_down(ill_t *ill)
1192 1193  {
1193 1194          mblk_t  *mp;
1194 1195          ip_stack_t      *ipst = ill->ill_ipst;
1195 1196  
1196 1197          /*
1197 1198           * Blow off any IREs dependent on this ILL.
1198 1199           * The caller needs to handle conn_ixa_cleanup
1199 1200           */
1200 1201          ill_delete_ires(ill);
1201 1202  
1202 1203          ire_walk_ill(0, 0, ill_downi, ill, ill);
1203 1204  
1204 1205          /* Remove any conn_*_ill depending on this ill */
1205 1206          ipcl_walk(conn_cleanup_ill, (caddr_t)ill, ipst);
1206 1207  
1207 1208          /*
1208 1209           * Free state for additional IREs.
1209 1210           */
1210 1211          mutex_enter(&ill->ill_saved_ire_lock);
1211 1212          mp = ill->ill_saved_ire_mp;
1212 1213          ill->ill_saved_ire_mp = NULL;
1213 1214          ill->ill_saved_ire_cnt = 0;
1214 1215          mutex_exit(&ill->ill_saved_ire_lock);
1215 1216          freemsg(mp);
1216 1217  }
1217 1218  
1218 1219  /*
1219 1220   * ire_walk routine used to delete every IRE that depends on
1220 1221   * 'ill'.  (Always called as writer, and may only be called from ire_walk.)
1221 1222   *
1222 1223   * Note: since the routes added by the kernel are deleted separately,
1223 1224   * this will only be 1) IRE_IF_CLONE and 2) manually added IRE_INTERFACE.
1224 1225   *
1225 1226   * We also remove references on ire_nce_cache entries that refer to the ill.
1226 1227   */
1227 1228  void
1228 1229  ill_downi(ire_t *ire, char *ill_arg)
1229 1230  {
1230 1231          ill_t   *ill = (ill_t *)ill_arg;
1231 1232          nce_t   *nce;
1232 1233  
1233 1234          mutex_enter(&ire->ire_lock);
1234 1235          nce = ire->ire_nce_cache;
1235 1236          if (nce != NULL && nce->nce_ill == ill)
1236 1237                  ire->ire_nce_cache = NULL;
1237 1238          else
1238 1239                  nce = NULL;
1239 1240          mutex_exit(&ire->ire_lock);
1240 1241          if (nce != NULL)
1241 1242                  nce_refrele(nce);
1242 1243          if (ire->ire_ill == ill) {
1243 1244                  /*
1244 1245                   * The existing interface binding for ire must be
1245 1246                   * deleted before trying to bind the route to another
1246 1247                   * interface. However, since we are using the contents of the
1247 1248                   * ire after ire_delete, the caller has to ensure that
1248 1249                   * CONDEMNED (deleted) ire's are not removed from the list
1249 1250                   * when ire_delete() returns. Currently ill_downi() is
1250 1251                   * only called as part of ire_walk*() routines, so that
1251 1252                   * the irb_refhold() done by ire_walk*() will ensure that
1252 1253                   * ire_delete() does not lead to ire_inactive().
1253 1254                   */
1254 1255                  ASSERT(ire->ire_bucket->irb_refcnt > 0);
1255 1256                  ire_delete(ire);
1256 1257                  if (ire->ire_unbound)
1257 1258                          ire_rebind(ire);
1258 1259          }
1259 1260  }
1260 1261  
1261 1262  /* Remove IRE_IF_CLONE on this ill */
1262 1263  void
1263 1264  ill_downi_if_clone(ire_t *ire, char *ill_arg)
1264 1265  {
1265 1266          ill_t   *ill = (ill_t *)ill_arg;
1266 1267  
1267 1268          ASSERT(ire->ire_type & IRE_IF_CLONE);
1268 1269          if (ire->ire_ill == ill)
1269 1270                  ire_delete(ire);
1270 1271  }
1271 1272  
1272 1273  /* Consume an M_IOCACK of the fastpath probe. */
1273 1274  void
1274 1275  ill_fastpath_ack(ill_t *ill, mblk_t *mp)
1275 1276  {
1276 1277          mblk_t  *mp1 = mp;
1277 1278  
1278 1279          /*
1279 1280           * If this was the first attempt turn on the fastpath probing.
1280 1281           */
1281 1282          mutex_enter(&ill->ill_lock);
1282 1283          if (ill->ill_dlpi_fastpath_state == IDS_INPROGRESS)
1283 1284                  ill->ill_dlpi_fastpath_state = IDS_OK;
1284 1285          mutex_exit(&ill->ill_lock);
1285 1286  
1286 1287          /* Free the M_IOCACK mblk, hold on to the data */
1287 1288          mp = mp->b_cont;
1288 1289          freeb(mp1);
1289 1290          if (mp == NULL)
1290 1291                  return;
1291 1292          if (mp->b_cont != NULL)
1292 1293                  nce_fastpath_update(ill, mp);
1293 1294          else
1294 1295                  ip0dbg(("ill_fastpath_ack:  no b_cont\n"));
1295 1296          freemsg(mp);
1296 1297  }
1297 1298  
1298 1299  /*
1299 1300   * Throw an M_IOCTL message downstream asking "do you know fastpath?"
1300 1301   * The data portion of the request is a dl_unitdata_req_t template for
1301 1302   * what we would send downstream in the absence of a fastpath confirmation.
1302 1303   */
1303 1304  int
1304 1305  ill_fastpath_probe(ill_t *ill, mblk_t *dlur_mp)
1305 1306  {
1306 1307          struct iocblk   *ioc;
1307 1308          mblk_t  *mp;
1308 1309  
1309 1310          if (dlur_mp == NULL)
1310 1311                  return (EINVAL);
1311 1312  
1312 1313          mutex_enter(&ill->ill_lock);
1313 1314          switch (ill->ill_dlpi_fastpath_state) {
1314 1315          case IDS_FAILED:
1315 1316                  /*
1316 1317                   * Driver NAKed the first fastpath ioctl - assume it doesn't
1317 1318                   * support it.
1318 1319                   */
1319 1320                  mutex_exit(&ill->ill_lock);
1320 1321                  return (ENOTSUP);
1321 1322          case IDS_UNKNOWN:
1322 1323                  /* This is the first probe */
1323 1324                  ill->ill_dlpi_fastpath_state = IDS_INPROGRESS;
1324 1325                  break;
1325 1326          default:
1326 1327                  break;
1327 1328          }
1328 1329          mutex_exit(&ill->ill_lock);
1329 1330  
1330 1331          if ((mp = mkiocb(DL_IOC_HDR_INFO)) == NULL)
1331 1332                  return (EAGAIN);
1332 1333  
1333 1334          mp->b_cont = copyb(dlur_mp);
1334 1335          if (mp->b_cont == NULL) {
1335 1336                  freeb(mp);
1336 1337                  return (EAGAIN);
1337 1338          }
1338 1339  
1339 1340          ioc = (struct iocblk *)mp->b_rptr;
1340 1341          ioc->ioc_count = msgdsize(mp->b_cont);
1341 1342  
1342 1343          DTRACE_PROBE3(ill__dlpi, char *, "ill_fastpath_probe",
1343 1344              char *, "DL_IOC_HDR_INFO", ill_t *, ill);
1344 1345          putnext(ill->ill_wq, mp);
1345 1346          return (0);
1346 1347  }
1347 1348  
1348 1349  void
1349 1350  ill_capability_probe(ill_t *ill)
1350 1351  {
1351 1352          mblk_t  *mp;
1352 1353  
1353 1354          ASSERT(IAM_WRITER_ILL(ill));
1354 1355  
1355 1356          if (ill->ill_dlpi_capab_state != IDCS_UNKNOWN &&
1356 1357              ill->ill_dlpi_capab_state != IDCS_FAILED)
1357 1358                  return;
1358 1359  
1359 1360          /*
1360 1361           * We are starting a new cycle of capability negotiation.
1361 1362           * Free up the capab reset messages of any previous incarnation.
1362 1363           * We will do a fresh allocation when we get the response to our probe
1363 1364           */
1364 1365          if (ill->ill_capab_reset_mp != NULL) {
1365 1366                  freemsg(ill->ill_capab_reset_mp);
1366 1367                  ill->ill_capab_reset_mp = NULL;
1367 1368          }
1368 1369  
1369 1370          ip1dbg(("ill_capability_probe: starting capability negotiation\n"));
1370 1371  
1371 1372          mp = ip_dlpi_alloc(sizeof (dl_capability_req_t), DL_CAPABILITY_REQ);
1372 1373          if (mp == NULL)
1373 1374                  return;
1374 1375  
1375 1376          ill_capability_send(ill, mp);
1376 1377          ill->ill_dlpi_capab_state = IDCS_PROBE_SENT;
1377 1378  }
1378 1379  
1379 1380  void
1380 1381  ill_capability_reset(ill_t *ill, boolean_t reneg)
1381 1382  {
1382 1383          ASSERT(IAM_WRITER_ILL(ill));
1383 1384  
1384 1385          if (ill->ill_dlpi_capab_state != IDCS_OK)
1385 1386                  return;
1386 1387  
1387 1388          ill->ill_dlpi_capab_state = reneg ? IDCS_RENEG : IDCS_RESET_SENT;
1388 1389  
1389 1390          ill_capability_send(ill, ill->ill_capab_reset_mp);
1390 1391          ill->ill_capab_reset_mp = NULL;
1391 1392          /*
1392 1393           * We turn off all capabilities except those pertaining to
1393 1394           * direct function call capabilities viz. ILL_CAPAB_DLD*
1394 1395           * which will be turned off by the corresponding reset functions.
1395 1396           */
1396 1397          ill->ill_capabilities &= ~(ILL_CAPAB_HCKSUM  | ILL_CAPAB_ZEROCOPY);
1397 1398  }
1398 1399  
1399 1400  static void
1400 1401  ill_capability_reset_alloc(ill_t *ill)
1401 1402  {
1402 1403          mblk_t *mp;
1403 1404          size_t  size = 0;
1404 1405          int     err;
1405 1406          dl_capability_req_t     *capb;
1406 1407  
1407 1408          ASSERT(IAM_WRITER_ILL(ill));
1408 1409          ASSERT(ill->ill_capab_reset_mp == NULL);
1409 1410  
1410 1411          if (ILL_HCKSUM_CAPABLE(ill)) {
1411 1412                  size += sizeof (dl_capability_sub_t) +
1412 1413                      sizeof (dl_capab_hcksum_t);
1413 1414          }
1414 1415  
1415 1416          if (ill->ill_capabilities & ILL_CAPAB_ZEROCOPY) {
1416 1417                  size += sizeof (dl_capability_sub_t) +
1417 1418                      sizeof (dl_capab_zerocopy_t);
1418 1419          }
1419 1420  
1420 1421          if (ill->ill_capabilities & ILL_CAPAB_DLD) {
1421 1422                  size += sizeof (dl_capability_sub_t) +
1422 1423                      sizeof (dl_capab_dld_t);
1423 1424          }
1424 1425  
1425 1426          mp = allocb_wait(size + sizeof (dl_capability_req_t), BPRI_MED,
1426 1427              STR_NOSIG, &err);
1427 1428  
1428 1429          mp->b_datap->db_type = M_PROTO;
1429 1430          bzero(mp->b_rptr, size + sizeof (dl_capability_req_t));
1430 1431  
1431 1432          capb = (dl_capability_req_t *)mp->b_rptr;
1432 1433          capb->dl_primitive = DL_CAPABILITY_REQ;
1433 1434          capb->dl_sub_offset = sizeof (dl_capability_req_t);
1434 1435          capb->dl_sub_length = size;
1435 1436  
1436 1437          mp->b_wptr += sizeof (dl_capability_req_t);
1437 1438  
1438 1439          /*
1439 1440           * Each handler fills in the corresponding dl_capability_sub_t
1440 1441           * inside the mblk,
1441 1442           */
1442 1443          ill_capability_hcksum_reset_fill(ill, mp);
1443 1444          ill_capability_zerocopy_reset_fill(ill, mp);
1444 1445          ill_capability_dld_reset_fill(ill, mp);
1445 1446  
1446 1447          ill->ill_capab_reset_mp = mp;
1447 1448  }
1448 1449  
1449 1450  static void
1450 1451  ill_capability_id_ack(ill_t *ill, mblk_t *mp, dl_capability_sub_t *outers)
1451 1452  {
1452 1453          dl_capab_id_t *id_ic;
1453 1454          uint_t sub_dl_cap = outers->dl_cap;
1454 1455          dl_capability_sub_t *inners;
1455 1456          uint8_t *capend;
1456 1457  
1457 1458          ASSERT(sub_dl_cap == DL_CAPAB_ID_WRAPPER);
1458 1459  
1459 1460          /*
1460 1461           * Note: range checks here are not absolutely sufficient to
1461 1462           * make us robust against malformed messages sent by drivers;
1462 1463           * this is in keeping with the rest of IP's dlpi handling.
1463 1464           * (Remember, it's coming from something else in the kernel
1464 1465           * address space)
1465 1466           */
1466 1467  
1467 1468          capend = (uint8_t *)(outers + 1) + outers->dl_length;
1468 1469          if (capend > mp->b_wptr) {
1469 1470                  cmn_err(CE_WARN, "ill_capability_id_ack: "
1470 1471                      "malformed sub-capability too long for mblk");
1471 1472                  return;
1472 1473          }
1473 1474  
1474 1475          id_ic = (dl_capab_id_t *)(outers + 1);
1475 1476  
1476 1477          if (outers->dl_length < sizeof (*id_ic) ||
1477 1478              (inners = &id_ic->id_subcap,
1478 1479              inners->dl_length > (outers->dl_length - sizeof (*inners)))) {
1479 1480                  cmn_err(CE_WARN, "ill_capability_id_ack: malformed "
1480 1481                      "encapsulated capab type %d too long for mblk",
1481 1482                      inners->dl_cap);
1482 1483                  return;
1483 1484          }
1484 1485  
1485 1486          if (!dlcapabcheckqid(&id_ic->id_mid, ill->ill_lmod_rq)) {
1486 1487                  ip1dbg(("ill_capability_id_ack: mid token for capab type %d "
1487 1488                      "isn't as expected; pass-thru module(s) detected, "
1488 1489                      "discarding capability\n", inners->dl_cap));
1489 1490                  return;
1490 1491          }
1491 1492  
1492 1493          /* Process the encapsulated sub-capability */
1493 1494          ill_capability_dispatch(ill, mp, inners);
1494 1495  }
1495 1496  
1496 1497  static void
1497 1498  ill_capability_dld_reset_fill(ill_t *ill, mblk_t *mp)
1498 1499  {
1499 1500          dl_capability_sub_t *dl_subcap;
1500 1501  
1501 1502          if (!(ill->ill_capabilities & ILL_CAPAB_DLD))
1502 1503                  return;
1503 1504  
1504 1505          /*
1505 1506           * The dl_capab_dld_t that follows the dl_capability_sub_t is not
1506 1507           * initialized below since it is not used by DLD.
1507 1508           */
1508 1509          dl_subcap = (dl_capability_sub_t *)mp->b_wptr;
1509 1510          dl_subcap->dl_cap = DL_CAPAB_DLD;
1510 1511          dl_subcap->dl_length = sizeof (dl_capab_dld_t);
1511 1512  
1512 1513          mp->b_wptr += sizeof (dl_capability_sub_t) + sizeof (dl_capab_dld_t);
1513 1514  }
1514 1515  
1515 1516  static void
1516 1517  ill_capability_dispatch(ill_t *ill, mblk_t *mp, dl_capability_sub_t *subp)
1517 1518  {
1518 1519          /*
1519 1520           * If no ipif was brought up over this ill, this DL_CAPABILITY_REQ/ACK
1520 1521           * is only to get the VRRP capability.
1521 1522           *
1522 1523           * Note that we cannot check ill_ipif_up_count here since
1523 1524           * ill_ipif_up_count is only incremented when the resolver is setup.
1524 1525           * That is done asynchronously, and can race with this function.
1525 1526           */
1526 1527          if (!ill->ill_dl_up) {
1527 1528                  if (subp->dl_cap == DL_CAPAB_VRRP)
1528 1529                          ill_capability_vrrp_ack(ill, mp, subp);
1529 1530                  return;
1530 1531          }
1531 1532  
1532 1533          switch (subp->dl_cap) {
1533 1534          case DL_CAPAB_HCKSUM:
1534 1535                  ill_capability_hcksum_ack(ill, mp, subp);
1535 1536                  break;
1536 1537          case DL_CAPAB_ZEROCOPY:
1537 1538                  ill_capability_zerocopy_ack(ill, mp, subp);
1538 1539                  break;
1539 1540          case DL_CAPAB_DLD:
1540 1541                  ill_capability_dld_ack(ill, mp, subp);
1541 1542                  break;
1542 1543          case DL_CAPAB_VRRP:
1543 1544                  break;
1544 1545          default:
1545 1546                  ip1dbg(("ill_capability_dispatch: unknown capab type %d\n",
1546 1547                      subp->dl_cap));
1547 1548          }
1548 1549  }
1549 1550  
1550 1551  /*
1551 1552   * Process the vrrp capability received from a DLS Provider. isub must point
1552 1553   * to the sub-capability (DL_CAPAB_VRRP) of a DL_CAPABILITY_ACK message.
1553 1554   */
1554 1555  static void
1555 1556  ill_capability_vrrp_ack(ill_t *ill, mblk_t *mp, dl_capability_sub_t *isub)
1556 1557  {
1557 1558          dl_capab_vrrp_t *vrrp;
1558 1559          uint_t          sub_dl_cap = isub->dl_cap;
1559 1560          uint8_t         *capend;
1560 1561  
1561 1562          ASSERT(IAM_WRITER_ILL(ill));
1562 1563          ASSERT(sub_dl_cap == DL_CAPAB_VRRP);
1563 1564  
1564 1565          /*
1565 1566           * Note: range checks here are not absolutely sufficient to
1566 1567           * make us robust against malformed messages sent by drivers;
1567 1568           * this is in keeping with the rest of IP's dlpi handling.
1568 1569           * (Remember, it's coming from something else in the kernel
1569 1570           * address space)
1570 1571           */
1571 1572          capend = (uint8_t *)(isub + 1) + isub->dl_length;
1572 1573          if (capend > mp->b_wptr) {
1573 1574                  cmn_err(CE_WARN, "ill_capability_vrrp_ack: "
1574 1575                      "malformed sub-capability too long for mblk");
1575 1576                  return;
1576 1577          }
1577 1578          vrrp = (dl_capab_vrrp_t *)(isub + 1);
1578 1579  
1579 1580          /*
1580 1581           * Compare the IP address family and set ILLF_VRRP for the right ill.
1581 1582           */
1582 1583          if ((vrrp->vrrp_af == AF_INET6 && ill->ill_isv6) ||
1583 1584              (vrrp->vrrp_af == AF_INET && !ill->ill_isv6)) {
1584 1585                  ill->ill_flags |= ILLF_VRRP;
1585 1586          }
1586 1587  }
1587 1588  
1588 1589  /*
1589 1590   * Process a hardware checksum offload capability negotiation ack received
1590 1591   * from a DLS Provider.isub must point to the sub-capability (DL_CAPAB_HCKSUM)
1591 1592   * of a DL_CAPABILITY_ACK message.
1592 1593   */
1593 1594  static void
1594 1595  ill_capability_hcksum_ack(ill_t *ill, mblk_t *mp, dl_capability_sub_t *isub)
1595 1596  {
1596 1597          dl_capability_req_t     *ocap;
1597 1598          dl_capab_hcksum_t       *ihck, *ohck;
1598 1599          ill_hcksum_capab_t      **ill_hcksum;
1599 1600          mblk_t                  *nmp = NULL;
1600 1601          uint_t                  sub_dl_cap = isub->dl_cap;
1601 1602          uint8_t                 *capend;
1602 1603  
1603 1604          ASSERT(sub_dl_cap == DL_CAPAB_HCKSUM);
1604 1605  
1605 1606          ill_hcksum = (ill_hcksum_capab_t **)&ill->ill_hcksum_capab;
1606 1607  
1607 1608          /*
1608 1609           * Note: range checks here are not absolutely sufficient to
1609 1610           * make us robust against malformed messages sent by drivers;
1610 1611           * this is in keeping with the rest of IP's dlpi handling.
1611 1612           * (Remember, it's coming from something else in the kernel
1612 1613           * address space)
1613 1614           */
1614 1615          capend = (uint8_t *)(isub + 1) + isub->dl_length;
1615 1616          if (capend > mp->b_wptr) {
1616 1617                  cmn_err(CE_WARN, "ill_capability_hcksum_ack: "
1617 1618                      "malformed sub-capability too long for mblk");
1618 1619                  return;
1619 1620          }
1620 1621  
1621 1622          /*
1622 1623           * There are two types of acks we process here:
1623 1624           * 1. acks in reply to a (first form) generic capability req
1624 1625           *    (no ENABLE flag set)
1625 1626           * 2. acks in reply to a ENABLE capability req.
1626 1627           *    (ENABLE flag set)
1627 1628           */
1628 1629          ihck = (dl_capab_hcksum_t *)(isub + 1);
1629 1630  
1630 1631          if (ihck->hcksum_version != HCKSUM_VERSION_1) {
1631 1632                  cmn_err(CE_CONT, "ill_capability_hcksum_ack: "
1632 1633                      "unsupported hardware checksum "
1633 1634                      "sub-capability (version %d, expected %d)",
1634 1635                      ihck->hcksum_version, HCKSUM_VERSION_1);
1635 1636                  return;
1636 1637          }
1637 1638  
1638 1639          if (!dlcapabcheckqid(&ihck->hcksum_mid, ill->ill_lmod_rq)) {
1639 1640                  ip1dbg(("ill_capability_hcksum_ack: mid token for hardware "
1640 1641                      "checksum capability isn't as expected; pass-thru "
1641 1642                      "module(s) detected, discarding capability\n"));
1642 1643                  return;
1643 1644          }
1644 1645  
1645 1646  #define CURR_HCKSUM_CAPAB                               \
1646 1647          (HCKSUM_INET_PARTIAL | HCKSUM_INET_FULL_V4 |    \
1647 1648          HCKSUM_INET_FULL_V6 | HCKSUM_IPHDRCKSUM)
1648 1649  
1649 1650          if ((ihck->hcksum_txflags & HCKSUM_ENABLE) &&
1650 1651              (ihck->hcksum_txflags & CURR_HCKSUM_CAPAB)) {
1651 1652                  /* do ENABLE processing */
1652 1653                  if (*ill_hcksum == NULL) {
1653 1654                          *ill_hcksum = kmem_zalloc(sizeof (ill_hcksum_capab_t),
1654 1655                              KM_NOSLEEP);
1655 1656  
1656 1657                          if (*ill_hcksum == NULL) {
1657 1658                                  cmn_err(CE_WARN, "ill_capability_hcksum_ack: "
1658 1659                                      "could not enable hcksum version %d "
1659 1660                                      "for %s (ENOMEM)\n", HCKSUM_CURRENT_VERSION,
1660 1661                                      ill->ill_name);
1661 1662                                  return;
1662 1663                          }
1663 1664                  }
1664 1665  
1665 1666                  (*ill_hcksum)->ill_hcksum_version = ihck->hcksum_version;
1666 1667                  (*ill_hcksum)->ill_hcksum_txflags = ihck->hcksum_txflags;
1667 1668                  ill->ill_capabilities |= ILL_CAPAB_HCKSUM;
1668 1669                  ip1dbg(("ill_capability_hcksum_ack: interface %s "
1669 1670                      "has enabled hardware checksumming\n ",
1670 1671                      ill->ill_name));
1671 1672          } else if (ihck->hcksum_txflags & CURR_HCKSUM_CAPAB) {
1672 1673                  /*
1673 1674                   * Enabling hardware checksum offload
1674 1675                   * Currently IP supports {TCP,UDP}/IPv4
1675 1676                   * partial and full cksum offload and
1676 1677                   * IPv4 header checksum offload.
1677 1678                   * Allocate new mblk which will
1678 1679                   * contain a new capability request
1679 1680                   * to enable hardware checksum offload.
1680 1681                   */
1681 1682                  uint_t  size;
1682 1683                  uchar_t *rptr;
1683 1684  
1684 1685                  size = sizeof (dl_capability_req_t) +
1685 1686                      sizeof (dl_capability_sub_t) + isub->dl_length;
1686 1687  
1687 1688                  if ((nmp = ip_dlpi_alloc(size, DL_CAPABILITY_REQ)) == NULL) {
1688 1689                          cmn_err(CE_WARN, "ill_capability_hcksum_ack: "
1689 1690                              "could not enable hardware cksum for %s (ENOMEM)\n",
1690 1691                              ill->ill_name);
1691 1692                          return;
1692 1693                  }
1693 1694  
1694 1695                  rptr = nmp->b_rptr;
1695 1696                  /* initialize dl_capability_req_t */
1696 1697                  ocap = (dl_capability_req_t *)nmp->b_rptr;
1697 1698                  ocap->dl_sub_offset =
1698 1699                      sizeof (dl_capability_req_t);
1699 1700                  ocap->dl_sub_length =
1700 1701                      sizeof (dl_capability_sub_t) +
1701 1702                      isub->dl_length;
1702 1703                  nmp->b_rptr += sizeof (dl_capability_req_t);
1703 1704  
1704 1705                  /* initialize dl_capability_sub_t */
1705 1706                  bcopy(isub, nmp->b_rptr, sizeof (*isub));
1706 1707                  nmp->b_rptr += sizeof (*isub);
1707 1708  
1708 1709                  /* initialize dl_capab_hcksum_t */
1709 1710                  ohck = (dl_capab_hcksum_t *)nmp->b_rptr;
1710 1711                  bcopy(ihck, ohck, sizeof (*ihck));
1711 1712  
1712 1713                  nmp->b_rptr = rptr;
1713 1714                  ASSERT(nmp->b_wptr == (nmp->b_rptr + size));
1714 1715  
1715 1716                  /* Set ENABLE flag */
1716 1717                  ohck->hcksum_txflags &= CURR_HCKSUM_CAPAB;
1717 1718                  ohck->hcksum_txflags |= HCKSUM_ENABLE;
1718 1719  
1719 1720                  /*
1720 1721                   * nmp points to a DL_CAPABILITY_REQ message to enable
1721 1722                   * hardware checksum acceleration.
1722 1723                   */
1723 1724                  ill_capability_send(ill, nmp);
1724 1725          } else {
1725 1726                  ip1dbg(("ill_capability_hcksum_ack: interface %s has "
1726 1727                      "advertised %x hardware checksum capability flags\n",
1727 1728                      ill->ill_name, ihck->hcksum_txflags));
1728 1729          }
1729 1730  }
1730 1731  
1731 1732  static void
1732 1733  ill_capability_hcksum_reset_fill(ill_t *ill, mblk_t *mp)
1733 1734  {
1734 1735          dl_capab_hcksum_t *hck_subcap;
1735 1736          dl_capability_sub_t *dl_subcap;
1736 1737  
1737 1738          if (!ILL_HCKSUM_CAPABLE(ill))
1738 1739                  return;
1739 1740  
1740 1741          ASSERT(ill->ill_hcksum_capab != NULL);
1741 1742  
1742 1743          dl_subcap = (dl_capability_sub_t *)mp->b_wptr;
1743 1744          dl_subcap->dl_cap = DL_CAPAB_HCKSUM;
1744 1745          dl_subcap->dl_length = sizeof (*hck_subcap);
1745 1746  
1746 1747          hck_subcap = (dl_capab_hcksum_t *)(dl_subcap + 1);
1747 1748          hck_subcap->hcksum_version = ill->ill_hcksum_capab->ill_hcksum_version;
1748 1749          hck_subcap->hcksum_txflags = 0;
1749 1750  
1750 1751          mp->b_wptr += sizeof (*dl_subcap) + sizeof (*hck_subcap);
1751 1752  }
1752 1753  
1753 1754  static void
1754 1755  ill_capability_zerocopy_ack(ill_t *ill, mblk_t *mp, dl_capability_sub_t *isub)
1755 1756  {
1756 1757          mblk_t *nmp = NULL;
1757 1758          dl_capability_req_t *oc;
1758 1759          dl_capab_zerocopy_t *zc_ic, *zc_oc;
1759 1760          ill_zerocopy_capab_t **ill_zerocopy_capab;
1760 1761          uint_t sub_dl_cap = isub->dl_cap;
1761 1762          uint8_t *capend;
1762 1763  
1763 1764          ASSERT(sub_dl_cap == DL_CAPAB_ZEROCOPY);
1764 1765  
1765 1766          ill_zerocopy_capab = (ill_zerocopy_capab_t **)&ill->ill_zerocopy_capab;
1766 1767  
1767 1768          /*
1768 1769           * Note: range checks here are not absolutely sufficient to
1769 1770           * make us robust against malformed messages sent by drivers;
1770 1771           * this is in keeping with the rest of IP's dlpi handling.
1771 1772           * (Remember, it's coming from something else in the kernel
1772 1773           * address space)
1773 1774           */
1774 1775          capend = (uint8_t *)(isub + 1) + isub->dl_length;
1775 1776          if (capend > mp->b_wptr) {
1776 1777                  cmn_err(CE_WARN, "ill_capability_zerocopy_ack: "
1777 1778                      "malformed sub-capability too long for mblk");
1778 1779                  return;
1779 1780          }
1780 1781  
1781 1782          zc_ic = (dl_capab_zerocopy_t *)(isub + 1);
1782 1783          if (zc_ic->zerocopy_version != ZEROCOPY_VERSION_1) {
1783 1784                  cmn_err(CE_CONT, "ill_capability_zerocopy_ack: "
1784 1785                      "unsupported ZEROCOPY sub-capability (version %d, "
1785 1786                      "expected %d)", zc_ic->zerocopy_version,
1786 1787                      ZEROCOPY_VERSION_1);
1787 1788                  return;
1788 1789          }
1789 1790  
1790 1791          if (!dlcapabcheckqid(&zc_ic->zerocopy_mid, ill->ill_lmod_rq)) {
1791 1792                  ip1dbg(("ill_capability_zerocopy_ack: mid token for zerocopy "
1792 1793                      "capability isn't as expected; pass-thru module(s) "
1793 1794                      "detected, discarding capability\n"));
1794 1795                  return;
1795 1796          }
1796 1797  
1797 1798          if ((zc_ic->zerocopy_flags & DL_CAPAB_VMSAFE_MEM) != 0) {
1798 1799                  if (*ill_zerocopy_capab == NULL) {
1799 1800                          *ill_zerocopy_capab =
1800 1801                              kmem_zalloc(sizeof (ill_zerocopy_capab_t),
1801 1802                              KM_NOSLEEP);
1802 1803  
1803 1804                          if (*ill_zerocopy_capab == NULL) {
1804 1805                                  cmn_err(CE_WARN, "ill_capability_zerocopy_ack: "
1805 1806                                      "could not enable Zero-copy version %d "
1806 1807                                      "for %s (ENOMEM)\n", ZEROCOPY_VERSION_1,
1807 1808                                      ill->ill_name);
1808 1809                                  return;
1809 1810                          }
1810 1811                  }
1811 1812  
1812 1813                  ip1dbg(("ill_capability_zerocopy_ack: interface %s "
1813 1814                      "supports Zero-copy version %d\n", ill->ill_name,
1814 1815                      ZEROCOPY_VERSION_1));
1815 1816  
1816 1817                  (*ill_zerocopy_capab)->ill_zerocopy_version =
1817 1818                      zc_ic->zerocopy_version;
1818 1819                  (*ill_zerocopy_capab)->ill_zerocopy_flags =
1819 1820                      zc_ic->zerocopy_flags;
1820 1821  
1821 1822                  ill->ill_capabilities |= ILL_CAPAB_ZEROCOPY;
1822 1823          } else {
1823 1824                  uint_t size;
1824 1825                  uchar_t *rptr;
1825 1826  
1826 1827                  size = sizeof (dl_capability_req_t) +
1827 1828                      sizeof (dl_capability_sub_t) +
1828 1829                      sizeof (dl_capab_zerocopy_t);
1829 1830  
1830 1831                  if ((nmp = ip_dlpi_alloc(size, DL_CAPABILITY_REQ)) == NULL) {
1831 1832                          cmn_err(CE_WARN, "ill_capability_zerocopy_ack: "
1832 1833                              "could not enable zerocopy for %s (ENOMEM)\n",
1833 1834                              ill->ill_name);
1834 1835                          return;
1835 1836                  }
1836 1837  
1837 1838                  rptr = nmp->b_rptr;
1838 1839                  /* initialize dl_capability_req_t */
1839 1840                  oc = (dl_capability_req_t *)rptr;
1840 1841                  oc->dl_sub_offset = sizeof (dl_capability_req_t);
1841 1842                  oc->dl_sub_length = sizeof (dl_capability_sub_t) +
1842 1843                      sizeof (dl_capab_zerocopy_t);
1843 1844                  rptr += sizeof (dl_capability_req_t);
1844 1845  
1845 1846                  /* initialize dl_capability_sub_t */
1846 1847                  bcopy(isub, rptr, sizeof (*isub));
1847 1848                  rptr += sizeof (*isub);
1848 1849  
1849 1850                  /* initialize dl_capab_zerocopy_t */
1850 1851                  zc_oc = (dl_capab_zerocopy_t *)rptr;
1851 1852                  *zc_oc = *zc_ic;
1852 1853  
1853 1854                  ip1dbg(("ill_capability_zerocopy_ack: asking interface %s "
1854 1855                      "to enable zero-copy version %d\n", ill->ill_name,
1855 1856                      ZEROCOPY_VERSION_1));
1856 1857  
1857 1858                  /* set VMSAFE_MEM flag */
1858 1859                  zc_oc->zerocopy_flags |= DL_CAPAB_VMSAFE_MEM;
1859 1860  
1860 1861                  /* nmp points to a DL_CAPABILITY_REQ message to enable zcopy */
1861 1862                  ill_capability_send(ill, nmp);
1862 1863          }
1863 1864  }
1864 1865  
1865 1866  static void
1866 1867  ill_capability_zerocopy_reset_fill(ill_t *ill, mblk_t *mp)
1867 1868  {
1868 1869          dl_capab_zerocopy_t *zerocopy_subcap;
1869 1870          dl_capability_sub_t *dl_subcap;
1870 1871  
1871 1872          if (!(ill->ill_capabilities & ILL_CAPAB_ZEROCOPY))
1872 1873                  return;
1873 1874  
1874 1875          ASSERT(ill->ill_zerocopy_capab != NULL);
1875 1876  
1876 1877          dl_subcap = (dl_capability_sub_t *)mp->b_wptr;
1877 1878          dl_subcap->dl_cap = DL_CAPAB_ZEROCOPY;
1878 1879          dl_subcap->dl_length = sizeof (*zerocopy_subcap);
1879 1880  
1880 1881          zerocopy_subcap = (dl_capab_zerocopy_t *)(dl_subcap + 1);
1881 1882          zerocopy_subcap->zerocopy_version =
1882 1883              ill->ill_zerocopy_capab->ill_zerocopy_version;
1883 1884          zerocopy_subcap->zerocopy_flags = 0;
1884 1885  
1885 1886          mp->b_wptr += sizeof (*dl_subcap) + sizeof (*zerocopy_subcap);
1886 1887  }
1887 1888  
1888 1889  /*
1889 1890   * DLD capability
1890 1891   * Refer to dld.h for more information regarding the purpose and usage
1891 1892   * of this capability.
1892 1893   */
1893 1894  static void
1894 1895  ill_capability_dld_ack(ill_t *ill, mblk_t *mp, dl_capability_sub_t *isub)
1895 1896  {
1896 1897          dl_capab_dld_t          *dld_ic, dld;
1897 1898          uint_t                  sub_dl_cap = isub->dl_cap;
1898 1899          uint8_t                 *capend;
1899 1900          ill_dld_capab_t         *idc;
1900 1901  
1901 1902          ASSERT(IAM_WRITER_ILL(ill));
1902 1903          ASSERT(sub_dl_cap == DL_CAPAB_DLD);
1903 1904  
1904 1905          /*
1905 1906           * Note: range checks here are not absolutely sufficient to
1906 1907           * make us robust against malformed messages sent by drivers;
1907 1908           * this is in keeping with the rest of IP's dlpi handling.
1908 1909           * (Remember, it's coming from something else in the kernel
1909 1910           * address space)
1910 1911           */
1911 1912          capend = (uint8_t *)(isub + 1) + isub->dl_length;
1912 1913          if (capend > mp->b_wptr) {
1913 1914                  cmn_err(CE_WARN, "ill_capability_dld_ack: "
1914 1915                      "malformed sub-capability too long for mblk");
1915 1916                  return;
1916 1917          }
1917 1918          dld_ic = (dl_capab_dld_t *)(isub + 1);
1918 1919          if (dld_ic->dld_version != DLD_CURRENT_VERSION) {
1919 1920                  cmn_err(CE_CONT, "ill_capability_dld_ack: "
1920 1921                      "unsupported DLD sub-capability (version %d, "
1921 1922                      "expected %d)", dld_ic->dld_version,
1922 1923                      DLD_CURRENT_VERSION);
1923 1924                  return;
1924 1925          }
1925 1926          if (!dlcapabcheckqid(&dld_ic->dld_mid, ill->ill_lmod_rq)) {
1926 1927                  ip1dbg(("ill_capability_dld_ack: mid token for dld "
1927 1928                      "capability isn't as expected; pass-thru module(s) "
1928 1929                      "detected, discarding capability\n"));
1929 1930                  return;
1930 1931          }
1931 1932  
1932 1933          /*
1933 1934           * Copy locally to ensure alignment.
1934 1935           */
1935 1936          bcopy(dld_ic, &dld, sizeof (dl_capab_dld_t));
1936 1937  
1937 1938          if ((idc = ill->ill_dld_capab) == NULL) {
1938 1939                  idc = kmem_zalloc(sizeof (ill_dld_capab_t), KM_NOSLEEP);
1939 1940                  if (idc == NULL) {
1940 1941                          cmn_err(CE_WARN, "ill_capability_dld_ack: "
1941 1942                              "could not enable DLD version %d "
1942 1943                              "for %s (ENOMEM)\n", DLD_CURRENT_VERSION,
1943 1944                              ill->ill_name);
1944 1945                          return;
1945 1946                  }
1946 1947                  ill->ill_dld_capab = idc;
1947 1948          }
1948 1949          idc->idc_capab_df = (ip_capab_func_t)dld.dld_capab;
1949 1950          idc->idc_capab_dh = (void *)dld.dld_capab_handle;
1950 1951          ip1dbg(("ill_capability_dld_ack: interface %s "
1951 1952              "supports DLD version %d\n", ill->ill_name, DLD_CURRENT_VERSION));
1952 1953  
1953 1954          ill_capability_dld_enable(ill);
1954 1955  }
1955 1956  
1956 1957  /*
1957 1958   * Typically capability negotiation between IP and the driver happens via
1958 1959   * DLPI message exchange. However GLD also offers a direct function call
1959 1960   * mechanism to exchange the DLD_DIRECT_CAPAB and DLD_POLL_CAPAB capabilities,
1960 1961   * But arbitrary function calls into IP or GLD are not permitted, since both
1961 1962   * of them are protected by their own perimeter mechanism. The perimeter can
1962 1963   * be viewed as a coarse lock or serialization mechanism. The hierarchy of
1963 1964   * these perimeters is IP -> MAC. Thus for example to enable the squeue
1964 1965   * polling, IP needs to enter its perimeter, then call ill_mac_perim_enter
1965 1966   * to enter the mac perimeter and then do the direct function calls into
1966 1967   * GLD to enable squeue polling. The ring related callbacks from the mac into
1967 1968   * the stack to add, bind, quiesce, restart or cleanup a ring are all
1968 1969   * protected by the mac perimeter.
1969 1970   */
1970 1971  static void
1971 1972  ill_mac_perim_enter(ill_t *ill, mac_perim_handle_t *mphp)
1972 1973  {
1973 1974          ill_dld_capab_t         *idc = ill->ill_dld_capab;
1974 1975          int                     err;
1975 1976  
1976 1977          err = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_PERIM, mphp,
1977 1978              DLD_ENABLE);
1978 1979          ASSERT(err == 0);
1979 1980  }
1980 1981  
1981 1982  static void
1982 1983  ill_mac_perim_exit(ill_t *ill, mac_perim_handle_t mph)
1983 1984  {
1984 1985          ill_dld_capab_t         *idc = ill->ill_dld_capab;
1985 1986          int                     err;
1986 1987  
1987 1988          err = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_PERIM, mph,
1988 1989              DLD_DISABLE);
1989 1990          ASSERT(err == 0);
1990 1991  }
1991 1992  
1992 1993  boolean_t
1993 1994  ill_mac_perim_held(ill_t *ill)
1994 1995  {
1995 1996          ill_dld_capab_t         *idc = ill->ill_dld_capab;
1996 1997  
1997 1998          return (idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_PERIM, NULL,
1998 1999              DLD_QUERY));
1999 2000  }
2000 2001  
2001 2002  static void
2002 2003  ill_capability_direct_enable(ill_t *ill)
2003 2004  {
2004 2005          ill_dld_capab_t         *idc = ill->ill_dld_capab;
2005 2006          ill_dld_direct_t        *idd = &idc->idc_direct;
2006 2007          dld_capab_direct_t      direct;
2007 2008          int                     rc;
2008 2009  
2009 2010          ASSERT(!ill->ill_isv6 && IAM_WRITER_ILL(ill));
2010 2011  
2011 2012          bzero(&direct, sizeof (direct));
2012 2013          direct.di_rx_cf = (uintptr_t)ip_input;
2013 2014          direct.di_rx_ch = ill;
2014 2015  
2015 2016          rc = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_DIRECT, &direct,
2016 2017              DLD_ENABLE);
2017 2018          if (rc == 0) {
2018 2019                  idd->idd_tx_df = (ip_dld_tx_t)direct.di_tx_df;
2019 2020                  idd->idd_tx_dh = direct.di_tx_dh;
2020 2021                  idd->idd_tx_cb_df = (ip_dld_callb_t)direct.di_tx_cb_df;
2021 2022                  idd->idd_tx_cb_dh = direct.di_tx_cb_dh;
2022 2023                  idd->idd_tx_fctl_df = (ip_dld_fctl_t)direct.di_tx_fctl_df;
2023 2024                  idd->idd_tx_fctl_dh = direct.di_tx_fctl_dh;
2024 2025                  ASSERT(idd->idd_tx_cb_df != NULL);
2025 2026                  ASSERT(idd->idd_tx_fctl_df != NULL);
2026 2027                  ASSERT(idd->idd_tx_df != NULL);
2027 2028                  /*
2028 2029                   * One time registration of flow enable callback function
2029 2030                   */
2030 2031                  ill->ill_flownotify_mh = idd->idd_tx_cb_df(idd->idd_tx_cb_dh,
2031 2032                      ill_flow_enable, ill);
2032 2033                  ill->ill_capabilities |= ILL_CAPAB_DLD_DIRECT;
2033 2034                  DTRACE_PROBE1(direct_on, (ill_t *), ill);
2034 2035          } else {
2035 2036                  cmn_err(CE_WARN, "warning: could not enable DIRECT "
2036 2037                      "capability, rc = %d\n", rc);
2037 2038                  DTRACE_PROBE2(direct_off, (ill_t *), ill, (int), rc);
2038 2039          }
2039 2040  }
2040 2041  
2041 2042  static void
2042 2043  ill_capability_poll_enable(ill_t *ill)
2043 2044  {
2044 2045          ill_dld_capab_t         *idc = ill->ill_dld_capab;
2045 2046          dld_capab_poll_t        poll;
2046 2047          int                     rc;
2047 2048  
2048 2049          ASSERT(!ill->ill_isv6 && IAM_WRITER_ILL(ill));
2049 2050  
2050 2051          bzero(&poll, sizeof (poll));
2051 2052          poll.poll_ring_add_cf = (uintptr_t)ip_squeue_add_ring;
2052 2053          poll.poll_ring_remove_cf = (uintptr_t)ip_squeue_clean_ring;
2053 2054          poll.poll_ring_quiesce_cf = (uintptr_t)ip_squeue_quiesce_ring;
2054 2055          poll.poll_ring_restart_cf = (uintptr_t)ip_squeue_restart_ring;
2055 2056          poll.poll_ring_bind_cf = (uintptr_t)ip_squeue_bind_ring;
2056 2057          poll.poll_ring_ch = ill;
2057 2058          rc = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_POLL, &poll,
2058 2059              DLD_ENABLE);
2059 2060          if (rc == 0) {
2060 2061                  ill->ill_capabilities |= ILL_CAPAB_DLD_POLL;
2061 2062                  DTRACE_PROBE1(poll_on, (ill_t *), ill);
2062 2063          } else {
2063 2064                  ip1dbg(("warning: could not enable POLL "
2064 2065                      "capability, rc = %d\n", rc));
2065 2066                  DTRACE_PROBE2(poll_off, (ill_t *), ill, (int), rc);
2066 2067          }
2067 2068  }
2068 2069  
2069 2070  /*
2070 2071   * Enable the LSO capability.
2071 2072   */
2072 2073  static void
2073 2074  ill_capability_lso_enable(ill_t *ill)
2074 2075  {
2075 2076          ill_dld_capab_t *idc = ill->ill_dld_capab;
2076 2077          dld_capab_lso_t lso;
2077 2078          int rc;
2078 2079  
2079 2080          ASSERT(!ill->ill_isv6 && IAM_WRITER_ILL(ill));
2080 2081  
2081 2082          if (ill->ill_lso_capab == NULL) {
2082 2083                  ill->ill_lso_capab = kmem_zalloc(sizeof (ill_lso_capab_t),
2083 2084                      KM_NOSLEEP);
2084 2085                  if (ill->ill_lso_capab == NULL) {
2085 2086                          cmn_err(CE_WARN, "ill_capability_lso_enable: "
2086 2087                              "could not enable LSO for %s (ENOMEM)\n",
2087 2088                              ill->ill_name);
2088 2089                          return;
2089 2090                  }
2090 2091          }
2091 2092  
2092 2093          bzero(&lso, sizeof (lso));
2093 2094          if ((rc = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_LSO, &lso,
2094 2095              DLD_ENABLE)) == 0) {
2095 2096                  ill->ill_lso_capab->ill_lso_flags = lso.lso_flags;
2096 2097                  ill->ill_lso_capab->ill_lso_max = lso.lso_max;
2097 2098                  ill->ill_capabilities |= ILL_CAPAB_LSO;
2098 2099                  ip1dbg(("ill_capability_lso_enable: interface %s "
2099 2100                      "has enabled LSO\n ", ill->ill_name));
2100 2101          } else {
2101 2102                  kmem_free(ill->ill_lso_capab, sizeof (ill_lso_capab_t));
2102 2103                  ill->ill_lso_capab = NULL;
2103 2104                  DTRACE_PROBE2(lso_off, (ill_t *), ill, (int), rc);
2104 2105          }
2105 2106  }
2106 2107  
2107 2108  static void
2108 2109  ill_capability_dld_enable(ill_t *ill)
2109 2110  {
2110 2111          mac_perim_handle_t mph;
2111 2112  
2112 2113          ASSERT(IAM_WRITER_ILL(ill));
2113 2114  
2114 2115          if (ill->ill_isv6)
2115 2116                  return;
2116 2117  
2117 2118          ill_mac_perim_enter(ill, &mph);
2118 2119          if (!ill->ill_isv6) {
2119 2120                  ill_capability_direct_enable(ill);
2120 2121                  ill_capability_poll_enable(ill);
2121 2122                  ill_capability_lso_enable(ill);
2122 2123          }
2123 2124          ill->ill_capabilities |= ILL_CAPAB_DLD;
2124 2125          ill_mac_perim_exit(ill, mph);
2125 2126  }
2126 2127  
2127 2128  static void
2128 2129  ill_capability_dld_disable(ill_t *ill)
2129 2130  {
2130 2131          ill_dld_capab_t *idc;
2131 2132          ill_dld_direct_t *idd;
2132 2133          mac_perim_handle_t      mph;
2133 2134  
2134 2135          ASSERT(IAM_WRITER_ILL(ill));
2135 2136  
2136 2137          if (!(ill->ill_capabilities & ILL_CAPAB_DLD))
2137 2138                  return;
2138 2139  
2139 2140          ill_mac_perim_enter(ill, &mph);
2140 2141  
2141 2142          idc = ill->ill_dld_capab;
2142 2143          if ((ill->ill_capabilities & ILL_CAPAB_DLD_DIRECT) != 0) {
2143 2144                  /*
2144 2145                   * For performance we avoid locks in the transmit data path
2145 2146                   * and don't maintain a count of the number of threads using
2146 2147                   * direct calls. Thus some threads could be using direct
2147 2148                   * transmit calls to GLD, even after the capability mechanism
2148 2149                   * turns it off. This is still safe since the handles used in
2149 2150                   * the direct calls continue to be valid until the unplumb is
2150 2151                   * completed. Remove the callback that was added (1-time) at
2151 2152                   * capab enable time.
2152 2153                   */
2153 2154                  mutex_enter(&ill->ill_lock);
2154 2155                  ill->ill_capabilities &= ~ILL_CAPAB_DLD_DIRECT;
2155 2156                  mutex_exit(&ill->ill_lock);
2156 2157                  if (ill->ill_flownotify_mh != NULL) {
2157 2158                          idd = &idc->idc_direct;
2158 2159                          idd->idd_tx_cb_df(idd->idd_tx_cb_dh, NULL,
2159 2160                              ill->ill_flownotify_mh);
2160 2161                          ill->ill_flownotify_mh = NULL;
2161 2162                  }
2162 2163                  (void) idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_DIRECT,
2163 2164                      NULL, DLD_DISABLE);
2164 2165          }
2165 2166  
2166 2167          if ((ill->ill_capabilities & ILL_CAPAB_DLD_POLL) != 0) {
2167 2168                  ill->ill_capabilities &= ~ILL_CAPAB_DLD_POLL;
2168 2169                  ip_squeue_clean_all(ill);
2169 2170                  (void) idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_POLL,
2170 2171                      NULL, DLD_DISABLE);
2171 2172          }
2172 2173  
2173 2174          if ((ill->ill_capabilities & ILL_CAPAB_LSO) != 0) {
2174 2175                  ASSERT(ill->ill_lso_capab != NULL);
2175 2176                  /*
2176 2177                   * Clear the capability flag for LSO but retain the
2177 2178                   * ill_lso_capab structure since it's possible that another
2178 2179                   * thread is still referring to it.  The structure only gets
2179 2180                   * deallocated when we destroy the ill.
2180 2181                   */
2181 2182  
2182 2183                  ill->ill_capabilities &= ~ILL_CAPAB_LSO;
2183 2184                  (void) idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_LSO,
2184 2185                      NULL, DLD_DISABLE);
2185 2186          }
2186 2187  
2187 2188          ill->ill_capabilities &= ~ILL_CAPAB_DLD;
2188 2189          ill_mac_perim_exit(ill, mph);
2189 2190  }
2190 2191  
2191 2192  /*
2192 2193   * Capability Negotiation protocol
2193 2194   *
2194 2195   * We don't wait for DLPI capability operations to finish during interface
2195 2196   * bringup or teardown. Doing so would introduce more asynchrony and the
2196 2197   * interface up/down operations will need multiple return and restarts.
2197 2198   * Instead the 'ipsq_current_ipif' of the ipsq is not cleared as long as
2198 2199   * the 'ill_dlpi_deferred' chain is non-empty. This ensures that the next
2199 2200   * exclusive operation won't start until the DLPI operations of the previous
2200 2201   * exclusive operation complete.
2201 2202   *
2202 2203   * The capability state machine is shown below.
2203 2204   *
2204 2205   * state                next state              event, action
2205 2206   *
2206 2207   * IDCS_UNKNOWN         IDCS_PROBE_SENT         ill_capability_probe
2207 2208   * IDCS_PROBE_SENT      IDCS_OK                 ill_capability_ack
2208 2209   * IDCS_PROBE_SENT      IDCS_FAILED             ip_rput_dlpi_writer (nack)
2209 2210   * IDCS_OK              IDCS_RENEG              Receipt of DL_NOTE_CAPAB_RENEG
2210 2211   * IDCS_OK              IDCS_RESET_SENT         ill_capability_reset
2211 2212   * IDCS_RESET_SENT      IDCS_UNKNOWN            ill_capability_ack_thr
2212 2213   * IDCS_RENEG           IDCS_PROBE_SENT         ill_capability_ack_thr ->
2213 2214   *                                                  ill_capability_probe.
2214 2215   */
2215 2216  
2216 2217  /*
2217 2218   * Dedicated thread started from ip_stack_init that handles capability
2218 2219   * disable. This thread ensures the taskq dispatch does not fail by waiting
2219 2220   * for resources using TQ_SLEEP. The taskq mechanism is used to ensure
2220 2221   * that direct calls to DLD are done in a cv_waitable context.
2221 2222   */
2222 2223  void
2223 2224  ill_taskq_dispatch(ip_stack_t *ipst)
2224 2225  {
2225 2226          callb_cpr_t cprinfo;
2226 2227          char    name[64];
2227 2228          mblk_t  *mp;
2228 2229  
2229 2230          (void) snprintf(name, sizeof (name), "ill_taskq_dispatch_%d",
2230 2231              ipst->ips_netstack->netstack_stackid);
2231 2232          CALLB_CPR_INIT(&cprinfo, &ipst->ips_capab_taskq_lock, callb_generic_cpr,
2232 2233              name);
2233 2234          mutex_enter(&ipst->ips_capab_taskq_lock);
2234 2235  
2235 2236          for (;;) {
2236 2237                  mp = ipst->ips_capab_taskq_head;
2237 2238                  while (mp != NULL) {
2238 2239                          ipst->ips_capab_taskq_head = mp->b_next;
2239 2240                          if (ipst->ips_capab_taskq_head == NULL)
2240 2241                                  ipst->ips_capab_taskq_tail = NULL;
2241 2242                          mutex_exit(&ipst->ips_capab_taskq_lock);
2242 2243                          mp->b_next = NULL;
2243 2244  
2244 2245                          VERIFY(taskq_dispatch(system_taskq,
2245 2246                              ill_capability_ack_thr, mp, TQ_SLEEP) != 0);
2246 2247                          mutex_enter(&ipst->ips_capab_taskq_lock);
2247 2248                          mp = ipst->ips_capab_taskq_head;
2248 2249                  }
2249 2250  
2250 2251                  if (ipst->ips_capab_taskq_quit)
2251 2252                          break;
2252 2253                  CALLB_CPR_SAFE_BEGIN(&cprinfo);
2253 2254                  cv_wait(&ipst->ips_capab_taskq_cv, &ipst->ips_capab_taskq_lock);
2254 2255                  CALLB_CPR_SAFE_END(&cprinfo, &ipst->ips_capab_taskq_lock);
2255 2256          }
2256 2257          VERIFY(ipst->ips_capab_taskq_head == NULL);
2257 2258          VERIFY(ipst->ips_capab_taskq_tail == NULL);
2258 2259          CALLB_CPR_EXIT(&cprinfo);
2259 2260          thread_exit();
2260 2261  }
2261 2262  
2262 2263  /*
2263 2264   * Consume a new-style hardware capabilities negotiation ack.
2264 2265   * Called via taskq on receipt of DL_CAPABILITY_ACK.
2265 2266   */
2266 2267  static void
2267 2268  ill_capability_ack_thr(void *arg)
2268 2269  {
2269 2270          mblk_t  *mp = arg;
2270 2271          dl_capability_ack_t *capp;
2271 2272          dl_capability_sub_t *subp, *endp;
2272 2273          ill_t   *ill;
2273 2274          boolean_t reneg;
2274 2275  
2275 2276          ill = (ill_t *)mp->b_prev;
2276 2277          mp->b_prev = NULL;
2277 2278  
2278 2279          VERIFY(ipsq_enter(ill, B_FALSE, CUR_OP) == B_TRUE);
2279 2280  
2280 2281          if (ill->ill_dlpi_capab_state == IDCS_RESET_SENT ||
2281 2282              ill->ill_dlpi_capab_state == IDCS_RENEG) {
2282 2283                  /*
2283 2284                   * We have received the ack for our DL_CAPAB reset request.
2284 2285                   * There isnt' anything in the message that needs processing.
2285 2286                   * All message based capabilities have been disabled, now
2286 2287                   * do the function call based capability disable.
2287 2288                   */
2288 2289                  reneg = ill->ill_dlpi_capab_state == IDCS_RENEG;
2289 2290                  ill_capability_dld_disable(ill);
2290 2291                  ill->ill_dlpi_capab_state = IDCS_UNKNOWN;
2291 2292                  if (reneg)
2292 2293                          ill_capability_probe(ill);
2293 2294                  goto done;
2294 2295          }
2295 2296  
2296 2297          if (ill->ill_dlpi_capab_state == IDCS_PROBE_SENT)
2297 2298                  ill->ill_dlpi_capab_state = IDCS_OK;
2298 2299  
2299 2300          capp = (dl_capability_ack_t *)mp->b_rptr;
2300 2301  
2301 2302          if (capp->dl_sub_length == 0) {
2302 2303                  /* no new-style capabilities */
2303 2304                  goto done;
2304 2305          }
2305 2306  
2306 2307          /* make sure the driver supplied correct dl_sub_length */
2307 2308          if ((sizeof (*capp) + capp->dl_sub_length) > MBLKL(mp)) {
2308 2309                  ip0dbg(("ill_capability_ack: bad DL_CAPABILITY_ACK, "
2309 2310                      "invalid dl_sub_length (%d)\n", capp->dl_sub_length));
2310 2311                  goto done;
2311 2312          }
2312 2313  
2313 2314  #define SC(base, offset) (dl_capability_sub_t *)(((uchar_t *)(base))+(offset))
2314 2315          /*
2315 2316           * There are sub-capabilities. Process the ones we know about.
2316 2317           * Loop until we don't have room for another sub-cap header..
2317 2318           */
2318 2319          for (subp = SC(capp, capp->dl_sub_offset),
2319 2320              endp = SC(subp, capp->dl_sub_length - sizeof (*subp));
2320 2321              subp <= endp;
2321 2322              subp = SC(subp, sizeof (dl_capability_sub_t) + subp->dl_length)) {
2322 2323  
2323 2324                  switch (subp->dl_cap) {
2324 2325                  case DL_CAPAB_ID_WRAPPER:
2325 2326                          ill_capability_id_ack(ill, mp, subp);
2326 2327                          break;
2327 2328                  default:
2328 2329                          ill_capability_dispatch(ill, mp, subp);
2329 2330                          break;
2330 2331                  }
2331 2332          }
2332 2333  #undef SC
2333 2334  done:
2334 2335          inet_freemsg(mp);
2335 2336          ill_capability_done(ill);
2336 2337          ipsq_exit(ill->ill_phyint->phyint_ipsq);
2337 2338  }
2338 2339  
2339 2340  /*
2340 2341   * This needs to be started in a taskq thread to provide a cv_waitable
2341 2342   * context.
2342 2343   */
2343 2344  void
2344 2345  ill_capability_ack(ill_t *ill, mblk_t *mp)
2345 2346  {
2346 2347          ip_stack_t      *ipst = ill->ill_ipst;
2347 2348  
2348 2349          mp->b_prev = (mblk_t *)ill;
2349 2350          ASSERT(mp->b_next == NULL);
2350 2351  
2351 2352          if (taskq_dispatch(system_taskq, ill_capability_ack_thr, mp,
2352 2353              TQ_NOSLEEP) != 0)
2353 2354                  return;
2354 2355  
2355 2356          /*
2356 2357           * The taskq dispatch failed. Signal the ill_taskq_dispatch thread
2357 2358           * which will do the dispatch using TQ_SLEEP to guarantee success.
2358 2359           */
2359 2360          mutex_enter(&ipst->ips_capab_taskq_lock);
2360 2361          if (ipst->ips_capab_taskq_head == NULL) {
2361 2362                  ASSERT(ipst->ips_capab_taskq_tail == NULL);
2362 2363                  ipst->ips_capab_taskq_head = mp;
2363 2364          } else {
2364 2365                  ipst->ips_capab_taskq_tail->b_next = mp;
2365 2366          }
2366 2367          ipst->ips_capab_taskq_tail = mp;
2367 2368  
2368 2369          cv_signal(&ipst->ips_capab_taskq_cv);
2369 2370          mutex_exit(&ipst->ips_capab_taskq_lock);
2370 2371  }
2371 2372  
2372 2373  /*
2373 2374   * This routine is called to scan the fragmentation reassembly table for
2374 2375   * the specified ILL for any packets that are starting to smell.
2375 2376   * dead_interval is the maximum time in seconds that will be tolerated.  It
2376 2377   * will either be the value specified in ip_g_frag_timeout, or zero if the
2377 2378   * ILL is shutting down and it is time to blow everything off.
2378 2379   *
2379 2380   * It returns the number of seconds (as a time_t) that the next frag timer
2380 2381   * should be scheduled for, 0 meaning that the timer doesn't need to be
2381 2382   * re-started.  Note that the method of calculating next_timeout isn't
2382 2383   * entirely accurate since time will flow between the time we grab
2383 2384   * current_time and the time we schedule the next timeout.  This isn't a
2384 2385   * big problem since this is the timer for sending an ICMP reassembly time
2385 2386   * exceeded messages, and it doesn't have to be exactly accurate.
2386 2387   *
2387 2388   * This function is
2388 2389   * sometimes called as writer, although this is not required.
2389 2390   */
2390 2391  time_t
2391 2392  ill_frag_timeout(ill_t *ill, time_t dead_interval)
2392 2393  {
2393 2394          ipfb_t  *ipfb;
2394 2395          ipfb_t  *endp;
2395 2396          ipf_t   *ipf;
2396 2397          ipf_t   *ipfnext;
2397 2398          mblk_t  *mp;
2398 2399          time_t  current_time = gethrestime_sec();
2399 2400          time_t  next_timeout = 0;
2400 2401          uint32_t        hdr_length;
2401 2402          mblk_t  *send_icmp_head;
2402 2403          mblk_t  *send_icmp_head_v6;
2403 2404          ip_stack_t *ipst = ill->ill_ipst;
2404 2405          ip_recv_attr_t iras;
2405 2406  
2406 2407          bzero(&iras, sizeof (iras));
2407 2408          iras.ira_flags = 0;
2408 2409          iras.ira_ill = iras.ira_rill = ill;
2409 2410          iras.ira_ruifindex = ill->ill_phyint->phyint_ifindex;
2410 2411          iras.ira_rifindex = iras.ira_ruifindex;
2411 2412  
2412 2413          ipfb = ill->ill_frag_hash_tbl;
2413 2414          if (ipfb == NULL)
2414 2415                  return (B_FALSE);
2415 2416          endp = &ipfb[ILL_FRAG_HASH_TBL_COUNT];
2416 2417          /* Walk the frag hash table. */
2417 2418          for (; ipfb < endp; ipfb++) {
2418 2419                  send_icmp_head = NULL;
2419 2420                  send_icmp_head_v6 = NULL;
2420 2421                  mutex_enter(&ipfb->ipfb_lock);
2421 2422                  while ((ipf = ipfb->ipfb_ipf) != 0) {
2422 2423                          time_t frag_time = current_time - ipf->ipf_timestamp;
2423 2424                          time_t frag_timeout;
2424 2425  
2425 2426                          if (frag_time < dead_interval) {
2426 2427                                  /*
2427 2428                                   * There are some outstanding fragments
2428 2429                                   * that will timeout later.  Make note of
2429 2430                                   * the time so that we can reschedule the
2430 2431                                   * next timeout appropriately.
2431 2432                                   */
2432 2433                                  frag_timeout = dead_interval - frag_time;
2433 2434                                  if (next_timeout == 0 ||
2434 2435                                      frag_timeout < next_timeout) {
2435 2436                                          next_timeout = frag_timeout;
2436 2437                                  }
2437 2438                                  break;
2438 2439                          }
2439 2440                          /* Time's up.  Get it out of here. */
2440 2441                          hdr_length = ipf->ipf_nf_hdr_len;
2441 2442                          ipfnext = ipf->ipf_hash_next;
2442 2443                          if (ipfnext)
2443 2444                                  ipfnext->ipf_ptphn = ipf->ipf_ptphn;
2444 2445                          *ipf->ipf_ptphn = ipfnext;
2445 2446                          mp = ipf->ipf_mp->b_cont;
2446 2447                          for (; mp; mp = mp->b_cont) {
2447 2448                                  /* Extra points for neatness. */
2448 2449                                  IP_REASS_SET_START(mp, 0);
2449 2450                                  IP_REASS_SET_END(mp, 0);
2450 2451                          }
2451 2452                          mp = ipf->ipf_mp->b_cont;
2452 2453                          atomic_add_32(&ill->ill_frag_count, -ipf->ipf_count);
2453 2454                          ASSERT(ipfb->ipfb_count >= ipf->ipf_count);
2454 2455                          ipfb->ipfb_count -= ipf->ipf_count;
2455 2456                          ASSERT(ipfb->ipfb_frag_pkts > 0);
2456 2457                          ipfb->ipfb_frag_pkts--;
2457 2458                          /*
2458 2459                           * We do not send any icmp message from here because
2459 2460                           * we currently are holding the ipfb_lock for this
2460 2461                           * hash chain. If we try and send any icmp messages
2461 2462                           * from here we may end up via a put back into ip
2462 2463                           * trying to get the same lock, causing a recursive
2463 2464                           * mutex panic. Instead we build a list and send all
2464 2465                           * the icmp messages after we have dropped the lock.
2465 2466                           */
2466 2467                          if (ill->ill_isv6) {
2467 2468                                  if (hdr_length != 0) {
2468 2469                                          mp->b_next = send_icmp_head_v6;
2469 2470                                          send_icmp_head_v6 = mp;
2470 2471                                  } else {
2471 2472                                          freemsg(mp);
2472 2473                                  }
2473 2474                          } else {
2474 2475                                  if (hdr_length != 0) {
2475 2476                                          mp->b_next = send_icmp_head;
2476 2477                                          send_icmp_head = mp;
2477 2478                                  } else {
2478 2479                                          freemsg(mp);
2479 2480                                  }
2480 2481                          }
2481 2482                          BUMP_MIB(ill->ill_ip_mib, ipIfStatsReasmFails);
2482 2483                          ip_drop_input("ipIfStatsReasmFails", ipf->ipf_mp, ill);
2483 2484                          freeb(ipf->ipf_mp);
2484 2485                  }
2485 2486                  mutex_exit(&ipfb->ipfb_lock);
2486 2487                  /*
2487 2488                   * Now need to send any icmp messages that we delayed from
2488 2489                   * above.
2489 2490                   */
2490 2491                  while (send_icmp_head_v6 != NULL) {
2491 2492                          ip6_t *ip6h;
2492 2493  
2493 2494                          mp = send_icmp_head_v6;
2494 2495                          send_icmp_head_v6 = send_icmp_head_v6->b_next;
2495 2496                          mp->b_next = NULL;
2496 2497                          ip6h = (ip6_t *)mp->b_rptr;
2497 2498                          iras.ira_flags = 0;
2498 2499                          /*
2499 2500                           * This will result in an incorrect ALL_ZONES zoneid
2500 2501                           * for multicast packets, but we
2501 2502                           * don't send ICMP errors for those in any case.
2502 2503                           */
2503 2504                          iras.ira_zoneid =
2504 2505                              ipif_lookup_addr_zoneid_v6(&ip6h->ip6_dst,
2505 2506                              ill, ipst);
2506 2507                          ip_drop_input("ICMP_TIME_EXCEEDED reass", mp, ill);
2507 2508                          icmp_time_exceeded_v6(mp,
2508 2509                              ICMP_REASSEMBLY_TIME_EXCEEDED, B_FALSE,
2509 2510                              &iras);
2510 2511                          ASSERT(!(iras.ira_flags & IRAF_IPSEC_SECURE));
2511 2512                  }
2512 2513                  while (send_icmp_head != NULL) {
2513 2514                          ipaddr_t dst;
2514 2515  
2515 2516                          mp = send_icmp_head;
2516 2517                          send_icmp_head = send_icmp_head->b_next;
2517 2518                          mp->b_next = NULL;
2518 2519  
2519 2520                          dst = ((ipha_t *)mp->b_rptr)->ipha_dst;
2520 2521  
2521 2522                          iras.ira_flags = IRAF_IS_IPV4;
2522 2523                          /*
2523 2524                           * This will result in an incorrect ALL_ZONES zoneid
2524 2525                           * for broadcast and multicast packets, but we
2525 2526                           * don't send ICMP errors for those in any case.
2526 2527                           */
2527 2528                          iras.ira_zoneid = ipif_lookup_addr_zoneid(dst,
2528 2529                              ill, ipst);
2529 2530                          ip_drop_input("ICMP_TIME_EXCEEDED reass", mp, ill);
2530 2531                          icmp_time_exceeded(mp,
2531 2532                              ICMP_REASSEMBLY_TIME_EXCEEDED, &iras);
2532 2533                          ASSERT(!(iras.ira_flags & IRAF_IPSEC_SECURE));
2533 2534                  }
2534 2535          }
2535 2536          /*
2536 2537           * A non-dying ILL will use the return value to decide whether to
2537 2538           * restart the frag timer, and for how long.
2538 2539           */
2539 2540          return (next_timeout);
2540 2541  }
2541 2542  
2542 2543  /*
2543 2544   * This routine is called when the approximate count of mblk memory used
2544 2545   * for the specified ILL has exceeded max_count.
2545 2546   */
2546 2547  void
2547 2548  ill_frag_prune(ill_t *ill, uint_t max_count)
2548 2549  {
2549 2550          ipfb_t  *ipfb;
2550 2551          ipf_t   *ipf;
2551 2552          size_t  count;
2552 2553          clock_t now;
2553 2554  
2554 2555          /*
2555 2556           * If we are here within ip_min_frag_prune_time msecs remove
2556 2557           * ill_frag_free_num_pkts oldest packets from each bucket and increment
2557 2558           * ill_frag_free_num_pkts.
2558 2559           */
2559 2560          mutex_enter(&ill->ill_lock);
2560 2561          now = ddi_get_lbolt();
2561 2562          if (TICK_TO_MSEC(now - ill->ill_last_frag_clean_time) <=
2562 2563              (ip_min_frag_prune_time != 0 ?
2563 2564              ip_min_frag_prune_time : msec_per_tick)) {
2564 2565  
2565 2566                  ill->ill_frag_free_num_pkts++;
2566 2567  
2567 2568          } else {
2568 2569                  ill->ill_frag_free_num_pkts = 0;
2569 2570          }
2570 2571          ill->ill_last_frag_clean_time = now;
2571 2572          mutex_exit(&ill->ill_lock);
2572 2573  
2573 2574          /*
2574 2575           * free ill_frag_free_num_pkts oldest packets from each bucket.
2575 2576           */
2576 2577          if (ill->ill_frag_free_num_pkts != 0) {
2577 2578                  int ix;
2578 2579  
2579 2580                  for (ix = 0; ix < ILL_FRAG_HASH_TBL_COUNT; ix++) {
2580 2581                          ipfb = &ill->ill_frag_hash_tbl[ix];
2581 2582                          mutex_enter(&ipfb->ipfb_lock);
2582 2583                          if (ipfb->ipfb_ipf != NULL) {
2583 2584                                  ill_frag_free_pkts(ill, ipfb, ipfb->ipfb_ipf,
2584 2585                                      ill->ill_frag_free_num_pkts);
2585 2586                          }
2586 2587                          mutex_exit(&ipfb->ipfb_lock);
2587 2588                  }
2588 2589          }
2589 2590          /*
2590 2591           * While the reassembly list for this ILL is too big, prune a fragment
2591 2592           * queue by age, oldest first.
2592 2593           */
2593 2594          while (ill->ill_frag_count > max_count) {
2594 2595                  int     ix;
2595 2596                  ipfb_t  *oipfb = NULL;
2596 2597                  uint_t  oldest = UINT_MAX;
2597 2598  
2598 2599                  count = 0;
2599 2600                  for (ix = 0; ix < ILL_FRAG_HASH_TBL_COUNT; ix++) {
2600 2601                          ipfb = &ill->ill_frag_hash_tbl[ix];
2601 2602                          mutex_enter(&ipfb->ipfb_lock);
2602 2603                          ipf = ipfb->ipfb_ipf;
2603 2604                          if (ipf != NULL && ipf->ipf_gen < oldest) {
2604 2605                                  oldest = ipf->ipf_gen;
2605 2606                                  oipfb = ipfb;
2606 2607                          }
2607 2608                          count += ipfb->ipfb_count;
2608 2609                          mutex_exit(&ipfb->ipfb_lock);
2609 2610                  }
2610 2611                  if (oipfb == NULL)
2611 2612                          break;
2612 2613  
2613 2614                  if (count <= max_count)
2614 2615                          return; /* Somebody beat us to it, nothing to do */
2615 2616                  mutex_enter(&oipfb->ipfb_lock);
2616 2617                  ipf = oipfb->ipfb_ipf;
2617 2618                  if (ipf != NULL) {
2618 2619                          ill_frag_free_pkts(ill, oipfb, ipf, 1);
2619 2620                  }
2620 2621                  mutex_exit(&oipfb->ipfb_lock);
2621 2622          }
2622 2623  }
2623 2624  
2624 2625  /*
2625 2626   * free 'free_cnt' fragmented packets starting at ipf.
2626 2627   */
2627 2628  void
2628 2629  ill_frag_free_pkts(ill_t *ill, ipfb_t *ipfb, ipf_t *ipf, int free_cnt)
2629 2630  {
2630 2631          size_t  count;
2631 2632          mblk_t  *mp;
2632 2633          mblk_t  *tmp;
2633 2634          ipf_t **ipfp = ipf->ipf_ptphn;
2634 2635  
2635 2636          ASSERT(MUTEX_HELD(&ipfb->ipfb_lock));
2636 2637          ASSERT(ipfp != NULL);
2637 2638          ASSERT(ipf != NULL);
2638 2639  
2639 2640          while (ipf != NULL && free_cnt-- > 0) {
2640 2641                  count = ipf->ipf_count;
2641 2642                  mp = ipf->ipf_mp;
2642 2643                  ipf = ipf->ipf_hash_next;
2643 2644                  for (tmp = mp; tmp; tmp = tmp->b_cont) {
2644 2645                          IP_REASS_SET_START(tmp, 0);
2645 2646                          IP_REASS_SET_END(tmp, 0);
2646 2647                  }
2647 2648                  atomic_add_32(&ill->ill_frag_count, -count);
2648 2649                  ASSERT(ipfb->ipfb_count >= count);
2649 2650                  ipfb->ipfb_count -= count;
2650 2651                  ASSERT(ipfb->ipfb_frag_pkts > 0);
2651 2652                  ipfb->ipfb_frag_pkts--;
2652 2653                  BUMP_MIB(ill->ill_ip_mib, ipIfStatsReasmFails);
2653 2654                  ip_drop_input("ipIfStatsReasmFails", mp, ill);
2654 2655                  freemsg(mp);
2655 2656          }
2656 2657  
2657 2658          if (ipf)
2658 2659                  ipf->ipf_ptphn = ipfp;
2659 2660          ipfp[0] = ipf;
2660 2661  }
2661 2662  
2662 2663  /*
2663 2664   * Helper function for ill_forward_set().
2664 2665   */
2665 2666  static void
2666 2667  ill_forward_set_on_ill(ill_t *ill, boolean_t enable)
2667 2668  {
2668 2669          ip_stack_t      *ipst = ill->ill_ipst;
2669 2670  
2670 2671          ASSERT(IAM_WRITER_ILL(ill) || RW_READ_HELD(&ipst->ips_ill_g_lock));
2671 2672  
2672 2673          ip1dbg(("ill_forward_set: %s %s forwarding on %s",
2673 2674              (enable ? "Enabling" : "Disabling"),
2674 2675              (ill->ill_isv6 ? "IPv6" : "IPv4"), ill->ill_name));
2675 2676          mutex_enter(&ill->ill_lock);
2676 2677          if (enable)
2677 2678                  ill->ill_flags |= ILLF_ROUTER;
2678 2679          else
2679 2680                  ill->ill_flags &= ~ILLF_ROUTER;
2680 2681          mutex_exit(&ill->ill_lock);
2681 2682          if (ill->ill_isv6)
2682 2683                  ill_set_nce_router_flags(ill, enable);
2683 2684          /* Notify routing socket listeners of this change. */
2684 2685          if (ill->ill_ipif != NULL)
2685 2686                  ip_rts_ifmsg(ill->ill_ipif, RTSQ_DEFAULT);
2686 2687  }
2687 2688  
2688 2689  /*
2689 2690   * Set an ill's ILLF_ROUTER flag appropriately.  Send up RTS_IFINFO routing
2690 2691   * socket messages for each interface whose flags we change.
2691 2692   */
2692 2693  int
2693 2694  ill_forward_set(ill_t *ill, boolean_t enable)
2694 2695  {
2695 2696          ipmp_illgrp_t *illg;
2696 2697          ip_stack_t *ipst = ill->ill_ipst;
2697 2698  
2698 2699          ASSERT(IAM_WRITER_ILL(ill) || RW_READ_HELD(&ipst->ips_ill_g_lock));
2699 2700  
2700 2701          if ((enable && (ill->ill_flags & ILLF_ROUTER)) ||
2701 2702              (!enable && !(ill->ill_flags & ILLF_ROUTER)))
2702 2703                  return (0);
2703 2704  
2704 2705          if (IS_LOOPBACK(ill))
2705 2706                  return (EINVAL);
2706 2707  
2707 2708          if (enable && ill->ill_allowed_ips_cnt > 0)
2708 2709                  return (EPERM);
2709 2710  
2710 2711          if (IS_IPMP(ill) || IS_UNDER_IPMP(ill)) {
2711 2712                  /*
2712 2713                   * Update all of the interfaces in the group.
2713 2714                   */
2714 2715                  illg = ill->ill_grp;
2715 2716                  ill = list_head(&illg->ig_if);
2716 2717                  for (; ill != NULL; ill = list_next(&illg->ig_if, ill))
2717 2718                          ill_forward_set_on_ill(ill, enable);
2718 2719  
2719 2720                  /*
2720 2721                   * Update the IPMP meta-interface.
2721 2722                   */
2722 2723                  ill_forward_set_on_ill(ipmp_illgrp_ipmp_ill(illg), enable);
2723 2724                  return (0);
2724 2725          }
2725 2726  
2726 2727          ill_forward_set_on_ill(ill, enable);
2727 2728          return (0);
2728 2729  }
2729 2730  
2730 2731  /*
2731 2732   * Based on the ILLF_ROUTER flag of an ill, make sure all local nce's for
2732 2733   * addresses assigned to the ill have the NCE_F_ISROUTER flag appropriately
2733 2734   * set or clear.
2734 2735   */
2735 2736  static void
2736 2737  ill_set_nce_router_flags(ill_t *ill, boolean_t enable)
2737 2738  {
2738 2739          ipif_t *ipif;
2739 2740          ncec_t *ncec;
2740 2741          nce_t *nce;
2741 2742  
2742 2743          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
2743 2744                  /*
2744 2745                   * NOTE: we match across the illgrp because nce's for
2745 2746                   * addresses on IPMP interfaces have an nce_ill that points to
2746 2747                   * the bound underlying ill.
2747 2748                   */
2748 2749                  nce = nce_lookup_v6(ill, &ipif->ipif_v6lcl_addr);
2749 2750                  if (nce != NULL) {
2750 2751                          ncec = nce->nce_common;
2751 2752                          mutex_enter(&ncec->ncec_lock);
2752 2753                          if (enable)
2753 2754                                  ncec->ncec_flags |= NCE_F_ISROUTER;
2754 2755                          else
2755 2756                                  ncec->ncec_flags &= ~NCE_F_ISROUTER;
2756 2757                          mutex_exit(&ncec->ncec_lock);
2757 2758                          nce_refrele(nce);
2758 2759                  }
2759 2760          }
2760 2761  }
2761 2762  
2762 2763  /*
2763 2764   * Intializes the context structure and returns the first ill in the list
2764 2765   * cuurently start_list and end_list can have values:
2765 2766   * MAX_G_HEADS          Traverse both IPV4 and IPV6 lists.
2766 2767   * IP_V4_G_HEAD         Traverse IPV4 list only.
2767 2768   * IP_V6_G_HEAD         Traverse IPV6 list only.
2768 2769   */
2769 2770  
2770 2771  /*
2771 2772   * We don't check for CONDEMNED ills here. Caller must do that if
2772 2773   * necessary under the ill lock.
2773 2774   */
2774 2775  ill_t *
2775 2776  ill_first(int start_list, int end_list, ill_walk_context_t *ctx,
2776 2777      ip_stack_t *ipst)
2777 2778  {
2778 2779          ill_if_t *ifp;
2779 2780          ill_t *ill;
2780 2781          avl_tree_t *avl_tree;
2781 2782  
2782 2783          ASSERT(RW_LOCK_HELD(&ipst->ips_ill_g_lock));
2783 2784          ASSERT(end_list <= MAX_G_HEADS && start_list >= 0);
2784 2785  
2785 2786          /*
2786 2787           * setup the lists to search
2787 2788           */
2788 2789          if (end_list != MAX_G_HEADS) {
2789 2790                  ctx->ctx_current_list = start_list;
2790 2791                  ctx->ctx_last_list = end_list;
2791 2792          } else {
2792 2793                  ctx->ctx_last_list = MAX_G_HEADS - 1;
2793 2794                  ctx->ctx_current_list = 0;
2794 2795          }
2795 2796  
2796 2797          while (ctx->ctx_current_list <= ctx->ctx_last_list) {
2797 2798                  ifp = IP_VX_ILL_G_LIST(ctx->ctx_current_list, ipst);
2798 2799                  if (ifp != (ill_if_t *)
2799 2800                      &IP_VX_ILL_G_LIST(ctx->ctx_current_list, ipst)) {
2800 2801                          avl_tree = &ifp->illif_avl_by_ppa;
2801 2802                          ill = avl_first(avl_tree);
2802 2803                          /*
2803 2804                           * ill is guaranteed to be non NULL or ifp should have
2804 2805                           * not existed.
2805 2806                           */
2806 2807                          ASSERT(ill != NULL);
2807 2808                          return (ill);
2808 2809                  }
2809 2810                  ctx->ctx_current_list++;
2810 2811          }
2811 2812  
2812 2813          return (NULL);
2813 2814  }
2814 2815  
2815 2816  /*
2816 2817   * returns the next ill in the list. ill_first() must have been called
2817 2818   * before calling ill_next() or bad things will happen.
2818 2819   */
2819 2820  
2820 2821  /*
2821 2822   * We don't check for CONDEMNED ills here. Caller must do that if
2822 2823   * necessary under the ill lock.
2823 2824   */
2824 2825  ill_t *
2825 2826  ill_next(ill_walk_context_t *ctx, ill_t *lastill)
2826 2827  {
2827 2828          ill_if_t *ifp;
2828 2829          ill_t *ill;
2829 2830          ip_stack_t      *ipst = lastill->ill_ipst;
2830 2831  
2831 2832          ASSERT(lastill->ill_ifptr != (ill_if_t *)
2832 2833              &IP_VX_ILL_G_LIST(ctx->ctx_current_list, ipst));
2833 2834          if ((ill = avl_walk(&lastill->ill_ifptr->illif_avl_by_ppa, lastill,
2834 2835              AVL_AFTER)) != NULL) {
2835 2836                  return (ill);
2836 2837          }
2837 2838  
2838 2839          /* goto next ill_ifp in the list. */
2839 2840          ifp = lastill->ill_ifptr->illif_next;
2840 2841  
2841 2842          /* make sure not at end of circular list */
2842 2843          while (ifp ==
2843 2844              (ill_if_t *)&IP_VX_ILL_G_LIST(ctx->ctx_current_list, ipst)) {
2844 2845                  if (++ctx->ctx_current_list > ctx->ctx_last_list)
2845 2846                          return (NULL);
2846 2847                  ifp = IP_VX_ILL_G_LIST(ctx->ctx_current_list, ipst);
2847 2848          }
2848 2849  
2849 2850          return (avl_first(&ifp->illif_avl_by_ppa));
2850 2851  }
2851 2852  
2852 2853  /*
2853 2854   * Check interface name for correct format: [a-zA-Z]+[a-zA-Z0-9._]*[0-9]+
2854 2855   * The final number (PPA) must not have any leading zeros.  Upon success, a
2855 2856   * pointer to the start of the PPA is returned; otherwise NULL is returned.
2856 2857   */
2857 2858  static char *
2858 2859  ill_get_ppa_ptr(char *name)
2859 2860  {
2860 2861          int namelen = strlen(name);
2861 2862          int end_ndx = namelen - 1;
2862 2863          int ppa_ndx, i;
2863 2864  
2864 2865          /*
2865 2866           * Check that the first character is [a-zA-Z], and that the last
2866 2867           * character is [0-9].
2867 2868           */
2868 2869          if (namelen == 0 || !isalpha(name[0]) || !isdigit(name[end_ndx]))
2869 2870                  return (NULL);
2870 2871  
2871 2872          /*
2872 2873           * Set `ppa_ndx' to the PPA start, and check for leading zeroes.
2873 2874           */
2874 2875          for (ppa_ndx = end_ndx; ppa_ndx > 0; ppa_ndx--)
2875 2876                  if (!isdigit(name[ppa_ndx - 1]))
2876 2877                          break;
2877 2878  
2878 2879          if (name[ppa_ndx] == '0' && ppa_ndx < end_ndx)
2879 2880                  return (NULL);
2880 2881  
2881 2882          /*
2882 2883           * Check that the intermediate characters are [a-z0-9.]
2883 2884           */
2884 2885          for (i = 1; i < ppa_ndx; i++) {
2885 2886                  if (!isalpha(name[i]) && !isdigit(name[i]) &&
2886 2887                      name[i] != '.' && name[i] != '_') {
2887 2888                          return (NULL);
2888 2889                  }
2889 2890          }
2890 2891  
2891 2892          return (name + ppa_ndx);
2892 2893  }
2893 2894  
2894 2895  /*
2895 2896   * use avl tree to locate the ill.
2896 2897   */
2897 2898  static ill_t *
2898 2899  ill_find_by_name(char *name, boolean_t isv6, ip_stack_t *ipst)
2899 2900  {
2900 2901          char *ppa_ptr = NULL;
2901 2902          int len;
2902 2903          uint_t ppa;
2903 2904          ill_t *ill = NULL;
2904 2905          ill_if_t *ifp;
2905 2906          int list;
2906 2907  
2907 2908          /*
2908 2909           * get ppa ptr
2909 2910           */
2910 2911          if (isv6)
2911 2912                  list = IP_V6_G_HEAD;
2912 2913          else
2913 2914                  list = IP_V4_G_HEAD;
2914 2915  
2915 2916          if ((ppa_ptr = ill_get_ppa_ptr(name)) == NULL) {
2916 2917                  return (NULL);
2917 2918          }
2918 2919  
2919 2920          len = ppa_ptr - name + 1;
2920 2921  
2921 2922          ppa = stoi(&ppa_ptr);
2922 2923  
2923 2924          ifp = IP_VX_ILL_G_LIST(list, ipst);
2924 2925  
2925 2926          while (ifp != (ill_if_t *)&IP_VX_ILL_G_LIST(list, ipst)) {
2926 2927                  /*
2927 2928                   * match is done on len - 1 as the name is not null
2928 2929                   * terminated it contains ppa in addition to the interface
2929 2930                   * name.
2930 2931                   */
2931 2932                  if ((ifp->illif_name_len == len) &&
2932 2933                      bcmp(ifp->illif_name, name, len - 1) == 0) {
2933 2934                          break;
2934 2935                  } else {
2935 2936                          ifp = ifp->illif_next;
2936 2937                  }
2937 2938          }
2938 2939  
2939 2940          if (ifp == (ill_if_t *)&IP_VX_ILL_G_LIST(list, ipst)) {
2940 2941                  /*
2941 2942                   * Even the interface type does not exist.
2942 2943                   */
2943 2944                  return (NULL);
2944 2945          }
2945 2946  
2946 2947          ill = avl_find(&ifp->illif_avl_by_ppa, (void *) &ppa, NULL);
2947 2948          if (ill != NULL) {
2948 2949                  mutex_enter(&ill->ill_lock);
2949 2950                  if (ILL_CAN_LOOKUP(ill)) {
2950 2951                          ill_refhold_locked(ill);
2951 2952                          mutex_exit(&ill->ill_lock);
2952 2953                          return (ill);
2953 2954                  }
2954 2955                  mutex_exit(&ill->ill_lock);
2955 2956          }
2956 2957          return (NULL);
2957 2958  }
2958 2959  
2959 2960  /*
2960 2961   * comparison function for use with avl.
2961 2962   */
2962 2963  static int
2963 2964  ill_compare_ppa(const void *ppa_ptr, const void *ill_ptr)
2964 2965  {
2965 2966          uint_t ppa;
2966 2967          uint_t ill_ppa;
2967 2968  
2968 2969          ASSERT(ppa_ptr != NULL && ill_ptr != NULL);
2969 2970  
2970 2971          ppa = *((uint_t *)ppa_ptr);
2971 2972          ill_ppa = ((const ill_t *)ill_ptr)->ill_ppa;
2972 2973          /*
2973 2974           * We want the ill with the lowest ppa to be on the
2974 2975           * top.
2975 2976           */
2976 2977          if (ill_ppa < ppa)
2977 2978                  return (1);
2978 2979          if (ill_ppa > ppa)
2979 2980                  return (-1);
2980 2981          return (0);
2981 2982  }
2982 2983  
2983 2984  /*
2984 2985   * remove an interface type from the global list.
2985 2986   */
2986 2987  static void
2987 2988  ill_delete_interface_type(ill_if_t *interface)
2988 2989  {
2989 2990          ASSERT(interface != NULL);
2990 2991          ASSERT(avl_numnodes(&interface->illif_avl_by_ppa) == 0);
2991 2992  
2992 2993          avl_destroy(&interface->illif_avl_by_ppa);
2993 2994          if (interface->illif_ppa_arena != NULL)
2994 2995                  vmem_destroy(interface->illif_ppa_arena);
2995 2996  
2996 2997          remque(interface);
2997 2998  
2998 2999          mi_free(interface);
2999 3000  }
3000 3001  
3001 3002  /*
3002 3003   * remove ill from the global list.
3003 3004   */
3004 3005  static void
3005 3006  ill_glist_delete(ill_t *ill)
3006 3007  {
3007 3008          ip_stack_t      *ipst;
3008 3009          phyint_t        *phyi;
3009 3010  
3010 3011          if (ill == NULL)
3011 3012                  return;
3012 3013          ipst = ill->ill_ipst;
3013 3014          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
3014 3015  
3015 3016          /*
3016 3017           * If the ill was never inserted into the AVL tree
3017 3018           * we skip the if branch.
3018 3019           */
3019 3020          if (ill->ill_ifptr != NULL) {
3020 3021                  /*
3021 3022                   * remove from AVL tree and free ppa number
3022 3023                   */
3023 3024                  avl_remove(&ill->ill_ifptr->illif_avl_by_ppa, ill);
3024 3025  
3025 3026                  if (ill->ill_ifptr->illif_ppa_arena != NULL) {
3026 3027                          vmem_free(ill->ill_ifptr->illif_ppa_arena,
3027 3028                              (void *)(uintptr_t)(ill->ill_ppa+1), 1);
3028 3029                  }
3029 3030                  if (avl_numnodes(&ill->ill_ifptr->illif_avl_by_ppa) == 0) {
3030 3031                          ill_delete_interface_type(ill->ill_ifptr);
3031 3032                  }
3032 3033  
3033 3034                  /*
3034 3035                   * Indicate ill is no longer in the list.
3035 3036                   */
3036 3037                  ill->ill_ifptr = NULL;
3037 3038                  ill->ill_name_length = 0;
3038 3039                  ill->ill_name[0] = '\0';
3039 3040                  ill->ill_ppa = UINT_MAX;
3040 3041          }
3041 3042  
3042 3043          /* Generate one last event for this ill. */
3043 3044          ill_nic_event_dispatch(ill, 0, NE_UNPLUMB, ill->ill_name,
3044 3045              ill->ill_name_length);
3045 3046  
3046 3047          ASSERT(ill->ill_phyint != NULL);
3047 3048          phyi = ill->ill_phyint;
3048 3049          ill->ill_phyint = NULL;
3049 3050  
3050 3051          /*
3051 3052           * ill_init allocates a phyint always to store the copy
3052 3053           * of flags relevant to phyint. At that point in time, we could
3053 3054           * not assign the name and hence phyint_illv4/v6 could not be
3054 3055           * initialized. Later in ipif_set_values, we assign the name to
3055 3056           * the ill, at which point in time we assign phyint_illv4/v6.
3056 3057           * Thus we don't rely on phyint_illv6 to be initialized always.
3057 3058           */
3058 3059          if (ill->ill_flags & ILLF_IPV6)
3059 3060                  phyi->phyint_illv6 = NULL;
3060 3061          else
3061 3062                  phyi->phyint_illv4 = NULL;
3062 3063  
3063 3064          if (phyi->phyint_illv4 != NULL || phyi->phyint_illv6 != NULL) {
3064 3065                  rw_exit(&ipst->ips_ill_g_lock);
3065 3066                  return;
3066 3067          }
3067 3068  
3068 3069          /*
3069 3070           * There are no ills left on this phyint; pull it out of the phyint
3070 3071           * avl trees, and free it.
3071 3072           */
3072 3073          if (phyi->phyint_ifindex > 0) {
3073 3074                  avl_remove(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
3074 3075                      phyi);
3075 3076                  avl_remove(&ipst->ips_phyint_g_list->phyint_list_avl_by_name,
3076 3077                      phyi);
3077 3078          }
3078 3079          rw_exit(&ipst->ips_ill_g_lock);
3079 3080  
3080 3081          phyint_free(phyi);
3081 3082  }
3082 3083  
3083 3084  /*
3084 3085   * allocate a ppa, if the number of plumbed interfaces of this type are
3085 3086   * less than ill_no_arena do a linear search to find a unused ppa.
3086 3087   * When the number goes beyond ill_no_arena switch to using an arena.
3087 3088   * Note: ppa value of zero cannot be allocated from vmem_arena as it
3088 3089   * is the return value for an error condition, so allocation starts at one
3089 3090   * and is decremented by one.
3090 3091   */
3091 3092  static int
3092 3093  ill_alloc_ppa(ill_if_t *ifp, ill_t *ill)
3093 3094  {
3094 3095          ill_t *tmp_ill;
3095 3096          uint_t start, end;
3096 3097          int ppa;
3097 3098  
3098 3099          if (ifp->illif_ppa_arena == NULL &&
3099 3100              (avl_numnodes(&ifp->illif_avl_by_ppa) + 1 > ill_no_arena)) {
3100 3101                  /*
3101 3102                   * Create an arena.
3102 3103                   */
3103 3104                  ifp->illif_ppa_arena = vmem_create(ifp->illif_name,
3104 3105                      (void *)1, UINT_MAX - 1, 1, NULL, NULL,
3105 3106                      NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
3106 3107                          /* allocate what has already been assigned */
3107 3108                  for (tmp_ill = avl_first(&ifp->illif_avl_by_ppa);
3108 3109                      tmp_ill != NULL; tmp_ill = avl_walk(&ifp->illif_avl_by_ppa,
3109 3110                      tmp_ill, AVL_AFTER)) {
3110 3111                          ppa = (int)(uintptr_t)vmem_xalloc(ifp->illif_ppa_arena,
3111 3112                              1,          /* size */
3112 3113                              1,          /* align/quantum */
3113 3114                              0,          /* phase */
3114 3115                              0,          /* nocross */
3115 3116                              /* minaddr */
3116 3117                              (void *)((uintptr_t)tmp_ill->ill_ppa + 1),
3117 3118                              /* maxaddr */
3118 3119                              (void *)((uintptr_t)tmp_ill->ill_ppa + 2),
3119 3120                              VM_NOSLEEP|VM_FIRSTFIT);
3120 3121                          if (ppa == 0) {
3121 3122                                  ip1dbg(("ill_alloc_ppa: ppa allocation"
3122 3123                                      " failed while switching"));
3123 3124                                  vmem_destroy(ifp->illif_ppa_arena);
3124 3125                                  ifp->illif_ppa_arena = NULL;
3125 3126                                  break;
3126 3127                          }
3127 3128                  }
3128 3129          }
3129 3130  
3130 3131          if (ifp->illif_ppa_arena != NULL) {
3131 3132                  if (ill->ill_ppa == UINT_MAX) {
3132 3133                          ppa = (int)(uintptr_t)vmem_alloc(ifp->illif_ppa_arena,
3133 3134                              1, VM_NOSLEEP|VM_FIRSTFIT);
3134 3135                          if (ppa == 0)
3135 3136                                  return (EAGAIN);
3136 3137                          ill->ill_ppa = --ppa;
3137 3138                  } else {
3138 3139                          ppa = (int)(uintptr_t)vmem_xalloc(ifp->illif_ppa_arena,
3139 3140                              1,          /* size */
3140 3141                              1,          /* align/quantum */
3141 3142                              0,          /* phase */
3142 3143                              0,          /* nocross */
3143 3144                              (void *)(uintptr_t)(ill->ill_ppa + 1), /* minaddr */
3144 3145                              (void *)(uintptr_t)(ill->ill_ppa + 2), /* maxaddr */
3145 3146                              VM_NOSLEEP|VM_FIRSTFIT);
3146 3147                          /*
3147 3148                           * Most likely the allocation failed because
3148 3149                           * the requested ppa was in use.
3149 3150                           */
3150 3151                          if (ppa == 0)
3151 3152                                  return (EEXIST);
3152 3153                  }
3153 3154                  return (0);
3154 3155          }
3155 3156  
3156 3157          /*
3157 3158           * No arena is in use and not enough (>ill_no_arena) interfaces have
3158 3159           * been plumbed to create one. Do a linear search to get a unused ppa.
3159 3160           */
3160 3161          if (ill->ill_ppa == UINT_MAX) {
3161 3162                  end = UINT_MAX - 1;
3162 3163                  start = 0;
3163 3164          } else {
3164 3165                  end = start = ill->ill_ppa;
3165 3166          }
3166 3167  
3167 3168          tmp_ill = avl_find(&ifp->illif_avl_by_ppa, (void *)&start, NULL);
3168 3169          while (tmp_ill != NULL && tmp_ill->ill_ppa == start) {
3169 3170                  if (start++ >= end) {
3170 3171                          if (ill->ill_ppa == UINT_MAX)
3171 3172                                  return (EAGAIN);
3172 3173                          else
3173 3174                                  return (EEXIST);
3174 3175                  }
3175 3176                  tmp_ill = avl_walk(&ifp->illif_avl_by_ppa, tmp_ill, AVL_AFTER);
3176 3177          }
3177 3178          ill->ill_ppa = start;
3178 3179          return (0);
3179 3180  }
3180 3181  
3181 3182  /*
3182 3183   * Insert ill into the list of configured ill's. Once this function completes,
3183 3184   * the ill is globally visible and is available through lookups. More precisely
3184 3185   * this happens after the caller drops the ill_g_lock.
3185 3186   */
3186 3187  static int
3187 3188  ill_glist_insert(ill_t *ill, char *name, boolean_t isv6)
3188 3189  {
3189 3190          ill_if_t *ill_interface;
3190 3191          avl_index_t where = 0;
3191 3192          int error;
3192 3193          int name_length;
3193 3194          int index;
3194 3195          boolean_t check_length = B_FALSE;
3195 3196          ip_stack_t      *ipst = ill->ill_ipst;
3196 3197  
3197 3198          ASSERT(RW_WRITE_HELD(&ipst->ips_ill_g_lock));
3198 3199  
3199 3200          name_length = mi_strlen(name) + 1;
3200 3201  
3201 3202          if (isv6)
3202 3203                  index = IP_V6_G_HEAD;
3203 3204          else
3204 3205                  index = IP_V4_G_HEAD;
3205 3206  
3206 3207          ill_interface = IP_VX_ILL_G_LIST(index, ipst);
3207 3208          /*
3208 3209           * Search for interface type based on name
3209 3210           */
3210 3211          while (ill_interface != (ill_if_t *)&IP_VX_ILL_G_LIST(index, ipst)) {
3211 3212                  if ((ill_interface->illif_name_len == name_length) &&
3212 3213                      (strcmp(ill_interface->illif_name, name) == 0)) {
3213 3214                          break;
3214 3215                  }
3215 3216                  ill_interface = ill_interface->illif_next;
3216 3217          }
3217 3218  
3218 3219          /*
3219 3220           * Interface type not found, create one.
3220 3221           */
3221 3222          if (ill_interface == (ill_if_t *)&IP_VX_ILL_G_LIST(index, ipst)) {
3222 3223                  ill_g_head_t ghead;
3223 3224  
3224 3225                  /*
3225 3226                   * allocate ill_if_t structure
3226 3227                   */
3227 3228                  ill_interface = (ill_if_t *)mi_zalloc(sizeof (ill_if_t));
3228 3229                  if (ill_interface == NULL) {
3229 3230                          return (ENOMEM);
3230 3231                  }
3231 3232  
3232 3233                  (void) strcpy(ill_interface->illif_name, name);
3233 3234                  ill_interface->illif_name_len = name_length;
3234 3235  
3235 3236                  avl_create(&ill_interface->illif_avl_by_ppa,
3236 3237                      ill_compare_ppa, sizeof (ill_t),
3237 3238                      offsetof(struct ill_s, ill_avl_byppa));
3238 3239  
3239 3240                  /*
3240 3241                   * link the structure in the back to maintain order
3241 3242                   * of configuration for ifconfig output.
3242 3243                   */
3243 3244                  ghead = ipst->ips_ill_g_heads[index];
3244 3245                  insque(ill_interface, ghead.ill_g_list_tail);
3245 3246          }
3246 3247  
3247 3248          if (ill->ill_ppa == UINT_MAX)
3248 3249                  check_length = B_TRUE;
3249 3250  
3250 3251          error = ill_alloc_ppa(ill_interface, ill);
3251 3252          if (error != 0) {
3252 3253                  if (avl_numnodes(&ill_interface->illif_avl_by_ppa) == 0)
3253 3254                          ill_delete_interface_type(ill->ill_ifptr);
3254 3255                  return (error);
3255 3256          }
3256 3257  
3257 3258          /*
3258 3259           * When the ppa is choosen by the system, check that there is
3259 3260           * enough space to insert ppa. if a specific ppa was passed in this
3260 3261           * check is not required as the interface name passed in will have
3261 3262           * the right ppa in it.
3262 3263           */
3263 3264          if (check_length) {
3264 3265                  /*
3265 3266                   * UINT_MAX - 1 should fit in 10 chars, alloc 12 chars.
3266 3267                   */
3267 3268                  char buf[sizeof (uint_t) * 3];
3268 3269  
3269 3270                  /*
3270 3271                   * convert ppa to string to calculate the amount of space
3271 3272                   * required for it in the name.
3272 3273                   */
3273 3274                  numtos(ill->ill_ppa, buf);
3274 3275  
3275 3276                  /* Do we have enough space to insert ppa ? */
3276 3277  
3277 3278                  if ((mi_strlen(name) + mi_strlen(buf) + 1) > LIFNAMSIZ) {
3278 3279                          /* Free ppa and interface type struct */
3279 3280                          if (ill_interface->illif_ppa_arena != NULL) {
3280 3281                                  vmem_free(ill_interface->illif_ppa_arena,
3281 3282                                      (void *)(uintptr_t)(ill->ill_ppa+1), 1);
3282 3283                          }
3283 3284                          if (avl_numnodes(&ill_interface->illif_avl_by_ppa) == 0)
3284 3285                                  ill_delete_interface_type(ill->ill_ifptr);
3285 3286  
3286 3287                          return (EINVAL);
3287 3288                  }
3288 3289          }
3289 3290  
3290 3291          (void) sprintf(ill->ill_name, "%s%u", name, ill->ill_ppa);
3291 3292          ill->ill_name_length = mi_strlen(ill->ill_name) + 1;
3292 3293  
3293 3294          (void) avl_find(&ill_interface->illif_avl_by_ppa, &ill->ill_ppa,
3294 3295              &where);
3295 3296          ill->ill_ifptr = ill_interface;
3296 3297          avl_insert(&ill_interface->illif_avl_by_ppa, ill, where);
3297 3298  
3298 3299          ill_phyint_reinit(ill);
3299 3300          return (0);
3300 3301  }
3301 3302  
3302 3303  /* Initialize the per phyint ipsq used for serialization */
3303 3304  static boolean_t
3304 3305  ipsq_init(ill_t *ill, boolean_t enter)
3305 3306  {
3306 3307          ipsq_t  *ipsq;
3307 3308          ipxop_t *ipx;
3308 3309  
3309 3310          if ((ipsq = kmem_zalloc(sizeof (ipsq_t), KM_NOSLEEP)) == NULL)
3310 3311                  return (B_FALSE);
3311 3312  
3312 3313          ill->ill_phyint->phyint_ipsq = ipsq;
3313 3314          ipx = ipsq->ipsq_xop = &ipsq->ipsq_ownxop;
3314 3315          ipx->ipx_ipsq = ipsq;
3315 3316          ipsq->ipsq_next = ipsq;
3316 3317          ipsq->ipsq_phyint = ill->ill_phyint;
3317 3318          mutex_init(&ipsq->ipsq_lock, NULL, MUTEX_DEFAULT, 0);
3318 3319          mutex_init(&ipx->ipx_lock, NULL, MUTEX_DEFAULT, 0);
3319 3320          ipsq->ipsq_ipst = ill->ill_ipst;        /* No netstack_hold */
3320 3321          if (enter) {
3321 3322                  ipx->ipx_writer = curthread;
3322 3323                  ipx->ipx_forced = B_FALSE;
3323 3324                  ipx->ipx_reentry_cnt = 1;
3324 3325  #ifdef DEBUG
3325 3326                  ipx->ipx_depth = getpcstack(ipx->ipx_stack, IPX_STACK_DEPTH);
3326 3327  #endif
3327 3328          }
3328 3329          return (B_TRUE);
3329 3330  }
3330 3331  
3331 3332  /*
3332 3333   * ill_init is called by ip_open when a device control stream is opened.
3333 3334   * It does a few initializations, and shoots a DL_INFO_REQ message down
3334 3335   * to the driver.  The response is later picked up in ip_rput_dlpi and
3335 3336   * used to set up default mechanisms for talking to the driver.  (Always
3336 3337   * called as writer.)
3337 3338   *
3338 3339   * If this function returns error, ip_open will call ip_close which in
3339 3340   * turn will call ill_delete to clean up any memory allocated here that
3340 3341   * is not yet freed.
3341 3342   */
3342 3343  int
3343 3344  ill_init(queue_t *q, ill_t *ill)
3344 3345  {
3345 3346          int     count;
3346 3347          dl_info_req_t   *dlir;
3347 3348          mblk_t  *info_mp;
3348 3349          uchar_t *frag_ptr;
3349 3350  
3350 3351          /*
3351 3352           * The ill is initialized to zero by mi_alloc*(). In addition
3352 3353           * some fields already contain valid values, initialized in
3353 3354           * ip_open(), before we reach here.
3354 3355           */
3355 3356          mutex_init(&ill->ill_lock, NULL, MUTEX_DEFAULT, 0);
3356 3357          mutex_init(&ill->ill_saved_ire_lock, NULL, MUTEX_DEFAULT, NULL);
3357 3358          ill->ill_saved_ire_cnt = 0;
3358 3359  
3359 3360          ill->ill_rq = q;
3360 3361          ill->ill_wq = WR(q);
3361 3362  
3362 3363          info_mp = allocb(MAX(sizeof (dl_info_req_t), sizeof (dl_info_ack_t)),
3363 3364              BPRI_HI);
3364 3365          if (info_mp == NULL)
3365 3366                  return (ENOMEM);
3366 3367  
3367 3368          /*
3368 3369           * Allocate sufficient space to contain our fragment hash table and
3369 3370           * the device name.
3370 3371           */
3371 3372          frag_ptr = (uchar_t *)mi_zalloc(ILL_FRAG_HASH_TBL_SIZE + 2 * LIFNAMSIZ);
3372 3373          if (frag_ptr == NULL) {
3373 3374                  freemsg(info_mp);
3374 3375                  return (ENOMEM);
3375 3376          }
3376 3377          ill->ill_frag_ptr = frag_ptr;
3377 3378          ill->ill_frag_free_num_pkts = 0;
3378 3379          ill->ill_last_frag_clean_time = 0;
3379 3380          ill->ill_frag_hash_tbl = (ipfb_t *)frag_ptr;
3380 3381          ill->ill_name = (char *)(frag_ptr + ILL_FRAG_HASH_TBL_SIZE);
3381 3382          for (count = 0; count < ILL_FRAG_HASH_TBL_COUNT; count++) {
3382 3383                  mutex_init(&ill->ill_frag_hash_tbl[count].ipfb_lock,
3383 3384                      NULL, MUTEX_DEFAULT, NULL);
3384 3385          }
3385 3386  
3386 3387          ill->ill_phyint = (phyint_t *)mi_zalloc(sizeof (phyint_t));
3387 3388          if (ill->ill_phyint == NULL) {
3388 3389                  freemsg(info_mp);
3389 3390                  mi_free(frag_ptr);
3390 3391                  return (ENOMEM);
3391 3392          }
3392 3393  
3393 3394          mutex_init(&ill->ill_phyint->phyint_lock, NULL, MUTEX_DEFAULT, 0);
3394 3395          /*
3395 3396           * For now pretend this is a v4 ill. We need to set phyint_ill*
3396 3397           * at this point because of the following reason. If we can't
3397 3398           * enter the ipsq at some point and cv_wait, the writer that
3398 3399           * wakes us up tries to locate us using the list of all phyints
3399 3400           * in an ipsq and the ills from the phyint thru the phyint_ill*.
3400 3401           * If we don't set it now, we risk a missed wakeup.
3401 3402           */
3402 3403          ill->ill_phyint->phyint_illv4 = ill;
3403 3404          ill->ill_ppa = UINT_MAX;
3404 3405          list_create(&ill->ill_nce, sizeof (nce_t), offsetof(nce_t, nce_node));
3405 3406  
3406 3407          ill_set_inputfn(ill);
3407 3408  
3408 3409          if (!ipsq_init(ill, B_TRUE)) {
3409 3410                  freemsg(info_mp);
3410 3411                  mi_free(frag_ptr);
3411 3412                  mi_free(ill->ill_phyint);
3412 3413                  return (ENOMEM);
3413 3414          }
3414 3415  
3415 3416          ill->ill_state_flags |= ILL_LL_SUBNET_PENDING;
3416 3417  
3417 3418          /* Frag queue limit stuff */
3418 3419          ill->ill_frag_count = 0;
3419 3420          ill->ill_ipf_gen = 0;
3420 3421  
3421 3422          rw_init(&ill->ill_mcast_lock, NULL, RW_DEFAULT, NULL);
3422 3423          mutex_init(&ill->ill_mcast_serializer, NULL, MUTEX_DEFAULT, NULL);
3423 3424          ill->ill_global_timer = INFINITY;
3424 3425          ill->ill_mcast_v1_time = ill->ill_mcast_v2_time = 0;
3425 3426          ill->ill_mcast_v1_tset = ill->ill_mcast_v2_tset = 0;
3426 3427          ill->ill_mcast_rv = MCAST_DEF_ROBUSTNESS;
3427 3428          ill->ill_mcast_qi = MCAST_DEF_QUERY_INTERVAL;
3428 3429  
3429 3430          /*
3430 3431           * Initialize IPv6 configuration variables.  The IP module is always
3431 3432           * opened as an IPv4 module.  Instead tracking down the cases where
3432 3433           * it switches to do ipv6, we'll just initialize the IPv6 configuration
3433 3434           * here for convenience, this has no effect until the ill is set to do
3434 3435           * IPv6.
3435 3436           */
3436 3437          ill->ill_reachable_time = ND_REACHABLE_TIME;
3437 3438          ill->ill_xmit_count = ND_MAX_MULTICAST_SOLICIT;
3438 3439          ill->ill_max_buf = ND_MAX_Q;
3439 3440          ill->ill_refcnt = 0;
3440 3441  
3441 3442          /* Send down the Info Request to the driver. */
3442 3443          info_mp->b_datap->db_type = M_PCPROTO;
3443 3444          dlir = (dl_info_req_t *)info_mp->b_rptr;
3444 3445          info_mp->b_wptr = (uchar_t *)&dlir[1];
3445 3446          dlir->dl_primitive = DL_INFO_REQ;
3446 3447  
3447 3448          ill->ill_dlpi_pending = DL_PRIM_INVAL;
3448 3449  
3449 3450          qprocson(q);
3450 3451          ill_dlpi_send(ill, info_mp);
3451 3452  
3452 3453          return (0);
3453 3454  }
3454 3455  
3455 3456  /*
3456 3457   * ill_dls_info
3457 3458   * creates datalink socket info from the device.
3458 3459   */
3459 3460  int
3460 3461  ill_dls_info(struct sockaddr_dl *sdl, const ill_t *ill)
3461 3462  {
3462 3463          size_t  len;
3463 3464  
3464 3465          sdl->sdl_family = AF_LINK;
3465 3466          sdl->sdl_index = ill_get_upper_ifindex(ill);
3466 3467          sdl->sdl_type = ill->ill_type;
3467 3468          ill_get_name(ill, sdl->sdl_data, sizeof (sdl->sdl_data));
3468 3469          len = strlen(sdl->sdl_data);
3469 3470          ASSERT(len < 256);
3470 3471          sdl->sdl_nlen = (uchar_t)len;
3471 3472          sdl->sdl_alen = ill->ill_phys_addr_length;
3472 3473          sdl->sdl_slen = 0;
3473 3474          if (ill->ill_phys_addr_length != 0 && ill->ill_phys_addr != NULL)
3474 3475                  bcopy(ill->ill_phys_addr, &sdl->sdl_data[len], sdl->sdl_alen);
3475 3476  
3476 3477          return (sizeof (struct sockaddr_dl));
3477 3478  }
3478 3479  
3479 3480  /*
3480 3481   * ill_xarp_info
3481 3482   * creates xarp info from the device.
3482 3483   */
3483 3484  static int
3484 3485  ill_xarp_info(struct sockaddr_dl *sdl, ill_t *ill)
3485 3486  {
3486 3487          sdl->sdl_family = AF_LINK;
3487 3488          sdl->sdl_index = ill->ill_phyint->phyint_ifindex;
3488 3489          sdl->sdl_type = ill->ill_type;
3489 3490          ill_get_name(ill, sdl->sdl_data, sizeof (sdl->sdl_data));
3490 3491          sdl->sdl_nlen = (uchar_t)mi_strlen(sdl->sdl_data);
3491 3492          sdl->sdl_alen = ill->ill_phys_addr_length;
3492 3493          sdl->sdl_slen = 0;
3493 3494          return (sdl->sdl_nlen);
3494 3495  }
3495 3496  
3496 3497  static int
3497 3498  loopback_kstat_update(kstat_t *ksp, int rw)
3498 3499  {
3499 3500          kstat_named_t *kn;
3500 3501          netstackid_t    stackid;
3501 3502          netstack_t      *ns;
3502 3503          ip_stack_t      *ipst;
3503 3504  
3504 3505          if (ksp == NULL || ksp->ks_data == NULL)
3505 3506                  return (EIO);
3506 3507  
3507 3508          if (rw == KSTAT_WRITE)
3508 3509                  return (EACCES);
3509 3510  
3510 3511          kn = KSTAT_NAMED_PTR(ksp);
3511 3512          stackid = (zoneid_t)(uintptr_t)ksp->ks_private;
3512 3513  
3513 3514          ns = netstack_find_by_stackid(stackid);
3514 3515          if (ns == NULL)
3515 3516                  return (-1);
3516 3517  
3517 3518          ipst = ns->netstack_ip;
3518 3519          if (ipst == NULL) {
3519 3520                  netstack_rele(ns);
3520 3521                  return (-1);
3521 3522          }
3522 3523          kn[0].value.ui32 = ipst->ips_loopback_packets;
3523 3524          kn[1].value.ui32 = ipst->ips_loopback_packets;
3524 3525          netstack_rele(ns);
3525 3526          return (0);
3526 3527  }
3527 3528  
3528 3529  /*
3529 3530   * Has ifindex been plumbed already?
3530 3531   */
3531 3532  static boolean_t
3532 3533  phyint_exists(uint_t index, ip_stack_t *ipst)
3533 3534  {
3534 3535          ASSERT(index != 0);
3535 3536          ASSERT(RW_LOCK_HELD(&ipst->ips_ill_g_lock));
3536 3537  
3537 3538          return (avl_find(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
3538 3539              &index, NULL) != NULL);
3539 3540  }
3540 3541  
3541 3542  /*
3542 3543   * Pick a unique ifindex.
3543 3544   * When the index counter passes IF_INDEX_MAX for the first time, the wrap
3544 3545   * flag is set so that next time time ip_assign_ifindex() is called, it
3545 3546   * falls through and resets the index counter back to 1, the minimum value
3546 3547   * for the interface index. The logic below assumes that ips_ill_index
3547 3548   * can hold a value of IF_INDEX_MAX+1 without there being any loss
3548 3549   * (i.e. reset back to 0.)
3549 3550   */
3550 3551  boolean_t
3551 3552  ip_assign_ifindex(uint_t *indexp, ip_stack_t *ipst)
3552 3553  {
3553 3554          uint_t loops;
3554 3555  
3555 3556          if (!ipst->ips_ill_index_wrap) {
3556 3557                  *indexp = ipst->ips_ill_index++;
3557 3558                  if (ipst->ips_ill_index > IF_INDEX_MAX) {
3558 3559                          /*
3559 3560                           * Reached the maximum ifindex value, set the wrap
3560 3561                           * flag to indicate that it is no longer possible
3561 3562                           * to assume that a given index is unallocated.
3562 3563                           */
3563 3564                          ipst->ips_ill_index_wrap = B_TRUE;
3564 3565                  }
3565 3566                  return (B_TRUE);
3566 3567          }
3567 3568  
3568 3569          if (ipst->ips_ill_index > IF_INDEX_MAX)
3569 3570                  ipst->ips_ill_index = 1;
3570 3571  
3571 3572          /*
3572 3573           * Start reusing unused indexes. Note that we hold the ill_g_lock
3573 3574           * at this point and don't want to call any function that attempts
3574 3575           * to get the lock again.
3575 3576           */
3576 3577          for (loops = IF_INDEX_MAX; loops > 0; loops--) {
3577 3578                  if (!phyint_exists(ipst->ips_ill_index, ipst)) {
3578 3579                          /* found unused index - use it */
3579 3580                          *indexp = ipst->ips_ill_index;
3580 3581                          return (B_TRUE);
3581 3582                  }
3582 3583  
3583 3584                  ipst->ips_ill_index++;
3584 3585                  if (ipst->ips_ill_index > IF_INDEX_MAX)
3585 3586                          ipst->ips_ill_index = 1;
3586 3587          }
3587 3588  
3588 3589          /*
3589 3590           * all interface indicies are inuse.
3590 3591           */
3591 3592          return (B_FALSE);
3592 3593  }
3593 3594  
3594 3595  /*
3595 3596   * Assign a unique interface index for the phyint.
3596 3597   */
3597 3598  static boolean_t
3598 3599  phyint_assign_ifindex(phyint_t *phyi, ip_stack_t *ipst)
3599 3600  {
3600 3601          ASSERT(phyi->phyint_ifindex == 0);
3601 3602          return (ip_assign_ifindex(&phyi->phyint_ifindex, ipst));
3602 3603  }
3603 3604  
3604 3605  /*
3605 3606   * Initialize the flags on `phyi' as per the provided mactype.
3606 3607   */
3607 3608  static void
3608 3609  phyint_flags_init(phyint_t *phyi, t_uscalar_t mactype)
3609 3610  {
3610 3611          uint64_t flags = 0;
3611 3612  
3612 3613          /*
3613 3614           * Initialize PHYI_RUNNING and PHYI_FAILED.  For non-IPMP interfaces,
3614 3615           * we always presume the underlying hardware is working and set
3615 3616           * PHYI_RUNNING (if it's not, the driver will subsequently send a
3616 3617           * DL_NOTE_LINK_DOWN message).  For IPMP interfaces, at initialization
3617 3618           * there are no active interfaces in the group so we set PHYI_FAILED.
3618 3619           */
3619 3620          if (mactype == SUNW_DL_IPMP)
3620 3621                  flags |= PHYI_FAILED;
3621 3622          else
3622 3623                  flags |= PHYI_RUNNING;
3623 3624  
3624 3625          switch (mactype) {
3625 3626          case SUNW_DL_VNI:
3626 3627                  flags |= PHYI_VIRTUAL;
3627 3628                  break;
3628 3629          case SUNW_DL_IPMP:
3629 3630                  flags |= PHYI_IPMP;
3630 3631                  break;
3631 3632          case DL_LOOP:
3632 3633                  flags |= (PHYI_LOOPBACK | PHYI_VIRTUAL);
3633 3634                  break;
3634 3635          }
3635 3636  
3636 3637          mutex_enter(&phyi->phyint_lock);
3637 3638          phyi->phyint_flags |= flags;
3638 3639          mutex_exit(&phyi->phyint_lock);
3639 3640  }
3640 3641  
3641 3642  /*
3642 3643   * Return a pointer to the ill which matches the supplied name.  Note that
3643 3644   * the ill name length includes the null termination character.  (May be
3644 3645   * called as writer.)
3645 3646   * If do_alloc and the interface is "lo0" it will be automatically created.
3646 3647   * Cannot bump up reference on condemned ills. So dup detect can't be done
3647 3648   * using this func.
3648 3649   */
3649 3650  ill_t *
3650 3651  ill_lookup_on_name(char *name, boolean_t do_alloc, boolean_t isv6,
3651 3652      boolean_t *did_alloc, ip_stack_t *ipst)
3652 3653  {
3653 3654          ill_t   *ill;
3654 3655          ipif_t  *ipif;
3655 3656          ipsq_t  *ipsq;
3656 3657          kstat_named_t   *kn;
3657 3658          boolean_t isloopback;
3658 3659          in6_addr_t ov6addr;
3659 3660  
3660 3661          isloopback = mi_strcmp(name, ipif_loopback_name) == 0;
3661 3662  
3662 3663          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
3663 3664          ill = ill_find_by_name(name, isv6, ipst);
3664 3665          rw_exit(&ipst->ips_ill_g_lock);
3665 3666          if (ill != NULL)
3666 3667                  return (ill);
3667 3668  
3668 3669          /*
3669 3670           * Couldn't find it.  Does this happen to be a lookup for the
3670 3671           * loopback device and are we allowed to allocate it?
3671 3672           */
3672 3673          if (!isloopback || !do_alloc)
3673 3674                  return (NULL);
3674 3675  
3675 3676          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
3676 3677          ill = ill_find_by_name(name, isv6, ipst);
3677 3678          if (ill != NULL) {
3678 3679                  rw_exit(&ipst->ips_ill_g_lock);
3679 3680                  return (ill);
3680 3681          }
3681 3682  
3682 3683          /* Create the loopback device on demand */
3683 3684          ill = (ill_t *)(mi_alloc(sizeof (ill_t) +
3684 3685              sizeof (ipif_loopback_name), BPRI_MED));
3685 3686          if (ill == NULL)
3686 3687                  goto done;
3687 3688  
3688 3689          *ill = ill_null;
3689 3690          mutex_init(&ill->ill_lock, NULL, MUTEX_DEFAULT, NULL);
3690 3691          ill->ill_ipst = ipst;
3691 3692          list_create(&ill->ill_nce, sizeof (nce_t), offsetof(nce_t, nce_node));
3692 3693          netstack_hold(ipst->ips_netstack);
3693 3694          /*
3694 3695           * For exclusive stacks we set the zoneid to zero
3695 3696           * to make IP operate as if in the global zone.
3696 3697           */
3697 3698          ill->ill_zoneid = GLOBAL_ZONEID;
3698 3699  
3699 3700          ill->ill_phyint = (phyint_t *)mi_zalloc(sizeof (phyint_t));
3700 3701          if (ill->ill_phyint == NULL)
3701 3702                  goto done;
3702 3703  
3703 3704          if (isv6)
3704 3705                  ill->ill_phyint->phyint_illv6 = ill;
3705 3706          else
3706 3707                  ill->ill_phyint->phyint_illv4 = ill;
3707 3708          mutex_init(&ill->ill_phyint->phyint_lock, NULL, MUTEX_DEFAULT, 0);
3708 3709          phyint_flags_init(ill->ill_phyint, DL_LOOP);
3709 3710  
3710 3711          if (isv6) {
3711 3712                  ill->ill_isv6 = B_TRUE;
3712 3713                  ill->ill_max_frag = ip_loopback_mtu_v6plus;
3713 3714          } else {
3714 3715                  ill->ill_max_frag = ip_loopback_mtuplus;
3715 3716          }
3716 3717          if (!ill_allocate_mibs(ill))
3717 3718                  goto done;
3718 3719          ill->ill_current_frag = ill->ill_max_frag;
3719 3720          ill->ill_mtu = ill->ill_max_frag;       /* Initial value */
3720 3721          ill->ill_mc_mtu = ill->ill_mtu;
3721 3722          /*
3722 3723           * ipif_loopback_name can't be pointed at directly because its used
3723 3724           * by both the ipv4 and ipv6 interfaces.  When the ill is removed
3724 3725           * from the glist, ill_glist_delete() sets the first character of
3725 3726           * ill_name to '\0'.
3726 3727           */
3727 3728          ill->ill_name = (char *)ill + sizeof (*ill);
3728 3729          (void) strcpy(ill->ill_name, ipif_loopback_name);
3729 3730          ill->ill_name_length = sizeof (ipif_loopback_name);
3730 3731          /* Set ill_dlpi_pending for ipsq_current_finish() to work properly */
3731 3732          ill->ill_dlpi_pending = DL_PRIM_INVAL;
3732 3733  
3733 3734          rw_init(&ill->ill_mcast_lock, NULL, RW_DEFAULT, NULL);
3734 3735          mutex_init(&ill->ill_mcast_serializer, NULL, MUTEX_DEFAULT, NULL);
3735 3736          ill->ill_global_timer = INFINITY;
3736 3737          ill->ill_mcast_v1_time = ill->ill_mcast_v2_time = 0;
3737 3738          ill->ill_mcast_v1_tset = ill->ill_mcast_v2_tset = 0;
3738 3739          ill->ill_mcast_rv = MCAST_DEF_ROBUSTNESS;
3739 3740          ill->ill_mcast_qi = MCAST_DEF_QUERY_INTERVAL;
3740 3741  
3741 3742          /* No resolver here. */
3742 3743          ill->ill_net_type = IRE_LOOPBACK;
3743 3744  
3744 3745          /* Initialize the ipsq */
3745 3746          if (!ipsq_init(ill, B_FALSE))
3746 3747                  goto done;
3747 3748  
3748 3749          ipif = ipif_allocate(ill, 0L, IRE_LOOPBACK, B_TRUE, B_TRUE, NULL);
3749 3750          if (ipif == NULL)
3750 3751                  goto done;
3751 3752  
3752 3753          ill->ill_flags = ILLF_MULTICAST;
3753 3754  
3754 3755          ov6addr = ipif->ipif_v6lcl_addr;
3755 3756          /* Set up default loopback address and mask. */
3756 3757          if (!isv6) {
3757 3758                  ipaddr_t inaddr_loopback = htonl(INADDR_LOOPBACK);
3758 3759  
3759 3760                  IN6_IPADDR_TO_V4MAPPED(inaddr_loopback, &ipif->ipif_v6lcl_addr);
3760 3761                  V4MASK_TO_V6(htonl(IN_CLASSA_NET), ipif->ipif_v6net_mask);
3761 3762                  V6_MASK_COPY(ipif->ipif_v6lcl_addr, ipif->ipif_v6net_mask,
3762 3763                      ipif->ipif_v6subnet);
3763 3764                  ill->ill_flags |= ILLF_IPV4;
3764 3765          } else {
3765 3766                  ipif->ipif_v6lcl_addr = ipv6_loopback;
3766 3767                  ipif->ipif_v6net_mask = ipv6_all_ones;
3767 3768                  V6_MASK_COPY(ipif->ipif_v6lcl_addr, ipif->ipif_v6net_mask,
3768 3769                      ipif->ipif_v6subnet);
3769 3770                  ill->ill_flags |= ILLF_IPV6;
3770 3771          }
3771 3772  
3772 3773          /*
3773 3774           * Chain us in at the end of the ill list. hold the ill
3774 3775           * before we make it globally visible. 1 for the lookup.
3775 3776           */
3776 3777          ill->ill_refcnt = 0;
3777 3778          ill_refhold(ill);
3778 3779  
3779 3780          ill->ill_frag_count = 0;
3780 3781          ill->ill_frag_free_num_pkts = 0;
3781 3782          ill->ill_last_frag_clean_time = 0;
3782 3783  
3783 3784          ipsq = ill->ill_phyint->phyint_ipsq;
3784 3785  
3785 3786          ill_set_inputfn(ill);
3786 3787  
3787 3788          if (ill_glist_insert(ill, "lo", isv6) != 0)
3788 3789                  cmn_err(CE_PANIC, "cannot insert loopback interface");
3789 3790  
3790 3791          /* Let SCTP know so that it can add this to its list */
3791 3792          sctp_update_ill(ill, SCTP_ILL_INSERT);
3792 3793  
3793 3794          /*
3794 3795           * We have already assigned ipif_v6lcl_addr above, but we need to
3795 3796           * call sctp_update_ipif_addr() after SCTP_ILL_INSERT, which
3796 3797           * requires to be after ill_glist_insert() since we need the
3797 3798           * ill_index set. Pass on ipv6_loopback as the old address.
3798 3799           */
3799 3800          sctp_update_ipif_addr(ipif, ov6addr);
3800 3801  
3801 3802          ip_rts_newaddrmsg(RTM_CHGADDR, 0, ipif, RTSQ_DEFAULT);
3802 3803  
3803 3804          /*
3804 3805           * ill_glist_insert() -> ill_phyint_reinit() may have merged IPSQs.
3805 3806           * If so, free our original one.
3806 3807           */
3807 3808          if (ipsq != ill->ill_phyint->phyint_ipsq)
3808 3809                  ipsq_delete(ipsq);
3809 3810  
3810 3811          if (ipst->ips_loopback_ksp == NULL) {
3811 3812                  /* Export loopback interface statistics */
3812 3813                  ipst->ips_loopback_ksp = kstat_create_netstack("lo", 0,
3813 3814                      ipif_loopback_name, "net",
3814 3815                      KSTAT_TYPE_NAMED, 2, 0,
3815 3816                      ipst->ips_netstack->netstack_stackid);
3816 3817                  if (ipst->ips_loopback_ksp != NULL) {
3817 3818                          ipst->ips_loopback_ksp->ks_update =
3818 3819                              loopback_kstat_update;
3819 3820                          kn = KSTAT_NAMED_PTR(ipst->ips_loopback_ksp);
3820 3821                          kstat_named_init(&kn[0], "ipackets", KSTAT_DATA_UINT32);
3821 3822                          kstat_named_init(&kn[1], "opackets", KSTAT_DATA_UINT32);
3822 3823                          ipst->ips_loopback_ksp->ks_private =
3823 3824                              (void *)(uintptr_t)ipst->ips_netstack->
3824 3825                              netstack_stackid;
3825 3826                          kstat_install(ipst->ips_loopback_ksp);
3826 3827                  }
3827 3828          }
3828 3829  
3829 3830          *did_alloc = B_TRUE;
3830 3831          rw_exit(&ipst->ips_ill_g_lock);
3831 3832          ill_nic_event_dispatch(ill, MAP_IPIF_ID(ill->ill_ipif->ipif_id),
3832 3833              NE_PLUMB, ill->ill_name, ill->ill_name_length);
3833 3834          return (ill);
3834 3835  done:
3835 3836          if (ill != NULL) {
3836 3837                  if (ill->ill_phyint != NULL) {
3837 3838                          ipsq = ill->ill_phyint->phyint_ipsq;
3838 3839                          if (ipsq != NULL) {
3839 3840                                  ipsq->ipsq_phyint = NULL;
3840 3841                                  ipsq_delete(ipsq);
3841 3842                          }
3842 3843                          mi_free(ill->ill_phyint);
3843 3844                  }
3844 3845                  ill_free_mib(ill);
3845 3846                  if (ill->ill_ipst != NULL)
3846 3847                          netstack_rele(ill->ill_ipst->ips_netstack);
3847 3848                  mi_free(ill);
3848 3849          }
3849 3850          rw_exit(&ipst->ips_ill_g_lock);
3850 3851          return (NULL);
3851 3852  }
3852 3853  
3853 3854  /*
3854 3855   * For IPP calls - use the ip_stack_t for global stack.
3855 3856   */
3856 3857  ill_t *
3857 3858  ill_lookup_on_ifindex_global_instance(uint_t index, boolean_t isv6)
3858 3859  {
3859 3860          ip_stack_t      *ipst;
3860 3861          ill_t           *ill;
3861 3862  
3862 3863          ipst = netstack_find_by_stackid(GLOBAL_NETSTACKID)->netstack_ip;
3863 3864          if (ipst == NULL) {
3864 3865                  cmn_err(CE_WARN, "No ip_stack_t for zoneid zero!\n");
3865 3866                  return (NULL);
3866 3867          }
3867 3868  
3868 3869          ill = ill_lookup_on_ifindex(index, isv6, ipst);
3869 3870          netstack_rele(ipst->ips_netstack);
3870 3871          return (ill);
3871 3872  }
3872 3873  
3873 3874  /*
3874 3875   * Return a pointer to the ill which matches the index and IP version type.
3875 3876   */
3876 3877  ill_t *
3877 3878  ill_lookup_on_ifindex(uint_t index, boolean_t isv6, ip_stack_t *ipst)
3878 3879  {
3879 3880          ill_t   *ill;
3880 3881          phyint_t *phyi;
3881 3882  
3882 3883          /*
3883 3884           * Indexes are stored in the phyint - a common structure
3884 3885           * to both IPv4 and IPv6.
3885 3886           */
3886 3887          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
3887 3888          phyi = avl_find(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
3888 3889              (void *) &index, NULL);
3889 3890          if (phyi != NULL) {
3890 3891                  ill = isv6 ? phyi->phyint_illv6: phyi->phyint_illv4;
3891 3892                  if (ill != NULL) {
3892 3893                          mutex_enter(&ill->ill_lock);
3893 3894                          if (!ILL_IS_CONDEMNED(ill)) {
3894 3895                                  ill_refhold_locked(ill);
3895 3896                                  mutex_exit(&ill->ill_lock);
3896 3897                                  rw_exit(&ipst->ips_ill_g_lock);
3897 3898                                  return (ill);
3898 3899                          }
3899 3900                          mutex_exit(&ill->ill_lock);
3900 3901                  }
3901 3902          }
3902 3903          rw_exit(&ipst->ips_ill_g_lock);
3903 3904          return (NULL);
3904 3905  }
3905 3906  
3906 3907  /*
3907 3908   * Verify whether or not an interface index is valid for the specified zoneid
3908 3909   * to transmit packets.
3909 3910   * It can be zero (meaning "reset") or an interface index assigned
3910 3911   * to a non-VNI interface. (We don't use VNI interface to send packets.)
3911 3912   */
3912 3913  boolean_t
3913 3914  ip_xmit_ifindex_valid(uint_t ifindex, zoneid_t zoneid, boolean_t isv6,
3914 3915      ip_stack_t *ipst)
3915 3916  {
3916 3917          ill_t           *ill;
3917 3918  
3918 3919          if (ifindex == 0)
3919 3920                  return (B_TRUE);
3920 3921  
3921 3922          ill = ill_lookup_on_ifindex_zoneid(ifindex, zoneid, isv6, ipst);
3922 3923          if (ill == NULL)
3923 3924                  return (B_FALSE);
3924 3925          if (IS_VNI(ill)) {
3925 3926                  ill_refrele(ill);
3926 3927                  return (B_FALSE);
3927 3928          }
3928 3929          ill_refrele(ill);
3929 3930          return (B_TRUE);
3930 3931  }
3931 3932  
3932 3933  /*
3933 3934   * Return the ifindex next in sequence after the passed in ifindex.
3934 3935   * If there is no next ifindex for the given protocol, return 0.
3935 3936   */
3936 3937  uint_t
3937 3938  ill_get_next_ifindex(uint_t index, boolean_t isv6, ip_stack_t *ipst)
3938 3939  {
3939 3940          phyint_t *phyi;
3940 3941          phyint_t *phyi_initial;
3941 3942          uint_t   ifindex;
3942 3943  
3943 3944          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
3944 3945  
3945 3946          if (index == 0) {
3946 3947                  phyi = avl_first(
3947 3948                      &ipst->ips_phyint_g_list->phyint_list_avl_by_index);
3948 3949          } else {
3949 3950                  phyi = phyi_initial = avl_find(
3950 3951                      &ipst->ips_phyint_g_list->phyint_list_avl_by_index,
3951 3952                      (void *) &index, NULL);
3952 3953          }
3953 3954  
3954 3955          for (; phyi != NULL;
3955 3956              phyi = avl_walk(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
3956 3957              phyi, AVL_AFTER)) {
3957 3958                  /*
3958 3959                   * If we're not returning the first interface in the tree
3959 3960                   * and we still haven't moved past the phyint_t that
3960 3961                   * corresponds to index, avl_walk needs to be called again
3961 3962                   */
3962 3963                  if (!((index != 0) && (phyi == phyi_initial))) {
3963 3964                          if (isv6) {
3964 3965                                  if ((phyi->phyint_illv6) &&
3965 3966                                      ILL_CAN_LOOKUP(phyi->phyint_illv6) &&
3966 3967                                      (phyi->phyint_illv6->ill_isv6 == 1))
3967 3968                                          break;
3968 3969                          } else {
3969 3970                                  if ((phyi->phyint_illv4) &&
3970 3971                                      ILL_CAN_LOOKUP(phyi->phyint_illv4) &&
3971 3972                                      (phyi->phyint_illv4->ill_isv6 == 0))
3972 3973                                          break;
3973 3974                          }
3974 3975                  }
3975 3976          }
3976 3977  
3977 3978          rw_exit(&ipst->ips_ill_g_lock);
3978 3979  
3979 3980          if (phyi != NULL)
3980 3981                  ifindex = phyi->phyint_ifindex;
3981 3982          else
3982 3983                  ifindex = 0;
3983 3984  
3984 3985          return (ifindex);
3985 3986  }
3986 3987  
3987 3988  /*
3988 3989   * Return the ifindex for the named interface.
3989 3990   * If there is no next ifindex for the interface, return 0.
3990 3991   */
3991 3992  uint_t
3992 3993  ill_get_ifindex_by_name(char *name, ip_stack_t *ipst)
3993 3994  {
3994 3995          phyint_t        *phyi;
3995 3996          avl_index_t     where = 0;
3996 3997          uint_t          ifindex;
3997 3998  
3998 3999          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
3999 4000  
4000 4001          if ((phyi = avl_find(&ipst->ips_phyint_g_list->phyint_list_avl_by_name,
4001 4002              name, &where)) == NULL) {
4002 4003                  rw_exit(&ipst->ips_ill_g_lock);
4003 4004                  return (0);
4004 4005          }
4005 4006  
4006 4007          ifindex = phyi->phyint_ifindex;
4007 4008  
4008 4009          rw_exit(&ipst->ips_ill_g_lock);
4009 4010  
4010 4011          return (ifindex);
4011 4012  }
4012 4013  
4013 4014  /*
4014 4015   * Return the ifindex to be used by upper layer protocols for instance
4015 4016   * for IPV6_RECVPKTINFO. If IPMP this is the one for the upper ill.
4016 4017   */
4017 4018  uint_t
4018 4019  ill_get_upper_ifindex(const ill_t *ill)
4019 4020  {
4020 4021          if (IS_UNDER_IPMP(ill))
4021 4022                  return (ipmp_ill_get_ipmp_ifindex(ill));
4022 4023          else
4023 4024                  return (ill->ill_phyint->phyint_ifindex);
4024 4025  }
4025 4026  
4026 4027  
4027 4028  /*
4028 4029   * Obtain a reference to the ill. The ill_refcnt is a dynamic refcnt
4029 4030   * that gives a running thread a reference to the ill. This reference must be
4030 4031   * released by the thread when it is done accessing the ill and related
4031 4032   * objects. ill_refcnt can not be used to account for static references
4032 4033   * such as other structures pointing to an ill. Callers must generally
4033 4034   * check whether an ill can be refheld by using ILL_CAN_LOOKUP macros
4034 4035   * or be sure that the ill is not being deleted or changing state before
4035 4036   * calling the refhold functions. A non-zero ill_refcnt ensures that the
4036 4037   * ill won't change any of its critical state such as address, netmask etc.
4037 4038   */
4038 4039  void
4039 4040  ill_refhold(ill_t *ill)
4040 4041  {
4041 4042          mutex_enter(&ill->ill_lock);
4042 4043          ill->ill_refcnt++;
4043 4044          ILL_TRACE_REF(ill);
4044 4045          mutex_exit(&ill->ill_lock);
4045 4046  }
4046 4047  
4047 4048  void
4048 4049  ill_refhold_locked(ill_t *ill)
4049 4050  {
4050 4051          ASSERT(MUTEX_HELD(&ill->ill_lock));
4051 4052          ill->ill_refcnt++;
4052 4053          ILL_TRACE_REF(ill);
4053 4054  }
4054 4055  
4055 4056  /* Returns true if we managed to get a refhold */
4056 4057  boolean_t
4057 4058  ill_check_and_refhold(ill_t *ill)
4058 4059  {
4059 4060          mutex_enter(&ill->ill_lock);
4060 4061          if (!ILL_IS_CONDEMNED(ill)) {
4061 4062                  ill_refhold_locked(ill);
4062 4063                  mutex_exit(&ill->ill_lock);
4063 4064                  return (B_TRUE);
4064 4065          }
4065 4066          mutex_exit(&ill->ill_lock);
4066 4067          return (B_FALSE);
4067 4068  }
4068 4069  
4069 4070  /*
4070 4071   * Must not be called while holding any locks. Otherwise if this is
4071 4072   * the last reference to be released, there is a chance of recursive mutex
4072 4073   * panic due to ill_refrele -> ipif_ill_refrele_tail -> qwriter_ip trying
4073 4074   * to restart an ioctl.
4074 4075   */
4075 4076  void
4076 4077  ill_refrele(ill_t *ill)
4077 4078  {
4078 4079          mutex_enter(&ill->ill_lock);
4079 4080          ASSERT(ill->ill_refcnt != 0);
4080 4081          ill->ill_refcnt--;
4081 4082          ILL_UNTRACE_REF(ill);
4082 4083          if (ill->ill_refcnt != 0) {
4083 4084                  /* Every ire pointing to the ill adds 1 to ill_refcnt */
4084 4085                  mutex_exit(&ill->ill_lock);
4085 4086                  return;
4086 4087          }
4087 4088  
4088 4089          /* Drops the ill_lock */
4089 4090          ipif_ill_refrele_tail(ill);
4090 4091  }
4091 4092  
4092 4093  /*
4093 4094   * Obtain a weak reference count on the ill. This reference ensures the
4094 4095   * ill won't be freed, but the ill may change any of its critical state
4095 4096   * such as netmask, address etc. Returns an error if the ill has started
4096 4097   * closing.
4097 4098   */
4098 4099  boolean_t
4099 4100  ill_waiter_inc(ill_t *ill)
4100 4101  {
4101 4102          mutex_enter(&ill->ill_lock);
4102 4103          if (ill->ill_state_flags & ILL_CONDEMNED) {
4103 4104                  mutex_exit(&ill->ill_lock);
4104 4105                  return (B_FALSE);
4105 4106          }
4106 4107          ill->ill_waiters++;
4107 4108          mutex_exit(&ill->ill_lock);
4108 4109          return (B_TRUE);
4109 4110  }
4110 4111  
4111 4112  void
4112 4113  ill_waiter_dcr(ill_t *ill)
4113 4114  {
4114 4115          mutex_enter(&ill->ill_lock);
4115 4116          ill->ill_waiters--;
4116 4117          if (ill->ill_waiters == 0)
4117 4118                  cv_broadcast(&ill->ill_cv);
4118 4119          mutex_exit(&ill->ill_lock);
4119 4120  }
4120 4121  
4121 4122  /*
4122 4123   * ip_ll_subnet_defaults is called when we get the DL_INFO_ACK back from the
4123 4124   * driver.  We construct best guess defaults for lower level information that
4124 4125   * we need.  If an interface is brought up without injection of any overriding
4125 4126   * information from outside, we have to be ready to go with these defaults.
4126 4127   * When we get the first DL_INFO_ACK (from ip_open() sending a DL_INFO_REQ)
4127 4128   * we primarely want the dl_provider_style.
4128 4129   * The subsequent DL_INFO_ACK is received after doing a DL_ATTACH and DL_BIND
4129 4130   * at which point we assume the other part of the information is valid.
4130 4131   */
4131 4132  void
4132 4133  ip_ll_subnet_defaults(ill_t *ill, mblk_t *mp)
4133 4134  {
4134 4135          uchar_t         *brdcst_addr;
4135 4136          uint_t          brdcst_addr_length, phys_addr_length;
4136 4137          t_scalar_t      sap_length;
4137 4138          dl_info_ack_t   *dlia;
4138 4139          ip_m_t          *ipm;
4139 4140          dl_qos_cl_sel1_t *sel1;
4140 4141          int             min_mtu;
4141 4142  
4142 4143          ASSERT(IAM_WRITER_ILL(ill));
4143 4144  
4144 4145          /*
4145 4146           * Till the ill is fully up  the ill is not globally visible.
4146 4147           * So no need for a lock.
4147 4148           */
4148 4149          dlia = (dl_info_ack_t *)mp->b_rptr;
4149 4150          ill->ill_mactype = dlia->dl_mac_type;
4150 4151  
4151 4152          ipm = ip_m_lookup(dlia->dl_mac_type);
4152 4153          if (ipm == NULL) {
4153 4154                  ipm = ip_m_lookup(DL_OTHER);
4154 4155                  ASSERT(ipm != NULL);
4155 4156          }
4156 4157          ill->ill_media = ipm;
4157 4158  
4158 4159          /*
4159 4160           * When the new DLPI stuff is ready we'll pull lengths
4160 4161           * from dlia.
4161 4162           */
4162 4163          if (dlia->dl_version == DL_VERSION_2) {
4163 4164                  brdcst_addr_length = dlia->dl_brdcst_addr_length;
4164 4165                  brdcst_addr = mi_offset_param(mp, dlia->dl_brdcst_addr_offset,
4165 4166                      brdcst_addr_length);
4166 4167                  if (brdcst_addr == NULL) {
4167 4168                          brdcst_addr_length = 0;
4168 4169                  }
4169 4170                  sap_length = dlia->dl_sap_length;
4170 4171                  phys_addr_length = dlia->dl_addr_length - ABS(sap_length);
4171 4172                  ip1dbg(("ip: bcast_len %d, sap_len %d, phys_len %d\n",
4172 4173                      brdcst_addr_length, sap_length, phys_addr_length));
4173 4174          } else {
4174 4175                  brdcst_addr_length = 6;
4175 4176                  brdcst_addr = ip_six_byte_all_ones;
4176 4177                  sap_length = -2;
4177 4178                  phys_addr_length = brdcst_addr_length;
4178 4179          }
4179 4180  
4180 4181          ill->ill_bcast_addr_length = brdcst_addr_length;
4181 4182          ill->ill_phys_addr_length = phys_addr_length;
4182 4183          ill->ill_sap_length = sap_length;
4183 4184  
4184 4185          /*
4185 4186           * Synthetic DLPI types such as SUNW_DL_IPMP specify a zero SDU,
4186 4187           * but we must ensure a minimum IP MTU is used since other bits of
4187 4188           * IP will fly apart otherwise.
4188 4189           */
4189 4190          min_mtu = ill->ill_isv6 ? IPV6_MIN_MTU : IP_MIN_MTU;
4190 4191          ill->ill_max_frag = MAX(min_mtu, dlia->dl_max_sdu);
4191 4192          ill->ill_current_frag = ill->ill_max_frag;
4192 4193          ill->ill_mtu = ill->ill_max_frag;
4193 4194          ill->ill_mc_mtu = ill->ill_mtu; /* Overridden by DL_NOTE_SDU_SIZE2 */
4194 4195  
4195 4196          ill->ill_type = ipm->ip_m_type;
4196 4197  
4197 4198          if (!ill->ill_dlpi_style_set) {
4198 4199                  if (dlia->dl_provider_style == DL_STYLE2)
4199 4200                          ill->ill_needs_attach = 1;
4200 4201  
4201 4202                  phyint_flags_init(ill->ill_phyint, ill->ill_mactype);
4202 4203  
4203 4204                  /*
4204 4205                   * Allocate the first ipif on this ill.  We don't delay it
4205 4206                   * further as ioctl handling assumes at least one ipif exists.
4206 4207                   *
4207 4208                   * At this point we don't know whether the ill is v4 or v6.
4208 4209                   * We will know this whan the SIOCSLIFNAME happens and
4209 4210                   * the correct value for ill_isv6 will be assigned in
4210 4211                   * ipif_set_values(). We need to hold the ill lock and
4211 4212                   * clear the ILL_LL_SUBNET_PENDING flag and atomically do
4212 4213                   * the wakeup.
4213 4214                   */
4214 4215                  (void) ipif_allocate(ill, 0, IRE_LOCAL,
4215 4216                      dlia->dl_provider_style != DL_STYLE2, B_TRUE, NULL);
4216 4217                  mutex_enter(&ill->ill_lock);
4217 4218                  ASSERT(ill->ill_dlpi_style_set == 0);
4218 4219                  ill->ill_dlpi_style_set = 1;
4219 4220                  ill->ill_state_flags &= ~ILL_LL_SUBNET_PENDING;
4220 4221                  cv_broadcast(&ill->ill_cv);
4221 4222                  mutex_exit(&ill->ill_lock);
4222 4223                  freemsg(mp);
4223 4224                  return;
4224 4225          }
4225 4226          ASSERT(ill->ill_ipif != NULL);
4226 4227          /*
4227 4228           * We know whether it is IPv4 or IPv6 now, as this is the
4228 4229           * second DL_INFO_ACK we are recieving in response to the
4229 4230           * DL_INFO_REQ sent in ipif_set_values.
4230 4231           */
4231 4232          ill->ill_sap = (ill->ill_isv6) ? ipm->ip_m_ipv6sap : ipm->ip_m_ipv4sap;
4232 4233          /*
4233 4234           * Clear all the flags that were set based on ill_bcast_addr_length
4234 4235           * and ill_phys_addr_length (in ipif_set_values) as these could have
4235 4236           * changed now and we need to re-evaluate.
4236 4237           */
4237 4238          ill->ill_flags &= ~(ILLF_MULTICAST | ILLF_NONUD | ILLF_NOARP);
4238 4239          ill->ill_ipif->ipif_flags &= ~(IPIF_BROADCAST | IPIF_POINTOPOINT);
4239 4240  
4240 4241          /*
4241 4242           * Free ill_bcast_mp as things could have changed now.
4242 4243           *
4243 4244           * NOTE: The IPMP meta-interface is special-cased because it starts
4244 4245           * with no underlying interfaces (and thus an unknown broadcast
4245 4246           * address length), but we enforce that an interface is broadcast-
4246 4247           * capable as part of allowing it to join a group.
4247 4248           */
4248 4249          if (ill->ill_bcast_addr_length == 0 && !IS_IPMP(ill)) {
4249 4250                  if (ill->ill_bcast_mp != NULL)
4250 4251                          freemsg(ill->ill_bcast_mp);
4251 4252                  ill->ill_net_type = IRE_IF_NORESOLVER;
4252 4253  
4253 4254                  ill->ill_bcast_mp = ill_dlur_gen(NULL,
4254 4255                      ill->ill_phys_addr_length,
4255 4256                      ill->ill_sap,
4256 4257                      ill->ill_sap_length);
4257 4258  
4258 4259                  if (ill->ill_isv6)
4259 4260                          /*
4260 4261                           * Note: xresolv interfaces will eventually need NOARP
4261 4262                           * set here as well, but that will require those
4262 4263                           * external resolvers to have some knowledge of
4263 4264                           * that flag and act appropriately. Not to be changed
4264 4265                           * at present.
4265 4266                           */
4266 4267                          ill->ill_flags |= ILLF_NONUD;
4267 4268                  else
4268 4269                          ill->ill_flags |= ILLF_NOARP;
4269 4270  
4270 4271                  if (ill->ill_mactype == SUNW_DL_VNI) {
4271 4272                          ill->ill_ipif->ipif_flags |= IPIF_NOXMIT;
4272 4273                  } else if (ill->ill_phys_addr_length == 0 ||
4273 4274                      ill->ill_mactype == DL_IPV4 ||
4274 4275                      ill->ill_mactype == DL_IPV6) {
4275 4276                          /*
4276 4277                           * The underying link is point-to-point, so mark the
4277 4278                           * interface as such.  We can do IP multicast over
4278 4279                           * such a link since it transmits all network-layer
4279 4280                           * packets to the remote side the same way.
4280 4281                           */
4281 4282                          ill->ill_flags |= ILLF_MULTICAST;
4282 4283                          ill->ill_ipif->ipif_flags |= IPIF_POINTOPOINT;
4283 4284                  }
4284 4285          } else {
4285 4286                  ill->ill_net_type = IRE_IF_RESOLVER;
4286 4287                  if (ill->ill_bcast_mp != NULL)
4287 4288                          freemsg(ill->ill_bcast_mp);
4288 4289                  ill->ill_bcast_mp = ill_dlur_gen(brdcst_addr,
4289 4290                      ill->ill_bcast_addr_length, ill->ill_sap,
4290 4291                      ill->ill_sap_length);
4291 4292                  /*
4292 4293                   * Later detect lack of DLPI driver multicast
4293 4294                   * capability by catching DL_ENABMULTI errors in
4294 4295                   * ip_rput_dlpi.
4295 4296                   */
4296 4297                  ill->ill_flags |= ILLF_MULTICAST;
4297 4298                  if (!ill->ill_isv6)
4298 4299                          ill->ill_ipif->ipif_flags |= IPIF_BROADCAST;
4299 4300          }
4300 4301  
4301 4302          /* For IPMP, PHYI_IPMP should already be set by phyint_flags_init() */
4302 4303          if (ill->ill_mactype == SUNW_DL_IPMP)
4303 4304                  ASSERT(ill->ill_phyint->phyint_flags & PHYI_IPMP);
4304 4305  
4305 4306          /* By default an interface does not support any CoS marking */
4306 4307          ill->ill_flags &= ~ILLF_COS_ENABLED;
4307 4308  
4308 4309          /*
4309 4310           * If we get QoS information in DL_INFO_ACK, the device supports
4310 4311           * some form of CoS marking, set ILLF_COS_ENABLED.
4311 4312           */
4312 4313          sel1 = (dl_qos_cl_sel1_t *)mi_offset_param(mp, dlia->dl_qos_offset,
4313 4314              dlia->dl_qos_length);
4314 4315          if ((sel1 != NULL) && (sel1->dl_qos_type == DL_QOS_CL_SEL1)) {
4315 4316                  ill->ill_flags |= ILLF_COS_ENABLED;
4316 4317          }
4317 4318  
4318 4319          /* Clear any previous error indication. */
4319 4320          ill->ill_error = 0;
4320 4321          freemsg(mp);
4321 4322  }
4322 4323  
4323 4324  /*
4324 4325   * Perform various checks to verify that an address would make sense as a
4325 4326   * local, remote, or subnet interface address.
4326 4327   */
4327 4328  static boolean_t
4328 4329  ip_addr_ok_v4(ipaddr_t addr, ipaddr_t subnet_mask)
4329 4330  {
4330 4331          ipaddr_t        net_mask;
4331 4332  
4332 4333          /*
4333 4334           * Don't allow all zeroes, or all ones, but allow
4334 4335           * all ones netmask.
4335 4336           */
4336 4337          if ((net_mask = ip_net_mask(addr)) == 0)
4337 4338                  return (B_FALSE);
4338 4339          /* A given netmask overrides the "guess" netmask */
4339 4340          if (subnet_mask != 0)
4340 4341                  net_mask = subnet_mask;
4341 4342          if ((net_mask != ~(ipaddr_t)0) && ((addr == (addr & net_mask)) ||
4342 4343              (addr == (addr | ~net_mask)))) {
4343 4344                  return (B_FALSE);
4344 4345          }
4345 4346  
4346 4347          /*
4347 4348           * Even if the netmask is all ones, we do not allow address to be
4348 4349           * 255.255.255.255
4349 4350           */
4350 4351          if (addr == INADDR_BROADCAST)
4351 4352                  return (B_FALSE);
4352 4353  
4353 4354          if (CLASSD(addr))
4354 4355                  return (B_FALSE);
4355 4356  
4356 4357          return (B_TRUE);
4357 4358  }
4358 4359  
4359 4360  #define V6_IPIF_LINKLOCAL(p)    \
4360 4361          IN6_IS_ADDR_LINKLOCAL(&(p)->ipif_v6lcl_addr)
4361 4362  
4362 4363  /*
4363 4364   * Compare two given ipifs and check if the second one is better than
4364 4365   * the first one using the order of preference (not taking deprecated
4365 4366   * into acount) specified in ipif_lookup_multicast().
4366 4367   */
4367 4368  static boolean_t
4368 4369  ipif_comp_multi(ipif_t *old_ipif, ipif_t *new_ipif, boolean_t isv6)
4369 4370  {
4370 4371          /* Check the least preferred first. */
4371 4372          if (IS_LOOPBACK(old_ipif->ipif_ill)) {
4372 4373                  /* If both ipifs are the same, use the first one. */
4373 4374                  if (IS_LOOPBACK(new_ipif->ipif_ill))
4374 4375                          return (B_FALSE);
4375 4376                  else
4376 4377                          return (B_TRUE);
4377 4378          }
4378 4379  
4379 4380          /* For IPv6, check for link local address. */
4380 4381          if (isv6 && V6_IPIF_LINKLOCAL(old_ipif)) {
4381 4382                  if (IS_LOOPBACK(new_ipif->ipif_ill) ||
4382 4383                      V6_IPIF_LINKLOCAL(new_ipif)) {
4383 4384                          /* The second one is equal or less preferred. */
4384 4385                          return (B_FALSE);
4385 4386                  } else {
4386 4387                          return (B_TRUE);
4387 4388                  }
4388 4389          }
4389 4390  
4390 4391          /* Then check for point to point interface. */
4391 4392          if (old_ipif->ipif_flags & IPIF_POINTOPOINT) {
4392 4393                  if (IS_LOOPBACK(new_ipif->ipif_ill) ||
4393 4394                      (isv6 && V6_IPIF_LINKLOCAL(new_ipif)) ||
4394 4395                      (new_ipif->ipif_flags & IPIF_POINTOPOINT)) {
4395 4396                          return (B_FALSE);
4396 4397                  } else {
4397 4398                          return (B_TRUE);
4398 4399                  }
4399 4400          }
4400 4401  
4401 4402          /* old_ipif is a normal interface, so no need to use the new one. */
4402 4403          return (B_FALSE);
4403 4404  }
4404 4405  
4405 4406  /*
4406 4407   * Find a mulitcast-capable ipif given an IP instance and zoneid.
4407 4408   * The ipif must be up, and its ill must multicast-capable, not
4408 4409   * condemned, not an underlying interface in an IPMP group, and
4409 4410   * not a VNI interface.  Order of preference:
4410 4411   *
4411 4412   *      1a. normal
4412 4413   *      1b. normal, but deprecated
4413 4414   *      2a. point to point
4414 4415   *      2b. point to point, but deprecated
4415 4416   *      3a. link local
4416 4417   *      3b. link local, but deprecated
4417 4418   *      4. loopback.
4418 4419   */
4419 4420  static ipif_t *
4420 4421  ipif_lookup_multicast(ip_stack_t *ipst, zoneid_t zoneid, boolean_t isv6)
4421 4422  {
4422 4423          ill_t                   *ill;
4423 4424          ill_walk_context_t      ctx;
4424 4425          ipif_t                  *ipif;
4425 4426          ipif_t                  *saved_ipif = NULL;
4426 4427          ipif_t                  *dep_ipif = NULL;
4427 4428  
4428 4429          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
4429 4430          if (isv6)
4430 4431                  ill = ILL_START_WALK_V6(&ctx, ipst);
4431 4432          else
4432 4433                  ill = ILL_START_WALK_V4(&ctx, ipst);
4433 4434  
4434 4435          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
4435 4436                  mutex_enter(&ill->ill_lock);
4436 4437                  if (IS_VNI(ill) || IS_UNDER_IPMP(ill) ||
4437 4438                      ILL_IS_CONDEMNED(ill) ||
4438 4439                      !(ill->ill_flags & ILLF_MULTICAST)) {
4439 4440                          mutex_exit(&ill->ill_lock);
4440 4441                          continue;
4441 4442                  }
4442 4443                  for (ipif = ill->ill_ipif; ipif != NULL;
4443 4444                      ipif = ipif->ipif_next) {
4444 4445                          if (zoneid != ipif->ipif_zoneid &&
4445 4446                              zoneid != ALL_ZONES &&
4446 4447                              ipif->ipif_zoneid != ALL_ZONES) {
4447 4448                                  continue;
4448 4449                          }
4449 4450                          if (!(ipif->ipif_flags & IPIF_UP) ||
4450 4451                              IPIF_IS_CONDEMNED(ipif)) {
4451 4452                                  continue;
4452 4453                          }
4453 4454  
4454 4455                          /*
4455 4456                           * Found one candidate.  If it is deprecated,
4456 4457                           * remember it in dep_ipif.  If it is not deprecated,
4457 4458                           * remember it in saved_ipif.
4458 4459                           */
4459 4460                          if (ipif->ipif_flags & IPIF_DEPRECATED) {
4460 4461                                  if (dep_ipif == NULL) {
4461 4462                                          dep_ipif = ipif;
4462 4463                                  } else if (ipif_comp_multi(dep_ipif, ipif,
4463 4464                                      isv6)) {
4464 4465                                          /*
4465 4466                                           * If the previous dep_ipif does not
4466 4467                                           * belong to the same ill, we've done
4467 4468                                           * a ipif_refhold() on it.  So we need
4468 4469                                           * to release it.
4469 4470                                           */
4470 4471                                          if (dep_ipif->ipif_ill != ill)
4471 4472                                                  ipif_refrele(dep_ipif);
4472 4473                                          dep_ipif = ipif;
4473 4474                                  }
4474 4475                                  continue;
4475 4476                          }
4476 4477                          if (saved_ipif == NULL) {
4477 4478                                  saved_ipif = ipif;
4478 4479                          } else {
4479 4480                                  if (ipif_comp_multi(saved_ipif, ipif, isv6)) {
4480 4481                                          if (saved_ipif->ipif_ill != ill)
4481 4482                                                  ipif_refrele(saved_ipif);
4482 4483                                          saved_ipif = ipif;
4483 4484                                  }
4484 4485                          }
4485 4486                  }
4486 4487                  /*
4487 4488                   * Before going to the next ill, do a ipif_refhold() on the
4488 4489                   * saved ones.
4489 4490                   */
4490 4491                  if (saved_ipif != NULL && saved_ipif->ipif_ill == ill)
4491 4492                          ipif_refhold_locked(saved_ipif);
4492 4493                  if (dep_ipif != NULL && dep_ipif->ipif_ill == ill)
4493 4494                          ipif_refhold_locked(dep_ipif);
4494 4495                  mutex_exit(&ill->ill_lock);
4495 4496          }
4496 4497          rw_exit(&ipst->ips_ill_g_lock);
4497 4498  
4498 4499          /*
4499 4500           * If we have only the saved_ipif, return it.  But if we have both
4500 4501           * saved_ipif and dep_ipif, check to see which one is better.
4501 4502           */
4502 4503          if (saved_ipif != NULL) {
4503 4504                  if (dep_ipif != NULL) {
4504 4505                          if (ipif_comp_multi(saved_ipif, dep_ipif, isv6)) {
4505 4506                                  ipif_refrele(saved_ipif);
4506 4507                                  return (dep_ipif);
4507 4508                          } else {
4508 4509                                  ipif_refrele(dep_ipif);
4509 4510                                  return (saved_ipif);
4510 4511                          }
4511 4512                  }
4512 4513                  return (saved_ipif);
4513 4514          } else {
4514 4515                  return (dep_ipif);
4515 4516          }
4516 4517  }
4517 4518  
4518 4519  ill_t *
4519 4520  ill_lookup_multicast(ip_stack_t *ipst, zoneid_t zoneid, boolean_t isv6)
4520 4521  {
4521 4522          ipif_t *ipif;
4522 4523          ill_t *ill;
4523 4524  
4524 4525          ipif = ipif_lookup_multicast(ipst, zoneid, isv6);
4525 4526          if (ipif == NULL)
4526 4527                  return (NULL);
4527 4528  
4528 4529          ill = ipif->ipif_ill;
4529 4530          ill_refhold(ill);
4530 4531          ipif_refrele(ipif);
4531 4532          return (ill);
4532 4533  }
4533 4534  
4534 4535  /*
4535 4536   * This function is called when an application does not specify an interface
4536 4537   * to be used for multicast traffic (joining a group/sending data).  It
4537 4538   * calls ire_lookup_multi() to look for an interface route for the
4538 4539   * specified multicast group.  Doing this allows the administrator to add
4539 4540   * prefix routes for multicast to indicate which interface to be used for
4540 4541   * multicast traffic in the above scenario.  The route could be for all
4541 4542   * multicast (224.0/4), for a single multicast group (a /32 route) or
4542 4543   * anything in between.  If there is no such multicast route, we just find
4543 4544   * any multicast capable interface and return it.  The returned ipif
4544 4545   * is refhold'ed.
4545 4546   *
4546 4547   * We support MULTIRT and RTF_SETSRC on the multicast routes added to the
4547 4548   * unicast table. This is used by CGTP.
4548 4549   */
4549 4550  ill_t *
4550 4551  ill_lookup_group_v4(ipaddr_t group, zoneid_t zoneid, ip_stack_t *ipst,
4551 4552      boolean_t *multirtp, ipaddr_t *setsrcp)
4552 4553  {
4553 4554          ill_t                   *ill;
4554 4555  
4555 4556          ill = ire_lookup_multi_ill_v4(group, zoneid, ipst, multirtp, setsrcp);
4556 4557          if (ill != NULL)
4557 4558                  return (ill);
4558 4559  
4559 4560          return (ill_lookup_multicast(ipst, zoneid, B_FALSE));
4560 4561  }
4561 4562  
4562 4563  /*
4563 4564   * Look for an ipif with the specified interface address and destination.
4564 4565   * The destination address is used only for matching point-to-point interfaces.
4565 4566   */
4566 4567  ipif_t *
4567 4568  ipif_lookup_interface(ipaddr_t if_addr, ipaddr_t dst, ip_stack_t *ipst)
4568 4569  {
4569 4570          ipif_t  *ipif;
4570 4571          ill_t   *ill;
4571 4572          ill_walk_context_t ctx;
4572 4573  
4573 4574          /*
4574 4575           * First match all the point-to-point interfaces
4575 4576           * before looking at non-point-to-point interfaces.
4576 4577           * This is done to avoid returning non-point-to-point
4577 4578           * ipif instead of unnumbered point-to-point ipif.
4578 4579           */
4579 4580          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
4580 4581          ill = ILL_START_WALK_V4(&ctx, ipst);
4581 4582          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
4582 4583                  mutex_enter(&ill->ill_lock);
4583 4584                  for (ipif = ill->ill_ipif; ipif != NULL;
4584 4585                      ipif = ipif->ipif_next) {
4585 4586                          /* Allow the ipif to be down */
4586 4587                          if ((ipif->ipif_flags & IPIF_POINTOPOINT) &&
4587 4588                              (ipif->ipif_lcl_addr == if_addr) &&
4588 4589                              (ipif->ipif_pp_dst_addr == dst)) {
4589 4590                                  if (!IPIF_IS_CONDEMNED(ipif)) {
4590 4591                                          ipif_refhold_locked(ipif);
4591 4592                                          mutex_exit(&ill->ill_lock);
4592 4593                                          rw_exit(&ipst->ips_ill_g_lock);
4593 4594                                          return (ipif);
4594 4595                                  }
4595 4596                          }
4596 4597                  }
4597 4598                  mutex_exit(&ill->ill_lock);
4598 4599          }
4599 4600          rw_exit(&ipst->ips_ill_g_lock);
4600 4601  
4601 4602          /* lookup the ipif based on interface address */
4602 4603          ipif = ipif_lookup_addr(if_addr, NULL, ALL_ZONES, ipst);
4603 4604          ASSERT(ipif == NULL || !ipif->ipif_isv6);
4604 4605          return (ipif);
4605 4606  }
4606 4607  
4607 4608  /*
4608 4609   * Common function for ipif_lookup_addr() and ipif_lookup_addr_exact().
4609 4610   */
4610 4611  static ipif_t *
4611 4612  ipif_lookup_addr_common(ipaddr_t addr, ill_t *match_ill, uint32_t match_flags,
4612 4613      zoneid_t zoneid, ip_stack_t *ipst)
4613 4614  {
4614 4615          ipif_t  *ipif;
4615 4616          ill_t   *ill;
4616 4617          boolean_t ptp = B_FALSE;
4617 4618          ill_walk_context_t      ctx;
4618 4619          boolean_t match_illgrp = (match_flags & IPIF_MATCH_ILLGRP);
4619 4620          boolean_t no_duplicate = (match_flags & IPIF_MATCH_NONDUP);
4620 4621  
4621 4622          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
4622 4623          /*
4623 4624           * Repeat twice, first based on local addresses and
4624 4625           * next time for pointopoint.
4625 4626           */
4626 4627  repeat:
4627 4628          ill = ILL_START_WALK_V4(&ctx, ipst);
4628 4629          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
4629 4630                  if (match_ill != NULL && ill != match_ill &&
4630 4631                      (!match_illgrp || !IS_IN_SAME_ILLGRP(ill, match_ill))) {
4631 4632                          continue;
4632 4633                  }
4633 4634                  mutex_enter(&ill->ill_lock);
4634 4635                  for (ipif = ill->ill_ipif; ipif != NULL;
4635 4636                      ipif = ipif->ipif_next) {
4636 4637                          if (zoneid != ALL_ZONES &&
4637 4638                              zoneid != ipif->ipif_zoneid &&
4638 4639                              ipif->ipif_zoneid != ALL_ZONES)
4639 4640                                  continue;
4640 4641  
4641 4642                          if (no_duplicate && !(ipif->ipif_flags & IPIF_UP))
4642 4643                                  continue;
4643 4644  
4644 4645                          /* Allow the ipif to be down */
4645 4646                          if ((!ptp && (ipif->ipif_lcl_addr == addr) &&
4646 4647                              ((ipif->ipif_flags & IPIF_UNNUMBERED) == 0)) ||
4647 4648                              (ptp && (ipif->ipif_flags & IPIF_POINTOPOINT) &&
4648 4649                              (ipif->ipif_pp_dst_addr == addr))) {
4649 4650                                  if (!IPIF_IS_CONDEMNED(ipif)) {
4650 4651                                          ipif_refhold_locked(ipif);
4651 4652                                          mutex_exit(&ill->ill_lock);
4652 4653                                          rw_exit(&ipst->ips_ill_g_lock);
4653 4654                                          return (ipif);
4654 4655                                  }
4655 4656                          }
4656 4657                  }
4657 4658                  mutex_exit(&ill->ill_lock);
4658 4659          }
4659 4660  
4660 4661          /* If we already did the ptp case, then we are done */
4661 4662          if (ptp) {
4662 4663                  rw_exit(&ipst->ips_ill_g_lock);
4663 4664                  return (NULL);
4664 4665          }
4665 4666          ptp = B_TRUE;
4666 4667          goto repeat;
4667 4668  }
4668 4669  
4669 4670  /*
4670 4671   * Lookup an ipif with the specified address.  For point-to-point links we
4671 4672   * look for matches on either the destination address or the local address,
4672 4673   * but we skip the local address check if IPIF_UNNUMBERED is set.  If the
4673 4674   * `match_ill' argument is non-NULL, the lookup is restricted to that ill
4674 4675   * (or illgrp if `match_ill' is in an IPMP group).
4675 4676   */
4676 4677  ipif_t *
4677 4678  ipif_lookup_addr(ipaddr_t addr, ill_t *match_ill, zoneid_t zoneid,
4678 4679      ip_stack_t *ipst)
4679 4680  {
4680 4681          return (ipif_lookup_addr_common(addr, match_ill, IPIF_MATCH_ILLGRP,
4681 4682              zoneid, ipst));
4682 4683  }
4683 4684  
4684 4685  /*
4685 4686   * Lookup an ipif with the specified address. Similar to ipif_lookup_addr,
4686 4687   * except that we will only return an address if it is not marked as
4687 4688   * IPIF_DUPLICATE
4688 4689   */
4689 4690  ipif_t *
4690 4691  ipif_lookup_addr_nondup(ipaddr_t addr, ill_t *match_ill, zoneid_t zoneid,
4691 4692      ip_stack_t *ipst)
4692 4693  {
4693 4694          return (ipif_lookup_addr_common(addr, match_ill,
4694 4695              (IPIF_MATCH_ILLGRP | IPIF_MATCH_NONDUP),
4695 4696              zoneid, ipst));
4696 4697  }
4697 4698  
4698 4699  /*
4699 4700   * Special abbreviated version of ipif_lookup_addr() that doesn't match
4700 4701   * `match_ill' across the IPMP group.  This function is only needed in some
4701 4702   * corner-cases; almost everything should use ipif_lookup_addr().
4702 4703   */
4703 4704  ipif_t *
4704 4705  ipif_lookup_addr_exact(ipaddr_t addr, ill_t *match_ill, ip_stack_t *ipst)
4705 4706  {
4706 4707          ASSERT(match_ill != NULL);
4707 4708          return (ipif_lookup_addr_common(addr, match_ill, 0, ALL_ZONES,
4708 4709              ipst));
4709 4710  }
4710 4711  
4711 4712  /*
4712 4713   * Look for an ipif with the specified address. For point-point links
4713 4714   * we look for matches on either the destination address and the local
4714 4715   * address, but we ignore the check on the local address if IPIF_UNNUMBERED
4715 4716   * is set.
4716 4717   * If the `match_ill' argument is non-NULL, the lookup is restricted to that
4717 4718   * ill (or illgrp if `match_ill' is in an IPMP group).
4718 4719   * Return the zoneid for the ipif which matches. ALL_ZONES if no match.
4719 4720   */
4720 4721  zoneid_t
4721 4722  ipif_lookup_addr_zoneid(ipaddr_t addr, ill_t *match_ill, ip_stack_t *ipst)
4722 4723  {
4723 4724          zoneid_t zoneid;
4724 4725          ipif_t  *ipif;
4725 4726          ill_t   *ill;
4726 4727          boolean_t ptp = B_FALSE;
4727 4728          ill_walk_context_t      ctx;
4728 4729  
4729 4730          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
4730 4731          /*
4731 4732           * Repeat twice, first based on local addresses and
4732 4733           * next time for pointopoint.
4733 4734           */
4734 4735  repeat:
4735 4736          ill = ILL_START_WALK_V4(&ctx, ipst);
4736 4737          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
4737 4738                  if (match_ill != NULL && ill != match_ill &&
4738 4739                      !IS_IN_SAME_ILLGRP(ill, match_ill)) {
4739 4740                          continue;
4740 4741                  }
4741 4742                  mutex_enter(&ill->ill_lock);
4742 4743                  for (ipif = ill->ill_ipif; ipif != NULL;
4743 4744                      ipif = ipif->ipif_next) {
4744 4745                          /* Allow the ipif to be down */
4745 4746                          if ((!ptp && (ipif->ipif_lcl_addr == addr) &&
4746 4747                              ((ipif->ipif_flags & IPIF_UNNUMBERED) == 0)) ||
4747 4748                              (ptp && (ipif->ipif_flags & IPIF_POINTOPOINT) &&
4748 4749                              (ipif->ipif_pp_dst_addr == addr)) &&
4749 4750                              !(ipif->ipif_state_flags & IPIF_CONDEMNED)) {
4750 4751                                  zoneid = ipif->ipif_zoneid;
4751 4752                                  mutex_exit(&ill->ill_lock);
4752 4753                                  rw_exit(&ipst->ips_ill_g_lock);
4753 4754                                  /*
4754 4755                                   * If ipif_zoneid was ALL_ZONES then we have
4755 4756                                   * a trusted extensions shared IP address.
4756 4757                                   * In that case GLOBAL_ZONEID works to send.
4757 4758                                   */
4758 4759                                  if (zoneid == ALL_ZONES)
4759 4760                                          zoneid = GLOBAL_ZONEID;
4760 4761                                  return (zoneid);
4761 4762                          }
4762 4763                  }
4763 4764                  mutex_exit(&ill->ill_lock);
4764 4765          }
4765 4766  
4766 4767          /* If we already did the ptp case, then we are done */
4767 4768          if (ptp) {
4768 4769                  rw_exit(&ipst->ips_ill_g_lock);
4769 4770                  return (ALL_ZONES);
4770 4771          }
4771 4772          ptp = B_TRUE;
4772 4773          goto repeat;
4773 4774  }
4774 4775  
4775 4776  /*
4776 4777   * Look for an ipif that matches the specified remote address i.e. the
4777 4778   * ipif that would receive the specified packet.
4778 4779   * First look for directly connected interfaces and then do a recursive
4779 4780   * IRE lookup and pick the first ipif corresponding to the source address in the
4780 4781   * ire.
4781 4782   * Returns: held ipif
4782 4783   *
4783 4784   * This is only used for ICMP_ADDRESS_MASK_REQUESTs
4784 4785   */
4785 4786  ipif_t *
4786 4787  ipif_lookup_remote(ill_t *ill, ipaddr_t addr, zoneid_t zoneid)
4787 4788  {
4788 4789          ipif_t  *ipif;
4789 4790  
4790 4791          ASSERT(!ill->ill_isv6);
4791 4792  
4792 4793          /*
4793 4794           * Someone could be changing this ipif currently or change it
4794 4795           * after we return this. Thus  a few packets could use the old
4795 4796           * old values. However structure updates/creates (ire, ilg, ilm etc)
4796 4797           * will atomically be updated or cleaned up with the new value
4797 4798           * Thus we don't need a lock to check the flags or other attrs below.
4798 4799           */
4799 4800          mutex_enter(&ill->ill_lock);
4800 4801          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
4801 4802                  if (IPIF_IS_CONDEMNED(ipif))
4802 4803                          continue;
4803 4804                  if (zoneid != ALL_ZONES && zoneid != ipif->ipif_zoneid &&
4804 4805                      ipif->ipif_zoneid != ALL_ZONES)
4805 4806                          continue;
4806 4807                  /* Allow the ipif to be down */
4807 4808                  if (ipif->ipif_flags & IPIF_POINTOPOINT) {
4808 4809                          if ((ipif->ipif_pp_dst_addr == addr) ||
4809 4810                              (!(ipif->ipif_flags & IPIF_UNNUMBERED) &&
4810 4811                              ipif->ipif_lcl_addr == addr)) {
4811 4812                                  ipif_refhold_locked(ipif);
4812 4813                                  mutex_exit(&ill->ill_lock);
4813 4814                                  return (ipif);
4814 4815                          }
4815 4816                  } else if (ipif->ipif_subnet == (addr & ipif->ipif_net_mask)) {
4816 4817                          ipif_refhold_locked(ipif);
4817 4818                          mutex_exit(&ill->ill_lock);
4818 4819                          return (ipif);
4819 4820                  }
4820 4821          }
4821 4822          mutex_exit(&ill->ill_lock);
4822 4823          /*
4823 4824           * For a remote destination it isn't possible to nail down a particular
4824 4825           * ipif.
4825 4826           */
4826 4827  
4827 4828          /* Pick the first interface */
4828 4829          ipif = ipif_get_next_ipif(NULL, ill);
4829 4830          return (ipif);
4830 4831  }
4831 4832  
4832 4833  /*
4833 4834   * This func does not prevent refcnt from increasing. But if
4834 4835   * the caller has taken steps to that effect, then this func
4835 4836   * can be used to determine whether the ill has become quiescent
4836 4837   */
4837 4838  static boolean_t
4838 4839  ill_is_quiescent(ill_t *ill)
4839 4840  {
4840 4841          ipif_t  *ipif;
4841 4842  
4842 4843          ASSERT(MUTEX_HELD(&ill->ill_lock));
4843 4844  
4844 4845          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
4845 4846                  if (ipif->ipif_refcnt != 0)
4846 4847                          return (B_FALSE);
4847 4848          }
4848 4849          if (!ILL_DOWN_OK(ill) || ill->ill_refcnt != 0) {
4849 4850                  return (B_FALSE);
4850 4851          }
4851 4852          return (B_TRUE);
4852 4853  }
4853 4854  
4854 4855  boolean_t
4855 4856  ill_is_freeable(ill_t *ill)
4856 4857  {
4857 4858          ipif_t  *ipif;
4858 4859  
4859 4860          ASSERT(MUTEX_HELD(&ill->ill_lock));
4860 4861  
4861 4862          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
4862 4863                  if (ipif->ipif_refcnt != 0) {
4863 4864                          return (B_FALSE);
4864 4865                  }
4865 4866          }
4866 4867          if (!ILL_FREE_OK(ill) || ill->ill_refcnt != 0) {
4867 4868                  return (B_FALSE);
4868 4869          }
4869 4870          return (B_TRUE);
4870 4871  }
4871 4872  
4872 4873  /*
4873 4874   * This func does not prevent refcnt from increasing. But if
4874 4875   * the caller has taken steps to that effect, then this func
4875 4876   * can be used to determine whether the ipif has become quiescent
4876 4877   */
4877 4878  static boolean_t
4878 4879  ipif_is_quiescent(ipif_t *ipif)
4879 4880  {
4880 4881          ill_t *ill;
4881 4882  
4882 4883          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
4883 4884  
4884 4885          if (ipif->ipif_refcnt != 0)
4885 4886                  return (B_FALSE);
4886 4887  
4887 4888          ill = ipif->ipif_ill;
4888 4889          if (ill->ill_ipif_up_count != 0 || ill->ill_ipif_dup_count != 0 ||
4889 4890              ill->ill_logical_down) {
4890 4891                  return (B_TRUE);
4891 4892          }
4892 4893  
4893 4894          /* This is the last ipif going down or being deleted on this ill */
4894 4895          if (ill->ill_ire_cnt != 0 || ill->ill_refcnt != 0) {
4895 4896                  return (B_FALSE);
4896 4897          }
4897 4898  
4898 4899          return (B_TRUE);
4899 4900  }
4900 4901  
4901 4902  /*
4902 4903   * return true if the ipif can be destroyed: the ipif has to be quiescent
4903 4904   * with zero references from ire/ilm to it.
4904 4905   */
4905 4906  static boolean_t
4906 4907  ipif_is_freeable(ipif_t *ipif)
4907 4908  {
4908 4909          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
4909 4910          ASSERT(ipif->ipif_id != 0);
4910 4911          return (ipif->ipif_refcnt == 0);
4911 4912  }
4912 4913  
4913 4914  /*
4914 4915   * The ipif/ill/ire has been refreled. Do the tail processing.
4915 4916   * Determine if the ipif or ill in question has become quiescent and if so
4916 4917   * wakeup close and/or restart any queued pending ioctl that is waiting
4917 4918   * for the ipif_down (or ill_down)
4918 4919   */
4919 4920  void
4920 4921  ipif_ill_refrele_tail(ill_t *ill)
4921 4922  {
4922 4923          mblk_t  *mp;
4923 4924          conn_t  *connp;
4924 4925          ipsq_t  *ipsq;
4925 4926          ipxop_t *ipx;
4926 4927          ipif_t  *ipif;
4927 4928          dl_notify_ind_t *dlindp;
4928 4929  
4929 4930          ASSERT(MUTEX_HELD(&ill->ill_lock));
4930 4931  
4931 4932          if ((ill->ill_state_flags & ILL_CONDEMNED) && ill_is_freeable(ill)) {
4932 4933                  /* ip_modclose() may be waiting */
4933 4934                  cv_broadcast(&ill->ill_cv);
4934 4935          }
4935 4936  
4936 4937          ipsq = ill->ill_phyint->phyint_ipsq;
4937 4938          mutex_enter(&ipsq->ipsq_lock);
4938 4939          ipx = ipsq->ipsq_xop;
4939 4940          mutex_enter(&ipx->ipx_lock);
4940 4941          if (ipx->ipx_waitfor == 0)      /* no one's waiting; bail */
4941 4942                  goto unlock;
4942 4943  
4943 4944          ASSERT(ipx->ipx_pending_mp != NULL && ipx->ipx_pending_ipif != NULL);
4944 4945  
4945 4946          ipif = ipx->ipx_pending_ipif;
4946 4947          if (ipif->ipif_ill != ill)      /* wait is for another ill; bail */
4947 4948                  goto unlock;
4948 4949  
4949 4950          switch (ipx->ipx_waitfor) {
4950 4951          case IPIF_DOWN:
4951 4952                  if (!ipif_is_quiescent(ipif))
4952 4953                          goto unlock;
4953 4954                  break;
4954 4955          case IPIF_FREE:
4955 4956                  if (!ipif_is_freeable(ipif))
4956 4957                          goto unlock;
4957 4958                  break;
4958 4959          case ILL_DOWN:
4959 4960                  if (!ill_is_quiescent(ill))
4960 4961                          goto unlock;
4961 4962                  break;
4962 4963          case ILL_FREE:
4963 4964                  /*
4964 4965                   * ILL_FREE is only for loopback; normal ill teardown waits
4965 4966                   * synchronously in ip_modclose() without using ipx_waitfor,
4966 4967                   * handled by the cv_broadcast() at the top of this function.
4967 4968                   */
4968 4969                  if (!ill_is_freeable(ill))
4969 4970                          goto unlock;
4970 4971                  break;
4971 4972          default:
4972 4973                  cmn_err(CE_PANIC, "ipsq: %p unknown ipx_waitfor %d\n",
4973 4974                      (void *)ipsq, ipx->ipx_waitfor);
4974 4975          }
4975 4976  
4976 4977          ill_refhold_locked(ill);        /* for qwriter_ip() call below */
4977 4978          mutex_exit(&ipx->ipx_lock);
4978 4979          mp = ipsq_pending_mp_get(ipsq, &connp);
4979 4980          mutex_exit(&ipsq->ipsq_lock);
4980 4981          mutex_exit(&ill->ill_lock);
4981 4982  
4982 4983          ASSERT(mp != NULL);
4983 4984          /*
4984 4985           * NOTE: all of the qwriter_ip() calls below use CUR_OP since
4985 4986           * we can only get here when the current operation decides it
4986 4987           * it needs to quiesce via ipsq_pending_mp_add().
4987 4988           */
4988 4989          switch (mp->b_datap->db_type) {
4989 4990          case M_PCPROTO:
4990 4991          case M_PROTO:
4991 4992                  /*
4992 4993                   * For now, only DL_NOTIFY_IND messages can use this facility.
4993 4994                   */
4994 4995                  dlindp = (dl_notify_ind_t *)mp->b_rptr;
4995 4996                  ASSERT(dlindp->dl_primitive == DL_NOTIFY_IND);
4996 4997  
4997 4998                  switch (dlindp->dl_notification) {
4998 4999                  case DL_NOTE_PHYS_ADDR:
4999 5000                          qwriter_ip(ill, ill->ill_rq, mp,
5000 5001                              ill_set_phys_addr_tail, CUR_OP, B_TRUE);
5001 5002                          return;
5002 5003                  case DL_NOTE_REPLUMB:
5003 5004                          qwriter_ip(ill, ill->ill_rq, mp,
5004 5005                              ill_replumb_tail, CUR_OP, B_TRUE);
5005 5006                          return;
5006 5007                  default:
5007 5008                          ASSERT(0);
5008 5009                          ill_refrele(ill);
5009 5010                  }
5010 5011                  break;
5011 5012  
5012 5013          case M_ERROR:
5013 5014          case M_HANGUP:
5014 5015                  qwriter_ip(ill, ill->ill_rq, mp, ipif_all_down_tail, CUR_OP,
5015 5016                      B_TRUE);
5016 5017                  return;
5017 5018  
5018 5019          case M_IOCTL:
5019 5020          case M_IOCDATA:
5020 5021                  qwriter_ip(ill, (connp != NULL ? CONNP_TO_WQ(connp) :
5021 5022                      ill->ill_wq), mp, ip_reprocess_ioctl, CUR_OP, B_TRUE);
5022 5023                  return;
5023 5024  
5024 5025          default:
5025 5026                  cmn_err(CE_PANIC, "ipif_ill_refrele_tail mp %p "
5026 5027                      "db_type %d\n", (void *)mp, mp->b_datap->db_type);
5027 5028          }
5028 5029          return;
5029 5030  unlock:
5030 5031          mutex_exit(&ipsq->ipsq_lock);
5031 5032          mutex_exit(&ipx->ipx_lock);
5032 5033          mutex_exit(&ill->ill_lock);
5033 5034  }
5034 5035  
5035 5036  #ifdef DEBUG
5036 5037  /* Reuse trace buffer from beginning (if reached the end) and record trace */
5037 5038  static void
5038 5039  th_trace_rrecord(th_trace_t *th_trace)
5039 5040  {
5040 5041          tr_buf_t *tr_buf;
5041 5042          uint_t lastref;
5042 5043  
5043 5044          lastref = th_trace->th_trace_lastref;
5044 5045          lastref++;
5045 5046          if (lastref == TR_BUF_MAX)
5046 5047                  lastref = 0;
5047 5048          th_trace->th_trace_lastref = lastref;
5048 5049          tr_buf = &th_trace->th_trbuf[lastref];
5049 5050          tr_buf->tr_time = ddi_get_lbolt();
5050 5051          tr_buf->tr_depth = getpcstack(tr_buf->tr_stack, TR_STACK_DEPTH);
5051 5052  }
5052 5053  
5053 5054  static void
5054 5055  th_trace_free(void *value)
5055 5056  {
5056 5057          th_trace_t *th_trace = value;
5057 5058  
5058 5059          ASSERT(th_trace->th_refcnt == 0);
5059 5060          kmem_free(th_trace, sizeof (*th_trace));
5060 5061  }
5061 5062  
5062 5063  /*
5063 5064   * Find or create the per-thread hash table used to track object references.
5064 5065   * The ipst argument is NULL if we shouldn't allocate.
5065 5066   *
5066 5067   * Accesses per-thread data, so there's no need to lock here.
5067 5068   */
5068 5069  static mod_hash_t *
5069 5070  th_trace_gethash(ip_stack_t *ipst)
5070 5071  {
5071 5072          th_hash_t *thh;
5072 5073  
5073 5074          if ((thh = tsd_get(ip_thread_data)) == NULL && ipst != NULL) {
5074 5075                  mod_hash_t *mh;
5075 5076                  char name[256];
5076 5077                  size_t objsize, rshift;
5077 5078                  int retv;
5078 5079  
5079 5080                  if ((thh = kmem_alloc(sizeof (*thh), KM_NOSLEEP)) == NULL)
5080 5081                          return (NULL);
5081 5082                  (void) snprintf(name, sizeof (name), "th_trace_%p",
5082 5083                      (void *)curthread);
5083 5084  
5084 5085                  /*
5085 5086                   * We use mod_hash_create_extended here rather than the more
5086 5087                   * obvious mod_hash_create_ptrhash because the latter has a
5087 5088                   * hard-coded KM_SLEEP, and we'd prefer to fail rather than
5088 5089                   * block.
5089 5090                   */
5090 5091                  objsize = MAX(MAX(sizeof (ill_t), sizeof (ipif_t)),
5091 5092                      MAX(sizeof (ire_t), sizeof (ncec_t)));
5092 5093                  rshift = highbit(objsize);
5093 5094                  mh = mod_hash_create_extended(name, 64, mod_hash_null_keydtor,
5094 5095                      th_trace_free, mod_hash_byptr, (void *)rshift,
5095 5096                      mod_hash_ptrkey_cmp, KM_NOSLEEP);
5096 5097                  if (mh == NULL) {
5097 5098                          kmem_free(thh, sizeof (*thh));
5098 5099                          return (NULL);
5099 5100                  }
5100 5101                  thh->thh_hash = mh;
5101 5102                  thh->thh_ipst = ipst;
5102 5103                  /*
5103 5104                   * We trace ills, ipifs, ires, and nces.  All of these are
5104 5105                   * per-IP-stack, so the lock on the thread list is as well.
5105 5106                   */
5106 5107                  rw_enter(&ip_thread_rwlock, RW_WRITER);
5107 5108                  list_insert_tail(&ip_thread_list, thh);
5108 5109                  rw_exit(&ip_thread_rwlock);
5109 5110                  retv = tsd_set(ip_thread_data, thh);
5110 5111                  ASSERT(retv == 0);
5111 5112          }
5112 5113          return (thh != NULL ? thh->thh_hash : NULL);
5113 5114  }
5114 5115  
5115 5116  boolean_t
5116 5117  th_trace_ref(const void *obj, ip_stack_t *ipst)
5117 5118  {
5118 5119          th_trace_t *th_trace;
5119 5120          mod_hash_t *mh;
5120 5121          mod_hash_val_t val;
5121 5122  
5122 5123          if ((mh = th_trace_gethash(ipst)) == NULL)
5123 5124                  return (B_FALSE);
5124 5125  
5125 5126          /*
5126 5127           * Attempt to locate the trace buffer for this obj and thread.
5127 5128           * If it does not exist, then allocate a new trace buffer and
5128 5129           * insert into the hash.
5129 5130           */
5130 5131          if (mod_hash_find(mh, (mod_hash_key_t)obj, &val) == MH_ERR_NOTFOUND) {
5131 5132                  th_trace = kmem_zalloc(sizeof (th_trace_t), KM_NOSLEEP);
5132 5133                  if (th_trace == NULL)
5133 5134                          return (B_FALSE);
5134 5135  
5135 5136                  th_trace->th_id = curthread;
5136 5137                  if (mod_hash_insert(mh, (mod_hash_key_t)obj,
5137 5138                      (mod_hash_val_t)th_trace) != 0) {
5138 5139                          kmem_free(th_trace, sizeof (th_trace_t));
5139 5140                          return (B_FALSE);
5140 5141                  }
5141 5142          } else {
5142 5143                  th_trace = (th_trace_t *)val;
5143 5144          }
5144 5145  
5145 5146          ASSERT(th_trace->th_refcnt >= 0 &&
5146 5147              th_trace->th_refcnt < TR_BUF_MAX - 1);
5147 5148  
5148 5149          th_trace->th_refcnt++;
5149 5150          th_trace_rrecord(th_trace);
5150 5151          return (B_TRUE);
5151 5152  }
5152 5153  
5153 5154  /*
5154 5155   * For the purpose of tracing a reference release, we assume that global
5155 5156   * tracing is always on and that the same thread initiated the reference hold
5156 5157   * is releasing.
5157 5158   */
5158 5159  void
5159 5160  th_trace_unref(const void *obj)
5160 5161  {
5161 5162          int retv;
5162 5163          mod_hash_t *mh;
5163 5164          th_trace_t *th_trace;
5164 5165          mod_hash_val_t val;
5165 5166  
5166 5167          mh = th_trace_gethash(NULL);
5167 5168          retv = mod_hash_find(mh, (mod_hash_key_t)obj, &val);
5168 5169          ASSERT(retv == 0);
5169 5170          th_trace = (th_trace_t *)val;
5170 5171  
5171 5172          ASSERT(th_trace->th_refcnt > 0);
5172 5173          th_trace->th_refcnt--;
5173 5174          th_trace_rrecord(th_trace);
5174 5175  }
5175 5176  
5176 5177  /*
5177 5178   * If tracing has been disabled, then we assume that the reference counts are
5178 5179   * now useless, and we clear them out before destroying the entries.
5179 5180   */
5180 5181  void
5181 5182  th_trace_cleanup(const void *obj, boolean_t trace_disable)
5182 5183  {
5183 5184          th_hash_t       *thh;
5184 5185          mod_hash_t      *mh;
5185 5186          mod_hash_val_t  val;
5186 5187          th_trace_t      *th_trace;
5187 5188          int             retv;
5188 5189  
5189 5190          rw_enter(&ip_thread_rwlock, RW_READER);
5190 5191          for (thh = list_head(&ip_thread_list); thh != NULL;
5191 5192              thh = list_next(&ip_thread_list, thh)) {
5192 5193                  if (mod_hash_find(mh = thh->thh_hash, (mod_hash_key_t)obj,
5193 5194                      &val) == 0) {
5194 5195                          th_trace = (th_trace_t *)val;
5195 5196                          if (trace_disable)
5196 5197                                  th_trace->th_refcnt = 0;
5197 5198                          retv = mod_hash_destroy(mh, (mod_hash_key_t)obj);
5198 5199                          ASSERT(retv == 0);
5199 5200                  }
5200 5201          }
5201 5202          rw_exit(&ip_thread_rwlock);
5202 5203  }
5203 5204  
5204 5205  void
5205 5206  ipif_trace_ref(ipif_t *ipif)
5206 5207  {
5207 5208          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
5208 5209  
5209 5210          if (ipif->ipif_trace_disable)
5210 5211                  return;
5211 5212  
5212 5213          if (!th_trace_ref(ipif, ipif->ipif_ill->ill_ipst)) {
5213 5214                  ipif->ipif_trace_disable = B_TRUE;
5214 5215                  ipif_trace_cleanup(ipif);
5215 5216          }
5216 5217  }
5217 5218  
5218 5219  void
5219 5220  ipif_untrace_ref(ipif_t *ipif)
5220 5221  {
5221 5222          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
5222 5223  
5223 5224          if (!ipif->ipif_trace_disable)
5224 5225                  th_trace_unref(ipif);
5225 5226  }
5226 5227  
5227 5228  void
5228 5229  ill_trace_ref(ill_t *ill)
5229 5230  {
5230 5231          ASSERT(MUTEX_HELD(&ill->ill_lock));
5231 5232  
5232 5233          if (ill->ill_trace_disable)
5233 5234                  return;
5234 5235  
5235 5236          if (!th_trace_ref(ill, ill->ill_ipst)) {
5236 5237                  ill->ill_trace_disable = B_TRUE;
5237 5238                  ill_trace_cleanup(ill);
5238 5239          }
5239 5240  }
5240 5241  
5241 5242  void
5242 5243  ill_untrace_ref(ill_t *ill)
5243 5244  {
5244 5245          ASSERT(MUTEX_HELD(&ill->ill_lock));
5245 5246  
5246 5247          if (!ill->ill_trace_disable)
5247 5248                  th_trace_unref(ill);
5248 5249  }
5249 5250  
5250 5251  /*
5251 5252   * Called when ipif is unplumbed or when memory alloc fails.  Note that on
5252 5253   * failure, ipif_trace_disable is set.
5253 5254   */
5254 5255  static void
5255 5256  ipif_trace_cleanup(const ipif_t *ipif)
5256 5257  {
5257 5258          th_trace_cleanup(ipif, ipif->ipif_trace_disable);
5258 5259  }
5259 5260  
5260 5261  /*
5261 5262   * Called when ill is unplumbed or when memory alloc fails.  Note that on
5262 5263   * failure, ill_trace_disable is set.
5263 5264   */
5264 5265  static void
5265 5266  ill_trace_cleanup(const ill_t *ill)
5266 5267  {
5267 5268          th_trace_cleanup(ill, ill->ill_trace_disable);
5268 5269  }
5269 5270  #endif /* DEBUG */
5270 5271  
5271 5272  void
5272 5273  ipif_refhold_locked(ipif_t *ipif)
5273 5274  {
5274 5275          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
5275 5276          ipif->ipif_refcnt++;
5276 5277          IPIF_TRACE_REF(ipif);
5277 5278  }
5278 5279  
5279 5280  void
5280 5281  ipif_refhold(ipif_t *ipif)
5281 5282  {
5282 5283          ill_t   *ill;
5283 5284  
5284 5285          ill = ipif->ipif_ill;
5285 5286          mutex_enter(&ill->ill_lock);
5286 5287          ipif->ipif_refcnt++;
5287 5288          IPIF_TRACE_REF(ipif);
5288 5289          mutex_exit(&ill->ill_lock);
5289 5290  }
5290 5291  
5291 5292  /*
5292 5293   * Must not be called while holding any locks. Otherwise if this is
5293 5294   * the last reference to be released there is a chance of recursive mutex
5294 5295   * panic due to ipif_refrele -> ipif_ill_refrele_tail -> qwriter_ip trying
5295 5296   * to restart an ioctl.
5296 5297   */
5297 5298  void
5298 5299  ipif_refrele(ipif_t *ipif)
5299 5300  {
5300 5301          ill_t   *ill;
5301 5302  
5302 5303          ill = ipif->ipif_ill;
5303 5304  
5304 5305          mutex_enter(&ill->ill_lock);
5305 5306          ASSERT(ipif->ipif_refcnt != 0);
5306 5307          ipif->ipif_refcnt--;
5307 5308          IPIF_UNTRACE_REF(ipif);
5308 5309          if (ipif->ipif_refcnt != 0) {
5309 5310                  mutex_exit(&ill->ill_lock);
5310 5311                  return;
5311 5312          }
5312 5313  
5313 5314          /* Drops the ill_lock */
5314 5315          ipif_ill_refrele_tail(ill);
5315 5316  }
5316 5317  
5317 5318  ipif_t *
5318 5319  ipif_get_next_ipif(ipif_t *curr, ill_t *ill)
5319 5320  {
5320 5321          ipif_t  *ipif;
5321 5322  
5322 5323          mutex_enter(&ill->ill_lock);
5323 5324          for (ipif = (curr == NULL ? ill->ill_ipif : curr->ipif_next);
5324 5325              ipif != NULL; ipif = ipif->ipif_next) {
5325 5326                  if (IPIF_IS_CONDEMNED(ipif))
5326 5327                          continue;
5327 5328                  ipif_refhold_locked(ipif);
5328 5329                  mutex_exit(&ill->ill_lock);
5329 5330                  return (ipif);
5330 5331          }
5331 5332          mutex_exit(&ill->ill_lock);
5332 5333          return (NULL);
5333 5334  }
5334 5335  
5335 5336  /*
5336 5337   * TODO: make this table extendible at run time
5337 5338   * Return a pointer to the mac type info for 'mac_type'
5338 5339   */
5339 5340  static ip_m_t *
5340 5341  ip_m_lookup(t_uscalar_t mac_type)
5341 5342  {
5342 5343          ip_m_t  *ipm;
5343 5344  
5344 5345          for (ipm = ip_m_tbl; ipm < A_END(ip_m_tbl); ipm++)
5345 5346                  if (ipm->ip_m_mac_type == mac_type)
5346 5347                          return (ipm);
5347 5348          return (NULL);
5348 5349  }
5349 5350  
5350 5351  /*
5351 5352   * Make a link layer address from the multicast IP address *addr.
5352 5353   * To form the link layer address, invoke the ip_m_v*mapping function
5353 5354   * associated with the link-layer type.
5354 5355   */
5355 5356  void
5356 5357  ip_mcast_mapping(ill_t *ill, uchar_t *addr, uchar_t *hwaddr)
5357 5358  {
5358 5359          ip_m_t *ipm;
5359 5360  
5360 5361          if (ill->ill_net_type == IRE_IF_NORESOLVER)
5361 5362                  return;
5362 5363  
5363 5364          ASSERT(addr != NULL);
5364 5365  
5365 5366          ipm = ip_m_lookup(ill->ill_mactype);
5366 5367          if (ipm == NULL ||
5367 5368              (ill->ill_isv6 && ipm->ip_m_v6mapping == NULL) ||
5368 5369              (!ill->ill_isv6 && ipm->ip_m_v4mapping == NULL)) {
5369 5370                  ip0dbg(("no mapping for ill %s mactype 0x%x\n",
5370 5371                      ill->ill_name, ill->ill_mactype));
5371 5372                  return;
5372 5373          }
5373 5374          if (ill->ill_isv6)
5374 5375                  (*ipm->ip_m_v6mapping)(ill, addr, hwaddr);
5375 5376          else
5376 5377                  (*ipm->ip_m_v4mapping)(ill, addr, hwaddr);
5377 5378  }
5378 5379  
5379 5380  /*
5380 5381   * Returns B_FALSE if the IPv4 netmask pointed by `mask' is non-contiguous.
5381 5382   * Otherwise returns B_TRUE.
5382 5383   *
5383 5384   * The netmask can be verified to be contiguous with 32 shifts and or
5384 5385   * operations. Take the contiguous mask (in host byte order) and compute
5385 5386   *      mask | mask << 1 | mask << 2 | ... | mask << 31
5386 5387   * the result will be the same as the 'mask' for contiguous mask.
5387 5388   */
5388 5389  static boolean_t
5389 5390  ip_contiguous_mask(uint32_t mask)
5390 5391  {
5391 5392          uint32_t        m = mask;
5392 5393          int             i;
5393 5394  
5394 5395          for (i = 1; i < 32; i++)
5395 5396                  m |= (mask << i);
5396 5397  
5397 5398          return (m == mask);
5398 5399  }
5399 5400  
5400 5401  /*
5401 5402   * ip_rt_add is called to add an IPv4 route to the forwarding table.
5402 5403   * ill is passed in to associate it with the correct interface.
5403 5404   * If ire_arg is set, then we return the held IRE in that location.
5404 5405   */
5405 5406  int
5406 5407  ip_rt_add(ipaddr_t dst_addr, ipaddr_t mask, ipaddr_t gw_addr,
5407 5408      ipaddr_t src_addr, int flags, ill_t *ill, ire_t **ire_arg,
5408 5409      boolean_t ioctl_msg, struct rtsa_s *sp, ip_stack_t *ipst, zoneid_t zoneid)
5409 5410  {
5410 5411          ire_t   *ire, *nire;
5411 5412          ire_t   *gw_ire = NULL;
5412 5413          ipif_t  *ipif = NULL;
5413 5414          uint_t  type;
5414 5415          int     match_flags = MATCH_IRE_TYPE;
5415 5416          tsol_gc_t *gc = NULL;
5416 5417          tsol_gcgrp_t *gcgrp = NULL;
5417 5418          boolean_t gcgrp_xtraref = B_FALSE;
5418 5419          boolean_t cgtp_broadcast;
5419 5420          boolean_t unbound = B_FALSE;
5420 5421  
5421 5422          ip1dbg(("ip_rt_add:"));
5422 5423  
5423 5424          if (ire_arg != NULL)
5424 5425                  *ire_arg = NULL;
5425 5426  
5426 5427          /* disallow non-contiguous netmasks */
5427 5428          if (!ip_contiguous_mask(ntohl(mask)))
5428 5429                  return (ENOTSUP);
5429 5430  
5430 5431          /*
5431 5432           * If this is the case of RTF_HOST being set, then we set the netmask
5432 5433           * to all ones (regardless if one was supplied).
5433 5434           */
5434 5435          if (flags & RTF_HOST)
5435 5436                  mask = IP_HOST_MASK;
5436 5437  
5437 5438          /*
5438 5439           * Prevent routes with a zero gateway from being created (since
5439 5440           * interfaces can currently be plumbed and brought up no assigned
5440 5441           * address).
5441 5442           */
5442 5443          if (gw_addr == 0)
5443 5444                  return (ENETUNREACH);
5444 5445          /*
5445 5446           * Get the ipif, if any, corresponding to the gw_addr
5446 5447           * If -ifp was specified we restrict ourselves to the ill, otherwise
5447 5448           * we match on the gatway and destination to handle unnumbered pt-pt
5448 5449           * interfaces.
5449 5450           */
5450 5451          if (ill != NULL)
5451 5452                  ipif = ipif_lookup_addr(gw_addr, ill, ALL_ZONES, ipst);
5452 5453          else
5453 5454                  ipif = ipif_lookup_interface(gw_addr, dst_addr, ipst);
5454 5455          if (ipif != NULL) {
5455 5456                  if (IS_VNI(ipif->ipif_ill)) {
5456 5457                          ipif_refrele(ipif);
5457 5458                          return (EINVAL);
5458 5459                  }
5459 5460          }
5460 5461  
5461 5462          /*
5462 5463           * GateD will attempt to create routes with a loopback interface
5463 5464           * address as the gateway and with RTF_GATEWAY set.  We allow
5464 5465           * these routes to be added, but create them as interface routes
5465 5466           * since the gateway is an interface address.
5466 5467           */
5467 5468          if ((ipif != NULL) && (ipif->ipif_ire_type == IRE_LOOPBACK)) {
5468 5469                  flags &= ~RTF_GATEWAY;
5469 5470                  if (gw_addr == INADDR_LOOPBACK && dst_addr == INADDR_LOOPBACK &&
5470 5471                      mask == IP_HOST_MASK) {
5471 5472                          ire = ire_ftable_lookup_v4(dst_addr, 0, 0, IRE_LOOPBACK,
5472 5473                              NULL, ALL_ZONES, NULL, MATCH_IRE_TYPE, 0, ipst,
5473 5474                              NULL);
5474 5475                          if (ire != NULL) {
5475 5476                                  ire_refrele(ire);
5476 5477                                  ipif_refrele(ipif);
5477 5478                                  return (EEXIST);
5478 5479                          }
5479 5480                          ip1dbg(("ip_rt_add: 0x%p creating IRE 0x%x"
5480 5481                              "for 0x%x\n", (void *)ipif,
5481 5482                              ipif->ipif_ire_type,
5482 5483                              ntohl(ipif->ipif_lcl_addr)));
5483 5484                          ire = ire_create(
5484 5485                              (uchar_t *)&dst_addr,       /* dest address */
5485 5486                              (uchar_t *)&mask,           /* mask */
5486 5487                              NULL,                       /* no gateway */
5487 5488                              ipif->ipif_ire_type,        /* LOOPBACK */
5488 5489                              ipif->ipif_ill,
5489 5490                              zoneid,
5490 5491                              (ipif->ipif_flags & IPIF_PRIVATE) ? RTF_PRIVATE : 0,
5491 5492                              NULL,
5492 5493                              ipst);
5493 5494  
5494 5495                          if (ire == NULL) {
5495 5496                                  ipif_refrele(ipif);
5496 5497                                  return (ENOMEM);
5497 5498                          }
5498 5499                          /* src address assigned by the caller? */
5499 5500                          if ((src_addr != INADDR_ANY) && (flags & RTF_SETSRC))
5500 5501                                  ire->ire_setsrc_addr = src_addr;
5501 5502  
5502 5503                          nire = ire_add(ire);
5503 5504                          if (nire == NULL) {
5504 5505                                  /*
5505 5506                                   * In the result of failure, ire_add() will have
5506 5507                                   * already deleted the ire in question, so there
5507 5508                                   * is no need to do that here.
5508 5509                                   */
5509 5510                                  ipif_refrele(ipif);
5510 5511                                  return (ENOMEM);
5511 5512                          }
5512 5513                          /*
5513 5514                           * Check if it was a duplicate entry. This handles
5514 5515                           * the case of two racing route adds for the same route
5515 5516                           */
5516 5517                          if (nire != ire) {
5517 5518                                  ASSERT(nire->ire_identical_ref > 1);
5518 5519                                  ire_delete(nire);
5519 5520                                  ire_refrele(nire);
5520 5521                                  ipif_refrele(ipif);
5521 5522                                  return (EEXIST);
5522 5523                          }
5523 5524                          ire = nire;
5524 5525                          goto save_ire;
5525 5526                  }
5526 5527          }
5527 5528  
5528 5529          /*
5529 5530           * The routes for multicast with CGTP are quite special in that
5530 5531           * the gateway is the local interface address, yet RTF_GATEWAY
5531 5532           * is set. We turn off RTF_GATEWAY to provide compatibility with
5532 5533           * this undocumented and unusual use of multicast routes.
5533 5534           */
5534 5535          if ((flags & RTF_MULTIRT) && ipif != NULL)
5535 5536                  flags &= ~RTF_GATEWAY;
5536 5537  
5537 5538          /*
5538 5539           * Traditionally, interface routes are ones where RTF_GATEWAY isn't set
5539 5540           * and the gateway address provided is one of the system's interface
5540 5541           * addresses.  By using the routing socket interface and supplying an
5541 5542           * RTA_IFP sockaddr with an interface index, an alternate method of
5542 5543           * specifying an interface route to be created is available which uses
5543 5544           * the interface index that specifies the outgoing interface rather than
5544 5545           * the address of an outgoing interface (which may not be able to
5545 5546           * uniquely identify an interface).  When coupled with the RTF_GATEWAY
5546 5547           * flag, routes can be specified which not only specify the next-hop to
5547 5548           * be used when routing to a certain prefix, but also which outgoing
5548 5549           * interface should be used.
5549 5550           *
5550 5551           * Previously, interfaces would have unique addresses assigned to them
5551 5552           * and so the address assigned to a particular interface could be used
5552 5553           * to identify a particular interface.  One exception to this was the
5553 5554           * case of an unnumbered interface (where IPIF_UNNUMBERED was set).
5554 5555           *
5555 5556           * With the advent of IPv6 and its link-local addresses, this
5556 5557           * restriction was relaxed and interfaces could share addresses between
5557 5558           * themselves.  In fact, typically all of the link-local interfaces on
5558 5559           * an IPv6 node or router will have the same link-local address.  In
5559 5560           * order to differentiate between these interfaces, the use of an
5560 5561           * interface index is necessary and this index can be carried inside a
5561 5562           * RTA_IFP sockaddr (which is actually a sockaddr_dl).  One restriction
5562 5563           * of using the interface index, however, is that all of the ipif's that
5563 5564           * are part of an ill have the same index and so the RTA_IFP sockaddr
5564 5565           * cannot be used to differentiate between ipif's (or logical
5565 5566           * interfaces) that belong to the same ill (physical interface).
5566 5567           *
5567 5568           * For example, in the following case involving IPv4 interfaces and
5568 5569           * logical interfaces
5569 5570           *
5570 5571           *      192.0.2.32      255.255.255.224 192.0.2.33      U       if0
5571 5572           *      192.0.2.32      255.255.255.224 192.0.2.34      U       if0
5572 5573           *      192.0.2.32      255.255.255.224 192.0.2.35      U       if0
5573 5574           *
5574 5575           * the ipif's corresponding to each of these interface routes can be
5575 5576           * uniquely identified by the "gateway" (actually interface address).
5576 5577           *
5577 5578           * In this case involving multiple IPv6 default routes to a particular
5578 5579           * link-local gateway, the use of RTA_IFP is necessary to specify which
5579 5580           * default route is of interest:
5580 5581           *
5581 5582           *      default         fe80::123:4567:89ab:cdef        U       if0
5582 5583           *      default         fe80::123:4567:89ab:cdef        U       if1
5583 5584           */
5584 5585  
5585 5586          /* RTF_GATEWAY not set */
5586 5587          if (!(flags & RTF_GATEWAY)) {
5587 5588                  if (sp != NULL) {
5588 5589                          ip2dbg(("ip_rt_add: gateway security attributes "
5589 5590                              "cannot be set with interface route\n"));
5590 5591                          if (ipif != NULL)
5591 5592                                  ipif_refrele(ipif);
5592 5593                          return (EINVAL);
5593 5594                  }
5594 5595  
5595 5596                  /*
5596 5597                   * Whether or not ill (RTA_IFP) is set, we require that
5597 5598                   * the gateway is one of our local addresses.
5598 5599                   */
5599 5600                  if (ipif == NULL)
5600 5601                          return (ENETUNREACH);
5601 5602  
5602 5603                  /*
5603 5604                   * We use MATCH_IRE_ILL here. If the caller specified an
5604 5605                   * interface (from the RTA_IFP sockaddr) we use it, otherwise
5605 5606                   * we use the ill derived from the gateway address.
5606 5607                   * We can always match the gateway address since we record it
5607 5608                   * in ire_gateway_addr.
5608 5609                   * We don't allow RTA_IFP to specify a different ill than the
5609 5610                   * one matching the ipif to make sure we can delete the route.
5610 5611                   */
5611 5612                  match_flags |= MATCH_IRE_GW | MATCH_IRE_ILL;
5612 5613                  if (ill == NULL) {
5613 5614                          ill = ipif->ipif_ill;
5614 5615                  } else if (ill != ipif->ipif_ill) {
5615 5616                          ipif_refrele(ipif);
5616 5617                          return (EINVAL);
5617 5618                  }
5618 5619  
5619 5620                  /*
5620 5621                   * We check for an existing entry at this point.
5621 5622                   *
5622 5623                   * Since a netmask isn't passed in via the ioctl interface
5623 5624                   * (SIOCADDRT), we don't check for a matching netmask in that
5624 5625                   * case.
5625 5626                   */
5626 5627                  if (!ioctl_msg)
5627 5628                          match_flags |= MATCH_IRE_MASK;
5628 5629                  ire = ire_ftable_lookup_v4(dst_addr, mask, gw_addr,
5629 5630                      IRE_INTERFACE, ill, ALL_ZONES, NULL, match_flags, 0, ipst,
5630 5631                      NULL);
5631 5632                  if (ire != NULL) {
5632 5633                          ire_refrele(ire);
5633 5634                          ipif_refrele(ipif);
5634 5635                          return (EEXIST);
5635 5636                  }
5636 5637  
5637 5638                  /*
5638 5639                   * Some software (for example, GateD and Sun Cluster) attempts
5639 5640                   * to create (what amount to) IRE_PREFIX routes with the
5640 5641                   * loopback address as the gateway.  This is primarily done to
5641 5642                   * set up prefixes with the RTF_REJECT flag set (for example,
5642 5643                   * when generating aggregate routes.)
5643 5644                   *
5644 5645                   * If the IRE type (as defined by ill->ill_net_type) would be
5645 5646                   * IRE_LOOPBACK, then we map the request into a
5646 5647                   * IRE_IF_NORESOLVER. We also OR in the RTF_BLACKHOLE flag as
5647 5648                   * these interface routes, by definition, can only be that.
5648 5649                   *
5649 5650                   * Needless to say, the real IRE_LOOPBACK is NOT created by this
5650 5651                   * routine, but rather using ire_create() directly.
5651 5652                   *
5652 5653                   */
5653 5654                  type = ill->ill_net_type;
5654 5655                  if (type == IRE_LOOPBACK) {
5655 5656                          type = IRE_IF_NORESOLVER;
5656 5657                          flags |= RTF_BLACKHOLE;
5657 5658                  }
5658 5659  
5659 5660                  /*
5660 5661                   * Create a copy of the IRE_IF_NORESOLVER or
5661 5662                   * IRE_IF_RESOLVER with the modified address, netmask, and
5662 5663                   * gateway.
5663 5664                   */
5664 5665                  ire = ire_create(
5665 5666                      (uchar_t *)&dst_addr,
5666 5667                      (uint8_t *)&mask,
5667 5668                      (uint8_t *)&gw_addr,
5668 5669                      type,
5669 5670                      ill,
5670 5671                      zoneid,
5671 5672                      flags,
5672 5673                      NULL,
5673 5674                      ipst);
5674 5675                  if (ire == NULL) {
5675 5676                          ipif_refrele(ipif);
5676 5677                          return (ENOMEM);
5677 5678                  }
5678 5679  
5679 5680                  /* src address assigned by the caller? */
5680 5681                  if ((src_addr != INADDR_ANY) && (flags & RTF_SETSRC))
5681 5682                          ire->ire_setsrc_addr = src_addr;
5682 5683  
5683 5684                  nire = ire_add(ire);
5684 5685                  if (nire == NULL) {
5685 5686                          /*
5686 5687                           * In the result of failure, ire_add() will have
5687 5688                           * already deleted the ire in question, so there
5688 5689                           * is no need to do that here.
5689 5690                           */
5690 5691                          ipif_refrele(ipif);
5691 5692                          return (ENOMEM);
5692 5693                  }
5693 5694                  /*
5694 5695                   * Check if it was a duplicate entry. This handles
5695 5696                   * the case of two racing route adds for the same route
5696 5697                   */
5697 5698                  if (nire != ire) {
5698 5699                          ire_delete(nire);
5699 5700                          ire_refrele(nire);
5700 5701                          ipif_refrele(ipif);
5701 5702                          return (EEXIST);
5702 5703                  }
5703 5704                  ire = nire;
5704 5705                  goto save_ire;
5705 5706          }
5706 5707  
5707 5708          /*
5708 5709           * Get an interface IRE for the specified gateway.
5709 5710           * If we don't have an IRE_IF_NORESOLVER or IRE_IF_RESOLVER for the
5710 5711           * gateway, it is currently unreachable and we fail the request
5711 5712           * accordingly. We reject any RTF_GATEWAY routes where the gateway
5712 5713           * is an IRE_LOCAL or IRE_LOOPBACK.
5713 5714           * If RTA_IFP was specified we look on that particular ill.
5714 5715           */
5715 5716          if (ill != NULL)
5716 5717                  match_flags |= MATCH_IRE_ILL;
5717 5718  
5718 5719          /* Check whether the gateway is reachable. */
5719 5720  again:
5720 5721          type = IRE_INTERFACE | IRE_LOCAL | IRE_LOOPBACK;
5721 5722          if (flags & RTF_INDIRECT)
5722 5723                  type |= IRE_OFFLINK;
5723 5724  
5724 5725          gw_ire = ire_ftable_lookup_v4(gw_addr, 0, 0, type, ill,
5725 5726              ALL_ZONES, NULL, match_flags, 0, ipst, NULL);
5726 5727          if (gw_ire == NULL) {
5727 5728                  /*
5728 5729                   * With IPMP, we allow host routes to influence in.mpathd's
5729 5730                   * target selection.  However, if the test addresses are on
5730 5731                   * their own network, the above lookup will fail since the
5731 5732                   * underlying IRE_INTERFACEs are marked hidden.  So allow
5732 5733                   * hidden test IREs to be found and try again.
5733 5734                   */
5734 5735                  if (!(match_flags & MATCH_IRE_TESTHIDDEN))  {
5735 5736                          match_flags |= MATCH_IRE_TESTHIDDEN;
5736 5737                          goto again;
5737 5738                  }
5738 5739                  if (ipif != NULL)
5739 5740                          ipif_refrele(ipif);
5740 5741                  return (ENETUNREACH);
5741 5742          }
5742 5743          if (gw_ire->ire_type & (IRE_LOCAL|IRE_LOOPBACK)) {
5743 5744                  ire_refrele(gw_ire);
5744 5745                  if (ipif != NULL)
5745 5746                          ipif_refrele(ipif);
5746 5747                  return (ENETUNREACH);
5747 5748          }
5748 5749  
5749 5750          if (ill == NULL && !(flags & RTF_INDIRECT)) {
5750 5751                  unbound = B_TRUE;
5751 5752                  if (ipst->ips_ip_strict_src_multihoming > 0)
5752 5753                          ill = gw_ire->ire_ill;
5753 5754          }
5754 5755  
5755 5756          /*
5756 5757           * We create one of three types of IREs as a result of this request
5757 5758           * based on the netmask.  A netmask of all ones (which is automatically
5758 5759           * assumed when RTF_HOST is set) results in an IRE_HOST being created.
5759 5760           * An all zeroes netmask implies a default route so an IRE_DEFAULT is
5760 5761           * created.  Otherwise, an IRE_PREFIX route is created for the
5761 5762           * destination prefix.
5762 5763           */
5763 5764          if (mask == IP_HOST_MASK)
5764 5765                  type = IRE_HOST;
5765 5766          else if (mask == 0)
5766 5767                  type = IRE_DEFAULT;
5767 5768          else
5768 5769                  type = IRE_PREFIX;
5769 5770  
5770 5771          /* check for a duplicate entry */
5771 5772          ire = ire_ftable_lookup_v4(dst_addr, mask, gw_addr, type, ill,
5772 5773              ALL_ZONES, NULL, match_flags | MATCH_IRE_MASK | MATCH_IRE_GW,
5773 5774              0, ipst, NULL);
5774 5775          if (ire != NULL) {
5775 5776                  if (ipif != NULL)
5776 5777                          ipif_refrele(ipif);
5777 5778                  ire_refrele(gw_ire);
5778 5779                  ire_refrele(ire);
5779 5780                  return (EEXIST);
5780 5781          }
5781 5782  
5782 5783          /* Security attribute exists */
5783 5784          if (sp != NULL) {
5784 5785                  tsol_gcgrp_addr_t ga;
5785 5786  
5786 5787                  /* find or create the gateway credentials group */
5787 5788                  ga.ga_af = AF_INET;
5788 5789                  IN6_IPADDR_TO_V4MAPPED(gw_addr, &ga.ga_addr);
5789 5790  
5790 5791                  /* we hold reference to it upon success */
5791 5792                  gcgrp = gcgrp_lookup(&ga, B_TRUE);
5792 5793                  if (gcgrp == NULL) {
5793 5794                          if (ipif != NULL)
5794 5795                                  ipif_refrele(ipif);
5795 5796                          ire_refrele(gw_ire);
5796 5797                          return (ENOMEM);
5797 5798                  }
5798 5799  
5799 5800                  /*
5800 5801                   * Create and add the security attribute to the group; a
5801 5802                   * reference to the group is made upon allocating a new
5802 5803                   * entry successfully.  If it finds an already-existing
5803 5804                   * entry for the security attribute in the group, it simply
5804 5805                   * returns it and no new reference is made to the group.
5805 5806                   */
5806 5807                  gc = gc_create(sp, gcgrp, &gcgrp_xtraref);
5807 5808                  if (gc == NULL) {
5808 5809                          if (ipif != NULL)
5809 5810                                  ipif_refrele(ipif);
5810 5811                          /* release reference held by gcgrp_lookup */
5811 5812                          GCGRP_REFRELE(gcgrp);
5812 5813                          ire_refrele(gw_ire);
5813 5814                          return (ENOMEM);
5814 5815                  }
5815 5816          }
5816 5817  
5817 5818          /* Create the IRE. */
5818 5819          ire = ire_create(
5819 5820              (uchar_t *)&dst_addr,               /* dest address */
5820 5821              (uchar_t *)&mask,                   /* mask */
5821 5822              (uchar_t *)&gw_addr,                /* gateway address */
5822 5823              (ushort_t)type,                     /* IRE type */
5823 5824              ill,
5824 5825              zoneid,
5825 5826              flags,
5826 5827              gc,                                 /* security attribute */
5827 5828              ipst);
5828 5829  
5829 5830          /*
5830 5831           * The ire holds a reference to the 'gc' and the 'gc' holds a
5831 5832           * reference to the 'gcgrp'. We can now release the extra reference
5832 5833           * the 'gcgrp' acquired in the gcgrp_lookup, if it was not used.
5833 5834           */
5834 5835          if (gcgrp_xtraref)
5835 5836                  GCGRP_REFRELE(gcgrp);
5836 5837          if (ire == NULL) {
5837 5838                  if (gc != NULL)
5838 5839                          GC_REFRELE(gc);
5839 5840                  if (ipif != NULL)
5840 5841                          ipif_refrele(ipif);
5841 5842                  ire_refrele(gw_ire);
5842 5843                  return (ENOMEM);
5843 5844          }
5844 5845  
5845 5846          /* Before we add, check if an extra CGTP broadcast is needed */
5846 5847          cgtp_broadcast = ((flags & RTF_MULTIRT) &&
5847 5848              ip_type_v4(ire->ire_addr, ipst) == IRE_BROADCAST);
5848 5849  
5849 5850          /* src address assigned by the caller? */
5850 5851          if ((src_addr != INADDR_ANY) && (flags & RTF_SETSRC))
5851 5852                  ire->ire_setsrc_addr = src_addr;
5852 5853  
5853 5854          ire->ire_unbound = unbound;
5854 5855  
5855 5856          /*
5856 5857           * POLICY: should we allow an RTF_HOST with address INADDR_ANY?
5857 5858           * SUN/OS socket stuff does but do we really want to allow 0.0.0.0?
5858 5859           */
5859 5860  
5860 5861          /* Add the new IRE. */
5861 5862          nire = ire_add(ire);
5862 5863          if (nire == NULL) {
5863 5864                  /*
5864 5865                   * In the result of failure, ire_add() will have
5865 5866                   * already deleted the ire in question, so there
5866 5867                   * is no need to do that here.
5867 5868                   */
5868 5869                  if (ipif != NULL)
5869 5870                          ipif_refrele(ipif);
5870 5871                  ire_refrele(gw_ire);
5871 5872                  return (ENOMEM);
5872 5873          }
5873 5874          /*
5874 5875           * Check if it was a duplicate entry. This handles
5875 5876           * the case of two racing route adds for the same route
5876 5877           */
5877 5878          if (nire != ire) {
5878 5879                  ire_delete(nire);
5879 5880                  ire_refrele(nire);
5880 5881                  if (ipif != NULL)
5881 5882                          ipif_refrele(ipif);
5882 5883                  ire_refrele(gw_ire);
5883 5884                  return (EEXIST);
5884 5885          }
5885 5886          ire = nire;
5886 5887  
5887 5888          if (flags & RTF_MULTIRT) {
5888 5889                  /*
5889 5890                   * Invoke the CGTP (multirouting) filtering module
5890 5891                   * to add the dst address in the filtering database.
5891 5892                   * Replicated inbound packets coming from that address
5892 5893                   * will be filtered to discard the duplicates.
5893 5894                   * It is not necessary to call the CGTP filter hook
5894 5895                   * when the dst address is a broadcast or multicast,
5895 5896                   * because an IP source address cannot be a broadcast
5896 5897                   * or a multicast.
5897 5898                   */
5898 5899                  if (cgtp_broadcast) {
5899 5900                          ip_cgtp_bcast_add(ire, ipst);
5900 5901                          goto save_ire;
5901 5902                  }
5902 5903                  if (ipst->ips_ip_cgtp_filter_ops != NULL &&
5903 5904                      !CLASSD(ire->ire_addr)) {
5904 5905                          int res;
5905 5906                          ipif_t *src_ipif;
5906 5907  
5907 5908                          /* Find the source address corresponding to gw_ire */
5908 5909                          src_ipif = ipif_lookup_addr(gw_ire->ire_gateway_addr,
5909 5910                              NULL, zoneid, ipst);
5910 5911                          if (src_ipif != NULL) {
5911 5912                                  res = ipst->ips_ip_cgtp_filter_ops->
5912 5913                                      cfo_add_dest_v4(
5913 5914                                      ipst->ips_netstack->netstack_stackid,
5914 5915                                      ire->ire_addr,
5915 5916                                      ire->ire_gateway_addr,
5916 5917                                      ire->ire_setsrc_addr,
5917 5918                                      src_ipif->ipif_lcl_addr);
5918 5919                                  ipif_refrele(src_ipif);
5919 5920                          } else {
5920 5921                                  res = EADDRNOTAVAIL;
5921 5922                          }
5922 5923                          if (res != 0) {
5923 5924                                  if (ipif != NULL)
5924 5925                                          ipif_refrele(ipif);
5925 5926                                  ire_refrele(gw_ire);
5926 5927                                  ire_delete(ire);
5927 5928                                  ire_refrele(ire);       /* Held in ire_add */
5928 5929                                  return (res);
5929 5930                          }
5930 5931                  }
5931 5932          }
5932 5933  
5933 5934  save_ire:
5934 5935          if (gw_ire != NULL) {
5935 5936                  ire_refrele(gw_ire);
5936 5937                  gw_ire = NULL;
5937 5938          }
5938 5939          if (ill != NULL) {
5939 5940                  /*
5940 5941                   * Save enough information so that we can recreate the IRE if
5941 5942                   * the interface goes down and then up.  The metrics associated
5942 5943                   * with the route will be saved as well when rts_setmetrics() is
5943 5944                   * called after the IRE has been created.  In the case where
5944 5945                   * memory cannot be allocated, none of this information will be
5945 5946                   * saved.
5946 5947                   */
5947 5948                  ill_save_ire(ill, ire);
5948 5949          }
5949 5950          if (ioctl_msg)
5950 5951                  ip_rts_rtmsg(RTM_OLDADD, ire, 0, ipst);
5951 5952          if (ire_arg != NULL) {
5952 5953                  /*
5953 5954                   * Store the ire that was successfully added into where ire_arg
5954 5955                   * points to so that callers don't have to look it up
5955 5956                   * themselves (but they are responsible for ire_refrele()ing
5956 5957                   * the ire when they are finished with it).
5957 5958                   */
5958 5959                  *ire_arg = ire;
5959 5960          } else {
5960 5961                  ire_refrele(ire);               /* Held in ire_add */
5961 5962          }
5962 5963          if (ipif != NULL)
5963 5964                  ipif_refrele(ipif);
5964 5965          return (0);
5965 5966  }
5966 5967  
5967 5968  /*
5968 5969   * ip_rt_delete is called to delete an IPv4 route.
5969 5970   * ill is passed in to associate it with the correct interface.
5970 5971   */
5971 5972  /* ARGSUSED4 */
5972 5973  int
5973 5974  ip_rt_delete(ipaddr_t dst_addr, ipaddr_t mask, ipaddr_t gw_addr,
5974 5975      uint_t rtm_addrs, int flags, ill_t *ill, boolean_t ioctl_msg,
5975 5976      ip_stack_t *ipst, zoneid_t zoneid)
5976 5977  {
5977 5978          ire_t   *ire = NULL;
5978 5979          ipif_t  *ipif;
5979 5980          uint_t  type;
5980 5981          uint_t  match_flags = MATCH_IRE_TYPE;
5981 5982          int     err = 0;
5982 5983  
5983 5984          ip1dbg(("ip_rt_delete:"));
5984 5985          /*
5985 5986           * If this is the case of RTF_HOST being set, then we set the netmask
5986 5987           * to all ones.  Otherwise, we use the netmask if one was supplied.
5987 5988           */
5988 5989          if (flags & RTF_HOST) {
5989 5990                  mask = IP_HOST_MASK;
5990 5991                  match_flags |= MATCH_IRE_MASK;
5991 5992          } else if (rtm_addrs & RTA_NETMASK) {
5992 5993                  match_flags |= MATCH_IRE_MASK;
5993 5994          }
5994 5995  
5995 5996          /*
5996 5997           * Note that RTF_GATEWAY is never set on a delete, therefore
5997 5998           * we check if the gateway address is one of our interfaces first,
5998 5999           * and fall back on RTF_GATEWAY routes.
5999 6000           *
6000 6001           * This makes it possible to delete an original
6001 6002           * IRE_IF_NORESOLVER/IRE_IF_RESOLVER - consistent with SunOS 4.1.
6002 6003           * However, we have RTF_KERNEL set on the ones created by ipif_up
6003 6004           * and those can not be deleted here.
6004 6005           *
6005 6006           * We use MATCH_IRE_ILL if we know the interface. If the caller
6006 6007           * specified an interface (from the RTA_IFP sockaddr) we use it,
6007 6008           * otherwise we use the ill derived from the gateway address.
6008 6009           * We can always match the gateway address since we record it
6009 6010           * in ire_gateway_addr.
6010 6011           *
6011 6012           * For more detail on specifying routes by gateway address and by
6012 6013           * interface index, see the comments in ip_rt_add().
6013 6014           */
6014 6015          ipif = ipif_lookup_interface(gw_addr, dst_addr, ipst);
6015 6016          if (ipif != NULL) {
6016 6017                  ill_t   *ill_match;
6017 6018  
6018 6019                  if (ill != NULL)
6019 6020                          ill_match = ill;
6020 6021                  else
6021 6022                          ill_match = ipif->ipif_ill;
6022 6023  
6023 6024                  match_flags |= MATCH_IRE_ILL;
6024 6025                  if (ipif->ipif_ire_type == IRE_LOOPBACK) {
6025 6026                          ire = ire_ftable_lookup_v4(dst_addr, mask, 0,
6026 6027                              IRE_LOOPBACK, ill_match, ALL_ZONES, NULL,
6027 6028                              match_flags, 0, ipst, NULL);
6028 6029                  }
6029 6030                  if (ire == NULL) {
6030 6031                          match_flags |= MATCH_IRE_GW;
6031 6032                          ire = ire_ftable_lookup_v4(dst_addr, mask, gw_addr,
6032 6033                              IRE_INTERFACE, ill_match, ALL_ZONES, NULL,
6033 6034                              match_flags, 0, ipst, NULL);
6034 6035                  }
6035 6036                  /* Avoid deleting routes created by kernel from an ipif */
6036 6037                  if (ire != NULL && (ire->ire_flags & RTF_KERNEL)) {
6037 6038                          ire_refrele(ire);
6038 6039                          ire = NULL;
6039 6040                  }
6040 6041  
6041 6042                  /* Restore in case we didn't find a match */
6042 6043                  match_flags &= ~(MATCH_IRE_GW|MATCH_IRE_ILL);
6043 6044          }
6044 6045  
6045 6046          if (ire == NULL) {
6046 6047                  /*
6047 6048                   * At this point, the gateway address is not one of our own
6048 6049                   * addresses or a matching interface route was not found.  We
6049 6050                   * set the IRE type to lookup based on whether
6050 6051                   * this is a host route, a default route or just a prefix.
6051 6052                   *
6052 6053                   * If an ill was passed in, then the lookup is based on an
6053 6054                   * interface index so MATCH_IRE_ILL is added to match_flags.
6054 6055                   */
6055 6056                  match_flags |= MATCH_IRE_GW;
6056 6057                  if (ill != NULL)
6057 6058                          match_flags |= MATCH_IRE_ILL;
6058 6059                  if (mask == IP_HOST_MASK)
6059 6060                          type = IRE_HOST;
6060 6061                  else if (mask == 0)
6061 6062                          type = IRE_DEFAULT;
6062 6063                  else
6063 6064                          type = IRE_PREFIX;
6064 6065                  ire = ire_ftable_lookup_v4(dst_addr, mask, gw_addr, type, ill,
6065 6066                      ALL_ZONES, NULL, match_flags, 0, ipst, NULL);
6066 6067          }
6067 6068  
6068 6069          if (ipif != NULL) {
6069 6070                  ipif_refrele(ipif);
6070 6071                  ipif = NULL;
6071 6072          }
6072 6073  
6073 6074          if (ire == NULL)
6074 6075                  return (ESRCH);
6075 6076  
6076 6077          if (ire->ire_flags & RTF_MULTIRT) {
6077 6078                  /*
6078 6079                   * Invoke the CGTP (multirouting) filtering module
6079 6080                   * to remove the dst address from the filtering database.
6080 6081                   * Packets coming from that address will no longer be
6081 6082                   * filtered to remove duplicates.
6082 6083                   */
6083 6084                  if (ipst->ips_ip_cgtp_filter_ops != NULL) {
6084 6085                          err = ipst->ips_ip_cgtp_filter_ops->cfo_del_dest_v4(
6085 6086                              ipst->ips_netstack->netstack_stackid,
6086 6087                              ire->ire_addr, ire->ire_gateway_addr);
6087 6088                  }
6088 6089                  ip_cgtp_bcast_delete(ire, ipst);
6089 6090          }
6090 6091  
6091 6092          ill = ire->ire_ill;
6092 6093          if (ill != NULL)
6093 6094                  ill_remove_saved_ire(ill, ire);
6094 6095          if (ioctl_msg)
6095 6096                  ip_rts_rtmsg(RTM_OLDDEL, ire, 0, ipst);
6096 6097          ire_delete(ire);
6097 6098          ire_refrele(ire);
6098 6099          return (err);
6099 6100  }
6100 6101  
6101 6102  /*
6102 6103   * ip_siocaddrt is called to complete processing of an SIOCADDRT IOCTL.
6103 6104   */
6104 6105  /* ARGSUSED */
6105 6106  int
6106 6107  ip_siocaddrt(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
6107 6108      ip_ioctl_cmd_t *ipip, void *dummy_if_req)
6108 6109  {
6109 6110          ipaddr_t dst_addr;
6110 6111          ipaddr_t gw_addr;
6111 6112          ipaddr_t mask;
6112 6113          int error = 0;
6113 6114          mblk_t *mp1;
6114 6115          struct rtentry *rt;
6115 6116          ipif_t *ipif = NULL;
6116 6117          ip_stack_t      *ipst;
6117 6118  
6118 6119          ASSERT(q->q_next == NULL);
6119 6120          ipst = CONNQ_TO_IPST(q);
6120 6121  
6121 6122          ip1dbg(("ip_siocaddrt:"));
6122 6123          /* Existence of mp1 verified in ip_wput_nondata */
6123 6124          mp1 = mp->b_cont->b_cont;
6124 6125          rt = (struct rtentry *)mp1->b_rptr;
6125 6126  
6126 6127          dst_addr = ((sin_t *)&rt->rt_dst)->sin_addr.s_addr;
6127 6128          gw_addr = ((sin_t *)&rt->rt_gateway)->sin_addr.s_addr;
6128 6129  
6129 6130          /*
6130 6131           * If the RTF_HOST flag is on, this is a request to assign a gateway
6131 6132           * to a particular host address.  In this case, we set the netmask to
6132 6133           * all ones for the particular destination address.  Otherwise,
6133 6134           * determine the netmask to be used based on dst_addr and the interfaces
6134 6135           * in use.
6135 6136           */
6136 6137          if (rt->rt_flags & RTF_HOST) {
6137 6138                  mask = IP_HOST_MASK;
6138 6139          } else {
6139 6140                  /*
6140 6141                   * Note that ip_subnet_mask returns a zero mask in the case of
6141 6142                   * default (an all-zeroes address).
6142 6143                   */
6143 6144                  mask = ip_subnet_mask(dst_addr, &ipif, ipst);
6144 6145          }
6145 6146  
6146 6147          error = ip_rt_add(dst_addr, mask, gw_addr, 0, rt->rt_flags, NULL, NULL,
6147 6148              B_TRUE, NULL, ipst, ALL_ZONES);
6148 6149          if (ipif != NULL)
6149 6150                  ipif_refrele(ipif);
6150 6151          return (error);
6151 6152  }
6152 6153  
6153 6154  /*
6154 6155   * ip_siocdelrt is called to complete processing of an SIOCDELRT IOCTL.
6155 6156   */
6156 6157  /* ARGSUSED */
6157 6158  int
6158 6159  ip_siocdelrt(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
6159 6160      ip_ioctl_cmd_t *ipip, void *dummy_if_req)
6160 6161  {
6161 6162          ipaddr_t dst_addr;
6162 6163          ipaddr_t gw_addr;
6163 6164          ipaddr_t mask;
6164 6165          int error;
6165 6166          mblk_t *mp1;
6166 6167          struct rtentry *rt;
6167 6168          ipif_t *ipif = NULL;
6168 6169          ip_stack_t      *ipst;
6169 6170  
6170 6171          ASSERT(q->q_next == NULL);
6171 6172          ipst = CONNQ_TO_IPST(q);
6172 6173  
6173 6174          ip1dbg(("ip_siocdelrt:"));
6174 6175          /* Existence of mp1 verified in ip_wput_nondata */
6175 6176          mp1 = mp->b_cont->b_cont;
6176 6177          rt = (struct rtentry *)mp1->b_rptr;
6177 6178  
6178 6179          dst_addr = ((sin_t *)&rt->rt_dst)->sin_addr.s_addr;
6179 6180          gw_addr = ((sin_t *)&rt->rt_gateway)->sin_addr.s_addr;
6180 6181  
6181 6182          /*
6182 6183           * If the RTF_HOST flag is on, this is a request to delete a gateway
6183 6184           * to a particular host address.  In this case, we set the netmask to
6184 6185           * all ones for the particular destination address.  Otherwise,
6185 6186           * determine the netmask to be used based on dst_addr and the interfaces
6186 6187           * in use.
6187 6188           */
6188 6189          if (rt->rt_flags & RTF_HOST) {
6189 6190                  mask = IP_HOST_MASK;
6190 6191          } else {
6191 6192                  /*
6192 6193                   * Note that ip_subnet_mask returns a zero mask in the case of
6193 6194                   * default (an all-zeroes address).
6194 6195                   */
6195 6196                  mask = ip_subnet_mask(dst_addr, &ipif, ipst);
6196 6197          }
6197 6198  
6198 6199          error = ip_rt_delete(dst_addr, mask, gw_addr,
6199 6200              RTA_DST | RTA_GATEWAY | RTA_NETMASK, rt->rt_flags, NULL, B_TRUE,
6200 6201              ipst, ALL_ZONES);
6201 6202          if (ipif != NULL)
6202 6203                  ipif_refrele(ipif);
6203 6204          return (error);
6204 6205  }
6205 6206  
6206 6207  /*
6207 6208   * Enqueue the mp onto the ipsq, chained by b_next.
6208 6209   * b_prev stores the function to be executed later, and b_queue the queue
6209 6210   * where this mp originated.
6210 6211   */
6211 6212  void
6212 6213  ipsq_enq(ipsq_t *ipsq, queue_t *q, mblk_t *mp, ipsq_func_t func, int type,
6213 6214      ill_t *pending_ill)
6214 6215  {
6215 6216          conn_t  *connp;
6216 6217          ipxop_t *ipx = ipsq->ipsq_xop;
6217 6218  
6218 6219          ASSERT(MUTEX_HELD(&ipsq->ipsq_lock));
6219 6220          ASSERT(MUTEX_HELD(&ipx->ipx_lock));
6220 6221          ASSERT(func != NULL);
6221 6222  
6222 6223          mp->b_queue = q;
6223 6224          mp->b_prev = (void *)func;
6224 6225          mp->b_next = NULL;
6225 6226  
6226 6227          switch (type) {
6227 6228          case CUR_OP:
6228 6229                  if (ipx->ipx_mptail != NULL) {
6229 6230                          ASSERT(ipx->ipx_mphead != NULL);
6230 6231                          ipx->ipx_mptail->b_next = mp;
6231 6232                  } else {
6232 6233                          ASSERT(ipx->ipx_mphead == NULL);
6233 6234                          ipx->ipx_mphead = mp;
6234 6235                  }
6235 6236                  ipx->ipx_mptail = mp;
6236 6237                  break;
6237 6238  
6238 6239          case NEW_OP:
6239 6240                  if (ipsq->ipsq_xopq_mptail != NULL) {
6240 6241                          ASSERT(ipsq->ipsq_xopq_mphead != NULL);
6241 6242                          ipsq->ipsq_xopq_mptail->b_next = mp;
6242 6243                  } else {
6243 6244                          ASSERT(ipsq->ipsq_xopq_mphead == NULL);
6244 6245                          ipsq->ipsq_xopq_mphead = mp;
6245 6246                  }
6246 6247                  ipsq->ipsq_xopq_mptail = mp;
6247 6248                  ipx->ipx_ipsq_queued = B_TRUE;
6248 6249                  break;
6249 6250  
6250 6251          case SWITCH_OP:
6251 6252                  ASSERT(ipsq->ipsq_swxop != NULL);
6252 6253                  /* only one switch operation is currently allowed */
6253 6254                  ASSERT(ipsq->ipsq_switch_mp == NULL);
6254 6255                  ipsq->ipsq_switch_mp = mp;
6255 6256                  ipx->ipx_ipsq_queued = B_TRUE;
6256 6257                  break;
6257 6258          default:
6258 6259                  cmn_err(CE_PANIC, "ipsq_enq %d type \n", type);
6259 6260          }
6260 6261  
6261 6262          if (CONN_Q(q) && pending_ill != NULL) {
6262 6263                  connp = Q_TO_CONN(q);
6263 6264                  ASSERT(MUTEX_HELD(&connp->conn_lock));
6264 6265                  connp->conn_oper_pending_ill = pending_ill;
6265 6266          }
6266 6267  }
6267 6268  
6268 6269  /*
6269 6270   * Dequeue the next message that requested exclusive access to this IPSQ's
6270 6271   * xop.  Specifically:
6271 6272   *
6272 6273   *  1. If we're still processing the current operation on `ipsq', then
6273 6274   *     dequeue the next message for the operation (from ipx_mphead), or
6274 6275   *     return NULL if there are no queued messages for the operation.
6275 6276   *     These messages are queued via CUR_OP to qwriter_ip() and friends.
6276 6277   *
6277 6278   *  2. If the current operation on `ipsq' has completed (ipx_current_ipif is
6278 6279   *     not set) see if the ipsq has requested an xop switch.  If so, switch
6279 6280   *     `ipsq' to a different xop.  Xop switches only happen when joining or
6280 6281   *     leaving IPMP groups and require a careful dance -- see the comments
6281 6282   *     in-line below for details.  If we're leaving a group xop or if we're
6282 6283   *     joining a group xop and become writer on it, then we proceed to (3).
6283 6284   *     Otherwise, we return NULL and exit the xop.
6284 6285   *
6285 6286   *  3. For each IPSQ in the xop, return any switch operation stored on
6286 6287   *     ipsq_switch_mp (set via SWITCH_OP); these must be processed before
6287 6288   *     any other messages queued on the IPSQ.  Otherwise, dequeue the next
6288 6289   *     exclusive operation (queued via NEW_OP) stored on ipsq_xopq_mphead.
6289 6290   *     Note that if the phyint tied to `ipsq' is not using IPMP there will
6290 6291   *     only be one IPSQ in the xop.  Otherwise, there will be one IPSQ for
6291 6292   *     each phyint in the group, including the IPMP meta-interface phyint.
6292 6293   */
6293 6294  static mblk_t *
6294 6295  ipsq_dq(ipsq_t *ipsq)
6295 6296  {
6296 6297          ill_t   *illv4, *illv6;
6297 6298          mblk_t  *mp;
6298 6299          ipsq_t  *xopipsq;
6299 6300          ipsq_t  *leftipsq = NULL;
6300 6301          ipxop_t *ipx;
6301 6302          phyint_t *phyi = ipsq->ipsq_phyint;
6302 6303          ip_stack_t *ipst = ipsq->ipsq_ipst;
6303 6304          boolean_t emptied = B_FALSE;
6304 6305  
6305 6306          /*
6306 6307           * Grab all the locks we need in the defined order (ill_g_lock ->
6307 6308           * ipsq_lock -> ipx_lock); ill_g_lock is needed to use ipsq_next.
6308 6309           */
6309 6310          rw_enter(&ipst->ips_ill_g_lock,
6310 6311              ipsq->ipsq_swxop != NULL ? RW_WRITER : RW_READER);
6311 6312          mutex_enter(&ipsq->ipsq_lock);
6312 6313          ipx = ipsq->ipsq_xop;
6313 6314          mutex_enter(&ipx->ipx_lock);
6314 6315  
6315 6316          /*
6316 6317           * Dequeue the next message associated with the current exclusive
6317 6318           * operation, if any.
6318 6319           */
6319 6320          if ((mp = ipx->ipx_mphead) != NULL) {
6320 6321                  ipx->ipx_mphead = mp->b_next;
6321 6322                  if (ipx->ipx_mphead == NULL)
6322 6323                          ipx->ipx_mptail = NULL;
6323 6324                  mp->b_next = (void *)ipsq;
6324 6325                  goto out;
6325 6326          }
6326 6327  
6327 6328          if (ipx->ipx_current_ipif != NULL)
6328 6329                  goto empty;
6329 6330  
6330 6331          if (ipsq->ipsq_swxop != NULL) {
6331 6332                  /*
6332 6333                   * The exclusive operation that is now being completed has
6333 6334                   * requested a switch to a different xop.  This happens
6334 6335                   * when an interface joins or leaves an IPMP group.  Joins
6335 6336                   * happen through SIOCSLIFGROUPNAME (ip_sioctl_groupname()).
6336 6337                   * Leaves happen via SIOCSLIFGROUPNAME, interface unplumb
6337 6338                   * (phyint_free()), or interface plumb for an ill type
6338 6339                   * not in the IPMP group (ip_rput_dlpi_writer()).
6339 6340                   *
6340 6341                   * Xop switches are not allowed on the IPMP meta-interface.
6341 6342                   */
6342 6343                  ASSERT(phyi == NULL || !(phyi->phyint_flags & PHYI_IPMP));
6343 6344                  ASSERT(RW_WRITE_HELD(&ipst->ips_ill_g_lock));
6344 6345                  DTRACE_PROBE1(ipsq__switch, (ipsq_t *), ipsq);
6345 6346  
6346 6347                  if (ipsq->ipsq_swxop == &ipsq->ipsq_ownxop) {
6347 6348                          /*
6348 6349                           * We're switching back to our own xop, so we have two
6349 6350                           * xop's to drain/exit: our own, and the group xop
6350 6351                           * that we are leaving.
6351 6352                           *
6352 6353                           * First, pull ourselves out of the group ipsq list.
6353 6354                           * This is safe since we're writer on ill_g_lock.
6354 6355                           */
6355 6356                          ASSERT(ipsq->ipsq_xop != &ipsq->ipsq_ownxop);
6356 6357  
6357 6358                          xopipsq = ipx->ipx_ipsq;
6358 6359                          while (xopipsq->ipsq_next != ipsq)
6359 6360                                  xopipsq = xopipsq->ipsq_next;
6360 6361  
6361 6362                          xopipsq->ipsq_next = ipsq->ipsq_next;
6362 6363                          ipsq->ipsq_next = ipsq;
6363 6364                          ipsq->ipsq_xop = ipsq->ipsq_swxop;
6364 6365                          ipsq->ipsq_swxop = NULL;
6365 6366  
6366 6367                          /*
6367 6368                           * Second, prepare to exit the group xop.  The actual
6368 6369                           * ipsq_exit() is done at the end of this function
6369 6370                           * since we cannot hold any locks across ipsq_exit().
6370 6371                           * Note that although we drop the group's ipx_lock, no
6371 6372                           * threads can proceed since we're still ipx_writer.
6372 6373                           */
6373 6374                          leftipsq = xopipsq;
6374 6375                          mutex_exit(&ipx->ipx_lock);
6375 6376  
6376 6377                          /*
6377 6378                           * Third, set ipx to point to our own xop (which was
6378 6379                           * inactive and therefore can be entered).
6379 6380                           */
6380 6381                          ipx = ipsq->ipsq_xop;
6381 6382                          mutex_enter(&ipx->ipx_lock);
6382 6383                          ASSERT(ipx->ipx_writer == NULL);
6383 6384                          ASSERT(ipx->ipx_current_ipif == NULL);
6384 6385                  } else {
6385 6386                          /*
6386 6387                           * We're switching from our own xop to a group xop.
6387 6388                           * The requestor of the switch must ensure that the
6388 6389                           * group xop cannot go away (e.g. by ensuring the
6389 6390                           * phyint associated with the xop cannot go away).
6390 6391                           *
6391 6392                           * If we can become writer on our new xop, then we'll
6392 6393                           * do the drain.  Otherwise, the current writer of our
6393 6394                           * new xop will do the drain when it exits.
6394 6395                           *
6395 6396                           * First, splice ourselves into the group IPSQ list.
6396 6397                           * This is safe since we're writer on ill_g_lock.
6397 6398                           */
6398 6399                          ASSERT(ipsq->ipsq_xop == &ipsq->ipsq_ownxop);
6399 6400  
6400 6401                          xopipsq = ipsq->ipsq_swxop->ipx_ipsq;
6401 6402                          while (xopipsq->ipsq_next != ipsq->ipsq_swxop->ipx_ipsq)
6402 6403                                  xopipsq = xopipsq->ipsq_next;
6403 6404  
6404 6405                          xopipsq->ipsq_next = ipsq;
6405 6406                          ipsq->ipsq_next = ipsq->ipsq_swxop->ipx_ipsq;
6406 6407                          ipsq->ipsq_xop = ipsq->ipsq_swxop;
6407 6408                          ipsq->ipsq_swxop = NULL;
6408 6409  
6409 6410                          /*
6410 6411                           * Second, exit our own xop, since it's now unused.
6411 6412                           * This is safe since we've got the only reference.
6412 6413                           */
6413 6414                          ASSERT(ipx->ipx_writer == curthread);
6414 6415                          ipx->ipx_writer = NULL;
6415 6416                          VERIFY(--ipx->ipx_reentry_cnt == 0);
6416 6417                          ipx->ipx_ipsq_queued = B_FALSE;
6417 6418                          mutex_exit(&ipx->ipx_lock);
6418 6419  
6419 6420                          /*
6420 6421                           * Third, set ipx to point to our new xop, and check
6421 6422                           * if we can become writer on it.  If we cannot, then
6422 6423                           * the current writer will drain the IPSQ group when
6423 6424                           * it exits.  Our ipsq_xop is guaranteed to be stable
6424 6425                           * because we're still holding ipsq_lock.
6425 6426                           */
6426 6427                          ipx = ipsq->ipsq_xop;
6427 6428                          mutex_enter(&ipx->ipx_lock);
6428 6429                          if (ipx->ipx_writer != NULL ||
6429 6430                              ipx->ipx_current_ipif != NULL) {
6430 6431                                  goto out;
6431 6432                          }
6432 6433                  }
6433 6434  
6434 6435                  /*
6435 6436                   * Fourth, become writer on our new ipx before we continue
6436 6437                   * with the drain.  Note that we never dropped ipsq_lock
6437 6438                   * above, so no other thread could've raced with us to
6438 6439                   * become writer first.  Also, we're holding ipx_lock, so
6439 6440                   * no other thread can examine the ipx right now.
6440 6441                   */
6441 6442                  ASSERT(ipx->ipx_current_ipif == NULL);
6442 6443                  ASSERT(ipx->ipx_mphead == NULL && ipx->ipx_mptail == NULL);
6443 6444                  VERIFY(ipx->ipx_reentry_cnt++ == 0);
6444 6445                  ipx->ipx_writer = curthread;
6445 6446                  ipx->ipx_forced = B_FALSE;
6446 6447  #ifdef DEBUG
6447 6448                  ipx->ipx_depth = getpcstack(ipx->ipx_stack, IPX_STACK_DEPTH);
6448 6449  #endif
6449 6450          }
6450 6451  
6451 6452          xopipsq = ipsq;
6452 6453          do {
6453 6454                  /*
6454 6455                   * So that other operations operate on a consistent and
6455 6456                   * complete phyint, a switch message on an IPSQ must be
6456 6457                   * handled prior to any other operations on that IPSQ.
6457 6458                   */
6458 6459                  if ((mp = xopipsq->ipsq_switch_mp) != NULL) {
6459 6460                          xopipsq->ipsq_switch_mp = NULL;
6460 6461                          ASSERT(mp->b_next == NULL);
6461 6462                          mp->b_next = (void *)xopipsq;
6462 6463                          goto out;
6463 6464                  }
6464 6465  
6465 6466                  if ((mp = xopipsq->ipsq_xopq_mphead) != NULL) {
6466 6467                          xopipsq->ipsq_xopq_mphead = mp->b_next;
6467 6468                          if (xopipsq->ipsq_xopq_mphead == NULL)
6468 6469                                  xopipsq->ipsq_xopq_mptail = NULL;
6469 6470                          mp->b_next = (void *)xopipsq;
6470 6471                          goto out;
6471 6472                  }
6472 6473          } while ((xopipsq = xopipsq->ipsq_next) != ipsq);
6473 6474  empty:
6474 6475          /*
6475 6476           * There are no messages.  Further, we are holding ipx_lock, hence no
6476 6477           * new messages can end up on any IPSQ in the xop.
6477 6478           */
6478 6479          ipx->ipx_writer = NULL;
6479 6480          ipx->ipx_forced = B_FALSE;
6480 6481          VERIFY(--ipx->ipx_reentry_cnt == 0);
6481 6482          ipx->ipx_ipsq_queued = B_FALSE;
6482 6483          emptied = B_TRUE;
6483 6484  #ifdef  DEBUG
6484 6485          ipx->ipx_depth = 0;
6485 6486  #endif
6486 6487  out:
6487 6488          mutex_exit(&ipx->ipx_lock);
6488 6489          mutex_exit(&ipsq->ipsq_lock);
6489 6490  
6490 6491          /*
6491 6492           * If we completely emptied the xop, then wake up any threads waiting
6492 6493           * to enter any of the IPSQ's associated with it.
6493 6494           */
6494 6495          if (emptied) {
6495 6496                  xopipsq = ipsq;
6496 6497                  do {
6497 6498                          if ((phyi = xopipsq->ipsq_phyint) == NULL)
6498 6499                                  continue;
6499 6500  
6500 6501                          illv4 = phyi->phyint_illv4;
6501 6502                          illv6 = phyi->phyint_illv6;
6502 6503  
6503 6504                          GRAB_ILL_LOCKS(illv4, illv6);
6504 6505                          if (illv4 != NULL)
6505 6506                                  cv_broadcast(&illv4->ill_cv);
6506 6507                          if (illv6 != NULL)
6507 6508                                  cv_broadcast(&illv6->ill_cv);
6508 6509                          RELEASE_ILL_LOCKS(illv4, illv6);
6509 6510                  } while ((xopipsq = xopipsq->ipsq_next) != ipsq);
6510 6511          }
6511 6512          rw_exit(&ipst->ips_ill_g_lock);
6512 6513  
6513 6514          /*
6514 6515           * Now that all locks are dropped, exit the IPSQ we left.
6515 6516           */
6516 6517          if (leftipsq != NULL)
6517 6518                  ipsq_exit(leftipsq);
6518 6519  
6519 6520          return (mp);
6520 6521  }
6521 6522  
6522 6523  /*
6523 6524   * Return completion status of previously initiated DLPI operations on
6524 6525   * ills in the purview of an ipsq.
6525 6526   */
6526 6527  static boolean_t
6527 6528  ipsq_dlpi_done(ipsq_t *ipsq)
6528 6529  {
6529 6530          ipsq_t          *ipsq_start;
6530 6531          phyint_t        *phyi;
6531 6532          ill_t           *ill;
6532 6533  
6533 6534          ASSERT(RW_LOCK_HELD(&ipsq->ipsq_ipst->ips_ill_g_lock));
6534 6535          ipsq_start = ipsq;
6535 6536  
6536 6537          do {
6537 6538                  /*
6538 6539                   * The only current users of this function are ipsq_try_enter
6539 6540                   * and ipsq_enter which have made sure that ipsq_writer is
6540 6541                   * NULL before we reach here. ill_dlpi_pending is modified
6541 6542                   * only by an ipsq writer
6542 6543                   */
6543 6544                  ASSERT(ipsq->ipsq_xop->ipx_writer == NULL);
6544 6545                  phyi = ipsq->ipsq_phyint;
6545 6546                  /*
6546 6547                   * phyi could be NULL if a phyint that is part of an
6547 6548                   * IPMP group is being unplumbed. A more detailed
6548 6549                   * comment is in ipmp_grp_update_kstats()
6549 6550                   */
6550 6551                  if (phyi != NULL) {
6551 6552                          ill = phyi->phyint_illv4;
6552 6553                          if (ill != NULL &&
6553 6554                              (ill->ill_dlpi_pending != DL_PRIM_INVAL ||
6554 6555                              ill->ill_arl_dlpi_pending))
6555 6556                                  return (B_FALSE);
6556 6557  
6557 6558                          ill = phyi->phyint_illv6;
6558 6559                          if (ill != NULL &&
6559 6560                              ill->ill_dlpi_pending != DL_PRIM_INVAL)
6560 6561                                  return (B_FALSE);
6561 6562                  }
6562 6563  
6563 6564          } while ((ipsq = ipsq->ipsq_next) != ipsq_start);
6564 6565  
6565 6566          return (B_TRUE);
6566 6567  }
6567 6568  
6568 6569  /*
6569 6570   * Enter the ipsq corresponding to ill, by waiting synchronously till
6570 6571   * we can enter the ipsq exclusively. Unless 'force' is used, the ipsq
6571 6572   * will have to drain completely before ipsq_enter returns success.
6572 6573   * ipx_current_ipif will be set if some exclusive op is in progress,
6573 6574   * and the ipsq_exit logic will start the next enqueued op after
6574 6575   * completion of the current op. If 'force' is used, we don't wait
6575 6576   * for the enqueued ops. This is needed when a conn_close wants to
6576 6577   * enter the ipsq and abort an ioctl that is somehow stuck. Unplumb
6577 6578   * of an ill can also use this option. But we dont' use it currently.
6578 6579   */
6579 6580  #define ENTER_SQ_WAIT_TICKS 100
6580 6581  boolean_t
6581 6582  ipsq_enter(ill_t *ill, boolean_t force, int type)
6582 6583  {
6583 6584          ipsq_t  *ipsq;
6584 6585          ipxop_t *ipx;
6585 6586          boolean_t waited_enough = B_FALSE;
6586 6587          ip_stack_t *ipst = ill->ill_ipst;
6587 6588  
6588 6589          /*
6589 6590           * Note that the relationship between ill and ipsq is fixed as long as
6590 6591           * the ill is not ILL_CONDEMNED.  Holding ipsq_lock ensures the
6591 6592           * relationship between the IPSQ and xop cannot change.  However,
6592 6593           * since we cannot hold ipsq_lock across the cv_wait(), it may change
6593 6594           * while we're waiting.  We wait on ill_cv and rely on ipsq_exit()
6594 6595           * waking up all ills in the xop when it becomes available.
6595 6596           */
6596 6597          for (;;) {
6597 6598                  rw_enter(&ipst->ips_ill_g_lock, RW_READER);
6598 6599                  mutex_enter(&ill->ill_lock);
6599 6600                  if (ill->ill_state_flags & ILL_CONDEMNED) {
6600 6601                          mutex_exit(&ill->ill_lock);
6601 6602                          rw_exit(&ipst->ips_ill_g_lock);
6602 6603                          return (B_FALSE);
6603 6604                  }
6604 6605  
6605 6606                  ipsq = ill->ill_phyint->phyint_ipsq;
6606 6607                  mutex_enter(&ipsq->ipsq_lock);
6607 6608                  ipx = ipsq->ipsq_xop;
6608 6609                  mutex_enter(&ipx->ipx_lock);
6609 6610  
6610 6611                  if (ipx->ipx_writer == NULL && (type == CUR_OP ||
6611 6612                      (ipx->ipx_current_ipif == NULL && ipsq_dlpi_done(ipsq)) ||
6612 6613                      waited_enough))
6613 6614                          break;
6614 6615  
6615 6616                  rw_exit(&ipst->ips_ill_g_lock);
6616 6617  
6617 6618                  if (!force || ipx->ipx_writer != NULL) {
6618 6619                          mutex_exit(&ipx->ipx_lock);
6619 6620                          mutex_exit(&ipsq->ipsq_lock);
6620 6621                          cv_wait(&ill->ill_cv, &ill->ill_lock);
6621 6622                  } else {
6622 6623                          mutex_exit(&ipx->ipx_lock);
6623 6624                          mutex_exit(&ipsq->ipsq_lock);
6624 6625                          (void) cv_reltimedwait(&ill->ill_cv,
6625 6626                              &ill->ill_lock, ENTER_SQ_WAIT_TICKS, TR_CLOCK_TICK);
6626 6627                          waited_enough = B_TRUE;
6627 6628                  }
6628 6629                  mutex_exit(&ill->ill_lock);
6629 6630          }
6630 6631  
6631 6632          ASSERT(ipx->ipx_mphead == NULL && ipx->ipx_mptail == NULL);
6632 6633          ASSERT(ipx->ipx_reentry_cnt == 0);
6633 6634          ipx->ipx_writer = curthread;
6634 6635          ipx->ipx_forced = (ipx->ipx_current_ipif != NULL);
6635 6636          ipx->ipx_reentry_cnt++;
6636 6637  #ifdef DEBUG
6637 6638          ipx->ipx_depth = getpcstack(ipx->ipx_stack, IPX_STACK_DEPTH);
6638 6639  #endif
6639 6640          mutex_exit(&ipx->ipx_lock);
6640 6641          mutex_exit(&ipsq->ipsq_lock);
6641 6642          mutex_exit(&ill->ill_lock);
6642 6643          rw_exit(&ipst->ips_ill_g_lock);
6643 6644  
6644 6645          return (B_TRUE);
6645 6646  }
6646 6647  
6647 6648  /*
6648 6649   * ipif_set_values() has a constraint that it cannot drop the ips_ill_g_lock
6649 6650   * across the call to the core interface ipsq_try_enter() and hence calls this
6650 6651   * function directly. This is explained more fully in ipif_set_values().
6651 6652   * In order to support the above constraint, ipsq_try_enter is implemented as
6652 6653   * a wrapper that grabs the ips_ill_g_lock and calls this function subsequently
6653 6654   */
6654 6655  static ipsq_t *
6655 6656  ipsq_try_enter_internal(ill_t *ill, queue_t *q, mblk_t *mp, ipsq_func_t func,
6656 6657      int type, boolean_t reentry_ok)
6657 6658  {
6658 6659          ipsq_t  *ipsq;
6659 6660          ipxop_t *ipx;
6660 6661          ip_stack_t *ipst = ill->ill_ipst;
6661 6662  
6662 6663          /*
6663 6664           * lock ordering:
6664 6665           * ill_g_lock -> conn_lock -> ill_lock -> ipsq_lock -> ipx_lock.
6665 6666           *
6666 6667           * ipx of an ipsq can't change when ipsq_lock is held.
6667 6668           */
6668 6669          ASSERT(RW_LOCK_HELD(&ipst->ips_ill_g_lock));
6669 6670          GRAB_CONN_LOCK(q);
6670 6671          mutex_enter(&ill->ill_lock);
6671 6672          ipsq = ill->ill_phyint->phyint_ipsq;
6672 6673          mutex_enter(&ipsq->ipsq_lock);
6673 6674          ipx = ipsq->ipsq_xop;
6674 6675          mutex_enter(&ipx->ipx_lock);
6675 6676  
6676 6677          /*
6677 6678           * 1. Enter the ipsq if we are already writer and reentry is ok.
6678 6679           *    (Note: If the caller does not specify reentry_ok then neither
6679 6680           *    'func' nor any of its callees must ever attempt to enter the ipsq
6680 6681           *    again. Otherwise it can lead to an infinite loop
6681 6682           * 2. Enter the ipsq if there is no current writer and this attempted
6682 6683           *    entry is part of the current operation
6683 6684           * 3. Enter the ipsq if there is no current writer and this is a new
6684 6685           *    operation and the operation queue is empty and there is no
6685 6686           *    operation currently in progress and if all previously initiated
6686 6687           *    DLPI operations have completed.
6687 6688           */
6688 6689          if ((ipx->ipx_writer == curthread && reentry_ok) ||
6689 6690              (ipx->ipx_writer == NULL && (type == CUR_OP || (type == NEW_OP &&
6690 6691              !ipx->ipx_ipsq_queued && ipx->ipx_current_ipif == NULL &&
6691 6692              ipsq_dlpi_done(ipsq))))) {
6692 6693                  /* Success. */
6693 6694                  ipx->ipx_reentry_cnt++;
6694 6695                  ipx->ipx_writer = curthread;
6695 6696                  ipx->ipx_forced = B_FALSE;
6696 6697                  mutex_exit(&ipx->ipx_lock);
6697 6698                  mutex_exit(&ipsq->ipsq_lock);
6698 6699                  mutex_exit(&ill->ill_lock);
6699 6700                  RELEASE_CONN_LOCK(q);
6700 6701  #ifdef DEBUG
6701 6702                  ipx->ipx_depth = getpcstack(ipx->ipx_stack, IPX_STACK_DEPTH);
6702 6703  #endif
6703 6704                  return (ipsq);
6704 6705          }
6705 6706  
6706 6707          if (func != NULL)
6707 6708                  ipsq_enq(ipsq, q, mp, func, type, ill);
6708 6709  
6709 6710          mutex_exit(&ipx->ipx_lock);
6710 6711          mutex_exit(&ipsq->ipsq_lock);
6711 6712          mutex_exit(&ill->ill_lock);
6712 6713          RELEASE_CONN_LOCK(q);
6713 6714          return (NULL);
6714 6715  }
6715 6716  
6716 6717  /*
6717 6718   * The ipsq_t (ipsq) is the synchronization data structure used to serialize
6718 6719   * certain critical operations like plumbing (i.e. most set ioctls), etc.
6719 6720   * There is one ipsq per phyint. The ipsq
6720 6721   * serializes exclusive ioctls issued by applications on a per ipsq basis in
6721 6722   * ipsq_xopq_mphead. It also protects against multiple threads executing in
6722 6723   * the ipsq. Responses from the driver pertain to the current ioctl (say a
6723 6724   * DL_BIND_ACK in response to a DL_BIND_REQ initiated as part of bringing
6724 6725   * up the interface) and are enqueued in ipx_mphead.
6725 6726   *
6726 6727   * If a thread does not want to reenter the ipsq when it is already writer,
6727 6728   * it must make sure that the specified reentry point to be called later
6728 6729   * when the ipsq is empty, nor any code path starting from the specified reentry
6729 6730   * point must never ever try to enter the ipsq again. Otherwise it can lead
6730 6731   * to an infinite loop. The reentry point ip_rput_dlpi_writer is an example.
6731 6732   * When the thread that is currently exclusive finishes, it (ipsq_exit)
6732 6733   * dequeues the requests waiting to become exclusive in ipx_mphead and calls
6733 6734   * the reentry point. When the list at ipx_mphead becomes empty ipsq_exit
6734 6735   * proceeds to dequeue the next ioctl in ipsq_xopq_mphead and start the next
6735 6736   * ioctl if the current ioctl has completed. If the current ioctl is still
6736 6737   * in progress it simply returns. The current ioctl could be waiting for
6737 6738   * a response from another module (the driver or could be waiting for
6738 6739   * the ipif/ill/ire refcnts to drop to zero. In such a case the ipx_pending_mp
6739 6740   * and ipx_pending_ipif are set. ipx_current_ipif is set throughout the
6740 6741   * execution of the ioctl and ipsq_exit does not start the next ioctl unless
6741 6742   * ipx_current_ipif is NULL which happens only once the ioctl is complete and
6742 6743   * all associated DLPI operations have completed.
6743 6744   */
6744 6745  
6745 6746  /*
6746 6747   * Try to enter the IPSQ corresponding to `ipif' or `ill' exclusively (`ipif'
6747 6748   * and `ill' cannot both be specified).  Returns a pointer to the entered IPSQ
6748 6749   * on success, or NULL on failure.  The caller ensures ipif/ill is valid by
6749 6750   * refholding it as necessary.  If the IPSQ cannot be entered and `func' is
6750 6751   * non-NULL, then `func' will be called back with `q' and `mp' once the IPSQ
6751 6752   * can be entered.  If `func' is NULL, then `q' and `mp' are ignored.
6752 6753   */
6753 6754  ipsq_t *
6754 6755  ipsq_try_enter(ipif_t *ipif, ill_t *ill, queue_t *q, mblk_t *mp,
6755 6756      ipsq_func_t func, int type, boolean_t reentry_ok)
6756 6757  {
6757 6758          ip_stack_t      *ipst;
6758 6759          ipsq_t          *ipsq;
6759 6760  
6760 6761          /* Only 1 of ipif or ill can be specified */
6761 6762          ASSERT((ipif != NULL) ^ (ill != NULL));
6762 6763  
6763 6764          if (ipif != NULL)
6764 6765                  ill = ipif->ipif_ill;
6765 6766          ipst = ill->ill_ipst;
6766 6767  
6767 6768          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
6768 6769          ipsq = ipsq_try_enter_internal(ill, q, mp, func, type, reentry_ok);
6769 6770          rw_exit(&ipst->ips_ill_g_lock);
6770 6771  
6771 6772          return (ipsq);
6772 6773  }
6773 6774  
6774 6775  /*
6775 6776   * Try to enter the IPSQ corresponding to `ill' as writer.  The caller ensures
6776 6777   * ill is valid by refholding it if necessary; we will refrele.  If the IPSQ
6777 6778   * cannot be entered, the mp is queued for completion.
6778 6779   */
6779 6780  void
6780 6781  qwriter_ip(ill_t *ill, queue_t *q, mblk_t *mp, ipsq_func_t func, int type,
6781 6782      boolean_t reentry_ok)
6782 6783  {
6783 6784          ipsq_t  *ipsq;
6784 6785  
6785 6786          ipsq = ipsq_try_enter(NULL, ill, q, mp, func, type, reentry_ok);
6786 6787  
6787 6788          /*
6788 6789           * Drop the caller's refhold on the ill.  This is safe since we either
6789 6790           * entered the IPSQ (and thus are exclusive), or failed to enter the
6790 6791           * IPSQ, in which case we return without accessing ill anymore.  This
6791 6792           * is needed because func needs to see the correct refcount.
6792 6793           * e.g. removeif can work only then.
6793 6794           */
6794 6795          ill_refrele(ill);
6795 6796          if (ipsq != NULL) {
6796 6797                  (*func)(ipsq, q, mp, NULL);
6797 6798                  ipsq_exit(ipsq);
6798 6799          }
6799 6800  }
6800 6801  
6801 6802  /*
6802 6803   * Exit the specified IPSQ.  If this is the final exit on it then drain it
6803 6804   * prior to exiting.  Caller must be writer on the specified IPSQ.
6804 6805   */
6805 6806  void
6806 6807  ipsq_exit(ipsq_t *ipsq)
6807 6808  {
6808 6809          mblk_t *mp;
6809 6810          ipsq_t *mp_ipsq;
6810 6811          queue_t *q;
6811 6812          phyint_t *phyi;
6812 6813          ipsq_func_t func;
6813 6814  
6814 6815          ASSERT(IAM_WRITER_IPSQ(ipsq));
6815 6816  
6816 6817          ASSERT(ipsq->ipsq_xop->ipx_reentry_cnt >= 1);
6817 6818          if (ipsq->ipsq_xop->ipx_reentry_cnt != 1) {
6818 6819                  ipsq->ipsq_xop->ipx_reentry_cnt--;
6819 6820                  return;
6820 6821          }
6821 6822  
6822 6823          for (;;) {
6823 6824                  phyi = ipsq->ipsq_phyint;
6824 6825                  mp = ipsq_dq(ipsq);
6825 6826                  mp_ipsq = (mp == NULL) ? NULL : (ipsq_t *)mp->b_next;
6826 6827  
6827 6828                  /*
6828 6829                   * If we've changed to a new IPSQ, and the phyint associated
6829 6830                   * with the old one has gone away, free the old IPSQ.  Note
6830 6831                   * that this cannot happen while the IPSQ is in a group.
6831 6832                   */
6832 6833                  if (mp_ipsq != ipsq && phyi == NULL) {
6833 6834                          ASSERT(ipsq->ipsq_next == ipsq);
6834 6835                          ASSERT(ipsq->ipsq_xop == &ipsq->ipsq_ownxop);
6835 6836                          ipsq_delete(ipsq);
6836 6837                  }
6837 6838  
6838 6839                  if (mp == NULL)
6839 6840                          break;
6840 6841  
6841 6842                  q = mp->b_queue;
6842 6843                  func = (ipsq_func_t)mp->b_prev;
6843 6844                  ipsq = mp_ipsq;
6844 6845                  mp->b_next = mp->b_prev = NULL;
6845 6846                  mp->b_queue = NULL;
6846 6847  
6847 6848                  /*
6848 6849                   * If 'q' is an conn queue, it is valid, since we did a
6849 6850                   * a refhold on the conn at the start of the ioctl.
6850 6851                   * If 'q' is an ill queue, it is valid, since close of an
6851 6852                   * ill will clean up its IPSQ.
6852 6853                   */
6853 6854                  (*func)(ipsq, q, mp, NULL);
6854 6855          }
6855 6856  }
6856 6857  
6857 6858  /*
6858 6859   * Used to start any igmp or mld timers that could not be started
6859 6860   * while holding ill_mcast_lock. The timers can't be started while holding
6860 6861   * the lock, since mld/igmp_start_timers may need to call untimeout()
6861 6862   * which can't be done while holding the lock which the timeout handler
6862 6863   * acquires. Otherwise
6863 6864   * there could be a deadlock since the timeout handlers
6864 6865   * mld_timeout_handler_per_ill/igmp_timeout_handler_per_ill also acquire
6865 6866   * ill_mcast_lock.
6866 6867   */
6867 6868  void
6868 6869  ill_mcast_timer_start(ip_stack_t *ipst)
6869 6870  {
6870 6871          int             next;
6871 6872  
6872 6873          mutex_enter(&ipst->ips_igmp_timer_lock);
6873 6874          next = ipst->ips_igmp_deferred_next;
6874 6875          ipst->ips_igmp_deferred_next = INFINITY;
6875 6876          mutex_exit(&ipst->ips_igmp_timer_lock);
6876 6877  
6877 6878          if (next != INFINITY)
6878 6879                  igmp_start_timers(next, ipst);
6879 6880  
6880 6881          mutex_enter(&ipst->ips_mld_timer_lock);
6881 6882          next = ipst->ips_mld_deferred_next;
6882 6883          ipst->ips_mld_deferred_next = INFINITY;
6883 6884          mutex_exit(&ipst->ips_mld_timer_lock);
6884 6885  
6885 6886          if (next != INFINITY)
6886 6887                  mld_start_timers(next, ipst);
6887 6888  }
6888 6889  
6889 6890  /*
6890 6891   * Start the current exclusive operation on `ipsq'; associate it with `ipif'
6891 6892   * and `ioccmd'.
6892 6893   */
6893 6894  void
6894 6895  ipsq_current_start(ipsq_t *ipsq, ipif_t *ipif, int ioccmd)
6895 6896  {
6896 6897          ill_t *ill = ipif->ipif_ill;
6897 6898          ipxop_t *ipx = ipsq->ipsq_xop;
6898 6899  
6899 6900          ASSERT(IAM_WRITER_IPSQ(ipsq));
6900 6901          ASSERT(ipx->ipx_current_ipif == NULL);
6901 6902          ASSERT(ipx->ipx_current_ioctl == 0);
6902 6903  
6903 6904          ipx->ipx_current_done = B_FALSE;
6904 6905          ipx->ipx_current_ioctl = ioccmd;
6905 6906          mutex_enter(&ipx->ipx_lock);
6906 6907          ipx->ipx_current_ipif = ipif;
6907 6908          mutex_exit(&ipx->ipx_lock);
6908 6909  
6909 6910          /*
6910 6911           * Set IPIF_CHANGING on one or more ipifs associated with the
6911 6912           * current exclusive operation.  IPIF_CHANGING prevents any new
6912 6913           * references to the ipif (so that the references will eventually
6913 6914           * drop to zero) and also prevents any "get" operations (e.g.,
6914 6915           * SIOCGLIFFLAGS) from being able to access the ipif until the
6915 6916           * operation has completed and the ipif is again in a stable state.
6916 6917           *
6917 6918           * For ioctls, IPIF_CHANGING is set on the ipif associated with the
6918 6919           * ioctl.  For internal operations (where ioccmd is zero), all ipifs
6919 6920           * on the ill are marked with IPIF_CHANGING since it's unclear which
6920 6921           * ipifs will be affected.
6921 6922           *
6922 6923           * Note that SIOCLIFREMOVEIF is a special case as it sets
6923 6924           * IPIF_CONDEMNED internally after identifying the right ipif to
6924 6925           * operate on.
6925 6926           */
6926 6927          switch (ioccmd) {
6927 6928          case SIOCLIFREMOVEIF:
6928 6929                  break;
6929 6930          case 0:
6930 6931                  mutex_enter(&ill->ill_lock);
6931 6932                  ipif = ipif->ipif_ill->ill_ipif;
6932 6933                  for (; ipif != NULL; ipif = ipif->ipif_next)
6933 6934                          ipif->ipif_state_flags |= IPIF_CHANGING;
6934 6935                  mutex_exit(&ill->ill_lock);
6935 6936                  break;
6936 6937          default:
6937 6938                  mutex_enter(&ill->ill_lock);
6938 6939                  ipif->ipif_state_flags |= IPIF_CHANGING;
6939 6940                  mutex_exit(&ill->ill_lock);
6940 6941          }
6941 6942  }
6942 6943  
6943 6944  /*
6944 6945   * Finish the current exclusive operation on `ipsq'.  Usually, this will allow
6945 6946   * the next exclusive operation to begin once we ipsq_exit().  However, if
6946 6947   * pending DLPI operations remain, then we will wait for the queue to drain
6947 6948   * before allowing the next exclusive operation to begin.  This ensures that
6948 6949   * DLPI operations from one exclusive operation are never improperly processed
6949 6950   * as part of a subsequent exclusive operation.
6950 6951   */
6951 6952  void
6952 6953  ipsq_current_finish(ipsq_t *ipsq)
6953 6954  {
6954 6955          ipxop_t *ipx = ipsq->ipsq_xop;
6955 6956          t_uscalar_t dlpi_pending = DL_PRIM_INVAL;
6956 6957          ipif_t  *ipif = ipx->ipx_current_ipif;
6957 6958  
6958 6959          ASSERT(IAM_WRITER_IPSQ(ipsq));
6959 6960  
6960 6961          /*
6961 6962           * For SIOCLIFREMOVEIF, the ipif has been already been blown away
6962 6963           * (but in that case, IPIF_CHANGING will already be clear and no
6963 6964           * pending DLPI messages can remain).
6964 6965           */
6965 6966          if (ipx->ipx_current_ioctl != SIOCLIFREMOVEIF) {
6966 6967                  ill_t *ill = ipif->ipif_ill;
6967 6968  
6968 6969                  mutex_enter(&ill->ill_lock);
6969 6970                  dlpi_pending = ill->ill_dlpi_pending;
6970 6971                  if (ipx->ipx_current_ioctl == 0) {
6971 6972                          ipif = ill->ill_ipif;
6972 6973                          for (; ipif != NULL; ipif = ipif->ipif_next)
6973 6974                                  ipif->ipif_state_flags &= ~IPIF_CHANGING;
6974 6975                  } else {
6975 6976                          ipif->ipif_state_flags &= ~IPIF_CHANGING;
6976 6977                  }
6977 6978                  mutex_exit(&ill->ill_lock);
6978 6979          }
6979 6980  
6980 6981          ASSERT(!ipx->ipx_current_done);
6981 6982          ipx->ipx_current_done = B_TRUE;
6982 6983          ipx->ipx_current_ioctl = 0;
6983 6984          if (dlpi_pending == DL_PRIM_INVAL) {
6984 6985                  mutex_enter(&ipx->ipx_lock);
6985 6986                  ipx->ipx_current_ipif = NULL;
6986 6987                  mutex_exit(&ipx->ipx_lock);
6987 6988          }
6988 6989  }
6989 6990  
6990 6991  /*
6991 6992   * The ill is closing. Flush all messages on the ipsq that originated
6992 6993   * from this ill. Usually there wont' be any messages on the ipsq_xopq_mphead
6993 6994   * for this ill since ipsq_enter could not have entered until then.
6994 6995   * New messages can't be queued since the CONDEMNED flag is set.
6995 6996   */
6996 6997  static void
6997 6998  ipsq_flush(ill_t *ill)
6998 6999  {
6999 7000          queue_t *q;
7000 7001          mblk_t  *prev;
7001 7002          mblk_t  *mp;
7002 7003          mblk_t  *mp_next;
7003 7004          ipxop_t *ipx = ill->ill_phyint->phyint_ipsq->ipsq_xop;
7004 7005  
7005 7006          ASSERT(IAM_WRITER_ILL(ill));
7006 7007  
7007 7008          /*
7008 7009           * Flush any messages sent up by the driver.
7009 7010           */
7010 7011          mutex_enter(&ipx->ipx_lock);
7011 7012          for (prev = NULL, mp = ipx->ipx_mphead; mp != NULL; mp = mp_next) {
7012 7013                  mp_next = mp->b_next;
7013 7014                  q = mp->b_queue;
7014 7015                  if (q == ill->ill_rq || q == ill->ill_wq) {
7015 7016                          /* dequeue mp */
7016 7017                          if (prev == NULL)
7017 7018                                  ipx->ipx_mphead = mp->b_next;
7018 7019                          else
7019 7020                                  prev->b_next = mp->b_next;
7020 7021                          if (ipx->ipx_mptail == mp) {
7021 7022                                  ASSERT(mp_next == NULL);
7022 7023                                  ipx->ipx_mptail = prev;
7023 7024                          }
7024 7025                          inet_freemsg(mp);
7025 7026                  } else {
7026 7027                          prev = mp;
7027 7028                  }
7028 7029          }
7029 7030          mutex_exit(&ipx->ipx_lock);
7030 7031          (void) ipsq_pending_mp_cleanup(ill, NULL);
7031 7032          ipsq_xopq_mp_cleanup(ill, NULL);
7032 7033  }
7033 7034  
7034 7035  /*
7035 7036   * Parse an ifreq or lifreq struct coming down ioctls and refhold
7036 7037   * and return the associated ipif.
7037 7038   * Return value:
7038 7039   *      Non zero: An error has occurred. ci may not be filled out.
7039 7040   *      zero : ci is filled out with the ioctl cmd in ci.ci_name, and
7040 7041   *      a held ipif in ci.ci_ipif.
7041 7042   */
7042 7043  int
7043 7044  ip_extract_lifreq(queue_t *q, mblk_t *mp, const ip_ioctl_cmd_t *ipip,
7044 7045      cmd_info_t *ci)
7045 7046  {
7046 7047          char            *name;
7047 7048          struct ifreq    *ifr;
7048 7049          struct lifreq    *lifr;
7049 7050          ipif_t          *ipif = NULL;
7050 7051          ill_t           *ill;
7051 7052          conn_t          *connp;
7052 7053          boolean_t       isv6;
7053 7054          int             err;
7054 7055          mblk_t          *mp1;
7055 7056          zoneid_t        zoneid;
7056 7057          ip_stack_t      *ipst;
7057 7058  
7058 7059          if (q->q_next != NULL) {
7059 7060                  ill = (ill_t *)q->q_ptr;
7060 7061                  isv6 = ill->ill_isv6;
7061 7062                  connp = NULL;
7062 7063                  zoneid = ALL_ZONES;
7063 7064                  ipst = ill->ill_ipst;
7064 7065          } else {
7065 7066                  ill = NULL;
7066 7067                  connp = Q_TO_CONN(q);
7067 7068                  isv6 = (connp->conn_family == AF_INET6);
7068 7069                  zoneid = connp->conn_zoneid;
7069 7070                  if (zoneid == GLOBAL_ZONEID) {
7070 7071                          /* global zone can access ipifs in all zones */
7071 7072                          zoneid = ALL_ZONES;
7072 7073                  }
7073 7074                  ipst = connp->conn_netstack->netstack_ip;
7074 7075          }
7075 7076  
7076 7077          /* Has been checked in ip_wput_nondata */
7077 7078          mp1 = mp->b_cont->b_cont;
7078 7079  
7079 7080          if (ipip->ipi_cmd_type == IF_CMD) {
7080 7081                  /* This a old style SIOC[GS]IF* command */
7081 7082                  ifr = (struct ifreq *)mp1->b_rptr;
7082 7083                  /*
7083 7084                   * Null terminate the string to protect against buffer
7084 7085                   * overrun. String was generated by user code and may not
7085 7086                   * be trusted.
7086 7087                   */
7087 7088                  ifr->ifr_name[IFNAMSIZ - 1] = '\0';
7088 7089                  name = ifr->ifr_name;
7089 7090                  ci->ci_sin = (sin_t *)&ifr->ifr_addr;
7090 7091                  ci->ci_sin6 = NULL;
7091 7092                  ci->ci_lifr = (struct lifreq *)ifr;
7092 7093          } else {
7093 7094                  /* This a new style SIOC[GS]LIF* command */
7094 7095                  ASSERT(ipip->ipi_cmd_type == LIF_CMD);
7095 7096                  lifr = (struct lifreq *)mp1->b_rptr;
7096 7097                  /*
7097 7098                   * Null terminate the string to protect against buffer
7098 7099                   * overrun. String was generated by user code and may not
7099 7100                   * be trusted.
7100 7101                   */
7101 7102                  lifr->lifr_name[LIFNAMSIZ - 1] = '\0';
7102 7103                  name = lifr->lifr_name;
7103 7104                  ci->ci_sin = (sin_t *)&lifr->lifr_addr;
7104 7105                  ci->ci_sin6 = (sin6_t *)&lifr->lifr_addr;
7105 7106                  ci->ci_lifr = lifr;
7106 7107          }
7107 7108  
7108 7109          if (ipip->ipi_cmd == SIOCSLIFNAME) {
7109 7110                  /*
7110 7111                   * The ioctl will be failed if the ioctl comes down
7111 7112                   * an conn stream
7112 7113                   */
7113 7114                  if (ill == NULL) {
7114 7115                          /*
7115 7116                           * Not an ill queue, return EINVAL same as the
7116 7117                           * old error code.
7117 7118                           */
7118 7119                          return (ENXIO);
7119 7120                  }
7120 7121                  ipif = ill->ill_ipif;
7121 7122                  ipif_refhold(ipif);
7122 7123          } else {
7123 7124                  /*
7124 7125                   * Ensure that ioctls don't see any internal state changes
7125 7126                   * caused by set ioctls by deferring them if IPIF_CHANGING is
7126 7127                   * set.
7127 7128                   */
7128 7129                  ipif = ipif_lookup_on_name_async(name, mi_strlen(name),
7129 7130                      isv6, zoneid, q, mp, ip_process_ioctl, &err, ipst);
7130 7131                  if (ipif == NULL) {
7131 7132                          if (err == EINPROGRESS)
7132 7133                                  return (err);
7133 7134                          err = 0;        /* Ensure we don't use it below */
7134 7135                  }
7135 7136          }
7136 7137  
7137 7138          /*
7138 7139           * Old style [GS]IFCMD does not admit IPv6 ipif
7139 7140           */
7140 7141          if (ipif != NULL && ipif->ipif_isv6 && ipip->ipi_cmd_type == IF_CMD) {
7141 7142                  ipif_refrele(ipif);
7142 7143                  return (ENXIO);
7143 7144          }
7144 7145  
7145 7146          if (ipif == NULL && ill != NULL && ill->ill_ipif != NULL &&
7146 7147              name[0] == '\0') {
7147 7148                  /*
7148 7149                   * Handle a or a SIOC?IF* with a null name
7149 7150                   * during plumb (on the ill queue before the I_PLINK).
7150 7151                   */
7151 7152                  ipif = ill->ill_ipif;
7152 7153                  ipif_refhold(ipif);
7153 7154          }
7154 7155  
7155 7156          if (ipif == NULL)
7156 7157                  return (ENXIO);
7157 7158  
7158 7159          DTRACE_PROBE4(ipif__ioctl, char *, "ip_extract_lifreq",
7159 7160              int, ipip->ipi_cmd, ill_t *, ipif->ipif_ill, ipif_t *, ipif);
7160 7161  
7161 7162          ci->ci_ipif = ipif;
7162 7163          return (0);
7163 7164  }
7164 7165  
7165 7166  /*
7166 7167   * Return the total number of ipifs.
7167 7168   */
7168 7169  static uint_t
7169 7170  ip_get_numifs(zoneid_t zoneid, ip_stack_t *ipst)
7170 7171  {
7171 7172          uint_t numifs = 0;
7172 7173          ill_t   *ill;
7173 7174          ill_walk_context_t      ctx;
7174 7175          ipif_t  *ipif;
7175 7176  
7176 7177          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
7177 7178          ill = ILL_START_WALK_V4(&ctx, ipst);
7178 7179          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
7179 7180                  if (IS_UNDER_IPMP(ill))
7180 7181                          continue;
7181 7182                  for (ipif = ill->ill_ipif; ipif != NULL;
7182 7183                      ipif = ipif->ipif_next) {
7183 7184                          if (ipif->ipif_zoneid == zoneid ||
7184 7185                              ipif->ipif_zoneid == ALL_ZONES)
7185 7186                                  numifs++;
7186 7187                  }
7187 7188          }
7188 7189          rw_exit(&ipst->ips_ill_g_lock);
7189 7190          return (numifs);
7190 7191  }
7191 7192  
7192 7193  /*
7193 7194   * Return the total number of ipifs.
7194 7195   */
7195 7196  static uint_t
7196 7197  ip_get_numlifs(int family, int lifn_flags, zoneid_t zoneid, ip_stack_t *ipst)
7197 7198  {
7198 7199          uint_t numifs = 0;
7199 7200          ill_t   *ill;
7200 7201          ipif_t  *ipif;
7201 7202          ill_walk_context_t      ctx;
7202 7203  
7203 7204          ip1dbg(("ip_get_numlifs(%d %u %d)\n", family, lifn_flags, (int)zoneid));
7204 7205  
7205 7206          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
7206 7207          if (family == AF_INET)
7207 7208                  ill = ILL_START_WALK_V4(&ctx, ipst);
7208 7209          else if (family == AF_INET6)
7209 7210                  ill = ILL_START_WALK_V6(&ctx, ipst);
7210 7211          else
7211 7212                  ill = ILL_START_WALK_ALL(&ctx, ipst);
7212 7213  
7213 7214          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
7214 7215                  if (IS_UNDER_IPMP(ill) && !(lifn_flags & LIFC_UNDER_IPMP))
7215 7216                          continue;
7216 7217  
7217 7218                  for (ipif = ill->ill_ipif; ipif != NULL;
7218 7219                      ipif = ipif->ipif_next) {
7219 7220                          if ((ipif->ipif_flags & IPIF_NOXMIT) &&
7220 7221                              !(lifn_flags & LIFC_NOXMIT))
7221 7222                                  continue;
7222 7223                          if ((ipif->ipif_flags & IPIF_TEMPORARY) &&
7223 7224                              !(lifn_flags & LIFC_TEMPORARY))
7224 7225                                  continue;
7225 7226                          if (((ipif->ipif_flags &
7226 7227                              (IPIF_NOXMIT|IPIF_NOLOCAL|
7227 7228                              IPIF_DEPRECATED)) ||
7228 7229                              IS_LOOPBACK(ill) ||
7229 7230                              !(ipif->ipif_flags & IPIF_UP)) &&
7230 7231                              (lifn_flags & LIFC_EXTERNAL_SOURCE))
7231 7232                                  continue;
7232 7233  
7233 7234                          if (zoneid != ipif->ipif_zoneid &&
7234 7235                              ipif->ipif_zoneid != ALL_ZONES &&
7235 7236                              (zoneid != GLOBAL_ZONEID ||
7236 7237                              !(lifn_flags & LIFC_ALLZONES)))
7237 7238                                  continue;
7238 7239  
7239 7240                          numifs++;
7240 7241                  }
7241 7242          }
7242 7243          rw_exit(&ipst->ips_ill_g_lock);
7243 7244          return (numifs);
7244 7245  }
7245 7246  
7246 7247  uint_t
7247 7248  ip_get_lifsrcofnum(ill_t *ill)
7248 7249  {
7249 7250          uint_t numifs = 0;
7250 7251          ill_t   *ill_head = ill;
7251 7252          ip_stack_t      *ipst = ill->ill_ipst;
7252 7253  
7253 7254          /*
7254 7255           * ill_g_usesrc_lock protects ill_usesrc_grp_next, for example, some
7255 7256           * other thread may be trying to relink the ILLs in this usesrc group
7256 7257           * and adjusting the ill_usesrc_grp_next pointers
7257 7258           */
7258 7259          rw_enter(&ipst->ips_ill_g_usesrc_lock, RW_READER);
7259 7260          if ((ill->ill_usesrc_ifindex == 0) &&
7260 7261              (ill->ill_usesrc_grp_next != NULL)) {
7261 7262                  for (; (ill != NULL) && (ill->ill_usesrc_grp_next != ill_head);
7262 7263                      ill = ill->ill_usesrc_grp_next)
7263 7264                          numifs++;
7264 7265          }
7265 7266          rw_exit(&ipst->ips_ill_g_usesrc_lock);
7266 7267  
7267 7268          return (numifs);
7268 7269  }
7269 7270  
7270 7271  /* Null values are passed in for ipif, sin, and ifreq */
7271 7272  /* ARGSUSED */
7272 7273  int
7273 7274  ip_sioctl_get_ifnum(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
7274 7275      mblk_t *mp, ip_ioctl_cmd_t *ipip, void *ifreq)
7275 7276  {
7276 7277          int *nump;
7277 7278          conn_t *connp = Q_TO_CONN(q);
7278 7279  
7279 7280          ASSERT(q->q_next == NULL); /* not a valid ioctl for ip as a module */
7280 7281  
7281 7282          /* Existence of b_cont->b_cont checked in ip_wput_nondata */
7282 7283          nump = (int *)mp->b_cont->b_cont->b_rptr;
7283 7284  
7284 7285          *nump = ip_get_numifs(connp->conn_zoneid,
7285 7286              connp->conn_netstack->netstack_ip);
7286 7287          ip1dbg(("ip_sioctl_get_ifnum numifs %d", *nump));
7287 7288          return (0);
7288 7289  }
7289 7290  
7290 7291  /* Null values are passed in for ipif, sin, and ifreq */
7291 7292  /* ARGSUSED */
7292 7293  int
7293 7294  ip_sioctl_get_lifnum(ipif_t *dummy_ipif, sin_t *dummy_sin,
7294 7295      queue_t *q, mblk_t *mp, ip_ioctl_cmd_t *ipip, void *ifreq)
7295 7296  {
7296 7297          struct lifnum *lifn;
7297 7298          mblk_t  *mp1;
7298 7299          conn_t *connp = Q_TO_CONN(q);
7299 7300  
7300 7301          ASSERT(q->q_next == NULL); /* not a valid ioctl for ip as a module */
7301 7302  
7302 7303          /* Existence checked in ip_wput_nondata */
7303 7304          mp1 = mp->b_cont->b_cont;
7304 7305  
7305 7306          lifn = (struct lifnum *)mp1->b_rptr;
7306 7307          switch (lifn->lifn_family) {
7307 7308          case AF_UNSPEC:
7308 7309          case AF_INET:
7309 7310          case AF_INET6:
7310 7311                  break;
7311 7312          default:
7312 7313                  return (EAFNOSUPPORT);
7313 7314          }
7314 7315  
7315 7316          lifn->lifn_count = ip_get_numlifs(lifn->lifn_family, lifn->lifn_flags,
7316 7317              connp->conn_zoneid, connp->conn_netstack->netstack_ip);
7317 7318          ip1dbg(("ip_sioctl_get_lifnum numifs %d", lifn->lifn_count));
7318 7319          return (0);
7319 7320  }
7320 7321  
7321 7322  /* ARGSUSED */
7322 7323  int
7323 7324  ip_sioctl_get_ifconf(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
7324 7325      mblk_t *mp, ip_ioctl_cmd_t *ipip, void *ifreq)
7325 7326  {
7326 7327          STRUCT_HANDLE(ifconf, ifc);
7327 7328          mblk_t *mp1;
7328 7329          struct iocblk *iocp;
7329 7330          struct ifreq *ifr;
7330 7331          ill_walk_context_t      ctx;
7331 7332          ill_t   *ill;
7332 7333          ipif_t  *ipif;
7333 7334          struct sockaddr_in *sin;
7334 7335          int32_t ifclen;
7335 7336          zoneid_t zoneid;
7336 7337          ip_stack_t *ipst = CONNQ_TO_IPST(q);
7337 7338  
7338 7339          ASSERT(q->q_next == NULL); /* not valid ioctls for ip as a module */
7339 7340  
7340 7341          ip1dbg(("ip_sioctl_get_ifconf"));
7341 7342          /* Existence verified in ip_wput_nondata */
7342 7343          mp1 = mp->b_cont->b_cont;
7343 7344          iocp = (struct iocblk *)mp->b_rptr;
7344 7345          zoneid = Q_TO_CONN(q)->conn_zoneid;
7345 7346  
7346 7347          /*
7347 7348           * The original SIOCGIFCONF passed in a struct ifconf which specified
7348 7349           * the user buffer address and length into which the list of struct
7349 7350           * ifreqs was to be copied.  Since AT&T Streams does not seem to
7350 7351           * allow M_COPYOUT to be used in conjunction with I_STR IOCTLS,
7351 7352           * the SIOCGIFCONF operation was redefined to simply provide
7352 7353           * a large output buffer into which we are supposed to jam the ifreq
7353 7354           * array.  The same ioctl command code was used, despite the fact that
7354 7355           * both the applications and the kernel code had to change, thus making
7355 7356           * it impossible to support both interfaces.
7356 7357           *
7357 7358           * For reasons not good enough to try to explain, the following
7358 7359           * algorithm is used for deciding what to do with one of these:
7359 7360           * If the IOCTL comes in as an I_STR, it is assumed to be of the new
7360 7361           * form with the output buffer coming down as the continuation message.
7361 7362           * If it arrives as a TRANSPARENT IOCTL, it is assumed to be old style,
7362 7363           * and we have to copy in the ifconf structure to find out how big the
7363 7364           * output buffer is and where to copy out to.  Sure no problem...
7364 7365           *
7365 7366           */
7366 7367          STRUCT_SET_HANDLE(ifc, iocp->ioc_flag, NULL);
7367 7368          if ((mp1->b_wptr - mp1->b_rptr) == STRUCT_SIZE(ifc)) {
7368 7369                  int numifs = 0;
7369 7370                  size_t ifc_bufsize;
7370 7371  
7371 7372                  /*
7372 7373                   * Must be (better be!) continuation of a TRANSPARENT
7373 7374                   * IOCTL.  We just copied in the ifconf structure.
7374 7375                   */
7375 7376                  STRUCT_SET_HANDLE(ifc, iocp->ioc_flag,
7376 7377                      (struct ifconf *)mp1->b_rptr);
7377 7378  
7378 7379                  /*
7379 7380                   * Allocate a buffer to hold requested information.
7380 7381                   *
7381 7382                   * If ifc_len is larger than what is needed, we only
7382 7383                   * allocate what we will use.
7383 7384                   *
7384 7385                   * If ifc_len is smaller than what is needed, return
7385 7386                   * EINVAL.
7386 7387                   *
7387 7388                   * XXX: the ill_t structure can hava 2 counters, for
7388 7389                   * v4 and v6 (not just ill_ipif_up_count) to store the
7389 7390                   * number of interfaces for a device, so we don't need
7390 7391                   * to count them here...
7391 7392                   */
7392 7393                  numifs = ip_get_numifs(zoneid, ipst);
7393 7394  
7394 7395                  ifclen = STRUCT_FGET(ifc, ifc_len);
7395 7396                  ifc_bufsize = numifs * sizeof (struct ifreq);
7396 7397                  if (ifc_bufsize > ifclen) {
7397 7398                          if (iocp->ioc_cmd == O_SIOCGIFCONF) {
7398 7399                                  /* old behaviour */
7399 7400                                  return (EINVAL);
7400 7401                          } else {
7401 7402                                  ifc_bufsize = ifclen;
7402 7403                          }
7403 7404                  }
7404 7405  
7405 7406                  mp1 = mi_copyout_alloc(q, mp,
7406 7407                      STRUCT_FGETP(ifc, ifc_buf), ifc_bufsize, B_FALSE);
7407 7408                  if (mp1 == NULL)
7408 7409                          return (ENOMEM);
7409 7410  
7410 7411                  mp1->b_wptr = mp1->b_rptr + ifc_bufsize;
7411 7412          }
7412 7413          bzero(mp1->b_rptr, mp1->b_wptr - mp1->b_rptr);
7413 7414          /*
7414 7415           * the SIOCGIFCONF ioctl only knows about
7415 7416           * IPv4 addresses, so don't try to tell
7416 7417           * it about interfaces with IPv6-only
7417 7418           * addresses. (Last parm 'isv6' is B_FALSE)
7418 7419           */
7419 7420  
7420 7421          ifr = (struct ifreq *)mp1->b_rptr;
7421 7422  
7422 7423          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
7423 7424          ill = ILL_START_WALK_V4(&ctx, ipst);
7424 7425          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
7425 7426                  if (IS_UNDER_IPMP(ill))
7426 7427                          continue;
7427 7428                  for (ipif = ill->ill_ipif; ipif != NULL;
7428 7429                      ipif = ipif->ipif_next) {
7429 7430                          if (zoneid != ipif->ipif_zoneid &&
7430 7431                              ipif->ipif_zoneid != ALL_ZONES)
7431 7432                                  continue;
7432 7433                          if ((uchar_t *)&ifr[1] > mp1->b_wptr) {
7433 7434                                  if (iocp->ioc_cmd == O_SIOCGIFCONF) {
7434 7435                                          /* old behaviour */
7435 7436                                          rw_exit(&ipst->ips_ill_g_lock);
7436 7437                                          return (EINVAL);
7437 7438                                  } else {
7438 7439                                          goto if_copydone;
7439 7440                                  }
7440 7441                          }
7441 7442                          ipif_get_name(ipif, ifr->ifr_name,
7442 7443                              sizeof (ifr->ifr_name));
7443 7444                          sin = (sin_t *)&ifr->ifr_addr;
7444 7445                          *sin = sin_null;
7445 7446                          sin->sin_family = AF_INET;
7446 7447                          sin->sin_addr.s_addr = ipif->ipif_lcl_addr;
7447 7448                          ifr++;
7448 7449                  }
7449 7450          }
7450 7451  if_copydone:
7451 7452          rw_exit(&ipst->ips_ill_g_lock);
7452 7453          mp1->b_wptr = (uchar_t *)ifr;
7453 7454  
7454 7455          if (STRUCT_BUF(ifc) != NULL) {
7455 7456                  STRUCT_FSET(ifc, ifc_len,
7456 7457                      (int)((uchar_t *)ifr - mp1->b_rptr));
7457 7458          }
7458 7459          return (0);
7459 7460  }
7460 7461  
7461 7462  /*
7462 7463   * Get the interfaces using the address hosted on the interface passed in,
7463 7464   * as a source adddress
7464 7465   */
7465 7466  /* ARGSUSED */
7466 7467  int
7467 7468  ip_sioctl_get_lifsrcof(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
7468 7469      mblk_t *mp, ip_ioctl_cmd_t *ipip, void *ifreq)
7469 7470  {
7470 7471          mblk_t *mp1;
7471 7472          ill_t   *ill, *ill_head;
7472 7473          ipif_t  *ipif, *orig_ipif;
7473 7474          int     numlifs = 0;
7474 7475          size_t  lifs_bufsize, lifsmaxlen;
7475 7476          struct  lifreq *lifr;
7476 7477          struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
7477 7478          uint_t  ifindex;
7478 7479          zoneid_t zoneid;
7479 7480          boolean_t isv6 = B_FALSE;
7480 7481          struct  sockaddr_in     *sin;
7481 7482          struct  sockaddr_in6    *sin6;
7482 7483          STRUCT_HANDLE(lifsrcof, lifs);
7483 7484          ip_stack_t              *ipst;
7484 7485  
7485 7486          ipst = CONNQ_TO_IPST(q);
7486 7487  
7487 7488          ASSERT(q->q_next == NULL);
7488 7489  
7489 7490          zoneid = Q_TO_CONN(q)->conn_zoneid;
7490 7491  
7491 7492          /* Existence verified in ip_wput_nondata */
7492 7493          mp1 = mp->b_cont->b_cont;
7493 7494  
7494 7495          /*
7495 7496           * Must be (better be!) continuation of a TRANSPARENT
7496 7497           * IOCTL.  We just copied in the lifsrcof structure.
7497 7498           */
7498 7499          STRUCT_SET_HANDLE(lifs, iocp->ioc_flag,
7499 7500              (struct lifsrcof *)mp1->b_rptr);
7500 7501  
7501 7502          if (MBLKL(mp1) != STRUCT_SIZE(lifs))
7502 7503                  return (EINVAL);
7503 7504  
7504 7505          ifindex = STRUCT_FGET(lifs, lifs_ifindex);
7505 7506          isv6 = (Q_TO_CONN(q))->conn_family == AF_INET6;
7506 7507          ipif = ipif_lookup_on_ifindex(ifindex, isv6, zoneid, ipst);
7507 7508          if (ipif == NULL) {
7508 7509                  ip1dbg(("ip_sioctl_get_lifsrcof: no ipif for ifindex %d\n",
7509 7510                      ifindex));
7510 7511                  return (ENXIO);
7511 7512          }
7512 7513  
7513 7514          /* Allocate a buffer to hold requested information */
7514 7515          numlifs = ip_get_lifsrcofnum(ipif->ipif_ill);
7515 7516          lifs_bufsize = numlifs * sizeof (struct lifreq);
7516 7517          lifsmaxlen =  STRUCT_FGET(lifs, lifs_maxlen);
7517 7518          /* The actual size needed is always returned in lifs_len */
7518 7519          STRUCT_FSET(lifs, lifs_len, lifs_bufsize);
7519 7520  
7520 7521          /* If the amount we need is more than what is passed in, abort */
7521 7522          if (lifs_bufsize > lifsmaxlen || lifs_bufsize == 0) {
7522 7523                  ipif_refrele(ipif);
7523 7524                  return (0);
7524 7525          }
7525 7526  
7526 7527          mp1 = mi_copyout_alloc(q, mp,
7527 7528              STRUCT_FGETP(lifs, lifs_buf), lifs_bufsize, B_FALSE);
7528 7529          if (mp1 == NULL) {
7529 7530                  ipif_refrele(ipif);
7530 7531                  return (ENOMEM);
7531 7532          }
7532 7533  
7533 7534          mp1->b_wptr = mp1->b_rptr + lifs_bufsize;
7534 7535          bzero(mp1->b_rptr, lifs_bufsize);
7535 7536  
7536 7537          lifr = (struct lifreq *)mp1->b_rptr;
7537 7538  
7538 7539          ill = ill_head = ipif->ipif_ill;
7539 7540          orig_ipif = ipif;
7540 7541  
7541 7542          /* ill_g_usesrc_lock protects ill_usesrc_grp_next */
7542 7543          rw_enter(&ipst->ips_ill_g_usesrc_lock, RW_READER);
7543 7544          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
7544 7545  
7545 7546          ill = ill->ill_usesrc_grp_next; /* start from next ill */
7546 7547          for (; (ill != NULL) && (ill != ill_head);
7547 7548              ill = ill->ill_usesrc_grp_next) {
7548 7549  
7549 7550                  if ((uchar_t *)&lifr[1] > mp1->b_wptr)
7550 7551                          break;
7551 7552  
7552 7553                  ipif = ill->ill_ipif;
7553 7554                  ipif_get_name(ipif, lifr->lifr_name, sizeof (lifr->lifr_name));
7554 7555                  if (ipif->ipif_isv6) {
7555 7556                          sin6 = (sin6_t *)&lifr->lifr_addr;
7556 7557                          *sin6 = sin6_null;
7557 7558                          sin6->sin6_family = AF_INET6;
7558 7559                          sin6->sin6_addr = ipif->ipif_v6lcl_addr;
7559 7560                          lifr->lifr_addrlen = ip_mask_to_plen_v6(
7560 7561                              &ipif->ipif_v6net_mask);
7561 7562                  } else {
7562 7563                          sin = (sin_t *)&lifr->lifr_addr;
7563 7564                          *sin = sin_null;
7564 7565                          sin->sin_family = AF_INET;
7565 7566                          sin->sin_addr.s_addr = ipif->ipif_lcl_addr;
7566 7567                          lifr->lifr_addrlen = ip_mask_to_plen(
7567 7568                              ipif->ipif_net_mask);
7568 7569                  }
7569 7570                  lifr++;
7570 7571          }
7571 7572          rw_exit(&ipst->ips_ill_g_lock);
7572 7573          rw_exit(&ipst->ips_ill_g_usesrc_lock);
7573 7574          ipif_refrele(orig_ipif);
7574 7575          mp1->b_wptr = (uchar_t *)lifr;
7575 7576          STRUCT_FSET(lifs, lifs_len, (int)((uchar_t *)lifr - mp1->b_rptr));
7576 7577  
7577 7578          return (0);
7578 7579  }
7579 7580  
7580 7581  /* ARGSUSED */
7581 7582  int
7582 7583  ip_sioctl_get_lifconf(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q,
7583 7584      mblk_t *mp, ip_ioctl_cmd_t *ipip, void *ifreq)
7584 7585  {
7585 7586          mblk_t *mp1;
7586 7587          int     list;
7587 7588          ill_t   *ill;
7588 7589          ipif_t  *ipif;
7589 7590          int     flags;
7590 7591          int     numlifs = 0;
7591 7592          size_t  lifc_bufsize;
7592 7593          struct  lifreq *lifr;
7593 7594          sa_family_t     family;
7594 7595          struct  sockaddr_in     *sin;
7595 7596          struct  sockaddr_in6    *sin6;
7596 7597          ill_walk_context_t      ctx;
7597 7598          struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
7598 7599          int32_t lifclen;
7599 7600          zoneid_t zoneid;
7600 7601          STRUCT_HANDLE(lifconf, lifc);
7601 7602          ip_stack_t *ipst = CONNQ_TO_IPST(q);
7602 7603  
7603 7604          ip1dbg(("ip_sioctl_get_lifconf"));
7604 7605  
7605 7606          ASSERT(q->q_next == NULL);
7606 7607  
7607 7608          zoneid = Q_TO_CONN(q)->conn_zoneid;
7608 7609  
7609 7610          /* Existence verified in ip_wput_nondata */
7610 7611          mp1 = mp->b_cont->b_cont;
7611 7612  
7612 7613          /*
7613 7614           * An extended version of SIOCGIFCONF that takes an
7614 7615           * additional address family and flags field.
7615 7616           * AF_UNSPEC retrieve both IPv4 and IPv6.
7616 7617           * Unless LIFC_NOXMIT is specified the IPIF_NOXMIT
7617 7618           * interfaces are omitted.
7618 7619           * Similarly, IPIF_TEMPORARY interfaces are omitted
7619 7620           * unless LIFC_TEMPORARY is specified.
7620 7621           * If LIFC_EXTERNAL_SOURCE is specified, IPIF_NOXMIT,
7621 7622           * IPIF_NOLOCAL, PHYI_LOOPBACK, IPIF_DEPRECATED and
7622 7623           * not IPIF_UP interfaces are omitted. LIFC_EXTERNAL_SOURCE
7623 7624           * has priority over LIFC_NOXMIT.
7624 7625           */
7625 7626          STRUCT_SET_HANDLE(lifc, iocp->ioc_flag, NULL);
7626 7627  
7627 7628          if ((mp1->b_wptr - mp1->b_rptr) != STRUCT_SIZE(lifc))
7628 7629                  return (EINVAL);
7629 7630  
7630 7631          /*
7631 7632           * Must be (better be!) continuation of a TRANSPARENT
7632 7633           * IOCTL.  We just copied in the lifconf structure.
7633 7634           */
7634 7635          STRUCT_SET_HANDLE(lifc, iocp->ioc_flag, (struct lifconf *)mp1->b_rptr);
7635 7636  
7636 7637          family = STRUCT_FGET(lifc, lifc_family);
7637 7638          flags = STRUCT_FGET(lifc, lifc_flags);
7638 7639  
7639 7640          switch (family) {
7640 7641          case AF_UNSPEC:
7641 7642                  /*
7642 7643                   * walk all ILL's.
7643 7644                   */
7644 7645                  list = MAX_G_HEADS;
7645 7646                  break;
7646 7647          case AF_INET:
7647 7648                  /*
7648 7649                   * walk only IPV4 ILL's.
7649 7650                   */
7650 7651                  list = IP_V4_G_HEAD;
7651 7652                  break;
7652 7653          case AF_INET6:
7653 7654                  /*
7654 7655                   * walk only IPV6 ILL's.
7655 7656                   */
7656 7657                  list = IP_V6_G_HEAD;
7657 7658                  break;
7658 7659          default:
7659 7660                  return (EAFNOSUPPORT);
7660 7661          }
7661 7662  
7662 7663          /*
7663 7664           * Allocate a buffer to hold requested information.
7664 7665           *
7665 7666           * If lifc_len is larger than what is needed, we only
7666 7667           * allocate what we will use.
7667 7668           *
7668 7669           * If lifc_len is smaller than what is needed, return
7669 7670           * EINVAL.
7670 7671           */
7671 7672          numlifs = ip_get_numlifs(family, flags, zoneid, ipst);
7672 7673          lifc_bufsize = numlifs * sizeof (struct lifreq);
7673 7674          lifclen = STRUCT_FGET(lifc, lifc_len);
7674 7675          if (lifc_bufsize > lifclen) {
7675 7676                  if (iocp->ioc_cmd == O_SIOCGLIFCONF)
7676 7677                          return (EINVAL);
7677 7678                  else
7678 7679                          lifc_bufsize = lifclen;
7679 7680          }
7680 7681  
7681 7682          mp1 = mi_copyout_alloc(q, mp,
7682 7683              STRUCT_FGETP(lifc, lifc_buf), lifc_bufsize, B_FALSE);
7683 7684          if (mp1 == NULL)
7684 7685                  return (ENOMEM);
7685 7686  
7686 7687          mp1->b_wptr = mp1->b_rptr + lifc_bufsize;
7687 7688          bzero(mp1->b_rptr, mp1->b_wptr - mp1->b_rptr);
7688 7689  
7689 7690          lifr = (struct lifreq *)mp1->b_rptr;
7690 7691  
7691 7692          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
7692 7693          ill = ill_first(list, list, &ctx, ipst);
7693 7694          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
7694 7695                  if (IS_UNDER_IPMP(ill) && !(flags & LIFC_UNDER_IPMP))
7695 7696                          continue;
7696 7697  
7697 7698                  for (ipif = ill->ill_ipif; ipif != NULL;
7698 7699                      ipif = ipif->ipif_next) {
7699 7700                          if ((ipif->ipif_flags & IPIF_NOXMIT) &&
7700 7701                              !(flags & LIFC_NOXMIT))
7701 7702                                  continue;
7702 7703  
7703 7704                          if ((ipif->ipif_flags & IPIF_TEMPORARY) &&
7704 7705                              !(flags & LIFC_TEMPORARY))
7705 7706                                  continue;
7706 7707  
7707 7708                          if (((ipif->ipif_flags &
7708 7709                              (IPIF_NOXMIT|IPIF_NOLOCAL|
7709 7710                              IPIF_DEPRECATED)) ||
7710 7711                              IS_LOOPBACK(ill) ||
7711 7712                              !(ipif->ipif_flags & IPIF_UP)) &&
7712 7713                              (flags & LIFC_EXTERNAL_SOURCE))
7713 7714                                  continue;
7714 7715  
7715 7716                          if (zoneid != ipif->ipif_zoneid &&
7716 7717                              ipif->ipif_zoneid != ALL_ZONES &&
7717 7718                              (zoneid != GLOBAL_ZONEID ||
7718 7719                              !(flags & LIFC_ALLZONES)))
7719 7720                                  continue;
7720 7721  
7721 7722                          if ((uchar_t *)&lifr[1] > mp1->b_wptr) {
7722 7723                                  if (iocp->ioc_cmd == O_SIOCGLIFCONF) {
7723 7724                                          rw_exit(&ipst->ips_ill_g_lock);
7724 7725                                          return (EINVAL);
7725 7726                                  } else {
7726 7727                                          goto lif_copydone;
7727 7728                                  }
7728 7729                          }
7729 7730  
7730 7731                          ipif_get_name(ipif, lifr->lifr_name,
7731 7732                              sizeof (lifr->lifr_name));
7732 7733                          lifr->lifr_type = ill->ill_type;
7733 7734                          if (ipif->ipif_isv6) {
7734 7735                                  sin6 = (sin6_t *)&lifr->lifr_addr;
7735 7736                                  *sin6 = sin6_null;
7736 7737                                  sin6->sin6_family = AF_INET6;
7737 7738                                  sin6->sin6_addr =
7738 7739                                      ipif->ipif_v6lcl_addr;
7739 7740                                  lifr->lifr_addrlen =
7740 7741                                      ip_mask_to_plen_v6(
7741 7742                                      &ipif->ipif_v6net_mask);
7742 7743                          } else {
7743 7744                                  sin = (sin_t *)&lifr->lifr_addr;
7744 7745                                  *sin = sin_null;
7745 7746                                  sin->sin_family = AF_INET;
7746 7747                                  sin->sin_addr.s_addr =
7747 7748                                      ipif->ipif_lcl_addr;
7748 7749                                  lifr->lifr_addrlen =
7749 7750                                      ip_mask_to_plen(
7750 7751                                      ipif->ipif_net_mask);
7751 7752                          }
7752 7753                          lifr++;
7753 7754                  }
7754 7755          }
7755 7756  lif_copydone:
7756 7757          rw_exit(&ipst->ips_ill_g_lock);
7757 7758  
7758 7759          mp1->b_wptr = (uchar_t *)lifr;
7759 7760          if (STRUCT_BUF(lifc) != NULL) {
7760 7761                  STRUCT_FSET(lifc, lifc_len,
7761 7762                      (int)((uchar_t *)lifr - mp1->b_rptr));
7762 7763          }
7763 7764          return (0);
7764 7765  }
7765 7766  
7766 7767  static void
7767 7768  ip_sioctl_ip6addrpolicy(queue_t *q, mblk_t *mp)
7768 7769  {
7769 7770          ip6_asp_t *table;
7770 7771          size_t table_size;
7771 7772          mblk_t *data_mp;
7772 7773          struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
7773 7774          ip_stack_t      *ipst;
7774 7775  
7775 7776          if (q->q_next == NULL)
7776 7777                  ipst = CONNQ_TO_IPST(q);
7777 7778          else
7778 7779                  ipst = ILLQ_TO_IPST(q);
7779 7780  
7780 7781          /* These two ioctls are I_STR only */
7781 7782          if (iocp->ioc_count == TRANSPARENT) {
7782 7783                  miocnak(q, mp, 0, EINVAL);
7783 7784                  return;
7784 7785          }
7785 7786  
7786 7787          data_mp = mp->b_cont;
7787 7788          if (data_mp == NULL) {
7788 7789                  /* The user passed us a NULL argument */
7789 7790                  table = NULL;
7790 7791                  table_size = iocp->ioc_count;
7791 7792          } else {
7792 7793                  /*
7793 7794                   * The user provided a table.  The stream head
7794 7795                   * may have copied in the user data in chunks,
7795 7796                   * so make sure everything is pulled up
7796 7797                   * properly.
7797 7798                   */
7798 7799                  if (MBLKL(data_mp) < iocp->ioc_count) {
7799 7800                          mblk_t *new_data_mp;
7800 7801                          if ((new_data_mp = msgpullup(data_mp, -1)) ==
7801 7802                              NULL) {
7802 7803                                  miocnak(q, mp, 0, ENOMEM);
7803 7804                                  return;
7804 7805                          }
7805 7806                          freemsg(data_mp);
7806 7807                          data_mp = new_data_mp;
7807 7808                          mp->b_cont = data_mp;
7808 7809                  }
7809 7810                  table = (ip6_asp_t *)data_mp->b_rptr;
7810 7811                  table_size = iocp->ioc_count;
7811 7812          }
7812 7813  
7813 7814          switch (iocp->ioc_cmd) {
7814 7815          case SIOCGIP6ADDRPOLICY:
7815 7816                  iocp->ioc_rval = ip6_asp_get(table, table_size, ipst);
7816 7817                  if (iocp->ioc_rval == -1)
7817 7818                          iocp->ioc_error = EINVAL;
7818 7819  #if defined(_SYSCALL32_IMPL) && _LONG_LONG_ALIGNMENT_32 == 4
7819 7820                  else if (table != NULL &&
7820 7821                      (iocp->ioc_flag & IOC_MODELS) == IOC_ILP32) {
7821 7822                          ip6_asp_t *src = table;
7822 7823                          ip6_asp32_t *dst = (void *)table;
7823 7824                          int count = table_size / sizeof (ip6_asp_t);
7824 7825                          int i;
7825 7826  
7826 7827                          /*
7827 7828                           * We need to do an in-place shrink of the array
7828 7829                           * to match the alignment attributes of the
7829 7830                           * 32-bit ABI looking at it.
7830 7831                           */
7831 7832                          /* LINTED: logical expression always true: op "||" */
7832 7833                          ASSERT(sizeof (*src) > sizeof (*dst));
7833 7834                          for (i = 1; i < count; i++)
7834 7835                                  bcopy(src + i, dst + i, sizeof (*dst));
7835 7836                  }
7836 7837  #endif
7837 7838                  break;
7838 7839  
7839 7840          case SIOCSIP6ADDRPOLICY:
7840 7841                  ASSERT(mp->b_prev == NULL);
7841 7842                  mp->b_prev = (void *)q;
7842 7843  #if defined(_SYSCALL32_IMPL) && _LONG_LONG_ALIGNMENT_32 == 4
7843 7844                  /*
7844 7845                   * We pass in the datamodel here so that the ip6_asp_replace()
7845 7846                   * routine can handle converting from 32-bit to native formats
7846 7847                   * where necessary.
7847 7848                   *
7848 7849                   * A better way to handle this might be to convert the inbound
7849 7850                   * data structure here, and hang it off a new 'mp'; thus the
7850 7851                   * ip6_asp_replace() logic would always be dealing with native
7851 7852                   * format data structures..
7852 7853                   *
7853 7854                   * (An even simpler way to handle these ioctls is to just
7854 7855                   * add a 32-bit trailing 'pad' field to the ip6_asp_t structure
7855 7856                   * and just recompile everything that depends on it.)
7856 7857                   */
7857 7858  #endif
7858 7859                  ip6_asp_replace(mp, table, table_size, B_FALSE, ipst,
7859 7860                      iocp->ioc_flag & IOC_MODELS);
7860 7861                  return;
7861 7862          }
7862 7863  
7863 7864          DB_TYPE(mp) =  (iocp->ioc_error == 0) ? M_IOCACK : M_IOCNAK;
7864 7865          qreply(q, mp);
7865 7866  }
7866 7867  
7867 7868  static void
7868 7869  ip_sioctl_dstinfo(queue_t *q, mblk_t *mp)
7869 7870  {
7870 7871          mblk_t          *data_mp;
7871 7872          struct dstinforeq       *dir;
7872 7873          uint8_t         *end, *cur;
7873 7874          in6_addr_t      *daddr, *saddr;
7874 7875          ipaddr_t        v4daddr;
7875 7876          ire_t           *ire;
7876 7877          ipaddr_t        v4setsrc;
7877 7878          in6_addr_t      v6setsrc;
7878 7879          char            *slabel, *dlabel;
7879 7880          boolean_t       isipv4;
7880 7881          int             match_ire;
7881 7882          ill_t           *dst_ill;
7882 7883          struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
7883 7884          conn_t          *connp = Q_TO_CONN(q);
7884 7885          zoneid_t        zoneid = IPCL_ZONEID(connp);
7885 7886          ip_stack_t      *ipst = connp->conn_netstack->netstack_ip;
7886 7887          uint64_t        ipif_flags;
7887 7888  
7888 7889          ASSERT(q->q_next == NULL); /* this ioctl not allowed if ip is module */
7889 7890  
7890 7891          /*
7891 7892           * This ioctl is I_STR only, and must have a
7892 7893           * data mblk following the M_IOCTL mblk.
7893 7894           */
7894 7895          data_mp = mp->b_cont;
7895 7896          if (iocp->ioc_count == TRANSPARENT || data_mp == NULL) {
7896 7897                  miocnak(q, mp, 0, EINVAL);
7897 7898                  return;
7898 7899          }
7899 7900  
7900 7901          if (MBLKL(data_mp) < iocp->ioc_count) {
7901 7902                  mblk_t *new_data_mp;
7902 7903  
7903 7904                  if ((new_data_mp = msgpullup(data_mp, -1)) == NULL) {
7904 7905                          miocnak(q, mp, 0, ENOMEM);
7905 7906                          return;
7906 7907                  }
7907 7908                  freemsg(data_mp);
7908 7909                  data_mp = new_data_mp;
7909 7910                  mp->b_cont = data_mp;
7910 7911          }
7911 7912          match_ire = MATCH_IRE_DSTONLY;
7912 7913  
7913 7914          for (cur = data_mp->b_rptr, end = data_mp->b_wptr;
7914 7915              end - cur >= sizeof (struct dstinforeq);
7915 7916              cur += sizeof (struct dstinforeq)) {
7916 7917                  dir = (struct dstinforeq *)cur;
7917 7918                  daddr = &dir->dir_daddr;
7918 7919                  saddr = &dir->dir_saddr;
7919 7920  
7920 7921                  /*
7921 7922                   * ip_addr_scope_v6() and ip6_asp_lookup() handle
7922 7923                   * v4 mapped addresses; ire_ftable_lookup_v6()
7923 7924                   * and ip_select_source_v6() do not.
7924 7925                   */
7925 7926                  dir->dir_dscope = ip_addr_scope_v6(daddr);
7926 7927                  dlabel = ip6_asp_lookup(daddr, &dir->dir_precedence, ipst);
7927 7928  
7928 7929                  isipv4 = IN6_IS_ADDR_V4MAPPED(daddr);
7929 7930                  if (isipv4) {
7930 7931                          IN6_V4MAPPED_TO_IPADDR(daddr, v4daddr);
7931 7932                          v4setsrc = INADDR_ANY;
7932 7933                          ire = ire_route_recursive_v4(v4daddr, 0, NULL, zoneid,
7933 7934                              NULL, match_ire, IRR_ALLOCATE, 0, ipst, &v4setsrc,
7934 7935                              NULL, NULL);
7935 7936                  } else {
7936 7937                          v6setsrc = ipv6_all_zeros;
7937 7938                          ire = ire_route_recursive_v6(daddr, 0, NULL, zoneid,
7938 7939                              NULL, match_ire, IRR_ALLOCATE, 0, ipst, &v6setsrc,
7939 7940                              NULL, NULL);
7940 7941                  }
7941 7942                  ASSERT(ire != NULL);
7942 7943                  if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
7943 7944                          ire_refrele(ire);
7944 7945                          dir->dir_dreachable = 0;
7945 7946  
7946 7947                          /* move on to next dst addr */
7947 7948                          continue;
7948 7949                  }
7949 7950                  dir->dir_dreachable = 1;
7950 7951  
7951 7952                  dst_ill = ire_nexthop_ill(ire);
7952 7953                  if (dst_ill == NULL) {
7953 7954                          ire_refrele(ire);
7954 7955                          continue;
7955 7956                  }
7956 7957  
7957 7958                  /* With ipmp we most likely look at the ipmp ill here */
7958 7959                  dir->dir_dmactype = dst_ill->ill_mactype;
7959 7960  
7960 7961                  if (isipv4) {
7961 7962                          ipaddr_t v4saddr;
7962 7963  
7963 7964                          if (ip_select_source_v4(dst_ill, v4setsrc, v4daddr,
7964 7965                              connp->conn_ixa->ixa_multicast_ifaddr, zoneid, ipst,
7965 7966                              &v4saddr, NULL, &ipif_flags) != 0) {
7966 7967                                  v4saddr = INADDR_ANY;
7967 7968                                  ipif_flags = 0;
7968 7969                          }
7969 7970                          IN6_IPADDR_TO_V4MAPPED(v4saddr, saddr);
7970 7971                  } else {
7971 7972                          if (ip_select_source_v6(dst_ill, &v6setsrc, daddr,
7972 7973                              zoneid, ipst, B_FALSE, IPV6_PREFER_SRC_DEFAULT,
7973 7974                              saddr, NULL, &ipif_flags) != 0) {
7974 7975                                  *saddr = ipv6_all_zeros;
7975 7976                                  ipif_flags = 0;
7976 7977                          }
7977 7978                  }
7978 7979  
7979 7980                  dir->dir_sscope = ip_addr_scope_v6(saddr);
7980 7981                  slabel = ip6_asp_lookup(saddr, NULL, ipst);
7981 7982                  dir->dir_labelmatch = ip6_asp_labelcmp(dlabel, slabel);
7982 7983                  dir->dir_sdeprecated = (ipif_flags & IPIF_DEPRECATED) ? 1 : 0;
7983 7984                  ire_refrele(ire);
7984 7985                  ill_refrele(dst_ill);
7985 7986          }
7986 7987          miocack(q, mp, iocp->ioc_count, 0);
7987 7988  }
7988 7989  
7989 7990  /*
7990 7991   * Check if this is an address assigned to this machine.
7991 7992   * Skips interfaces that are down by using ire checks.
7992 7993   * Translates mapped addresses to v4 addresses and then
7993 7994   * treats them as such, returning true if the v4 address
7994 7995   * associated with this mapped address is configured.
7995 7996   * Note: Applications will have to be careful what they do
7996 7997   * with the response; use of mapped addresses limits
7997 7998   * what can be done with the socket, especially with
7998 7999   * respect to socket options and ioctls - neither IPv4
7999 8000   * options nor IPv6 sticky options/ancillary data options
8000 8001   * may be used.
8001 8002   */
8002 8003  /* ARGSUSED */
8003 8004  int
8004 8005  ip_sioctl_tmyaddr(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
8005 8006      ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
8006 8007  {
8007 8008          struct sioc_addrreq *sia;
8008 8009          sin_t *sin;
8009 8010          ire_t *ire;
8010 8011          mblk_t *mp1;
8011 8012          zoneid_t zoneid;
8012 8013          ip_stack_t      *ipst;
8013 8014  
8014 8015          ip1dbg(("ip_sioctl_tmyaddr"));
8015 8016  
8016 8017          ASSERT(q->q_next == NULL); /* this ioctl not allowed if ip is module */
8017 8018          zoneid = Q_TO_CONN(q)->conn_zoneid;
8018 8019          ipst = CONNQ_TO_IPST(q);
8019 8020  
8020 8021          /* Existence verified in ip_wput_nondata */
8021 8022          mp1 = mp->b_cont->b_cont;
8022 8023          sia = (struct sioc_addrreq *)mp1->b_rptr;
8023 8024          sin = (sin_t *)&sia->sa_addr;
8024 8025          switch (sin->sin_family) {
8025 8026          case AF_INET6: {
8026 8027                  sin6_t *sin6 = (sin6_t *)sin;
8027 8028  
8028 8029                  if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
8029 8030                          ipaddr_t v4_addr;
8030 8031  
8031 8032                          IN6_V4MAPPED_TO_IPADDR(&sin6->sin6_addr,
8032 8033                              v4_addr);
8033 8034                          ire = ire_ftable_lookup_v4(v4_addr, 0, 0,
8034 8035                              IRE_LOCAL|IRE_LOOPBACK, NULL, zoneid, NULL,
8035 8036                              MATCH_IRE_TYPE | MATCH_IRE_ZONEONLY, 0, ipst, NULL);
8036 8037                  } else {
8037 8038                          in6_addr_t v6addr;
8038 8039  
8039 8040                          v6addr = sin6->sin6_addr;
8040 8041                          ire = ire_ftable_lookup_v6(&v6addr, 0, 0,
8041 8042                              IRE_LOCAL|IRE_LOOPBACK, NULL, zoneid, NULL,
8042 8043                              MATCH_IRE_TYPE | MATCH_IRE_ZONEONLY, 0, ipst, NULL);
8043 8044                  }
8044 8045                  break;
8045 8046          }
8046 8047          case AF_INET: {
8047 8048                  ipaddr_t v4addr;
8048 8049  
8049 8050                  v4addr = sin->sin_addr.s_addr;
8050 8051                  ire = ire_ftable_lookup_v4(v4addr, 0, 0,
8051 8052                      IRE_LOCAL|IRE_LOOPBACK, NULL, zoneid,
8052 8053                      NULL, MATCH_IRE_TYPE | MATCH_IRE_ZONEONLY, 0, ipst, NULL);
8053 8054                  break;
8054 8055          }
8055 8056          default:
8056 8057                  return (EAFNOSUPPORT);
8057 8058          }
8058 8059          if (ire != NULL) {
8059 8060                  sia->sa_res = 1;
8060 8061                  ire_refrele(ire);
8061 8062          } else {
8062 8063                  sia->sa_res = 0;
8063 8064          }
8064 8065          return (0);
8065 8066  }
8066 8067  
8067 8068  /*
8068 8069   * Check if this is an address assigned on-link i.e. neighbor,
8069 8070   * and makes sure it's reachable from the current zone.
8070 8071   * Returns true for my addresses as well.
8071 8072   * Translates mapped addresses to v4 addresses and then
8072 8073   * treats them as such, returning true if the v4 address
8073 8074   * associated with this mapped address is configured.
8074 8075   * Note: Applications will have to be careful what they do
8075 8076   * with the response; use of mapped addresses limits
8076 8077   * what can be done with the socket, especially with
8077 8078   * respect to socket options and ioctls - neither IPv4
8078 8079   * options nor IPv6 sticky options/ancillary data options
8079 8080   * may be used.
8080 8081   */
8081 8082  /* ARGSUSED */
8082 8083  int
8083 8084  ip_sioctl_tonlink(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
8084 8085      ip_ioctl_cmd_t *ipip, void *duymmy_ifreq)
8085 8086  {
8086 8087          struct sioc_addrreq *sia;
8087 8088          sin_t *sin;
8088 8089          mblk_t  *mp1;
8089 8090          ire_t *ire = NULL;
8090 8091          zoneid_t zoneid;
8091 8092          ip_stack_t      *ipst;
8092 8093  
8093 8094          ip1dbg(("ip_sioctl_tonlink"));
8094 8095  
8095 8096          ASSERT(q->q_next == NULL); /* this ioctl not allowed if ip is module */
8096 8097          zoneid = Q_TO_CONN(q)->conn_zoneid;
8097 8098          ipst = CONNQ_TO_IPST(q);
8098 8099  
8099 8100          /* Existence verified in ip_wput_nondata */
8100 8101          mp1 = mp->b_cont->b_cont;
8101 8102          sia = (struct sioc_addrreq *)mp1->b_rptr;
8102 8103          sin = (sin_t *)&sia->sa_addr;
8103 8104  
8104 8105          /*
8105 8106           * We check for IRE_ONLINK and exclude IRE_BROADCAST|IRE_MULTICAST
8106 8107           * to make sure we only look at on-link unicast address.
8107 8108           */
8108 8109          switch (sin->sin_family) {
8109 8110          case AF_INET6: {
8110 8111                  sin6_t *sin6 = (sin6_t *)sin;
8111 8112  
8112 8113                  if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
8113 8114                          ipaddr_t v4_addr;
8114 8115  
8115 8116                          IN6_V4MAPPED_TO_IPADDR(&sin6->sin6_addr,
8116 8117                              v4_addr);
8117 8118                          if (!CLASSD(v4_addr)) {
8118 8119                                  ire = ire_ftable_lookup_v4(v4_addr, 0, 0, 0,
8119 8120                                      NULL, zoneid, NULL, MATCH_IRE_DSTONLY,
8120 8121                                      0, ipst, NULL);
8121 8122                          }
8122 8123                  } else {
8123 8124                          in6_addr_t v6addr;
8124 8125  
8125 8126                          v6addr = sin6->sin6_addr;
8126 8127                          if (!IN6_IS_ADDR_MULTICAST(&v6addr)) {
8127 8128                                  ire = ire_ftable_lookup_v6(&v6addr, 0, 0, 0,
8128 8129                                      NULL, zoneid, NULL, MATCH_IRE_DSTONLY, 0,
8129 8130                                      ipst, NULL);
8130 8131                          }
8131 8132                  }
8132 8133                  break;
8133 8134          }
8134 8135          case AF_INET: {
8135 8136                  ipaddr_t v4addr;
8136 8137  
8137 8138                  v4addr = sin->sin_addr.s_addr;
8138 8139                  if (!CLASSD(v4addr)) {
8139 8140                          ire = ire_ftable_lookup_v4(v4addr, 0, 0, 0, NULL,
8140 8141                              zoneid, NULL, MATCH_IRE_DSTONLY, 0, ipst, NULL);
8141 8142                  }
8142 8143                  break;
8143 8144          }
8144 8145          default:
8145 8146                  return (EAFNOSUPPORT);
8146 8147          }
8147 8148          sia->sa_res = 0;
8148 8149          if (ire != NULL) {
8149 8150                  ASSERT(!(ire->ire_type & IRE_MULTICAST));
8150 8151  
8151 8152                  if ((ire->ire_type & IRE_ONLINK) &&
8152 8153                      !(ire->ire_type & IRE_BROADCAST))
8153 8154                          sia->sa_res = 1;
8154 8155                  ire_refrele(ire);
8155 8156          }
8156 8157          return (0);
8157 8158  }
8158 8159  
8159 8160  /*
8160 8161   * TBD: implement when kernel maintaines a list of site prefixes.
8161 8162   */
8162 8163  /* ARGSUSED */
8163 8164  int
8164 8165  ip_sioctl_tmysite(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
8165 8166      ip_ioctl_cmd_t *ipip, void *ifreq)
8166 8167  {
8167 8168          return (ENXIO);
8168 8169  }
8169 8170  
8170 8171  /* ARP IOCTLs. */
8171 8172  /* ARGSUSED */
8172 8173  int
8173 8174  ip_sioctl_arp(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
8174 8175      ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
8175 8176  {
8176 8177          int             err;
8177 8178          ipaddr_t        ipaddr;
8178 8179          struct iocblk   *iocp;
8179 8180          conn_t          *connp;
8180 8181          struct arpreq   *ar;
8181 8182          struct xarpreq  *xar;
8182 8183          int             arp_flags, flags, alength;
8183 8184          uchar_t         *lladdr;
8184 8185          ip_stack_t      *ipst;
8185 8186          ill_t           *ill = ipif->ipif_ill;
8186 8187          ill_t           *proxy_ill = NULL;
8187 8188          ipmp_arpent_t   *entp = NULL;
8188 8189          boolean_t       proxyarp = B_FALSE;
8189 8190          boolean_t       if_arp_ioctl = B_FALSE;
8190 8191          ncec_t          *ncec = NULL;
8191 8192          nce_t           *nce;
8192 8193  
8193 8194          ASSERT(!(q->q_flag & QREADR) && q->q_next == NULL);
8194 8195          connp = Q_TO_CONN(q);
8195 8196          ipst = connp->conn_netstack->netstack_ip;
8196 8197          iocp = (struct iocblk *)mp->b_rptr;
8197 8198  
8198 8199          if (ipip->ipi_cmd_type == XARP_CMD) {
8199 8200                  /* We have a chain - M_IOCTL-->MI_COPY_MBLK-->XARPREQ_MBLK */
8200 8201                  xar = (struct xarpreq *)mp->b_cont->b_cont->b_rptr;
8201 8202                  ar = NULL;
8202 8203  
8203 8204                  arp_flags = xar->xarp_flags;
8204 8205                  lladdr = (uchar_t *)LLADDR(&xar->xarp_ha);
8205 8206                  if_arp_ioctl = (xar->xarp_ha.sdl_nlen != 0);
8206 8207                  /*
8207 8208                   * Validate against user's link layer address length
8208 8209                   * input and name and addr length limits.
8209 8210                   */
8210 8211                  alength = ill->ill_phys_addr_length;
8211 8212                  if (ipip->ipi_cmd == SIOCSXARP) {
8212 8213                          if (alength != xar->xarp_ha.sdl_alen ||
8213 8214                              (alength + xar->xarp_ha.sdl_nlen >
8214 8215                              sizeof (xar->xarp_ha.sdl_data)))
8215 8216                                  return (EINVAL);
8216 8217                  }
8217 8218          } else {
8218 8219                  /* We have a chain - M_IOCTL-->MI_COPY_MBLK-->ARPREQ_MBLK */
8219 8220                  ar = (struct arpreq *)mp->b_cont->b_cont->b_rptr;
8220 8221                  xar = NULL;
8221 8222  
8222 8223                  arp_flags = ar->arp_flags;
8223 8224                  lladdr = (uchar_t *)ar->arp_ha.sa_data;
8224 8225                  /*
8225 8226                   * Theoretically, the sa_family could tell us what link
8226 8227                   * layer type this operation is trying to deal with. By
8227 8228                   * common usage AF_UNSPEC means ethernet. We'll assume
8228 8229                   * any attempt to use the SIOC?ARP ioctls is for ethernet,
8229 8230                   * for now. Our new SIOC*XARP ioctls can be used more
8230 8231                   * generally.
8231 8232                   *
8232 8233                   * If the underlying media happens to have a non 6 byte
8233 8234                   * address, arp module will fail set/get, but the del
8234 8235                   * operation will succeed.
8235 8236                   */
8236 8237                  alength = 6;
8237 8238                  if ((ipip->ipi_cmd != SIOCDARP) &&
8238 8239                      (alength != ill->ill_phys_addr_length)) {
8239 8240                          return (EINVAL);
8240 8241                  }
8241 8242          }
8242 8243  
8243 8244          /* Translate ATF* flags to NCE* flags */
8244 8245          flags = 0;
8245 8246          if (arp_flags & ATF_AUTHORITY)
8246 8247                  flags |= NCE_F_AUTHORITY;
8247 8248          if (arp_flags & ATF_PERM)
8248 8249                  flags |= NCE_F_NONUD; /* not subject to aging */
8249 8250          if (arp_flags & ATF_PUBL)
8250 8251                  flags |= NCE_F_PUBLISH;
8251 8252  
8252 8253          /*
8253 8254           * IPMP ARP special handling:
8254 8255           *
8255 8256           * 1. Since ARP mappings must appear consistent across the group,
8256 8257           *    prohibit changing ARP mappings on the underlying interfaces.
8257 8258           *
8258 8259           * 2. Since ARP mappings for IPMP data addresses are maintained by
8259 8260           *    IP itself, prohibit changing them.
8260 8261           *
8261 8262           * 3. For proxy ARP, use a functioning hardware address in the group,
8262 8263           *    provided one exists.  If one doesn't, just add the entry as-is;
8263 8264           *    ipmp_illgrp_refresh_arpent() will refresh it if things change.
8264 8265           */
8265 8266          if (IS_UNDER_IPMP(ill)) {
8266 8267                  if (ipip->ipi_cmd != SIOCGARP && ipip->ipi_cmd != SIOCGXARP)
8267 8268                          return (EPERM);
8268 8269          }
8269 8270          if (IS_IPMP(ill)) {
8270 8271                  ipmp_illgrp_t *illg = ill->ill_grp;
8271 8272  
8272 8273                  switch (ipip->ipi_cmd) {
8273 8274                  case SIOCSARP:
8274 8275                  case SIOCSXARP:
8275 8276                          proxy_ill = ipmp_illgrp_find_ill(illg, lladdr, alength);
8276 8277                          if (proxy_ill != NULL) {
8277 8278                                  proxyarp = B_TRUE;
8278 8279                                  if (!ipmp_ill_is_active(proxy_ill))
8279 8280                                          proxy_ill = ipmp_illgrp_next_ill(illg);
8280 8281                                  if (proxy_ill != NULL)
8281 8282                                          lladdr = proxy_ill->ill_phys_addr;
8282 8283                          }
8283 8284                          /* FALLTHRU */
8284 8285                  }
8285 8286          }
8286 8287  
8287 8288          ipaddr = sin->sin_addr.s_addr;
8288 8289          /*
8289 8290           * don't match across illgrp per case (1) and (2).
8290 8291           * XXX use IS_IPMP(ill) like ndp_sioc_update?
8291 8292           */
8292 8293          nce = nce_lookup_v4(ill, &ipaddr);
8293 8294          if (nce != NULL)
8294 8295                  ncec = nce->nce_common;
8295 8296  
8296 8297          switch (iocp->ioc_cmd) {
8297 8298          case SIOCDARP:
8298 8299          case SIOCDXARP: {
8299 8300                  /*
8300 8301                   * Delete the NCE if any.
8301 8302                   */
8302 8303                  if (ncec == NULL) {
8303 8304                          iocp->ioc_error = ENXIO;
8304 8305                          break;
8305 8306                  }
8306 8307                  /* Don't allow changes to arp mappings of local addresses. */
8307 8308                  if (NCE_MYADDR(ncec)) {
8308 8309                          nce_refrele(nce);
8309 8310                          return (ENOTSUP);
8310 8311                  }
8311 8312                  iocp->ioc_error = 0;
8312 8313  
8313 8314                  /*
8314 8315                   * Delete the nce_common which has ncec_ill set to ipmp_ill.
8315 8316                   * This will delete all the nce entries on the under_ills.
8316 8317                   */
8317 8318                  ncec_delete(ncec);
8318 8319                  /*
8319 8320                   * Once the NCE has been deleted, then the ire_dep* consistency
8320 8321                   * mechanism will find any IRE which depended on the now
8321 8322                   * condemned NCE (as part of sending packets).
8322 8323                   * That mechanism handles redirects by deleting redirects
8323 8324                   * that refer to UNREACHABLE nces.
8324 8325                   */
8325 8326                  break;
8326 8327          }
8327 8328          case SIOCGARP:
8328 8329          case SIOCGXARP:
8329 8330                  if (ncec != NULL) {
8330 8331                          lladdr = ncec->ncec_lladdr;
8331 8332                          flags = ncec->ncec_flags;
8332 8333                          iocp->ioc_error = 0;
8333 8334                          ip_sioctl_garp_reply(mp, ncec->ncec_ill, lladdr, flags);
8334 8335                  } else {
8335 8336                          iocp->ioc_error = ENXIO;
8336 8337                  }
8337 8338                  break;
8338 8339          case SIOCSARP:
8339 8340          case SIOCSXARP:
8340 8341                  /* Don't allow changes to arp mappings of local addresses. */
8341 8342                  if (ncec != NULL && NCE_MYADDR(ncec)) {
8342 8343                          nce_refrele(nce);
8343 8344                          return (ENOTSUP);
8344 8345                  }
8345 8346  
8346 8347                  /* static arp entries will undergo NUD if ATF_PERM is not set */
8347 8348                  flags |= NCE_F_STATIC;
8348 8349                  if (!if_arp_ioctl) {
8349 8350                          ip_nce_lookup_and_update(&ipaddr, NULL, ipst,
8350 8351                              lladdr, alength, flags);
8351 8352                  } else {
8352 8353                          ipif_t *ipif = ipif_get_next_ipif(NULL, ill);
8353 8354                          if (ipif != NULL) {
8354 8355                                  ip_nce_lookup_and_update(&ipaddr, ipif, ipst,
8355 8356                                      lladdr, alength, flags);
8356 8357                                  ipif_refrele(ipif);
8357 8358                          }
8358 8359                  }
8359 8360                  if (nce != NULL) {
8360 8361                          nce_refrele(nce);
8361 8362                          nce = NULL;
8362 8363                  }
8363 8364                  /*
8364 8365                   * NCE_F_STATIC entries will be added in state ND_REACHABLE
8365 8366                   * by nce_add_common()
8366 8367                   */
8367 8368                  err = nce_lookup_then_add_v4(ill, lladdr,
8368 8369                      ill->ill_phys_addr_length, &ipaddr, flags, ND_UNCHANGED,
8369 8370                      &nce);
8370 8371                  if (err == EEXIST) {
8371 8372                          ncec = nce->nce_common;
8372 8373                          mutex_enter(&ncec->ncec_lock);
8373 8374                          ncec->ncec_state = ND_REACHABLE;
8374 8375                          ncec->ncec_flags = flags;
8375 8376                          nce_update(ncec, ND_UNCHANGED, lladdr);
8376 8377                          mutex_exit(&ncec->ncec_lock);
8377 8378                          err = 0;
8378 8379                  }
8379 8380                  if (nce != NULL) {
8380 8381                          nce_refrele(nce);
8381 8382                          nce = NULL;
8382 8383                  }
8383 8384                  if (IS_IPMP(ill) && err == 0) {
8384 8385                          entp = ipmp_illgrp_create_arpent(ill->ill_grp,
8385 8386                              proxyarp, ipaddr, lladdr, ill->ill_phys_addr_length,
8386 8387                              flags);
8387 8388                          if (entp == NULL || (proxyarp && proxy_ill == NULL)) {
8388 8389                                  iocp->ioc_error = (entp == NULL ? ENOMEM : 0);
8389 8390                                  break;
8390 8391                          }
8391 8392                  }
8392 8393                  iocp->ioc_error = err;
8393 8394          }
8394 8395  
8395 8396          if (nce != NULL) {
8396 8397                  nce_refrele(nce);
8397 8398          }
8398 8399  
8399 8400          /*
8400 8401           * If we created an IPMP ARP entry, mark that we've notified ARP.
8401 8402           */
8402 8403          if (entp != NULL)
8403 8404                  ipmp_illgrp_mark_arpent(ill->ill_grp, entp);
8404 8405  
8405 8406          return (iocp->ioc_error);
8406 8407  }
8407 8408  
8408 8409  /*
8409 8410   * Parse an [x]arpreq structure coming down SIOC[GSD][X]ARP ioctls, identify
8410 8411   * the associated sin and refhold and return the associated ipif via `ci'.
8411 8412   */
8412 8413  int
8413 8414  ip_extract_arpreq(queue_t *q, mblk_t *mp, const ip_ioctl_cmd_t *ipip,
8414 8415      cmd_info_t *ci)
8415 8416  {
8416 8417          mblk_t  *mp1;
8417 8418          sin_t   *sin;
8418 8419          conn_t  *connp;
8419 8420          ipif_t  *ipif;
8420 8421          ire_t   *ire = NULL;
8421 8422          ill_t   *ill = NULL;
8422 8423          boolean_t exists;
8423 8424          ip_stack_t *ipst;
8424 8425          struct arpreq *ar;
8425 8426          struct xarpreq *xar;
8426 8427          struct sockaddr_dl *sdl;
8427 8428  
8428 8429          /* ioctl comes down on a conn */
8429 8430          ASSERT(!(q->q_flag & QREADR) && q->q_next == NULL);
8430 8431          connp = Q_TO_CONN(q);
8431 8432          if (connp->conn_family == AF_INET6)
8432 8433                  return (ENXIO);
8433 8434  
8434 8435          ipst = connp->conn_netstack->netstack_ip;
8435 8436  
8436 8437          /* Verified in ip_wput_nondata */
8437 8438          mp1 = mp->b_cont->b_cont;
8438 8439  
8439 8440          if (ipip->ipi_cmd_type == XARP_CMD) {
8440 8441                  ASSERT(MBLKL(mp1) >= sizeof (struct xarpreq));
8441 8442                  xar = (struct xarpreq *)mp1->b_rptr;
8442 8443                  sin = (sin_t *)&xar->xarp_pa;
8443 8444                  sdl = &xar->xarp_ha;
8444 8445  
8445 8446                  if (sdl->sdl_family != AF_LINK || sin->sin_family != AF_INET)
8446 8447                          return (ENXIO);
8447 8448                  if (sdl->sdl_nlen >= LIFNAMSIZ)
8448 8449                          return (EINVAL);
8449 8450          } else {
8450 8451                  ASSERT(ipip->ipi_cmd_type == ARP_CMD);
8451 8452                  ASSERT(MBLKL(mp1) >= sizeof (struct arpreq));
8452 8453                  ar = (struct arpreq *)mp1->b_rptr;
8453 8454                  sin = (sin_t *)&ar->arp_pa;
8454 8455          }
8455 8456  
8456 8457          if (ipip->ipi_cmd_type == XARP_CMD && sdl->sdl_nlen != 0) {
8457 8458                  ipif = ipif_lookup_on_name(sdl->sdl_data, sdl->sdl_nlen,
8458 8459                      B_FALSE, &exists, B_FALSE, ALL_ZONES, ipst);
8459 8460                  if (ipif == NULL)
8460 8461                          return (ENXIO);
8461 8462                  if (ipif->ipif_id != 0) {
8462 8463                          ipif_refrele(ipif);
8463 8464                          return (ENXIO);
8464 8465                  }
8465 8466          } else {
8466 8467                  /*
8467 8468                   * Either an SIOC[DGS]ARP or an SIOC[DGS]XARP with an sdl_nlen
8468 8469                   * of 0: use the IP address to find the ipif.  If the IP
8469 8470                   * address is an IPMP test address, ire_ftable_lookup() will
8470 8471                   * find the wrong ill, so we first do an ipif_lookup_addr().
8471 8472                   */
8472 8473                  ipif = ipif_lookup_addr(sin->sin_addr.s_addr, NULL, ALL_ZONES,
8473 8474                      ipst);
8474 8475                  if (ipif == NULL) {
8475 8476                          ire = ire_ftable_lookup_v4(sin->sin_addr.s_addr,
8476 8477                              0, 0, IRE_IF_RESOLVER, NULL, ALL_ZONES,
8477 8478                              NULL, MATCH_IRE_TYPE, 0, ipst, NULL);
8478 8479                          if (ire == NULL || ((ill = ire->ire_ill) == NULL)) {
8479 8480                                  if (ire != NULL)
8480 8481                                          ire_refrele(ire);
8481 8482                                  return (ENXIO);
8482 8483                          }
8483 8484                          ASSERT(ire != NULL && ill != NULL);
8484 8485                          ipif = ill->ill_ipif;
8485 8486                          ipif_refhold(ipif);
8486 8487                          ire_refrele(ire);
8487 8488                  }
8488 8489          }
8489 8490  
8490 8491          if (ipif->ipif_ill->ill_net_type != IRE_IF_RESOLVER) {
8491 8492                  ipif_refrele(ipif);
8492 8493                  return (ENXIO);
8493 8494          }
8494 8495  
8495 8496          ci->ci_sin = sin;
8496 8497          ci->ci_ipif = ipif;
8497 8498          return (0);
8498 8499  }
8499 8500  
8500 8501  /*
8501 8502   * Link or unlink the illgrp on IPMP meta-interface `ill' depending on the
8502 8503   * value of `ioccmd'.  While an illgrp is linked to an ipmp_grp_t, it is
8503 8504   * accessible from that ipmp_grp_t, which means SIOCSLIFGROUPNAME can look it
8504 8505   * up and thus an ill can join that illgrp.
8505 8506   *
8506 8507   * We use I_PLINK/I_PUNLINK to do the link/unlink operations rather than
8507 8508   * open()/close() primarily because close() is not allowed to fail or block
8508 8509   * forever.  On the other hand, I_PUNLINK *can* fail, and there's no reason
8509 8510   * why anyone should ever need to I_PUNLINK an in-use IPMP stream.  To ensure
8510 8511   * symmetric behavior (e.g., doing an I_PLINK after and I_PUNLINK undoes the
8511 8512   * I_PUNLINK) we defer linking to I_PLINK.  Separately, we also fail attempts
8512 8513   * to I_LINK since I_UNLINK is optional and we'd end up in an inconsistent
8513 8514   * state if I_UNLINK didn't occur.
8514 8515   *
8515 8516   * Note that for each plumb/unplumb operation, we may end up here more than
8516 8517   * once because of the way ifconfig works.  However, it's OK to link the same
8517 8518   * illgrp more than once, or unlink an illgrp that's already unlinked.
8518 8519   */
8519 8520  static int
8520 8521  ip_sioctl_plink_ipmp(ill_t *ill, int ioccmd)
8521 8522  {
8522 8523          int err;
8523 8524          ip_stack_t *ipst = ill->ill_ipst;
8524 8525  
8525 8526          ASSERT(IS_IPMP(ill));
8526 8527          ASSERT(IAM_WRITER_ILL(ill));
8527 8528  
8528 8529          switch (ioccmd) {
8529 8530          case I_LINK:
8530 8531                  return (ENOTSUP);
8531 8532  
8532 8533          case I_PLINK:
8533 8534                  rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
8534 8535                  ipmp_illgrp_link_grp(ill->ill_grp, ill->ill_phyint->phyint_grp);
8535 8536                  rw_exit(&ipst->ips_ipmp_lock);
8536 8537                  break;
8537 8538  
8538 8539          case I_PUNLINK:
8539 8540                  /*
8540 8541                   * Require all UP ipifs be brought down prior to unlinking the
8541 8542                   * illgrp so any associated IREs (and other state) is torched.
8542 8543                   */
8543 8544                  if (ill->ill_ipif_up_count + ill->ill_ipif_dup_count > 0)
8544 8545                          return (EBUSY);
8545 8546  
8546 8547                  /*
8547 8548                   * NOTE: We hold ipmp_lock across the unlink to prevent a race
8548 8549                   * with an SIOCSLIFGROUPNAME request from an ill trying to
8549 8550                   * join this group.  Specifically: ills trying to join grab
8550 8551                   * ipmp_lock and bump a "pending join" counter checked by
8551 8552                   * ipmp_illgrp_unlink_grp().  During the unlink no new pending
8552 8553                   * joins can occur (since we have ipmp_lock).  Once we drop
8553 8554                   * ipmp_lock, subsequent SIOCSLIFGROUPNAME requests will not
8554 8555                   * find the illgrp (since we unlinked it) and will return
8555 8556                   * EAFNOSUPPORT.  This will then take them back through the
8556 8557                   * IPMP meta-interface plumbing logic in ifconfig, and thus
8557 8558                   * back through I_PLINK above.
8558 8559                   */
8559 8560                  rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
8560 8561                  err = ipmp_illgrp_unlink_grp(ill->ill_grp);
8561 8562                  rw_exit(&ipst->ips_ipmp_lock);
8562 8563                  return (err);
8563 8564          default:
8564 8565                  break;
8565 8566          }
8566 8567          return (0);
8567 8568  }
8568 8569  
8569 8570  /*
8570 8571   * Do I_PLINK/I_LINK or I_PUNLINK/I_UNLINK with consistency checks and also
8571 8572   * atomically set/clear the muxids. Also complete the ioctl by acking or
8572 8573   * naking it.  Note that the code is structured such that the link type,
8573 8574   * whether it's persistent or not, is treated equally.  ifconfig(1M) and
8574 8575   * its clones use the persistent link, while pppd(1M) and perhaps many
8575 8576   * other daemons may use non-persistent link.  When combined with some
8576 8577   * ill_t states, linking and unlinking lower streams may be used as
8577 8578   * indicators of dynamic re-plumbing events [see PSARC/1999/348].
8578 8579   */
8579 8580  /* ARGSUSED */
8580 8581  void
8581 8582  ip_sioctl_plink(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg)
8582 8583  {
8583 8584          mblk_t          *mp1;
8584 8585          struct linkblk  *li;
8585 8586          int             ioccmd = ((struct iocblk *)mp->b_rptr)->ioc_cmd;
8586 8587          int             err = 0;
8587 8588  
8588 8589          ASSERT(ioccmd == I_PLINK || ioccmd == I_PUNLINK ||
8589 8590              ioccmd == I_LINK || ioccmd == I_UNLINK);
8590 8591  
8591 8592          mp1 = mp->b_cont;       /* This is the linkblk info */
8592 8593          li = (struct linkblk *)mp1->b_rptr;
8593 8594  
8594 8595          err = ip_sioctl_plink_ipmod(ipsq, q, mp, ioccmd, li);
8595 8596          if (err == EINPROGRESS)
8596 8597                  return;
8597 8598          if (err == 0)
8598 8599                  miocack(q, mp, 0, 0);
8599 8600          else
8600 8601                  miocnak(q, mp, 0, err);
8601 8602  
8602 8603          /* Conn was refheld in ip_sioctl_copyin_setup */
8603 8604          if (CONN_Q(q)) {
8604 8605                  CONN_DEC_IOCTLREF(Q_TO_CONN(q));
8605 8606                  CONN_OPER_PENDING_DONE(Q_TO_CONN(q));
8606 8607          }
8607 8608  }
8608 8609  
8609 8610  /*
8610 8611   * Process I_{P}LINK and I_{P}UNLINK requests named by `ioccmd' and pointed to
8611 8612   * by `mp' and `li' for the IP module stream (if li->q_bot is in fact an IP
8612 8613   * module stream).
8613 8614   * Returns zero on success, EINPROGRESS if the operation is still pending, or
8614 8615   * an error code on failure.
8615 8616   */
8616 8617  static int
8617 8618  ip_sioctl_plink_ipmod(ipsq_t *ipsq, queue_t *q, mblk_t *mp, int ioccmd,
8618 8619      struct linkblk *li)
8619 8620  {
8620 8621          int             err = 0;
8621 8622          ill_t           *ill;
8622 8623          queue_t         *ipwq, *dwq;
8623 8624          const char      *name;
8624 8625          struct qinit    *qinfo;
8625 8626          boolean_t       islink = (ioccmd == I_PLINK || ioccmd == I_LINK);
8626 8627          boolean_t       entered_ipsq = B_FALSE;
8627 8628          boolean_t       is_ip = B_FALSE;
8628 8629          arl_t           *arl;
8629 8630  
8630 8631          /*
8631 8632           * Walk the lower stream to verify it's the IP module stream.
8632 8633           * The IP module is identified by its name, wput function,
8633 8634           * and non-NULL q_next.  STREAMS ensures that the lower stream
8634 8635           * (li->l_qbot) will not vanish until this ioctl completes.
8635 8636           */
8636 8637          for (ipwq = li->l_qbot; ipwq != NULL; ipwq = ipwq->q_next) {
8637 8638                  qinfo = ipwq->q_qinfo;
8638 8639                  name = qinfo->qi_minfo->mi_idname;
8639 8640                  if (name != NULL && strcmp(name, ip_mod_info.mi_idname) == 0 &&
8640 8641                      qinfo->qi_putp != (pfi_t)ip_lwput && ipwq->q_next != NULL) {
8641 8642                          is_ip = B_TRUE;
8642 8643                          break;
8643 8644                  }
8644 8645                  if (name != NULL && strcmp(name, arp_mod_info.mi_idname) == 0 &&
8645 8646                      qinfo->qi_putp != (pfi_t)ip_lwput && ipwq->q_next != NULL) {
8646 8647                          break;
8647 8648                  }
8648 8649          }
8649 8650  
8650 8651          /*
8651 8652           * If this isn't an IP module stream, bail.
8652 8653           */
8653 8654          if (ipwq == NULL)
8654 8655                  return (0);
8655 8656  
8656 8657          if (!is_ip) {
8657 8658                  arl = (arl_t *)ipwq->q_ptr;
8658 8659                  ill = arl_to_ill(arl);
8659 8660                  if (ill == NULL)
8660 8661                          return (0);
8661 8662          } else {
8662 8663                  ill = ipwq->q_ptr;
8663 8664          }
8664 8665          ASSERT(ill != NULL);
8665 8666  
8666 8667          if (ipsq == NULL) {
8667 8668                  ipsq = ipsq_try_enter(NULL, ill, q, mp, ip_sioctl_plink,
8668 8669                      NEW_OP, B_FALSE);
8669 8670                  if (ipsq == NULL) {
8670 8671                          if (!is_ip)
8671 8672                                  ill_refrele(ill);
8672 8673                          return (EINPROGRESS);
8673 8674                  }
8674 8675                  entered_ipsq = B_TRUE;
8675 8676          }
8676 8677          ASSERT(IAM_WRITER_ILL(ill));
8677 8678          mutex_enter(&ill->ill_lock);
8678 8679          if (!is_ip) {
8679 8680                  if (islink && ill->ill_muxid == 0) {
8680 8681                          /*
8681 8682                           * Plumbing has to be done with IP plumbed first, arp
8682 8683                           * second, but here we have arp being plumbed first.
8683 8684                           */
8684 8685                          mutex_exit(&ill->ill_lock);
8685 8686                          if (entered_ipsq)
8686 8687                                  ipsq_exit(ipsq);
8687 8688                          ill_refrele(ill);
8688 8689                          return (EINVAL);
8689 8690                  }
8690 8691          }
8691 8692          mutex_exit(&ill->ill_lock);
8692 8693          if (!is_ip) {
8693 8694                  arl->arl_muxid = islink ? li->l_index : 0;
8694 8695                  ill_refrele(ill);
8695 8696                  goto done;
8696 8697          }
8697 8698  
8698 8699          if (IS_IPMP(ill) && (err = ip_sioctl_plink_ipmp(ill, ioccmd)) != 0)
8699 8700                  goto done;
8700 8701  
8701 8702          /*
8702 8703           * As part of I_{P}LINKing, stash the number of downstream modules and
8703 8704           * the read queue of the module immediately below IP in the ill.
8704 8705           * These are used during the capability negotiation below.
8705 8706           */
8706 8707          ill->ill_lmod_rq = NULL;
8707 8708          ill->ill_lmod_cnt = 0;
8708 8709          if (islink && ((dwq = ipwq->q_next) != NULL)) {
8709 8710                  ill->ill_lmod_rq = RD(dwq);
8710 8711                  for (; dwq != NULL; dwq = dwq->q_next)
8711 8712                          ill->ill_lmod_cnt++;
8712 8713          }
8713 8714  
8714 8715          ill->ill_muxid = islink ? li->l_index : 0;
8715 8716  
8716 8717          /*
8717 8718           * Mark the ipsq busy until the capability operations initiated below
8718 8719           * complete. The PLINK/UNLINK ioctl itself completes when our caller
8719 8720           * returns, but the capability operation may complete asynchronously
8720 8721           * much later.
8721 8722           */
8722 8723          ipsq_current_start(ipsq, ill->ill_ipif, ioccmd);
8723 8724          /*
8724 8725           * If there's at least one up ipif on this ill, then we're bound to
8725 8726           * the underlying driver via DLPI.  In that case, renegotiate
8726 8727           * capabilities to account for any possible change in modules
8727 8728           * interposed between IP and the driver.
8728 8729           */
8729 8730          if (ill->ill_ipif_up_count > 0) {
8730 8731                  if (islink)
8731 8732                          ill_capability_probe(ill);
8732 8733                  else
8733 8734                          ill_capability_reset(ill, B_FALSE);
8734 8735          }
8735 8736          ipsq_current_finish(ipsq);
8736 8737  done:
8737 8738          if (entered_ipsq)
8738 8739                  ipsq_exit(ipsq);
8739 8740  
8740 8741          return (err);
8741 8742  }
8742 8743  
8743 8744  /*
8744 8745   * Search the ioctl command in the ioctl tables and return a pointer
8745 8746   * to the ioctl command information. The ioctl command tables are
8746 8747   * static and fully populated at compile time.
8747 8748   */
8748 8749  ip_ioctl_cmd_t *
8749 8750  ip_sioctl_lookup(int ioc_cmd)
8750 8751  {
8751 8752          int index;
8752 8753          ip_ioctl_cmd_t *ipip;
8753 8754          ip_ioctl_cmd_t *ipip_end;
8754 8755  
8755 8756          if (ioc_cmd == IPI_DONTCARE)
8756 8757                  return (NULL);
8757 8758  
8758 8759          /*
8759 8760           * Do a 2 step search. First search the indexed table
8760 8761           * based on the least significant byte of the ioctl cmd.
8761 8762           * If we don't find a match, then search the misc table
8762 8763           * serially.
8763 8764           */
8764 8765          index = ioc_cmd & 0xFF;
8765 8766          if (index < ip_ndx_ioctl_count) {
8766 8767                  ipip = &ip_ndx_ioctl_table[index];
8767 8768                  if (ipip->ipi_cmd == ioc_cmd) {
8768 8769                          /* Found a match in the ndx table */
8769 8770                          return (ipip);
8770 8771                  }
8771 8772          }
8772 8773  
8773 8774          /* Search the misc table */
8774 8775          ipip_end = &ip_misc_ioctl_table[ip_misc_ioctl_count];
8775 8776          for (ipip = ip_misc_ioctl_table; ipip < ipip_end; ipip++) {
8776 8777                  if (ipip->ipi_cmd == ioc_cmd)
8777 8778                          /* Found a match in the misc table */
8778 8779                          return (ipip);
8779 8780          }
8780 8781  
8781 8782          return (NULL);
8782 8783  }
8783 8784  
8784 8785  /*
8785 8786   * helper function for ip_sioctl_getsetprop(), which does some sanity checks
8786 8787   */
8787 8788  static boolean_t
8788 8789  getset_ioctl_checks(mblk_t *mp)
8789 8790  {
8790 8791          struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8791 8792          mblk_t          *mp1 = mp->b_cont;
8792 8793          mod_ioc_prop_t  *pioc;
8793 8794          uint_t          flags;
8794 8795          uint_t          pioc_size;
8795 8796  
8796 8797          /* do sanity checks on various arguments */
8797 8798          if (mp1 == NULL || iocp->ioc_count == 0 ||
8798 8799              iocp->ioc_count == TRANSPARENT) {
8799 8800                  return (B_FALSE);
8800 8801          }
8801 8802          if (msgdsize(mp1) < iocp->ioc_count) {
8802 8803                  if (!pullupmsg(mp1, iocp->ioc_count))
8803 8804                          return (B_FALSE);
8804 8805          }
8805 8806  
8806 8807          pioc = (mod_ioc_prop_t *)mp1->b_rptr;
8807 8808  
8808 8809          /* sanity checks on mpr_valsize */
8809 8810          pioc_size = sizeof (mod_ioc_prop_t);
8810 8811          if (pioc->mpr_valsize != 0)
8811 8812                  pioc_size += pioc->mpr_valsize - 1;
8812 8813  
8813 8814          if (iocp->ioc_count != pioc_size)
8814 8815                  return (B_FALSE);
8815 8816  
8816 8817          flags = pioc->mpr_flags;
8817 8818          if (iocp->ioc_cmd == SIOCSETPROP) {
8818 8819                  /*
8819 8820                   * One can either reset the value to it's default value or
8820 8821                   * change the current value or append/remove the value from
8821 8822                   * a multi-valued properties.
8822 8823                   */
8823 8824                  if ((flags & MOD_PROP_DEFAULT) != MOD_PROP_DEFAULT &&
8824 8825                      flags != MOD_PROP_ACTIVE &&
8825 8826                      flags != (MOD_PROP_ACTIVE|MOD_PROP_APPEND) &&
8826 8827                      flags != (MOD_PROP_ACTIVE|MOD_PROP_REMOVE))
8827 8828                          return (B_FALSE);
8828 8829          } else {
8829 8830                  ASSERT(iocp->ioc_cmd == SIOCGETPROP);
8830 8831  
8831 8832                  /*
8832 8833                   * One can retrieve only one kind of property information
8833 8834                   * at a time.
8834 8835                   */
8835 8836                  if ((flags & MOD_PROP_ACTIVE) != MOD_PROP_ACTIVE &&
8836 8837                      (flags & MOD_PROP_DEFAULT) != MOD_PROP_DEFAULT &&
8837 8838                      (flags & MOD_PROP_POSSIBLE) != MOD_PROP_POSSIBLE &&
8838 8839                      (flags & MOD_PROP_PERM) != MOD_PROP_PERM)
8839 8840                          return (B_FALSE);
8840 8841          }
8841 8842  
8842 8843          return (B_TRUE);
8843 8844  }
8844 8845  
8845 8846  /*
8846 8847   * process the SIOC{SET|GET}PROP ioctl's
8847 8848   */
8848 8849  /* ARGSUSED */
8849 8850  static void
  
    | 
      ↓ open down ↓ | 
    8733 lines elided | 
    
      ↑ open up ↑ | 
  
8850 8851  ip_sioctl_getsetprop(queue_t *q, mblk_t *mp)
8851 8852  {
8852 8853          struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8853 8854          mblk_t          *mp1 = mp->b_cont;
8854 8855          mod_ioc_prop_t  *pioc;
8855 8856          mod_prop_info_t *ptbl = NULL, *pinfo = NULL;
8856 8857          ip_stack_t      *ipst;
8857 8858          icmp_stack_t    *is;
8858 8859          tcp_stack_t     *tcps;
8859 8860          sctp_stack_t    *sctps;
     8861 +        dccp_stack_t    *dccps;
8860 8862          udp_stack_t     *us;
8861 8863          netstack_t      *stack;
8862 8864          void            *cbarg;
8863 8865          cred_t          *cr;
8864 8866          boolean_t       set;
8865 8867          int             err;
8866 8868  
8867 8869          ASSERT(q->q_next == NULL);
8868 8870          ASSERT(CONN_Q(q));
8869 8871  
8870 8872          if (!getset_ioctl_checks(mp)) {
8871 8873                  miocnak(q, mp, 0, EINVAL);
8872 8874                  return;
8873 8875          }
8874 8876          ipst = CONNQ_TO_IPST(q);
8875 8877          stack = ipst->ips_netstack;
8876 8878          pioc = (mod_ioc_prop_t *)mp1->b_rptr;
8877 8879  
8878 8880          switch (pioc->mpr_proto) {
8879 8881          case MOD_PROTO_IP:
8880 8882          case MOD_PROTO_IPV4:
8881 8883          case MOD_PROTO_IPV6:
8882 8884                  ptbl = ipst->ips_propinfo_tbl;
8883 8885                  cbarg = ipst;
8884 8886                  break;
8885 8887          case MOD_PROTO_RAWIP:
8886 8888                  is = stack->netstack_icmp;
8887 8889                  ptbl = is->is_propinfo_tbl;
8888 8890                  cbarg = is;
8889 8891                  break;
8890 8892          case MOD_PROTO_TCP:
8891 8893                  tcps = stack->netstack_tcp;
8892 8894                  ptbl = tcps->tcps_propinfo_tbl;
8893 8895                  cbarg = tcps;
8894 8896                  break;
  
    | 
      ↓ open down ↓ | 
    25 lines elided | 
    
      ↑ open up ↑ | 
  
8895 8897          case MOD_PROTO_UDP:
8896 8898                  us = stack->netstack_udp;
8897 8899                  ptbl = us->us_propinfo_tbl;
8898 8900                  cbarg = us;
8899 8901                  break;
8900 8902          case MOD_PROTO_SCTP:
8901 8903                  sctps = stack->netstack_sctp;
8902 8904                  ptbl = sctps->sctps_propinfo_tbl;
8903 8905                  cbarg = sctps;
8904 8906                  break;
     8907 +        case MOD_PROTO_DCCP:
     8908 +                dccps = stack->netstack_dccp;
     8909 +                ptbl = dccps->dccps_propinfo_tbl;
     8910 +                cbarg = dccps;
8905 8911          default:
8906 8912                  miocnak(q, mp, 0, EINVAL);
8907 8913                  return;
8908 8914          }
8909 8915  
8910 8916          /* search for given property in respective protocol propinfo table */
8911 8917          for (pinfo = ptbl; pinfo->mpi_name != NULL; pinfo++) {
8912 8918                  if (strcmp(pinfo->mpi_name, pioc->mpr_name) == 0 &&
8913 8919                      pinfo->mpi_proto == pioc->mpr_proto)
8914 8920                          break;
8915 8921          }
8916 8922          if (pinfo->mpi_name == NULL) {
8917 8923                  miocnak(q, mp, 0, ENOENT);
8918 8924                  return;
8919 8925          }
8920 8926  
8921 8927          set = (iocp->ioc_cmd == SIOCSETPROP) ? B_TRUE : B_FALSE;
8922 8928          if (set && pinfo->mpi_setf != NULL) {
8923 8929                  cr = msg_getcred(mp, NULL);
8924 8930                  if (cr == NULL)
8925 8931                          cr = iocp->ioc_cr;
8926 8932                  err = pinfo->mpi_setf(cbarg, cr, pinfo, pioc->mpr_ifname,
8927 8933                      pioc->mpr_val, pioc->mpr_flags);
8928 8934          } else if (!set && pinfo->mpi_getf != NULL) {
8929 8935                  err = pinfo->mpi_getf(cbarg, pinfo, pioc->mpr_ifname,
8930 8936                      pioc->mpr_val, pioc->mpr_valsize, pioc->mpr_flags);
8931 8937          } else {
8932 8938                  err = EPERM;
8933 8939          }
8934 8940  
8935 8941          if (err != 0) {
8936 8942                  miocnak(q, mp, 0, err);
8937 8943          } else {
8938 8944                  if (set)
8939 8945                          miocack(q, mp, 0, 0);
8940 8946                  else    /* For get, we need to return back the data */
8941 8947                          miocack(q, mp, iocp->ioc_count, 0);
8942 8948          }
8943 8949  }
8944 8950  
8945 8951  /*
8946 8952   * process the legacy ND_GET, ND_SET ioctl just for {ip|ip6}_forwarding
8947 8953   * as several routing daemons have unfortunately used this 'unpublished'
8948 8954   * but well-known ioctls.
8949 8955   */
8950 8956  /* ARGSUSED */
8951 8957  static void
8952 8958  ip_process_legacy_nddprop(queue_t *q, mblk_t *mp)
8953 8959  {
8954 8960          struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8955 8961          mblk_t          *mp1 = mp->b_cont;
8956 8962          char            *pname, *pval, *buf;
8957 8963          uint_t          bufsize, proto;
8958 8964          mod_prop_info_t *ptbl = NULL, *pinfo = NULL;
8959 8965          ip_stack_t      *ipst;
8960 8966          int             err = 0;
8961 8967  
8962 8968          ASSERT(CONN_Q(q));
8963 8969          ipst = CONNQ_TO_IPST(q);
8964 8970  
8965 8971          if (iocp->ioc_count == 0 || mp1 == NULL) {
8966 8972                  miocnak(q, mp, 0, EINVAL);
8967 8973                  return;
8968 8974          }
8969 8975  
8970 8976          mp1->b_datap->db_lim[-1] = '\0';        /* Force null termination */
8971 8977          pval = buf = pname = (char *)mp1->b_rptr;
8972 8978          bufsize = MBLKL(mp1);
8973 8979  
8974 8980          if (strcmp(pname, "ip_forwarding") == 0) {
8975 8981                  pname = "forwarding";
8976 8982                  proto = MOD_PROTO_IPV4;
8977 8983          } else if (strcmp(pname, "ip6_forwarding") == 0) {
8978 8984                  pname = "forwarding";
8979 8985                  proto = MOD_PROTO_IPV6;
8980 8986          } else {
8981 8987                  miocnak(q, mp, 0, EINVAL);
8982 8988                  return;
8983 8989          }
8984 8990  
8985 8991          ptbl = ipst->ips_propinfo_tbl;
8986 8992          for (pinfo = ptbl; pinfo->mpi_name != NULL; pinfo++) {
8987 8993                  if (strcmp(pinfo->mpi_name, pname) == 0 &&
8988 8994                      pinfo->mpi_proto == proto)
8989 8995                          break;
8990 8996          }
8991 8997  
8992 8998          ASSERT(pinfo->mpi_name != NULL);
8993 8999  
8994 9000          switch (iocp->ioc_cmd) {
8995 9001          case ND_GET:
8996 9002                  if ((err = pinfo->mpi_getf(ipst, pinfo, NULL, buf, bufsize,
8997 9003                      0)) == 0) {
8998 9004                          miocack(q, mp, iocp->ioc_count, 0);
8999 9005                          return;
9000 9006                  }
9001 9007                  break;
9002 9008          case ND_SET:
9003 9009                  /*
9004 9010                   * buffer will have property name and value in the following
9005 9011                   * format,
9006 9012                   * <property name>'\0'<property value>'\0', extract them;
9007 9013                   */
9008 9014                  while (*pval++)
9009 9015                          noop;
9010 9016  
9011 9017                  if (!*pval || pval >= (char *)mp1->b_wptr) {
9012 9018                          err = EINVAL;
9013 9019                  } else if ((err = pinfo->mpi_setf(ipst, NULL, pinfo, NULL,
9014 9020                      pval, 0)) == 0) {
9015 9021                          miocack(q, mp, 0, 0);
9016 9022                          return;
9017 9023                  }
9018 9024                  break;
9019 9025          default:
9020 9026                  err = EINVAL;
9021 9027                  break;
9022 9028          }
9023 9029          miocnak(q, mp, 0, err);
9024 9030  }
9025 9031  
9026 9032  /*
9027 9033   * Wrapper function for resuming deferred ioctl processing
9028 9034   * Used for SIOCGDSTINFO, SIOCGIP6ADDRPOLICY, SIOCGMSFILTER,
9029 9035   * SIOCSMSFILTER, SIOCGIPMSFILTER, and SIOCSIPMSFILTER currently.
9030 9036   */
9031 9037  /* ARGSUSED */
9032 9038  void
9033 9039  ip_sioctl_copyin_resume(ipsq_t *dummy_ipsq, queue_t *q, mblk_t *mp,
9034 9040      void *dummy_arg)
9035 9041  {
9036 9042          ip_sioctl_copyin_setup(q, mp);
9037 9043  }
9038 9044  
9039 9045  /*
9040 9046   * ip_sioctl_copyin_setup is called by ip_wput_nondata with any M_IOCTL message
9041 9047   * that arrives.  Most of the IOCTLs are "socket" IOCTLs which we handle
9042 9048   * in either I_STR or TRANSPARENT form, using the mi_copy facility.
9043 9049   * We establish here the size of the block to be copied in.  mi_copyin
9044 9050   * arranges for this to happen, an processing continues in ip_wput_nondata with
9045 9051   * an M_IOCDATA message.
9046 9052   */
9047 9053  void
9048 9054  ip_sioctl_copyin_setup(queue_t *q, mblk_t *mp)
9049 9055  {
9050 9056          int     copyin_size;
9051 9057          struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
9052 9058          ip_ioctl_cmd_t *ipip;
9053 9059          cred_t *cr;
9054 9060          ip_stack_t      *ipst;
9055 9061  
9056 9062          if (CONN_Q(q))
9057 9063                  ipst = CONNQ_TO_IPST(q);
9058 9064          else
9059 9065                  ipst = ILLQ_TO_IPST(q);
9060 9066  
9061 9067          ipip = ip_sioctl_lookup(iocp->ioc_cmd);
9062 9068          if (ipip == NULL) {
9063 9069                  /*
9064 9070                   * The ioctl is not one we understand or own.
9065 9071                   * Pass it along to be processed down stream,
9066 9072                   * if this is a module instance of IP, else nak
9067 9073                   * the ioctl.
9068 9074                   */
9069 9075                  if (q->q_next == NULL) {
9070 9076                          goto nak;
9071 9077                  } else {
9072 9078                          putnext(q, mp);
9073 9079                          return;
9074 9080                  }
9075 9081          }
9076 9082  
9077 9083          /*
9078 9084           * If this is deferred, then we will do all the checks when we
9079 9085           * come back.
9080 9086           */
9081 9087          if ((iocp->ioc_cmd == SIOCGDSTINFO ||
9082 9088              iocp->ioc_cmd == SIOCGIP6ADDRPOLICY) && !ip6_asp_can_lookup(ipst)) {
9083 9089                  ip6_asp_pending_op(q, mp, ip_sioctl_copyin_resume);
9084 9090                  return;
9085 9091          }
9086 9092  
9087 9093          /*
9088 9094           * Only allow a very small subset of IP ioctls on this stream if
9089 9095           * IP is a module and not a driver. Allowing ioctls to be processed
9090 9096           * in this case may cause assert failures or data corruption.
9091 9097           * Typically G[L]IFFLAGS, SLIFNAME/IF_UNITSEL are the only few
9092 9098           * ioctls allowed on an IP module stream, after which this stream
9093 9099           * normally becomes a multiplexor (at which time the stream head
9094 9100           * will fail all ioctls).
9095 9101           */
9096 9102          if ((q->q_next != NULL) && !(ipip->ipi_flags & IPI_MODOK)) {
9097 9103                  goto nak;
9098 9104          }
9099 9105  
9100 9106          /* Make sure we have ioctl data to process. */
9101 9107          if (mp->b_cont == NULL && !(ipip->ipi_flags & IPI_NULL_BCONT))
9102 9108                  goto nak;
9103 9109  
9104 9110          /*
9105 9111           * Prefer dblk credential over ioctl credential; some synthesized
9106 9112           * ioctls have kcred set because there's no way to crhold()
9107 9113           * a credential in some contexts.  (ioc_cr is not crfree() by
9108 9114           * the framework; the caller of ioctl needs to hold the reference
9109 9115           * for the duration of the call).
9110 9116           */
9111 9117          cr = msg_getcred(mp, NULL);
9112 9118          if (cr == NULL)
9113 9119                  cr = iocp->ioc_cr;
9114 9120  
9115 9121          /* Make sure normal users don't send down privileged ioctls */
9116 9122          if ((ipip->ipi_flags & IPI_PRIV) &&
9117 9123              (cr != NULL) && secpolicy_ip_config(cr, B_TRUE) != 0) {
9118 9124                  /* We checked the privilege earlier but log it here */
9119 9125                  miocnak(q, mp, 0, secpolicy_ip_config(cr, B_FALSE));
9120 9126                  return;
9121 9127          }
9122 9128  
9123 9129          /*
9124 9130           * The ioctl command tables can only encode fixed length
9125 9131           * ioctl data. If the length is variable, the table will
9126 9132           * encode the length as zero. Such special cases are handled
9127 9133           * below in the switch.
9128 9134           */
9129 9135          if (ipip->ipi_copyin_size != 0) {
9130 9136                  mi_copyin(q, mp, NULL, ipip->ipi_copyin_size);
9131 9137                  return;
9132 9138          }
9133 9139  
9134 9140          switch (iocp->ioc_cmd) {
9135 9141          case O_SIOCGIFCONF:
9136 9142          case SIOCGIFCONF:
9137 9143                  /*
9138 9144                   * This IOCTL is hilarious.  See comments in
9139 9145                   * ip_sioctl_get_ifconf for the story.
9140 9146                   */
9141 9147                  if (iocp->ioc_count == TRANSPARENT)
9142 9148                          copyin_size = SIZEOF_STRUCT(ifconf,
9143 9149                              iocp->ioc_flag);
9144 9150                  else
9145 9151                          copyin_size = iocp->ioc_count;
9146 9152                  mi_copyin(q, mp, NULL, copyin_size);
9147 9153                  return;
9148 9154  
9149 9155          case O_SIOCGLIFCONF:
9150 9156          case SIOCGLIFCONF:
9151 9157                  copyin_size = SIZEOF_STRUCT(lifconf, iocp->ioc_flag);
9152 9158                  mi_copyin(q, mp, NULL, copyin_size);
9153 9159                  return;
9154 9160  
9155 9161          case SIOCGLIFSRCOF:
9156 9162                  copyin_size = SIZEOF_STRUCT(lifsrcof, iocp->ioc_flag);
9157 9163                  mi_copyin(q, mp, NULL, copyin_size);
9158 9164                  return;
9159 9165  
9160 9166          case SIOCGIP6ADDRPOLICY:
9161 9167                  ip_sioctl_ip6addrpolicy(q, mp);
9162 9168                  ip6_asp_table_refrele(ipst);
9163 9169                  return;
9164 9170  
9165 9171          case SIOCSIP6ADDRPOLICY:
9166 9172                  ip_sioctl_ip6addrpolicy(q, mp);
9167 9173                  return;
9168 9174  
9169 9175          case SIOCGDSTINFO:
9170 9176                  ip_sioctl_dstinfo(q, mp);
9171 9177                  ip6_asp_table_refrele(ipst);
9172 9178                  return;
9173 9179  
9174 9180          case ND_SET:
9175 9181          case ND_GET:
9176 9182                  ip_process_legacy_nddprop(q, mp);
9177 9183                  return;
9178 9184  
9179 9185          case SIOCSETPROP:
9180 9186          case SIOCGETPROP:
9181 9187                  ip_sioctl_getsetprop(q, mp);
9182 9188                  return;
9183 9189  
9184 9190          case I_PLINK:
9185 9191          case I_PUNLINK:
9186 9192          case I_LINK:
9187 9193          case I_UNLINK:
9188 9194                  /*
9189 9195                   * We treat non-persistent link similarly as the persistent
9190 9196                   * link case, in terms of plumbing/unplumbing, as well as
9191 9197                   * dynamic re-plumbing events indicator.  See comments
9192 9198                   * in ip_sioctl_plink() for more.
9193 9199                   *
9194 9200                   * Request can be enqueued in the 'ipsq' while waiting
9195 9201                   * to become exclusive. So bump up the conn ref.
9196 9202                   */
9197 9203                  if (CONN_Q(q)) {
9198 9204                          CONN_INC_REF(Q_TO_CONN(q));
9199 9205                          CONN_INC_IOCTLREF(Q_TO_CONN(q))
9200 9206                  }
9201 9207                  ip_sioctl_plink(NULL, q, mp, NULL);
9202 9208                  return;
9203 9209  
9204 9210          case IP_IOCTL:
9205 9211                  ip_wput_ioctl(q, mp);
9206 9212                  return;
9207 9213  
9208 9214          case SIOCILB:
9209 9215                  /* The ioctl length varies depending on the ILB command. */
9210 9216                  copyin_size = iocp->ioc_count;
9211 9217                  if (copyin_size < sizeof (ilb_cmd_t))
9212 9218                          goto nak;
9213 9219                  mi_copyin(q, mp, NULL, copyin_size);
9214 9220                  return;
9215 9221  
9216 9222          default:
9217 9223                  cmn_err(CE_PANIC, "should not happen ");
9218 9224          }
9219 9225  nak:
9220 9226          if (mp->b_cont != NULL) {
9221 9227                  freemsg(mp->b_cont);
9222 9228                  mp->b_cont = NULL;
9223 9229          }
9224 9230          iocp->ioc_error = EINVAL;
9225 9231          mp->b_datap->db_type = M_IOCNAK;
9226 9232          iocp->ioc_count = 0;
9227 9233          qreply(q, mp);
9228 9234  }
9229 9235  
9230 9236  static void
9231 9237  ip_sioctl_garp_reply(mblk_t *mp, ill_t *ill, void *hwaddr, int flags)
9232 9238  {
9233 9239          struct arpreq *ar;
9234 9240          struct xarpreq *xar;
9235 9241          mblk_t  *tmp;
9236 9242          struct iocblk *iocp;
9237 9243          int x_arp_ioctl = B_FALSE;
9238 9244          int *flagsp;
9239 9245          char *storage = NULL;
9240 9246  
9241 9247          ASSERT(ill != NULL);
9242 9248  
9243 9249          iocp = (struct iocblk *)mp->b_rptr;
9244 9250          ASSERT(iocp->ioc_cmd == SIOCGXARP || iocp->ioc_cmd == SIOCGARP);
9245 9251  
9246 9252          tmp = (mp->b_cont)->b_cont; /* xarpreq/arpreq */
9247 9253          if ((iocp->ioc_cmd == SIOCGXARP) ||
9248 9254              (iocp->ioc_cmd == SIOCSXARP)) {
9249 9255                  x_arp_ioctl = B_TRUE;
9250 9256                  xar = (struct xarpreq *)tmp->b_rptr;
9251 9257                  flagsp = &xar->xarp_flags;
9252 9258                  storage = xar->xarp_ha.sdl_data;
9253 9259          } else {
9254 9260                  ar = (struct arpreq *)tmp->b_rptr;
9255 9261                  flagsp = &ar->arp_flags;
9256 9262                  storage = ar->arp_ha.sa_data;
9257 9263          }
9258 9264  
9259 9265          /*
9260 9266           * We're done if this is not an SIOCG{X}ARP
9261 9267           */
9262 9268          if (x_arp_ioctl) {
9263 9269                  storage += ill_xarp_info(&xar->xarp_ha, ill);
9264 9270                  if ((ill->ill_phys_addr_length + ill->ill_name_length) >
9265 9271                      sizeof (xar->xarp_ha.sdl_data)) {
9266 9272                          iocp->ioc_error = EINVAL;
9267 9273                          return;
9268 9274                  }
9269 9275          }
9270 9276          *flagsp = ATF_INUSE;
9271 9277          /*
9272 9278           * If /sbin/arp told us we are the authority using the "permanent"
9273 9279           * flag, or if this is one of my addresses print "permanent"
9274 9280           * in the /sbin/arp output.
9275 9281           */
9276 9282          if ((flags & NCE_F_MYADDR) || (flags & NCE_F_AUTHORITY))
9277 9283                  *flagsp |= ATF_AUTHORITY;
9278 9284          if (flags & NCE_F_NONUD)
9279 9285                  *flagsp |= ATF_PERM; /* not subject to aging */
9280 9286          if (flags & NCE_F_PUBLISH)
9281 9287                  *flagsp |= ATF_PUBL;
9282 9288          if (hwaddr != NULL) {
9283 9289                  *flagsp |= ATF_COM;
9284 9290                  bcopy((char *)hwaddr, storage, ill->ill_phys_addr_length);
9285 9291          }
9286 9292  }
9287 9293  
9288 9294  /*
9289 9295   * Create a new logical interface. If ipif_id is zero (i.e. not a logical
9290 9296   * interface) create the next available logical interface for this
9291 9297   * physical interface.
9292 9298   * If ipif is NULL (i.e. the lookup didn't find one) attempt to create an
9293 9299   * ipif with the specified name.
9294 9300   *
9295 9301   * If the address family is not AF_UNSPEC then set the address as well.
9296 9302   *
9297 9303   * If ip_sioctl_addr returns EINPROGRESS then the ioctl (the copyout)
9298 9304   * is completed when the DL_BIND_ACK arrive in ip_rput_dlpi_writer.
9299 9305   *
9300 9306   * Executed as a writer on the ill.
9301 9307   * So no lock is needed to traverse the ipif chain, or examine the
9302 9308   * phyint flags.
9303 9309   */
9304 9310  /* ARGSUSED */
9305 9311  int
9306 9312  ip_sioctl_addif(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
9307 9313      ip_ioctl_cmd_t *dummy_ipip, void *dummy_ifreq)
9308 9314  {
9309 9315          mblk_t  *mp1;
9310 9316          struct lifreq *lifr;
9311 9317          boolean_t       isv6;
9312 9318          boolean_t       exists;
9313 9319          char    *name;
9314 9320          char    *endp;
9315 9321          char    *cp;
9316 9322          int     namelen;
9317 9323          ipif_t  *ipif;
9318 9324          long    id;
9319 9325          ipsq_t  *ipsq;
9320 9326          ill_t   *ill;
9321 9327          sin_t   *sin;
9322 9328          int     err = 0;
9323 9329          boolean_t found_sep = B_FALSE;
9324 9330          conn_t  *connp;
9325 9331          zoneid_t zoneid;
9326 9332          ip_stack_t *ipst = CONNQ_TO_IPST(q);
9327 9333  
9328 9334          ASSERT(q->q_next == NULL);
9329 9335          ip1dbg(("ip_sioctl_addif\n"));
9330 9336          /* Existence of mp1 has been checked in ip_wput_nondata */
9331 9337          mp1 = mp->b_cont->b_cont;
9332 9338          /*
9333 9339           * Null terminate the string to protect against buffer
9334 9340           * overrun. String was generated by user code and may not
9335 9341           * be trusted.
9336 9342           */
9337 9343          lifr = (struct lifreq *)mp1->b_rptr;
9338 9344          lifr->lifr_name[LIFNAMSIZ - 1] = '\0';
9339 9345          name = lifr->lifr_name;
9340 9346          ASSERT(CONN_Q(q));
9341 9347          connp = Q_TO_CONN(q);
9342 9348          isv6 = (connp->conn_family == AF_INET6);
9343 9349          zoneid = connp->conn_zoneid;
9344 9350          namelen = mi_strlen(name);
9345 9351          if (namelen == 0)
9346 9352                  return (EINVAL);
9347 9353  
9348 9354          exists = B_FALSE;
9349 9355          if ((namelen + 1 == sizeof (ipif_loopback_name)) &&
9350 9356              (mi_strcmp(name, ipif_loopback_name) == 0)) {
9351 9357                  /*
9352 9358                   * Allow creating lo0 using SIOCLIFADDIF.
9353 9359                   * can't be any other writer thread. So can pass null below
9354 9360                   * for the last 4 args to ipif_lookup_name.
9355 9361                   */
9356 9362                  ipif = ipif_lookup_on_name(lifr->lifr_name, namelen, B_TRUE,
9357 9363                      &exists, isv6, zoneid, ipst);
9358 9364                  /* Prevent any further action */
9359 9365                  if (ipif == NULL) {
9360 9366                          return (ENOBUFS);
9361 9367                  } else if (!exists) {
9362 9368                          /* We created the ipif now and as writer */
9363 9369                          ipif_refrele(ipif);
9364 9370                          return (0);
9365 9371                  } else {
9366 9372                          ill = ipif->ipif_ill;
9367 9373                          ill_refhold(ill);
9368 9374                          ipif_refrele(ipif);
9369 9375                  }
9370 9376          } else {
9371 9377                  /* Look for a colon in the name. */
9372 9378                  endp = &name[namelen];
9373 9379                  for (cp = endp; --cp > name; ) {
9374 9380                          if (*cp == IPIF_SEPARATOR_CHAR) {
9375 9381                                  found_sep = B_TRUE;
9376 9382                                  /*
9377 9383                                   * Reject any non-decimal aliases for plumbing
9378 9384                                   * of logical interfaces. Aliases with leading
9379 9385                                   * zeroes are also rejected as they introduce
9380 9386                                   * ambiguity in the naming of the interfaces.
9381 9387                                   * Comparing with "0" takes care of all such
9382 9388                                   * cases.
9383 9389                                   */
9384 9390                                  if ((strncmp("0", cp+1, 1)) == 0)
9385 9391                                          return (EINVAL);
9386 9392  
9387 9393                                  if (ddi_strtol(cp+1, &endp, 10, &id) != 0 ||
9388 9394                                      id <= 0 || *endp != '\0') {
9389 9395                                          return (EINVAL);
9390 9396                                  }
9391 9397                                  *cp = '\0';
9392 9398                                  break;
9393 9399                          }
9394 9400                  }
9395 9401                  ill = ill_lookup_on_name(name, B_FALSE, isv6, NULL, ipst);
9396 9402                  if (found_sep)
9397 9403                          *cp = IPIF_SEPARATOR_CHAR;
9398 9404                  if (ill == NULL)
9399 9405                          return (ENXIO);
9400 9406          }
9401 9407  
9402 9408          ipsq = ipsq_try_enter(NULL, ill, q, mp, ip_process_ioctl, NEW_OP,
9403 9409              B_TRUE);
9404 9410  
9405 9411          /*
9406 9412           * Release the refhold due to the lookup, now that we are excl
9407 9413           * or we are just returning
9408 9414           */
9409 9415          ill_refrele(ill);
9410 9416  
9411 9417          if (ipsq == NULL)
9412 9418                  return (EINPROGRESS);
9413 9419  
9414 9420          /* We are now exclusive on the IPSQ */
9415 9421          ASSERT(IAM_WRITER_ILL(ill));
9416 9422  
9417 9423          if (found_sep) {
9418 9424                  /* Now see if there is an IPIF with this unit number. */
9419 9425                  for (ipif = ill->ill_ipif; ipif != NULL;
9420 9426                      ipif = ipif->ipif_next) {
9421 9427                          if (ipif->ipif_id == id) {
9422 9428                                  err = EEXIST;
9423 9429                                  goto done;
9424 9430                          }
9425 9431                  }
9426 9432          }
9427 9433  
9428 9434          /*
9429 9435           * We use IRE_LOCAL for lo0:1 etc. for "receive only" use
9430 9436           * of lo0.  Plumbing for lo0:0 happens in ipif_lookup_on_name()
9431 9437           * instead.
9432 9438           */
9433 9439          if ((ipif = ipif_allocate(ill, found_sep ? id : -1, IRE_LOCAL,
9434 9440              B_TRUE, B_TRUE, &err)) == NULL) {
9435 9441                  goto done;
9436 9442          }
9437 9443  
9438 9444          /* Return created name with ioctl */
9439 9445          (void) sprintf(lifr->lifr_name, "%s%c%d", ill->ill_name,
9440 9446              IPIF_SEPARATOR_CHAR, ipif->ipif_id);
9441 9447          ip1dbg(("created %s\n", lifr->lifr_name));
9442 9448  
9443 9449          /* Set address */
9444 9450          sin = (sin_t *)&lifr->lifr_addr;
9445 9451          if (sin->sin_family != AF_UNSPEC) {
9446 9452                  err = ip_sioctl_addr(ipif, sin, q, mp,
9447 9453                      &ip_ndx_ioctl_table[SIOCLIFADDR_NDX], lifr);
9448 9454          }
9449 9455  
9450 9456  done:
9451 9457          ipsq_exit(ipsq);
9452 9458          return (err);
9453 9459  }
9454 9460  
9455 9461  /*
9456 9462   * Remove an existing logical interface. If ipif_id is zero (i.e. not a logical
9457 9463   * interface) delete it based on the IP address (on this physical interface).
9458 9464   * Otherwise delete it based on the ipif_id.
9459 9465   * Also, special handling to allow a removeif of lo0.
9460 9466   */
9461 9467  /* ARGSUSED */
9462 9468  int
9463 9469  ip_sioctl_removeif(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9464 9470      ip_ioctl_cmd_t *ipip, void *dummy_if_req)
9465 9471  {
9466 9472          conn_t          *connp;
9467 9473          ill_t           *ill = ipif->ipif_ill;
9468 9474          boolean_t        success;
9469 9475          ip_stack_t      *ipst;
9470 9476  
9471 9477          ipst = CONNQ_TO_IPST(q);
9472 9478  
9473 9479          ASSERT(q->q_next == NULL);
9474 9480          ip1dbg(("ip_sioctl_remove_if(%s:%u %p)\n",
9475 9481              ill->ill_name, ipif->ipif_id, (void *)ipif));
9476 9482          ASSERT(IAM_WRITER_IPIF(ipif));
9477 9483  
9478 9484          connp = Q_TO_CONN(q);
9479 9485          /*
9480 9486           * Special case for unplumbing lo0 (the loopback physical interface).
9481 9487           * If unplumbing lo0, the incoming address structure has been
9482 9488           * initialized to all zeros. When unplumbing lo0, all its logical
9483 9489           * interfaces must be removed too.
9484 9490           *
9485 9491           * Note that this interface may be called to remove a specific
9486 9492           * loopback logical interface (eg, lo0:1). But in that case
9487 9493           * ipif->ipif_id != 0 so that the code path for that case is the
9488 9494           * same as any other interface (meaning it skips the code directly
9489 9495           * below).
9490 9496           */
9491 9497          if (ipif->ipif_id == 0 && ill->ill_net_type == IRE_LOOPBACK) {
9492 9498                  if (sin->sin_family == AF_UNSPEC &&
9493 9499                      (IN6_IS_ADDR_UNSPECIFIED(&((sin6_t *)sin)->sin6_addr))) {
9494 9500                          /*
9495 9501                           * Mark it condemned. No new ref. will be made to ill.
9496 9502                           */
9497 9503                          mutex_enter(&ill->ill_lock);
9498 9504                          ill->ill_state_flags |= ILL_CONDEMNED;
9499 9505                          for (ipif = ill->ill_ipif; ipif != NULL;
9500 9506                              ipif = ipif->ipif_next) {
9501 9507                                  ipif->ipif_state_flags |= IPIF_CONDEMNED;
9502 9508                          }
9503 9509                          mutex_exit(&ill->ill_lock);
9504 9510  
9505 9511                          ipif = ill->ill_ipif;
9506 9512                          /* unplumb the loopback interface */
9507 9513                          ill_delete(ill);
9508 9514                          mutex_enter(&connp->conn_lock);
9509 9515                          mutex_enter(&ill->ill_lock);
9510 9516  
9511 9517                          /* Are any references to this ill active */
9512 9518                          if (ill_is_freeable(ill)) {
9513 9519                                  mutex_exit(&ill->ill_lock);
9514 9520                                  mutex_exit(&connp->conn_lock);
9515 9521                                  ill_delete_tail(ill);
9516 9522                                  mi_free(ill);
9517 9523                                  return (0);
9518 9524                          }
9519 9525                          success = ipsq_pending_mp_add(connp, ipif,
9520 9526                              CONNP_TO_WQ(connp), mp, ILL_FREE);
9521 9527                          mutex_exit(&connp->conn_lock);
9522 9528                          mutex_exit(&ill->ill_lock);
9523 9529                          if (success)
9524 9530                                  return (EINPROGRESS);
9525 9531                          else
9526 9532                                  return (EINTR);
9527 9533                  }
9528 9534          }
9529 9535  
9530 9536          if (ipif->ipif_id == 0) {
9531 9537                  ipsq_t *ipsq;
9532 9538  
9533 9539                  /* Find based on address */
9534 9540                  if (ipif->ipif_isv6) {
9535 9541                          sin6_t *sin6;
9536 9542  
9537 9543                          if (sin->sin_family != AF_INET6)
9538 9544                                  return (EAFNOSUPPORT);
9539 9545  
9540 9546                          sin6 = (sin6_t *)sin;
9541 9547                          /* We are a writer, so we should be able to lookup */
9542 9548                          ipif = ipif_lookup_addr_exact_v6(&sin6->sin6_addr, ill,
9543 9549                              ipst);
9544 9550                  } else {
9545 9551                          if (sin->sin_family != AF_INET)
9546 9552                                  return (EAFNOSUPPORT);
9547 9553  
9548 9554                          /* We are a writer, so we should be able to lookup */
9549 9555                          ipif = ipif_lookup_addr_exact(sin->sin_addr.s_addr, ill,
9550 9556                              ipst);
9551 9557                  }
9552 9558                  if (ipif == NULL) {
9553 9559                          return (EADDRNOTAVAIL);
9554 9560                  }
9555 9561  
9556 9562                  /*
9557 9563                   * It is possible for a user to send an SIOCLIFREMOVEIF with
9558 9564                   * lifr_name of the physical interface but with an ip address
9559 9565                   * lifr_addr of a logical interface plumbed over it.
9560 9566                   * So update ipx_current_ipif now that ipif points to the
9561 9567                   * correct one.
9562 9568                   */
9563 9569                  ipsq = ipif->ipif_ill->ill_phyint->phyint_ipsq;
9564 9570                  ipsq->ipsq_xop->ipx_current_ipif = ipif;
9565 9571  
9566 9572                  /* This is a writer */
9567 9573                  ipif_refrele(ipif);
9568 9574          }
9569 9575  
9570 9576          /*
9571 9577           * Can not delete instance zero since it is tied to the ill.
9572 9578           */
9573 9579          if (ipif->ipif_id == 0)
9574 9580                  return (EBUSY);
9575 9581  
9576 9582          mutex_enter(&ill->ill_lock);
9577 9583          ipif->ipif_state_flags |= IPIF_CONDEMNED;
9578 9584          mutex_exit(&ill->ill_lock);
9579 9585  
9580 9586          ipif_free(ipif);
9581 9587  
9582 9588          mutex_enter(&connp->conn_lock);
9583 9589          mutex_enter(&ill->ill_lock);
9584 9590  
9585 9591          /* Are any references to this ipif active */
9586 9592          if (ipif_is_freeable(ipif)) {
9587 9593                  mutex_exit(&ill->ill_lock);
9588 9594                  mutex_exit(&connp->conn_lock);
9589 9595                  ipif_non_duplicate(ipif);
9590 9596                  (void) ipif_down_tail(ipif);
9591 9597                  ipif_free_tail(ipif); /* frees ipif */
9592 9598                  return (0);
9593 9599          }
9594 9600          success = ipsq_pending_mp_add(connp, ipif, CONNP_TO_WQ(connp), mp,
9595 9601              IPIF_FREE);
9596 9602          mutex_exit(&ill->ill_lock);
9597 9603          mutex_exit(&connp->conn_lock);
9598 9604          if (success)
9599 9605                  return (EINPROGRESS);
9600 9606          else
9601 9607                  return (EINTR);
9602 9608  }
9603 9609  
9604 9610  /*
9605 9611   * Restart the removeif ioctl. The refcnt has gone down to 0.
9606 9612   * The ipif is already condemned. So can't find it thru lookups.
9607 9613   */
9608 9614  /* ARGSUSED */
9609 9615  int
9610 9616  ip_sioctl_removeif_restart(ipif_t *ipif, sin_t *dummy_sin, queue_t *q,
9611 9617      mblk_t *mp, ip_ioctl_cmd_t *ipip, void *dummy_if_req)
9612 9618  {
9613 9619          ill_t *ill = ipif->ipif_ill;
9614 9620  
9615 9621          ASSERT(IAM_WRITER_IPIF(ipif));
9616 9622          ASSERT(ipif->ipif_state_flags & IPIF_CONDEMNED);
9617 9623  
9618 9624          ip1dbg(("ip_sioctl_removeif_restart(%s:%u %p)\n",
9619 9625              ill->ill_name, ipif->ipif_id, (void *)ipif));
9620 9626  
9621 9627          if (ipif->ipif_id == 0 && ill->ill_net_type == IRE_LOOPBACK) {
9622 9628                  ASSERT(ill->ill_state_flags & ILL_CONDEMNED);
9623 9629                  ill_delete_tail(ill);
9624 9630                  mi_free(ill);
9625 9631                  return (0);
9626 9632          }
9627 9633  
9628 9634          ipif_non_duplicate(ipif);
9629 9635          (void) ipif_down_tail(ipif);
9630 9636          ipif_free_tail(ipif);
9631 9637  
9632 9638          return (0);
9633 9639  }
9634 9640  
9635 9641  /*
9636 9642   * Set the local interface address using the given prefix and ill_token.
9637 9643   */
9638 9644  /* ARGSUSED */
9639 9645  int
9640 9646  ip_sioctl_prefix(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9641 9647      ip_ioctl_cmd_t *dummy_ipip, void *dummy_ifreq)
9642 9648  {
9643 9649          int err;
9644 9650          in6_addr_t v6addr;
9645 9651          sin6_t *sin6;
9646 9652          ill_t *ill;
9647 9653          int i;
9648 9654  
9649 9655          ip1dbg(("ip_sioctl_prefix(%s:%u %p)\n",
9650 9656              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
9651 9657  
9652 9658          ASSERT(IAM_WRITER_IPIF(ipif));
9653 9659  
9654 9660          if (!ipif->ipif_isv6)
9655 9661                  return (EINVAL);
9656 9662  
9657 9663          if (sin->sin_family != AF_INET6)
9658 9664                  return (EAFNOSUPPORT);
9659 9665  
9660 9666          sin6 = (sin6_t *)sin;
9661 9667          v6addr = sin6->sin6_addr;
9662 9668          ill = ipif->ipif_ill;
9663 9669  
9664 9670          if (IN6_IS_ADDR_UNSPECIFIED(&v6addr) ||
9665 9671              IN6_IS_ADDR_UNSPECIFIED(&ill->ill_token))
9666 9672                  return (EADDRNOTAVAIL);
9667 9673  
9668 9674          for (i = 0; i < 4; i++)
9669 9675                  sin6->sin6_addr.s6_addr32[i] |= ill->ill_token.s6_addr32[i];
9670 9676  
9671 9677          err = ip_sioctl_addr(ipif, sin, q, mp,
9672 9678              &ip_ndx_ioctl_table[SIOCLIFADDR_NDX], dummy_ifreq);
9673 9679          return (err);
9674 9680  }
9675 9681  
9676 9682  /*
9677 9683   * Restart entry point to restart the address set operation after the
9678 9684   * refcounts have dropped to zero.
9679 9685   */
9680 9686  /* ARGSUSED */
9681 9687  int
9682 9688  ip_sioctl_prefix_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9683 9689      ip_ioctl_cmd_t *ipip, void *ifreq)
9684 9690  {
9685 9691          ip1dbg(("ip_sioctl_prefix_restart(%s:%u %p)\n",
9686 9692              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
9687 9693          return (ip_sioctl_addr_restart(ipif, sin, q, mp, ipip, ifreq));
9688 9694  }
9689 9695  
9690 9696  /*
9691 9697   * Set the local interface address.
9692 9698   * Allow an address of all zero when the interface is down.
9693 9699   */
9694 9700  /* ARGSUSED */
9695 9701  int
9696 9702  ip_sioctl_addr(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9697 9703      ip_ioctl_cmd_t *dummy_ipip, void *dummy_ifreq)
9698 9704  {
9699 9705          int err = 0;
9700 9706          in6_addr_t v6addr;
9701 9707          boolean_t need_up = B_FALSE;
9702 9708          ill_t *ill;
9703 9709          int i;
9704 9710  
9705 9711          ip1dbg(("ip_sioctl_addr(%s:%u %p)\n",
9706 9712              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
9707 9713  
9708 9714          ASSERT(IAM_WRITER_IPIF(ipif));
9709 9715  
9710 9716          ill = ipif->ipif_ill;
9711 9717          if (ipif->ipif_isv6) {
9712 9718                  sin6_t *sin6;
9713 9719                  phyint_t *phyi;
9714 9720  
9715 9721                  if (sin->sin_family != AF_INET6)
9716 9722                          return (EAFNOSUPPORT);
9717 9723  
9718 9724                  sin6 = (sin6_t *)sin;
9719 9725                  v6addr = sin6->sin6_addr;
9720 9726                  phyi = ill->ill_phyint;
9721 9727  
9722 9728                  /*
9723 9729                   * Enforce that true multicast interfaces have a link-local
9724 9730                   * address for logical unit 0.
9725 9731                   *
9726 9732                   * However for those ipif's for which link-local address was
9727 9733                   * not created by default, also allow setting :: as the address.
9728 9734                   * This scenario would arise, when we delete an address on ipif
9729 9735                   * with logical unit 0, we would want to set :: as the address.
9730 9736                   */
9731 9737                  if (ipif->ipif_id == 0 &&
9732 9738                      (ill->ill_flags & ILLF_MULTICAST) &&
9733 9739                      !(ipif->ipif_flags & (IPIF_POINTOPOINT)) &&
9734 9740                      !(phyi->phyint_flags & (PHYI_LOOPBACK)) &&
9735 9741                      !IN6_IS_ADDR_LINKLOCAL(&v6addr)) {
9736 9742  
9737 9743                          /*
9738 9744                           * if default link-local was not created by kernel for
9739 9745                           * this ill, allow setting :: as the address on ipif:0.
9740 9746                           */
9741 9747                          if (ill->ill_flags & ILLF_NOLINKLOCAL) {
9742 9748                                  if (!IN6_IS_ADDR_UNSPECIFIED(&v6addr))
9743 9749                                          return (EADDRNOTAVAIL);
9744 9750                          } else {
9745 9751                                  return (EADDRNOTAVAIL);
9746 9752                          }
9747 9753                  }
9748 9754  
9749 9755                  /*
9750 9756                   * up interfaces shouldn't have the unspecified address
9751 9757                   * unless they also have the IPIF_NOLOCAL flags set and
9752 9758                   * have a subnet assigned.
9753 9759                   */
9754 9760                  if ((ipif->ipif_flags & IPIF_UP) &&
9755 9761                      IN6_IS_ADDR_UNSPECIFIED(&v6addr) &&
9756 9762                      (!(ipif->ipif_flags & IPIF_NOLOCAL) ||
9757 9763                      IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6subnet))) {
9758 9764                          return (EADDRNOTAVAIL);
9759 9765                  }
9760 9766  
9761 9767                  if (!ip_local_addr_ok_v6(&v6addr, &ipif->ipif_v6net_mask))
9762 9768                          return (EADDRNOTAVAIL);
9763 9769          } else {
9764 9770                  ipaddr_t addr;
9765 9771  
9766 9772                  if (sin->sin_family != AF_INET)
9767 9773                          return (EAFNOSUPPORT);
9768 9774  
9769 9775                  addr = sin->sin_addr.s_addr;
9770 9776  
9771 9777                  /* Allow INADDR_ANY as the local address. */
9772 9778                  if (addr != INADDR_ANY &&
9773 9779                      !ip_addr_ok_v4(addr, ipif->ipif_net_mask))
9774 9780                          return (EADDRNOTAVAIL);
9775 9781  
9776 9782                  IN6_IPADDR_TO_V4MAPPED(addr, &v6addr);
9777 9783          }
9778 9784          /*
9779 9785           * verify that the address being configured is permitted by the
9780 9786           * ill_allowed_ips[] for the interface.
9781 9787           */
9782 9788          if (ill->ill_allowed_ips_cnt > 0) {
9783 9789                  for (i = 0; i < ill->ill_allowed_ips_cnt; i++) {
9784 9790                          if (IN6_ARE_ADDR_EQUAL(&ill->ill_allowed_ips[i],
9785 9791                              &v6addr))
9786 9792                                  break;
9787 9793                  }
9788 9794                  if (i == ill->ill_allowed_ips_cnt) {
9789 9795                          pr_addr_dbg("!allowed addr %s\n", AF_INET6, &v6addr);
9790 9796                          return (EPERM);
9791 9797                  }
9792 9798          }
9793 9799          /*
9794 9800           * Even if there is no change we redo things just to rerun
9795 9801           * ipif_set_default.
9796 9802           */
9797 9803          if (ipif->ipif_flags & IPIF_UP) {
9798 9804                  /*
9799 9805                   * Setting a new local address, make sure
9800 9806                   * we have net and subnet bcast ire's for
9801 9807                   * the old address if we need them.
9802 9808                   */
9803 9809                  /*
9804 9810                   * If the interface is already marked up,
9805 9811                   * we call ipif_down which will take care
9806 9812                   * of ditching any IREs that have been set
9807 9813                   * up based on the old interface address.
9808 9814                   */
9809 9815                  err = ipif_logical_down(ipif, q, mp);
9810 9816                  if (err == EINPROGRESS)
9811 9817                          return (err);
9812 9818                  (void) ipif_down_tail(ipif);
9813 9819                  need_up = 1;
9814 9820          }
9815 9821  
9816 9822          err = ip_sioctl_addr_tail(ipif, sin, q, mp, need_up);
9817 9823          return (err);
9818 9824  }
9819 9825  
9820 9826  int
9821 9827  ip_sioctl_addr_tail(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9822 9828      boolean_t need_up)
9823 9829  {
9824 9830          in6_addr_t v6addr;
9825 9831          in6_addr_t ov6addr;
9826 9832          ipaddr_t addr;
9827 9833          sin6_t  *sin6;
9828 9834          int     sinlen;
9829 9835          int     err = 0;
9830 9836          ill_t   *ill = ipif->ipif_ill;
9831 9837          boolean_t need_dl_down;
9832 9838          boolean_t need_arp_down;
9833 9839          struct iocblk *iocp;
9834 9840  
9835 9841          iocp = (mp != NULL) ? (struct iocblk *)mp->b_rptr : NULL;
9836 9842  
9837 9843          ip1dbg(("ip_sioctl_addr_tail(%s:%u %p)\n",
9838 9844              ill->ill_name, ipif->ipif_id, (void *)ipif));
9839 9845          ASSERT(IAM_WRITER_IPIF(ipif));
9840 9846  
9841 9847          /* Must cancel any pending timer before taking the ill_lock */
9842 9848          if (ipif->ipif_recovery_id != 0)
9843 9849                  (void) untimeout(ipif->ipif_recovery_id);
9844 9850          ipif->ipif_recovery_id = 0;
9845 9851  
9846 9852          if (ipif->ipif_isv6) {
9847 9853                  sin6 = (sin6_t *)sin;
9848 9854                  v6addr = sin6->sin6_addr;
9849 9855                  sinlen = sizeof (struct sockaddr_in6);
9850 9856          } else {
9851 9857                  addr = sin->sin_addr.s_addr;
9852 9858                  IN6_IPADDR_TO_V4MAPPED(addr, &v6addr);
9853 9859                  sinlen = sizeof (struct sockaddr_in);
9854 9860          }
9855 9861          mutex_enter(&ill->ill_lock);
9856 9862          ov6addr = ipif->ipif_v6lcl_addr;
9857 9863          ipif->ipif_v6lcl_addr = v6addr;
9858 9864          sctp_update_ipif_addr(ipif, ov6addr);
9859 9865          ipif->ipif_addr_ready = 0;
9860 9866  
9861 9867          ip_rts_newaddrmsg(RTM_CHGADDR, 0, ipif, RTSQ_DEFAULT);
9862 9868  
9863 9869          /*
9864 9870           * If the interface was previously marked as a duplicate, then since
9865 9871           * we've now got a "new" address, it should no longer be considered a
9866 9872           * duplicate -- even if the "new" address is the same as the old one.
9867 9873           * Note that if all ipifs are down, we may have a pending ARP down
9868 9874           * event to handle.  This is because we want to recover from duplicates
9869 9875           * and thus delay tearing down ARP until the duplicates have been
9870 9876           * removed or disabled.
9871 9877           */
9872 9878          need_dl_down = need_arp_down = B_FALSE;
9873 9879          if (ipif->ipif_flags & IPIF_DUPLICATE) {
9874 9880                  need_arp_down = !need_up;
9875 9881                  ipif->ipif_flags &= ~IPIF_DUPLICATE;
9876 9882                  if (--ill->ill_ipif_dup_count == 0 && !need_up &&
9877 9883                      ill->ill_ipif_up_count == 0 && ill->ill_dl_up) {
9878 9884                          need_dl_down = B_TRUE;
9879 9885                  }
9880 9886          }
9881 9887  
9882 9888          ipif_set_default(ipif);
9883 9889  
9884 9890          /*
9885 9891           * If we've just manually set the IPv6 link-local address (0th ipif),
9886 9892           * tag the ill so that future updates to the interface ID don't result
9887 9893           * in this address getting automatically reconfigured from under the
9888 9894           * administrator.
9889 9895           */
9890 9896          if (ipif->ipif_isv6 && ipif->ipif_id == 0) {
9891 9897                  if (iocp == NULL || (iocp->ioc_cmd == SIOCSLIFADDR &&
9892 9898                      !IN6_IS_ADDR_UNSPECIFIED(&v6addr)))
9893 9899                          ill->ill_manual_linklocal = 1;
9894 9900          }
9895 9901  
9896 9902          /*
9897 9903           * When publishing an interface address change event, we only notify
9898 9904           * the event listeners of the new address.  It is assumed that if they
9899 9905           * actively care about the addresses assigned that they will have
9900 9906           * already discovered the previous address assigned (if there was one.)
9901 9907           *
9902 9908           * Don't attach nic event message for SIOCLIFADDIF ioctl.
9903 9909           */
9904 9910          if (iocp != NULL && iocp->ioc_cmd != SIOCLIFADDIF) {
9905 9911                  ill_nic_event_dispatch(ill, MAP_IPIF_ID(ipif->ipif_id),
9906 9912                      NE_ADDRESS_CHANGE, sin, sinlen);
9907 9913          }
9908 9914  
9909 9915          mutex_exit(&ill->ill_lock);
9910 9916  
9911 9917          if (need_up) {
9912 9918                  /*
9913 9919                   * Now bring the interface back up.  If this
9914 9920                   * is the only IPIF for the ILL, ipif_up
9915 9921                   * will have to re-bind to the device, so
9916 9922                   * we may get back EINPROGRESS, in which
9917 9923                   * case, this IOCTL will get completed in
9918 9924                   * ip_rput_dlpi when we see the DL_BIND_ACK.
9919 9925                   */
9920 9926                  err = ipif_up(ipif, q, mp);
9921 9927          } else {
9922 9928                  /* Perhaps ilgs should use this ill */
9923 9929                  update_conn_ill(NULL, ill->ill_ipst);
9924 9930          }
9925 9931  
9926 9932          if (need_dl_down)
9927 9933                  ill_dl_down(ill);
9928 9934  
9929 9935          if (need_arp_down && !ill->ill_isv6)
9930 9936                  (void) ipif_arp_down(ipif);
9931 9937  
9932 9938          /*
9933 9939           * The default multicast interface might have changed (for
9934 9940           * instance if the IPv6 scope of the address changed)
9935 9941           */
9936 9942          ire_increment_multicast_generation(ill->ill_ipst, ill->ill_isv6);
9937 9943  
9938 9944          return (err);
9939 9945  }
9940 9946  
9941 9947  /*
9942 9948   * Restart entry point to restart the address set operation after the
9943 9949   * refcounts have dropped to zero.
9944 9950   */
9945 9951  /* ARGSUSED */
9946 9952  int
9947 9953  ip_sioctl_addr_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9948 9954      ip_ioctl_cmd_t *ipip, void *ifreq)
9949 9955  {
9950 9956          ip1dbg(("ip_sioctl_addr_restart(%s:%u %p)\n",
9951 9957              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
9952 9958          ASSERT(IAM_WRITER_IPIF(ipif));
9953 9959          (void) ipif_down_tail(ipif);
9954 9960          return (ip_sioctl_addr_tail(ipif, sin, q, mp, B_TRUE));
9955 9961  }
9956 9962  
9957 9963  /* ARGSUSED */
9958 9964  int
9959 9965  ip_sioctl_get_addr(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9960 9966      ip_ioctl_cmd_t *ipip, void *if_req)
9961 9967  {
9962 9968          sin6_t *sin6 = (struct sockaddr_in6 *)sin;
9963 9969          struct lifreq *lifr = (struct lifreq *)if_req;
9964 9970  
9965 9971          ip1dbg(("ip_sioctl_get_addr(%s:%u %p)\n",
9966 9972              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
9967 9973          /*
9968 9974           * The net mask and address can't change since we have a
9969 9975           * reference to the ipif. So no lock is necessary.
9970 9976           */
9971 9977          if (ipif->ipif_isv6) {
9972 9978                  *sin6 = sin6_null;
9973 9979                  sin6->sin6_family = AF_INET6;
9974 9980                  sin6->sin6_addr = ipif->ipif_v6lcl_addr;
9975 9981                  ASSERT(ipip->ipi_cmd_type == LIF_CMD);
9976 9982                  lifr->lifr_addrlen =
9977 9983                      ip_mask_to_plen_v6(&ipif->ipif_v6net_mask);
9978 9984          } else {
9979 9985                  *sin = sin_null;
9980 9986                  sin->sin_family = AF_INET;
9981 9987                  sin->sin_addr.s_addr = ipif->ipif_lcl_addr;
9982 9988                  if (ipip->ipi_cmd_type == LIF_CMD) {
9983 9989                          lifr->lifr_addrlen =
9984 9990                              ip_mask_to_plen(ipif->ipif_net_mask);
9985 9991                  }
9986 9992          }
9987 9993          return (0);
9988 9994  }
9989 9995  
9990 9996  /*
9991 9997   * Set the destination address for a pt-pt interface.
9992 9998   */
9993 9999  /* ARGSUSED */
9994 10000  int
9995 10001  ip_sioctl_dstaddr(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
9996 10002      ip_ioctl_cmd_t *ipip, void *if_req)
9997 10003  {
9998 10004          int err = 0;
9999 10005          in6_addr_t v6addr;
10000 10006          boolean_t need_up = B_FALSE;
10001 10007  
10002 10008          ip1dbg(("ip_sioctl_dstaddr(%s:%u %p)\n",
10003 10009              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10004 10010          ASSERT(IAM_WRITER_IPIF(ipif));
10005 10011  
10006 10012          if (ipif->ipif_isv6) {
10007 10013                  sin6_t *sin6;
10008 10014  
10009 10015                  if (sin->sin_family != AF_INET6)
10010 10016                          return (EAFNOSUPPORT);
10011 10017  
10012 10018                  sin6 = (sin6_t *)sin;
10013 10019                  v6addr = sin6->sin6_addr;
10014 10020  
10015 10021                  if (!ip_remote_addr_ok_v6(&v6addr, &ipif->ipif_v6net_mask))
10016 10022                          return (EADDRNOTAVAIL);
10017 10023          } else {
10018 10024                  ipaddr_t addr;
10019 10025  
10020 10026                  if (sin->sin_family != AF_INET)
10021 10027                          return (EAFNOSUPPORT);
10022 10028  
10023 10029                  addr = sin->sin_addr.s_addr;
10024 10030                  if (addr != INADDR_ANY &&
10025 10031                      !ip_addr_ok_v4(addr, ipif->ipif_net_mask)) {
10026 10032                          return (EADDRNOTAVAIL);
10027 10033                  }
10028 10034  
10029 10035                  IN6_IPADDR_TO_V4MAPPED(addr, &v6addr);
10030 10036          }
10031 10037  
10032 10038          if (IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6pp_dst_addr, &v6addr))
10033 10039                  return (0);     /* No change */
10034 10040  
10035 10041          if (ipif->ipif_flags & IPIF_UP) {
10036 10042                  /*
10037 10043                   * If the interface is already marked up,
10038 10044                   * we call ipif_down which will take care
10039 10045                   * of ditching any IREs that have been set
10040 10046                   * up based on the old pp dst address.
10041 10047                   */
10042 10048                  err = ipif_logical_down(ipif, q, mp);
10043 10049                  if (err == EINPROGRESS)
10044 10050                          return (err);
10045 10051                  (void) ipif_down_tail(ipif);
10046 10052                  need_up = B_TRUE;
10047 10053          }
10048 10054          /*
10049 10055           * could return EINPROGRESS. If so ioctl will complete in
10050 10056           * ip_rput_dlpi_writer
10051 10057           */
10052 10058          err = ip_sioctl_dstaddr_tail(ipif, sin, q, mp, need_up);
10053 10059          return (err);
10054 10060  }
10055 10061  
10056 10062  static int
10057 10063  ip_sioctl_dstaddr_tail(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10058 10064      boolean_t need_up)
10059 10065  {
10060 10066          in6_addr_t v6addr;
10061 10067          ill_t   *ill = ipif->ipif_ill;
10062 10068          int     err = 0;
10063 10069          boolean_t need_dl_down;
10064 10070          boolean_t need_arp_down;
10065 10071  
10066 10072          ip1dbg(("ip_sioctl_dstaddr_tail(%s:%u %p)\n", ill->ill_name,
10067 10073              ipif->ipif_id, (void *)ipif));
10068 10074  
10069 10075          /* Must cancel any pending timer before taking the ill_lock */
10070 10076          if (ipif->ipif_recovery_id != 0)
10071 10077                  (void) untimeout(ipif->ipif_recovery_id);
10072 10078          ipif->ipif_recovery_id = 0;
10073 10079  
10074 10080          if (ipif->ipif_isv6) {
10075 10081                  sin6_t *sin6;
10076 10082  
10077 10083                  sin6 = (sin6_t *)sin;
10078 10084                  v6addr = sin6->sin6_addr;
10079 10085          } else {
10080 10086                  ipaddr_t addr;
10081 10087  
10082 10088                  addr = sin->sin_addr.s_addr;
10083 10089                  IN6_IPADDR_TO_V4MAPPED(addr, &v6addr);
10084 10090          }
10085 10091          mutex_enter(&ill->ill_lock);
10086 10092          /* Set point to point destination address. */
10087 10093          if ((ipif->ipif_flags & IPIF_POINTOPOINT) == 0) {
10088 10094                  /*
10089 10095                   * Allow this as a means of creating logical
10090 10096                   * pt-pt interfaces on top of e.g. an Ethernet.
10091 10097                   * XXX Undocumented HACK for testing.
10092 10098                   * pt-pt interfaces are created with NUD disabled.
10093 10099                   */
10094 10100                  ipif->ipif_flags |= IPIF_POINTOPOINT;
10095 10101                  ipif->ipif_flags &= ~IPIF_BROADCAST;
10096 10102                  if (ipif->ipif_isv6)
10097 10103                          ill->ill_flags |= ILLF_NONUD;
10098 10104          }
10099 10105  
10100 10106          /*
10101 10107           * If the interface was previously marked as a duplicate, then since
10102 10108           * we've now got a "new" address, it should no longer be considered a
10103 10109           * duplicate -- even if the "new" address is the same as the old one.
10104 10110           * Note that if all ipifs are down, we may have a pending ARP down
10105 10111           * event to handle.
10106 10112           */
10107 10113          need_dl_down = need_arp_down = B_FALSE;
10108 10114          if (ipif->ipif_flags & IPIF_DUPLICATE) {
10109 10115                  need_arp_down = !need_up;
10110 10116                  ipif->ipif_flags &= ~IPIF_DUPLICATE;
10111 10117                  if (--ill->ill_ipif_dup_count == 0 && !need_up &&
10112 10118                      ill->ill_ipif_up_count == 0 && ill->ill_dl_up) {
10113 10119                          need_dl_down = B_TRUE;
10114 10120                  }
10115 10121          }
10116 10122  
10117 10123          /*
10118 10124           * If we've just manually set the IPv6 destination link-local address
10119 10125           * (0th ipif), tag the ill so that future updates to the destination
10120 10126           * interface ID (as can happen with interfaces over IP tunnels) don't
10121 10127           * result in this address getting automatically reconfigured from
10122 10128           * under the administrator.
10123 10129           */
10124 10130          if (ipif->ipif_isv6 && ipif->ipif_id == 0)
10125 10131                  ill->ill_manual_dst_linklocal = 1;
10126 10132  
10127 10133          /* Set the new address. */
10128 10134          ipif->ipif_v6pp_dst_addr = v6addr;
10129 10135          /* Make sure subnet tracks pp_dst */
10130 10136          ipif->ipif_v6subnet = ipif->ipif_v6pp_dst_addr;
10131 10137          mutex_exit(&ill->ill_lock);
10132 10138  
10133 10139          if (need_up) {
10134 10140                  /*
10135 10141                   * Now bring the interface back up.  If this
10136 10142                   * is the only IPIF for the ILL, ipif_up
10137 10143                   * will have to re-bind to the device, so
10138 10144                   * we may get back EINPROGRESS, in which
10139 10145                   * case, this IOCTL will get completed in
10140 10146                   * ip_rput_dlpi when we see the DL_BIND_ACK.
10141 10147                   */
10142 10148                  err = ipif_up(ipif, q, mp);
10143 10149          }
10144 10150  
10145 10151          if (need_dl_down)
10146 10152                  ill_dl_down(ill);
10147 10153          if (need_arp_down && !ipif->ipif_isv6)
10148 10154                  (void) ipif_arp_down(ipif);
10149 10155  
10150 10156          return (err);
10151 10157  }
10152 10158  
10153 10159  /*
10154 10160   * Restart entry point to restart the dstaddress set operation after the
10155 10161   * refcounts have dropped to zero.
10156 10162   */
10157 10163  /* ARGSUSED */
10158 10164  int
10159 10165  ip_sioctl_dstaddr_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10160 10166      ip_ioctl_cmd_t *ipip, void *ifreq)
10161 10167  {
10162 10168          ip1dbg(("ip_sioctl_dstaddr_restart(%s:%u %p)\n",
10163 10169              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10164 10170          (void) ipif_down_tail(ipif);
10165 10171          return (ip_sioctl_dstaddr_tail(ipif, sin, q, mp, B_TRUE));
10166 10172  }
10167 10173  
10168 10174  /* ARGSUSED */
10169 10175  int
10170 10176  ip_sioctl_get_dstaddr(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10171 10177      ip_ioctl_cmd_t *ipip, void *if_req)
10172 10178  {
10173 10179          sin6_t  *sin6 = (struct sockaddr_in6 *)sin;
10174 10180  
10175 10181          ip1dbg(("ip_sioctl_get_dstaddr(%s:%u %p)\n",
10176 10182              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10177 10183          /*
10178 10184           * Get point to point destination address. The addresses can't
10179 10185           * change since we hold a reference to the ipif.
10180 10186           */
10181 10187          if ((ipif->ipif_flags & IPIF_POINTOPOINT) == 0)
10182 10188                  return (EADDRNOTAVAIL);
10183 10189  
10184 10190          if (ipif->ipif_isv6) {
10185 10191                  ASSERT(ipip->ipi_cmd_type == LIF_CMD);
10186 10192                  *sin6 = sin6_null;
10187 10193                  sin6->sin6_family = AF_INET6;
10188 10194                  sin6->sin6_addr = ipif->ipif_v6pp_dst_addr;
10189 10195          } else {
10190 10196                  *sin = sin_null;
10191 10197                  sin->sin_family = AF_INET;
10192 10198                  sin->sin_addr.s_addr = ipif->ipif_pp_dst_addr;
10193 10199          }
10194 10200          return (0);
10195 10201  }
10196 10202  
10197 10203  /*
10198 10204   * Check which flags will change by the given flags being set
10199 10205   * silently ignore flags which userland is not allowed to control.
10200 10206   * (Because these flags may change between SIOCGLIFFLAGS and
10201 10207   * SIOCSLIFFLAGS, and that's outside of userland's control,
10202 10208   * we need to silently ignore them rather than fail.)
10203 10209   */
10204 10210  static void
10205 10211  ip_sioctl_flags_onoff(ipif_t *ipif, uint64_t flags, uint64_t *onp,
10206 10212      uint64_t *offp)
10207 10213  {
10208 10214          ill_t           *ill = ipif->ipif_ill;
10209 10215          phyint_t        *phyi = ill->ill_phyint;
10210 10216          uint64_t        cantchange_flags, intf_flags;
10211 10217          uint64_t        turn_on, turn_off;
10212 10218  
10213 10219          intf_flags = ipif->ipif_flags | ill->ill_flags | phyi->phyint_flags;
10214 10220          cantchange_flags = IFF_CANTCHANGE;
10215 10221          if (IS_IPMP(ill))
10216 10222                  cantchange_flags |= IFF_IPMP_CANTCHANGE;
10217 10223          turn_on = (flags ^ intf_flags) & ~cantchange_flags;
10218 10224          turn_off = intf_flags & turn_on;
10219 10225          turn_on ^= turn_off;
10220 10226          *onp = turn_on;
10221 10227          *offp = turn_off;
10222 10228  }
10223 10229  
10224 10230  /*
10225 10231   * Set interface flags.  Many flags require special handling (e.g.,
10226 10232   * bringing the interface down); see below for details.
10227 10233   *
10228 10234   * NOTE : We really don't enforce that ipif_id zero should be used
10229 10235   *        for setting any flags other than IFF_LOGINT_FLAGS. This
10230 10236   *        is because applications generally does SICGLIFFLAGS and
10231 10237   *        ORs in the new flags (that affects the logical) and does a
10232 10238   *        SIOCSLIFFLAGS. Thus, "flags" below could contain bits other
10233 10239   *        than IFF_LOGINT_FLAGS. One could check whether "turn_on" - the
10234 10240   *        flags that will be turned on is correct with respect to
10235 10241   *        ipif_id 0. For backward compatibility reasons, it is not done.
10236 10242   */
10237 10243  /* ARGSUSED */
10238 10244  int
10239 10245  ip_sioctl_flags(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10240 10246      ip_ioctl_cmd_t *ipip, void *if_req)
10241 10247  {
10242 10248          uint64_t turn_on;
10243 10249          uint64_t turn_off;
10244 10250          int     err = 0;
10245 10251          phyint_t *phyi;
10246 10252          ill_t *ill;
10247 10253          conn_t *connp;
10248 10254          uint64_t intf_flags;
10249 10255          boolean_t phyint_flags_modified = B_FALSE;
10250 10256          uint64_t flags;
10251 10257          struct ifreq *ifr;
10252 10258          struct lifreq *lifr;
10253 10259          boolean_t set_linklocal = B_FALSE;
10254 10260  
10255 10261          ip1dbg(("ip_sioctl_flags(%s:%u %p)\n",
10256 10262              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10257 10263  
10258 10264          ASSERT(IAM_WRITER_IPIF(ipif));
10259 10265  
10260 10266          ill = ipif->ipif_ill;
10261 10267          phyi = ill->ill_phyint;
10262 10268  
10263 10269          if (ipip->ipi_cmd_type == IF_CMD) {
10264 10270                  ifr = (struct ifreq *)if_req;
10265 10271                  flags =  (uint64_t)(ifr->ifr_flags & 0x0000ffff);
10266 10272          } else {
10267 10273                  lifr = (struct lifreq *)if_req;
10268 10274                  flags = lifr->lifr_flags;
10269 10275          }
10270 10276  
10271 10277          intf_flags = ipif->ipif_flags | ill->ill_flags | phyi->phyint_flags;
10272 10278  
10273 10279          /*
10274 10280           * Have the flags been set correctly until now?
10275 10281           */
10276 10282          ASSERT((phyi->phyint_flags & ~(IFF_PHYINT_FLAGS)) == 0);
10277 10283          ASSERT((ill->ill_flags & ~(IFF_PHYINTINST_FLAGS)) == 0);
10278 10284          ASSERT((ipif->ipif_flags & ~(IFF_LOGINT_FLAGS)) == 0);
10279 10285          /*
10280 10286           * Compare the new flags to the old, and partition
10281 10287           * into those coming on and those going off.
10282 10288           * For the 16 bit command keep the bits above bit 16 unchanged.
10283 10289           */
10284 10290          if (ipip->ipi_cmd == SIOCSIFFLAGS)
10285 10291                  flags |= intf_flags & ~0xFFFF;
10286 10292  
10287 10293          /*
10288 10294           * Explicitly fail attempts to change flags that are always invalid on
10289 10295           * an IPMP meta-interface.
10290 10296           */
10291 10297          if (IS_IPMP(ill) && ((flags ^ intf_flags) & IFF_IPMP_INVALID))
10292 10298                  return (EINVAL);
10293 10299  
10294 10300          ip_sioctl_flags_onoff(ipif, flags, &turn_on, &turn_off);
10295 10301          if ((turn_on|turn_off) == 0)
10296 10302                  return (0);     /* No change */
10297 10303  
10298 10304          /*
10299 10305           * All test addresses must be IFF_DEPRECATED (to ensure source address
10300 10306           * selection avoids them) -- so force IFF_DEPRECATED on, and do not
10301 10307           * allow it to be turned off.
10302 10308           */
10303 10309          if ((turn_off & (IFF_DEPRECATED|IFF_NOFAILOVER)) == IFF_DEPRECATED &&
10304 10310              (turn_on|intf_flags) & IFF_NOFAILOVER)
10305 10311                  return (EINVAL);
10306 10312  
10307 10313          if ((connp = Q_TO_CONN(q)) == NULL)
10308 10314                  return (EINVAL);
10309 10315  
10310 10316          /*
10311 10317           * Only vrrp control socket is allowed to change IFF_UP and
10312 10318           * IFF_NOACCEPT flags when IFF_VRRP is set.
10313 10319           */
10314 10320          if ((intf_flags & IFF_VRRP) && ((turn_off | turn_on) & IFF_UP)) {
10315 10321                  if (!connp->conn_isvrrp)
10316 10322                          return (EINVAL);
10317 10323          }
10318 10324  
10319 10325          /*
10320 10326           * The IFF_NOACCEPT flag can only be set on an IFF_VRRP IP address by
10321 10327           * VRRP control socket.
10322 10328           */
10323 10329          if ((turn_off | turn_on) & IFF_NOACCEPT) {
10324 10330                  if (!connp->conn_isvrrp || !(intf_flags & IFF_VRRP))
10325 10331                          return (EINVAL);
10326 10332          }
10327 10333  
10328 10334          if (turn_on & IFF_NOFAILOVER) {
10329 10335                  turn_on |= IFF_DEPRECATED;
10330 10336                  flags |= IFF_DEPRECATED;
10331 10337          }
10332 10338  
10333 10339          /*
10334 10340           * On underlying interfaces, only allow applications to manage test
10335 10341           * addresses -- otherwise, they may get confused when the address
10336 10342           * moves as part of being brought up.  Likewise, prevent an
10337 10343           * application-managed test address from being converted to a data
10338 10344           * address.  To prevent migration of administratively up addresses in
10339 10345           * the kernel, we don't allow them to be converted either.
10340 10346           */
10341 10347          if (IS_UNDER_IPMP(ill)) {
10342 10348                  const uint64_t appflags = IFF_DHCPRUNNING | IFF_ADDRCONF;
10343 10349  
10344 10350                  if ((turn_on & appflags) && !(flags & IFF_NOFAILOVER))
10345 10351                          return (EINVAL);
10346 10352  
10347 10353                  if ((turn_off & IFF_NOFAILOVER) &&
10348 10354                      (flags & (appflags | IFF_UP | IFF_DUPLICATE)))
10349 10355                          return (EINVAL);
10350 10356          }
10351 10357  
10352 10358          /*
10353 10359           * Only allow IFF_TEMPORARY flag to be set on
10354 10360           * IPv6 interfaces.
10355 10361           */
10356 10362          if ((turn_on & IFF_TEMPORARY) && !(ipif->ipif_isv6))
10357 10363                  return (EINVAL);
10358 10364  
10359 10365          /*
10360 10366           * cannot turn off IFF_NOXMIT on  VNI interfaces.
10361 10367           */
10362 10368          if ((turn_off & IFF_NOXMIT) && IS_VNI(ipif->ipif_ill))
10363 10369                  return (EINVAL);
10364 10370  
10365 10371          /*
10366 10372           * Don't allow the IFF_ROUTER flag to be turned on on loopback
10367 10373           * interfaces.  It makes no sense in that context.
10368 10374           */
10369 10375          if ((turn_on & IFF_ROUTER) && (phyi->phyint_flags & PHYI_LOOPBACK))
10370 10376                  return (EINVAL);
10371 10377  
10372 10378          /*
10373 10379           * For IPv6 ipif_id 0, don't allow the interface to be up without
10374 10380           * a link local address if IFF_NOLOCAL or IFF_ANYCAST are not set.
10375 10381           * If the link local address isn't set, and can be set, it will get
10376 10382           * set later on in this function.
10377 10383           */
10378 10384          if (ipif->ipif_id == 0 && ipif->ipif_isv6 &&
10379 10385              (flags & IFF_UP) && !(flags & (IFF_NOLOCAL|IFF_ANYCAST)) &&
10380 10386              IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr)) {
10381 10387                  if (ipif_cant_setlinklocal(ipif))
10382 10388                          return (EINVAL);
10383 10389                  set_linklocal = B_TRUE;
10384 10390          }
10385 10391  
10386 10392          /*
10387 10393           * If we modify physical interface flags, we'll potentially need to
10388 10394           * send up two routing socket messages for the changes (one for the
10389 10395           * IPv4 ill, and another for the IPv6 ill).  Note that here.
10390 10396           */
10391 10397          if ((turn_on|turn_off) & IFF_PHYINT_FLAGS)
10392 10398                  phyint_flags_modified = B_TRUE;
10393 10399  
10394 10400          /*
10395 10401           * All functioning PHYI_STANDBY interfaces start life PHYI_INACTIVE
10396 10402           * (otherwise, we'd immediately use them, defeating standby).  Also,
10397 10403           * since PHYI_INACTIVE has a separate meaning when PHYI_STANDBY is not
10398 10404           * set, don't allow PHYI_STANDBY to be set if PHYI_INACTIVE is already
10399 10405           * set, and clear PHYI_INACTIVE if PHYI_STANDBY is being cleared.  We
10400 10406           * also don't allow PHYI_STANDBY if VNI is enabled since its semantics
10401 10407           * will not be honored.
10402 10408           */
10403 10409          if (turn_on & PHYI_STANDBY) {
10404 10410                  /*
10405 10411                   * No need to grab ill_g_usesrc_lock here; see the
10406 10412                   * synchronization notes in ip.c.
10407 10413                   */
10408 10414                  if (ill->ill_usesrc_grp_next != NULL ||
10409 10415                      intf_flags & PHYI_INACTIVE)
10410 10416                          return (EINVAL);
10411 10417                  if (!(flags & PHYI_FAILED)) {
10412 10418                          flags |= PHYI_INACTIVE;
10413 10419                          turn_on |= PHYI_INACTIVE;
10414 10420                  }
10415 10421          }
10416 10422  
10417 10423          if (turn_off & PHYI_STANDBY) {
10418 10424                  flags &= ~PHYI_INACTIVE;
10419 10425                  turn_off |= PHYI_INACTIVE;
10420 10426          }
10421 10427  
10422 10428          /*
10423 10429           * PHYI_FAILED and PHYI_INACTIVE are mutually exclusive; fail if both
10424 10430           * would end up on.
10425 10431           */
10426 10432          if ((flags & (PHYI_FAILED | PHYI_INACTIVE)) ==
10427 10433              (PHYI_FAILED | PHYI_INACTIVE))
10428 10434                  return (EINVAL);
10429 10435  
10430 10436          /*
10431 10437           * If ILLF_ROUTER changes, we need to change the ip forwarding
10432 10438           * status of the interface.
10433 10439           */
10434 10440          if ((turn_on | turn_off) & ILLF_ROUTER) {
10435 10441                  err = ill_forward_set(ill, ((turn_on & ILLF_ROUTER) != 0));
10436 10442                  if (err != 0)
10437 10443                          return (err);
10438 10444          }
10439 10445  
10440 10446          /*
10441 10447           * If the interface is not UP and we are not going to
10442 10448           * bring it UP, record the flags and return. When the
10443 10449           * interface comes UP later, the right actions will be
10444 10450           * taken.
10445 10451           */
10446 10452          if (!(ipif->ipif_flags & IPIF_UP) &&
10447 10453              !(turn_on & IPIF_UP)) {
10448 10454                  /* Record new flags in their respective places. */
10449 10455                  mutex_enter(&ill->ill_lock);
10450 10456                  mutex_enter(&ill->ill_phyint->phyint_lock);
10451 10457                  ipif->ipif_flags |= (turn_on & IFF_LOGINT_FLAGS);
10452 10458                  ipif->ipif_flags &= (~turn_off & IFF_LOGINT_FLAGS);
10453 10459                  ill->ill_flags |= (turn_on & IFF_PHYINTINST_FLAGS);
10454 10460                  ill->ill_flags &= (~turn_off & IFF_PHYINTINST_FLAGS);
10455 10461                  phyi->phyint_flags |= (turn_on & IFF_PHYINT_FLAGS);
10456 10462                  phyi->phyint_flags &= (~turn_off & IFF_PHYINT_FLAGS);
10457 10463                  mutex_exit(&ill->ill_lock);
10458 10464                  mutex_exit(&ill->ill_phyint->phyint_lock);
10459 10465  
10460 10466                  /*
10461 10467                   * PHYI_FAILED, PHYI_INACTIVE, and PHYI_OFFLINE are all the
10462 10468                   * same to the kernel: if any of them has been set by
10463 10469                   * userland, the interface cannot be used for data traffic.
10464 10470                   */
10465 10471                  if ((turn_on|turn_off) &
10466 10472                      (PHYI_FAILED | PHYI_INACTIVE | PHYI_OFFLINE)) {
10467 10473                          ASSERT(!IS_IPMP(ill));
10468 10474                          /*
10469 10475                           * It's possible the ill is part of an "anonymous"
10470 10476                           * IPMP group rather than a real group.  In that case,
10471 10477                           * there are no other interfaces in the group and thus
10472 10478                           * no need to call ipmp_phyint_refresh_active().
10473 10479                           */
10474 10480                          if (IS_UNDER_IPMP(ill))
10475 10481                                  ipmp_phyint_refresh_active(phyi);
10476 10482                  }
10477 10483  
10478 10484                  if (phyint_flags_modified) {
10479 10485                          if (phyi->phyint_illv4 != NULL) {
10480 10486                                  ip_rts_ifmsg(phyi->phyint_illv4->
10481 10487                                      ill_ipif, RTSQ_DEFAULT);
10482 10488                          }
10483 10489                          if (phyi->phyint_illv6 != NULL) {
10484 10490                                  ip_rts_ifmsg(phyi->phyint_illv6->
10485 10491                                      ill_ipif, RTSQ_DEFAULT);
10486 10492                          }
10487 10493                  }
10488 10494                  /* The default multicast interface might have changed */
10489 10495                  ire_increment_multicast_generation(ill->ill_ipst,
10490 10496                      ill->ill_isv6);
10491 10497  
10492 10498                  return (0);
10493 10499          } else if (set_linklocal) {
10494 10500                  mutex_enter(&ill->ill_lock);
10495 10501                  if (set_linklocal)
10496 10502                          ipif->ipif_state_flags |= IPIF_SET_LINKLOCAL;
10497 10503                  mutex_exit(&ill->ill_lock);
10498 10504          }
10499 10505  
10500 10506          /*
10501 10507           * Disallow IPv6 interfaces coming up that have the unspecified address,
10502 10508           * or point-to-point interfaces with an unspecified destination. We do
10503 10509           * allow the address to be unspecified for IPIF_NOLOCAL interfaces that
10504 10510           * have a subnet assigned, which is how in.ndpd currently manages its
10505 10511           * onlink prefix list when no addresses are configured with those
10506 10512           * prefixes.
10507 10513           */
10508 10514          if (ipif->ipif_isv6 &&
10509 10515              ((IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr) &&
10510 10516              (!(ipif->ipif_flags & IPIF_NOLOCAL) && !(turn_on & IPIF_NOLOCAL) ||
10511 10517              IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6subnet))) ||
10512 10518              ((ipif->ipif_flags & IPIF_POINTOPOINT) &&
10513 10519              IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6pp_dst_addr)))) {
10514 10520                  return (EINVAL);
10515 10521          }
10516 10522  
10517 10523          /*
10518 10524           * Prevent IPv4 point-to-point interfaces with a 0.0.0.0 destination
10519 10525           * from being brought up.
10520 10526           */
10521 10527          if (!ipif->ipif_isv6 &&
10522 10528              ((ipif->ipif_flags & IPIF_POINTOPOINT) &&
10523 10529              ipif->ipif_pp_dst_addr == INADDR_ANY)) {
10524 10530                  return (EINVAL);
10525 10531          }
10526 10532  
10527 10533          /*
10528 10534           * If we are going to change one or more of the flags that are
10529 10535           * IPIF_UP, IPIF_DEPRECATED, IPIF_NOXMIT, IPIF_NOLOCAL, ILLF_NOARP,
10530 10536           * ILLF_NONUD, IPIF_PRIVATE, IPIF_ANYCAST, IPIF_PREFERRED, and
10531 10537           * IPIF_NOFAILOVER, we will take special action.  This is
10532 10538           * done by bring the ipif down, changing the flags and bringing
10533 10539           * it back up again.  For IPIF_NOFAILOVER, the act of bringing it
10534 10540           * back up will trigger the address to be moved.
10535 10541           *
10536 10542           * If we are going to change IFF_NOACCEPT, we need to bring
10537 10543           * all the ipifs down then bring them up again.  The act of
10538 10544           * bringing all the ipifs back up will trigger the local
10539 10545           * ires being recreated with "no_accept" set/cleared.
10540 10546           *
10541 10547           * Note that ILLF_NOACCEPT is always set separately from the
10542 10548           * other flags.
10543 10549           */
10544 10550          if ((turn_on|turn_off) &
10545 10551              (IPIF_UP|IPIF_DEPRECATED|IPIF_NOXMIT|IPIF_NOLOCAL|ILLF_NOARP|
10546 10552              ILLF_NONUD|IPIF_PRIVATE|IPIF_ANYCAST|IPIF_PREFERRED|
10547 10553              IPIF_NOFAILOVER)) {
10548 10554                  /*
10549 10555                   * ipif_down() will ire_delete bcast ire's for the subnet,
10550 10556                   * while the ire_identical_ref tracks the case of IRE_BROADCAST
10551 10557                   * entries shared between multiple ipifs on the same subnet.
10552 10558                   */
10553 10559                  if (((ipif->ipif_flags | turn_on) & IPIF_UP) &&
10554 10560                      !(turn_off & IPIF_UP)) {
10555 10561                          if (ipif->ipif_flags & IPIF_UP)
10556 10562                                  ill->ill_logical_down = 1;
10557 10563                          turn_on &= ~IPIF_UP;
10558 10564                  }
10559 10565                  err = ipif_down(ipif, q, mp);
10560 10566                  ip1dbg(("ipif_down returns %d err ", err));
10561 10567                  if (err == EINPROGRESS)
10562 10568                          return (err);
10563 10569                  (void) ipif_down_tail(ipif);
10564 10570          } else if ((turn_on|turn_off) & ILLF_NOACCEPT) {
10565 10571                  /*
10566 10572                   * If we can quiesce the ill, then continue.  If not, then
10567 10573                   * ip_sioctl_flags_tail() will be called from
10568 10574                   * ipif_ill_refrele_tail().
10569 10575                   */
10570 10576                  ill_down_ipifs(ill, B_TRUE);
10571 10577  
10572 10578                  mutex_enter(&connp->conn_lock);
10573 10579                  mutex_enter(&ill->ill_lock);
10574 10580                  if (!ill_is_quiescent(ill)) {
10575 10581                          boolean_t success;
10576 10582  
10577 10583                          success = ipsq_pending_mp_add(connp, ill->ill_ipif,
10578 10584                              q, mp, ILL_DOWN);
10579 10585                          mutex_exit(&ill->ill_lock);
10580 10586                          mutex_exit(&connp->conn_lock);
10581 10587                          return (success ? EINPROGRESS : EINTR);
10582 10588                  }
10583 10589                  mutex_exit(&ill->ill_lock);
10584 10590                  mutex_exit(&connp->conn_lock);
10585 10591          }
10586 10592          return (ip_sioctl_flags_tail(ipif, flags, q, mp));
10587 10593  }
10588 10594  
10589 10595  static int
10590 10596  ip_sioctl_flags_tail(ipif_t *ipif, uint64_t flags, queue_t *q, mblk_t *mp)
10591 10597  {
10592 10598          ill_t   *ill;
10593 10599          phyint_t *phyi;
10594 10600          uint64_t turn_on, turn_off;
10595 10601          boolean_t phyint_flags_modified = B_FALSE;
10596 10602          int     err = 0;
10597 10603          boolean_t set_linklocal = B_FALSE;
10598 10604  
10599 10605          ip1dbg(("ip_sioctl_flags_tail(%s:%u)\n",
10600 10606              ipif->ipif_ill->ill_name, ipif->ipif_id));
10601 10607  
10602 10608          ASSERT(IAM_WRITER_IPIF(ipif));
10603 10609  
10604 10610          ill = ipif->ipif_ill;
10605 10611          phyi = ill->ill_phyint;
10606 10612  
10607 10613          ip_sioctl_flags_onoff(ipif, flags, &turn_on, &turn_off);
10608 10614  
10609 10615          /*
10610 10616           * IFF_UP is handled separately.
10611 10617           */
10612 10618          turn_on &= ~IFF_UP;
10613 10619          turn_off &= ~IFF_UP;
10614 10620  
10615 10621          if ((turn_on|turn_off) & IFF_PHYINT_FLAGS)
10616 10622                  phyint_flags_modified = B_TRUE;
10617 10623  
10618 10624          /*
10619 10625           * Now we change the flags. Track current value of
10620 10626           * other flags in their respective places.
10621 10627           */
10622 10628          mutex_enter(&ill->ill_lock);
10623 10629          mutex_enter(&phyi->phyint_lock);
10624 10630          ipif->ipif_flags |= (turn_on & IFF_LOGINT_FLAGS);
10625 10631          ipif->ipif_flags &= (~turn_off & IFF_LOGINT_FLAGS);
10626 10632          ill->ill_flags |= (turn_on & IFF_PHYINTINST_FLAGS);
10627 10633          ill->ill_flags &= (~turn_off & IFF_PHYINTINST_FLAGS);
10628 10634          phyi->phyint_flags |= (turn_on & IFF_PHYINT_FLAGS);
10629 10635          phyi->phyint_flags &= (~turn_off & IFF_PHYINT_FLAGS);
10630 10636          if (ipif->ipif_state_flags & IPIF_SET_LINKLOCAL) {
10631 10637                  set_linklocal = B_TRUE;
10632 10638                  ipif->ipif_state_flags &= ~IPIF_SET_LINKLOCAL;
10633 10639          }
10634 10640  
10635 10641          mutex_exit(&ill->ill_lock);
10636 10642          mutex_exit(&phyi->phyint_lock);
10637 10643  
10638 10644          if (set_linklocal)
10639 10645                  (void) ipif_setlinklocal(ipif);
10640 10646  
10641 10647          /*
10642 10648           * PHYI_FAILED, PHYI_INACTIVE, and PHYI_OFFLINE are all the same to
10643 10649           * the kernel: if any of them has been set by userland, the interface
10644 10650           * cannot be used for data traffic.
10645 10651           */
10646 10652          if ((turn_on|turn_off) & (PHYI_FAILED | PHYI_INACTIVE | PHYI_OFFLINE)) {
10647 10653                  ASSERT(!IS_IPMP(ill));
10648 10654                  /*
10649 10655                   * It's possible the ill is part of an "anonymous" IPMP group
10650 10656                   * rather than a real group.  In that case, there are no other
10651 10657                   * interfaces in the group and thus no need for us to call
10652 10658                   * ipmp_phyint_refresh_active().
10653 10659                   */
10654 10660                  if (IS_UNDER_IPMP(ill))
10655 10661                          ipmp_phyint_refresh_active(phyi);
10656 10662          }
10657 10663  
10658 10664          if ((turn_on|turn_off) & ILLF_NOACCEPT) {
10659 10665                  /*
10660 10666                   * If the ILLF_NOACCEPT flag is changed, bring up all the
10661 10667                   * ipifs that were brought down.
10662 10668                   *
10663 10669                   * The routing sockets messages are sent as the result
10664 10670                   * of ill_up_ipifs(), further, SCTP's IPIF list was updated
10665 10671                   * as well.
10666 10672                   */
10667 10673                  err = ill_up_ipifs(ill, q, mp);
10668 10674          } else if ((flags & IFF_UP) && !(ipif->ipif_flags & IPIF_UP)) {
10669 10675                  /*
10670 10676                   * XXX ipif_up really does not know whether a phyint flags
10671 10677                   * was modified or not. So, it sends up information on
10672 10678                   * only one routing sockets message. As we don't bring up
10673 10679                   * the interface and also set PHYI_ flags simultaneously
10674 10680                   * it should be okay.
10675 10681                   */
10676 10682                  err = ipif_up(ipif, q, mp);
10677 10683          } else {
10678 10684                  /*
10679 10685                   * Make sure routing socket sees all changes to the flags.
10680 10686                   * ipif_up_done* handles this when we use ipif_up.
10681 10687                   */
10682 10688                  if (phyint_flags_modified) {
10683 10689                          if (phyi->phyint_illv4 != NULL) {
10684 10690                                  ip_rts_ifmsg(phyi->phyint_illv4->
10685 10691                                      ill_ipif, RTSQ_DEFAULT);
10686 10692                          }
10687 10693                          if (phyi->phyint_illv6 != NULL) {
10688 10694                                  ip_rts_ifmsg(phyi->phyint_illv6->
10689 10695                                      ill_ipif, RTSQ_DEFAULT);
10690 10696                          }
10691 10697                  } else {
10692 10698                          ip_rts_ifmsg(ipif, RTSQ_DEFAULT);
10693 10699                  }
10694 10700                  /*
10695 10701                   * Update the flags in SCTP's IPIF list, ipif_up() will do
10696 10702                   * this in need_up case.
10697 10703                   */
10698 10704                  sctp_update_ipif(ipif, SCTP_IPIF_UPDATE);
10699 10705          }
10700 10706  
10701 10707          /* The default multicast interface might have changed */
10702 10708          ire_increment_multicast_generation(ill->ill_ipst, ill->ill_isv6);
10703 10709          return (err);
10704 10710  }
10705 10711  
10706 10712  /*
10707 10713   * Restart the flags operation now that the refcounts have dropped to zero.
10708 10714   */
10709 10715  /* ARGSUSED */
10710 10716  int
10711 10717  ip_sioctl_flags_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10712 10718      ip_ioctl_cmd_t *ipip, void *if_req)
10713 10719  {
10714 10720          uint64_t flags;
10715 10721          struct ifreq *ifr = if_req;
10716 10722          struct lifreq *lifr = if_req;
10717 10723          uint64_t turn_on, turn_off;
10718 10724  
10719 10725          ip1dbg(("ip_sioctl_flags_restart(%s:%u %p)\n",
10720 10726              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10721 10727  
10722 10728          if (ipip->ipi_cmd_type == IF_CMD) {
10723 10729                  /* cast to uint16_t prevents unwanted sign extension */
10724 10730                  flags = (uint16_t)ifr->ifr_flags;
10725 10731          } else {
10726 10732                  flags = lifr->lifr_flags;
10727 10733          }
10728 10734  
10729 10735          /*
10730 10736           * If this function call is a result of the ILLF_NOACCEPT flag
10731 10737           * change, do not call ipif_down_tail(). See ip_sioctl_flags().
10732 10738           */
10733 10739          ip_sioctl_flags_onoff(ipif, flags, &turn_on, &turn_off);
10734 10740          if (!((turn_on|turn_off) & ILLF_NOACCEPT))
10735 10741                  (void) ipif_down_tail(ipif);
10736 10742  
10737 10743          return (ip_sioctl_flags_tail(ipif, flags, q, mp));
10738 10744  }
10739 10745  
10740 10746  /*
10741 10747   * Can operate on either a module or a driver queue.
10742 10748   */
10743 10749  /* ARGSUSED */
10744 10750  int
10745 10751  ip_sioctl_get_flags(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10746 10752      ip_ioctl_cmd_t *ipip, void *if_req)
10747 10753  {
10748 10754          /*
10749 10755           * Has the flags been set correctly till now ?
10750 10756           */
10751 10757          ill_t *ill = ipif->ipif_ill;
10752 10758          phyint_t *phyi = ill->ill_phyint;
10753 10759  
10754 10760          ip1dbg(("ip_sioctl_get_flags(%s:%u %p)\n",
10755 10761              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10756 10762          ASSERT((phyi->phyint_flags & ~(IFF_PHYINT_FLAGS)) == 0);
10757 10763          ASSERT((ill->ill_flags & ~(IFF_PHYINTINST_FLAGS)) == 0);
10758 10764          ASSERT((ipif->ipif_flags & ~(IFF_LOGINT_FLAGS)) == 0);
10759 10765  
10760 10766          /*
10761 10767           * Need a lock since some flags can be set even when there are
10762 10768           * references to the ipif.
10763 10769           */
10764 10770          mutex_enter(&ill->ill_lock);
10765 10771          if (ipip->ipi_cmd_type == IF_CMD) {
10766 10772                  struct ifreq *ifr = (struct ifreq *)if_req;
10767 10773  
10768 10774                  /* Get interface flags (low 16 only). */
10769 10775                  ifr->ifr_flags = ((ipif->ipif_flags |
10770 10776                      ill->ill_flags | phyi->phyint_flags) & 0xffff);
10771 10777          } else {
10772 10778                  struct lifreq *lifr = (struct lifreq *)if_req;
10773 10779  
10774 10780                  /* Get interface flags. */
10775 10781                  lifr->lifr_flags = ipif->ipif_flags |
10776 10782                      ill->ill_flags | phyi->phyint_flags;
10777 10783          }
10778 10784          mutex_exit(&ill->ill_lock);
10779 10785          return (0);
10780 10786  }
10781 10787  
10782 10788  /*
10783 10789   * We allow the MTU to be set on an ILL, but not have it be different
10784 10790   * for different IPIFs since we don't actually send packets on IPIFs.
10785 10791   */
10786 10792  /* ARGSUSED */
10787 10793  int
10788 10794  ip_sioctl_mtu(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10789 10795      ip_ioctl_cmd_t *ipip, void *if_req)
10790 10796  {
10791 10797          int mtu;
10792 10798          int ip_min_mtu;
10793 10799          struct ifreq    *ifr;
10794 10800          struct lifreq *lifr;
10795 10801          ill_t   *ill;
10796 10802  
10797 10803          ip1dbg(("ip_sioctl_mtu(%s:%u %p)\n", ipif->ipif_ill->ill_name,
10798 10804              ipif->ipif_id, (void *)ipif));
10799 10805          if (ipip->ipi_cmd_type == IF_CMD) {
10800 10806                  ifr = (struct ifreq *)if_req;
10801 10807                  mtu = ifr->ifr_metric;
10802 10808          } else {
10803 10809                  lifr = (struct lifreq *)if_req;
10804 10810                  mtu = lifr->lifr_mtu;
10805 10811          }
10806 10812          /* Only allow for logical unit zero i.e. not on "bge0:17" */
10807 10813          if (ipif->ipif_id != 0)
10808 10814                  return (EINVAL);
10809 10815  
10810 10816          ill = ipif->ipif_ill;
10811 10817          if (ipif->ipif_isv6)
10812 10818                  ip_min_mtu = IPV6_MIN_MTU;
10813 10819          else
10814 10820                  ip_min_mtu = IP_MIN_MTU;
10815 10821  
10816 10822          mutex_enter(&ill->ill_lock);
10817 10823          if (mtu > ill->ill_max_frag || mtu < ip_min_mtu) {
10818 10824                  mutex_exit(&ill->ill_lock);
10819 10825                  return (EINVAL);
10820 10826          }
10821 10827          /* Avoid increasing ill_mc_mtu */
10822 10828          if (ill->ill_mc_mtu > mtu)
10823 10829                  ill->ill_mc_mtu = mtu;
10824 10830  
10825 10831          /*
10826 10832           * The dce and fragmentation code can handle changes to ill_mtu
10827 10833           * concurrent with sending/fragmenting packets.
10828 10834           */
10829 10835          ill->ill_mtu = mtu;
10830 10836          ill->ill_flags |= ILLF_FIXEDMTU;
10831 10837          mutex_exit(&ill->ill_lock);
10832 10838  
10833 10839          /*
10834 10840           * Make sure all dce_generation checks find out
10835 10841           * that ill_mtu/ill_mc_mtu has changed.
10836 10842           */
10837 10843          dce_increment_all_generations(ill->ill_isv6, ill->ill_ipst);
10838 10844  
10839 10845          /*
10840 10846           * Refresh IPMP meta-interface MTU if necessary.
10841 10847           */
10842 10848          if (IS_UNDER_IPMP(ill))
10843 10849                  ipmp_illgrp_refresh_mtu(ill->ill_grp);
10844 10850  
10845 10851          /* Update the MTU in SCTP's list */
10846 10852          sctp_update_ipif(ipif, SCTP_IPIF_UPDATE);
10847 10853          return (0);
10848 10854  }
10849 10855  
10850 10856  /* Get interface MTU. */
10851 10857  /* ARGSUSED */
10852 10858  int
10853 10859  ip_sioctl_get_mtu(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10854 10860          ip_ioctl_cmd_t *ipip, void *if_req)
10855 10861  {
10856 10862          struct ifreq    *ifr;
10857 10863          struct lifreq   *lifr;
10858 10864  
10859 10865          ip1dbg(("ip_sioctl_get_mtu(%s:%u %p)\n",
10860 10866              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10861 10867  
10862 10868          /*
10863 10869           * We allow a get on any logical interface even though the set
10864 10870           * can only be done on logical unit 0.
10865 10871           */
10866 10872          if (ipip->ipi_cmd_type == IF_CMD) {
10867 10873                  ifr = (struct ifreq *)if_req;
10868 10874                  ifr->ifr_metric = ipif->ipif_ill->ill_mtu;
10869 10875          } else {
10870 10876                  lifr = (struct lifreq *)if_req;
10871 10877                  lifr->lifr_mtu = ipif->ipif_ill->ill_mtu;
10872 10878          }
10873 10879          return (0);
10874 10880  }
10875 10881  
10876 10882  /* Set interface broadcast address. */
10877 10883  /* ARGSUSED2 */
10878 10884  int
10879 10885  ip_sioctl_brdaddr(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10880 10886          ip_ioctl_cmd_t *ipip, void *if_req)
10881 10887  {
10882 10888          ipaddr_t addr;
10883 10889          ire_t   *ire;
10884 10890          ill_t           *ill = ipif->ipif_ill;
10885 10891          ip_stack_t      *ipst = ill->ill_ipst;
10886 10892  
10887 10893          ip1dbg(("ip_sioctl_brdaddr(%s:%u)\n", ill->ill_name,
10888 10894              ipif->ipif_id));
10889 10895  
10890 10896          ASSERT(IAM_WRITER_IPIF(ipif));
10891 10897          if (!(ipif->ipif_flags & IPIF_BROADCAST))
10892 10898                  return (EADDRNOTAVAIL);
10893 10899  
10894 10900          ASSERT(!(ipif->ipif_isv6));     /* No IPv6 broadcast */
10895 10901  
10896 10902          if (sin->sin_family != AF_INET)
10897 10903                  return (EAFNOSUPPORT);
10898 10904  
10899 10905          addr = sin->sin_addr.s_addr;
10900 10906  
10901 10907          if (ipif->ipif_flags & IPIF_UP) {
10902 10908                  /*
10903 10909                   * If we are already up, make sure the new
10904 10910                   * broadcast address makes sense.  If it does,
10905 10911                   * there should be an IRE for it already.
10906 10912                   */
10907 10913                  ire = ire_ftable_lookup_v4(addr, 0, 0, IRE_BROADCAST,
10908 10914                      ill, ipif->ipif_zoneid, NULL,
10909 10915                      (MATCH_IRE_ILL | MATCH_IRE_TYPE), 0, ipst, NULL);
10910 10916                  if (ire == NULL) {
10911 10917                          return (EINVAL);
10912 10918                  } else {
10913 10919                          ire_refrele(ire);
10914 10920                  }
10915 10921          }
10916 10922          /*
10917 10923           * Changing the broadcast addr for this ipif. Since the IRE_BROADCAST
10918 10924           * needs to already exist we never need to change the set of
10919 10925           * IRE_BROADCASTs when we are UP.
10920 10926           */
10921 10927          if (addr != ipif->ipif_brd_addr)
10922 10928                  IN6_IPADDR_TO_V4MAPPED(addr, &ipif->ipif_v6brd_addr);
10923 10929  
10924 10930          return (0);
10925 10931  }
10926 10932  
10927 10933  /* Get interface broadcast address. */
10928 10934  /* ARGSUSED */
10929 10935  int
10930 10936  ip_sioctl_get_brdaddr(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10931 10937      ip_ioctl_cmd_t *ipip, void *if_req)
10932 10938  {
10933 10939          ip1dbg(("ip_sioctl_get_brdaddr(%s:%u %p)\n",
10934 10940              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10935 10941          if (!(ipif->ipif_flags & IPIF_BROADCAST))
10936 10942                  return (EADDRNOTAVAIL);
10937 10943  
10938 10944          /* IPIF_BROADCAST not possible with IPv6 */
10939 10945          ASSERT(!ipif->ipif_isv6);
10940 10946          *sin = sin_null;
10941 10947          sin->sin_family = AF_INET;
10942 10948          sin->sin_addr.s_addr = ipif->ipif_brd_addr;
10943 10949          return (0);
10944 10950  }
10945 10951  
10946 10952  /*
10947 10953   * This routine is called to handle the SIOCS*IFNETMASK IOCTL.
10948 10954   */
10949 10955  /* ARGSUSED */
10950 10956  int
10951 10957  ip_sioctl_netmask(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
10952 10958      ip_ioctl_cmd_t *ipip, void *if_req)
10953 10959  {
10954 10960          int err = 0;
10955 10961          in6_addr_t v6mask;
10956 10962  
10957 10963          ip1dbg(("ip_sioctl_netmask(%s:%u %p)\n",
10958 10964              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
10959 10965  
10960 10966          ASSERT(IAM_WRITER_IPIF(ipif));
10961 10967  
10962 10968          if (ipif->ipif_isv6) {
10963 10969                  sin6_t *sin6;
10964 10970  
10965 10971                  if (sin->sin_family != AF_INET6)
10966 10972                          return (EAFNOSUPPORT);
10967 10973  
10968 10974                  sin6 = (sin6_t *)sin;
10969 10975                  v6mask = sin6->sin6_addr;
10970 10976          } else {
10971 10977                  ipaddr_t mask;
10972 10978  
10973 10979                  if (sin->sin_family != AF_INET)
10974 10980                          return (EAFNOSUPPORT);
10975 10981  
10976 10982                  mask = sin->sin_addr.s_addr;
10977 10983                  if (!ip_contiguous_mask(ntohl(mask)))
10978 10984                          return (ENOTSUP);
10979 10985                  V4MASK_TO_V6(mask, v6mask);
10980 10986          }
10981 10987  
10982 10988          /*
10983 10989           * No big deal if the interface isn't already up, or the mask
10984 10990           * isn't really changing, or this is pt-pt.
10985 10991           */
10986 10992          if (!(ipif->ipif_flags & IPIF_UP) ||
10987 10993              IN6_ARE_ADDR_EQUAL(&v6mask, &ipif->ipif_v6net_mask) ||
10988 10994              (ipif->ipif_flags & IPIF_POINTOPOINT)) {
10989 10995                  ipif->ipif_v6net_mask = v6mask;
10990 10996                  if ((ipif->ipif_flags & IPIF_POINTOPOINT) == 0) {
10991 10997                          V6_MASK_COPY(ipif->ipif_v6lcl_addr,
10992 10998                              ipif->ipif_v6net_mask,
10993 10999                              ipif->ipif_v6subnet);
10994 11000                  }
10995 11001                  return (0);
10996 11002          }
10997 11003          /*
10998 11004           * Make sure we have valid net and subnet broadcast ire's
10999 11005           * for the old netmask, if needed by other logical interfaces.
11000 11006           */
11001 11007          err = ipif_logical_down(ipif, q, mp);
11002 11008          if (err == EINPROGRESS)
11003 11009                  return (err);
11004 11010          (void) ipif_down_tail(ipif);
11005 11011          err = ip_sioctl_netmask_tail(ipif, sin, q, mp);
11006 11012          return (err);
11007 11013  }
11008 11014  
11009 11015  static int
11010 11016  ip_sioctl_netmask_tail(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp)
11011 11017  {
11012 11018          in6_addr_t v6mask;
11013 11019          int err = 0;
11014 11020  
11015 11021          ip1dbg(("ip_sioctl_netmask_tail(%s:%u %p)\n",
11016 11022              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11017 11023  
11018 11024          if (ipif->ipif_isv6) {
11019 11025                  sin6_t *sin6;
11020 11026  
11021 11027                  sin6 = (sin6_t *)sin;
11022 11028                  v6mask = sin6->sin6_addr;
11023 11029          } else {
11024 11030                  ipaddr_t mask;
11025 11031  
11026 11032                  mask = sin->sin_addr.s_addr;
11027 11033                  V4MASK_TO_V6(mask, v6mask);
11028 11034          }
11029 11035  
11030 11036          ipif->ipif_v6net_mask = v6mask;
11031 11037          if ((ipif->ipif_flags & IPIF_POINTOPOINT) == 0) {
11032 11038                  V6_MASK_COPY(ipif->ipif_v6lcl_addr, ipif->ipif_v6net_mask,
11033 11039                      ipif->ipif_v6subnet);
11034 11040          }
11035 11041          err = ipif_up(ipif, q, mp);
11036 11042  
11037 11043          if (err == 0 || err == EINPROGRESS) {
11038 11044                  /*
11039 11045                   * The interface must be DL_BOUND if this packet has to
11040 11046                   * go out on the wire. Since we only go through a logical
11041 11047                   * down and are bound with the driver during an internal
11042 11048                   * down/up that is satisfied.
11043 11049                   */
11044 11050                  if (!ipif->ipif_isv6 && ipif->ipif_ill->ill_wq != NULL) {
11045 11051                          /* Potentially broadcast an address mask reply. */
11046 11052                          ipif_mask_reply(ipif);
11047 11053                  }
11048 11054          }
11049 11055          return (err);
11050 11056  }
11051 11057  
11052 11058  /* ARGSUSED */
11053 11059  int
11054 11060  ip_sioctl_netmask_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11055 11061      ip_ioctl_cmd_t *ipip, void *if_req)
11056 11062  {
11057 11063          ip1dbg(("ip_sioctl_netmask_restart(%s:%u %p)\n",
11058 11064              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11059 11065          (void) ipif_down_tail(ipif);
11060 11066          return (ip_sioctl_netmask_tail(ipif, sin, q, mp));
11061 11067  }
11062 11068  
11063 11069  /* Get interface net mask. */
11064 11070  /* ARGSUSED */
11065 11071  int
11066 11072  ip_sioctl_get_netmask(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11067 11073      ip_ioctl_cmd_t *ipip, void *if_req)
11068 11074  {
11069 11075          struct lifreq *lifr = (struct lifreq *)if_req;
11070 11076          struct sockaddr_in6 *sin6 = (sin6_t *)sin;
11071 11077  
11072 11078          ip1dbg(("ip_sioctl_get_netmask(%s:%u %p)\n",
11073 11079              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11074 11080  
11075 11081          /*
11076 11082           * net mask can't change since we have a reference to the ipif.
11077 11083           */
11078 11084          if (ipif->ipif_isv6) {
11079 11085                  ASSERT(ipip->ipi_cmd_type == LIF_CMD);
11080 11086                  *sin6 = sin6_null;
11081 11087                  sin6->sin6_family = AF_INET6;
11082 11088                  sin6->sin6_addr = ipif->ipif_v6net_mask;
11083 11089                  lifr->lifr_addrlen =
11084 11090                      ip_mask_to_plen_v6(&ipif->ipif_v6net_mask);
11085 11091          } else {
11086 11092                  *sin = sin_null;
11087 11093                  sin->sin_family = AF_INET;
11088 11094                  sin->sin_addr.s_addr = ipif->ipif_net_mask;
11089 11095                  if (ipip->ipi_cmd_type == LIF_CMD) {
11090 11096                          lifr->lifr_addrlen =
11091 11097                              ip_mask_to_plen(ipif->ipif_net_mask);
11092 11098                  }
11093 11099          }
11094 11100          return (0);
11095 11101  }
11096 11102  
11097 11103  /* ARGSUSED */
11098 11104  int
11099 11105  ip_sioctl_metric(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11100 11106      ip_ioctl_cmd_t *ipip, void *if_req)
11101 11107  {
11102 11108          ip1dbg(("ip_sioctl_metric(%s:%u %p)\n",
11103 11109              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11104 11110  
11105 11111          /*
11106 11112           * Since no applications should ever be setting metrics on underlying
11107 11113           * interfaces, we explicitly fail to smoke 'em out.
11108 11114           */
11109 11115          if (IS_UNDER_IPMP(ipif->ipif_ill))
11110 11116                  return (EINVAL);
11111 11117  
11112 11118          /*
11113 11119           * Set interface metric.  We don't use this for
11114 11120           * anything but we keep track of it in case it is
11115 11121           * important to routing applications or such.
11116 11122           */
11117 11123          if (ipip->ipi_cmd_type == IF_CMD) {
11118 11124                  struct ifreq    *ifr;
11119 11125  
11120 11126                  ifr = (struct ifreq *)if_req;
11121 11127                  ipif->ipif_ill->ill_metric = ifr->ifr_metric;
11122 11128          } else {
11123 11129                  struct lifreq   *lifr;
11124 11130  
11125 11131                  lifr = (struct lifreq *)if_req;
11126 11132                  ipif->ipif_ill->ill_metric = lifr->lifr_metric;
11127 11133          }
11128 11134          return (0);
11129 11135  }
11130 11136  
11131 11137  /* ARGSUSED */
11132 11138  int
11133 11139  ip_sioctl_get_metric(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11134 11140      ip_ioctl_cmd_t *ipip, void *if_req)
11135 11141  {
11136 11142          /* Get interface metric. */
11137 11143          ip1dbg(("ip_sioctl_get_metric(%s:%u %p)\n",
11138 11144              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11139 11145  
11140 11146          if (ipip->ipi_cmd_type == IF_CMD) {
11141 11147                  struct ifreq    *ifr;
11142 11148  
11143 11149                  ifr = (struct ifreq *)if_req;
11144 11150                  ifr->ifr_metric = ipif->ipif_ill->ill_metric;
11145 11151          } else {
11146 11152                  struct lifreq   *lifr;
11147 11153  
11148 11154                  lifr = (struct lifreq *)if_req;
11149 11155                  lifr->lifr_metric = ipif->ipif_ill->ill_metric;
11150 11156          }
11151 11157  
11152 11158          return (0);
11153 11159  }
11154 11160  
11155 11161  /* ARGSUSED */
11156 11162  int
11157 11163  ip_sioctl_muxid(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11158 11164      ip_ioctl_cmd_t *ipip, void *if_req)
11159 11165  {
11160 11166          int     arp_muxid;
11161 11167  
11162 11168          ip1dbg(("ip_sioctl_muxid(%s:%u %p)\n",
11163 11169              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11164 11170          /*
11165 11171           * Set the muxid returned from I_PLINK.
11166 11172           */
11167 11173          if (ipip->ipi_cmd_type == IF_CMD) {
11168 11174                  struct ifreq *ifr = (struct ifreq *)if_req;
11169 11175  
11170 11176                  ipif->ipif_ill->ill_muxid = ifr->ifr_ip_muxid;
11171 11177                  arp_muxid = ifr->ifr_arp_muxid;
11172 11178          } else {
11173 11179                  struct lifreq *lifr = (struct lifreq *)if_req;
11174 11180  
11175 11181                  ipif->ipif_ill->ill_muxid = lifr->lifr_ip_muxid;
11176 11182                  arp_muxid = lifr->lifr_arp_muxid;
11177 11183          }
11178 11184          arl_set_muxid(ipif->ipif_ill, arp_muxid);
11179 11185          return (0);
11180 11186  }
11181 11187  
11182 11188  /* ARGSUSED */
11183 11189  int
11184 11190  ip_sioctl_get_muxid(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11185 11191      ip_ioctl_cmd_t *ipip, void *if_req)
11186 11192  {
11187 11193          int     arp_muxid = 0;
11188 11194  
11189 11195          ip1dbg(("ip_sioctl_get_muxid(%s:%u %p)\n",
11190 11196              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11191 11197          /*
11192 11198           * Get the muxid saved in ill for I_PUNLINK.
11193 11199           */
11194 11200          arp_muxid = arl_get_muxid(ipif->ipif_ill);
11195 11201          if (ipip->ipi_cmd_type == IF_CMD) {
11196 11202                  struct ifreq *ifr = (struct ifreq *)if_req;
11197 11203  
11198 11204                  ifr->ifr_ip_muxid = ipif->ipif_ill->ill_muxid;
11199 11205                  ifr->ifr_arp_muxid = arp_muxid;
11200 11206          } else {
11201 11207                  struct lifreq *lifr = (struct lifreq *)if_req;
11202 11208  
11203 11209                  lifr->lifr_ip_muxid = ipif->ipif_ill->ill_muxid;
11204 11210                  lifr->lifr_arp_muxid = arp_muxid;
11205 11211          }
11206 11212          return (0);
11207 11213  }
11208 11214  
11209 11215  /*
11210 11216   * Set the subnet prefix. Does not modify the broadcast address.
11211 11217   */
11212 11218  /* ARGSUSED */
11213 11219  int
11214 11220  ip_sioctl_subnet(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11215 11221      ip_ioctl_cmd_t *ipip, void *if_req)
11216 11222  {
11217 11223          int err = 0;
11218 11224          in6_addr_t v6addr;
11219 11225          in6_addr_t v6mask;
11220 11226          boolean_t need_up = B_FALSE;
11221 11227          int addrlen;
11222 11228  
11223 11229          ip1dbg(("ip_sioctl_subnet(%s:%u %p)\n",
11224 11230              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11225 11231  
11226 11232          ASSERT(IAM_WRITER_IPIF(ipif));
11227 11233          addrlen = ((struct lifreq *)if_req)->lifr_addrlen;
11228 11234  
11229 11235          if (ipif->ipif_isv6) {
11230 11236                  sin6_t *sin6;
11231 11237  
11232 11238                  if (sin->sin_family != AF_INET6)
11233 11239                          return (EAFNOSUPPORT);
11234 11240  
11235 11241                  sin6 = (sin6_t *)sin;
11236 11242                  v6addr = sin6->sin6_addr;
11237 11243                  if (!ip_remote_addr_ok_v6(&v6addr, &ipv6_all_ones))
11238 11244                          return (EADDRNOTAVAIL);
11239 11245          } else {
11240 11246                  ipaddr_t addr;
11241 11247  
11242 11248                  if (sin->sin_family != AF_INET)
11243 11249                          return (EAFNOSUPPORT);
11244 11250  
11245 11251                  addr = sin->sin_addr.s_addr;
11246 11252                  if (!ip_addr_ok_v4(addr, 0xFFFFFFFF))
11247 11253                          return (EADDRNOTAVAIL);
11248 11254                  IN6_IPADDR_TO_V4MAPPED(addr, &v6addr);
11249 11255                  /* Add 96 bits */
11250 11256                  addrlen += IPV6_ABITS - IP_ABITS;
11251 11257          }
11252 11258  
11253 11259          if (ip_plen_to_mask_v6(addrlen, &v6mask) == NULL)
11254 11260                  return (EINVAL);
11255 11261  
11256 11262          /* Check if bits in the address is set past the mask */
11257 11263          if (!V6_MASK_EQ(v6addr, v6mask, v6addr))
11258 11264                  return (EINVAL);
11259 11265  
11260 11266          if (IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6subnet, &v6addr) &&
11261 11267              IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6net_mask, &v6mask))
11262 11268                  return (0);     /* No change */
11263 11269  
11264 11270          if (ipif->ipif_flags & IPIF_UP) {
11265 11271                  /*
11266 11272                   * If the interface is already marked up,
11267 11273                   * we call ipif_down which will take care
11268 11274                   * of ditching any IREs that have been set
11269 11275                   * up based on the old interface address.
11270 11276                   */
11271 11277                  err = ipif_logical_down(ipif, q, mp);
11272 11278                  if (err == EINPROGRESS)
11273 11279                          return (err);
11274 11280                  (void) ipif_down_tail(ipif);
11275 11281                  need_up = B_TRUE;
11276 11282          }
11277 11283  
11278 11284          err = ip_sioctl_subnet_tail(ipif, v6addr, v6mask, q, mp, need_up);
11279 11285          return (err);
11280 11286  }
11281 11287  
11282 11288  static int
11283 11289  ip_sioctl_subnet_tail(ipif_t *ipif, in6_addr_t v6addr, in6_addr_t v6mask,
11284 11290      queue_t *q, mblk_t *mp, boolean_t need_up)
11285 11291  {
11286 11292          ill_t   *ill = ipif->ipif_ill;
11287 11293          int     err = 0;
11288 11294  
11289 11295          ip1dbg(("ip_sioctl_subnet_tail(%s:%u %p)\n",
11290 11296              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11291 11297  
11292 11298          /* Set the new address. */
11293 11299          mutex_enter(&ill->ill_lock);
11294 11300          ipif->ipif_v6net_mask = v6mask;
11295 11301          if ((ipif->ipif_flags & IPIF_POINTOPOINT) == 0) {
11296 11302                  V6_MASK_COPY(v6addr, ipif->ipif_v6net_mask,
11297 11303                      ipif->ipif_v6subnet);
11298 11304          }
11299 11305          mutex_exit(&ill->ill_lock);
11300 11306  
11301 11307          if (need_up) {
11302 11308                  /*
11303 11309                   * Now bring the interface back up.  If this
11304 11310                   * is the only IPIF for the ILL, ipif_up
11305 11311                   * will have to re-bind to the device, so
11306 11312                   * we may get back EINPROGRESS, in which
11307 11313                   * case, this IOCTL will get completed in
11308 11314                   * ip_rput_dlpi when we see the DL_BIND_ACK.
11309 11315                   */
11310 11316                  err = ipif_up(ipif, q, mp);
11311 11317                  if (err == EINPROGRESS)
11312 11318                          return (err);
11313 11319          }
11314 11320          return (err);
11315 11321  }
11316 11322  
11317 11323  /* ARGSUSED */
11318 11324  int
11319 11325  ip_sioctl_subnet_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11320 11326      ip_ioctl_cmd_t *ipip, void *if_req)
11321 11327  {
11322 11328          int     addrlen;
11323 11329          in6_addr_t v6addr;
11324 11330          in6_addr_t v6mask;
11325 11331          struct lifreq *lifr = (struct lifreq *)if_req;
11326 11332  
11327 11333          ip1dbg(("ip_sioctl_subnet_restart(%s:%u %p)\n",
11328 11334              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11329 11335          (void) ipif_down_tail(ipif);
11330 11336  
11331 11337          addrlen = lifr->lifr_addrlen;
11332 11338          if (ipif->ipif_isv6) {
11333 11339                  sin6_t *sin6;
11334 11340  
11335 11341                  sin6 = (sin6_t *)sin;
11336 11342                  v6addr = sin6->sin6_addr;
11337 11343          } else {
11338 11344                  ipaddr_t addr;
11339 11345  
11340 11346                  addr = sin->sin_addr.s_addr;
11341 11347                  IN6_IPADDR_TO_V4MAPPED(addr, &v6addr);
11342 11348                  addrlen += IPV6_ABITS - IP_ABITS;
11343 11349          }
11344 11350          (void) ip_plen_to_mask_v6(addrlen, &v6mask);
11345 11351  
11346 11352          return (ip_sioctl_subnet_tail(ipif, v6addr, v6mask, q, mp, B_TRUE));
11347 11353  }
11348 11354  
11349 11355  /* ARGSUSED */
11350 11356  int
11351 11357  ip_sioctl_get_subnet(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11352 11358      ip_ioctl_cmd_t *ipip, void *if_req)
11353 11359  {
11354 11360          struct lifreq *lifr = (struct lifreq *)if_req;
11355 11361          struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin;
11356 11362  
11357 11363          ip1dbg(("ip_sioctl_get_subnet(%s:%u %p)\n",
11358 11364              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11359 11365          ASSERT(ipip->ipi_cmd_type == LIF_CMD);
11360 11366  
11361 11367          if (ipif->ipif_isv6) {
11362 11368                  *sin6 = sin6_null;
11363 11369                  sin6->sin6_family = AF_INET6;
11364 11370                  sin6->sin6_addr = ipif->ipif_v6subnet;
11365 11371                  lifr->lifr_addrlen =
11366 11372                      ip_mask_to_plen_v6(&ipif->ipif_v6net_mask);
11367 11373          } else {
11368 11374                  *sin = sin_null;
11369 11375                  sin->sin_family = AF_INET;
11370 11376                  sin->sin_addr.s_addr = ipif->ipif_subnet;
11371 11377                  lifr->lifr_addrlen = ip_mask_to_plen(ipif->ipif_net_mask);
11372 11378          }
11373 11379          return (0);
11374 11380  }
11375 11381  
11376 11382  /*
11377 11383   * Set the IPv6 address token.
11378 11384   */
11379 11385  /* ARGSUSED */
11380 11386  int
11381 11387  ip_sioctl_token(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11382 11388      ip_ioctl_cmd_t *ipi, void *if_req)
11383 11389  {
11384 11390          ill_t *ill = ipif->ipif_ill;
11385 11391          int err;
11386 11392          in6_addr_t v6addr;
11387 11393          in6_addr_t v6mask;
11388 11394          boolean_t need_up = B_FALSE;
11389 11395          int i;
11390 11396          sin6_t *sin6 = (sin6_t *)sin;
11391 11397          struct lifreq *lifr = (struct lifreq *)if_req;
11392 11398          int addrlen;
11393 11399  
11394 11400          ip1dbg(("ip_sioctl_token(%s:%u %p)\n",
11395 11401              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11396 11402          ASSERT(IAM_WRITER_IPIF(ipif));
11397 11403  
11398 11404          addrlen = lifr->lifr_addrlen;
11399 11405          /* Only allow for logical unit zero i.e. not on "le0:17" */
11400 11406          if (ipif->ipif_id != 0)
11401 11407                  return (EINVAL);
11402 11408  
11403 11409          if (!ipif->ipif_isv6)
11404 11410                  return (EINVAL);
11405 11411  
11406 11412          if (addrlen > IPV6_ABITS)
11407 11413                  return (EINVAL);
11408 11414  
11409 11415          v6addr = sin6->sin6_addr;
11410 11416  
11411 11417          /*
11412 11418           * The length of the token is the length from the end.  To get
11413 11419           * the proper mask for this, compute the mask of the bits not
11414 11420           * in the token; ie. the prefix, and then xor to get the mask.
11415 11421           */
11416 11422          if (ip_plen_to_mask_v6(IPV6_ABITS - addrlen, &v6mask) == NULL)
11417 11423                  return (EINVAL);
11418 11424          for (i = 0; i < 4; i++) {
11419 11425                  v6mask.s6_addr32[i] ^= (uint32_t)0xffffffff;
11420 11426          }
11421 11427  
11422 11428          if (V6_MASK_EQ(v6addr, v6mask, ill->ill_token) &&
11423 11429              ill->ill_token_length == addrlen)
11424 11430                  return (0);     /* No change */
11425 11431  
11426 11432          if (ipif->ipif_flags & IPIF_UP) {
11427 11433                  err = ipif_logical_down(ipif, q, mp);
11428 11434                  if (err == EINPROGRESS)
11429 11435                          return (err);
11430 11436                  (void) ipif_down_tail(ipif);
11431 11437                  need_up = B_TRUE;
11432 11438          }
11433 11439          err = ip_sioctl_token_tail(ipif, sin6, addrlen, q, mp, need_up);
11434 11440          return (err);
11435 11441  }
11436 11442  
11437 11443  static int
11438 11444  ip_sioctl_token_tail(ipif_t *ipif, sin6_t *sin6, int addrlen, queue_t *q,
11439 11445      mblk_t *mp, boolean_t need_up)
11440 11446  {
11441 11447          in6_addr_t v6addr;
11442 11448          in6_addr_t v6mask;
11443 11449          ill_t   *ill = ipif->ipif_ill;
11444 11450          int     i;
11445 11451          int     err = 0;
11446 11452  
11447 11453          ip1dbg(("ip_sioctl_token_tail(%s:%u %p)\n",
11448 11454              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11449 11455          v6addr = sin6->sin6_addr;
11450 11456          /*
11451 11457           * The length of the token is the length from the end.  To get
11452 11458           * the proper mask for this, compute the mask of the bits not
11453 11459           * in the token; ie. the prefix, and then xor to get the mask.
11454 11460           */
11455 11461          (void) ip_plen_to_mask_v6(IPV6_ABITS - addrlen, &v6mask);
11456 11462          for (i = 0; i < 4; i++)
11457 11463                  v6mask.s6_addr32[i] ^= (uint32_t)0xffffffff;
11458 11464  
11459 11465          mutex_enter(&ill->ill_lock);
11460 11466          V6_MASK_COPY(v6addr, v6mask, ill->ill_token);
11461 11467          ill->ill_token_length = addrlen;
11462 11468          ill->ill_manual_token = 1;
11463 11469  
11464 11470          /* Reconfigure the link-local address based on this new token */
11465 11471          ipif_setlinklocal(ill->ill_ipif);
11466 11472  
11467 11473          mutex_exit(&ill->ill_lock);
11468 11474  
11469 11475          if (need_up) {
11470 11476                  /*
11471 11477                   * Now bring the interface back up.  If this
11472 11478                   * is the only IPIF for the ILL, ipif_up
11473 11479                   * will have to re-bind to the device, so
11474 11480                   * we may get back EINPROGRESS, in which
11475 11481                   * case, this IOCTL will get completed in
11476 11482                   * ip_rput_dlpi when we see the DL_BIND_ACK.
11477 11483                   */
11478 11484                  err = ipif_up(ipif, q, mp);
11479 11485                  if (err == EINPROGRESS)
11480 11486                          return (err);
11481 11487          }
11482 11488          return (err);
11483 11489  }
11484 11490  
11485 11491  /* ARGSUSED */
11486 11492  int
11487 11493  ip_sioctl_get_token(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11488 11494      ip_ioctl_cmd_t *ipi, void *if_req)
11489 11495  {
11490 11496          ill_t *ill;
11491 11497          sin6_t *sin6 = (sin6_t *)sin;
11492 11498          struct lifreq *lifr = (struct lifreq *)if_req;
11493 11499  
11494 11500          ip1dbg(("ip_sioctl_get_token(%s:%u %p)\n",
11495 11501              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11496 11502          if (ipif->ipif_id != 0)
11497 11503                  return (EINVAL);
11498 11504  
11499 11505          ill = ipif->ipif_ill;
11500 11506          if (!ill->ill_isv6)
11501 11507                  return (ENXIO);
11502 11508  
11503 11509          *sin6 = sin6_null;
11504 11510          sin6->sin6_family = AF_INET6;
11505 11511          ASSERT(!IN6_IS_ADDR_V4MAPPED(&ill->ill_token));
11506 11512          sin6->sin6_addr = ill->ill_token;
11507 11513          lifr->lifr_addrlen = ill->ill_token_length;
11508 11514          return (0);
11509 11515  }
11510 11516  
11511 11517  /*
11512 11518   * Set (hardware) link specific information that might override
11513 11519   * what was acquired through the DL_INFO_ACK.
11514 11520   */
11515 11521  /* ARGSUSED */
11516 11522  int
11517 11523  ip_sioctl_lnkinfo(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11518 11524      ip_ioctl_cmd_t *ipi, void *if_req)
11519 11525  {
11520 11526          ill_t           *ill = ipif->ipif_ill;
11521 11527          int             ip_min_mtu;
11522 11528          struct lifreq   *lifr = (struct lifreq *)if_req;
11523 11529          lif_ifinfo_req_t *lir;
11524 11530  
11525 11531          ip1dbg(("ip_sioctl_lnkinfo(%s:%u %p)\n",
11526 11532              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11527 11533          lir = &lifr->lifr_ifinfo;
11528 11534          ASSERT(IAM_WRITER_IPIF(ipif));
11529 11535  
11530 11536          /* Only allow for logical unit zero i.e. not on "bge0:17" */
11531 11537          if (ipif->ipif_id != 0)
11532 11538                  return (EINVAL);
11533 11539  
11534 11540          /* Set interface MTU. */
11535 11541          if (ipif->ipif_isv6)
11536 11542                  ip_min_mtu = IPV6_MIN_MTU;
11537 11543          else
11538 11544                  ip_min_mtu = IP_MIN_MTU;
11539 11545  
11540 11546          /*
11541 11547           * Verify values before we set anything. Allow zero to
11542 11548           * mean unspecified.
11543 11549           *
11544 11550           * XXX We should be able to set the user-defined lir_mtu to some value
11545 11551           * that is greater than ill_current_frag but less than ill_max_frag- the
11546 11552           * ill_max_frag value tells us the max MTU that can be handled by the
11547 11553           * datalink, whereas the ill_current_frag is dynamically computed for
11548 11554           * some link-types like tunnels, based on the tunnel PMTU. However,
11549 11555           * since there is currently no way of distinguishing between
11550 11556           * administratively fixed link mtu values (e.g., those set via
11551 11557           * /sbin/dladm) and dynamically discovered MTUs (e.g., those discovered
11552 11558           * for tunnels) we conservatively choose the  ill_current_frag as the
11553 11559           * upper-bound.
11554 11560           */
11555 11561          if (lir->lir_maxmtu != 0 &&
11556 11562              (lir->lir_maxmtu > ill->ill_current_frag ||
11557 11563              lir->lir_maxmtu < ip_min_mtu))
11558 11564                  return (EINVAL);
11559 11565          if (lir->lir_reachtime != 0 &&
11560 11566              lir->lir_reachtime > ND_MAX_REACHTIME)
11561 11567                  return (EINVAL);
11562 11568          if (lir->lir_reachretrans != 0 &&
11563 11569              lir->lir_reachretrans > ND_MAX_REACHRETRANSTIME)
11564 11570                  return (EINVAL);
11565 11571  
11566 11572          mutex_enter(&ill->ill_lock);
11567 11573          /*
11568 11574           * The dce and fragmentation code can handle changes to ill_mtu
11569 11575           * concurrent with sending/fragmenting packets.
11570 11576           */
11571 11577          if (lir->lir_maxmtu != 0)
11572 11578                  ill->ill_user_mtu = lir->lir_maxmtu;
11573 11579  
11574 11580          if (lir->lir_reachtime != 0)
11575 11581                  ill->ill_reachable_time = lir->lir_reachtime;
11576 11582  
11577 11583          if (lir->lir_reachretrans != 0)
11578 11584                  ill->ill_reachable_retrans_time = lir->lir_reachretrans;
11579 11585  
11580 11586          ill->ill_max_hops = lir->lir_maxhops;
11581 11587          ill->ill_max_buf = ND_MAX_Q;
11582 11588          if (!(ill->ill_flags & ILLF_FIXEDMTU) && ill->ill_user_mtu != 0) {
11583 11589                  /*
11584 11590                   * ill_mtu is the actual interface MTU, obtained as the min
11585 11591                   * of user-configured mtu and the value announced by the
11586 11592                   * driver (via DL_NOTE_SDU_SIZE/DL_INFO_ACK). Note that since
11587 11593                   * we have already made the choice of requiring
11588 11594                   * ill_user_mtu < ill_current_frag by the time we get here,
11589 11595                   * the ill_mtu effectively gets assigned to the ill_user_mtu
11590 11596                   * here.
11591 11597                   */
11592 11598                  ill->ill_mtu = MIN(ill->ill_current_frag, ill->ill_user_mtu);
11593 11599                  ill->ill_mc_mtu = MIN(ill->ill_mc_mtu, ill->ill_user_mtu);
11594 11600          }
11595 11601          mutex_exit(&ill->ill_lock);
11596 11602  
11597 11603          /*
11598 11604           * Make sure all dce_generation checks find out
11599 11605           * that ill_mtu/ill_mc_mtu has changed.
11600 11606           */
11601 11607          if (!(ill->ill_flags & ILLF_FIXEDMTU) && (lir->lir_maxmtu != 0))
11602 11608                  dce_increment_all_generations(ill->ill_isv6, ill->ill_ipst);
11603 11609  
11604 11610          /*
11605 11611           * Refresh IPMP meta-interface MTU if necessary.
11606 11612           */
11607 11613          if (IS_UNDER_IPMP(ill))
11608 11614                  ipmp_illgrp_refresh_mtu(ill->ill_grp);
11609 11615  
11610 11616          return (0);
11611 11617  }
11612 11618  
11613 11619  /* ARGSUSED */
11614 11620  int
11615 11621  ip_sioctl_get_lnkinfo(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
11616 11622      ip_ioctl_cmd_t *ipi, void *if_req)
11617 11623  {
11618 11624          struct lif_ifinfo_req *lir;
11619 11625          ill_t *ill = ipif->ipif_ill;
11620 11626  
11621 11627          ip1dbg(("ip_sioctl_get_lnkinfo(%s:%u %p)\n",
11622 11628              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
11623 11629          if (ipif->ipif_id != 0)
11624 11630                  return (EINVAL);
11625 11631  
11626 11632          lir = &((struct lifreq *)if_req)->lifr_ifinfo;
11627 11633          lir->lir_maxhops = ill->ill_max_hops;
11628 11634          lir->lir_reachtime = ill->ill_reachable_time;
11629 11635          lir->lir_reachretrans = ill->ill_reachable_retrans_time;
11630 11636          lir->lir_maxmtu = ill->ill_mtu;
11631 11637  
11632 11638          return (0);
11633 11639  }
11634 11640  
11635 11641  /*
11636 11642   * Return best guess as to the subnet mask for the specified address.
11637 11643   * Based on the subnet masks for all the configured interfaces.
11638 11644   *
11639 11645   * We end up returning a zero mask in the case of default, multicast or
11640 11646   * experimental.
11641 11647   */
11642 11648  static ipaddr_t
11643 11649  ip_subnet_mask(ipaddr_t addr, ipif_t **ipifp, ip_stack_t *ipst)
11644 11650  {
11645 11651          ipaddr_t net_mask;
11646 11652          ill_t   *ill;
11647 11653          ipif_t  *ipif;
11648 11654          ill_walk_context_t ctx;
11649 11655          ipif_t  *fallback_ipif = NULL;
11650 11656  
11651 11657          net_mask = ip_net_mask(addr);
11652 11658          if (net_mask == 0) {
11653 11659                  *ipifp = NULL;
11654 11660                  return (0);
11655 11661          }
11656 11662  
11657 11663          /* Let's check to see if this is maybe a local subnet route. */
11658 11664          /* this function only applies to IPv4 interfaces */
11659 11665          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
11660 11666          ill = ILL_START_WALK_V4(&ctx, ipst);
11661 11667          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
11662 11668                  mutex_enter(&ill->ill_lock);
11663 11669                  for (ipif = ill->ill_ipif; ipif != NULL;
11664 11670                      ipif = ipif->ipif_next) {
11665 11671                          if (IPIF_IS_CONDEMNED(ipif))
11666 11672                                  continue;
11667 11673                          if (!(ipif->ipif_flags & IPIF_UP))
11668 11674                                  continue;
11669 11675                          if ((ipif->ipif_subnet & net_mask) ==
11670 11676                              (addr & net_mask)) {
11671 11677                                  /*
11672 11678                                   * Don't trust pt-pt interfaces if there are
11673 11679                                   * other interfaces.
11674 11680                                   */
11675 11681                                  if (ipif->ipif_flags & IPIF_POINTOPOINT) {
11676 11682                                          if (fallback_ipif == NULL) {
11677 11683                                                  ipif_refhold_locked(ipif);
11678 11684                                                  fallback_ipif = ipif;
11679 11685                                          }
11680 11686                                          continue;
11681 11687                                  }
11682 11688  
11683 11689                                  /*
11684 11690                                   * Fine. Just assume the same net mask as the
11685 11691                                   * directly attached subnet interface is using.
11686 11692                                   */
11687 11693                                  ipif_refhold_locked(ipif);
11688 11694                                  mutex_exit(&ill->ill_lock);
11689 11695                                  rw_exit(&ipst->ips_ill_g_lock);
11690 11696                                  if (fallback_ipif != NULL)
11691 11697                                          ipif_refrele(fallback_ipif);
11692 11698                                  *ipifp = ipif;
11693 11699                                  return (ipif->ipif_net_mask);
11694 11700                          }
11695 11701                  }
11696 11702                  mutex_exit(&ill->ill_lock);
11697 11703          }
11698 11704          rw_exit(&ipst->ips_ill_g_lock);
11699 11705  
11700 11706          *ipifp = fallback_ipif;
11701 11707          return ((fallback_ipif != NULL) ?
11702 11708              fallback_ipif->ipif_net_mask : net_mask);
11703 11709  }
11704 11710  
11705 11711  /*
11706 11712   * ip_sioctl_copyin_setup calls ip_wput_ioctl to process the IP_IOCTL ioctl.
11707 11713   */
11708 11714  static void
11709 11715  ip_wput_ioctl(queue_t *q, mblk_t *mp)
11710 11716  {
11711 11717          IOCP    iocp;
11712 11718          ipft_t  *ipft;
11713 11719          ipllc_t *ipllc;
11714 11720          mblk_t  *mp1;
11715 11721          cred_t  *cr;
11716 11722          int     error = 0;
11717 11723          conn_t  *connp;
11718 11724  
11719 11725          ip1dbg(("ip_wput_ioctl"));
11720 11726          iocp = (IOCP)mp->b_rptr;
11721 11727          mp1 = mp->b_cont;
11722 11728          if (mp1 == NULL) {
11723 11729                  iocp->ioc_error = EINVAL;
11724 11730                  mp->b_datap->db_type = M_IOCNAK;
11725 11731                  iocp->ioc_count = 0;
11726 11732                  qreply(q, mp);
11727 11733                  return;
11728 11734          }
11729 11735  
11730 11736          /*
11731 11737           * These IOCTLs provide various control capabilities to
11732 11738           * upstream agents such as ULPs and processes.  There
11733 11739           * are currently two such IOCTLs implemented.  They
11734 11740           * are used by TCP to provide update information for
11735 11741           * existing IREs and to forcibly delete an IRE for a
11736 11742           * host that is not responding, thereby forcing an
11737 11743           * attempt at a new route.
11738 11744           */
11739 11745          iocp->ioc_error = EINVAL;
11740 11746          if (!pullupmsg(mp1, sizeof (ipllc->ipllc_cmd)))
11741 11747                  goto done;
11742 11748  
11743 11749          ipllc = (ipllc_t *)mp1->b_rptr;
11744 11750          for (ipft = ip_ioctl_ftbl; ipft->ipft_pfi; ipft++) {
11745 11751                  if (ipllc->ipllc_cmd == ipft->ipft_cmd)
11746 11752                          break;
11747 11753          }
11748 11754          /*
11749 11755           * prefer credential from mblk over ioctl;
11750 11756           * see ip_sioctl_copyin_setup
11751 11757           */
11752 11758          cr = msg_getcred(mp, NULL);
11753 11759          if (cr == NULL)
11754 11760                  cr = iocp->ioc_cr;
11755 11761  
11756 11762          /*
11757 11763           * Refhold the conn in case the request gets queued up in some lookup
11758 11764           */
11759 11765          ASSERT(CONN_Q(q));
11760 11766          connp = Q_TO_CONN(q);
11761 11767          CONN_INC_REF(connp);
11762 11768          CONN_INC_IOCTLREF(connp);
11763 11769          if (ipft->ipft_pfi &&
11764 11770              ((mp1->b_wptr - mp1->b_rptr) >= ipft->ipft_min_size ||
11765 11771              pullupmsg(mp1, ipft->ipft_min_size))) {
11766 11772                  error = (*ipft->ipft_pfi)(q,
11767 11773                      (ipft->ipft_flags & IPFT_F_SELF_REPLY) ? mp : mp1, cr);
11768 11774          }
11769 11775          if (ipft->ipft_flags & IPFT_F_SELF_REPLY) {
11770 11776                  /*
11771 11777                   * CONN_OPER_PENDING_DONE happens in the function called
11772 11778                   * through ipft_pfi above.
11773 11779                   */
11774 11780                  return;
11775 11781          }
11776 11782  
11777 11783          CONN_DEC_IOCTLREF(connp);
11778 11784          CONN_OPER_PENDING_DONE(connp);
11779 11785          if (ipft->ipft_flags & IPFT_F_NO_REPLY) {
11780 11786                  freemsg(mp);
11781 11787                  return;
11782 11788          }
11783 11789          iocp->ioc_error = error;
11784 11790  
11785 11791  done:
11786 11792          mp->b_datap->db_type = M_IOCACK;
11787 11793          if (iocp->ioc_error)
11788 11794                  iocp->ioc_count = 0;
11789 11795          qreply(q, mp);
11790 11796  }
11791 11797  
11792 11798  /*
11793 11799   * Assign a unique id for the ipif. This is used by sctp_addr.c
11794 11800   * Note: remove if sctp_addr.c is redone to not shadow ill/ipif data structures.
11795 11801   */
11796 11802  static void
11797 11803  ipif_assign_seqid(ipif_t *ipif)
11798 11804  {
11799 11805          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
11800 11806  
11801 11807          ipif->ipif_seqid = atomic_add_64_nv(&ipst->ips_ipif_g_seqid, 1);
11802 11808  }
11803 11809  
11804 11810  /*
11805 11811   * Clone the contents of `sipif' to `dipif'.  Requires that both ipifs are
11806 11812   * administratively down (i.e., no DAD), of the same type, and locked.  Note
11807 11813   * that the clone is complete -- including the seqid -- and the expectation is
11808 11814   * that the caller will either free or overwrite `sipif' before it's unlocked.
11809 11815   */
11810 11816  static void
11811 11817  ipif_clone(const ipif_t *sipif, ipif_t *dipif)
11812 11818  {
11813 11819          ASSERT(MUTEX_HELD(&sipif->ipif_ill->ill_lock));
11814 11820          ASSERT(MUTEX_HELD(&dipif->ipif_ill->ill_lock));
11815 11821          ASSERT(!(sipif->ipif_flags & (IPIF_UP|IPIF_DUPLICATE)));
11816 11822          ASSERT(!(dipif->ipif_flags & (IPIF_UP|IPIF_DUPLICATE)));
11817 11823          ASSERT(sipif->ipif_ire_type == dipif->ipif_ire_type);
11818 11824  
11819 11825          dipif->ipif_flags = sipif->ipif_flags;
11820 11826          dipif->ipif_zoneid = sipif->ipif_zoneid;
11821 11827          dipif->ipif_v6subnet = sipif->ipif_v6subnet;
11822 11828          dipif->ipif_v6lcl_addr = sipif->ipif_v6lcl_addr;
11823 11829          dipif->ipif_v6net_mask = sipif->ipif_v6net_mask;
11824 11830          dipif->ipif_v6brd_addr = sipif->ipif_v6brd_addr;
11825 11831          dipif->ipif_v6pp_dst_addr = sipif->ipif_v6pp_dst_addr;
11826 11832  
11827 11833          /*
11828 11834           * As per the comment atop the function, we assume that these sipif
11829 11835           * fields will be changed before sipif is unlocked.
11830 11836           */
11831 11837          dipif->ipif_seqid = sipif->ipif_seqid;
11832 11838          dipif->ipif_state_flags = sipif->ipif_state_flags;
11833 11839  }
11834 11840  
11835 11841  /*
11836 11842   * Transfer the contents of `sipif' to `dipif', and then free (if `virgipif'
11837 11843   * is NULL) or overwrite `sipif' with `virgipif', which must be a virgin
11838 11844   * (unreferenced) ipif.  Also, if `sipif' is used by the current xop, then
11839 11845   * transfer the xop to `dipif'.  Requires that all ipifs are administratively
11840 11846   * down (i.e., no DAD), of the same type, and unlocked.
11841 11847   */
11842 11848  static void
11843 11849  ipif_transfer(ipif_t *sipif, ipif_t *dipif, ipif_t *virgipif)
11844 11850  {
11845 11851          ipsq_t *ipsq = sipif->ipif_ill->ill_phyint->phyint_ipsq;
11846 11852          ipxop_t *ipx = ipsq->ipsq_xop;
11847 11853  
11848 11854          ASSERT(sipif != dipif);
11849 11855          ASSERT(sipif != virgipif);
11850 11856  
11851 11857          /*
11852 11858           * Grab all of the locks that protect the ipif in a defined order.
11853 11859           */
11854 11860          GRAB_ILL_LOCKS(sipif->ipif_ill, dipif->ipif_ill);
11855 11861  
11856 11862          ipif_clone(sipif, dipif);
11857 11863          if (virgipif != NULL) {
11858 11864                  ipif_clone(virgipif, sipif);
11859 11865                  mi_free(virgipif);
11860 11866          }
11861 11867  
11862 11868          RELEASE_ILL_LOCKS(sipif->ipif_ill, dipif->ipif_ill);
11863 11869  
11864 11870          /*
11865 11871           * Transfer ownership of the current xop, if necessary.
11866 11872           */
11867 11873          if (ipx->ipx_current_ipif == sipif) {
11868 11874                  ASSERT(ipx->ipx_pending_ipif == NULL);
11869 11875                  mutex_enter(&ipx->ipx_lock);
11870 11876                  ipx->ipx_current_ipif = dipif;
11871 11877                  mutex_exit(&ipx->ipx_lock);
11872 11878          }
11873 11879  
11874 11880          if (virgipif == NULL)
11875 11881                  mi_free(sipif);
11876 11882  }
11877 11883  
11878 11884  /*
11879 11885   * checks if:
11880 11886   *      - <ill_name>:<ipif_id> is at most LIFNAMSIZ - 1 and
11881 11887   *      - logical interface is within the allowed range
11882 11888   */
11883 11889  static int
11884 11890  is_lifname_valid(ill_t *ill, unsigned int ipif_id)
11885 11891  {
11886 11892          if (snprintf(NULL, 0, "%s:%d", ill->ill_name, ipif_id) >= LIFNAMSIZ)
11887 11893                  return (ENAMETOOLONG);
11888 11894  
11889 11895          if (ipif_id >= ill->ill_ipst->ips_ip_addrs_per_if)
11890 11896                  return (ERANGE);
11891 11897          return (0);
11892 11898  }
11893 11899  
11894 11900  /*
11895 11901   * Insert the ipif, so that the list of ipifs on the ill will be sorted
11896 11902   * with respect to ipif_id. Note that an ipif with an ipif_id of -1 will
11897 11903   * be inserted into the first space available in the list. The value of
11898 11904   * ipif_id will then be set to the appropriate value for its position.
11899 11905   */
11900 11906  static int
11901 11907  ipif_insert(ipif_t *ipif, boolean_t acquire_g_lock)
11902 11908  {
11903 11909          ill_t *ill;
11904 11910          ipif_t *tipif;
11905 11911          ipif_t **tipifp;
11906 11912          int id, err;
11907 11913          ip_stack_t      *ipst;
11908 11914  
11909 11915          ASSERT(ipif->ipif_ill->ill_net_type == IRE_LOOPBACK ||
11910 11916              IAM_WRITER_IPIF(ipif));
11911 11917  
11912 11918          ill = ipif->ipif_ill;
11913 11919          ASSERT(ill != NULL);
11914 11920          ipst = ill->ill_ipst;
11915 11921  
11916 11922          /*
11917 11923           * In the case of lo0:0 we already hold the ill_g_lock.
11918 11924           * ill_lookup_on_name (acquires ill_g_lock) -> ipif_allocate ->
11919 11925           * ipif_insert.
11920 11926           */
11921 11927          if (acquire_g_lock)
11922 11928                  rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
11923 11929          mutex_enter(&ill->ill_lock);
11924 11930          id = ipif->ipif_id;
11925 11931          tipifp = &(ill->ill_ipif);
11926 11932          if (id == -1) { /* need to find a real id */
11927 11933                  id = 0;
11928 11934                  while ((tipif = *tipifp) != NULL) {
11929 11935                          ASSERT(tipif->ipif_id >= id);
11930 11936                          if (tipif->ipif_id != id)
11931 11937                                  break; /* non-consecutive id */
11932 11938                          id++;
11933 11939                          tipifp = &(tipif->ipif_next);
11934 11940                  }
11935 11941                  if ((err = is_lifname_valid(ill, id)) != 0) {
11936 11942                          mutex_exit(&ill->ill_lock);
11937 11943                          if (acquire_g_lock)
11938 11944                                  rw_exit(&ipst->ips_ill_g_lock);
11939 11945                          return (err);
11940 11946                  }
11941 11947                  ipif->ipif_id = id; /* assign new id */
11942 11948          } else if ((err = is_lifname_valid(ill, id)) == 0) {
11943 11949                  /* we have a real id; insert ipif in the right place */
11944 11950                  while ((tipif = *tipifp) != NULL) {
11945 11951                          ASSERT(tipif->ipif_id != id);
11946 11952                          if (tipif->ipif_id > id)
11947 11953                                  break; /* found correct location */
11948 11954                          tipifp = &(tipif->ipif_next);
11949 11955                  }
11950 11956          } else {
11951 11957                  mutex_exit(&ill->ill_lock);
11952 11958                  if (acquire_g_lock)
11953 11959                          rw_exit(&ipst->ips_ill_g_lock);
11954 11960                  return (err);
11955 11961          }
11956 11962  
11957 11963          ASSERT(tipifp != &(ill->ill_ipif) || id == 0);
11958 11964  
11959 11965          ipif->ipif_next = tipif;
11960 11966          *tipifp = ipif;
11961 11967          mutex_exit(&ill->ill_lock);
11962 11968          if (acquire_g_lock)
11963 11969                  rw_exit(&ipst->ips_ill_g_lock);
11964 11970  
11965 11971          return (0);
11966 11972  }
11967 11973  
11968 11974  static void
11969 11975  ipif_remove(ipif_t *ipif)
11970 11976  {
11971 11977          ipif_t  **ipifp;
11972 11978          ill_t   *ill = ipif->ipif_ill;
11973 11979  
11974 11980          ASSERT(RW_WRITE_HELD(&ill->ill_ipst->ips_ill_g_lock));
11975 11981  
11976 11982          mutex_enter(&ill->ill_lock);
11977 11983          ipifp = &ill->ill_ipif;
11978 11984          for (; *ipifp != NULL; ipifp = &ipifp[0]->ipif_next) {
11979 11985                  if (*ipifp == ipif) {
11980 11986                          *ipifp = ipif->ipif_next;
11981 11987                          break;
11982 11988                  }
11983 11989          }
11984 11990          mutex_exit(&ill->ill_lock);
11985 11991  }
11986 11992  
11987 11993  /*
11988 11994   * Allocate and initialize a new interface control structure.  (Always
11989 11995   * called as writer.)
11990 11996   * When ipif_allocate() is called from ip_ll_subnet_defaults, the ill
11991 11997   * is not part of the global linked list of ills. ipif_seqid is unique
11992 11998   * in the system and to preserve the uniqueness, it is assigned only
11993 11999   * when ill becomes part of the global list. At that point ill will
11994 12000   * have a name. If it doesn't get assigned here, it will get assigned
11995 12001   * in ipif_set_values() as part of SIOCSLIFNAME processing.
11996 12002   * Aditionally, if we come here from ip_ll_subnet_defaults, we don't set
11997 12003   * the interface flags or any other information from the DL_INFO_ACK for
11998 12004   * DL_STYLE2 drivers (initialize == B_FALSE), since we won't have them at
11999 12005   * this point. The flags etc. will be set in ip_ll_subnet_defaults when the
12000 12006   * second DL_INFO_ACK comes in from the driver.
12001 12007   */
12002 12008  static ipif_t *
12003 12009  ipif_allocate(ill_t *ill, int id, uint_t ire_type, boolean_t initialize,
12004 12010      boolean_t insert, int *errorp)
12005 12011  {
12006 12012          int err;
12007 12013          ipif_t  *ipif;
12008 12014          ip_stack_t *ipst = ill->ill_ipst;
12009 12015  
12010 12016          ip1dbg(("ipif_allocate(%s:%d ill %p)\n",
12011 12017              ill->ill_name, id, (void *)ill));
12012 12018          ASSERT(ire_type == IRE_LOOPBACK || IAM_WRITER_ILL(ill));
12013 12019  
12014 12020          if (errorp != NULL)
12015 12021                  *errorp = 0;
12016 12022  
12017 12023          if ((ipif = mi_alloc(sizeof (ipif_t), BPRI_MED)) == NULL) {
12018 12024                  if (errorp != NULL)
12019 12025                          *errorp = ENOMEM;
12020 12026                  return (NULL);
12021 12027          }
12022 12028          *ipif = ipif_zero;      /* start clean */
12023 12029  
12024 12030          ipif->ipif_ill = ill;
12025 12031          ipif->ipif_id = id;     /* could be -1 */
12026 12032          /*
12027 12033           * Inherit the zoneid from the ill; for the shared stack instance
12028 12034           * this is always the global zone
12029 12035           */
12030 12036          ipif->ipif_zoneid = ill->ill_zoneid;
12031 12037  
12032 12038          ipif->ipif_refcnt = 0;
12033 12039  
12034 12040          if (insert) {
12035 12041                  if ((err = ipif_insert(ipif, ire_type != IRE_LOOPBACK)) != 0) {
12036 12042                          mi_free(ipif);
12037 12043                          if (errorp != NULL)
12038 12044                                  *errorp = err;
12039 12045                          return (NULL);
12040 12046                  }
12041 12047                  /* -1 id should have been replaced by real id */
12042 12048                  id = ipif->ipif_id;
12043 12049                  ASSERT(id >= 0);
12044 12050          }
12045 12051  
12046 12052          if (ill->ill_name[0] != '\0')
12047 12053                  ipif_assign_seqid(ipif);
12048 12054  
12049 12055          /*
12050 12056           * If this is the zeroth ipif on the IPMP ill, create the illgrp
12051 12057           * (which must not exist yet because the zeroth ipif is created once
12052 12058           * per ill).  However, do not not link it to the ipmp_grp_t until
12053 12059           * I_PLINK is called; see ip_sioctl_plink_ipmp() for details.
12054 12060           */
12055 12061          if (id == 0 && IS_IPMP(ill)) {
12056 12062                  if (ipmp_illgrp_create(ill) == NULL) {
12057 12063                          if (insert) {
12058 12064                                  rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
12059 12065                                  ipif_remove(ipif);
12060 12066                                  rw_exit(&ipst->ips_ill_g_lock);
12061 12067                          }
12062 12068                          mi_free(ipif);
12063 12069                          if (errorp != NULL)
12064 12070                                  *errorp = ENOMEM;
12065 12071                          return (NULL);
12066 12072                  }
12067 12073          }
12068 12074  
12069 12075          /*
12070 12076           * We grab ill_lock to protect the flag changes.  The ipif is still
12071 12077           * not up and can't be looked up until the ioctl completes and the
12072 12078           * IPIF_CHANGING flag is cleared.
12073 12079           */
12074 12080          mutex_enter(&ill->ill_lock);
12075 12081  
12076 12082          ipif->ipif_ire_type = ire_type;
12077 12083  
12078 12084          if (ipif->ipif_isv6) {
12079 12085                  ill->ill_flags |= ILLF_IPV6;
12080 12086          } else {
12081 12087                  ipaddr_t inaddr_any = INADDR_ANY;
12082 12088  
12083 12089                  ill->ill_flags |= ILLF_IPV4;
12084 12090  
12085 12091                  /* Keep the IN6_IS_ADDR_V4MAPPED assertions happy */
12086 12092                  IN6_IPADDR_TO_V4MAPPED(inaddr_any,
12087 12093                      &ipif->ipif_v6lcl_addr);
12088 12094                  IN6_IPADDR_TO_V4MAPPED(inaddr_any,
12089 12095                      &ipif->ipif_v6subnet);
12090 12096                  IN6_IPADDR_TO_V4MAPPED(inaddr_any,
12091 12097                      &ipif->ipif_v6net_mask);
12092 12098                  IN6_IPADDR_TO_V4MAPPED(inaddr_any,
12093 12099                      &ipif->ipif_v6brd_addr);
12094 12100                  IN6_IPADDR_TO_V4MAPPED(inaddr_any,
12095 12101                      &ipif->ipif_v6pp_dst_addr);
12096 12102          }
12097 12103  
12098 12104          /*
12099 12105           * Don't set the interface flags etc. now, will do it in
12100 12106           * ip_ll_subnet_defaults.
12101 12107           */
12102 12108          if (!initialize)
12103 12109                  goto out;
12104 12110  
12105 12111          /*
12106 12112           * NOTE: The IPMP meta-interface is special-cased because it starts
12107 12113           * with no underlying interfaces (and thus an unknown broadcast
12108 12114           * address length), but all interfaces that can be placed into an IPMP
12109 12115           * group are required to be broadcast-capable.
12110 12116           */
12111 12117          if (ill->ill_bcast_addr_length != 0 || IS_IPMP(ill)) {
12112 12118                  /*
12113 12119                   * Later detect lack of DLPI driver multicast capability by
12114 12120                   * catching DL_ENABMULTI_REQ errors in ip_rput_dlpi().
12115 12121                   */
12116 12122                  ill->ill_flags |= ILLF_MULTICAST;
12117 12123                  if (!ipif->ipif_isv6)
12118 12124                          ipif->ipif_flags |= IPIF_BROADCAST;
12119 12125          } else {
12120 12126                  if (ill->ill_net_type != IRE_LOOPBACK) {
12121 12127                          if (ipif->ipif_isv6)
12122 12128                                  /*
12123 12129                                   * Note: xresolv interfaces will eventually need
12124 12130                                   * NOARP set here as well, but that will require
12125 12131                                   * those external resolvers to have some
12126 12132                                   * knowledge of that flag and act appropriately.
12127 12133                                   * Not to be changed at present.
12128 12134                                   */
12129 12135                                  ill->ill_flags |= ILLF_NONUD;
12130 12136                          else
12131 12137                                  ill->ill_flags |= ILLF_NOARP;
12132 12138                  }
12133 12139                  if (ill->ill_phys_addr_length == 0) {
12134 12140                          if (IS_VNI(ill)) {
12135 12141                                  ipif->ipif_flags |= IPIF_NOXMIT;
12136 12142                          } else {
12137 12143                                  /* pt-pt supports multicast. */
12138 12144                                  ill->ill_flags |= ILLF_MULTICAST;
12139 12145                                  if (ill->ill_net_type != IRE_LOOPBACK)
12140 12146                                          ipif->ipif_flags |= IPIF_POINTOPOINT;
12141 12147                          }
12142 12148                  }
12143 12149          }
12144 12150  out:
12145 12151          mutex_exit(&ill->ill_lock);
12146 12152          return (ipif);
12147 12153  }
12148 12154  
12149 12155  /*
12150 12156   * Remove the neighbor cache entries associated with this logical
12151 12157   * interface.
12152 12158   */
12153 12159  int
12154 12160  ipif_arp_down(ipif_t *ipif)
12155 12161  {
12156 12162          ill_t   *ill = ipif->ipif_ill;
12157 12163          int     err = 0;
12158 12164  
12159 12165          ip1dbg(("ipif_arp_down(%s:%u)\n", ill->ill_name, ipif->ipif_id));
12160 12166          ASSERT(IAM_WRITER_IPIF(ipif));
12161 12167  
12162 12168          DTRACE_PROBE3(ipif__downup, char *, "ipif_arp_down",
12163 12169              ill_t *, ill, ipif_t *, ipif);
12164 12170          ipif_nce_down(ipif);
12165 12171  
12166 12172          /*
12167 12173           * If this is the last ipif that is going down and there are no
12168 12174           * duplicate addresses we may yet attempt to re-probe, then we need to
12169 12175           * clean up ARP completely.
12170 12176           */
12171 12177          if (ill->ill_ipif_up_count == 0 && ill->ill_ipif_dup_count == 0 &&
12172 12178              !ill->ill_logical_down && ill->ill_net_type == IRE_IF_RESOLVER) {
12173 12179                  /*
12174 12180                   * If this was the last ipif on an IPMP interface, purge any
12175 12181                   * static ARP entries associated with it.
12176 12182                   */
12177 12183                  if (IS_IPMP(ill))
12178 12184                          ipmp_illgrp_refresh_arpent(ill->ill_grp);
12179 12185  
12180 12186                  /* UNBIND, DETACH */
12181 12187                  err = arp_ll_down(ill);
12182 12188          }
12183 12189  
12184 12190          return (err);
12185 12191  }
12186 12192  
12187 12193  /*
12188 12194   * Get the resolver set up for a new IP address.  (Always called as writer.)
12189 12195   * Called both for IPv4 and IPv6 interfaces, though it only does some
12190 12196   * basic DAD related initialization for IPv6. Honors ILLF_NOARP.
12191 12197   *
12192 12198   * The enumerated value res_act tunes the behavior:
12193 12199   *      * Res_act_initial: set up all the resolver structures for a new
12194 12200   *        IP address.
12195 12201   *      * Res_act_defend: tell ARP that it needs to send a single gratuitous
12196 12202   *        ARP message in defense of the address.
12197 12203   *      * Res_act_rebind: tell ARP to change the hardware address for an IP
12198 12204   *        address (and issue gratuitous ARPs).  Used by ipmp_ill_bind_ipif().
12199 12205   *
12200 12206   * Returns zero on success, or an errno upon failure.
12201 12207   */
12202 12208  int
12203 12209  ipif_resolver_up(ipif_t *ipif, enum ip_resolver_action res_act)
12204 12210  {
12205 12211          ill_t           *ill = ipif->ipif_ill;
12206 12212          int             err;
12207 12213          boolean_t       was_dup;
12208 12214  
12209 12215          ip1dbg(("ipif_resolver_up(%s:%u) flags 0x%x\n",
12210 12216              ill->ill_name, ipif->ipif_id, (uint_t)ipif->ipif_flags));
12211 12217          ASSERT(IAM_WRITER_IPIF(ipif));
12212 12218  
12213 12219          was_dup = B_FALSE;
12214 12220          if (res_act == Res_act_initial) {
12215 12221                  ipif->ipif_addr_ready = 0;
12216 12222                  /*
12217 12223                   * We're bringing an interface up here.  There's no way that we
12218 12224                   * should need to shut down ARP now.
12219 12225                   */
12220 12226                  mutex_enter(&ill->ill_lock);
12221 12227                  if (ipif->ipif_flags & IPIF_DUPLICATE) {
12222 12228                          ipif->ipif_flags &= ~IPIF_DUPLICATE;
12223 12229                          ill->ill_ipif_dup_count--;
12224 12230                          was_dup = B_TRUE;
12225 12231                  }
12226 12232                  mutex_exit(&ill->ill_lock);
12227 12233          }
12228 12234          if (ipif->ipif_recovery_id != 0)
12229 12235                  (void) untimeout(ipif->ipif_recovery_id);
12230 12236          ipif->ipif_recovery_id = 0;
12231 12237          if (ill->ill_net_type != IRE_IF_RESOLVER) {
12232 12238                  ipif->ipif_addr_ready = 1;
12233 12239                  return (0);
12234 12240          }
12235 12241          /* NDP will set the ipif_addr_ready flag when it's ready */
12236 12242          if (ill->ill_isv6)
12237 12243                  return (0);
12238 12244  
12239 12245          err = ipif_arp_up(ipif, res_act, was_dup);
12240 12246          return (err);
12241 12247  }
12242 12248  
12243 12249  /*
12244 12250   * This routine restarts IPv4/IPv6 duplicate address detection (DAD)
12245 12251   * when a link has just gone back up.
12246 12252   */
12247 12253  static void
12248 12254  ipif_nce_start_dad(ipif_t *ipif)
12249 12255  {
12250 12256          ncec_t *ncec;
12251 12257          ill_t *ill = ipif->ipif_ill;
12252 12258          boolean_t isv6 = ill->ill_isv6;
12253 12259  
12254 12260          if (isv6) {
12255 12261                  ncec = ncec_lookup_illgrp_v6(ipif->ipif_ill,
12256 12262                      &ipif->ipif_v6lcl_addr);
12257 12263          } else {
12258 12264                  ipaddr_t v4addr;
12259 12265  
12260 12266                  if (ill->ill_net_type != IRE_IF_RESOLVER ||
12261 12267                      (ipif->ipif_flags & IPIF_UNNUMBERED) ||
12262 12268                      ipif->ipif_lcl_addr == INADDR_ANY) {
12263 12269                          /*
12264 12270                           * If we can't contact ARP for some reason,
12265 12271                           * that's not really a problem.  Just send
12266 12272                           * out the routing socket notification that
12267 12273                           * DAD completion would have done, and continue.
12268 12274                           */
12269 12275                          ipif_mask_reply(ipif);
12270 12276                          ipif_up_notify(ipif);
12271 12277                          ipif->ipif_addr_ready = 1;
12272 12278                          return;
12273 12279                  }
12274 12280  
12275 12281                  IN6_V4MAPPED_TO_IPADDR(&ipif->ipif_v6lcl_addr, v4addr);
12276 12282                  ncec = ncec_lookup_illgrp_v4(ipif->ipif_ill, &v4addr);
12277 12283          }
12278 12284  
12279 12285          if (ncec == NULL) {
12280 12286                  ip1dbg(("couldn't find ncec for ipif %p leaving !ready\n",
12281 12287                      (void *)ipif));
12282 12288                  return;
12283 12289          }
12284 12290          if (!nce_restart_dad(ncec)) {
12285 12291                  /*
12286 12292                   * If we can't restart DAD for some reason, that's not really a
12287 12293                   * problem.  Just send out the routing socket notification that
12288 12294                   * DAD completion would have done, and continue.
12289 12295                   */
12290 12296                  ipif_up_notify(ipif);
12291 12297                  ipif->ipif_addr_ready = 1;
12292 12298          }
12293 12299          ncec_refrele(ncec);
12294 12300  }
12295 12301  
12296 12302  /*
12297 12303   * Restart duplicate address detection on all interfaces on the given ill.
12298 12304   *
12299 12305   * This is called when an interface transitions from down to up
12300 12306   * (DL_NOTE_LINK_UP) or up to down (DL_NOTE_LINK_DOWN).
12301 12307   *
12302 12308   * Note that since the underlying physical link has transitioned, we must cause
12303 12309   * at least one routing socket message to be sent here, either via DAD
12304 12310   * completion or just by default on the first ipif.  (If we don't do this, then
12305 12311   * in.mpathd will see long delays when doing link-based failure recovery.)
12306 12312   */
12307 12313  void
12308 12314  ill_restart_dad(ill_t *ill, boolean_t went_up)
12309 12315  {
12310 12316          ipif_t *ipif;
12311 12317  
12312 12318          if (ill == NULL)
12313 12319                  return;
12314 12320  
12315 12321          /*
12316 12322           * If layer two doesn't support duplicate address detection, then just
12317 12323           * send the routing socket message now and be done with it.
12318 12324           */
12319 12325          if (!ill->ill_isv6 && arp_no_defense) {
12320 12326                  ip_rts_ifmsg(ill->ill_ipif, RTSQ_DEFAULT);
12321 12327                  return;
12322 12328          }
12323 12329  
12324 12330          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
12325 12331                  if (went_up) {
12326 12332  
12327 12333                          if (ipif->ipif_flags & IPIF_UP) {
12328 12334                                  ipif_nce_start_dad(ipif);
12329 12335                          } else if (ipif->ipif_flags & IPIF_DUPLICATE) {
12330 12336                                  /*
12331 12337                                   * kick off the bring-up process now.
12332 12338                                   */
12333 12339                                  ipif_do_recovery(ipif);
12334 12340                          } else {
12335 12341                                  /*
12336 12342                                   * Unfortunately, the first ipif is "special"
12337 12343                                   * and represents the underlying ill in the
12338 12344                                   * routing socket messages.  Thus, when this
12339 12345                                   * one ipif is down, we must still notify so
12340 12346                                   * that the user knows the IFF_RUNNING status
12341 12347                                   * change.  (If the first ipif is up, then
12342 12348                                   * we'll handle eventual routing socket
12343 12349                                   * notification via DAD completion.)
12344 12350                                   */
12345 12351                                  if (ipif == ill->ill_ipif) {
12346 12352                                          ip_rts_ifmsg(ill->ill_ipif,
12347 12353                                              RTSQ_DEFAULT);
12348 12354                                  }
12349 12355                          }
12350 12356                  } else {
12351 12357                          /*
12352 12358                           * After link down, we'll need to send a new routing
12353 12359                           * message when the link comes back, so clear
12354 12360                           * ipif_addr_ready.
12355 12361                           */
12356 12362                          ipif->ipif_addr_ready = 0;
12357 12363                  }
12358 12364          }
12359 12365  
12360 12366          /*
12361 12367           * If we've torn down links, then notify the user right away.
12362 12368           */
12363 12369          if (!went_up)
12364 12370                  ip_rts_ifmsg(ill->ill_ipif, RTSQ_DEFAULT);
12365 12371  }
12366 12372  
12367 12373  static void
12368 12374  ipsq_delete(ipsq_t *ipsq)
12369 12375  {
12370 12376          ipxop_t *ipx = ipsq->ipsq_xop;
12371 12377  
12372 12378          ipsq->ipsq_ipst = NULL;
12373 12379          ASSERT(ipsq->ipsq_phyint == NULL);
12374 12380          ASSERT(ipsq->ipsq_xop != NULL);
12375 12381          ASSERT(ipsq->ipsq_xopq_mphead == NULL && ipx->ipx_mphead == NULL);
12376 12382          ASSERT(ipx->ipx_pending_mp == NULL);
12377 12383          kmem_free(ipsq, sizeof (ipsq_t));
12378 12384  }
12379 12385  
12380 12386  static int
12381 12387  ill_up_ipifs_on_ill(ill_t *ill, queue_t *q, mblk_t *mp)
12382 12388  {
12383 12389          int err = 0;
12384 12390          ipif_t *ipif;
12385 12391  
12386 12392          if (ill == NULL)
12387 12393                  return (0);
12388 12394  
12389 12395          ASSERT(IAM_WRITER_ILL(ill));
12390 12396          ill->ill_up_ipifs = B_TRUE;
12391 12397          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
12392 12398                  if (ipif->ipif_was_up) {
12393 12399                          if (!(ipif->ipif_flags & IPIF_UP))
12394 12400                                  err = ipif_up(ipif, q, mp);
12395 12401                          ipif->ipif_was_up = B_FALSE;
12396 12402                          if (err != 0) {
12397 12403                                  ASSERT(err == EINPROGRESS);
12398 12404                                  return (err);
12399 12405                          }
12400 12406                  }
12401 12407          }
12402 12408          ill->ill_up_ipifs = B_FALSE;
12403 12409          return (0);
12404 12410  }
12405 12411  
12406 12412  /*
12407 12413   * This function is called to bring up all the ipifs that were up before
12408 12414   * bringing the ill down via ill_down_ipifs().
12409 12415   */
12410 12416  int
12411 12417  ill_up_ipifs(ill_t *ill, queue_t *q, mblk_t *mp)
12412 12418  {
12413 12419          int err;
12414 12420  
12415 12421          ASSERT(IAM_WRITER_ILL(ill));
12416 12422  
12417 12423          if (ill->ill_replumbing) {
12418 12424                  ill->ill_replumbing = 0;
12419 12425                  /*
12420 12426                   * Send down REPLUMB_DONE notification followed by the
12421 12427                   * BIND_REQ on the arp stream.
12422 12428                   */
12423 12429                  if (!ill->ill_isv6)
12424 12430                          arp_send_replumb_conf(ill);
12425 12431          }
12426 12432          err = ill_up_ipifs_on_ill(ill->ill_phyint->phyint_illv4, q, mp);
12427 12433          if (err != 0)
12428 12434                  return (err);
12429 12435  
12430 12436          return (ill_up_ipifs_on_ill(ill->ill_phyint->phyint_illv6, q, mp));
12431 12437  }
12432 12438  
12433 12439  /*
12434 12440   * Bring down any IPIF_UP ipifs on ill. If "logical" is B_TRUE, we bring
12435 12441   * down the ipifs without sending DL_UNBIND_REQ to the driver.
12436 12442   */
12437 12443  static void
12438 12444  ill_down_ipifs(ill_t *ill, boolean_t logical)
12439 12445  {
12440 12446          ipif_t *ipif;
12441 12447  
12442 12448          ASSERT(IAM_WRITER_ILL(ill));
12443 12449  
12444 12450          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
12445 12451                  /*
12446 12452                   * We go through the ipif_down logic even if the ipif
12447 12453                   * is already down, since routes can be added based
12448 12454                   * on down ipifs. Going through ipif_down once again
12449 12455                   * will delete any IREs created based on these routes.
12450 12456                   */
12451 12457                  if (ipif->ipif_flags & IPIF_UP)
12452 12458                          ipif->ipif_was_up = B_TRUE;
12453 12459  
12454 12460                  if (logical) {
12455 12461                          (void) ipif_logical_down(ipif, NULL, NULL);
12456 12462                          ipif_non_duplicate(ipif);
12457 12463                          (void) ipif_down_tail(ipif);
12458 12464                  } else {
12459 12465                          (void) ipif_down(ipif, NULL, NULL);
12460 12466                  }
12461 12467          }
12462 12468  }
12463 12469  
12464 12470  /*
12465 12471   * Redo source address selection.  This makes IXAF_VERIFY_SOURCE take
12466 12472   * a look again at valid source addresses.
12467 12473   * This should be called each time after the set of source addresses has been
12468 12474   * changed.
12469 12475   */
12470 12476  void
12471 12477  ip_update_source_selection(ip_stack_t *ipst)
12472 12478  {
12473 12479          /* We skip past SRC_GENERATION_VERIFY */
12474 12480          if (atomic_add_32_nv(&ipst->ips_src_generation, 1) ==
12475 12481              SRC_GENERATION_VERIFY)
12476 12482                  atomic_add_32(&ipst->ips_src_generation, 1);
12477 12483  }
12478 12484  
12479 12485  /*
12480 12486   * Finish the group join started in ip_sioctl_groupname().
12481 12487   */
12482 12488  /* ARGSUSED */
12483 12489  static void
12484 12490  ip_join_illgrps(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy)
12485 12491  {
12486 12492          ill_t           *ill = q->q_ptr;
12487 12493          phyint_t        *phyi = ill->ill_phyint;
12488 12494          ipmp_grp_t      *grp = phyi->phyint_grp;
12489 12495          ip_stack_t      *ipst = ill->ill_ipst;
12490 12496  
12491 12497          /* IS_UNDER_IPMP() won't work until ipmp_ill_join_illgrp() is called */
12492 12498          ASSERT(!IS_IPMP(ill) && grp != NULL);
12493 12499          ASSERT(IAM_WRITER_IPSQ(ipsq));
12494 12500  
12495 12501          if (phyi->phyint_illv4 != NULL) {
12496 12502                  rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
12497 12503                  VERIFY(grp->gr_pendv4-- > 0);
12498 12504                  rw_exit(&ipst->ips_ipmp_lock);
12499 12505                  ipmp_ill_join_illgrp(phyi->phyint_illv4, grp->gr_v4);
12500 12506          }
12501 12507          if (phyi->phyint_illv6 != NULL) {
12502 12508                  rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
12503 12509                  VERIFY(grp->gr_pendv6-- > 0);
12504 12510                  rw_exit(&ipst->ips_ipmp_lock);
12505 12511                  ipmp_ill_join_illgrp(phyi->phyint_illv6, grp->gr_v6);
12506 12512          }
12507 12513          freemsg(mp);
12508 12514  }
12509 12515  
12510 12516  /*
12511 12517   * Process an SIOCSLIFGROUPNAME request.
12512 12518   */
12513 12519  /* ARGSUSED */
12514 12520  int
12515 12521  ip_sioctl_groupname(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
12516 12522      ip_ioctl_cmd_t *ipip, void *ifreq)
12517 12523  {
12518 12524          struct lifreq   *lifr = ifreq;
12519 12525          ill_t           *ill = ipif->ipif_ill;
12520 12526          ip_stack_t      *ipst = ill->ill_ipst;
12521 12527          phyint_t        *phyi = ill->ill_phyint;
12522 12528          ipmp_grp_t      *grp = phyi->phyint_grp;
12523 12529          mblk_t          *ipsq_mp;
12524 12530          int             err = 0;
12525 12531  
12526 12532          /*
12527 12533           * Note that phyint_grp can only change here, where we're exclusive.
12528 12534           */
12529 12535          ASSERT(IAM_WRITER_ILL(ill));
12530 12536  
12531 12537          if (ipif->ipif_id != 0 || ill->ill_usesrc_grp_next != NULL ||
12532 12538              (phyi->phyint_flags & PHYI_VIRTUAL))
12533 12539                  return (EINVAL);
12534 12540  
12535 12541          lifr->lifr_groupname[LIFGRNAMSIZ - 1] = '\0';
12536 12542  
12537 12543          rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
12538 12544  
12539 12545          /*
12540 12546           * If the name hasn't changed, there's nothing to do.
12541 12547           */
12542 12548          if (grp != NULL && strcmp(grp->gr_name, lifr->lifr_groupname) == 0)
12543 12549                  goto unlock;
12544 12550  
12545 12551          /*
12546 12552           * Handle requests to rename an IPMP meta-interface.
12547 12553           *
12548 12554           * Note that creation of the IPMP meta-interface is handled in
12549 12555           * userland through the standard plumbing sequence.  As part of the
12550 12556           * plumbing the IPMP meta-interface, its initial groupname is set to
12551 12557           * the name of the interface (see ipif_set_values_tail()).
12552 12558           */
12553 12559          if (IS_IPMP(ill)) {
12554 12560                  err = ipmp_grp_rename(grp, lifr->lifr_groupname);
12555 12561                  goto unlock;
12556 12562          }
12557 12563  
12558 12564          /*
12559 12565           * Handle requests to add or remove an IP interface from a group.
12560 12566           */
12561 12567          if (lifr->lifr_groupname[0] != '\0') {                  /* add */
12562 12568                  /*
12563 12569                   * Moves are handled by first removing the interface from
12564 12570                   * its existing group, and then adding it to another group.
12565 12571                   * So, fail if it's already in a group.
12566 12572                   */
12567 12573                  if (IS_UNDER_IPMP(ill)) {
12568 12574                          err = EALREADY;
12569 12575                          goto unlock;
12570 12576                  }
12571 12577  
12572 12578                  grp = ipmp_grp_lookup(lifr->lifr_groupname, ipst);
12573 12579                  if (grp == NULL) {
12574 12580                          err = ENOENT;
12575 12581                          goto unlock;
12576 12582                  }
12577 12583  
12578 12584                  /*
12579 12585                   * Check if the phyint and its ills are suitable for
12580 12586                   * inclusion into the group.
12581 12587                   */
12582 12588                  if ((err = ipmp_grp_vet_phyint(grp, phyi)) != 0)
12583 12589                          goto unlock;
12584 12590  
12585 12591                  /*
12586 12592                   * Checks pass; join the group, and enqueue the remaining
12587 12593                   * illgrp joins for when we've become part of the group xop
12588 12594                   * and are exclusive across its IPSQs.  Since qwriter_ip()
12589 12595                   * requires an mblk_t to scribble on, and since `mp' will be
12590 12596                   * freed as part of completing the ioctl, allocate another.
12591 12597                   */
12592 12598                  if ((ipsq_mp = allocb(0, BPRI_MED)) == NULL) {
12593 12599                          err = ENOMEM;
12594 12600                          goto unlock;
12595 12601                  }
12596 12602  
12597 12603                  /*
12598 12604                   * Before we drop ipmp_lock, bump gr_pend* to ensure that the
12599 12605                   * IPMP meta-interface ills needed by `phyi' cannot go away
12600 12606                   * before ip_join_illgrps() is called back.  See the comments
12601 12607                   * in ip_sioctl_plink_ipmp() for more.
12602 12608                   */
12603 12609                  if (phyi->phyint_illv4 != NULL)
12604 12610                          grp->gr_pendv4++;
12605 12611                  if (phyi->phyint_illv6 != NULL)
12606 12612                          grp->gr_pendv6++;
12607 12613  
12608 12614                  rw_exit(&ipst->ips_ipmp_lock);
12609 12615  
12610 12616                  ipmp_phyint_join_grp(phyi, grp);
12611 12617                  ill_refhold(ill);
12612 12618                  qwriter_ip(ill, ill->ill_rq, ipsq_mp, ip_join_illgrps,
12613 12619                      SWITCH_OP, B_FALSE);
12614 12620                  return (0);
12615 12621          } else {
12616 12622                  /*
12617 12623                   * Request to remove the interface from a group.  If the
12618 12624                   * interface is not in a group, this trivially succeeds.
12619 12625                   */
12620 12626                  rw_exit(&ipst->ips_ipmp_lock);
12621 12627                  if (IS_UNDER_IPMP(ill))
12622 12628                          ipmp_phyint_leave_grp(phyi);
12623 12629                  return (0);
12624 12630          }
12625 12631  unlock:
12626 12632          rw_exit(&ipst->ips_ipmp_lock);
12627 12633          return (err);
12628 12634  }
12629 12635  
12630 12636  /*
12631 12637   * Process an SIOCGLIFBINDING request.
12632 12638   */
12633 12639  /* ARGSUSED */
12634 12640  int
12635 12641  ip_sioctl_get_binding(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
12636 12642      ip_ioctl_cmd_t *ipip, void *ifreq)
12637 12643  {
12638 12644          ill_t           *ill;
12639 12645          struct lifreq   *lifr = ifreq;
12640 12646          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
12641 12647  
12642 12648          if (!IS_IPMP(ipif->ipif_ill))
12643 12649                  return (EINVAL);
12644 12650  
12645 12651          rw_enter(&ipst->ips_ipmp_lock, RW_READER);
12646 12652          if ((ill = ipif->ipif_bound_ill) == NULL)
12647 12653                  lifr->lifr_binding[0] = '\0';
12648 12654          else
12649 12655                  (void) strlcpy(lifr->lifr_binding, ill->ill_name, LIFNAMSIZ);
12650 12656          rw_exit(&ipst->ips_ipmp_lock);
12651 12657          return (0);
12652 12658  }
12653 12659  
12654 12660  /*
12655 12661   * Process an SIOCGLIFGROUPNAME request.
12656 12662   */
12657 12663  /* ARGSUSED */
12658 12664  int
12659 12665  ip_sioctl_get_groupname(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
12660 12666      ip_ioctl_cmd_t *ipip, void *ifreq)
12661 12667  {
12662 12668          ipmp_grp_t      *grp;
12663 12669          struct lifreq   *lifr = ifreq;
12664 12670          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
12665 12671  
12666 12672          rw_enter(&ipst->ips_ipmp_lock, RW_READER);
12667 12673          if ((grp = ipif->ipif_ill->ill_phyint->phyint_grp) == NULL)
12668 12674                  lifr->lifr_groupname[0] = '\0';
12669 12675          else
12670 12676                  (void) strlcpy(lifr->lifr_groupname, grp->gr_name, LIFGRNAMSIZ);
12671 12677          rw_exit(&ipst->ips_ipmp_lock);
12672 12678          return (0);
12673 12679  }
12674 12680  
12675 12681  /*
12676 12682   * Process an SIOCGLIFGROUPINFO request.
12677 12683   */
12678 12684  /* ARGSUSED */
12679 12685  int
12680 12686  ip_sioctl_groupinfo(ipif_t *dummy_ipif, sin_t *sin, queue_t *q, mblk_t *mp,
12681 12687      ip_ioctl_cmd_t *ipip, void *dummy)
12682 12688  {
12683 12689          ipmp_grp_t      *grp;
12684 12690          lifgroupinfo_t  *lifgr;
12685 12691          ip_stack_t      *ipst = CONNQ_TO_IPST(q);
12686 12692  
12687 12693          /* ip_wput_nondata() verified mp->b_cont->b_cont */
12688 12694          lifgr = (lifgroupinfo_t *)mp->b_cont->b_cont->b_rptr;
12689 12695          lifgr->gi_grname[LIFGRNAMSIZ - 1] = '\0';
12690 12696  
12691 12697          rw_enter(&ipst->ips_ipmp_lock, RW_READER);
12692 12698          if ((grp = ipmp_grp_lookup(lifgr->gi_grname, ipst)) == NULL) {
12693 12699                  rw_exit(&ipst->ips_ipmp_lock);
12694 12700                  return (ENOENT);
12695 12701          }
12696 12702          ipmp_grp_info(grp, lifgr);
12697 12703          rw_exit(&ipst->ips_ipmp_lock);
12698 12704          return (0);
12699 12705  }
12700 12706  
12701 12707  static void
12702 12708  ill_dl_down(ill_t *ill)
12703 12709  {
12704 12710          DTRACE_PROBE2(ill__downup, char *, "ill_dl_down", ill_t *, ill);
12705 12711  
12706 12712          /*
12707 12713           * The ill is down; unbind but stay attached since we're still
12708 12714           * associated with a PPA. If we have negotiated DLPI capabilites
12709 12715           * with the data link service provider (IDS_OK) then reset them.
12710 12716           * The interval between unbinding and rebinding is potentially
12711 12717           * unbounded hence we cannot assume things will be the same.
12712 12718           * The DLPI capabilities will be probed again when the data link
12713 12719           * is brought up.
12714 12720           */
12715 12721          mblk_t  *mp = ill->ill_unbind_mp;
12716 12722  
12717 12723          ip1dbg(("ill_dl_down(%s)\n", ill->ill_name));
12718 12724  
12719 12725          if (!ill->ill_replumbing) {
12720 12726                  /* Free all ilms for this ill */
12721 12727                  update_conn_ill(ill, ill->ill_ipst);
12722 12728          } else {
12723 12729                  ill_leave_multicast(ill);
12724 12730          }
12725 12731  
12726 12732          ill->ill_unbind_mp = NULL;
12727 12733          if (mp != NULL) {
12728 12734                  ip1dbg(("ill_dl_down: %s (%u) for %s\n",
12729 12735                      dl_primstr(*(int *)mp->b_rptr), *(int *)mp->b_rptr,
12730 12736                      ill->ill_name));
12731 12737                  mutex_enter(&ill->ill_lock);
12732 12738                  ill->ill_state_flags |= ILL_DL_UNBIND_IN_PROGRESS;
12733 12739                  mutex_exit(&ill->ill_lock);
12734 12740                  /*
12735 12741                   * ip_rput does not pass up normal (M_PROTO) DLPI messages
12736 12742                   * after ILL_CONDEMNED is set. So in the unplumb case, we call
12737 12743                   * ill_capability_dld_disable disable rightaway. If this is not
12738 12744                   * an unplumb operation then the disable happens on receipt of
12739 12745                   * the capab ack via ip_rput_dlpi_writer ->
12740 12746                   * ill_capability_ack_thr. In both cases the order of
12741 12747                   * the operations seen by DLD is capability disable followed
12742 12748                   * by DL_UNBIND. Also the DLD capability disable needs a
12743 12749                   * cv_wait'able context.
12744 12750                   */
12745 12751                  if (ill->ill_state_flags & ILL_CONDEMNED)
12746 12752                          ill_capability_dld_disable(ill);
12747 12753                  ill_capability_reset(ill, B_FALSE);
12748 12754                  ill_dlpi_send(ill, mp);
12749 12755          }
12750 12756          mutex_enter(&ill->ill_lock);
12751 12757          ill->ill_dl_up = 0;
12752 12758          ill_nic_event_dispatch(ill, 0, NE_DOWN, NULL, 0);
12753 12759          mutex_exit(&ill->ill_lock);
12754 12760  }
12755 12761  
12756 12762  void
12757 12763  ill_dlpi_dispatch(ill_t *ill, mblk_t *mp)
12758 12764  {
12759 12765          union DL_primitives *dlp;
12760 12766          t_uscalar_t prim;
12761 12767          boolean_t waitack = B_FALSE;
12762 12768  
12763 12769          ASSERT(DB_TYPE(mp) == M_PROTO || DB_TYPE(mp) == M_PCPROTO);
12764 12770  
12765 12771          dlp = (union DL_primitives *)mp->b_rptr;
12766 12772          prim = dlp->dl_primitive;
12767 12773  
12768 12774          ip1dbg(("ill_dlpi_dispatch: sending %s (%u) to %s\n",
12769 12775              dl_primstr(prim), prim, ill->ill_name));
12770 12776  
12771 12777          switch (prim) {
12772 12778          case DL_PHYS_ADDR_REQ:
12773 12779          {
12774 12780                  dl_phys_addr_req_t *dlpap = (dl_phys_addr_req_t *)mp->b_rptr;
12775 12781                  ill->ill_phys_addr_pend = dlpap->dl_addr_type;
12776 12782                  break;
12777 12783          }
12778 12784          case DL_BIND_REQ:
12779 12785                  mutex_enter(&ill->ill_lock);
12780 12786                  ill->ill_state_flags &= ~ILL_DL_UNBIND_IN_PROGRESS;
12781 12787                  mutex_exit(&ill->ill_lock);
12782 12788                  break;
12783 12789          }
12784 12790  
12785 12791          /*
12786 12792           * Except for the ACKs for the M_PCPROTO messages, all other ACKs
12787 12793           * are dropped by ip_rput() if ILL_CONDEMNED is set. Therefore
12788 12794           * we only wait for the ACK of the DL_UNBIND_REQ.
12789 12795           */
12790 12796          mutex_enter(&ill->ill_lock);
12791 12797          if (!(ill->ill_state_flags & ILL_CONDEMNED) ||
12792 12798              (prim == DL_UNBIND_REQ)) {
12793 12799                  ill->ill_dlpi_pending = prim;
12794 12800                  waitack = B_TRUE;
12795 12801          }
12796 12802  
12797 12803          mutex_exit(&ill->ill_lock);
12798 12804          DTRACE_PROBE3(ill__dlpi, char *, "ill_dlpi_dispatch",
12799 12805              char *, dl_primstr(prim), ill_t *, ill);
12800 12806          putnext(ill->ill_wq, mp);
12801 12807  
12802 12808          /*
12803 12809           * There is no ack for DL_NOTIFY_CONF messages
12804 12810           */
12805 12811          if (waitack && prim == DL_NOTIFY_CONF)
12806 12812                  ill_dlpi_done(ill, prim);
12807 12813  }
12808 12814  
12809 12815  /*
12810 12816   * Helper function for ill_dlpi_send().
12811 12817   */
12812 12818  /* ARGSUSED */
12813 12819  static void
12814 12820  ill_dlpi_send_writer(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *arg)
12815 12821  {
12816 12822          ill_dlpi_send(q->q_ptr, mp);
12817 12823  }
12818 12824  
12819 12825  /*
12820 12826   * Send a DLPI control message to the driver but make sure there
12821 12827   * is only one outstanding message. Uses ill_dlpi_pending to tell
12822 12828   * when it must queue. ip_rput_dlpi_writer calls ill_dlpi_done()
12823 12829   * when an ACK or a NAK is received to process the next queued message.
12824 12830   */
12825 12831  void
12826 12832  ill_dlpi_send(ill_t *ill, mblk_t *mp)
12827 12833  {
12828 12834          mblk_t **mpp;
12829 12835  
12830 12836          ASSERT(DB_TYPE(mp) == M_PROTO || DB_TYPE(mp) == M_PCPROTO);
12831 12837  
12832 12838          /*
12833 12839           * To ensure that any DLPI requests for current exclusive operation
12834 12840           * are always completely sent before any DLPI messages for other
12835 12841           * operations, require writer access before enqueuing.
12836 12842           */
12837 12843          if (!IAM_WRITER_ILL(ill)) {
12838 12844                  ill_refhold(ill);
12839 12845                  /* qwriter_ip() does the ill_refrele() */
12840 12846                  qwriter_ip(ill, ill->ill_wq, mp, ill_dlpi_send_writer,
12841 12847                      NEW_OP, B_TRUE);
12842 12848                  return;
12843 12849          }
12844 12850  
12845 12851          mutex_enter(&ill->ill_lock);
12846 12852          if (ill->ill_dlpi_pending != DL_PRIM_INVAL) {
12847 12853                  /* Must queue message. Tail insertion */
12848 12854                  mpp = &ill->ill_dlpi_deferred;
12849 12855                  while (*mpp != NULL)
12850 12856                          mpp = &((*mpp)->b_next);
12851 12857  
12852 12858                  ip1dbg(("ill_dlpi_send: deferring request for %s "
12853 12859                      "while %s pending\n", ill->ill_name,
12854 12860                      dl_primstr(ill->ill_dlpi_pending)));
12855 12861  
12856 12862                  *mpp = mp;
12857 12863                  mutex_exit(&ill->ill_lock);
12858 12864                  return;
12859 12865          }
12860 12866          mutex_exit(&ill->ill_lock);
12861 12867          ill_dlpi_dispatch(ill, mp);
12862 12868  }
12863 12869  
12864 12870  void
12865 12871  ill_capability_send(ill_t *ill, mblk_t *mp)
12866 12872  {
12867 12873          ill->ill_capab_pending_cnt++;
12868 12874          ill_dlpi_send(ill, mp);
12869 12875  }
12870 12876  
12871 12877  void
12872 12878  ill_capability_done(ill_t *ill)
12873 12879  {
12874 12880          ASSERT(ill->ill_capab_pending_cnt != 0);
12875 12881  
12876 12882          ill_dlpi_done(ill, DL_CAPABILITY_REQ);
12877 12883  
12878 12884          ill->ill_capab_pending_cnt--;
12879 12885          if (ill->ill_capab_pending_cnt == 0 &&
12880 12886              ill->ill_dlpi_capab_state == IDCS_OK)
12881 12887                  ill_capability_reset_alloc(ill);
12882 12888  }
12883 12889  
12884 12890  /*
12885 12891   * Send all deferred DLPI messages without waiting for their ACKs.
12886 12892   */
12887 12893  void
12888 12894  ill_dlpi_send_deferred(ill_t *ill)
12889 12895  {
12890 12896          mblk_t *mp, *nextmp;
12891 12897  
12892 12898          /*
12893 12899           * Clear ill_dlpi_pending so that the message is not queued in
12894 12900           * ill_dlpi_send().
12895 12901           */
12896 12902          mutex_enter(&ill->ill_lock);
12897 12903          ill->ill_dlpi_pending = DL_PRIM_INVAL;
12898 12904          mp = ill->ill_dlpi_deferred;
12899 12905          ill->ill_dlpi_deferred = NULL;
12900 12906          mutex_exit(&ill->ill_lock);
12901 12907  
12902 12908          for (; mp != NULL; mp = nextmp) {
12903 12909                  nextmp = mp->b_next;
12904 12910                  mp->b_next = NULL;
12905 12911                  ill_dlpi_send(ill, mp);
12906 12912          }
12907 12913  }
12908 12914  
12909 12915  /*
12910 12916   * Clear all the deferred DLPI messages. Called on receiving an M_ERROR
12911 12917   * or M_HANGUP
12912 12918   */
12913 12919  static void
12914 12920  ill_dlpi_clear_deferred(ill_t *ill)
12915 12921  {
12916 12922          mblk_t  *mp, *nextmp;
12917 12923  
12918 12924          mutex_enter(&ill->ill_lock);
12919 12925          ill->ill_dlpi_pending = DL_PRIM_INVAL;
12920 12926          mp = ill->ill_dlpi_deferred;
12921 12927          ill->ill_dlpi_deferred = NULL;
12922 12928          mutex_exit(&ill->ill_lock);
12923 12929  
12924 12930          for (; mp != NULL; mp = nextmp) {
12925 12931                  nextmp = mp->b_next;
12926 12932                  inet_freemsg(mp);
12927 12933          }
12928 12934  }
12929 12935  
12930 12936  /*
12931 12937   * Check if the DLPI primitive `prim' is pending; print a warning if not.
12932 12938   */
12933 12939  boolean_t
12934 12940  ill_dlpi_pending(ill_t *ill, t_uscalar_t prim)
12935 12941  {
12936 12942          t_uscalar_t pending;
12937 12943  
12938 12944          mutex_enter(&ill->ill_lock);
12939 12945          if (ill->ill_dlpi_pending == prim) {
12940 12946                  mutex_exit(&ill->ill_lock);
12941 12947                  return (B_TRUE);
12942 12948          }
12943 12949  
12944 12950          /*
12945 12951           * During teardown, ill_dlpi_dispatch() will send DLPI requests
12946 12952           * without waiting, so don't print any warnings in that case.
12947 12953           */
12948 12954          if (ill->ill_state_flags & ILL_CONDEMNED) {
12949 12955                  mutex_exit(&ill->ill_lock);
12950 12956                  return (B_FALSE);
12951 12957          }
12952 12958          pending = ill->ill_dlpi_pending;
12953 12959          mutex_exit(&ill->ill_lock);
12954 12960  
12955 12961          if (pending == DL_PRIM_INVAL) {
12956 12962                  (void) mi_strlog(ill->ill_rq, 1, SL_CONSOLE|SL_ERROR|SL_TRACE,
12957 12963                      "received unsolicited ack for %s on %s\n",
12958 12964                      dl_primstr(prim), ill->ill_name);
12959 12965          } else {
12960 12966                  (void) mi_strlog(ill->ill_rq, 1, SL_CONSOLE|SL_ERROR|SL_TRACE,
12961 12967                      "received unexpected ack for %s on %s (expecting %s)\n",
12962 12968                      dl_primstr(prim), ill->ill_name, dl_primstr(pending));
12963 12969          }
12964 12970          return (B_FALSE);
12965 12971  }
12966 12972  
12967 12973  /*
12968 12974   * Complete the current DLPI operation associated with `prim' on `ill' and
12969 12975   * start the next queued DLPI operation (if any).  If there are no queued DLPI
12970 12976   * operations and the ill's current exclusive IPSQ operation has finished
12971 12977   * (i.e., ipsq_current_finish() was called), then clear ipsq_current_ipif to
12972 12978   * allow the next exclusive IPSQ operation to begin upon ipsq_exit().  See
12973 12979   * the comments above ipsq_current_finish() for details.
12974 12980   */
12975 12981  void
12976 12982  ill_dlpi_done(ill_t *ill, t_uscalar_t prim)
12977 12983  {
12978 12984          mblk_t *mp;
12979 12985          ipsq_t *ipsq = ill->ill_phyint->phyint_ipsq;
12980 12986          ipxop_t *ipx = ipsq->ipsq_xop;
12981 12987  
12982 12988          ASSERT(IAM_WRITER_IPSQ(ipsq));
12983 12989          mutex_enter(&ill->ill_lock);
12984 12990  
12985 12991          ASSERT(prim != DL_PRIM_INVAL);
12986 12992          ASSERT(ill->ill_dlpi_pending == prim);
12987 12993  
12988 12994          ip1dbg(("ill_dlpi_done: %s has completed %s (%u)\n", ill->ill_name,
12989 12995              dl_primstr(ill->ill_dlpi_pending), ill->ill_dlpi_pending));
12990 12996  
12991 12997          if ((mp = ill->ill_dlpi_deferred) == NULL) {
12992 12998                  ill->ill_dlpi_pending = DL_PRIM_INVAL;
12993 12999                  if (ipx->ipx_current_done) {
12994 13000                          mutex_enter(&ipx->ipx_lock);
12995 13001                          ipx->ipx_current_ipif = NULL;
12996 13002                          mutex_exit(&ipx->ipx_lock);
12997 13003                  }
12998 13004                  cv_signal(&ill->ill_cv);
12999 13005                  mutex_exit(&ill->ill_lock);
13000 13006                  return;
13001 13007          }
13002 13008  
13003 13009          ill->ill_dlpi_deferred = mp->b_next;
13004 13010          mp->b_next = NULL;
13005 13011          mutex_exit(&ill->ill_lock);
13006 13012  
13007 13013          ill_dlpi_dispatch(ill, mp);
13008 13014  }
13009 13015  
13010 13016  /*
13011 13017   * Queue a (multicast) DLPI control message to be sent to the driver by
13012 13018   * later calling ill_dlpi_send_queued.
13013 13019   * We queue them while holding a lock (ill_mcast_lock) to ensure that they
13014 13020   * are sent in order i.e., prevent a DL_DISABMULTI_REQ and DL_ENABMULTI_REQ
13015 13021   * for the same group to race.
13016 13022   * We send DLPI control messages in order using ill_lock.
13017 13023   * For IPMP we should be called on the cast_ill.
13018 13024   */
13019 13025  void
13020 13026  ill_dlpi_queue(ill_t *ill, mblk_t *mp)
13021 13027  {
13022 13028          mblk_t **mpp;
13023 13029  
13024 13030          ASSERT(DB_TYPE(mp) == M_PROTO || DB_TYPE(mp) == M_PCPROTO);
13025 13031  
13026 13032          mutex_enter(&ill->ill_lock);
13027 13033          /* Must queue message. Tail insertion */
13028 13034          mpp = &ill->ill_dlpi_deferred;
13029 13035          while (*mpp != NULL)
13030 13036                  mpp = &((*mpp)->b_next);
13031 13037  
13032 13038          *mpp = mp;
13033 13039          mutex_exit(&ill->ill_lock);
13034 13040  }
13035 13041  
13036 13042  /*
13037 13043   * Send the messages that were queued. Make sure there is only
13038 13044   * one outstanding message. ip_rput_dlpi_writer calls ill_dlpi_done()
13039 13045   * when an ACK or a NAK is received to process the next queued message.
13040 13046   * For IPMP we are called on the upper ill, but when send what is queued
13041 13047   * on the cast_ill.
13042 13048   */
13043 13049  void
13044 13050  ill_dlpi_send_queued(ill_t *ill)
13045 13051  {
13046 13052          mblk_t  *mp;
13047 13053          union DL_primitives *dlp;
13048 13054          t_uscalar_t prim;
13049 13055          ill_t *release_ill = NULL;
13050 13056  
13051 13057          if (IS_IPMP(ill)) {
13052 13058                  /* On the upper IPMP ill. */
13053 13059                  release_ill = ipmp_illgrp_hold_cast_ill(ill->ill_grp);
13054 13060                  if (release_ill == NULL) {
13055 13061                          /* Avoid ever sending anything down to the ipmpstub */
13056 13062                          return;
13057 13063                  }
13058 13064                  ill = release_ill;
13059 13065          }
13060 13066          mutex_enter(&ill->ill_lock);
13061 13067          while ((mp = ill->ill_dlpi_deferred) != NULL) {
13062 13068                  if (ill->ill_dlpi_pending != DL_PRIM_INVAL) {
13063 13069                          /* Can't send. Somebody else will send it */
13064 13070                          mutex_exit(&ill->ill_lock);
13065 13071                          goto done;
13066 13072                  }
13067 13073                  ill->ill_dlpi_deferred = mp->b_next;
13068 13074                  mp->b_next = NULL;
13069 13075                  if (!ill->ill_dl_up) {
13070 13076                          /*
13071 13077                           * Nobody there. All multicast addresses will be
13072 13078                           * re-joined when we get the DL_BIND_ACK bringing the
13073 13079                           * interface up.
13074 13080                           */
13075 13081                          freemsg(mp);
13076 13082                          continue;
13077 13083                  }
13078 13084                  dlp = (union DL_primitives *)mp->b_rptr;
13079 13085                  prim = dlp->dl_primitive;
13080 13086  
13081 13087                  if (!(ill->ill_state_flags & ILL_CONDEMNED) ||
13082 13088                      (prim == DL_UNBIND_REQ)) {
13083 13089                          ill->ill_dlpi_pending = prim;
13084 13090                  }
13085 13091                  mutex_exit(&ill->ill_lock);
13086 13092  
13087 13093                  DTRACE_PROBE3(ill__dlpi, char *, "ill_dlpi_send_queued",
13088 13094                      char *, dl_primstr(prim), ill_t *, ill);
13089 13095                  putnext(ill->ill_wq, mp);
13090 13096                  mutex_enter(&ill->ill_lock);
13091 13097          }
13092 13098          mutex_exit(&ill->ill_lock);
13093 13099  done:
13094 13100          if (release_ill != NULL)
13095 13101                  ill_refrele(release_ill);
13096 13102  }
13097 13103  
13098 13104  /*
13099 13105   * Queue an IP (IGMP/MLD) message to be sent by IP from
13100 13106   * ill_mcast_send_queued
13101 13107   * We queue them while holding a lock (ill_mcast_lock) to ensure that they
13102 13108   * are sent in order i.e., prevent a IGMP leave and IGMP join for the same
13103 13109   * group to race.
13104 13110   * We send them in order using ill_lock.
13105 13111   * For IPMP we are called on the upper ill, but we queue on the cast_ill.
13106 13112   */
13107 13113  void
13108 13114  ill_mcast_queue(ill_t *ill, mblk_t *mp)
13109 13115  {
13110 13116          mblk_t **mpp;
13111 13117          ill_t *release_ill = NULL;
13112 13118  
13113 13119          ASSERT(RW_LOCK_HELD(&ill->ill_mcast_lock));
13114 13120  
13115 13121          if (IS_IPMP(ill)) {
13116 13122                  /* On the upper IPMP ill. */
13117 13123                  release_ill = ipmp_illgrp_hold_cast_ill(ill->ill_grp);
13118 13124                  if (release_ill == NULL) {
13119 13125                          /* Discard instead of queuing for the ipmp interface */
13120 13126                          BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
13121 13127                          ip_drop_output("ipIfStatsOutDiscards - no cast_ill",
13122 13128                              mp, ill);
13123 13129                          freemsg(mp);
13124 13130                          return;
13125 13131                  }
13126 13132                  ill = release_ill;
13127 13133          }
13128 13134  
13129 13135          mutex_enter(&ill->ill_lock);
13130 13136          /* Must queue message. Tail insertion */
13131 13137          mpp = &ill->ill_mcast_deferred;
13132 13138          while (*mpp != NULL)
13133 13139                  mpp = &((*mpp)->b_next);
13134 13140  
13135 13141          *mpp = mp;
13136 13142          mutex_exit(&ill->ill_lock);
13137 13143          if (release_ill != NULL)
13138 13144                  ill_refrele(release_ill);
13139 13145  }
13140 13146  
13141 13147  /*
13142 13148   * Send the IP packets that were queued by ill_mcast_queue.
13143 13149   * These are IGMP/MLD packets.
13144 13150   *
13145 13151   * For IPMP we are called on the upper ill, but when send what is queued
13146 13152   * on the cast_ill.
13147 13153   *
13148 13154   * Request loopback of the report if we are acting as a multicast
13149 13155   * router, so that the process-level routing demon can hear it.
13150 13156   * This will run multiple times for the same group if there are members
13151 13157   * on the same group for multiple ipif's on the same ill. The
13152 13158   * igmp_input/mld_input code will suppress this due to the loopback thus we
13153 13159   * always loopback membership report.
13154 13160   *
13155 13161   * We also need to make sure that this does not get load balanced
13156 13162   * by IPMP. We do this by passing an ill to ip_output_simple.
13157 13163   */
13158 13164  void
13159 13165  ill_mcast_send_queued(ill_t *ill)
13160 13166  {
13161 13167          mblk_t  *mp;
13162 13168          ip_xmit_attr_t ixas;
13163 13169          ill_t *release_ill = NULL;
13164 13170  
13165 13171          if (IS_IPMP(ill)) {
13166 13172                  /* On the upper IPMP ill. */
13167 13173                  release_ill = ipmp_illgrp_hold_cast_ill(ill->ill_grp);
13168 13174                  if (release_ill == NULL) {
13169 13175                          /*
13170 13176                           * We should have no messages on the ipmp interface
13171 13177                           * but no point in trying to send them.
13172 13178                           */
13173 13179                          return;
13174 13180                  }
13175 13181                  ill = release_ill;
13176 13182          }
13177 13183          bzero(&ixas, sizeof (ixas));
13178 13184          ixas.ixa_zoneid = ALL_ZONES;
13179 13185          ixas.ixa_cred = kcred;
13180 13186          ixas.ixa_cpid = NOPID;
13181 13187          ixas.ixa_tsl = NULL;
13182 13188          /*
13183 13189           * Here we set ixa_ifindex. If IPMP it will be the lower ill which
13184 13190           * makes ip_select_route pick the IRE_MULTICAST for the cast_ill.
13185 13191           * That is necessary to handle IGMP/MLD snooping switches.
13186 13192           */
13187 13193          ixas.ixa_ifindex = ill->ill_phyint->phyint_ifindex;
13188 13194          ixas.ixa_ipst = ill->ill_ipst;
13189 13195  
13190 13196          mutex_enter(&ill->ill_lock);
13191 13197          while ((mp = ill->ill_mcast_deferred) != NULL) {
13192 13198                  ill->ill_mcast_deferred = mp->b_next;
13193 13199                  mp->b_next = NULL;
13194 13200                  if (!ill->ill_dl_up) {
13195 13201                          /*
13196 13202                           * Nobody there. Just drop the ip packets.
13197 13203                           * IGMP/MLD will resend later, if this is a replumb.
13198 13204                           */
13199 13205                          freemsg(mp);
13200 13206                          continue;
13201 13207                  }
13202 13208                  mutex_enter(&ill->ill_phyint->phyint_lock);
13203 13209                  if (IS_UNDER_IPMP(ill) && !ipmp_ill_is_active(ill)) {
13204 13210                          /*
13205 13211                           * When the ill is getting deactivated, we only want to
13206 13212                           * send the DLPI messages, so drop IGMP/MLD packets.
13207 13213                           * DLPI messages are handled by ill_dlpi_send_queued()
13208 13214                           */
13209 13215                          mutex_exit(&ill->ill_phyint->phyint_lock);
13210 13216                          freemsg(mp);
13211 13217                          continue;
13212 13218                  }
13213 13219                  mutex_exit(&ill->ill_phyint->phyint_lock);
13214 13220                  mutex_exit(&ill->ill_lock);
13215 13221  
13216 13222                  /* Check whether we are sending IPv4 or IPv6. */
13217 13223                  if (ill->ill_isv6) {
13218 13224                          ip6_t  *ip6h = (ip6_t *)mp->b_rptr;
13219 13225  
13220 13226                          ixas.ixa_multicast_ttl = ip6h->ip6_hops;
13221 13227                          ixas.ixa_flags = IXAF_BASIC_SIMPLE_V6;
13222 13228                  } else {
13223 13229                          ipha_t *ipha = (ipha_t *)mp->b_rptr;
13224 13230  
13225 13231                          ixas.ixa_multicast_ttl = ipha->ipha_ttl;
13226 13232                          ixas.ixa_flags = IXAF_BASIC_SIMPLE_V4;
13227 13233                          ixas.ixa_flags &= ~IXAF_SET_ULP_CKSUM;
13228 13234                  }
13229 13235                  ixas.ixa_flags &= ~IXAF_VERIFY_SOURCE;
13230 13236                  ixas.ixa_flags |= IXAF_MULTICAST_LOOP | IXAF_SET_SOURCE;
13231 13237                  (void) ip_output_simple(mp, &ixas);
13232 13238                  ixa_cleanup(&ixas);
13233 13239  
13234 13240                  mutex_enter(&ill->ill_lock);
13235 13241          }
13236 13242          mutex_exit(&ill->ill_lock);
13237 13243  
13238 13244  done:
13239 13245          if (release_ill != NULL)
13240 13246                  ill_refrele(release_ill);
13241 13247  }
13242 13248  
13243 13249  /*
13244 13250   * Take down a specific interface, but don't lose any information about it.
13245 13251   * (Always called as writer.)
13246 13252   * This function goes through the down sequence even if the interface is
13247 13253   * already down. There are 2 reasons.
13248 13254   * a. Currently we permit interface routes that depend on down interfaces
13249 13255   *    to be added. This behaviour itself is questionable. However it appears
13250 13256   *    that both Solaris and 4.3 BSD have exhibited this behaviour for a long
13251 13257   *    time. We go thru the cleanup in order to remove these routes.
13252 13258   * b. The bringup of the interface could fail in ill_dl_up i.e. we get
13253 13259   *    DL_ERROR_ACK in response to the DL_BIND request. The interface is
13254 13260   *    down, but we need to cleanup i.e. do ill_dl_down and
13255 13261   *    ip_rput_dlpi_writer (DL_ERROR_ACK) -> ipif_down.
13256 13262   *
13257 13263   * IP-MT notes:
13258 13264   *
13259 13265   * Model of reference to interfaces.
13260 13266   *
13261 13267   * The following members in ipif_t track references to the ipif.
13262 13268   *      int     ipif_refcnt;    Active reference count
13263 13269   *
13264 13270   * The following members in ill_t track references to the ill.
13265 13271   *      int             ill_refcnt;     active refcnt
13266 13272   *      uint_t          ill_ire_cnt;    Number of ires referencing ill
13267 13273   *      uint_t          ill_ncec_cnt;   Number of ncecs referencing ill
13268 13274   *      uint_t          ill_nce_cnt;    Number of nces referencing ill
13269 13275   *      uint_t          ill_ilm_cnt;    Number of ilms referencing ill
13270 13276   *
13271 13277   * Reference to an ipif or ill can be obtained in any of the following ways.
13272 13278   *
13273 13279   * Through the lookup functions ipif_lookup_* / ill_lookup_* functions
13274 13280   * Pointers to ipif / ill from other data structures viz ire and conn.
13275 13281   * Implicit reference to the ipif / ill by holding a reference to the ire.
13276 13282   *
13277 13283   * The ipif/ill lookup functions return a reference held ipif / ill.
13278 13284   * ipif_refcnt and ill_refcnt track the reference counts respectively.
13279 13285   * This is a purely dynamic reference count associated with threads holding
13280 13286   * references to the ipif / ill. Pointers from other structures do not
13281 13287   * count towards this reference count.
13282 13288   *
13283 13289   * ill_ire_cnt is the number of ire's associated with the
13284 13290   * ill. This is incremented whenever a new ire is created referencing the
13285 13291   * ill. This is done atomically inside ire_add_v[46] where the ire is
13286 13292   * actually added to the ire hash table. The count is decremented in
13287 13293   * ire_inactive where the ire is destroyed.
13288 13294   *
13289 13295   * ill_ncec_cnt is the number of ncec's referencing the ill thru ncec_ill.
13290 13296   * This is incremented atomically in
13291 13297   * ndp_add_v4()/ndp_add_v6() where the nce is actually added to the
13292 13298   * table. Similarly it is decremented in ncec_inactive() where the ncec
13293 13299   * is destroyed.
13294 13300   *
13295 13301   * ill_nce_cnt is the number of nce's referencing the ill thru nce_ill. This is
13296 13302   * incremented atomically in nce_add() where the nce is actually added to the
13297 13303   * ill_nce. Similarly it is decremented in nce_inactive() where the nce
13298 13304   * is destroyed.
13299 13305   *
13300 13306   * ill_ilm_cnt is the ilm's reference to the ill. It is incremented in
13301 13307   * ilm_add() and decremented before the ilm is freed in ilm_delete().
13302 13308   *
13303 13309   * Flow of ioctls involving interface down/up
13304 13310   *
13305 13311   * The following is the sequence of an attempt to set some critical flags on an
13306 13312   * up interface.
13307 13313   * ip_sioctl_flags
13308 13314   * ipif_down
13309 13315   * wait for ipif to be quiescent
13310 13316   * ipif_down_tail
13311 13317   * ip_sioctl_flags_tail
13312 13318   *
13313 13319   * All set ioctls that involve down/up sequence would have a skeleton similar
13314 13320   * to the above. All the *tail functions are called after the refcounts have
13315 13321   * dropped to the appropriate values.
13316 13322   *
13317 13323   * SIOC ioctls during the IPIF_CHANGING interval.
13318 13324   *
13319 13325   * Threads handling SIOC set ioctls serialize on the squeue, but this
13320 13326   * is not done for SIOC get ioctls. Since a set ioctl can cause several
13321 13327   * steps of internal changes to the state, some of which are visible in
13322 13328   * ipif_flags (such as IFF_UP being cleared and later set), and we want
13323 13329   * the set ioctl to be atomic related to the get ioctls, the SIOC get code
13324 13330   * will wait and restart ioctls if IPIF_CHANGING is set. The mblk is then
13325 13331   * enqueued in the ipsq and the operation is restarted by ipsq_exit() when
13326 13332   * the current exclusive operation completes. The IPIF_CHANGING check
13327 13333   * and enqueue is atomic using the ill_lock and ipsq_lock. The
13328 13334   * lookup is done holding the ill_lock. Hence the ill/ipif state flags can't
13329 13335   * change while the ill_lock is held. Before dropping the ill_lock we acquire
13330 13336   * the ipsq_lock and call ipsq_enq. This ensures that ipsq_exit can't finish
13331 13337   * until we release the ipsq_lock, even though the ill/ipif state flags
13332 13338   * can change after we drop the ill_lock.
13333 13339   */
13334 13340  int
13335 13341  ipif_down(ipif_t *ipif, queue_t *q, mblk_t *mp)
13336 13342  {
13337 13343          ill_t           *ill = ipif->ipif_ill;
13338 13344          conn_t          *connp;
13339 13345          boolean_t       success;
13340 13346          boolean_t       ipif_was_up = B_FALSE;
13341 13347          ip_stack_t      *ipst = ill->ill_ipst;
13342 13348  
13343 13349          ASSERT(IAM_WRITER_IPIF(ipif));
13344 13350  
13345 13351          ip1dbg(("ipif_down(%s:%u)\n", ill->ill_name, ipif->ipif_id));
13346 13352  
13347 13353          DTRACE_PROBE3(ipif__downup, char *, "ipif_down",
13348 13354              ill_t *, ill, ipif_t *, ipif);
13349 13355  
13350 13356          if (ipif->ipif_flags & IPIF_UP) {
13351 13357                  mutex_enter(&ill->ill_lock);
13352 13358                  ipif->ipif_flags &= ~IPIF_UP;
13353 13359                  ASSERT(ill->ill_ipif_up_count > 0);
13354 13360                  --ill->ill_ipif_up_count;
13355 13361                  mutex_exit(&ill->ill_lock);
13356 13362                  ipif_was_up = B_TRUE;
13357 13363                  /* Update status in SCTP's list */
13358 13364                  sctp_update_ipif(ipif, SCTP_IPIF_DOWN);
13359 13365                  ill_nic_event_dispatch(ipif->ipif_ill,
13360 13366                      MAP_IPIF_ID(ipif->ipif_id), NE_LIF_DOWN, NULL, 0);
13361 13367          }
13362 13368  
13363 13369          /*
13364 13370           * Removal of the last ipif from an ill may result in a DL_UNBIND
13365 13371           * being sent to the driver, and we must not send any data packets to
13366 13372           * the driver after the DL_UNBIND_REQ. To ensure this, all the
13367 13373           * ire and nce entries used in the data path will be cleaned
13368 13374           * up, and we also set  the ILL_DOWN_IN_PROGRESS bit to make
13369 13375           * sure on new entries will be added until the ill is bound
13370 13376           * again. The ILL_DOWN_IN_PROGRESS bit is turned off upon
13371 13377           * receipt of a DL_BIND_ACK.
13372 13378           */
13373 13379          if (ill->ill_wq != NULL && !ill->ill_logical_down &&
13374 13380              ill->ill_ipif_up_count == 0 && ill->ill_ipif_dup_count == 0 &&
13375 13381              ill->ill_dl_up) {
13376 13382                  ill->ill_state_flags |= ILL_DOWN_IN_PROGRESS;
13377 13383          }
13378 13384  
13379 13385          /*
13380 13386           * Blow away memberships we established in ipif_multicast_up().
13381 13387           */
13382 13388          ipif_multicast_down(ipif);
13383 13389  
13384 13390          /*
13385 13391           * Remove from the mapping for __sin6_src_id. We insert only
13386 13392           * when the address is not INADDR_ANY. As IPv4 addresses are
13387 13393           * stored as mapped addresses, we need to check for mapped
13388 13394           * INADDR_ANY also.
13389 13395           */
13390 13396          if (ipif_was_up && !IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr) &&
13391 13397              !IN6_IS_ADDR_V4MAPPED_ANY(&ipif->ipif_v6lcl_addr) &&
13392 13398              !(ipif->ipif_flags & IPIF_NOLOCAL)) {
13393 13399                  int err;
13394 13400  
13395 13401                  err = ip_srcid_remove(&ipif->ipif_v6lcl_addr,
13396 13402                      ipif->ipif_zoneid, ipst);
13397 13403                  if (err != 0) {
13398 13404                          ip0dbg(("ipif_down: srcid_remove %d\n", err));
13399 13405                  }
13400 13406          }
13401 13407  
13402 13408          if (ipif_was_up) {
13403 13409                  /* only delete if we'd added ire's before */
13404 13410                  if (ipif->ipif_isv6)
13405 13411                          ipif_delete_ires_v6(ipif);
13406 13412                  else
13407 13413                          ipif_delete_ires_v4(ipif);
13408 13414          }
13409 13415  
13410 13416          if (ipif_was_up && ill->ill_ipif_up_count == 0) {
13411 13417                  /*
13412 13418                   * Since the interface is now down, it may have just become
13413 13419                   * inactive.  Note that this needs to be done even for a
13414 13420                   * lll_logical_down(), or ARP entries will not get correctly
13415 13421                   * restored when the interface comes back up.
13416 13422                   */
13417 13423                  if (IS_UNDER_IPMP(ill))
13418 13424                          ipmp_ill_refresh_active(ill);
13419 13425          }
13420 13426  
13421 13427          /*
13422 13428           * neighbor-discovery or arp entries for this interface. The ipif
13423 13429           * has to be quiesced, so we walk all the nce's and delete those
13424 13430           * that point at the ipif->ipif_ill. At the same time, we also
13425 13431           * update IPMP so that ipifs for data addresses are unbound. We dont
13426 13432           * call ipif_arp_down to DL_UNBIND the arp stream itself here, but defer
13427 13433           * that for ipif_down_tail()
13428 13434           */
13429 13435          ipif_nce_down(ipif);
13430 13436  
13431 13437          /*
13432 13438           * If this is the last ipif on the ill, we also need to remove
13433 13439           * any IREs with ire_ill set. Otherwise ipif_is_quiescent() will
13434 13440           * never succeed.
13435 13441           */
13436 13442          if (ill->ill_ipif_up_count == 0 && ill->ill_ipif_dup_count == 0)
13437 13443                  ire_walk_ill(0, 0, ill_downi, ill, ill);
13438 13444  
13439 13445          /*
13440 13446           * Walk all CONNs that can have a reference on an ire for this
13441 13447           * ipif (we actually walk all that now have stale references).
13442 13448           */
13443 13449          ipcl_walk(conn_ixa_cleanup, (void *)B_TRUE, ipst);
13444 13450  
13445 13451          /*
13446 13452           * If mp is NULL the caller will wait for the appropriate refcnt.
13447 13453           * Eg. ip_sioctl_removeif -> ipif_free  -> ipif_down
13448 13454           * and ill_delete -> ipif_free -> ipif_down
13449 13455           */
13450 13456          if (mp == NULL) {
13451 13457                  ASSERT(q == NULL);
13452 13458                  return (0);
13453 13459          }
13454 13460  
13455 13461          if (CONN_Q(q)) {
13456 13462                  connp = Q_TO_CONN(q);
13457 13463                  mutex_enter(&connp->conn_lock);
13458 13464          } else {
13459 13465                  connp = NULL;
13460 13466          }
13461 13467          mutex_enter(&ill->ill_lock);
13462 13468          /*
13463 13469           * Are there any ire's pointing to this ipif that are still active ?
13464 13470           * If this is the last ipif going down, are there any ire's pointing
13465 13471           * to this ill that are still active ?
13466 13472           */
13467 13473          if (ipif_is_quiescent(ipif)) {
13468 13474                  mutex_exit(&ill->ill_lock);
13469 13475                  if (connp != NULL)
13470 13476                          mutex_exit(&connp->conn_lock);
13471 13477                  return (0);
13472 13478          }
13473 13479  
13474 13480          ip1dbg(("ipif_down: need to wait, adding pending mp %s ill %p",
13475 13481              ill->ill_name, (void *)ill));
13476 13482          /*
13477 13483           * Enqueue the mp atomically in ipsq_pending_mp. When the refcount
13478 13484           * drops down, the operation will be restarted by ipif_ill_refrele_tail
13479 13485           * which in turn is called by the last refrele on the ipif/ill/ire.
13480 13486           */
13481 13487          success = ipsq_pending_mp_add(connp, ipif, q, mp, IPIF_DOWN);
13482 13488          if (!success) {
13483 13489                  /* The conn is closing. So just return */
13484 13490                  ASSERT(connp != NULL);
13485 13491                  mutex_exit(&ill->ill_lock);
13486 13492                  mutex_exit(&connp->conn_lock);
13487 13493                  return (EINTR);
13488 13494          }
13489 13495  
13490 13496          mutex_exit(&ill->ill_lock);
13491 13497          if (connp != NULL)
13492 13498                  mutex_exit(&connp->conn_lock);
13493 13499          return (EINPROGRESS);
13494 13500  }
13495 13501  
13496 13502  int
13497 13503  ipif_down_tail(ipif_t *ipif)
13498 13504  {
13499 13505          ill_t   *ill = ipif->ipif_ill;
13500 13506          int     err = 0;
13501 13507  
13502 13508          DTRACE_PROBE3(ipif__downup, char *, "ipif_down_tail",
13503 13509              ill_t *, ill, ipif_t *, ipif);
13504 13510  
13505 13511          /*
13506 13512           * Skip any loopback interface (null wq).
13507 13513           * If this is the last logical interface on the ill
13508 13514           * have ill_dl_down tell the driver we are gone (unbind)
13509 13515           * Note that lun 0 can ipif_down even though
13510 13516           * there are other logical units that are up.
13511 13517           * This occurs e.g. when we change a "significant" IFF_ flag.
13512 13518           */
13513 13519          if (ill->ill_wq != NULL && !ill->ill_logical_down &&
13514 13520              ill->ill_ipif_up_count == 0 && ill->ill_ipif_dup_count == 0 &&
13515 13521              ill->ill_dl_up) {
13516 13522                  ill_dl_down(ill);
13517 13523          }
13518 13524          if (!ipif->ipif_isv6)
13519 13525                  err = ipif_arp_down(ipif);
13520 13526  
13521 13527          ill->ill_logical_down = 0;
13522 13528  
13523 13529          ip_rts_ifmsg(ipif, RTSQ_DEFAULT);
13524 13530          ip_rts_newaddrmsg(RTM_DELETE, 0, ipif, RTSQ_DEFAULT);
13525 13531          return (err);
13526 13532  }
13527 13533  
13528 13534  /*
13529 13535   * Bring interface logically down without bringing the physical interface
13530 13536   * down e.g. when the netmask is changed. This avoids long lasting link
13531 13537   * negotiations between an ethernet interface and a certain switches.
13532 13538   */
13533 13539  static int
13534 13540  ipif_logical_down(ipif_t *ipif, queue_t *q, mblk_t *mp)
13535 13541  {
13536 13542          DTRACE_PROBE3(ipif__downup, char *, "ipif_logical_down",
13537 13543              ill_t *, ipif->ipif_ill, ipif_t *, ipif);
13538 13544  
13539 13545          /*
13540 13546           * The ill_logical_down flag is a transient flag. It is set here
13541 13547           * and is cleared once the down has completed in ipif_down_tail.
13542 13548           * This flag does not indicate whether the ill stream is in the
13543 13549           * DL_BOUND state with the driver. Instead this flag is used by
13544 13550           * ipif_down_tail to determine whether to DL_UNBIND the stream with
13545 13551           * the driver. The state of the ill stream i.e. whether it is
13546 13552           * DL_BOUND with the driver or not is indicated by the ill_dl_up flag.
13547 13553           */
13548 13554          ipif->ipif_ill->ill_logical_down = 1;
13549 13555          return (ipif_down(ipif, q, mp));
13550 13556  }
13551 13557  
13552 13558  /*
13553 13559   * Initiate deallocate of an IPIF. Always called as writer. Called by
13554 13560   * ill_delete or ip_sioctl_removeif.
13555 13561   */
13556 13562  static void
13557 13563  ipif_free(ipif_t *ipif)
13558 13564  {
13559 13565          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
13560 13566  
13561 13567          ASSERT(IAM_WRITER_IPIF(ipif));
13562 13568  
13563 13569          if (ipif->ipif_recovery_id != 0)
13564 13570                  (void) untimeout(ipif->ipif_recovery_id);
13565 13571          ipif->ipif_recovery_id = 0;
13566 13572  
13567 13573          /*
13568 13574           * Take down the interface. We can be called either from ill_delete
13569 13575           * or from ip_sioctl_removeif.
13570 13576           */
13571 13577          (void) ipif_down(ipif, NULL, NULL);
13572 13578  
13573 13579          /*
13574 13580           * Now that the interface is down, there's no chance it can still
13575 13581           * become a duplicate.  Cancel any timer that may have been set while
13576 13582           * tearing down.
13577 13583           */
13578 13584          if (ipif->ipif_recovery_id != 0)
13579 13585                  (void) untimeout(ipif->ipif_recovery_id);
13580 13586          ipif->ipif_recovery_id = 0;
13581 13587  
13582 13588          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
13583 13589          /* Remove pointers to this ill in the multicast routing tables */
13584 13590          reset_mrt_vif_ipif(ipif);
13585 13591          /* If necessary, clear the cached source ipif rotor. */
13586 13592          if (ipif->ipif_ill->ill_src_ipif == ipif)
13587 13593                  ipif->ipif_ill->ill_src_ipif = NULL;
13588 13594          rw_exit(&ipst->ips_ill_g_lock);
13589 13595  }
13590 13596  
13591 13597  static void
13592 13598  ipif_free_tail(ipif_t *ipif)
13593 13599  {
13594 13600          ip_stack_t *ipst = ipif->ipif_ill->ill_ipst;
13595 13601  
13596 13602          /*
13597 13603           * Need to hold both ill_g_lock and ill_lock while
13598 13604           * inserting or removing an ipif from the linked list
13599 13605           * of ipifs hanging off the ill.
13600 13606           */
13601 13607          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
13602 13608  
13603 13609  #ifdef DEBUG
13604 13610          ipif_trace_cleanup(ipif);
13605 13611  #endif
13606 13612  
13607 13613          /* Ask SCTP to take it out of it list */
13608 13614          sctp_update_ipif(ipif, SCTP_IPIF_REMOVE);
13609 13615          ip_rts_newaddrmsg(RTM_FREEADDR, 0, ipif, RTSQ_DEFAULT);
13610 13616  
13611 13617          /* Get it out of the ILL interface list. */
13612 13618          ipif_remove(ipif);
13613 13619          rw_exit(&ipst->ips_ill_g_lock);
13614 13620  
13615 13621          ASSERT(!(ipif->ipif_flags & (IPIF_UP | IPIF_DUPLICATE)));
13616 13622          ASSERT(ipif->ipif_recovery_id == 0);
13617 13623          ASSERT(ipif->ipif_ire_local == NULL);
13618 13624          ASSERT(ipif->ipif_ire_if == NULL);
13619 13625  
13620 13626          /* Free the memory. */
13621 13627          mi_free(ipif);
13622 13628  }
13623 13629  
13624 13630  /*
13625 13631   * Sets `buf' to an ipif name of the form "ill_name:id", or "ill_name" if "id"
13626 13632   * is zero.
13627 13633   */
13628 13634  void
13629 13635  ipif_get_name(const ipif_t *ipif, char *buf, int len)
13630 13636  {
13631 13637          char    lbuf[LIFNAMSIZ];
13632 13638          char    *name;
13633 13639          size_t  name_len;
13634 13640  
13635 13641          buf[0] = '\0';
13636 13642          name = ipif->ipif_ill->ill_name;
13637 13643          name_len = ipif->ipif_ill->ill_name_length;
13638 13644          if (ipif->ipif_id != 0) {
13639 13645                  (void) sprintf(lbuf, "%s%c%d", name, IPIF_SEPARATOR_CHAR,
13640 13646                      ipif->ipif_id);
13641 13647                  name = lbuf;
13642 13648                  name_len = mi_strlen(name) + 1;
13643 13649          }
13644 13650          len -= 1;
13645 13651          buf[len] = '\0';
13646 13652          len = MIN(len, name_len);
13647 13653          bcopy(name, buf, len);
13648 13654  }
13649 13655  
13650 13656  /*
13651 13657   * Sets `buf' to an ill name.
13652 13658   */
13653 13659  void
13654 13660  ill_get_name(const ill_t *ill, char *buf, int len)
13655 13661  {
13656 13662          char    *name;
13657 13663          size_t  name_len;
13658 13664  
13659 13665          name = ill->ill_name;
13660 13666          name_len = ill->ill_name_length;
13661 13667          len -= 1;
13662 13668          buf[len] = '\0';
13663 13669          len = MIN(len, name_len);
13664 13670          bcopy(name, buf, len);
13665 13671  }
13666 13672  
13667 13673  /*
13668 13674   * Find an IPIF based on the name passed in.  Names can be of the form <phys>
13669 13675   * (e.g., le0) or <phys>:<#> (e.g., le0:1).  When there is no colon, the
13670 13676   * implied unit id is zero. <phys> must correspond to the name of an ILL.
13671 13677   * (May be called as writer.)
13672 13678   */
13673 13679  static ipif_t *
13674 13680  ipif_lookup_on_name(char *name, size_t namelen, boolean_t do_alloc,
13675 13681      boolean_t *exists, boolean_t isv6, zoneid_t zoneid, ip_stack_t *ipst)
13676 13682  {
13677 13683          char    *cp;
13678 13684          char    *endp;
13679 13685          long    id;
13680 13686          ill_t   *ill;
13681 13687          ipif_t  *ipif;
13682 13688          uint_t  ire_type;
13683 13689          boolean_t did_alloc = B_FALSE;
13684 13690          char    last;
13685 13691  
13686 13692          /*
13687 13693           * If the caller wants to us to create the ipif, make sure we have a
13688 13694           * valid zoneid
13689 13695           */
13690 13696          ASSERT(!do_alloc || zoneid != ALL_ZONES);
13691 13697  
13692 13698          if (namelen == 0) {
13693 13699                  return (NULL);
13694 13700          }
13695 13701  
13696 13702          *exists = B_FALSE;
13697 13703          /* Look for a colon in the name. */
13698 13704          endp = &name[namelen];
13699 13705          for (cp = endp; --cp > name; ) {
13700 13706                  if (*cp == IPIF_SEPARATOR_CHAR)
13701 13707                          break;
13702 13708          }
13703 13709  
13704 13710          if (*cp == IPIF_SEPARATOR_CHAR) {
13705 13711                  /*
13706 13712                   * Reject any non-decimal aliases for logical
13707 13713                   * interfaces. Aliases with leading zeroes
13708 13714                   * are also rejected as they introduce ambiguity
13709 13715                   * in the naming of the interfaces.
13710 13716                   * In order to confirm with existing semantics,
13711 13717                   * and to not break any programs/script relying
13712 13718                   * on that behaviour, if<0>:0 is considered to be
13713 13719                   * a valid interface.
13714 13720                   *
13715 13721                   * If alias has two or more digits and the first
13716 13722                   * is zero, fail.
13717 13723                   */
13718 13724                  if (&cp[2] < endp && cp[1] == '0') {
13719 13725                          return (NULL);
13720 13726                  }
13721 13727          }
13722 13728  
13723 13729          if (cp <= name) {
13724 13730                  cp = endp;
13725 13731          }
13726 13732          last = *cp;
13727 13733          *cp = '\0';
13728 13734  
13729 13735          /*
13730 13736           * Look up the ILL, based on the portion of the name
13731 13737           * before the slash. ill_lookup_on_name returns a held ill.
13732 13738           * Temporary to check whether ill exists already. If so
13733 13739           * ill_lookup_on_name will clear it.
13734 13740           */
13735 13741          ill = ill_lookup_on_name(name, do_alloc, isv6,
13736 13742              &did_alloc, ipst);
13737 13743          *cp = last;
13738 13744          if (ill == NULL)
13739 13745                  return (NULL);
13740 13746  
13741 13747          /* Establish the unit number in the name. */
13742 13748          id = 0;
13743 13749          if (cp < endp && *endp == '\0') {
13744 13750                  /* If there was a colon, the unit number follows. */
13745 13751                  cp++;
13746 13752                  if (ddi_strtol(cp, NULL, 0, &id) != 0) {
13747 13753                          ill_refrele(ill);
13748 13754                          return (NULL);
13749 13755                  }
13750 13756          }
13751 13757  
13752 13758          mutex_enter(&ill->ill_lock);
13753 13759          /* Now see if there is an IPIF with this unit number. */
13754 13760          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
13755 13761                  if (ipif->ipif_id == id) {
13756 13762                          if (zoneid != ALL_ZONES &&
13757 13763                              zoneid != ipif->ipif_zoneid &&
13758 13764                              ipif->ipif_zoneid != ALL_ZONES) {
13759 13765                                  mutex_exit(&ill->ill_lock);
13760 13766                                  ill_refrele(ill);
13761 13767                                  return (NULL);
13762 13768                          }
13763 13769                          if (IPIF_CAN_LOOKUP(ipif)) {
13764 13770                                  ipif_refhold_locked(ipif);
13765 13771                                  mutex_exit(&ill->ill_lock);
13766 13772                                  if (!did_alloc)
13767 13773                                          *exists = B_TRUE;
13768 13774                                  /*
13769 13775                                   * Drop locks before calling ill_refrele
13770 13776                                   * since it can potentially call into
13771 13777                                   * ipif_ill_refrele_tail which can end up
13772 13778                                   * in trying to acquire any lock.
13773 13779                                   */
13774 13780                                  ill_refrele(ill);
13775 13781                                  return (ipif);
13776 13782                          }
13777 13783                  }
13778 13784          }
13779 13785  
13780 13786          if (!do_alloc) {
13781 13787                  mutex_exit(&ill->ill_lock);
13782 13788                  ill_refrele(ill);
13783 13789                  return (NULL);
13784 13790          }
13785 13791  
13786 13792          /*
13787 13793           * If none found, atomically allocate and return a new one.
13788 13794           * Historically, we used IRE_LOOPBACK only for lun 0, and IRE_LOCAL
13789 13795           * to support "receive only" use of lo0:1 etc. as is still done
13790 13796           * below as an initial guess.
13791 13797           * However, this is now likely to be overriden later in ipif_up_done()
13792 13798           * when we know for sure what address has been configured on the
13793 13799           * interface, since we might have more than one loopback interface
13794 13800           * with a loopback address, e.g. in the case of zones, and all the
13795 13801           * interfaces with loopback addresses need to be marked IRE_LOOPBACK.
13796 13802           */
13797 13803          if (ill->ill_net_type == IRE_LOOPBACK && id == 0)
13798 13804                  ire_type = IRE_LOOPBACK;
13799 13805          else
13800 13806                  ire_type = IRE_LOCAL;
13801 13807          ipif = ipif_allocate(ill, id, ire_type, B_TRUE, B_TRUE, NULL);
13802 13808          if (ipif != NULL)
13803 13809                  ipif_refhold_locked(ipif);
13804 13810          mutex_exit(&ill->ill_lock);
13805 13811          ill_refrele(ill);
13806 13812          return (ipif);
13807 13813  }
13808 13814  
13809 13815  /*
13810 13816   * Variant of the above that queues the request on the ipsq when
13811 13817   * IPIF_CHANGING is set.
13812 13818   */
13813 13819  static ipif_t *
13814 13820  ipif_lookup_on_name_async(char *name, size_t namelen, boolean_t isv6,
13815 13821      zoneid_t zoneid, queue_t *q, mblk_t *mp, ipsq_func_t func, int *error,
13816 13822      ip_stack_t *ipst)
13817 13823  {
13818 13824          char    *cp;
13819 13825          char    *endp;
13820 13826          long    id;
13821 13827          ill_t   *ill;
13822 13828          ipif_t  *ipif;
13823 13829          boolean_t did_alloc = B_FALSE;
13824 13830          ipsq_t  *ipsq;
13825 13831  
13826 13832          if (error != NULL)
13827 13833                  *error = 0;
13828 13834  
13829 13835          if (namelen == 0) {
13830 13836                  if (error != NULL)
13831 13837                          *error = ENXIO;
13832 13838                  return (NULL);
13833 13839          }
13834 13840  
13835 13841          /* Look for a colon in the name. */
13836 13842          endp = &name[namelen];
13837 13843          for (cp = endp; --cp > name; ) {
13838 13844                  if (*cp == IPIF_SEPARATOR_CHAR)
13839 13845                          break;
13840 13846          }
13841 13847  
13842 13848          if (*cp == IPIF_SEPARATOR_CHAR) {
13843 13849                  /*
13844 13850                   * Reject any non-decimal aliases for logical
13845 13851                   * interfaces. Aliases with leading zeroes
13846 13852                   * are also rejected as they introduce ambiguity
13847 13853                   * in the naming of the interfaces.
13848 13854                   * In order to confirm with existing semantics,
13849 13855                   * and to not break any programs/script relying
13850 13856                   * on that behaviour, if<0>:0 is considered to be
13851 13857                   * a valid interface.
13852 13858                   *
13853 13859                   * If alias has two or more digits and the first
13854 13860                   * is zero, fail.
13855 13861                   */
13856 13862                  if (&cp[2] < endp && cp[1] == '0') {
13857 13863                          if (error != NULL)
13858 13864                                  *error = EINVAL;
13859 13865                          return (NULL);
13860 13866                  }
13861 13867          }
13862 13868  
13863 13869          if (cp <= name) {
13864 13870                  cp = endp;
13865 13871          } else {
13866 13872                  *cp = '\0';
13867 13873          }
13868 13874  
13869 13875          /*
13870 13876           * Look up the ILL, based on the portion of the name
13871 13877           * before the slash. ill_lookup_on_name returns a held ill.
13872 13878           * Temporary to check whether ill exists already. If so
13873 13879           * ill_lookup_on_name will clear it.
13874 13880           */
13875 13881          ill = ill_lookup_on_name(name, B_FALSE, isv6, &did_alloc, ipst);
13876 13882          if (cp != endp)
13877 13883                  *cp = IPIF_SEPARATOR_CHAR;
13878 13884          if (ill == NULL)
13879 13885                  return (NULL);
13880 13886  
13881 13887          /* Establish the unit number in the name. */
13882 13888          id = 0;
13883 13889          if (cp < endp && *endp == '\0') {
13884 13890                  /* If there was a colon, the unit number follows. */
13885 13891                  cp++;
13886 13892                  if (ddi_strtol(cp, NULL, 0, &id) != 0) {
13887 13893                          ill_refrele(ill);
13888 13894                          if (error != NULL)
13889 13895                                  *error = ENXIO;
13890 13896                          return (NULL);
13891 13897                  }
13892 13898          }
13893 13899  
13894 13900          GRAB_CONN_LOCK(q);
13895 13901          mutex_enter(&ill->ill_lock);
13896 13902          /* Now see if there is an IPIF with this unit number. */
13897 13903          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
13898 13904                  if (ipif->ipif_id == id) {
13899 13905                          if (zoneid != ALL_ZONES &&
13900 13906                              zoneid != ipif->ipif_zoneid &&
13901 13907                              ipif->ipif_zoneid != ALL_ZONES) {
13902 13908                                  mutex_exit(&ill->ill_lock);
13903 13909                                  RELEASE_CONN_LOCK(q);
13904 13910                                  ill_refrele(ill);
13905 13911                                  if (error != NULL)
13906 13912                                          *error = ENXIO;
13907 13913                                  return (NULL);
13908 13914                          }
13909 13915  
13910 13916                          if (!(IPIF_IS_CHANGING(ipif) ||
13911 13917                              IPIF_IS_CONDEMNED(ipif)) ||
13912 13918                              IAM_WRITER_IPIF(ipif)) {
13913 13919                                  ipif_refhold_locked(ipif);
13914 13920                                  mutex_exit(&ill->ill_lock);
13915 13921                                  /*
13916 13922                                   * Drop locks before calling ill_refrele
13917 13923                                   * since it can potentially call into
13918 13924                                   * ipif_ill_refrele_tail which can end up
13919 13925                                   * in trying to acquire any lock.
13920 13926                                   */
13921 13927                                  RELEASE_CONN_LOCK(q);
13922 13928                                  ill_refrele(ill);
13923 13929                                  return (ipif);
13924 13930                          } else if (q != NULL && !IPIF_IS_CONDEMNED(ipif)) {
13925 13931                                  ipsq = ill->ill_phyint->phyint_ipsq;
13926 13932                                  mutex_enter(&ipsq->ipsq_lock);
13927 13933                                  mutex_enter(&ipsq->ipsq_xop->ipx_lock);
13928 13934                                  mutex_exit(&ill->ill_lock);
13929 13935                                  ipsq_enq(ipsq, q, mp, func, NEW_OP, ill);
13930 13936                                  mutex_exit(&ipsq->ipsq_xop->ipx_lock);
13931 13937                                  mutex_exit(&ipsq->ipsq_lock);
13932 13938                                  RELEASE_CONN_LOCK(q);
13933 13939                                  ill_refrele(ill);
13934 13940                                  if (error != NULL)
13935 13941                                          *error = EINPROGRESS;
13936 13942                                  return (NULL);
13937 13943                          }
13938 13944                  }
13939 13945          }
13940 13946          RELEASE_CONN_LOCK(q);
13941 13947          mutex_exit(&ill->ill_lock);
13942 13948          ill_refrele(ill);
13943 13949          if (error != NULL)
13944 13950                  *error = ENXIO;
13945 13951          return (NULL);
13946 13952  }
13947 13953  
13948 13954  /*
13949 13955   * This routine is called whenever a new address comes up on an ipif.  If
13950 13956   * we are configured to respond to address mask requests, then we are supposed
13951 13957   * to broadcast an address mask reply at this time.  This routine is also
13952 13958   * called if we are already up, but a netmask change is made.  This is legal
13953 13959   * but might not make the system manager very popular.  (May be called
13954 13960   * as writer.)
13955 13961   */
13956 13962  void
13957 13963  ipif_mask_reply(ipif_t *ipif)
13958 13964  {
13959 13965          icmph_t *icmph;
13960 13966          ipha_t  *ipha;
13961 13967          mblk_t  *mp;
13962 13968          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
13963 13969          ip_xmit_attr_t ixas;
13964 13970  
13965 13971  #define REPLY_LEN       (sizeof (icmp_ipha) + sizeof (icmph_t) + IP_ADDR_LEN)
13966 13972  
13967 13973          if (!ipst->ips_ip_respond_to_address_mask_broadcast)
13968 13974                  return;
13969 13975  
13970 13976          /* ICMP mask reply is IPv4 only */
13971 13977          ASSERT(!ipif->ipif_isv6);
13972 13978          /* ICMP mask reply is not for a loopback interface */
13973 13979          ASSERT(ipif->ipif_ill->ill_wq != NULL);
13974 13980  
13975 13981          if (ipif->ipif_lcl_addr == INADDR_ANY)
13976 13982                  return;
13977 13983  
13978 13984          mp = allocb(REPLY_LEN, BPRI_HI);
13979 13985          if (mp == NULL)
13980 13986                  return;
13981 13987          mp->b_wptr = mp->b_rptr + REPLY_LEN;
13982 13988  
13983 13989          ipha = (ipha_t *)mp->b_rptr;
13984 13990          bzero(ipha, REPLY_LEN);
13985 13991          *ipha = icmp_ipha;
13986 13992          ipha->ipha_ttl = ipst->ips_ip_broadcast_ttl;
13987 13993          ipha->ipha_src = ipif->ipif_lcl_addr;
13988 13994          ipha->ipha_dst = ipif->ipif_brd_addr;
13989 13995          ipha->ipha_length = htons(REPLY_LEN);
13990 13996          ipha->ipha_ident = 0;
13991 13997  
13992 13998          icmph = (icmph_t *)&ipha[1];
13993 13999          icmph->icmph_type = ICMP_ADDRESS_MASK_REPLY;
13994 14000          bcopy(&ipif->ipif_net_mask, &icmph[1], IP_ADDR_LEN);
13995 14001          icmph->icmph_checksum = IP_CSUM(mp, sizeof (ipha_t), 0);
13996 14002  
13997 14003          bzero(&ixas, sizeof (ixas));
13998 14004          ixas.ixa_flags = IXAF_BASIC_SIMPLE_V4;
13999 14005          ixas.ixa_zoneid = ALL_ZONES;
14000 14006          ixas.ixa_ifindex = 0;
14001 14007          ixas.ixa_ipst = ipst;
14002 14008          ixas.ixa_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
14003 14009          (void) ip_output_simple(mp, &ixas);
14004 14010          ixa_cleanup(&ixas);
14005 14011  #undef  REPLY_LEN
14006 14012  }
14007 14013  
14008 14014  /*
14009 14015   * Join the ipif specific multicast groups.
14010 14016   * Must be called after a mapping has been set up in the resolver.  (Always
14011 14017   * called as writer.)
14012 14018   */
14013 14019  void
14014 14020  ipif_multicast_up(ipif_t *ipif)
14015 14021  {
14016 14022          int err;
14017 14023          ill_t *ill;
14018 14024          ilm_t *ilm;
14019 14025  
14020 14026          ASSERT(IAM_WRITER_IPIF(ipif));
14021 14027  
14022 14028          ill = ipif->ipif_ill;
14023 14029  
14024 14030          ip1dbg(("ipif_multicast_up\n"));
14025 14031          if (!(ill->ill_flags & ILLF_MULTICAST) ||
14026 14032              ipif->ipif_allhosts_ilm != NULL)
14027 14033                  return;
14028 14034  
14029 14035          if (ipif->ipif_isv6) {
14030 14036                  in6_addr_t v6allmc = ipv6_all_hosts_mcast;
14031 14037                  in6_addr_t v6solmc = ipv6_solicited_node_mcast;
14032 14038  
14033 14039                  v6solmc.s6_addr32[3] |= ipif->ipif_v6lcl_addr.s6_addr32[3];
14034 14040  
14035 14041                  if (IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr))
14036 14042                          return;
14037 14043  
14038 14044                  ip1dbg(("ipif_multicast_up - addmulti\n"));
14039 14045  
14040 14046                  /*
14041 14047                   * Join the all hosts multicast address.  We skip this for
14042 14048                   * underlying IPMP interfaces since they should be invisible.
14043 14049                   */
14044 14050                  if (!IS_UNDER_IPMP(ill)) {
14045 14051                          ilm = ip_addmulti(&v6allmc, ill, ipif->ipif_zoneid,
14046 14052                              &err);
14047 14053                          if (ilm == NULL) {
14048 14054                                  ASSERT(err != 0);
14049 14055                                  ip0dbg(("ipif_multicast_up: "
14050 14056                                      "all_hosts_mcast failed %d\n", err));
14051 14057                                  return;
14052 14058                          }
14053 14059                          ipif->ipif_allhosts_ilm = ilm;
14054 14060                  }
14055 14061  
14056 14062                  /*
14057 14063                   * Enable multicast for the solicited node multicast address.
14058 14064                   * If IPMP we need to put the membership on the upper ill.
14059 14065                   */
14060 14066                  if (!(ipif->ipif_flags & IPIF_NOLOCAL)) {
14061 14067                          ill_t *mcast_ill = NULL;
14062 14068                          boolean_t need_refrele;
14063 14069  
14064 14070                          if (IS_UNDER_IPMP(ill) &&
14065 14071                              (mcast_ill = ipmp_ill_hold_ipmp_ill(ill)) != NULL) {
14066 14072                                  need_refrele = B_TRUE;
14067 14073                          } else {
14068 14074                                  mcast_ill = ill;
14069 14075                                  need_refrele = B_FALSE;
14070 14076                          }
14071 14077  
14072 14078                          ilm = ip_addmulti(&v6solmc, mcast_ill,
14073 14079                              ipif->ipif_zoneid, &err);
14074 14080                          if (need_refrele)
14075 14081                                  ill_refrele(mcast_ill);
14076 14082  
14077 14083                          if (ilm == NULL) {
14078 14084                                  ASSERT(err != 0);
14079 14085                                  ip0dbg(("ipif_multicast_up: solicited MC"
14080 14086                                      " failed %d\n", err));
14081 14087                                  if ((ilm = ipif->ipif_allhosts_ilm) != NULL) {
14082 14088                                          ipif->ipif_allhosts_ilm = NULL;
14083 14089                                          (void) ip_delmulti(ilm);
14084 14090                                  }
14085 14091                                  return;
14086 14092                          }
14087 14093                          ipif->ipif_solmulti_ilm = ilm;
14088 14094                  }
14089 14095          } else {
14090 14096                  in6_addr_t v6group;
14091 14097  
14092 14098                  if (ipif->ipif_lcl_addr == INADDR_ANY || IS_UNDER_IPMP(ill))
14093 14099                          return;
14094 14100  
14095 14101                  /* Join the all hosts multicast address */
14096 14102                  ip1dbg(("ipif_multicast_up - addmulti\n"));
14097 14103                  IN6_IPADDR_TO_V4MAPPED(htonl(INADDR_ALLHOSTS_GROUP), &v6group);
14098 14104  
14099 14105                  ilm = ip_addmulti(&v6group, ill, ipif->ipif_zoneid, &err);
14100 14106                  if (ilm == NULL) {
14101 14107                          ASSERT(err != 0);
14102 14108                          ip0dbg(("ipif_multicast_up: failed %d\n", err));
14103 14109                          return;
14104 14110                  }
14105 14111                  ipif->ipif_allhosts_ilm = ilm;
14106 14112          }
14107 14113  }
14108 14114  
14109 14115  /*
14110 14116   * Blow away any multicast groups that we joined in ipif_multicast_up().
14111 14117   * (ilms from explicit memberships are handled in conn_update_ill.)
14112 14118   */
14113 14119  void
14114 14120  ipif_multicast_down(ipif_t *ipif)
14115 14121  {
14116 14122          ASSERT(IAM_WRITER_IPIF(ipif));
14117 14123  
14118 14124          ip1dbg(("ipif_multicast_down\n"));
14119 14125  
14120 14126          if (ipif->ipif_allhosts_ilm != NULL) {
14121 14127                  (void) ip_delmulti(ipif->ipif_allhosts_ilm);
14122 14128                  ipif->ipif_allhosts_ilm = NULL;
14123 14129          }
14124 14130          if (ipif->ipif_solmulti_ilm != NULL) {
14125 14131                  (void) ip_delmulti(ipif->ipif_solmulti_ilm);
14126 14132                  ipif->ipif_solmulti_ilm = NULL;
14127 14133          }
14128 14134  }
14129 14135  
14130 14136  /*
14131 14137   * Used when an interface comes up to recreate any extra routes on this
14132 14138   * interface.
14133 14139   */
14134 14140  int
14135 14141  ill_recover_saved_ire(ill_t *ill)
14136 14142  {
14137 14143          mblk_t          *mp;
14138 14144          ip_stack_t      *ipst = ill->ill_ipst;
14139 14145  
14140 14146          ip1dbg(("ill_recover_saved_ire(%s)", ill->ill_name));
14141 14147  
14142 14148          mutex_enter(&ill->ill_saved_ire_lock);
14143 14149          for (mp = ill->ill_saved_ire_mp; mp != NULL; mp = mp->b_cont) {
14144 14150                  ire_t           *ire, *nire;
14145 14151                  ifrt_t          *ifrt;
14146 14152  
14147 14153                  ifrt = (ifrt_t *)mp->b_rptr;
14148 14154                  /*
14149 14155                   * Create a copy of the IRE with the saved address and netmask.
14150 14156                   */
14151 14157                  if (ill->ill_isv6) {
14152 14158                          ire = ire_create_v6(
14153 14159                              &ifrt->ifrt_v6addr,
14154 14160                              &ifrt->ifrt_v6mask,
14155 14161                              &ifrt->ifrt_v6gateway_addr,
14156 14162                              ifrt->ifrt_type,
14157 14163                              ill,
14158 14164                              ifrt->ifrt_zoneid,
14159 14165                              ifrt->ifrt_flags,
14160 14166                              NULL,
14161 14167                              ipst);
14162 14168                  } else {
14163 14169                          ire = ire_create(
14164 14170                              (uint8_t *)&ifrt->ifrt_addr,
14165 14171                              (uint8_t *)&ifrt->ifrt_mask,
14166 14172                              (uint8_t *)&ifrt->ifrt_gateway_addr,
14167 14173                              ifrt->ifrt_type,
14168 14174                              ill,
14169 14175                              ifrt->ifrt_zoneid,
14170 14176                              ifrt->ifrt_flags,
14171 14177                              NULL,
14172 14178                              ipst);
14173 14179                  }
14174 14180                  if (ire == NULL) {
14175 14181                          mutex_exit(&ill->ill_saved_ire_lock);
14176 14182                          return (ENOMEM);
14177 14183                  }
14178 14184  
14179 14185                  if (ifrt->ifrt_flags & RTF_SETSRC) {
14180 14186                          if (ill->ill_isv6) {
14181 14187                                  ire->ire_setsrc_addr_v6 =
14182 14188                                      ifrt->ifrt_v6setsrc_addr;
14183 14189                          } else {
14184 14190                                  ire->ire_setsrc_addr = ifrt->ifrt_setsrc_addr;
14185 14191                          }
14186 14192                  }
14187 14193  
14188 14194                  /*
14189 14195                   * Some software (for example, GateD and Sun Cluster) attempts
14190 14196                   * to create (what amount to) IRE_PREFIX routes with the
14191 14197                   * loopback address as the gateway.  This is primarily done to
14192 14198                   * set up prefixes with the RTF_REJECT flag set (for example,
14193 14199                   * when generating aggregate routes.)
14194 14200                   *
14195 14201                   * If the IRE type (as defined by ill->ill_net_type) is
14196 14202                   * IRE_LOOPBACK, then we map the request into a
14197 14203                   * IRE_IF_NORESOLVER.
14198 14204                   */
14199 14205                  if (ill->ill_net_type == IRE_LOOPBACK)
14200 14206                          ire->ire_type = IRE_IF_NORESOLVER;
14201 14207  
14202 14208                  /*
14203 14209                   * ire held by ire_add, will be refreled' towards the
14204 14210                   * the end of ipif_up_done
14205 14211                   */
14206 14212                  nire = ire_add(ire);
14207 14213                  /*
14208 14214                   * Check if it was a duplicate entry. This handles
14209 14215                   * the case of two racing route adds for the same route
14210 14216                   */
14211 14217                  if (nire == NULL) {
14212 14218                          ip1dbg(("ill_recover_saved_ire: FAILED\n"));
14213 14219                  } else if (nire != ire) {
14214 14220                          ip1dbg(("ill_recover_saved_ire: duplicate ire %p\n",
14215 14221                              (void *)nire));
14216 14222                          ire_delete(nire);
14217 14223                  } else {
14218 14224                          ip1dbg(("ill_recover_saved_ire: added ire %p\n",
14219 14225                              (void *)nire));
14220 14226                  }
14221 14227                  if (nire != NULL)
14222 14228                          ire_refrele(nire);
14223 14229          }
14224 14230          mutex_exit(&ill->ill_saved_ire_lock);
14225 14231          return (0);
14226 14232  }
14227 14233  
14228 14234  /*
14229 14235   * Used to set the netmask and broadcast address to default values when the
14230 14236   * interface is brought up.  (Always called as writer.)
14231 14237   */
14232 14238  static void
14233 14239  ipif_set_default(ipif_t *ipif)
14234 14240  {
14235 14241          ASSERT(MUTEX_HELD(&ipif->ipif_ill->ill_lock));
14236 14242  
14237 14243          if (!ipif->ipif_isv6) {
14238 14244                  /*
14239 14245                   * Interface holds an IPv4 address. Default
14240 14246                   * mask is the natural netmask.
14241 14247                   */
14242 14248                  if (!ipif->ipif_net_mask) {
14243 14249                          ipaddr_t        v4mask;
14244 14250  
14245 14251                          v4mask = ip_net_mask(ipif->ipif_lcl_addr);
14246 14252                          V4MASK_TO_V6(v4mask, ipif->ipif_v6net_mask);
14247 14253                  }
14248 14254                  if (ipif->ipif_flags & IPIF_POINTOPOINT) {
14249 14255                          /* ipif_subnet is ipif_pp_dst_addr for pt-pt */
14250 14256                          ipif->ipif_v6subnet = ipif->ipif_v6pp_dst_addr;
14251 14257                  } else {
14252 14258                          V6_MASK_COPY(ipif->ipif_v6lcl_addr,
14253 14259                              ipif->ipif_v6net_mask, ipif->ipif_v6subnet);
14254 14260                  }
14255 14261                  /*
14256 14262                   * NOTE: SunOS 4.X does this even if the broadcast address
14257 14263                   * has been already set thus we do the same here.
14258 14264                   */
14259 14265                  if (ipif->ipif_flags & IPIF_BROADCAST) {
14260 14266                          ipaddr_t        v4addr;
14261 14267  
14262 14268                          v4addr = ipif->ipif_subnet | ~ipif->ipif_net_mask;
14263 14269                          IN6_IPADDR_TO_V4MAPPED(v4addr, &ipif->ipif_v6brd_addr);
14264 14270                  }
14265 14271          } else {
14266 14272                  /*
14267 14273                   * Interface holds an IPv6-only address.  Default
14268 14274                   * mask is all-ones.
14269 14275                   */
14270 14276                  if (IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6net_mask))
14271 14277                          ipif->ipif_v6net_mask = ipv6_all_ones;
14272 14278                  if (ipif->ipif_flags & IPIF_POINTOPOINT) {
14273 14279                          /* ipif_subnet is ipif_pp_dst_addr for pt-pt */
14274 14280                          ipif->ipif_v6subnet = ipif->ipif_v6pp_dst_addr;
14275 14281                  } else {
14276 14282                          V6_MASK_COPY(ipif->ipif_v6lcl_addr,
14277 14283                              ipif->ipif_v6net_mask, ipif->ipif_v6subnet);
14278 14284                  }
14279 14285          }
14280 14286  }
14281 14287  
14282 14288  /*
14283 14289   * Return 0 if this address can be used as local address without causing
14284 14290   * duplicate address problems. Otherwise, return EADDRNOTAVAIL if the address
14285 14291   * is already up on a different ill, and EADDRINUSE if it's up on the same ill.
14286 14292   * Note that the same IPv6 link-local address is allowed as long as the ills
14287 14293   * are not on the same link.
14288 14294   */
14289 14295  int
14290 14296  ip_addr_availability_check(ipif_t *new_ipif)
14291 14297  {
14292 14298          in6_addr_t our_v6addr;
14293 14299          ill_t *ill;
14294 14300          ipif_t *ipif;
14295 14301          ill_walk_context_t ctx;
14296 14302          ip_stack_t      *ipst = new_ipif->ipif_ill->ill_ipst;
14297 14303  
14298 14304          ASSERT(IAM_WRITER_IPIF(new_ipif));
14299 14305          ASSERT(MUTEX_HELD(&ipst->ips_ip_addr_avail_lock));
14300 14306          ASSERT(RW_READ_HELD(&ipst->ips_ill_g_lock));
14301 14307  
14302 14308          new_ipif->ipif_flags &= ~IPIF_UNNUMBERED;
14303 14309          if (IN6_IS_ADDR_UNSPECIFIED(&new_ipif->ipif_v6lcl_addr) ||
14304 14310              IN6_IS_ADDR_V4MAPPED_ANY(&new_ipif->ipif_v6lcl_addr))
14305 14311                  return (0);
14306 14312  
14307 14313          our_v6addr = new_ipif->ipif_v6lcl_addr;
14308 14314  
14309 14315          if (new_ipif->ipif_isv6)
14310 14316                  ill = ILL_START_WALK_V6(&ctx, ipst);
14311 14317          else
14312 14318                  ill = ILL_START_WALK_V4(&ctx, ipst);
14313 14319  
14314 14320          for (; ill != NULL; ill = ill_next(&ctx, ill)) {
14315 14321                  for (ipif = ill->ill_ipif; ipif != NULL;
14316 14322                      ipif = ipif->ipif_next) {
14317 14323                          if ((ipif == new_ipif) ||
14318 14324                              !(ipif->ipif_flags & IPIF_UP) ||
14319 14325                              (ipif->ipif_flags & IPIF_UNNUMBERED) ||
14320 14326                              !IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6lcl_addr,
14321 14327                              &our_v6addr))
14322 14328                                  continue;
14323 14329  
14324 14330                          if (new_ipif->ipif_flags & IPIF_POINTOPOINT)
14325 14331                                  new_ipif->ipif_flags |= IPIF_UNNUMBERED;
14326 14332                          else if (ipif->ipif_flags & IPIF_POINTOPOINT)
14327 14333                                  ipif->ipif_flags |= IPIF_UNNUMBERED;
14328 14334                          else if ((IN6_IS_ADDR_LINKLOCAL(&our_v6addr) ||
14329 14335                              IN6_IS_ADDR_SITELOCAL(&our_v6addr)) &&
14330 14336                              !IS_ON_SAME_LAN(ill, new_ipif->ipif_ill))
14331 14337                                  continue;
14332 14338                          else if (new_ipif->ipif_zoneid != ipif->ipif_zoneid &&
14333 14339                              ipif->ipif_zoneid != ALL_ZONES && IS_LOOPBACK(ill))
14334 14340                                  continue;
14335 14341                          else if (new_ipif->ipif_ill == ill)
14336 14342                                  return (EADDRINUSE);
14337 14343                          else
14338 14344                                  return (EADDRNOTAVAIL);
14339 14345                  }
14340 14346          }
14341 14347  
14342 14348          return (0);
14343 14349  }
14344 14350  
14345 14351  /*
14346 14352   * Bring up an ipif: bring up arp/ndp, bring up the DLPI stream, and add
14347 14353   * IREs for the ipif.
14348 14354   * When the routine returns EINPROGRESS then mp has been consumed and
14349 14355   * the ioctl will be acked from ip_rput_dlpi.
14350 14356   */
14351 14357  int
14352 14358  ipif_up(ipif_t *ipif, queue_t *q, mblk_t *mp)
14353 14359  {
14354 14360          ill_t           *ill = ipif->ipif_ill;
14355 14361          boolean_t       isv6 = ipif->ipif_isv6;
14356 14362          int             err = 0;
14357 14363          boolean_t       success;
14358 14364          uint_t          ipif_orig_id;
14359 14365          ip_stack_t      *ipst = ill->ill_ipst;
14360 14366  
14361 14367          ASSERT(IAM_WRITER_IPIF(ipif));
14362 14368  
14363 14369          ip1dbg(("ipif_up(%s:%u)\n", ill->ill_name, ipif->ipif_id));
14364 14370          DTRACE_PROBE3(ipif__downup, char *, "ipif_up",
14365 14371              ill_t *, ill, ipif_t *, ipif);
14366 14372  
14367 14373          /* Shouldn't get here if it is already up. */
14368 14374          if (ipif->ipif_flags & IPIF_UP)
14369 14375                  return (EALREADY);
14370 14376  
14371 14377          /*
14372 14378           * If this is a request to bring up a data address on an interface
14373 14379           * under IPMP, then move the address to its IPMP meta-interface and
14374 14380           * try to bring it up.  One complication is that the zeroth ipif for
14375 14381           * an ill is special, in that every ill always has one, and that code
14376 14382           * throughout IP deferences ill->ill_ipif without holding any locks.
14377 14383           */
14378 14384          if (IS_UNDER_IPMP(ill) && ipmp_ipif_is_dataaddr(ipif) &&
14379 14385              (!ipif->ipif_isv6 || !V6_IPIF_LINKLOCAL(ipif))) {
14380 14386                  ipif_t  *stubipif = NULL, *moveipif = NULL;
14381 14387                  ill_t   *ipmp_ill = ipmp_illgrp_ipmp_ill(ill->ill_grp);
14382 14388  
14383 14389                  /*
14384 14390                   * The ipif being brought up should be quiesced.  If it's not,
14385 14391                   * something has gone amiss and we need to bail out.  (If it's
14386 14392                   * quiesced, we know it will remain so via IPIF_CONDEMNED.)
14387 14393                   */
14388 14394                  mutex_enter(&ill->ill_lock);
14389 14395                  if (!ipif_is_quiescent(ipif)) {
14390 14396                          mutex_exit(&ill->ill_lock);
14391 14397                          return (EINVAL);
14392 14398                  }
14393 14399                  mutex_exit(&ill->ill_lock);
14394 14400  
14395 14401                  /*
14396 14402                   * If we're going to need to allocate ipifs, do it prior
14397 14403                   * to starting the move (and grabbing locks).
14398 14404                   */
14399 14405                  if (ipif->ipif_id == 0) {
14400 14406                          if ((moveipif = ipif_allocate(ill, 0, IRE_LOCAL, B_TRUE,
14401 14407                              B_FALSE, &err)) == NULL) {
14402 14408                                  return (err);
14403 14409                          }
14404 14410                          if ((stubipif = ipif_allocate(ill, 0, IRE_LOCAL, B_TRUE,
14405 14411                              B_FALSE, &err)) == NULL) {
14406 14412                                  mi_free(moveipif);
14407 14413                                  return (err);
14408 14414                          }
14409 14415                  }
14410 14416  
14411 14417                  /*
14412 14418                   * Grab or transfer the ipif to move.  During the move, keep
14413 14419                   * ill_g_lock held to prevent any ill walker threads from
14414 14420                   * seeing things in an inconsistent state.
14415 14421                   */
14416 14422                  rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
14417 14423                  if (ipif->ipif_id != 0) {
14418 14424                          ipif_remove(ipif);
14419 14425                  } else {
14420 14426                          ipif_transfer(ipif, moveipif, stubipif);
14421 14427                          ipif = moveipif;
14422 14428                  }
14423 14429  
14424 14430                  /*
14425 14431                   * Place the ipif on the IPMP ill.  If the zeroth ipif on
14426 14432                   * the IPMP ill is a stub (0.0.0.0 down address) then we
14427 14433                   * replace that one.  Otherwise, pick the next available slot.
14428 14434                   */
14429 14435                  ipif->ipif_ill = ipmp_ill;
14430 14436                  ipif_orig_id = ipif->ipif_id;
14431 14437  
14432 14438                  if (ipmp_ipif_is_stubaddr(ipmp_ill->ill_ipif)) {
14433 14439                          ipif_transfer(ipif, ipmp_ill->ill_ipif, NULL);
14434 14440                          ipif = ipmp_ill->ill_ipif;
14435 14441                  } else {
14436 14442                          ipif->ipif_id = -1;
14437 14443                          if ((err = ipif_insert(ipif, B_FALSE)) != 0) {
14438 14444                                  /*
14439 14445                                   * No more available ipif_id's -- put it back
14440 14446                                   * on the original ill and fail the operation.
14441 14447                                   * Since we're writer on the ill, we can be
14442 14448                                   * sure our old slot is still available.
14443 14449                                   */
14444 14450                                  ipif->ipif_id = ipif_orig_id;
14445 14451                                  ipif->ipif_ill = ill;
14446 14452                                  if (ipif_orig_id == 0) {
14447 14453                                          ipif_transfer(ipif, ill->ill_ipif,
14448 14454                                              NULL);
14449 14455                                  } else {
14450 14456                                          VERIFY(ipif_insert(ipif, B_FALSE) == 0);
14451 14457                                  }
14452 14458                                  rw_exit(&ipst->ips_ill_g_lock);
14453 14459                                  return (err);
14454 14460                          }
14455 14461                  }
14456 14462                  rw_exit(&ipst->ips_ill_g_lock);
14457 14463  
14458 14464                  /*
14459 14465                   * Tell SCTP that the ipif has moved.  Note that even if we
14460 14466                   * had to allocate a new ipif, the original sequence id was
14461 14467                   * preserved and therefore SCTP won't know.
14462 14468                   */
14463 14469                  sctp_move_ipif(ipif, ill, ipmp_ill);
14464 14470  
14465 14471                  /*
14466 14472                   * If the ipif being brought up was on slot zero, then we
14467 14473                   * first need to bring up the placeholder we stuck there.  In
14468 14474                   * ip_rput_dlpi_writer(), arp_bringup_done(), or the recursive
14469 14475                   * call to ipif_up() itself, if we successfully bring up the
14470 14476                   * placeholder, we'll check ill_move_ipif and bring it up too.
14471 14477                   */
14472 14478                  if (ipif_orig_id == 0) {
14473 14479                          ASSERT(ill->ill_move_ipif == NULL);
14474 14480                          ill->ill_move_ipif = ipif;
14475 14481                          if ((err = ipif_up(ill->ill_ipif, q, mp)) == 0)
14476 14482                                  ASSERT(ill->ill_move_ipif == NULL);
14477 14483                          if (err != EINPROGRESS)
14478 14484                                  ill->ill_move_ipif = NULL;
14479 14485                          return (err);
14480 14486                  }
14481 14487  
14482 14488                  /*
14483 14489                   * Bring it up on the IPMP ill.
14484 14490                   */
14485 14491                  return (ipif_up(ipif, q, mp));
14486 14492          }
14487 14493  
14488 14494          /* Skip arp/ndp for any loopback interface. */
14489 14495          if (ill->ill_wq != NULL) {
14490 14496                  conn_t *connp = CONN_Q(q) ? Q_TO_CONN(q) : NULL;
14491 14497                  ipsq_t  *ipsq = ill->ill_phyint->phyint_ipsq;
14492 14498  
14493 14499                  if (!ill->ill_dl_up) {
14494 14500                          /*
14495 14501                           * ill_dl_up is not yet set. i.e. we are yet to
14496 14502                           * DL_BIND with the driver and this is the first
14497 14503                           * logical interface on the ill to become "up".
14498 14504                           * Tell the driver to get going (via DL_BIND_REQ).
14499 14505                           * Note that changing "significant" IFF_ flags
14500 14506                           * address/netmask etc cause a down/up dance, but
14501 14507                           * does not cause an unbind (DL_UNBIND) with the driver
14502 14508                           */
14503 14509                          return (ill_dl_up(ill, ipif, mp, q));
14504 14510                  }
14505 14511  
14506 14512                  /*
14507 14513                   * ipif_resolver_up may end up needeing to bind/attach
14508 14514                   * the ARP stream, which in turn necessitates a
14509 14515                   * DLPI message exchange with the driver. ioctls are
14510 14516                   * serialized and so we cannot send more than one
14511 14517                   * interface up message at a time. If ipif_resolver_up
14512 14518                   * does need to wait for the DLPI handshake for the ARP stream,
14513 14519                   * we get EINPROGRESS and we will complete in arp_bringup_done.
14514 14520                   */
14515 14521  
14516 14522                  ASSERT(connp != NULL || !CONN_Q(q));
14517 14523                  if (connp != NULL)
14518 14524                          mutex_enter(&connp->conn_lock);
14519 14525                  mutex_enter(&ill->ill_lock);
14520 14526                  success = ipsq_pending_mp_add(connp, ipif, q, mp, 0);
14521 14527                  mutex_exit(&ill->ill_lock);
14522 14528                  if (connp != NULL)
14523 14529                          mutex_exit(&connp->conn_lock);
14524 14530                  if (!success)
14525 14531                          return (EINTR);
14526 14532  
14527 14533                  /*
14528 14534                   * Crank up IPv6 neighbor discovery. Unlike ARP, this should
14529 14535                   * complete when ipif_ndp_up returns.
14530 14536                   */
14531 14537                  err = ipif_resolver_up(ipif, Res_act_initial);
14532 14538                  if (err == EINPROGRESS) {
14533 14539                          /* We will complete it in arp_bringup_done() */
14534 14540                          return (err);
14535 14541                  }
14536 14542  
14537 14543                  if (isv6 && err == 0)
14538 14544                          err = ipif_ndp_up(ipif, B_TRUE);
14539 14545  
14540 14546                  ASSERT(err != EINPROGRESS);
14541 14547                  mp = ipsq_pending_mp_get(ipsq, &connp);
14542 14548                  ASSERT(mp != NULL);
14543 14549                  if (err != 0)
14544 14550                          return (err);
14545 14551          } else {
14546 14552                  /*
14547 14553                   * Interfaces without underlying hardware don't do duplicate
14548 14554                   * address detection.
14549 14555                   */
14550 14556                  ASSERT(!(ipif->ipif_flags & IPIF_DUPLICATE));
14551 14557                  ipif->ipif_addr_ready = 1;
14552 14558                  err = ill_add_ires(ill);
14553 14559                  /* allocation failure? */
14554 14560                  if (err != 0)
14555 14561                          return (err);
14556 14562          }
14557 14563  
14558 14564          err = (isv6 ? ipif_up_done_v6(ipif) : ipif_up_done(ipif));
14559 14565          if (err == 0 && ill->ill_move_ipif != NULL) {
14560 14566                  ipif = ill->ill_move_ipif;
14561 14567                  ill->ill_move_ipif = NULL;
14562 14568                  return (ipif_up(ipif, q, mp));
14563 14569          }
14564 14570          return (err);
14565 14571  }
14566 14572  
14567 14573  /*
14568 14574   * Add any IREs tied to the ill. For now this is just an IRE_MULTICAST.
14569 14575   * The identical set of IREs need to be removed in ill_delete_ires().
14570 14576   */
14571 14577  int
14572 14578  ill_add_ires(ill_t *ill)
14573 14579  {
14574 14580          ire_t   *ire;
14575 14581          in6_addr_t dummy6 = {(uint32_t)V6_MCAST, 0, 0, 1};
14576 14582          in_addr_t dummy4 = htonl(INADDR_ALLHOSTS_GROUP);
14577 14583  
14578 14584          if (ill->ill_ire_multicast != NULL)
14579 14585                  return (0);
14580 14586  
14581 14587          /*
14582 14588           * provide some dummy ire_addr for creating the ire.
14583 14589           */
14584 14590          if (ill->ill_isv6) {
14585 14591                  ire = ire_create_v6(&dummy6, 0, 0, IRE_MULTICAST, ill,
14586 14592                      ALL_ZONES, RTF_UP, NULL, ill->ill_ipst);
14587 14593          } else {
14588 14594                  ire = ire_create((uchar_t *)&dummy4, 0, 0, IRE_MULTICAST, ill,
14589 14595                      ALL_ZONES, RTF_UP, NULL, ill->ill_ipst);
14590 14596          }
14591 14597          if (ire == NULL)
14592 14598                  return (ENOMEM);
14593 14599  
14594 14600          ill->ill_ire_multicast = ire;
14595 14601          return (0);
14596 14602  }
14597 14603  
14598 14604  void
14599 14605  ill_delete_ires(ill_t *ill)
14600 14606  {
14601 14607          if (ill->ill_ire_multicast != NULL) {
14602 14608                  /*
14603 14609                   * BIND/ATTACH completed; Release the ref for ill_ire_multicast
14604 14610                   * which was taken without any th_tracing enabled.
14605 14611                   * We also mark it as condemned (note that it was never added)
14606 14612                   * so that caching conn's can move off of it.
14607 14613                   */
14608 14614                  ire_make_condemned(ill->ill_ire_multicast);
14609 14615                  ire_refrele_notr(ill->ill_ire_multicast);
14610 14616                  ill->ill_ire_multicast = NULL;
14611 14617          }
14612 14618  }
14613 14619  
14614 14620  /*
14615 14621   * Perform a bind for the physical device.
14616 14622   * When the routine returns EINPROGRESS then mp has been consumed and
14617 14623   * the ioctl will be acked from ip_rput_dlpi.
14618 14624   * Allocate an unbind message and save it until ipif_down.
14619 14625   */
14620 14626  static int
14621 14627  ill_dl_up(ill_t *ill, ipif_t *ipif, mblk_t *mp, queue_t *q)
14622 14628  {
14623 14629          mblk_t  *bind_mp = NULL;
14624 14630          mblk_t  *unbind_mp = NULL;
14625 14631          conn_t  *connp;
14626 14632          boolean_t success;
14627 14633          int     err;
14628 14634  
14629 14635          DTRACE_PROBE2(ill__downup, char *, "ill_dl_up", ill_t *, ill);
14630 14636  
14631 14637          ip1dbg(("ill_dl_up(%s)\n", ill->ill_name));
14632 14638          ASSERT(IAM_WRITER_ILL(ill));
14633 14639          ASSERT(mp != NULL);
14634 14640  
14635 14641          /*
14636 14642           * Make sure we have an IRE_MULTICAST in case we immediately
14637 14643           * start receiving packets.
14638 14644           */
14639 14645          err = ill_add_ires(ill);
14640 14646          if (err != 0)
14641 14647                  goto bad;
14642 14648  
14643 14649          bind_mp = ip_dlpi_alloc(sizeof (dl_bind_req_t) + sizeof (long),
14644 14650              DL_BIND_REQ);
14645 14651          if (bind_mp == NULL)
14646 14652                  goto bad;
14647 14653          ((dl_bind_req_t *)bind_mp->b_rptr)->dl_sap = ill->ill_sap;
14648 14654          ((dl_bind_req_t *)bind_mp->b_rptr)->dl_service_mode = DL_CLDLS;
14649 14655  
14650 14656          /*
14651 14657           * ill_unbind_mp would be non-null if the following sequence had
14652 14658           * happened:
14653 14659           * - send DL_BIND_REQ to driver, wait for response
14654 14660           * - multiple ioctls that need to bring the ipif up are encountered,
14655 14661           *   but they cannot enter the ipsq due to the outstanding DL_BIND_REQ.
14656 14662           *   These ioctls will then be enqueued on the ipsq
14657 14663           * - a DL_ERROR_ACK is returned for the DL_BIND_REQ
14658 14664           * At this point, the pending ioctls in the ipsq will be drained, and
14659 14665           * since ill->ill_dl_up was not set, ill_dl_up would be invoked with
14660 14666           * a non-null ill->ill_unbind_mp
14661 14667           */
14662 14668          if (ill->ill_unbind_mp == NULL) {
14663 14669                  unbind_mp = ip_dlpi_alloc(sizeof (dl_unbind_req_t),
14664 14670                      DL_UNBIND_REQ);
14665 14671                  if (unbind_mp == NULL)
14666 14672                          goto bad;
14667 14673          }
14668 14674          /*
14669 14675           * Record state needed to complete this operation when the
14670 14676           * DL_BIND_ACK shows up.  Also remember the pre-allocated mblks.
14671 14677           */
14672 14678          connp = CONN_Q(q) ? Q_TO_CONN(q) : NULL;
14673 14679          ASSERT(connp != NULL || !CONN_Q(q));
14674 14680          GRAB_CONN_LOCK(q);
14675 14681          mutex_enter(&ipif->ipif_ill->ill_lock);
14676 14682          success = ipsq_pending_mp_add(connp, ipif, q, mp, 0);
14677 14683          mutex_exit(&ipif->ipif_ill->ill_lock);
14678 14684          RELEASE_CONN_LOCK(q);
14679 14685          if (!success)
14680 14686                  goto bad;
14681 14687  
14682 14688          /*
14683 14689           * Save the unbind message for ill_dl_down(); it will be consumed when
14684 14690           * the interface goes down.
14685 14691           */
14686 14692          if (ill->ill_unbind_mp == NULL)
14687 14693                  ill->ill_unbind_mp = unbind_mp;
14688 14694  
14689 14695          ill_dlpi_send(ill, bind_mp);
14690 14696          /* Send down link-layer capabilities probe if not already done. */
14691 14697          ill_capability_probe(ill);
14692 14698  
14693 14699          /*
14694 14700           * Sysid used to rely on the fact that netboots set domainname
14695 14701           * and the like. Now that miniroot boots aren't strictly netboots
14696 14702           * and miniroot network configuration is driven from userland
14697 14703           * these things still need to be set. This situation can be detected
14698 14704           * by comparing the interface being configured here to the one
14699 14705           * dhcifname was set to reference by the boot loader. Once sysid is
14700 14706           * converted to use dhcp_ipc_getinfo() this call can go away.
14701 14707           */
14702 14708          if ((ipif->ipif_flags & IPIF_DHCPRUNNING) &&
14703 14709              (strcmp(ill->ill_name, dhcifname) == 0) &&
14704 14710              (strlen(srpc_domain) == 0)) {
14705 14711                  if (dhcpinit() != 0)
14706 14712                          cmn_err(CE_WARN, "no cached dhcp response");
14707 14713          }
14708 14714  
14709 14715          /*
14710 14716           * This operation will complete in ip_rput_dlpi with either
14711 14717           * a DL_BIND_ACK or DL_ERROR_ACK.
14712 14718           */
14713 14719          return (EINPROGRESS);
14714 14720  bad:
14715 14721          ip1dbg(("ill_dl_up(%s) FAILED\n", ill->ill_name));
14716 14722  
14717 14723          freemsg(bind_mp);
14718 14724          freemsg(unbind_mp);
14719 14725          return (ENOMEM);
14720 14726  }
14721 14727  
14722 14728  /* Add room for tcp+ip headers */
14723 14729  uint_t ip_loopback_mtuplus = IP_LOOPBACK_MTU + IP_SIMPLE_HDR_LENGTH + 20;
14724 14730  
14725 14731  /*
14726 14732   * DLPI and ARP is up.
14727 14733   * Create all the IREs associated with an interface. Bring up multicast.
14728 14734   * Set the interface flag and finish other initialization
14729 14735   * that potentially had to be deferred to after DL_BIND_ACK.
14730 14736   */
14731 14737  int
14732 14738  ipif_up_done(ipif_t *ipif)
14733 14739  {
14734 14740          ill_t           *ill = ipif->ipif_ill;
14735 14741          int             err = 0;
14736 14742          boolean_t       loopback = B_FALSE;
14737 14743          boolean_t       update_src_selection = B_TRUE;
14738 14744          ipif_t          *tmp_ipif;
14739 14745  
14740 14746          ip1dbg(("ipif_up_done(%s:%u)\n",
14741 14747              ipif->ipif_ill->ill_name, ipif->ipif_id));
14742 14748          DTRACE_PROBE3(ipif__downup, char *, "ipif_up_done",
14743 14749              ill_t *, ill, ipif_t *, ipif);
14744 14750  
14745 14751          /* Check if this is a loopback interface */
14746 14752          if (ipif->ipif_ill->ill_wq == NULL)
14747 14753                  loopback = B_TRUE;
14748 14754  
14749 14755          ASSERT(!MUTEX_HELD(&ipif->ipif_ill->ill_lock));
14750 14756  
14751 14757          /*
14752 14758           * If all other interfaces for this ill are down or DEPRECATED,
14753 14759           * or otherwise unsuitable for source address selection,
14754 14760           * reset the src generation numbers to make sure source
14755 14761           * address selection gets to take this new ipif into account.
14756 14762           * No need to hold ill_lock while traversing the ipif list since
14757 14763           * we are writer
14758 14764           */
14759 14765          for (tmp_ipif = ill->ill_ipif; tmp_ipif;
14760 14766              tmp_ipif = tmp_ipif->ipif_next) {
14761 14767                  if (((tmp_ipif->ipif_flags &
14762 14768                      (IPIF_NOXMIT|IPIF_ANYCAST|IPIF_NOLOCAL|IPIF_DEPRECATED)) ||
14763 14769                      !(tmp_ipif->ipif_flags & IPIF_UP)) ||
14764 14770                      (tmp_ipif == ipif))
14765 14771                          continue;
14766 14772                  /* first useable pre-existing interface */
14767 14773                  update_src_selection = B_FALSE;
14768 14774                  break;
14769 14775          }
14770 14776          if (update_src_selection)
14771 14777                  ip_update_source_selection(ill->ill_ipst);
14772 14778  
14773 14779          if (IS_LOOPBACK(ill) || ill->ill_net_type == IRE_IF_NORESOLVER) {
14774 14780                  nce_t *loop_nce = NULL;
14775 14781                  uint16_t flags = (NCE_F_MYADDR | NCE_F_AUTHORITY | NCE_F_NONUD);
14776 14782  
14777 14783                  /*
14778 14784                   * lo0:1 and subsequent ipifs were marked IRE_LOCAL in
14779 14785                   * ipif_lookup_on_name(), but in the case of zones we can have
14780 14786                   * several loopback addresses on lo0. So all the interfaces with
14781 14787                   * loopback addresses need to be marked IRE_LOOPBACK.
14782 14788                   */
14783 14789                  if (V4_PART_OF_V6(ipif->ipif_v6lcl_addr) ==
14784 14790                      htonl(INADDR_LOOPBACK))
14785 14791                          ipif->ipif_ire_type = IRE_LOOPBACK;
14786 14792                  else
14787 14793                          ipif->ipif_ire_type = IRE_LOCAL;
14788 14794                  if (ill->ill_net_type != IRE_LOOPBACK)
14789 14795                          flags |= NCE_F_PUBLISH;
14790 14796  
14791 14797                  /* add unicast nce for the local addr */
14792 14798                  err = nce_lookup_then_add_v4(ill, NULL,
14793 14799                      ill->ill_phys_addr_length, &ipif->ipif_lcl_addr, flags,
14794 14800                      ND_REACHABLE, &loop_nce);
14795 14801                  /* A shared-IP zone sees EEXIST for lo0:N */
14796 14802                  if (err == 0 || err == EEXIST) {
14797 14803                          ipif->ipif_added_nce = 1;
14798 14804                          loop_nce->nce_ipif_cnt++;
14799 14805                          nce_refrele(loop_nce);
14800 14806                          err = 0;
14801 14807                  } else {
14802 14808                          ASSERT(loop_nce == NULL);
14803 14809                          return (err);
14804 14810                  }
14805 14811          }
14806 14812  
14807 14813          /* Create all the IREs associated with this interface */
14808 14814          err = ipif_add_ires_v4(ipif, loopback);
14809 14815          if (err != 0) {
14810 14816                  /*
14811 14817                   * see comments about return value from
14812 14818                   * ip_addr_availability_check() in ipif_add_ires_v4().
14813 14819                   */
14814 14820                  if (err != EADDRINUSE) {
14815 14821                          (void) ipif_arp_down(ipif);
14816 14822                  } else {
14817 14823                          /*
14818 14824                           * Make IPMP aware of the deleted ipif so that
14819 14825                           * the needed ipmp cleanup (e.g., of ipif_bound_ill)
14820 14826                           * can be completed. Note that we do not want to
14821 14827                           * destroy the nce that was created on the ipmp_ill
14822 14828                           * for the active copy of the duplicate address in
14823 14829                           * use.
14824 14830                           */
14825 14831                          if (IS_IPMP(ill))
14826 14832                                  ipmp_illgrp_del_ipif(ill->ill_grp, ipif);
14827 14833                          err = EADDRNOTAVAIL;
14828 14834                  }
14829 14835                  return (err);
14830 14836          }
14831 14837  
14832 14838          if (ill->ill_ipif_up_count == 1 && !loopback) {
14833 14839                  /* Recover any additional IREs entries for this ill */
14834 14840                  (void) ill_recover_saved_ire(ill);
14835 14841          }
14836 14842  
14837 14843          if (ill->ill_need_recover_multicast) {
14838 14844                  /*
14839 14845                   * Need to recover all multicast memberships in the driver.
14840 14846                   * This had to be deferred until we had attached.  The same
14841 14847                   * code exists in ipif_up_done_v6() to recover IPv6
14842 14848                   * memberships.
14843 14849                   *
14844 14850                   * Note that it would be preferable to unconditionally do the
14845 14851                   * ill_recover_multicast() in ill_dl_up(), but we cannot do
14846 14852                   * that since ill_join_allmulti() depends on ill_dl_up being
14847 14853                   * set, and it is not set until we receive a DL_BIND_ACK after
14848 14854                   * having called ill_dl_up().
14849 14855                   */
14850 14856                  ill_recover_multicast(ill);
14851 14857          }
14852 14858  
14853 14859          if (ill->ill_ipif_up_count == 1) {
14854 14860                  /*
14855 14861                   * Since the interface is now up, it may now be active.
14856 14862                   */
14857 14863                  if (IS_UNDER_IPMP(ill))
14858 14864                          ipmp_ill_refresh_active(ill);
14859 14865  
14860 14866                  /*
14861 14867                   * If this is an IPMP interface, we may now be able to
14862 14868                   * establish ARP entries.
14863 14869                   */
14864 14870                  if (IS_IPMP(ill))
14865 14871                          ipmp_illgrp_refresh_arpent(ill->ill_grp);
14866 14872          }
14867 14873  
14868 14874          /* Join the allhosts multicast address */
14869 14875          ipif_multicast_up(ipif);
14870 14876  
14871 14877          if (!loopback && !update_src_selection &&
14872 14878              !(ipif->ipif_flags & (IPIF_NOLOCAL|IPIF_ANYCAST|IPIF_DEPRECATED)))
14873 14879                  ip_update_source_selection(ill->ill_ipst);
14874 14880  
14875 14881          if (!loopback && ipif->ipif_addr_ready) {
14876 14882                  /* Broadcast an address mask reply. */
14877 14883                  ipif_mask_reply(ipif);
14878 14884          }
14879 14885          /* Perhaps ilgs should use this ill */
14880 14886          update_conn_ill(NULL, ill->ill_ipst);
14881 14887  
14882 14888          /*
14883 14889           * This had to be deferred until we had bound.  Tell routing sockets and
14884 14890           * others that this interface is up if it looks like the address has
14885 14891           * been validated.  Otherwise, if it isn't ready yet, wait for
14886 14892           * duplicate address detection to do its thing.
14887 14893           */
14888 14894          if (ipif->ipif_addr_ready)
14889 14895                  ipif_up_notify(ipif);
14890 14896          return (0);
14891 14897  }
14892 14898  
14893 14899  /*
14894 14900   * Add the IREs associated with the ipif.
14895 14901   * Those MUST be explicitly removed in ipif_delete_ires_v4.
14896 14902   */
14897 14903  static int
14898 14904  ipif_add_ires_v4(ipif_t *ipif, boolean_t loopback)
14899 14905  {
14900 14906          ill_t           *ill = ipif->ipif_ill;
14901 14907          ip_stack_t      *ipst = ill->ill_ipst;
14902 14908          ire_t           *ire_array[20];
14903 14909          ire_t           **irep = ire_array;
14904 14910          ire_t           **irep1;
14905 14911          ipaddr_t        net_mask = 0;
14906 14912          ipaddr_t        subnet_mask, route_mask;
14907 14913          int             err;
14908 14914          ire_t           *ire_local = NULL;      /* LOCAL or LOOPBACK */
14909 14915          ire_t           *ire_if = NULL;
14910 14916          uchar_t         *gw;
14911 14917  
14912 14918          if ((ipif->ipif_lcl_addr != INADDR_ANY) &&
14913 14919              !(ipif->ipif_flags & IPIF_NOLOCAL)) {
14914 14920                  /*
14915 14921                   * If we're on a labeled system then make sure that zone-
14916 14922                   * private addresses have proper remote host database entries.
14917 14923                   */
14918 14924                  if (is_system_labeled() &&
14919 14925                      ipif->ipif_ire_type != IRE_LOOPBACK &&
14920 14926                      !tsol_check_interface_address(ipif))
14921 14927                          return (EINVAL);
14922 14928  
14923 14929                  /* Register the source address for __sin6_src_id */
14924 14930                  err = ip_srcid_insert(&ipif->ipif_v6lcl_addr,
14925 14931                      ipif->ipif_zoneid, ipst);
14926 14932                  if (err != 0) {
14927 14933                          ip0dbg(("ipif_add_ires: srcid_insert %d\n", err));
14928 14934                          return (err);
14929 14935                  }
14930 14936  
14931 14937                  if (loopback)
14932 14938                          gw = (uchar_t *)&ipif->ipif_lcl_addr;
14933 14939                  else
14934 14940                          gw = NULL;
14935 14941  
14936 14942                  /* If the interface address is set, create the local IRE. */
14937 14943                  ire_local = ire_create(
14938 14944                      (uchar_t *)&ipif->ipif_lcl_addr,    /* dest address */
14939 14945                      (uchar_t *)&ip_g_all_ones,          /* mask */
14940 14946                      gw,                                 /* gateway */
14941 14947                      ipif->ipif_ire_type,                /* LOCAL or LOOPBACK */
14942 14948                      ipif->ipif_ill,
14943 14949                      ipif->ipif_zoneid,
14944 14950                      ((ipif->ipif_flags & IPIF_PRIVATE) ?
14945 14951                      RTF_PRIVATE : 0) | RTF_KERNEL,
14946 14952                      NULL,
14947 14953                      ipst);
14948 14954                  ip1dbg(("ipif_add_ires: 0x%p creating IRE %p type 0x%x"
14949 14955                      " for 0x%x\n", (void *)ipif, (void *)ire_local,
14950 14956                      ipif->ipif_ire_type,
14951 14957                      ntohl(ipif->ipif_lcl_addr)));
14952 14958                  if (ire_local == NULL) {
14953 14959                          ip1dbg(("ipif_up_done: NULL ire_local\n"));
14954 14960                          err = ENOMEM;
14955 14961                          goto bad;
14956 14962                  }
14957 14963          } else {
14958 14964                  ip1dbg((
14959 14965                      "ipif_add_ires: not creating IRE %d for 0x%x: flags 0x%x\n",
14960 14966                      ipif->ipif_ire_type,
14961 14967                      ntohl(ipif->ipif_lcl_addr),
14962 14968                      (uint_t)ipif->ipif_flags));
14963 14969          }
14964 14970          if ((ipif->ipif_lcl_addr != INADDR_ANY) &&
14965 14971              !(ipif->ipif_flags & IPIF_NOLOCAL)) {
14966 14972                  net_mask = ip_net_mask(ipif->ipif_lcl_addr);
14967 14973          } else {
14968 14974                  net_mask = htonl(IN_CLASSA_NET);        /* fallback */
14969 14975          }
14970 14976  
14971 14977          subnet_mask = ipif->ipif_net_mask;
14972 14978  
14973 14979          /*
14974 14980           * If mask was not specified, use natural netmask of
14975 14981           * interface address. Also, store this mask back into the
14976 14982           * ipif struct.
14977 14983           */
14978 14984          if (subnet_mask == 0) {
14979 14985                  subnet_mask = net_mask;
14980 14986                  V4MASK_TO_V6(subnet_mask, ipif->ipif_v6net_mask);
14981 14987                  V6_MASK_COPY(ipif->ipif_v6lcl_addr, ipif->ipif_v6net_mask,
14982 14988                      ipif->ipif_v6subnet);
14983 14989          }
14984 14990  
14985 14991          /* Set up the IRE_IF_RESOLVER or IRE_IF_NORESOLVER, as appropriate. */
14986 14992          if (!loopback && !(ipif->ipif_flags & IPIF_NOXMIT) &&
14987 14993              ipif->ipif_subnet != INADDR_ANY) {
14988 14994                  /* ipif_subnet is ipif_pp_dst_addr for pt-pt */
14989 14995  
14990 14996                  if (ipif->ipif_flags & IPIF_POINTOPOINT) {
14991 14997                          route_mask = IP_HOST_MASK;
14992 14998                  } else {
14993 14999                          route_mask = subnet_mask;
14994 15000                  }
14995 15001  
14996 15002                  ip1dbg(("ipif_add_ires: ipif 0x%p ill 0x%p "
14997 15003                      "creating if IRE ill_net_type 0x%x for 0x%x\n",
14998 15004                      (void *)ipif, (void *)ill, ill->ill_net_type,
14999 15005                      ntohl(ipif->ipif_subnet)));
15000 15006                  ire_if = ire_create(
15001 15007                      (uchar_t *)&ipif->ipif_subnet,
15002 15008                      (uchar_t *)&route_mask,
15003 15009                      (uchar_t *)&ipif->ipif_lcl_addr,
15004 15010                      ill->ill_net_type,
15005 15011                      ill,
15006 15012                      ipif->ipif_zoneid,
15007 15013                      ((ipif->ipif_flags & IPIF_PRIVATE) ?
15008 15014                      RTF_PRIVATE: 0) | RTF_KERNEL,
15009 15015                      NULL,
15010 15016                      ipst);
15011 15017                  if (ire_if == NULL) {
15012 15018                          ip1dbg(("ipif_up_done: NULL ire_if\n"));
15013 15019                          err = ENOMEM;
15014 15020                          goto bad;
15015 15021                  }
15016 15022          }
15017 15023  
15018 15024          /*
15019 15025           * Create any necessary broadcast IREs.
15020 15026           */
15021 15027          if ((ipif->ipif_flags & IPIF_BROADCAST) &&
15022 15028              !(ipif->ipif_flags & IPIF_NOXMIT))
15023 15029                  irep = ipif_create_bcast_ires(ipif, irep);
15024 15030  
15025 15031          /* If an earlier ire_create failed, get out now */
15026 15032          for (irep1 = irep; irep1 > ire_array; ) {
15027 15033                  irep1--;
15028 15034                  if (*irep1 == NULL) {
15029 15035                          ip1dbg(("ipif_up_done: NULL ire found in ire_array\n"));
15030 15036                          err = ENOMEM;
15031 15037                          goto bad;
15032 15038                  }
15033 15039          }
15034 15040  
15035 15041          /*
15036 15042           * Need to atomically check for IP address availability under
15037 15043           * ip_addr_avail_lock.  ill_g_lock is held as reader to ensure no new
15038 15044           * ills or new ipifs can be added while we are checking availability.
15039 15045           */
15040 15046          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
15041 15047          mutex_enter(&ipst->ips_ip_addr_avail_lock);
15042 15048          /* Mark it up, and increment counters. */
15043 15049          ipif->ipif_flags |= IPIF_UP;
15044 15050          ill->ill_ipif_up_count++;
15045 15051          err = ip_addr_availability_check(ipif);
15046 15052          mutex_exit(&ipst->ips_ip_addr_avail_lock);
15047 15053          rw_exit(&ipst->ips_ill_g_lock);
15048 15054  
15049 15055          if (err != 0) {
15050 15056                  /*
15051 15057                   * Our address may already be up on the same ill. In this case,
15052 15058                   * the ARP entry for our ipif replaced the one for the other
15053 15059                   * ipif. So we don't want to delete it (otherwise the other ipif
15054 15060                   * would be unable to send packets).
15055 15061                   * ip_addr_availability_check() identifies this case for us and
15056 15062                   * returns EADDRINUSE; Caller should turn it into EADDRNOTAVAIL
15057 15063                   * which is the expected error code.
15058 15064                   */
15059 15065                  ill->ill_ipif_up_count--;
15060 15066                  ipif->ipif_flags &= ~IPIF_UP;
15061 15067                  goto bad;
15062 15068          }
15063 15069  
15064 15070          /*
15065 15071           * Add in all newly created IREs.  ire_create_bcast() has
15066 15072           * already checked for duplicates of the IRE_BROADCAST type.
15067 15073           * We add the IRE_INTERFACE before the IRE_LOCAL to ensure
15068 15074           * that lookups find the IRE_LOCAL even if the IRE_INTERFACE is
15069 15075           * a /32 route.
15070 15076           */
15071 15077          if (ire_if != NULL) {
15072 15078                  ire_if = ire_add(ire_if);
15073 15079                  if (ire_if == NULL) {
15074 15080                          err = ENOMEM;
15075 15081                          goto bad2;
15076 15082                  }
15077 15083  #ifdef DEBUG
15078 15084                  ire_refhold_notr(ire_if);
15079 15085                  ire_refrele(ire_if);
15080 15086  #endif
15081 15087          }
15082 15088          if (ire_local != NULL) {
15083 15089                  ire_local = ire_add(ire_local);
15084 15090                  if (ire_local == NULL) {
15085 15091                          err = ENOMEM;
15086 15092                          goto bad2;
15087 15093                  }
15088 15094  #ifdef DEBUG
15089 15095                  ire_refhold_notr(ire_local);
15090 15096                  ire_refrele(ire_local);
15091 15097  #endif
15092 15098          }
15093 15099          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
15094 15100          if (ire_local != NULL)
15095 15101                  ipif->ipif_ire_local = ire_local;
15096 15102          if (ire_if != NULL)
15097 15103                  ipif->ipif_ire_if = ire_if;
15098 15104          rw_exit(&ipst->ips_ill_g_lock);
15099 15105          ire_local = NULL;
15100 15106          ire_if = NULL;
15101 15107  
15102 15108          /*
15103 15109           * We first add all of them, and if that succeeds we refrele the
15104 15110           * bunch. That enables us to delete all of them should any of the
15105 15111           * ire_adds fail.
15106 15112           */
15107 15113          for (irep1 = irep; irep1 > ire_array; ) {
15108 15114                  irep1--;
15109 15115                  ASSERT(!MUTEX_HELD(&((*irep1)->ire_ill->ill_lock)));
15110 15116                  *irep1 = ire_add(*irep1);
15111 15117                  if (*irep1 == NULL) {
15112 15118                          err = ENOMEM;
15113 15119                          goto bad2;
15114 15120                  }
15115 15121          }
15116 15122  
15117 15123          for (irep1 = irep; irep1 > ire_array; ) {
15118 15124                  irep1--;
15119 15125                  /* refheld by ire_add. */
15120 15126                  if (*irep1 != NULL) {
15121 15127                          ire_refrele(*irep1);
15122 15128                          *irep1 = NULL;
15123 15129                  }
15124 15130          }
15125 15131  
15126 15132          if (!loopback) {
15127 15133                  /*
15128 15134                   * If the broadcast address has been set, make sure it makes
15129 15135                   * sense based on the interface address.
15130 15136                   * Only match on ill since we are sharing broadcast addresses.
15131 15137                   */
15132 15138                  if ((ipif->ipif_brd_addr != INADDR_ANY) &&
15133 15139                      (ipif->ipif_flags & IPIF_BROADCAST)) {
15134 15140                          ire_t   *ire;
15135 15141  
15136 15142                          ire = ire_ftable_lookup_v4(ipif->ipif_brd_addr, 0, 0,
15137 15143                              IRE_BROADCAST, ipif->ipif_ill, ALL_ZONES, NULL,
15138 15144                              (MATCH_IRE_TYPE | MATCH_IRE_ILL), 0, ipst, NULL);
15139 15145  
15140 15146                          if (ire == NULL) {
15141 15147                                  /*
15142 15148                                   * If there isn't a matching broadcast IRE,
15143 15149                                   * revert to the default for this netmask.
15144 15150                                   */
15145 15151                                  ipif->ipif_v6brd_addr = ipv6_all_zeros;
15146 15152                                  mutex_enter(&ipif->ipif_ill->ill_lock);
15147 15153                                  ipif_set_default(ipif);
15148 15154                                  mutex_exit(&ipif->ipif_ill->ill_lock);
15149 15155                          } else {
15150 15156                                  ire_refrele(ire);
15151 15157                          }
15152 15158                  }
15153 15159  
15154 15160          }
15155 15161          return (0);
15156 15162  
15157 15163  bad2:
15158 15164          ill->ill_ipif_up_count--;
15159 15165          ipif->ipif_flags &= ~IPIF_UP;
15160 15166  
15161 15167  bad:
15162 15168          ip1dbg(("ipif_add_ires: FAILED \n"));
15163 15169          if (ire_local != NULL)
15164 15170                  ire_delete(ire_local);
15165 15171          if (ire_if != NULL)
15166 15172                  ire_delete(ire_if);
15167 15173  
15168 15174          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
15169 15175          ire_local = ipif->ipif_ire_local;
15170 15176          ipif->ipif_ire_local = NULL;
15171 15177          ire_if = ipif->ipif_ire_if;
15172 15178          ipif->ipif_ire_if = NULL;
15173 15179          rw_exit(&ipst->ips_ill_g_lock);
15174 15180          if (ire_local != NULL) {
15175 15181                  ire_delete(ire_local);
15176 15182                  ire_refrele_notr(ire_local);
15177 15183          }
15178 15184          if (ire_if != NULL) {
15179 15185                  ire_delete(ire_if);
15180 15186                  ire_refrele_notr(ire_if);
15181 15187          }
15182 15188  
15183 15189          while (irep > ire_array) {
15184 15190                  irep--;
15185 15191                  if (*irep != NULL) {
15186 15192                          ire_delete(*irep);
15187 15193                  }
15188 15194          }
15189 15195          (void) ip_srcid_remove(&ipif->ipif_v6lcl_addr, ipif->ipif_zoneid, ipst);
15190 15196  
15191 15197          return (err);
15192 15198  }
15193 15199  
15194 15200  /* Remove all the IREs created by ipif_add_ires_v4 */
15195 15201  void
15196 15202  ipif_delete_ires_v4(ipif_t *ipif)
15197 15203  {
15198 15204          ill_t           *ill = ipif->ipif_ill;
15199 15205          ip_stack_t      *ipst = ill->ill_ipst;
15200 15206          ire_t           *ire;
15201 15207  
15202 15208          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
15203 15209          ire = ipif->ipif_ire_local;
15204 15210          ipif->ipif_ire_local = NULL;
15205 15211          rw_exit(&ipst->ips_ill_g_lock);
15206 15212          if (ire != NULL) {
15207 15213                  /*
15208 15214                   * Move count to ipif so we don't loose the count due to
15209 15215                   * a down/up dance.
15210 15216                   */
15211 15217                  atomic_add_32(&ipif->ipif_ib_pkt_count, ire->ire_ib_pkt_count);
15212 15218  
15213 15219                  ire_delete(ire);
15214 15220                  ire_refrele_notr(ire);
15215 15221          }
15216 15222          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
15217 15223          ire = ipif->ipif_ire_if;
15218 15224          ipif->ipif_ire_if = NULL;
15219 15225          rw_exit(&ipst->ips_ill_g_lock);
15220 15226          if (ire != NULL) {
15221 15227                  ire_delete(ire);
15222 15228                  ire_refrele_notr(ire);
15223 15229          }
15224 15230  
15225 15231          /*
15226 15232           * Delete the broadcast IREs.
15227 15233           */
15228 15234          if ((ipif->ipif_flags & IPIF_BROADCAST) &&
15229 15235              !(ipif->ipif_flags & IPIF_NOXMIT))
15230 15236                  ipif_delete_bcast_ires(ipif);
15231 15237  }
15232 15238  
15233 15239  /*
15234 15240   * Checks for availbility of a usable source address (if there is one) when the
15235 15241   * destination ILL has the ill_usesrc_ifindex pointing to another ILL. Note
15236 15242   * this selection is done regardless of the destination.
15237 15243   */
15238 15244  boolean_t
15239 15245  ipif_zone_avail(uint_t ifindex, boolean_t isv6, zoneid_t zoneid,
15240 15246      ip_stack_t *ipst)
15241 15247  {
15242 15248          ipif_t          *ipif = NULL;
15243 15249          ill_t           *uill;
15244 15250  
15245 15251          ASSERT(ifindex != 0);
15246 15252  
15247 15253          uill = ill_lookup_on_ifindex(ifindex, isv6, ipst);
15248 15254          if (uill == NULL)
15249 15255                  return (B_FALSE);
15250 15256  
15251 15257          mutex_enter(&uill->ill_lock);
15252 15258          for (ipif = uill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
15253 15259                  if (IPIF_IS_CONDEMNED(ipif))
15254 15260                          continue;
15255 15261                  if (ipif->ipif_flags & (IPIF_NOLOCAL|IPIF_ANYCAST))
15256 15262                          continue;
15257 15263                  if (!(ipif->ipif_flags & IPIF_UP))
15258 15264                          continue;
15259 15265                  if (ipif->ipif_zoneid != zoneid)
15260 15266                          continue;
15261 15267                  if (isv6 ? IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr) :
15262 15268                      ipif->ipif_lcl_addr == INADDR_ANY)
15263 15269                          continue;
15264 15270                  mutex_exit(&uill->ill_lock);
15265 15271                  ill_refrele(uill);
15266 15272                  return (B_TRUE);
15267 15273          }
15268 15274          mutex_exit(&uill->ill_lock);
15269 15275          ill_refrele(uill);
15270 15276          return (B_FALSE);
15271 15277  }
15272 15278  
15273 15279  /*
15274 15280   * Find an ipif with a good local address on the ill+zoneid.
15275 15281   */
15276 15282  ipif_t *
15277 15283  ipif_good_addr(ill_t *ill, zoneid_t zoneid)
15278 15284  {
15279 15285          ipif_t          *ipif;
15280 15286  
15281 15287          mutex_enter(&ill->ill_lock);
15282 15288          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
15283 15289                  if (IPIF_IS_CONDEMNED(ipif))
15284 15290                          continue;
15285 15291                  if (ipif->ipif_flags & (IPIF_NOLOCAL|IPIF_ANYCAST))
15286 15292                          continue;
15287 15293                  if (!(ipif->ipif_flags & IPIF_UP))
15288 15294                          continue;
15289 15295                  if (ipif->ipif_zoneid != zoneid &&
15290 15296                      ipif->ipif_zoneid != ALL_ZONES && zoneid != ALL_ZONES)
15291 15297                          continue;
15292 15298                  if (ill->ill_isv6 ?
15293 15299                      IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr) :
15294 15300                      ipif->ipif_lcl_addr == INADDR_ANY)
15295 15301                          continue;
15296 15302                  ipif_refhold_locked(ipif);
15297 15303                  mutex_exit(&ill->ill_lock);
15298 15304                  return (ipif);
15299 15305          }
15300 15306          mutex_exit(&ill->ill_lock);
15301 15307          return (NULL);
15302 15308  }
15303 15309  
15304 15310  /*
15305 15311   * IP source address type, sorted from worst to best.  For a given type,
15306 15312   * always prefer IP addresses on the same subnet.  All-zones addresses are
15307 15313   * suboptimal because they pose problems with unlabeled destinations.
15308 15314   */
15309 15315  typedef enum {
15310 15316          IPIF_NONE,
15311 15317          IPIF_DIFFNET_DEPRECATED,        /* deprecated and different subnet */
15312 15318          IPIF_SAMENET_DEPRECATED,        /* deprecated and same subnet */
15313 15319          IPIF_DIFFNET_ALLZONES,          /* allzones and different subnet */
15314 15320          IPIF_SAMENET_ALLZONES,          /* allzones and same subnet */
15315 15321          IPIF_DIFFNET,                   /* normal and different subnet */
15316 15322          IPIF_SAMENET,                   /* normal and same subnet */
15317 15323          IPIF_LOCALADDR                  /* local loopback */
15318 15324  } ipif_type_t;
15319 15325  
15320 15326  /*
15321 15327   * Pick the optimal ipif on `ill' for sending to destination `dst' from zone
15322 15328   * `zoneid'.  We rate usable ipifs from low -> high as per the ipif_type_t
15323 15329   * enumeration, and return the highest-rated ipif.  If there's a tie, we pick
15324 15330   * the first one, unless IPMP is used in which case we round-robin among them;
15325 15331   * see below for more.
15326 15332   *
15327 15333   * Returns NULL if there is no suitable source address for the ill.
15328 15334   * This only occurs when there is no valid source address for the ill.
15329 15335   */
15330 15336  ipif_t *
15331 15337  ipif_select_source_v4(ill_t *ill, ipaddr_t dst, zoneid_t zoneid,
15332 15338      boolean_t allow_usesrc, boolean_t *notreadyp)
15333 15339  {
15334 15340          ill_t   *usill = NULL;
15335 15341          ill_t   *ipmp_ill = NULL;
15336 15342          ipif_t  *start_ipif, *next_ipif, *ipif, *best_ipif;
15337 15343          ipif_type_t type, best_type;
15338 15344          tsol_tpc_t *src_rhtp, *dst_rhtp;
15339 15345          ip_stack_t *ipst = ill->ill_ipst;
15340 15346          boolean_t samenet;
15341 15347  
15342 15348          if (ill->ill_usesrc_ifindex != 0 && allow_usesrc) {
15343 15349                  usill = ill_lookup_on_ifindex(ill->ill_usesrc_ifindex,
15344 15350                      B_FALSE, ipst);
15345 15351                  if (usill != NULL)
15346 15352                          ill = usill;    /* Select source from usesrc ILL */
15347 15353                  else
15348 15354                          return (NULL);
15349 15355          }
15350 15356  
15351 15357          /*
15352 15358           * Test addresses should never be used for source address selection,
15353 15359           * so if we were passed one, switch to the IPMP meta-interface.
15354 15360           */
15355 15361          if (IS_UNDER_IPMP(ill)) {
15356 15362                  if ((ipmp_ill = ipmp_ill_hold_ipmp_ill(ill)) != NULL)
15357 15363                          ill = ipmp_ill; /* Select source from IPMP ill */
15358 15364                  else
15359 15365                          return (NULL);
15360 15366          }
15361 15367  
15362 15368          /*
15363 15369           * If we're dealing with an unlabeled destination on a labeled system,
15364 15370           * make sure that we ignore source addresses that are incompatible with
15365 15371           * the destination's default label.  That destination's default label
15366 15372           * must dominate the minimum label on the source address.
15367 15373           */
15368 15374          dst_rhtp = NULL;
15369 15375          if (is_system_labeled()) {
15370 15376                  dst_rhtp = find_tpc(&dst, IPV4_VERSION, B_FALSE);
15371 15377                  if (dst_rhtp == NULL)
15372 15378                          return (NULL);
15373 15379                  if (dst_rhtp->tpc_tp.host_type != UNLABELED) {
15374 15380                          TPC_RELE(dst_rhtp);
15375 15381                          dst_rhtp = NULL;
15376 15382                  }
15377 15383          }
15378 15384  
15379 15385          /*
15380 15386           * Hold the ill_g_lock as reader. This makes sure that no ipif/ill
15381 15387           * can be deleted. But an ipif/ill can get CONDEMNED any time.
15382 15388           * After selecting the right ipif, under ill_lock make sure ipif is
15383 15389           * not condemned, and increment refcnt. If ipif is CONDEMNED,
15384 15390           * we retry. Inside the loop we still need to check for CONDEMNED,
15385 15391           * but not under a lock.
15386 15392           */
15387 15393          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
15388 15394  retry:
15389 15395          /*
15390 15396           * For source address selection, we treat the ipif list as circular
15391 15397           * and continue until we get back to where we started.  This allows
15392 15398           * IPMP to vary source address selection (which improves inbound load
15393 15399           * spreading) by caching its last ending point and starting from
15394 15400           * there.  NOTE: we don't have to worry about ill_src_ipif changing
15395 15401           * ills since that can't happen on the IPMP ill.
15396 15402           */
15397 15403          start_ipif = ill->ill_ipif;
15398 15404          if (IS_IPMP(ill) && ill->ill_src_ipif != NULL)
15399 15405                  start_ipif = ill->ill_src_ipif;
15400 15406  
15401 15407          ipif = start_ipif;
15402 15408          best_ipif = NULL;
15403 15409          best_type = IPIF_NONE;
15404 15410          do {
15405 15411                  if ((next_ipif = ipif->ipif_next) == NULL)
15406 15412                          next_ipif = ill->ill_ipif;
15407 15413  
15408 15414                  if (IPIF_IS_CONDEMNED(ipif))
15409 15415                          continue;
15410 15416                  /* Always skip NOLOCAL and ANYCAST interfaces */
15411 15417                  if (ipif->ipif_flags & (IPIF_NOLOCAL|IPIF_ANYCAST))
15412 15418                          continue;
15413 15419                  /* Always skip NOACCEPT interfaces */
15414 15420                  if (ipif->ipif_ill->ill_flags & ILLF_NOACCEPT)
15415 15421                          continue;
15416 15422                  if (!(ipif->ipif_flags & IPIF_UP))
15417 15423                          continue;
15418 15424  
15419 15425                  if (!ipif->ipif_addr_ready) {
15420 15426                          if (notreadyp != NULL)
15421 15427                                  *notreadyp = B_TRUE;
15422 15428                          continue;
15423 15429                  }
15424 15430  
15425 15431                  if (zoneid != ALL_ZONES &&
15426 15432                      ipif->ipif_zoneid != zoneid &&
15427 15433                      ipif->ipif_zoneid != ALL_ZONES)
15428 15434                          continue;
15429 15435  
15430 15436                  /*
15431 15437                   * Interfaces with 0.0.0.0 address are allowed to be UP, but
15432 15438                   * are not valid as source addresses.
15433 15439                   */
15434 15440                  if (ipif->ipif_lcl_addr == INADDR_ANY)
15435 15441                          continue;
15436 15442  
15437 15443                  /*
15438 15444                   * Check compatibility of local address for destination's
15439 15445                   * default label if we're on a labeled system.  Incompatible
15440 15446                   * addresses can't be used at all.
15441 15447                   */
15442 15448                  if (dst_rhtp != NULL) {
15443 15449                          boolean_t incompat;
15444 15450  
15445 15451                          src_rhtp = find_tpc(&ipif->ipif_lcl_addr,
15446 15452                              IPV4_VERSION, B_FALSE);
15447 15453                          if (src_rhtp == NULL)
15448 15454                                  continue;
15449 15455                          incompat = src_rhtp->tpc_tp.host_type != SUN_CIPSO ||
15450 15456                              src_rhtp->tpc_tp.tp_doi !=
15451 15457                              dst_rhtp->tpc_tp.tp_doi ||
15452 15458                              (!_blinrange(&dst_rhtp->tpc_tp.tp_def_label,
15453 15459                              &src_rhtp->tpc_tp.tp_sl_range_cipso) &&
15454 15460                              !blinlset(&dst_rhtp->tpc_tp.tp_def_label,
15455 15461                              src_rhtp->tpc_tp.tp_sl_set_cipso));
15456 15462                          TPC_RELE(src_rhtp);
15457 15463                          if (incompat)
15458 15464                                  continue;
15459 15465                  }
15460 15466  
15461 15467                  samenet = ((ipif->ipif_net_mask & dst) == ipif->ipif_subnet);
15462 15468  
15463 15469                  if (ipif->ipif_lcl_addr == dst) {
15464 15470                          type = IPIF_LOCALADDR;
15465 15471                  } else if (ipif->ipif_flags & IPIF_DEPRECATED) {
15466 15472                          type = samenet ? IPIF_SAMENET_DEPRECATED :
15467 15473                              IPIF_DIFFNET_DEPRECATED;
15468 15474                  } else if (ipif->ipif_zoneid == ALL_ZONES) {
15469 15475                          type = samenet ? IPIF_SAMENET_ALLZONES :
15470 15476                              IPIF_DIFFNET_ALLZONES;
15471 15477                  } else {
15472 15478                          type = samenet ? IPIF_SAMENET : IPIF_DIFFNET;
15473 15479                  }
15474 15480  
15475 15481                  if (type > best_type) {
15476 15482                          best_type = type;
15477 15483                          best_ipif = ipif;
15478 15484                          if (best_type == IPIF_LOCALADDR)
15479 15485                                  break; /* can't get better */
15480 15486                  }
15481 15487          } while ((ipif = next_ipif) != start_ipif);
15482 15488  
15483 15489          if ((ipif = best_ipif) != NULL) {
15484 15490                  mutex_enter(&ipif->ipif_ill->ill_lock);
15485 15491                  if (IPIF_IS_CONDEMNED(ipif)) {
15486 15492                          mutex_exit(&ipif->ipif_ill->ill_lock);
15487 15493                          goto retry;
15488 15494                  }
15489 15495                  ipif_refhold_locked(ipif);
15490 15496  
15491 15497                  /*
15492 15498                   * For IPMP, update the source ipif rotor to the next ipif,
15493 15499                   * provided we can look it up.  (We must not use it if it's
15494 15500                   * IPIF_CONDEMNED since we may have grabbed ill_g_lock after
15495 15501                   * ipif_free() checked ill_src_ipif.)
15496 15502                   */
15497 15503                  if (IS_IPMP(ill) && ipif != NULL) {
15498 15504                          next_ipif = ipif->ipif_next;
15499 15505                          if (next_ipif != NULL && !IPIF_IS_CONDEMNED(next_ipif))
15500 15506                                  ill->ill_src_ipif = next_ipif;
15501 15507                          else
15502 15508                                  ill->ill_src_ipif = NULL;
15503 15509                  }
15504 15510                  mutex_exit(&ipif->ipif_ill->ill_lock);
15505 15511          }
15506 15512  
15507 15513          rw_exit(&ipst->ips_ill_g_lock);
15508 15514          if (usill != NULL)
15509 15515                  ill_refrele(usill);
15510 15516          if (ipmp_ill != NULL)
15511 15517                  ill_refrele(ipmp_ill);
15512 15518          if (dst_rhtp != NULL)
15513 15519                  TPC_RELE(dst_rhtp);
15514 15520  
15515 15521  #ifdef DEBUG
15516 15522          if (ipif == NULL) {
15517 15523                  char buf1[INET6_ADDRSTRLEN];
15518 15524  
15519 15525                  ip1dbg(("ipif_select_source_v4(%s, %s) -> NULL\n",
15520 15526                      ill->ill_name,
15521 15527                      inet_ntop(AF_INET, &dst, buf1, sizeof (buf1))));
15522 15528          } else {
15523 15529                  char buf1[INET6_ADDRSTRLEN];
15524 15530                  char buf2[INET6_ADDRSTRLEN];
15525 15531  
15526 15532                  ip1dbg(("ipif_select_source_v4(%s, %s) -> %s\n",
15527 15533                      ipif->ipif_ill->ill_name,
15528 15534                      inet_ntop(AF_INET, &dst, buf1, sizeof (buf1)),
15529 15535                      inet_ntop(AF_INET, &ipif->ipif_lcl_addr,
15530 15536                      buf2, sizeof (buf2))));
15531 15537          }
15532 15538  #endif /* DEBUG */
15533 15539          return (ipif);
15534 15540  }
15535 15541  
15536 15542  /*
15537 15543   * Pick a source address based on the destination ill and an optional setsrc
15538 15544   * address.
15539 15545   * The result is stored in srcp. If generation is set, then put the source
15540 15546   * generation number there before we look for the source address (to avoid
15541 15547   * missing changes in the set of source addresses.
15542 15548   * If flagsp is set, then us it to pass back ipif_flags.
15543 15549   *
15544 15550   * If the caller wants to cache the returned source address and detect when
15545 15551   * that might be stale, the caller should pass in a generation argument,
15546 15552   * which the caller can later compare against ips_src_generation
15547 15553   *
15548 15554   * The precedence order for selecting an IPv4 source address is:
15549 15555   *  - RTF_SETSRC on the offlink ire always wins.
15550 15556   *  - If usrsrc is set, swap the ill to be the usesrc one.
15551 15557   *  - If IPMP is used on the ill, select a random address from the most
15552 15558   *    preferred ones below:
15553 15559   * 1. If onlink destination, same subnet and not deprecated, not ALL_ZONES
15554 15560   * 2. Not deprecated, not ALL_ZONES
15555 15561   * 3. If onlink destination, same subnet and not deprecated, ALL_ZONES
15556 15562   * 4. Not deprecated, ALL_ZONES
15557 15563   * 5. If onlink destination, same subnet and deprecated
15558 15564   * 6. Deprecated.
15559 15565   *
15560 15566   * We have lower preference for ALL_ZONES IP addresses,
15561 15567   * as they pose problems with unlabeled destinations.
15562 15568   *
15563 15569   * Note that when multiple IP addresses match e.g., #1 we pick
15564 15570   * the first one if IPMP is not in use. With IPMP we randomize.
15565 15571   */
15566 15572  int
15567 15573  ip_select_source_v4(ill_t *ill, ipaddr_t setsrc, ipaddr_t dst,
15568 15574      ipaddr_t multicast_ifaddr,
15569 15575      zoneid_t zoneid, ip_stack_t *ipst, ipaddr_t *srcp,
15570 15576      uint32_t *generation, uint64_t *flagsp)
15571 15577  {
15572 15578          ipif_t *ipif;
15573 15579          boolean_t notready = B_FALSE;   /* Set if !ipif_addr_ready found */
15574 15580  
15575 15581          if (flagsp != NULL)
15576 15582                  *flagsp = 0;
15577 15583  
15578 15584          /*
15579 15585           * Need to grab the generation number before we check to
15580 15586           * avoid a race with a change to the set of local addresses.
15581 15587           * No lock needed since the thread which updates the set of local
15582 15588           * addresses use ipif/ill locks and exit those (hence a store memory
15583 15589           * barrier) before doing the atomic increase of ips_src_generation.
15584 15590           */
15585 15591          if (generation != NULL) {
15586 15592                  *generation = ipst->ips_src_generation;
15587 15593          }
15588 15594  
15589 15595          if (CLASSD(dst) && multicast_ifaddr != INADDR_ANY) {
15590 15596                  *srcp = multicast_ifaddr;
15591 15597                  return (0);
15592 15598          }
15593 15599  
15594 15600          /* Was RTF_SETSRC set on the first IRE in the recursive lookup? */
15595 15601          if (setsrc != INADDR_ANY) {
15596 15602                  *srcp = setsrc;
15597 15603                  return (0);
15598 15604          }
15599 15605          ipif = ipif_select_source_v4(ill, dst, zoneid, B_TRUE, ¬ready);
15600 15606          if (ipif == NULL) {
15601 15607                  if (notready)
15602 15608                          return (ENETDOWN);
15603 15609                  else
15604 15610                          return (EADDRNOTAVAIL);
15605 15611          }
15606 15612          *srcp = ipif->ipif_lcl_addr;
15607 15613          if (flagsp != NULL)
15608 15614                  *flagsp = ipif->ipif_flags;
15609 15615          ipif_refrele(ipif);
15610 15616          return (0);
15611 15617  }
15612 15618  
15613 15619  /* ARGSUSED */
15614 15620  int
15615 15621  if_unitsel_restart(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
15616 15622          ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
15617 15623  {
15618 15624          /*
15619 15625           * ill_phyint_reinit merged the v4 and v6 into a single
15620 15626           * ipsq.  We might not have been able to complete the
15621 15627           * operation in ipif_set_values, if we could not become
15622 15628           * exclusive.  If so restart it here.
15623 15629           */
15624 15630          return (ipif_set_values_tail(ipif->ipif_ill, ipif, mp, q));
15625 15631  }
15626 15632  
15627 15633  /*
15628 15634   * Can operate on either a module or a driver queue.
15629 15635   * Returns an error if not a module queue.
15630 15636   */
15631 15637  /* ARGSUSED */
15632 15638  int
15633 15639  if_unitsel(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
15634 15640      ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
15635 15641  {
15636 15642          queue_t         *q1 = q;
15637 15643          char            *cp;
15638 15644          char            interf_name[LIFNAMSIZ];
15639 15645          uint_t          ppa = *(uint_t *)mp->b_cont->b_cont->b_rptr;
15640 15646  
15641 15647          if (q->q_next == NULL) {
15642 15648                  ip1dbg((
15643 15649                      "if_unitsel: IF_UNITSEL: no q_next\n"));
15644 15650                  return (EINVAL);
15645 15651          }
15646 15652  
15647 15653          if (((ill_t *)(q->q_ptr))->ill_name[0] != '\0')
15648 15654                  return (EALREADY);
15649 15655  
15650 15656          do {
15651 15657                  q1 = q1->q_next;
15652 15658          } while (q1->q_next);
15653 15659          cp = q1->q_qinfo->qi_minfo->mi_idname;
15654 15660          (void) sprintf(interf_name, "%s%d", cp, ppa);
15655 15661  
15656 15662          /*
15657 15663           * Here we are not going to delay the ioack until after
15658 15664           * ACKs from DL_ATTACH_REQ/DL_BIND_REQ. So no need to save the
15659 15665           * original ioctl message before sending the requests.
15660 15666           */
15661 15667          return (ipif_set_values(q, mp, interf_name, &ppa));
15662 15668  }
15663 15669  
15664 15670  /* ARGSUSED */
15665 15671  int
15666 15672  ip_sioctl_sifname(ipif_t *dummy_ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
15667 15673      ip_ioctl_cmd_t *ipip, void *dummy_ifreq)
15668 15674  {
15669 15675          return (ENXIO);
15670 15676  }
15671 15677  
15672 15678  /*
15673 15679   * Create any IRE_BROADCAST entries for `ipif', and store those entries in
15674 15680   * `irep'.  Returns a pointer to the next free `irep' entry
15675 15681   * A mirror exists in ipif_delete_bcast_ires().
15676 15682   *
15677 15683   * The management of any "extra" or seemingly duplicate IRE_BROADCASTs is
15678 15684   * done in ire_add.
15679 15685   */
15680 15686  static ire_t **
15681 15687  ipif_create_bcast_ires(ipif_t *ipif, ire_t **irep)
15682 15688  {
15683 15689          ipaddr_t addr;
15684 15690          ipaddr_t netmask = ip_net_mask(ipif->ipif_lcl_addr);
15685 15691          ipaddr_t subnetmask = ipif->ipif_net_mask;
15686 15692          ill_t *ill = ipif->ipif_ill;
15687 15693          zoneid_t zoneid = ipif->ipif_zoneid;
15688 15694  
15689 15695          ip1dbg(("ipif_create_bcast_ires: creating broadcast IREs\n"));
15690 15696  
15691 15697          ASSERT(ipif->ipif_flags & IPIF_BROADCAST);
15692 15698          ASSERT(!(ipif->ipif_flags & IPIF_NOXMIT));
15693 15699  
15694 15700          if (ipif->ipif_lcl_addr == INADDR_ANY ||
15695 15701              (ipif->ipif_flags & IPIF_NOLOCAL))
15696 15702                  netmask = htonl(IN_CLASSA_NET);         /* fallback */
15697 15703  
15698 15704          irep = ire_create_bcast(ill, 0, zoneid, irep);
15699 15705          irep = ire_create_bcast(ill, INADDR_BROADCAST, zoneid, irep);
15700 15706  
15701 15707          /*
15702 15708           * For backward compatibility, we create net broadcast IREs based on
15703 15709           * the old "IP address class system", since some old machines only
15704 15710           * respond to these class derived net broadcast.  However, we must not
15705 15711           * create these net broadcast IREs if the subnetmask is shorter than
15706 15712           * the IP address class based derived netmask.  Otherwise, we may
15707 15713           * create a net broadcast address which is the same as an IP address
15708 15714           * on the subnet -- and then TCP will refuse to talk to that address.
15709 15715           */
15710 15716          if (netmask < subnetmask) {
15711 15717                  addr = netmask & ipif->ipif_subnet;
15712 15718                  irep = ire_create_bcast(ill, addr, zoneid, irep);
15713 15719                  irep = ire_create_bcast(ill, ~netmask | addr, zoneid, irep);
15714 15720          }
15715 15721  
15716 15722          /*
15717 15723           * Don't create IRE_BROADCAST IREs for the interface if the subnetmask
15718 15724           * is 0xFFFFFFFF, as an IRE_LOCAL for that interface is already
15719 15725           * created.  Creating these broadcast IREs will only create confusion
15720 15726           * as `addr' will be the same as the IP address.
15721 15727           */
15722 15728          if (subnetmask != 0xFFFFFFFF) {
15723 15729                  addr = ipif->ipif_subnet;
15724 15730                  irep = ire_create_bcast(ill, addr, zoneid, irep);
15725 15731                  irep = ire_create_bcast(ill, ~subnetmask | addr, zoneid, irep);
15726 15732          }
15727 15733  
15728 15734          return (irep);
15729 15735  }
15730 15736  
15731 15737  /*
15732 15738   * Mirror of ipif_create_bcast_ires()
15733 15739   */
15734 15740  static void
15735 15741  ipif_delete_bcast_ires(ipif_t *ipif)
15736 15742  {
15737 15743          ipaddr_t        addr;
15738 15744          ipaddr_t        netmask = ip_net_mask(ipif->ipif_lcl_addr);
15739 15745          ipaddr_t        subnetmask = ipif->ipif_net_mask;
15740 15746          ill_t           *ill = ipif->ipif_ill;
15741 15747          zoneid_t        zoneid = ipif->ipif_zoneid;
15742 15748          ire_t           *ire;
15743 15749  
15744 15750          ASSERT(ipif->ipif_flags & IPIF_BROADCAST);
15745 15751          ASSERT(!(ipif->ipif_flags & IPIF_NOXMIT));
15746 15752  
15747 15753          if (ipif->ipif_lcl_addr == INADDR_ANY ||
15748 15754              (ipif->ipif_flags & IPIF_NOLOCAL))
15749 15755                  netmask = htonl(IN_CLASSA_NET);         /* fallback */
15750 15756  
15751 15757          ire = ire_lookup_bcast(ill, 0, zoneid);
15752 15758          ASSERT(ire != NULL);
15753 15759          ire_delete(ire); ire_refrele(ire);
15754 15760          ire = ire_lookup_bcast(ill, INADDR_BROADCAST, zoneid);
15755 15761          ASSERT(ire != NULL);
15756 15762          ire_delete(ire); ire_refrele(ire);
15757 15763  
15758 15764          /*
15759 15765           * For backward compatibility, we create net broadcast IREs based on
15760 15766           * the old "IP address class system", since some old machines only
15761 15767           * respond to these class derived net broadcast.  However, we must not
15762 15768           * create these net broadcast IREs if the subnetmask is shorter than
15763 15769           * the IP address class based derived netmask.  Otherwise, we may
15764 15770           * create a net broadcast address which is the same as an IP address
15765 15771           * on the subnet -- and then TCP will refuse to talk to that address.
15766 15772           */
15767 15773          if (netmask < subnetmask) {
15768 15774                  addr = netmask & ipif->ipif_subnet;
15769 15775                  ire = ire_lookup_bcast(ill, addr, zoneid);
15770 15776                  ASSERT(ire != NULL);
15771 15777                  ire_delete(ire); ire_refrele(ire);
15772 15778                  ire = ire_lookup_bcast(ill, ~netmask | addr, zoneid);
15773 15779                  ASSERT(ire != NULL);
15774 15780                  ire_delete(ire); ire_refrele(ire);
15775 15781          }
15776 15782  
15777 15783          /*
15778 15784           * Don't create IRE_BROADCAST IREs for the interface if the subnetmask
15779 15785           * is 0xFFFFFFFF, as an IRE_LOCAL for that interface is already
15780 15786           * created.  Creating these broadcast IREs will only create confusion
15781 15787           * as `addr' will be the same as the IP address.
15782 15788           */
15783 15789          if (subnetmask != 0xFFFFFFFF) {
15784 15790                  addr = ipif->ipif_subnet;
15785 15791                  ire = ire_lookup_bcast(ill, addr, zoneid);
15786 15792                  ASSERT(ire != NULL);
15787 15793                  ire_delete(ire); ire_refrele(ire);
15788 15794                  ire = ire_lookup_bcast(ill, ~subnetmask | addr, zoneid);
15789 15795                  ASSERT(ire != NULL);
15790 15796                  ire_delete(ire); ire_refrele(ire);
15791 15797          }
15792 15798  }
15793 15799  
15794 15800  /*
15795 15801   * Extract both the flags (including IFF_CANTCHANGE) such as IFF_IPV*
15796 15802   * from lifr_flags and the name from lifr_name.
15797 15803   * Set IFF_IPV* and ill_isv6 prior to doing the lookup
15798 15804   * since ipif_lookup_on_name uses the _isv6 flags when matching.
15799 15805   * Returns EINPROGRESS when mp has been consumed by queueing it on
15800 15806   * ipx_pending_mp and the ioctl will complete in ip_rput.
15801 15807   *
15802 15808   * Can operate on either a module or a driver queue.
15803 15809   * Returns an error if not a module queue.
15804 15810   */
15805 15811  /* ARGSUSED */
15806 15812  int
15807 15813  ip_sioctl_slifname(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
15808 15814      ip_ioctl_cmd_t *ipip, void *if_req)
15809 15815  {
15810 15816          ill_t   *ill = q->q_ptr;
15811 15817          phyint_t *phyi;
15812 15818          ip_stack_t *ipst;
15813 15819          struct lifreq *lifr = if_req;
15814 15820          uint64_t new_flags;
15815 15821  
15816 15822          ASSERT(ipif != NULL);
15817 15823          ip1dbg(("ip_sioctl_slifname %s\n", lifr->lifr_name));
15818 15824  
15819 15825          if (q->q_next == NULL) {
15820 15826                  ip1dbg(("if_sioctl_slifname: SIOCSLIFNAME: no q_next\n"));
15821 15827                  return (EINVAL);
15822 15828          }
15823 15829  
15824 15830          /*
15825 15831           * If we are not writer on 'q' then this interface exists already
15826 15832           * and previous lookups (ip_extract_lifreq()) found this ipif --
15827 15833           * so return EALREADY.
15828 15834           */
15829 15835          if (ill != ipif->ipif_ill)
15830 15836                  return (EALREADY);
15831 15837  
15832 15838          if (ill->ill_name[0] != '\0')
15833 15839                  return (EALREADY);
15834 15840  
15835 15841          /*
15836 15842           * If there's another ill already with the requested name, ensure
15837 15843           * that it's of the same type.  Otherwise, ill_phyint_reinit() will
15838 15844           * fuse together two unrelated ills, which will cause chaos.
15839 15845           */
15840 15846          ipst = ill->ill_ipst;
15841 15847          phyi = avl_find(&ipst->ips_phyint_g_list->phyint_list_avl_by_name,
15842 15848              lifr->lifr_name, NULL);
15843 15849          if (phyi != NULL) {
15844 15850                  ill_t *ill_mate = phyi->phyint_illv4;
15845 15851  
15846 15852                  if (ill_mate == NULL)
15847 15853                          ill_mate = phyi->phyint_illv6;
15848 15854                  ASSERT(ill_mate != NULL);
15849 15855  
15850 15856                  if (ill_mate->ill_media->ip_m_mac_type !=
15851 15857                      ill->ill_media->ip_m_mac_type) {
15852 15858                          ip1dbg(("if_sioctl_slifname: SIOCSLIFNAME: attempt to "
15853 15859                              "use the same ill name on differing media\n"));
15854 15860                          return (EINVAL);
15855 15861                  }
15856 15862          }
15857 15863  
15858 15864          /*
15859 15865           * We start off as IFF_IPV4 in ipif_allocate and become
15860 15866           * IFF_IPV4 or IFF_IPV6 here depending  on lifr_flags value.
15861 15867           * The only flags that we read from user space are IFF_IPV4,
15862 15868           * IFF_IPV6, and IFF_BROADCAST.
15863 15869           *
15864 15870           * This ill has not been inserted into the global list.
15865 15871           * So we are still single threaded and don't need any lock
15866 15872           *
15867 15873           * Saniy check the flags.
15868 15874           */
15869 15875  
15870 15876          if ((lifr->lifr_flags & IFF_BROADCAST) &&
15871 15877              ((lifr->lifr_flags & IFF_IPV6) ||
15872 15878              (!ill->ill_needs_attach && ill->ill_bcast_addr_length == 0))) {
15873 15879                  ip1dbg(("ip_sioctl_slifname: link not broadcast capable "
15874 15880                      "or IPv6 i.e., no broadcast \n"));
15875 15881                  return (EINVAL);
15876 15882          }
15877 15883  
15878 15884          new_flags =
15879 15885              lifr->lifr_flags & (IFF_IPV6|IFF_IPV4|IFF_BROADCAST);
15880 15886  
15881 15887          if ((new_flags ^ (IFF_IPV6|IFF_IPV4)) == 0) {
15882 15888                  ip1dbg(("ip_sioctl_slifname: flags must be exactly one of "
15883 15889                      "IFF_IPV4 or IFF_IPV6\n"));
15884 15890                  return (EINVAL);
15885 15891          }
15886 15892  
15887 15893          /*
15888 15894           * We always start off as IPv4, so only need to check for IPv6.
15889 15895           */
15890 15896          if ((new_flags & IFF_IPV6) != 0) {
15891 15897                  ill->ill_flags |= ILLF_IPV6;
15892 15898                  ill->ill_flags &= ~ILLF_IPV4;
15893 15899  
15894 15900                  if (lifr->lifr_flags & IFF_NOLINKLOCAL)
15895 15901                          ill->ill_flags |= ILLF_NOLINKLOCAL;
15896 15902          }
15897 15903  
15898 15904          if ((new_flags & IFF_BROADCAST) != 0)
15899 15905                  ipif->ipif_flags |= IPIF_BROADCAST;
15900 15906          else
15901 15907                  ipif->ipif_flags &= ~IPIF_BROADCAST;
15902 15908  
15903 15909          /* We started off as V4. */
15904 15910          if (ill->ill_flags & ILLF_IPV6) {
15905 15911                  ill->ill_phyint->phyint_illv6 = ill;
15906 15912                  ill->ill_phyint->phyint_illv4 = NULL;
15907 15913          }
15908 15914  
15909 15915          return (ipif_set_values(q, mp, lifr->lifr_name, &lifr->lifr_ppa));
15910 15916  }
15911 15917  
15912 15918  /* ARGSUSED */
15913 15919  int
15914 15920  ip_sioctl_slifname_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
15915 15921      ip_ioctl_cmd_t *ipip, void *if_req)
15916 15922  {
15917 15923          /*
15918 15924           * ill_phyint_reinit merged the v4 and v6 into a single
15919 15925           * ipsq.  We might not have been able to complete the
15920 15926           * slifname in ipif_set_values, if we could not become
15921 15927           * exclusive.  If so restart it here
15922 15928           */
15923 15929          return (ipif_set_values_tail(ipif->ipif_ill, ipif, mp, q));
15924 15930  }
15925 15931  
15926 15932  /*
15927 15933   * Return a pointer to the ipif which matches the index, IP version type and
15928 15934   * zoneid.
15929 15935   */
15930 15936  ipif_t *
15931 15937  ipif_lookup_on_ifindex(uint_t index, boolean_t isv6, zoneid_t zoneid,
15932 15938      ip_stack_t *ipst)
15933 15939  {
15934 15940          ill_t   *ill;
15935 15941          ipif_t  *ipif = NULL;
15936 15942  
15937 15943          ill = ill_lookup_on_ifindex(index, isv6, ipst);
15938 15944          if (ill != NULL) {
15939 15945                  mutex_enter(&ill->ill_lock);
15940 15946                  for (ipif = ill->ill_ipif; ipif != NULL;
15941 15947                      ipif = ipif->ipif_next) {
15942 15948                          if (!IPIF_IS_CONDEMNED(ipif) && (zoneid == ALL_ZONES ||
15943 15949                              zoneid == ipif->ipif_zoneid ||
15944 15950                              ipif->ipif_zoneid == ALL_ZONES)) {
15945 15951                                  ipif_refhold_locked(ipif);
15946 15952                                  break;
15947 15953                          }
15948 15954                  }
15949 15955                  mutex_exit(&ill->ill_lock);
15950 15956                  ill_refrele(ill);
15951 15957          }
15952 15958          return (ipif);
15953 15959  }
15954 15960  
15955 15961  /*
15956 15962   * Change an existing physical interface's index. If the new index
15957 15963   * is acceptable we update the index and the phyint_list_avl_by_index tree.
15958 15964   * Finally, we update other systems which may have a dependence on the
15959 15965   * index value.
15960 15966   */
15961 15967  /* ARGSUSED */
15962 15968  int
15963 15969  ip_sioctl_slifindex(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
15964 15970      ip_ioctl_cmd_t *ipip, void *ifreq)
15965 15971  {
15966 15972          ill_t           *ill;
15967 15973          phyint_t        *phyi;
15968 15974          struct ifreq    *ifr = (struct ifreq *)ifreq;
15969 15975          struct lifreq   *lifr = (struct lifreq *)ifreq;
15970 15976          uint_t  old_index, index;
15971 15977          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
15972 15978          avl_index_t     where;
15973 15979  
15974 15980          if (ipip->ipi_cmd_type == IF_CMD)
15975 15981                  index = ifr->ifr_index;
15976 15982          else
15977 15983                  index = lifr->lifr_index;
15978 15984  
15979 15985          /*
15980 15986           * Only allow on physical interface. Also, index zero is illegal.
15981 15987           */
15982 15988          ill = ipif->ipif_ill;
15983 15989          phyi = ill->ill_phyint;
15984 15990          if (ipif->ipif_id != 0 || index == 0 || index > IF_INDEX_MAX) {
15985 15991                  return (EINVAL);
15986 15992          }
15987 15993  
15988 15994          /* If the index is not changing, no work to do */
15989 15995          if (phyi->phyint_ifindex == index)
15990 15996                  return (0);
15991 15997  
15992 15998          /*
15993 15999           * Use phyint_exists() to determine if the new interface index
15994 16000           * is already in use. If the index is unused then we need to
15995 16001           * change the phyint's position in the phyint_list_avl_by_index
15996 16002           * tree. If we do not do this, subsequent lookups (using the new
15997 16003           * index value) will not find the phyint.
15998 16004           */
15999 16005          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
16000 16006          if (phyint_exists(index, ipst)) {
16001 16007                  rw_exit(&ipst->ips_ill_g_lock);
16002 16008                  return (EEXIST);
16003 16009          }
16004 16010  
16005 16011          /*
16006 16012           * The new index is unused. Set it in the phyint. However we must not
16007 16013           * forget to trigger NE_IFINDEX_CHANGE event before the ifindex
16008 16014           * changes. The event must be bound to old ifindex value.
16009 16015           */
16010 16016          ill_nic_event_dispatch(ill, 0, NE_IFINDEX_CHANGE,
16011 16017              &index, sizeof (index));
16012 16018  
16013 16019          old_index = phyi->phyint_ifindex;
16014 16020          phyi->phyint_ifindex = index;
16015 16021  
16016 16022          avl_remove(&ipst->ips_phyint_g_list->phyint_list_avl_by_index, phyi);
16017 16023          (void) avl_find(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
16018 16024              &index, &where);
16019 16025          avl_insert(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
16020 16026              phyi, where);
16021 16027          rw_exit(&ipst->ips_ill_g_lock);
16022 16028  
16023 16029          /* Update SCTP's ILL list */
16024 16030          sctp_ill_reindex(ill, old_index);
16025 16031  
16026 16032          /* Send the routing sockets message */
16027 16033          ip_rts_ifmsg(ipif, RTSQ_DEFAULT);
16028 16034          if (ILL_OTHER(ill))
16029 16035                  ip_rts_ifmsg(ILL_OTHER(ill)->ill_ipif, RTSQ_DEFAULT);
16030 16036  
16031 16037          /* Perhaps ilgs should use this ill */
16032 16038          update_conn_ill(NULL, ill->ill_ipst);
16033 16039          return (0);
16034 16040  }
16035 16041  
16036 16042  /* ARGSUSED */
16037 16043  int
16038 16044  ip_sioctl_get_lifindex(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16039 16045      ip_ioctl_cmd_t *ipip, void *ifreq)
16040 16046  {
16041 16047          struct ifreq    *ifr = (struct ifreq *)ifreq;
16042 16048          struct lifreq   *lifr = (struct lifreq *)ifreq;
16043 16049  
16044 16050          ip1dbg(("ip_sioctl_get_lifindex(%s:%u %p)\n",
16045 16051              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
16046 16052          /* Get the interface index */
16047 16053          if (ipip->ipi_cmd_type == IF_CMD) {
16048 16054                  ifr->ifr_index = ipif->ipif_ill->ill_phyint->phyint_ifindex;
16049 16055          } else {
16050 16056                  lifr->lifr_index = ipif->ipif_ill->ill_phyint->phyint_ifindex;
16051 16057          }
16052 16058          return (0);
16053 16059  }
16054 16060  
16055 16061  /* ARGSUSED */
16056 16062  int
16057 16063  ip_sioctl_get_lifzone(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16058 16064      ip_ioctl_cmd_t *ipip, void *ifreq)
16059 16065  {
16060 16066          struct lifreq   *lifr = (struct lifreq *)ifreq;
16061 16067  
16062 16068          ip1dbg(("ip_sioctl_get_lifzone(%s:%u %p)\n",
16063 16069              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
16064 16070          /* Get the interface zone */
16065 16071          ASSERT(ipip->ipi_cmd_type == LIF_CMD);
16066 16072          lifr->lifr_zoneid = ipif->ipif_zoneid;
16067 16073          return (0);
16068 16074  }
16069 16075  
16070 16076  /*
16071 16077   * Set the zoneid of an interface.
16072 16078   */
16073 16079  /* ARGSUSED */
16074 16080  int
16075 16081  ip_sioctl_slifzone(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16076 16082      ip_ioctl_cmd_t *ipip, void *ifreq)
16077 16083  {
16078 16084          struct lifreq   *lifr = (struct lifreq *)ifreq;
16079 16085          int err = 0;
16080 16086          boolean_t need_up = B_FALSE;
16081 16087          zone_t *zptr;
16082 16088          zone_status_t status;
16083 16089          zoneid_t zoneid;
16084 16090  
16085 16091          ASSERT(ipip->ipi_cmd_type == LIF_CMD);
16086 16092          if ((zoneid = lifr->lifr_zoneid) == ALL_ZONES) {
16087 16093                  if (!is_system_labeled())
16088 16094                          return (ENOTSUP);
16089 16095                  zoneid = GLOBAL_ZONEID;
16090 16096          }
16091 16097  
16092 16098          /* cannot assign instance zero to a non-global zone */
16093 16099          if (ipif->ipif_id == 0 && zoneid != GLOBAL_ZONEID)
16094 16100                  return (ENOTSUP);
16095 16101  
16096 16102          /*
16097 16103           * Cannot assign to a zone that doesn't exist or is shutting down.  In
16098 16104           * the event of a race with the zone shutdown processing, since IP
16099 16105           * serializes this ioctl and SIOCGLIFCONF/SIOCLIFREMOVEIF, we know the
16100 16106           * interface will be cleaned up even if the zone is shut down
16101 16107           * immediately after the status check. If the interface can't be brought
16102 16108           * down right away, and the zone is shut down before the restart
16103 16109           * function is called, we resolve the possible races by rechecking the
16104 16110           * zone status in the restart function.
16105 16111           */
16106 16112          if ((zptr = zone_find_by_id(zoneid)) == NULL)
16107 16113                  return (EINVAL);
16108 16114          status = zone_status_get(zptr);
16109 16115          zone_rele(zptr);
16110 16116  
16111 16117          if (status != ZONE_IS_READY && status != ZONE_IS_RUNNING)
16112 16118                  return (EINVAL);
16113 16119  
16114 16120          if (ipif->ipif_flags & IPIF_UP) {
16115 16121                  /*
16116 16122                   * If the interface is already marked up,
16117 16123                   * we call ipif_down which will take care
16118 16124                   * of ditching any IREs that have been set
16119 16125                   * up based on the old interface address.
16120 16126                   */
16121 16127                  err = ipif_logical_down(ipif, q, mp);
16122 16128                  if (err == EINPROGRESS)
16123 16129                          return (err);
16124 16130                  (void) ipif_down_tail(ipif);
16125 16131                  need_up = B_TRUE;
16126 16132          }
16127 16133  
16128 16134          err = ip_sioctl_slifzone_tail(ipif, lifr->lifr_zoneid, q, mp, need_up);
16129 16135          return (err);
16130 16136  }
16131 16137  
16132 16138  static int
16133 16139  ip_sioctl_slifzone_tail(ipif_t *ipif, zoneid_t zoneid,
16134 16140      queue_t *q, mblk_t *mp, boolean_t need_up)
16135 16141  {
16136 16142          int     err = 0;
16137 16143          ip_stack_t      *ipst;
16138 16144  
16139 16145          ip1dbg(("ip_sioctl_zoneid_tail(%s:%u %p)\n",
16140 16146              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
16141 16147  
16142 16148          if (CONN_Q(q))
16143 16149                  ipst = CONNQ_TO_IPST(q);
16144 16150          else
16145 16151                  ipst = ILLQ_TO_IPST(q);
16146 16152  
16147 16153          /*
16148 16154           * For exclusive stacks we don't allow a different zoneid than
16149 16155           * global.
16150 16156           */
16151 16157          if (ipst->ips_netstack->netstack_stackid != GLOBAL_NETSTACKID &&
16152 16158              zoneid != GLOBAL_ZONEID)
16153 16159                  return (EINVAL);
16154 16160  
16155 16161          /* Set the new zone id. */
16156 16162          ipif->ipif_zoneid = zoneid;
16157 16163  
16158 16164          /* Update sctp list */
16159 16165          sctp_update_ipif(ipif, SCTP_IPIF_UPDATE);
16160 16166  
16161 16167          /* The default multicast interface might have changed */
16162 16168          ire_increment_multicast_generation(ipst, ipif->ipif_ill->ill_isv6);
16163 16169  
16164 16170          if (need_up) {
16165 16171                  /*
16166 16172                   * Now bring the interface back up.  If this
16167 16173                   * is the only IPIF for the ILL, ipif_up
16168 16174                   * will have to re-bind to the device, so
16169 16175                   * we may get back EINPROGRESS, in which
16170 16176                   * case, this IOCTL will get completed in
16171 16177                   * ip_rput_dlpi when we see the DL_BIND_ACK.
16172 16178                   */
16173 16179                  err = ipif_up(ipif, q, mp);
16174 16180          }
16175 16181          return (err);
16176 16182  }
16177 16183  
16178 16184  /* ARGSUSED */
16179 16185  int
16180 16186  ip_sioctl_slifzone_restart(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16181 16187      ip_ioctl_cmd_t *ipip, void *if_req)
16182 16188  {
16183 16189          struct lifreq *lifr = (struct lifreq *)if_req;
16184 16190          zoneid_t zoneid;
16185 16191          zone_t *zptr;
16186 16192          zone_status_t status;
16187 16193  
16188 16194          ASSERT(ipip->ipi_cmd_type == LIF_CMD);
16189 16195          if ((zoneid = lifr->lifr_zoneid) == ALL_ZONES)
16190 16196                  zoneid = GLOBAL_ZONEID;
16191 16197  
16192 16198          ip1dbg(("ip_sioctl_slifzone_restart(%s:%u %p)\n",
16193 16199              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
16194 16200  
16195 16201          /*
16196 16202           * We recheck the zone status to resolve the following race condition:
16197 16203           * 1) process sends SIOCSLIFZONE to put hme0:1 in zone "myzone";
16198 16204           * 2) hme0:1 is up and can't be brought down right away;
16199 16205           * ip_sioctl_slifzone() returns EINPROGRESS and the request is queued;
16200 16206           * 3) zone "myzone" is halted; the zone status switches to
16201 16207           * 'shutting_down' and the zones framework sends SIOCGLIFCONF to list
16202 16208           * the interfaces to remove - hme0:1 is not returned because it's not
16203 16209           * yet in "myzone", so it won't be removed;
16204 16210           * 4) the restart function for SIOCSLIFZONE is called; without the
16205 16211           * status check here, we would have hme0:1 in "myzone" after it's been
16206 16212           * destroyed.
16207 16213           * Note that if the status check fails, we need to bring the interface
16208 16214           * back to its state prior to ip_sioctl_slifzone(), hence the call to
16209 16215           * ipif_up_done[_v6]().
16210 16216           */
16211 16217          status = ZONE_IS_UNINITIALIZED;
16212 16218          if ((zptr = zone_find_by_id(zoneid)) != NULL) {
16213 16219                  status = zone_status_get(zptr);
16214 16220                  zone_rele(zptr);
16215 16221          }
16216 16222          if (status != ZONE_IS_READY && status != ZONE_IS_RUNNING) {
16217 16223                  if (ipif->ipif_isv6) {
16218 16224                          (void) ipif_up_done_v6(ipif);
16219 16225                  } else {
16220 16226                          (void) ipif_up_done(ipif);
16221 16227                  }
16222 16228                  return (EINVAL);
16223 16229          }
16224 16230  
16225 16231          (void) ipif_down_tail(ipif);
16226 16232  
16227 16233          return (ip_sioctl_slifzone_tail(ipif, lifr->lifr_zoneid, q, mp,
16228 16234              B_TRUE));
16229 16235  }
16230 16236  
16231 16237  /*
16232 16238   * Return the number of addresses on `ill' with one or more of the values
16233 16239   * in `set' set and all of the values in `clear' clear.
16234 16240   */
16235 16241  static uint_t
16236 16242  ill_flagaddr_cnt(const ill_t *ill, uint64_t set, uint64_t clear)
16237 16243  {
16238 16244          ipif_t  *ipif;
16239 16245          uint_t  cnt = 0;
16240 16246  
16241 16247          ASSERT(IAM_WRITER_ILL(ill));
16242 16248  
16243 16249          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next)
16244 16250                  if ((ipif->ipif_flags & set) && !(ipif->ipif_flags & clear))
16245 16251                          cnt++;
16246 16252  
16247 16253          return (cnt);
16248 16254  }
16249 16255  
16250 16256  /*
16251 16257   * Return the number of migratable addresses on `ill' that are under
16252 16258   * application control.
16253 16259   */
16254 16260  uint_t
16255 16261  ill_appaddr_cnt(const ill_t *ill)
16256 16262  {
16257 16263          return (ill_flagaddr_cnt(ill, IPIF_DHCPRUNNING | IPIF_ADDRCONF,
16258 16264              IPIF_NOFAILOVER));
16259 16265  }
16260 16266  
16261 16267  /*
16262 16268   * Return the number of point-to-point addresses on `ill'.
16263 16269   */
16264 16270  uint_t
16265 16271  ill_ptpaddr_cnt(const ill_t *ill)
16266 16272  {
16267 16273          return (ill_flagaddr_cnt(ill, IPIF_POINTOPOINT, 0));
16268 16274  }
16269 16275  
16270 16276  /* ARGSUSED */
16271 16277  int
16272 16278  ip_sioctl_get_lifusesrc(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16273 16279          ip_ioctl_cmd_t *ipip, void *ifreq)
16274 16280  {
16275 16281          struct lifreq   *lifr = ifreq;
16276 16282  
16277 16283          ASSERT(q->q_next == NULL);
16278 16284          ASSERT(CONN_Q(q));
16279 16285  
16280 16286          ip1dbg(("ip_sioctl_get_lifusesrc(%s:%u %p)\n",
16281 16287              ipif->ipif_ill->ill_name, ipif->ipif_id, (void *)ipif));
16282 16288          lifr->lifr_index = ipif->ipif_ill->ill_usesrc_ifindex;
16283 16289          ip1dbg(("ip_sioctl_get_lifusesrc:lifr_index = %d\n", lifr->lifr_index));
16284 16290  
16285 16291          return (0);
16286 16292  }
16287 16293  
16288 16294  /* Find the previous ILL in this usesrc group */
16289 16295  static ill_t *
16290 16296  ill_prev_usesrc(ill_t *uill)
16291 16297  {
16292 16298          ill_t *ill;
16293 16299  
16294 16300          for (ill = uill->ill_usesrc_grp_next;
16295 16301              ASSERT(ill), ill->ill_usesrc_grp_next != uill;
16296 16302              ill = ill->ill_usesrc_grp_next)
16297 16303                  /* do nothing */;
16298 16304          return (ill);
16299 16305  }
16300 16306  
16301 16307  /*
16302 16308   * Release all members of the usesrc group. This routine is called
16303 16309   * from ill_delete when the interface being unplumbed is the
16304 16310   * group head.
16305 16311   *
16306 16312   * This silently clears the usesrc that ifconfig setup.
16307 16313   * An alternative would be to keep that ifindex, and drop packets on the floor
16308 16314   * since no source address can be selected.
16309 16315   * Even if we keep the current semantics, don't need a lock and a linked list.
16310 16316   * Can walk all the ills checking if they have a ill_usesrc_ifindex matching
16311 16317   * the one that is being removed. Issue is how we return the usesrc users
16312 16318   * (SIOCGLIFSRCOF). We want to be able to find the ills which have an
16313 16319   * ill_usesrc_ifindex matching a target ill. We could also do that with an
16314 16320   * ill walk, but the walker would need to insert in the ioctl response.
16315 16321   */
16316 16322  static void
16317 16323  ill_disband_usesrc_group(ill_t *uill)
16318 16324  {
16319 16325          ill_t *next_ill, *tmp_ill;
16320 16326          ip_stack_t      *ipst = uill->ill_ipst;
16321 16327  
16322 16328          ASSERT(RW_WRITE_HELD(&ipst->ips_ill_g_usesrc_lock));
16323 16329          next_ill = uill->ill_usesrc_grp_next;
16324 16330  
16325 16331          do {
16326 16332                  ASSERT(next_ill != NULL);
16327 16333                  tmp_ill = next_ill->ill_usesrc_grp_next;
16328 16334                  ASSERT(tmp_ill != NULL);
16329 16335                  next_ill->ill_usesrc_grp_next = NULL;
16330 16336                  next_ill->ill_usesrc_ifindex = 0;
16331 16337                  next_ill = tmp_ill;
16332 16338          } while (next_ill->ill_usesrc_ifindex != 0);
16333 16339          uill->ill_usesrc_grp_next = NULL;
16334 16340  }
16335 16341  
16336 16342  /*
16337 16343   * Remove the client usesrc ILL from the list and relink to a new list
16338 16344   */
16339 16345  int
16340 16346  ill_relink_usesrc_ills(ill_t *ucill, ill_t *uill, uint_t ifindex)
16341 16347  {
16342 16348          ill_t *ill, *tmp_ill;
16343 16349          ip_stack_t      *ipst = ucill->ill_ipst;
16344 16350  
16345 16351          ASSERT((ucill != NULL) && (ucill->ill_usesrc_grp_next != NULL) &&
16346 16352              (uill != NULL) && RW_WRITE_HELD(&ipst->ips_ill_g_usesrc_lock));
16347 16353  
16348 16354          /*
16349 16355           * Check if the usesrc client ILL passed in is not already
16350 16356           * in use as a usesrc ILL i.e one whose source address is
16351 16357           * in use OR a usesrc ILL is not already in use as a usesrc
16352 16358           * client ILL
16353 16359           */
16354 16360          if ((ucill->ill_usesrc_ifindex == 0) ||
16355 16361              (uill->ill_usesrc_ifindex != 0)) {
16356 16362                  return (-1);
16357 16363          }
16358 16364  
16359 16365          ill = ill_prev_usesrc(ucill);
16360 16366          ASSERT(ill->ill_usesrc_grp_next != NULL);
16361 16367  
16362 16368          /* Remove from the current list */
16363 16369          if (ill->ill_usesrc_grp_next->ill_usesrc_grp_next == ill) {
16364 16370                  /* Only two elements in the list */
16365 16371                  ASSERT(ill->ill_usesrc_ifindex == 0);
16366 16372                  ill->ill_usesrc_grp_next = NULL;
16367 16373          } else {
16368 16374                  ill->ill_usesrc_grp_next = ucill->ill_usesrc_grp_next;
16369 16375          }
16370 16376  
16371 16377          if (ifindex == 0) {
16372 16378                  ucill->ill_usesrc_ifindex = 0;
16373 16379                  ucill->ill_usesrc_grp_next = NULL;
16374 16380                  return (0);
16375 16381          }
16376 16382  
16377 16383          ucill->ill_usesrc_ifindex = ifindex;
16378 16384          tmp_ill = uill->ill_usesrc_grp_next;
16379 16385          uill->ill_usesrc_grp_next = ucill;
16380 16386          ucill->ill_usesrc_grp_next =
16381 16387              (tmp_ill != NULL) ? tmp_ill : uill;
16382 16388          return (0);
16383 16389  }
16384 16390  
16385 16391  /*
16386 16392   * Set the ill_usesrc and ill_usesrc_head fields. See synchronization notes in
16387 16393   * ip.c for locking details.
16388 16394   */
16389 16395  /* ARGSUSED */
16390 16396  int
16391 16397  ip_sioctl_slifusesrc(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16392 16398      ip_ioctl_cmd_t *ipip, void *ifreq)
16393 16399  {
16394 16400          struct lifreq *lifr = (struct lifreq *)ifreq;
16395 16401          boolean_t isv6 = B_FALSE, reset_flg = B_FALSE;
16396 16402          ill_t *usesrc_ill, *usesrc_cli_ill = ipif->ipif_ill;
16397 16403          int err = 0, ret;
16398 16404          uint_t ifindex;
16399 16405          ipsq_t *ipsq = NULL;
16400 16406          ip_stack_t      *ipst = ipif->ipif_ill->ill_ipst;
16401 16407  
16402 16408          ASSERT(IAM_WRITER_IPIF(ipif));
16403 16409          ASSERT(q->q_next == NULL);
16404 16410          ASSERT(CONN_Q(q));
16405 16411  
16406 16412          isv6 = (Q_TO_CONN(q))->conn_family == AF_INET6;
16407 16413  
16408 16414          ifindex = lifr->lifr_index;
16409 16415          if (ifindex == 0) {
16410 16416                  if (usesrc_cli_ill->ill_usesrc_grp_next == NULL) {
16411 16417                          /* non usesrc group interface, nothing to reset */
16412 16418                          return (0);
16413 16419                  }
16414 16420                  ifindex = usesrc_cli_ill->ill_usesrc_ifindex;
16415 16421                  /* valid reset request */
16416 16422                  reset_flg = B_TRUE;
16417 16423          }
16418 16424  
16419 16425          usesrc_ill = ill_lookup_on_ifindex(ifindex, isv6, ipst);
16420 16426          if (usesrc_ill == NULL)
16421 16427                  return (ENXIO);
16422 16428          if (usesrc_ill == ipif->ipif_ill) {
16423 16429                  ill_refrele(usesrc_ill);
16424 16430                  return (EINVAL);
16425 16431          }
16426 16432  
16427 16433          ipsq = ipsq_try_enter(NULL, usesrc_ill, q, mp, ip_process_ioctl,
16428 16434              NEW_OP, B_TRUE);
16429 16435          if (ipsq == NULL) {
16430 16436                  err = EINPROGRESS;
16431 16437                  /* Operation enqueued on the ipsq of the usesrc ILL */
16432 16438                  goto done;
16433 16439          }
16434 16440  
16435 16441          /* USESRC isn't currently supported with IPMP */
16436 16442          if (IS_IPMP(usesrc_ill) || IS_UNDER_IPMP(usesrc_ill)) {
16437 16443                  err = ENOTSUP;
16438 16444                  goto done;
16439 16445          }
16440 16446  
16441 16447          /*
16442 16448           * USESRC isn't compatible with the STANDBY flag.  (STANDBY is only
16443 16449           * used by IPMP underlying interfaces, but someone might think it's
16444 16450           * more general and try to use it independently with VNI.)
16445 16451           */
16446 16452          if (usesrc_ill->ill_phyint->phyint_flags & PHYI_STANDBY) {
16447 16453                  err = ENOTSUP;
16448 16454                  goto done;
16449 16455          }
16450 16456  
16451 16457          /*
16452 16458           * If the client is already in use as a usesrc_ill or a usesrc_ill is
16453 16459           * already a client then return EINVAL
16454 16460           */
16455 16461          if (IS_USESRC_ILL(usesrc_cli_ill) || IS_USESRC_CLI_ILL(usesrc_ill)) {
16456 16462                  err = EINVAL;
16457 16463                  goto done;
16458 16464          }
16459 16465  
16460 16466          /*
16461 16467           * If the ill_usesrc_ifindex field is already set to what it needs to
16462 16468           * be then this is a duplicate operation.
16463 16469           */
16464 16470          if (!reset_flg && usesrc_cli_ill->ill_usesrc_ifindex == ifindex) {
16465 16471                  err = 0;
16466 16472                  goto done;
16467 16473          }
16468 16474  
16469 16475          ip1dbg(("ip_sioctl_slifusesrc: usesrc_cli_ill %s, usesrc_ill %s,"
16470 16476              " v6 = %d", usesrc_cli_ill->ill_name, usesrc_ill->ill_name,
16471 16477              usesrc_ill->ill_isv6));
16472 16478  
16473 16479          /*
16474 16480           * ill_g_usesrc_lock global lock protects the ill_usesrc_grp_next
16475 16481           * and the ill_usesrc_ifindex fields
16476 16482           */
16477 16483          rw_enter(&ipst->ips_ill_g_usesrc_lock, RW_WRITER);
16478 16484  
16479 16485          if (reset_flg) {
16480 16486                  ret = ill_relink_usesrc_ills(usesrc_cli_ill, usesrc_ill, 0);
16481 16487                  if (ret != 0) {
16482 16488                          err = EINVAL;
16483 16489                  }
16484 16490                  rw_exit(&ipst->ips_ill_g_usesrc_lock);
16485 16491                  goto done;
16486 16492          }
16487 16493  
16488 16494          /*
16489 16495           * Four possibilities to consider:
16490 16496           * 1. Both usesrc_ill and usesrc_cli_ill are not part of any usesrc grp
16491 16497           * 2. usesrc_ill is part of a group but usesrc_cli_ill isn't
16492 16498           * 3. usesrc_cli_ill is part of a group but usesrc_ill isn't
16493 16499           * 4. Both are part of their respective usesrc groups
16494 16500           */
16495 16501          if ((usesrc_ill->ill_usesrc_grp_next == NULL) &&
16496 16502              (usesrc_cli_ill->ill_usesrc_grp_next == NULL)) {
16497 16503                  ASSERT(usesrc_ill->ill_usesrc_ifindex == 0);
16498 16504                  usesrc_cli_ill->ill_usesrc_ifindex = ifindex;
16499 16505                  usesrc_ill->ill_usesrc_grp_next = usesrc_cli_ill;
16500 16506                  usesrc_cli_ill->ill_usesrc_grp_next = usesrc_ill;
16501 16507          } else if ((usesrc_ill->ill_usesrc_grp_next != NULL) &&
16502 16508              (usesrc_cli_ill->ill_usesrc_grp_next == NULL)) {
16503 16509                  usesrc_cli_ill->ill_usesrc_ifindex = ifindex;
16504 16510                  /* Insert at head of list */
16505 16511                  usesrc_cli_ill->ill_usesrc_grp_next =
16506 16512                      usesrc_ill->ill_usesrc_grp_next;
16507 16513                  usesrc_ill->ill_usesrc_grp_next = usesrc_cli_ill;
16508 16514          } else {
16509 16515                  ret = ill_relink_usesrc_ills(usesrc_cli_ill, usesrc_ill,
16510 16516                      ifindex);
16511 16517                  if (ret != 0)
16512 16518                          err = EINVAL;
16513 16519          }
16514 16520          rw_exit(&ipst->ips_ill_g_usesrc_lock);
16515 16521  
16516 16522  done:
16517 16523          if (ipsq != NULL)
16518 16524                  ipsq_exit(ipsq);
16519 16525          /* The refrele on the lifr_name ipif is done by ip_process_ioctl */
16520 16526          ill_refrele(usesrc_ill);
16521 16527  
16522 16528          /* Let conn_ixa caching know that source address selection changed */
16523 16529          ip_update_source_selection(ipst);
16524 16530  
16525 16531          return (err);
16526 16532  }
16527 16533  
16528 16534  /* ARGSUSED */
16529 16535  int
16530 16536  ip_sioctl_get_dadstate(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
16531 16537      ip_ioctl_cmd_t *ipip, void *if_req)
16532 16538  {
16533 16539          struct lifreq   *lifr = (struct lifreq *)if_req;
16534 16540          ill_t           *ill = ipif->ipif_ill;
16535 16541  
16536 16542          /*
16537 16543           * Need a lock since IFF_UP can be set even when there are
16538 16544           * references to the ipif.
16539 16545           */
16540 16546          mutex_enter(&ill->ill_lock);
16541 16547          if ((ipif->ipif_flags & IPIF_UP) && ipif->ipif_addr_ready == 0)
16542 16548                  lifr->lifr_dadstate = DAD_IN_PROGRESS;
16543 16549          else
16544 16550                  lifr->lifr_dadstate = DAD_DONE;
16545 16551          mutex_exit(&ill->ill_lock);
16546 16552          return (0);
16547 16553  }
16548 16554  
16549 16555  /*
16550 16556   * comparison function used by avl.
16551 16557   */
16552 16558  static int
16553 16559  ill_phyint_compare_index(const void *index_ptr, const void *phyip)
16554 16560  {
16555 16561  
16556 16562          uint_t index;
16557 16563  
16558 16564          ASSERT(phyip != NULL && index_ptr != NULL);
16559 16565  
16560 16566          index = *((uint_t *)index_ptr);
16561 16567          /*
16562 16568           * let the phyint with the lowest index be on top.
16563 16569           */
16564 16570          if (((phyint_t *)phyip)->phyint_ifindex < index)
16565 16571                  return (1);
16566 16572          if (((phyint_t *)phyip)->phyint_ifindex > index)
16567 16573                  return (-1);
16568 16574          return (0);
16569 16575  }
16570 16576  
16571 16577  /*
16572 16578   * comparison function used by avl.
16573 16579   */
16574 16580  static int
16575 16581  ill_phyint_compare_name(const void *name_ptr, const void *phyip)
16576 16582  {
16577 16583          ill_t *ill;
16578 16584          int res = 0;
16579 16585  
16580 16586          ASSERT(phyip != NULL && name_ptr != NULL);
16581 16587  
16582 16588          if (((phyint_t *)phyip)->phyint_illv4)
16583 16589                  ill = ((phyint_t *)phyip)->phyint_illv4;
16584 16590          else
16585 16591                  ill = ((phyint_t *)phyip)->phyint_illv6;
16586 16592          ASSERT(ill != NULL);
16587 16593  
16588 16594          res = strcmp(ill->ill_name, (char *)name_ptr);
16589 16595          if (res > 0)
16590 16596                  return (1);
16591 16597          else if (res < 0)
16592 16598                  return (-1);
16593 16599          return (0);
16594 16600  }
16595 16601  
16596 16602  /*
16597 16603   * This function is called on the unplumb path via ill_glist_delete() when
16598 16604   * there are no ills left on the phyint and thus the phyint can be freed.
16599 16605   */
16600 16606  static void
16601 16607  phyint_free(phyint_t *phyi)
16602 16608  {
16603 16609          ip_stack_t *ipst = PHYINT_TO_IPST(phyi);
16604 16610  
16605 16611          ASSERT(phyi->phyint_illv4 == NULL && phyi->phyint_illv6 == NULL);
16606 16612  
16607 16613          /*
16608 16614           * If this phyint was an IPMP meta-interface, blow away the group.
16609 16615           * This is safe to do because all of the illgrps have already been
16610 16616           * removed by I_PUNLINK, and thus SIOCSLIFGROUPNAME cannot find us.
16611 16617           * If we're cleaning up as a result of failed initialization,
16612 16618           * phyint_grp may be NULL.
16613 16619           */
16614 16620          if ((phyi->phyint_flags & PHYI_IPMP) && (phyi->phyint_grp != NULL)) {
16615 16621                  rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
16616 16622                  ipmp_grp_destroy(phyi->phyint_grp);
16617 16623                  phyi->phyint_grp = NULL;
16618 16624                  rw_exit(&ipst->ips_ipmp_lock);
16619 16625          }
16620 16626  
16621 16627          /*
16622 16628           * If this interface was under IPMP, take it out of the group.
16623 16629           */
16624 16630          if (phyi->phyint_grp != NULL)
16625 16631                  ipmp_phyint_leave_grp(phyi);
16626 16632  
16627 16633          /*
16628 16634           * Delete the phyint and disassociate its ipsq.  The ipsq itself
16629 16635           * will be freed in ipsq_exit().
16630 16636           */
16631 16637          phyi->phyint_ipsq->ipsq_phyint = NULL;
16632 16638          phyi->phyint_name[0] = '\0';
16633 16639  
16634 16640          mi_free(phyi);
16635 16641  }
16636 16642  
16637 16643  /*
16638 16644   * Attach the ill to the phyint structure which can be shared by both
16639 16645   * IPv4 and IPv6 ill. ill_init allocates a phyint to just hold flags. This
16640 16646   * function is called from ipif_set_values and ill_lookup_on_name (for
16641 16647   * loopback) where we know the name of the ill. We lookup the ill and if
16642 16648   * there is one present already with the name use that phyint. Otherwise
16643 16649   * reuse the one allocated by ill_init.
16644 16650   */
16645 16651  static void
16646 16652  ill_phyint_reinit(ill_t *ill)
16647 16653  {
16648 16654          boolean_t isv6 = ill->ill_isv6;
16649 16655          phyint_t *phyi_old;
16650 16656          phyint_t *phyi;
16651 16657          avl_index_t where = 0;
16652 16658          ill_t   *ill_other = NULL;
16653 16659          ip_stack_t      *ipst = ill->ill_ipst;
16654 16660  
16655 16661          ASSERT(RW_WRITE_HELD(&ipst->ips_ill_g_lock));
16656 16662  
16657 16663          phyi_old = ill->ill_phyint;
16658 16664          ASSERT(isv6 || (phyi_old->phyint_illv4 == ill &&
16659 16665              phyi_old->phyint_illv6 == NULL));
16660 16666          ASSERT(!isv6 || (phyi_old->phyint_illv6 == ill &&
16661 16667              phyi_old->phyint_illv4 == NULL));
16662 16668          ASSERT(phyi_old->phyint_ifindex == 0);
16663 16669  
16664 16670          /*
16665 16671           * Now that our ill has a name, set it in the phyint.
16666 16672           */
16667 16673          (void) strlcpy(ill->ill_phyint->phyint_name, ill->ill_name, LIFNAMSIZ);
16668 16674  
16669 16675          phyi = avl_find(&ipst->ips_phyint_g_list->phyint_list_avl_by_name,
16670 16676              ill->ill_name, &where);
16671 16677  
16672 16678          /*
16673 16679           * 1. We grabbed the ill_g_lock before inserting this ill into
16674 16680           *    the global list of ills. So no other thread could have located
16675 16681           *    this ill and hence the ipsq of this ill is guaranteed to be empty.
16676 16682           * 2. Now locate the other protocol instance of this ill.
16677 16683           * 3. Now grab both ill locks in the right order, and the phyint lock of
16678 16684           *    the new ipsq. Holding ill locks + ill_g_lock ensures that the ipsq
16679 16685           *    of neither ill can change.
16680 16686           * 4. Merge the phyint and thus the ipsq as well of this ill onto the
16681 16687           *    other ill.
16682 16688           * 5. Release all locks.
16683 16689           */
16684 16690  
16685 16691          /*
16686 16692           * Look for IPv4 if we are initializing IPv6 or look for IPv6 if
16687 16693           * we are initializing IPv4.
16688 16694           */
16689 16695          if (phyi != NULL) {
16690 16696                  ill_other = (isv6) ? phyi->phyint_illv4 : phyi->phyint_illv6;
16691 16697                  ASSERT(ill_other->ill_phyint != NULL);
16692 16698                  ASSERT((isv6 && !ill_other->ill_isv6) ||
16693 16699                      (!isv6 && ill_other->ill_isv6));
16694 16700                  GRAB_ILL_LOCKS(ill, ill_other);
16695 16701                  /*
16696 16702                   * We are potentially throwing away phyint_flags which
16697 16703                   * could be different from the one that we obtain from
16698 16704                   * ill_other->ill_phyint. But it is okay as we are assuming
16699 16705                   * that the state maintained within IP is correct.
16700 16706                   */
16701 16707                  mutex_enter(&phyi->phyint_lock);
16702 16708                  if (isv6) {
16703 16709                          ASSERT(phyi->phyint_illv6 == NULL);
16704 16710                          phyi->phyint_illv6 = ill;
16705 16711                  } else {
16706 16712                          ASSERT(phyi->phyint_illv4 == NULL);
16707 16713                          phyi->phyint_illv4 = ill;
16708 16714                  }
16709 16715  
16710 16716                  /*
16711 16717                   * Delete the old phyint and make its ipsq eligible
16712 16718                   * to be freed in ipsq_exit().
16713 16719                   */
16714 16720                  phyi_old->phyint_illv4 = NULL;
16715 16721                  phyi_old->phyint_illv6 = NULL;
16716 16722                  phyi_old->phyint_ipsq->ipsq_phyint = NULL;
16717 16723                  phyi_old->phyint_name[0] = '\0';
16718 16724                  mi_free(phyi_old);
16719 16725          } else {
16720 16726                  mutex_enter(&ill->ill_lock);
16721 16727                  /*
16722 16728                   * We don't need to acquire any lock, since
16723 16729                   * the ill is not yet visible globally  and we
16724 16730                   * have not yet released the ill_g_lock.
16725 16731                   */
16726 16732                  phyi = phyi_old;
16727 16733                  mutex_enter(&phyi->phyint_lock);
16728 16734                  /* XXX We need a recovery strategy here. */
16729 16735                  if (!phyint_assign_ifindex(phyi, ipst))
16730 16736                          cmn_err(CE_PANIC, "phyint_assign_ifindex() failed");
16731 16737  
16732 16738                  avl_insert(&ipst->ips_phyint_g_list->phyint_list_avl_by_name,
16733 16739                      (void *)phyi, where);
16734 16740  
16735 16741                  (void) avl_find(&ipst->ips_phyint_g_list->
16736 16742                      phyint_list_avl_by_index,
16737 16743                      &phyi->phyint_ifindex, &where);
16738 16744                  avl_insert(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
16739 16745                      (void *)phyi, where);
16740 16746          }
16741 16747  
16742 16748          /*
16743 16749           * Reassigning ill_phyint automatically reassigns the ipsq also.
16744 16750           * pending mp is not affected because that is per ill basis.
16745 16751           */
16746 16752          ill->ill_phyint = phyi;
16747 16753  
16748 16754          /*
16749 16755           * Now that the phyint's ifindex has been assigned, complete the
16750 16756           * remaining
16751 16757           */
16752 16758          ill->ill_ip_mib->ipIfStatsIfIndex = ill->ill_phyint->phyint_ifindex;
16753 16759          if (ill->ill_isv6) {
16754 16760                  ill->ill_icmp6_mib->ipv6IfIcmpIfIndex =
16755 16761                      ill->ill_phyint->phyint_ifindex;
16756 16762                  ill->ill_mcast_type = ipst->ips_mld_max_version;
16757 16763          } else {
16758 16764                  ill->ill_mcast_type = ipst->ips_igmp_max_version;
16759 16765          }
16760 16766  
16761 16767          /*
16762 16768           * Generate an event within the hooks framework to indicate that
16763 16769           * a new interface has just been added to IP.  For this event to
16764 16770           * be generated, the network interface must, at least, have an
16765 16771           * ifindex assigned to it.  (We don't generate the event for
16766 16772           * loopback since ill_lookup_on_name() has its own NE_PLUMB event.)
16767 16773           *
16768 16774           * This needs to be run inside the ill_g_lock perimeter to ensure
16769 16775           * that the ordering of delivered events to listeners matches the
16770 16776           * order of them in the kernel.
16771 16777           */
16772 16778          if (!IS_LOOPBACK(ill)) {
16773 16779                  ill_nic_event_dispatch(ill, 0, NE_PLUMB, ill->ill_name,
16774 16780                      ill->ill_name_length);
16775 16781          }
16776 16782          RELEASE_ILL_LOCKS(ill, ill_other);
16777 16783          mutex_exit(&phyi->phyint_lock);
16778 16784  }
16779 16785  
16780 16786  /*
16781 16787   * Notify any downstream modules of the name of this interface.
16782 16788   * An M_IOCTL is used even though we don't expect a successful reply.
16783 16789   * Any reply message from the driver (presumably an M_IOCNAK) will
16784 16790   * eventually get discarded somewhere upstream.  The message format is
16785 16791   * simply an SIOCSLIFNAME ioctl just as might be sent from ifconfig
16786 16792   * to IP.
16787 16793   */
16788 16794  static void
16789 16795  ip_ifname_notify(ill_t *ill, queue_t *q)
16790 16796  {
16791 16797          mblk_t *mp1, *mp2;
16792 16798          struct iocblk *iocp;
16793 16799          struct lifreq *lifr;
16794 16800  
16795 16801          mp1 = mkiocb(SIOCSLIFNAME);
16796 16802          if (mp1 == NULL)
16797 16803                  return;
16798 16804          mp2 = allocb(sizeof (struct lifreq), BPRI_HI);
16799 16805          if (mp2 == NULL) {
16800 16806                  freeb(mp1);
16801 16807                  return;
16802 16808          }
16803 16809  
16804 16810          mp1->b_cont = mp2;
16805 16811          iocp = (struct iocblk *)mp1->b_rptr;
16806 16812          iocp->ioc_count = sizeof (struct lifreq);
16807 16813  
16808 16814          lifr = (struct lifreq *)mp2->b_rptr;
16809 16815          mp2->b_wptr += sizeof (struct lifreq);
16810 16816          bzero(lifr, sizeof (struct lifreq));
16811 16817  
16812 16818          (void) strncpy(lifr->lifr_name, ill->ill_name, LIFNAMSIZ);
16813 16819          lifr->lifr_ppa = ill->ill_ppa;
16814 16820          lifr->lifr_flags = (ill->ill_flags & (ILLF_IPV4|ILLF_IPV6));
16815 16821  
16816 16822          DTRACE_PROBE3(ill__dlpi, char *, "ip_ifname_notify",
16817 16823              char *, "SIOCSLIFNAME", ill_t *, ill);
16818 16824          putnext(q, mp1);
16819 16825  }
16820 16826  
16821 16827  static int
16822 16828  ipif_set_values_tail(ill_t *ill, ipif_t *ipif, mblk_t *mp, queue_t *q)
16823 16829  {
16824 16830          int             err;
16825 16831          ip_stack_t      *ipst = ill->ill_ipst;
16826 16832          phyint_t        *phyi = ill->ill_phyint;
16827 16833  
16828 16834          /*
16829 16835           * Now that ill_name is set, the configuration for the IPMP
16830 16836           * meta-interface can be performed.
16831 16837           */
16832 16838          if (IS_IPMP(ill)) {
16833 16839                  rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
16834 16840                  /*
16835 16841                   * If phyi->phyint_grp is NULL, then this is the first IPMP
16836 16842                   * meta-interface and we need to create the IPMP group.
16837 16843                   */
16838 16844                  if (phyi->phyint_grp == NULL) {
16839 16845                          /*
16840 16846                           * If someone has renamed another IPMP group to have
16841 16847                           * the same name as our interface, bail.
16842 16848                           */
16843 16849                          if (ipmp_grp_lookup(ill->ill_name, ipst) != NULL) {
16844 16850                                  rw_exit(&ipst->ips_ipmp_lock);
16845 16851                                  return (EEXIST);
16846 16852                          }
16847 16853                          phyi->phyint_grp = ipmp_grp_create(ill->ill_name, phyi);
16848 16854                          if (phyi->phyint_grp == NULL) {
16849 16855                                  rw_exit(&ipst->ips_ipmp_lock);
16850 16856                                  return (ENOMEM);
16851 16857                          }
16852 16858                  }
16853 16859                  rw_exit(&ipst->ips_ipmp_lock);
16854 16860          }
16855 16861  
16856 16862          /* Tell downstream modules where they are. */
16857 16863          ip_ifname_notify(ill, q);
16858 16864  
16859 16865          /*
16860 16866           * ill_dl_phys returns EINPROGRESS in the usual case.
16861 16867           * Error cases are ENOMEM ...
16862 16868           */
16863 16869          err = ill_dl_phys(ill, ipif, mp, q);
16864 16870  
16865 16871          if (ill->ill_isv6) {
16866 16872                  mutex_enter(&ipst->ips_mld_slowtimeout_lock);
16867 16873                  if (ipst->ips_mld_slowtimeout_id == 0) {
16868 16874                          ipst->ips_mld_slowtimeout_id = timeout(mld_slowtimo,
16869 16875                              (void *)ipst,
16870 16876                              MSEC_TO_TICK(MCAST_SLOWTIMO_INTERVAL));
16871 16877                  }
16872 16878                  mutex_exit(&ipst->ips_mld_slowtimeout_lock);
16873 16879          } else {
16874 16880                  mutex_enter(&ipst->ips_igmp_slowtimeout_lock);
16875 16881                  if (ipst->ips_igmp_slowtimeout_id == 0) {
16876 16882                          ipst->ips_igmp_slowtimeout_id = timeout(igmp_slowtimo,
16877 16883                              (void *)ipst,
16878 16884                              MSEC_TO_TICK(MCAST_SLOWTIMO_INTERVAL));
16879 16885                  }
16880 16886                  mutex_exit(&ipst->ips_igmp_slowtimeout_lock);
16881 16887          }
16882 16888  
16883 16889          return (err);
16884 16890  }
16885 16891  
16886 16892  /*
16887 16893   * Common routine for ppa and ifname setting. Should be called exclusive.
16888 16894   *
16889 16895   * Returns EINPROGRESS when mp has been consumed by queueing it on
16890 16896   * ipx_pending_mp and the ioctl will complete in ip_rput.
16891 16897   *
16892 16898   * NOTE : If ppa is UNIT_MAX, we assign the next valid ppa and return
16893 16899   * the new name and new ppa in lifr_name and lifr_ppa respectively.
16894 16900   * For SLIFNAME, we pass these values back to the userland.
16895 16901   */
16896 16902  static int
16897 16903  ipif_set_values(queue_t *q, mblk_t *mp, char *interf_name, uint_t *new_ppa_ptr)
16898 16904  {
16899 16905          ill_t   *ill;
16900 16906          ipif_t  *ipif;
16901 16907          ipsq_t  *ipsq;
16902 16908          char    *ppa_ptr;
16903 16909          char    *old_ptr;
16904 16910          char    old_char;
16905 16911          int     error;
16906 16912          ip_stack_t      *ipst;
16907 16913  
16908 16914          ip1dbg(("ipif_set_values: interface %s\n", interf_name));
16909 16915          ASSERT(q->q_next != NULL);
16910 16916          ASSERT(interf_name != NULL);
16911 16917  
16912 16918          ill = (ill_t *)q->q_ptr;
16913 16919          ipst = ill->ill_ipst;
16914 16920  
16915 16921          ASSERT(ill->ill_ipst != NULL);
16916 16922          ASSERT(ill->ill_name[0] == '\0');
16917 16923          ASSERT(IAM_WRITER_ILL(ill));
16918 16924          ASSERT((mi_strlen(interf_name) + 1) <= LIFNAMSIZ);
16919 16925          ASSERT(ill->ill_ppa == UINT_MAX);
16920 16926  
16921 16927          ill->ill_defend_start = ill->ill_defend_count = 0;
16922 16928          /* The ppa is sent down by ifconfig or is chosen */
16923 16929          if ((ppa_ptr = ill_get_ppa_ptr(interf_name)) == NULL) {
16924 16930                  return (EINVAL);
16925 16931          }
16926 16932  
16927 16933          /*
16928 16934           * make sure ppa passed in is same as ppa in the name.
16929 16935           * This check is not made when ppa == UINT_MAX in that case ppa
16930 16936           * in the name could be anything. System will choose a ppa and
16931 16937           * update new_ppa_ptr and inter_name to contain the choosen ppa.
16932 16938           */
16933 16939          if (*new_ppa_ptr != UINT_MAX) {
16934 16940                  /* stoi changes the pointer */
16935 16941                  old_ptr = ppa_ptr;
16936 16942                  /*
16937 16943                   * ifconfig passed in 0 for the ppa for DLPI 1 style devices
16938 16944                   * (they don't have an externally visible ppa).  We assign one
16939 16945                   * here so that we can manage the interface.  Note that in
16940 16946                   * the past this value was always 0 for DLPI 1 drivers.
16941 16947                   */
16942 16948                  if (*new_ppa_ptr == 0)
16943 16949                          *new_ppa_ptr = stoi(&old_ptr);
16944 16950                  else if (*new_ppa_ptr != (uint_t)stoi(&old_ptr))
16945 16951                          return (EINVAL);
16946 16952          }
16947 16953          /*
16948 16954           * terminate string before ppa
16949 16955           * save char at that location.
16950 16956           */
16951 16957          old_char = ppa_ptr[0];
16952 16958          ppa_ptr[0] = '\0';
16953 16959  
16954 16960          ill->ill_ppa = *new_ppa_ptr;
16955 16961          /*
16956 16962           * Finish as much work now as possible before calling ill_glist_insert
16957 16963           * which makes the ill globally visible and also merges it with the
16958 16964           * other protocol instance of this phyint. The remaining work is
16959 16965           * done after entering the ipsq which may happen sometime later.
16960 16966           */
16961 16967          ipif = ill->ill_ipif;
16962 16968  
16963 16969          /* We didn't do this when we allocated ipif in ip_ll_subnet_defaults */
16964 16970          ipif_assign_seqid(ipif);
16965 16971  
16966 16972          if (!(ill->ill_flags & (ILLF_IPV4|ILLF_IPV6)))
16967 16973                  ill->ill_flags |= ILLF_IPV4;
16968 16974  
16969 16975          ASSERT(ipif->ipif_next == NULL);        /* Only one ipif on ill */
16970 16976          ASSERT((ipif->ipif_flags & IPIF_UP) == 0);
16971 16977  
16972 16978          if (ill->ill_flags & ILLF_IPV6) {
16973 16979  
16974 16980                  ill->ill_isv6 = B_TRUE;
16975 16981                  ill_set_inputfn(ill);
16976 16982                  if (ill->ill_rq != NULL) {
16977 16983                          ill->ill_rq->q_qinfo = &iprinitv6;
16978 16984                  }
16979 16985  
16980 16986                  /* Keep the !IN6_IS_ADDR_V4MAPPED assertions happy */
16981 16987                  ipif->ipif_v6lcl_addr = ipv6_all_zeros;
16982 16988                  ipif->ipif_v6subnet = ipv6_all_zeros;
16983 16989                  ipif->ipif_v6net_mask = ipv6_all_zeros;
16984 16990                  ipif->ipif_v6brd_addr = ipv6_all_zeros;
16985 16991                  ipif->ipif_v6pp_dst_addr = ipv6_all_zeros;
16986 16992                  ill->ill_reachable_retrans_time = ND_RETRANS_TIMER;
16987 16993                  /*
16988 16994                   * point-to-point or Non-mulicast capable
16989 16995                   * interfaces won't do NUD unless explicitly
16990 16996                   * configured to do so.
16991 16997                   */
16992 16998                  if (ipif->ipif_flags & IPIF_POINTOPOINT ||
16993 16999                      !(ill->ill_flags & ILLF_MULTICAST)) {
16994 17000                          ill->ill_flags |= ILLF_NONUD;
16995 17001                  }
16996 17002                  /* Make sure IPv4 specific flag is not set on IPv6 if */
16997 17003                  if (ill->ill_flags & ILLF_NOARP) {
16998 17004                          /*
16999 17005                           * Note: xresolv interfaces will eventually need
17000 17006                           * NOARP set here as well, but that will require
17001 17007                           * those external resolvers to have some
17002 17008                           * knowledge of that flag and act appropriately.
17003 17009                           * Not to be changed at present.
17004 17010                           */
17005 17011                          ill->ill_flags &= ~ILLF_NOARP;
17006 17012                  }
17007 17013                  /*
17008 17014                   * Set the ILLF_ROUTER flag according to the global
17009 17015                   * IPv6 forwarding policy.
17010 17016                   */
17011 17017                  if (ipst->ips_ipv6_forwarding != 0)
17012 17018                          ill->ill_flags |= ILLF_ROUTER;
17013 17019          } else if (ill->ill_flags & ILLF_IPV4) {
17014 17020                  ill->ill_isv6 = B_FALSE;
17015 17021                  ill_set_inputfn(ill);
17016 17022                  ill->ill_reachable_retrans_time = ARP_RETRANS_TIMER;
17017 17023                  IN6_IPADDR_TO_V4MAPPED(INADDR_ANY, &ipif->ipif_v6lcl_addr);
17018 17024                  IN6_IPADDR_TO_V4MAPPED(INADDR_ANY, &ipif->ipif_v6subnet);
17019 17025                  IN6_IPADDR_TO_V4MAPPED(INADDR_ANY, &ipif->ipif_v6net_mask);
17020 17026                  IN6_IPADDR_TO_V4MAPPED(INADDR_ANY, &ipif->ipif_v6brd_addr);
17021 17027                  IN6_IPADDR_TO_V4MAPPED(INADDR_ANY, &ipif->ipif_v6pp_dst_addr);
17022 17028                  /*
17023 17029                   * Set the ILLF_ROUTER flag according to the global
17024 17030                   * IPv4 forwarding policy.
17025 17031                   */
17026 17032                  if (ipst->ips_ip_forwarding != 0)
17027 17033                          ill->ill_flags |= ILLF_ROUTER;
17028 17034          }
17029 17035  
17030 17036          ASSERT(ill->ill_phyint != NULL);
17031 17037  
17032 17038          /*
17033 17039           * The ipIfStatsIfindex and ipv6IfIcmpIfIndex assignments will
17034 17040           * be completed in ill_glist_insert -> ill_phyint_reinit
17035 17041           */
17036 17042          if (!ill_allocate_mibs(ill))
17037 17043                  return (ENOMEM);
17038 17044  
17039 17045          /*
17040 17046           * Pick a default sap until we get the DL_INFO_ACK back from
17041 17047           * the driver.
17042 17048           */
17043 17049          ill->ill_sap = (ill->ill_isv6) ? ill->ill_media->ip_m_ipv6sap :
17044 17050              ill->ill_media->ip_m_ipv4sap;
17045 17051  
17046 17052          ill->ill_ifname_pending = 1;
17047 17053          ill->ill_ifname_pending_err = 0;
17048 17054  
17049 17055          /*
17050 17056           * When the first ipif comes up in ipif_up_done(), multicast groups
17051 17057           * that were joined while this ill was not bound to the DLPI link need
17052 17058           * to be recovered by ill_recover_multicast().
17053 17059           */
17054 17060          ill->ill_need_recover_multicast = 1;
17055 17061  
17056 17062          ill_refhold(ill);
17057 17063          rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
17058 17064          if ((error = ill_glist_insert(ill, interf_name,
17059 17065              (ill->ill_flags & ILLF_IPV6) == ILLF_IPV6)) > 0) {
17060 17066                  ill->ill_ppa = UINT_MAX;
17061 17067                  ill->ill_name[0] = '\0';
17062 17068                  /*
17063 17069                   * undo null termination done above.
17064 17070                   */
17065 17071                  ppa_ptr[0] = old_char;
17066 17072                  rw_exit(&ipst->ips_ill_g_lock);
17067 17073                  ill_refrele(ill);
17068 17074                  return (error);
17069 17075          }
17070 17076  
17071 17077          ASSERT(ill->ill_name_length <= LIFNAMSIZ);
17072 17078  
17073 17079          /*
17074 17080           * When we return the buffer pointed to by interf_name should contain
17075 17081           * the same name as in ill_name.
17076 17082           * If a ppa was choosen by the system (ppa passed in was UINT_MAX)
17077 17083           * the buffer pointed to by new_ppa_ptr would not contain the right ppa
17078 17084           * so copy full name and update the ppa ptr.
17079 17085           * When ppa passed in != UINT_MAX all values are correct just undo
17080 17086           * null termination, this saves a bcopy.
17081 17087           */
17082 17088          if (*new_ppa_ptr == UINT_MAX) {
17083 17089                  bcopy(ill->ill_name, interf_name, ill->ill_name_length);
17084 17090                  *new_ppa_ptr = ill->ill_ppa;
17085 17091          } else {
17086 17092                  /*
17087 17093                   * undo null termination done above.
17088 17094                   */
17089 17095                  ppa_ptr[0] = old_char;
17090 17096          }
17091 17097  
17092 17098          /* Let SCTP know about this ILL */
17093 17099          sctp_update_ill(ill, SCTP_ILL_INSERT);
17094 17100  
17095 17101          /*
17096 17102           * ill_glist_insert has made the ill visible globally, and
17097 17103           * ill_phyint_reinit could have changed the ipsq. At this point,
17098 17104           * we need to hold the ips_ill_g_lock across the call to enter the
17099 17105           * ipsq to enforce atomicity and prevent reordering. In the event
17100 17106           * the ipsq has changed, and if the new ipsq is currently busy,
17101 17107           * we need to make sure that this half-completed ioctl is ahead of
17102 17108           * any subsequent ioctl. We achieve this by not dropping the
17103 17109           * ips_ill_g_lock which prevents any ill lookup itself thereby
17104 17110           * ensuring that new ioctls can't start.
17105 17111           */
17106 17112          ipsq = ipsq_try_enter_internal(ill, q, mp, ip_reprocess_ioctl, NEW_OP,
17107 17113              B_TRUE);
17108 17114  
17109 17115          rw_exit(&ipst->ips_ill_g_lock);
17110 17116          ill_refrele(ill);
17111 17117          if (ipsq == NULL)
17112 17118                  return (EINPROGRESS);
17113 17119  
17114 17120          /*
17115 17121           * If ill_phyint_reinit() changed our ipsq, then start on the new ipsq.
17116 17122           */
17117 17123          if (ipsq->ipsq_xop->ipx_current_ipif == NULL)
17118 17124                  ipsq_current_start(ipsq, ipif, SIOCSLIFNAME);
17119 17125          else
17120 17126                  ASSERT(ipsq->ipsq_xop->ipx_current_ipif == ipif);
17121 17127  
17122 17128          error = ipif_set_values_tail(ill, ipif, mp, q);
17123 17129          ipsq_exit(ipsq);
17124 17130          if (error != 0 && error != EINPROGRESS) {
17125 17131                  /*
17126 17132                   * restore previous values
17127 17133                   */
17128 17134                  ill->ill_isv6 = B_FALSE;
17129 17135                  ill_set_inputfn(ill);
17130 17136          }
17131 17137          return (error);
17132 17138  }
17133 17139  
17134 17140  void
17135 17141  ipif_init(ip_stack_t *ipst)
17136 17142  {
17137 17143          int i;
17138 17144  
17139 17145          for (i = 0; i < MAX_G_HEADS; i++) {
17140 17146                  ipst->ips_ill_g_heads[i].ill_g_list_head =
17141 17147                      (ill_if_t *)&ipst->ips_ill_g_heads[i];
17142 17148                  ipst->ips_ill_g_heads[i].ill_g_list_tail =
17143 17149                      (ill_if_t *)&ipst->ips_ill_g_heads[i];
17144 17150          }
17145 17151  
17146 17152          avl_create(&ipst->ips_phyint_g_list->phyint_list_avl_by_index,
17147 17153              ill_phyint_compare_index,
17148 17154              sizeof (phyint_t),
17149 17155              offsetof(struct phyint, phyint_avl_by_index));
17150 17156          avl_create(&ipst->ips_phyint_g_list->phyint_list_avl_by_name,
17151 17157              ill_phyint_compare_name,
17152 17158              sizeof (phyint_t),
17153 17159              offsetof(struct phyint, phyint_avl_by_name));
17154 17160  }
17155 17161  
17156 17162  /*
17157 17163   * Save enough information so that we can recreate the IRE if
17158 17164   * the interface goes down and then up.
17159 17165   */
17160 17166  void
17161 17167  ill_save_ire(ill_t *ill, ire_t *ire)
17162 17168  {
17163 17169          mblk_t  *save_mp;
17164 17170  
17165 17171          save_mp = allocb(sizeof (ifrt_t), BPRI_MED);
17166 17172          if (save_mp != NULL) {
17167 17173                  ifrt_t  *ifrt;
17168 17174  
17169 17175                  save_mp->b_wptr += sizeof (ifrt_t);
17170 17176                  ifrt = (ifrt_t *)save_mp->b_rptr;
17171 17177                  bzero(ifrt, sizeof (ifrt_t));
17172 17178                  ifrt->ifrt_type = ire->ire_type;
17173 17179                  if (ire->ire_ipversion == IPV4_VERSION) {
17174 17180                          ASSERT(!ill->ill_isv6);
17175 17181                          ifrt->ifrt_addr = ire->ire_addr;
17176 17182                          ifrt->ifrt_gateway_addr = ire->ire_gateway_addr;
17177 17183                          ifrt->ifrt_setsrc_addr = ire->ire_setsrc_addr;
17178 17184                          ifrt->ifrt_mask = ire->ire_mask;
17179 17185                  } else {
17180 17186                          ASSERT(ill->ill_isv6);
17181 17187                          ifrt->ifrt_v6addr = ire->ire_addr_v6;
17182 17188                          /* ire_gateway_addr_v6 can change due to RTM_CHANGE */
17183 17189                          mutex_enter(&ire->ire_lock);
17184 17190                          ifrt->ifrt_v6gateway_addr = ire->ire_gateway_addr_v6;
17185 17191                          mutex_exit(&ire->ire_lock);
17186 17192                          ifrt->ifrt_v6setsrc_addr = ire->ire_setsrc_addr_v6;
17187 17193                          ifrt->ifrt_v6mask = ire->ire_mask_v6;
17188 17194                  }
17189 17195                  ifrt->ifrt_flags = ire->ire_flags;
17190 17196                  ifrt->ifrt_zoneid = ire->ire_zoneid;
17191 17197                  mutex_enter(&ill->ill_saved_ire_lock);
17192 17198                  save_mp->b_cont = ill->ill_saved_ire_mp;
17193 17199                  ill->ill_saved_ire_mp = save_mp;
17194 17200                  ill->ill_saved_ire_cnt++;
17195 17201                  mutex_exit(&ill->ill_saved_ire_lock);
17196 17202          }
17197 17203  }
17198 17204  
17199 17205  /*
17200 17206   * Remove one entry from ill_saved_ire_mp.
17201 17207   */
17202 17208  void
17203 17209  ill_remove_saved_ire(ill_t *ill, ire_t *ire)
17204 17210  {
17205 17211          mblk_t  **mpp;
17206 17212          mblk_t  *mp;
17207 17213          ifrt_t  *ifrt;
17208 17214  
17209 17215          /* Remove from ill_saved_ire_mp list if it is there */
17210 17216          mutex_enter(&ill->ill_saved_ire_lock);
17211 17217          for (mpp = &ill->ill_saved_ire_mp; *mpp != NULL;
17212 17218              mpp = &(*mpp)->b_cont) {
17213 17219                  in6_addr_t      gw_addr_v6;
17214 17220  
17215 17221                  /*
17216 17222                   * On a given ill, the tuple of address, gateway, mask,
17217 17223                   * ire_type, and zoneid is unique for each saved IRE.
17218 17224                   */
17219 17225                  mp = *mpp;
17220 17226                  ifrt = (ifrt_t *)mp->b_rptr;
17221 17227                  /* ire_gateway_addr_v6 can change - need lock */
17222 17228                  mutex_enter(&ire->ire_lock);
17223 17229                  gw_addr_v6 = ire->ire_gateway_addr_v6;
17224 17230                  mutex_exit(&ire->ire_lock);
17225 17231  
17226 17232                  if (ifrt->ifrt_zoneid != ire->ire_zoneid ||
17227 17233                      ifrt->ifrt_type != ire->ire_type)
17228 17234                          continue;
17229 17235  
17230 17236                  if (ill->ill_isv6 ?
17231 17237                      (IN6_ARE_ADDR_EQUAL(&ifrt->ifrt_v6addr,
17232 17238                      &ire->ire_addr_v6) &&
17233 17239                      IN6_ARE_ADDR_EQUAL(&ifrt->ifrt_v6gateway_addr,
17234 17240                      &gw_addr_v6) &&
17235 17241                      IN6_ARE_ADDR_EQUAL(&ifrt->ifrt_v6mask,
17236 17242                      &ire->ire_mask_v6)) :
17237 17243                      (ifrt->ifrt_addr == ire->ire_addr &&
17238 17244                      ifrt->ifrt_gateway_addr == ire->ire_gateway_addr &&
17239 17245                      ifrt->ifrt_mask == ire->ire_mask)) {
17240 17246                          *mpp = mp->b_cont;
17241 17247                          ill->ill_saved_ire_cnt--;
17242 17248                          freeb(mp);
17243 17249                          break;
17244 17250                  }
17245 17251          }
17246 17252          mutex_exit(&ill->ill_saved_ire_lock);
17247 17253  }
17248 17254  
17249 17255  /*
17250 17256   * IP multirouting broadcast routes handling
17251 17257   * Append CGTP broadcast IREs to regular ones created
17252 17258   * at ifconfig time.
17253 17259   * The usage is a route add <cgtp_bc> <nic_bc> -multirt i.e., both
17254 17260   * the destination and the gateway are broadcast addresses.
17255 17261   * The caller has verified that the destination is an IRE_BROADCAST and that
17256 17262   * RTF_MULTIRT was set. Here if the gateway is a broadcast address, then
17257 17263   * we create a MULTIRT IRE_BROADCAST.
17258 17264   * Note that the IRE_HOST created by ire_rt_add doesn't get found by anything
17259 17265   * since the IRE_BROADCAST takes precedence; ire_add_v4 does head insertion.
17260 17266   */
17261 17267  static void
17262 17268  ip_cgtp_bcast_add(ire_t *ire, ip_stack_t *ipst)
17263 17269  {
17264 17270          ire_t *ire_prim;
17265 17271  
17266 17272          ASSERT(ire != NULL);
17267 17273  
17268 17274          ire_prim = ire_ftable_lookup_v4(ire->ire_gateway_addr, 0, 0,
17269 17275              IRE_BROADCAST, NULL, ALL_ZONES, NULL, MATCH_IRE_TYPE, 0, ipst,
17270 17276              NULL);
17271 17277          if (ire_prim != NULL) {
17272 17278                  /*
17273 17279                   * We are in the special case of broadcasts for
17274 17280                   * CGTP. We add an IRE_BROADCAST that holds
17275 17281                   * the RTF_MULTIRT flag, the destination
17276 17282                   * address and the low level
17277 17283                   * info of ire_prim. In other words, CGTP
17278 17284                   * broadcast is added to the redundant ipif.
17279 17285                   */
17280 17286                  ill_t *ill_prim;
17281 17287                  ire_t  *bcast_ire;
17282 17288  
17283 17289                  ill_prim = ire_prim->ire_ill;
17284 17290  
17285 17291                  ip2dbg(("ip_cgtp_filter_bcast_add: ire_prim %p, ill_prim %p\n",
17286 17292                      (void *)ire_prim, (void *)ill_prim));
17287 17293  
17288 17294                  bcast_ire = ire_create(
17289 17295                      (uchar_t *)&ire->ire_addr,
17290 17296                      (uchar_t *)&ip_g_all_ones,
17291 17297                      (uchar_t *)&ire->ire_gateway_addr,
17292 17298                      IRE_BROADCAST,
17293 17299                      ill_prim,
17294 17300                      GLOBAL_ZONEID,      /* CGTP is only for the global zone */
17295 17301                      ire->ire_flags | RTF_KERNEL,
17296 17302                      NULL,
17297 17303                      ipst);
17298 17304  
17299 17305                  /*
17300 17306                   * Here we assume that ire_add does head insertion so that
17301 17307                   * the added IRE_BROADCAST comes before the existing IRE_HOST.
17302 17308                   */
17303 17309                  if (bcast_ire != NULL) {
17304 17310                          if (ire->ire_flags & RTF_SETSRC) {
17305 17311                                  bcast_ire->ire_setsrc_addr =
17306 17312                                      ire->ire_setsrc_addr;
17307 17313                          }
17308 17314                          bcast_ire = ire_add(bcast_ire);
17309 17315                          if (bcast_ire != NULL) {
17310 17316                                  ip2dbg(("ip_cgtp_filter_bcast_add: "
17311 17317                                      "added bcast_ire %p\n",
17312 17318                                      (void *)bcast_ire));
17313 17319  
17314 17320                                  ill_save_ire(ill_prim, bcast_ire);
17315 17321                                  ire_refrele(bcast_ire);
17316 17322                          }
17317 17323                  }
17318 17324                  ire_refrele(ire_prim);
17319 17325          }
17320 17326  }
17321 17327  
17322 17328  /*
17323 17329   * IP multirouting broadcast routes handling
17324 17330   * Remove the broadcast ire.
17325 17331   * The usage is a route delete <cgtp_bc> <nic_bc> -multirt i.e., both
17326 17332   * the destination and the gateway are broadcast addresses.
17327 17333   * The caller has only verified that RTF_MULTIRT was set. We check
17328 17334   * that the destination is broadcast and that the gateway is a broadcast
17329 17335   * address, and if so delete the IRE added by ip_cgtp_bcast_add().
17330 17336   */
17331 17337  static void
17332 17338  ip_cgtp_bcast_delete(ire_t *ire, ip_stack_t *ipst)
17333 17339  {
17334 17340          ASSERT(ire != NULL);
17335 17341  
17336 17342          if (ip_type_v4(ire->ire_addr, ipst) == IRE_BROADCAST) {
17337 17343                  ire_t *ire_prim;
17338 17344  
17339 17345                  ire_prim = ire_ftable_lookup_v4(ire->ire_gateway_addr, 0, 0,
17340 17346                      IRE_BROADCAST, NULL, ALL_ZONES, NULL, MATCH_IRE_TYPE, 0,
17341 17347                      ipst, NULL);
17342 17348                  if (ire_prim != NULL) {
17343 17349                          ill_t *ill_prim;
17344 17350                          ire_t  *bcast_ire;
17345 17351  
17346 17352                          ill_prim = ire_prim->ire_ill;
17347 17353  
17348 17354                          ip2dbg(("ip_cgtp_filter_bcast_delete: "
17349 17355                              "ire_prim %p, ill_prim %p\n",
17350 17356                              (void *)ire_prim, (void *)ill_prim));
17351 17357  
17352 17358                          bcast_ire = ire_ftable_lookup_v4(ire->ire_addr, 0,
17353 17359                              ire->ire_gateway_addr, IRE_BROADCAST,
17354 17360                              ill_prim, ALL_ZONES, NULL,
17355 17361                              MATCH_IRE_TYPE | MATCH_IRE_GW | MATCH_IRE_ILL |
17356 17362                              MATCH_IRE_MASK, 0, ipst, NULL);
17357 17363  
17358 17364                          if (bcast_ire != NULL) {
17359 17365                                  ip2dbg(("ip_cgtp_filter_bcast_delete: "
17360 17366                                      "looked up bcast_ire %p\n",
17361 17367                                      (void *)bcast_ire));
17362 17368                                  ill_remove_saved_ire(bcast_ire->ire_ill,
17363 17369                                      bcast_ire);
17364 17370                                  ire_delete(bcast_ire);
17365 17371                                  ire_refrele(bcast_ire);
17366 17372                          }
17367 17373                          ire_refrele(ire_prim);
17368 17374                  }
17369 17375          }
17370 17376  }
17371 17377  
17372 17378  /*
17373 17379   * Derive an interface id from the link layer address.
17374 17380   * Knows about IEEE 802 and IEEE EUI-64 mappings.
17375 17381   */
17376 17382  static void
17377 17383  ip_ether_v6intfid(ill_t *ill, in6_addr_t *v6addr)
17378 17384  {
17379 17385          char            *addr;
17380 17386  
17381 17387          /*
17382 17388           * Note that some IPv6 interfaces get plumbed over links that claim to
17383 17389           * be DL_ETHER, but don't actually have Ethernet MAC addresses (e.g.
17384 17390           * PPP links).  The ETHERADDRL check here ensures that we only set the
17385 17391           * interface ID on IPv6 interfaces above links that actually have real
17386 17392           * Ethernet addresses.
17387 17393           */
17388 17394          if (ill->ill_phys_addr_length == ETHERADDRL) {
17389 17395                  /* Form EUI-64 like address */
17390 17396                  addr = (char *)&v6addr->s6_addr32[2];
17391 17397                  bcopy(ill->ill_phys_addr, addr, 3);
17392 17398                  addr[0] ^= 0x2;         /* Toggle Universal/Local bit */
17393 17399                  addr[3] = (char)0xff;
17394 17400                  addr[4] = (char)0xfe;
17395 17401                  bcopy(ill->ill_phys_addr + 3, addr + 5, 3);
17396 17402          }
17397 17403  }
17398 17404  
17399 17405  /* ARGSUSED */
17400 17406  static void
17401 17407  ip_nodef_v6intfid(ill_t *ill, in6_addr_t *v6addr)
17402 17408  {
17403 17409  }
17404 17410  
17405 17411  typedef struct ipmp_ifcookie {
17406 17412          uint32_t        ic_hostid;
17407 17413          char            ic_ifname[LIFNAMSIZ];
17408 17414          char            ic_zonename[ZONENAME_MAX];
17409 17415  } ipmp_ifcookie_t;
17410 17416  
17411 17417  /*
17412 17418   * Construct a pseudo-random interface ID for the IPMP interface that's both
17413 17419   * predictable and (almost) guaranteed to be unique.
17414 17420   */
17415 17421  static void
17416 17422  ip_ipmp_v6intfid(ill_t *ill, in6_addr_t *v6addr)
17417 17423  {
17418 17424          zone_t          *zp;
17419 17425          uint8_t         *addr;
17420 17426          uchar_t         hash[16];
17421 17427          ulong_t         hostid;
17422 17428          MD5_CTX         ctx;
17423 17429          ipmp_ifcookie_t ic = { 0 };
17424 17430  
17425 17431          ASSERT(IS_IPMP(ill));
17426 17432  
17427 17433          (void) ddi_strtoul(hw_serial, NULL, 10, &hostid);
17428 17434          ic.ic_hostid = htonl((uint32_t)hostid);
17429 17435  
17430 17436          (void) strlcpy(ic.ic_ifname, ill->ill_name, LIFNAMSIZ);
17431 17437  
17432 17438          if ((zp = zone_find_by_id(ill->ill_zoneid)) != NULL) {
17433 17439                  (void) strlcpy(ic.ic_zonename, zp->zone_name, ZONENAME_MAX);
17434 17440                  zone_rele(zp);
17435 17441          }
17436 17442  
17437 17443          MD5Init(&ctx);
17438 17444          MD5Update(&ctx, &ic, sizeof (ic));
17439 17445          MD5Final(hash, &ctx);
17440 17446  
17441 17447          /*
17442 17448           * Map the hash to an interface ID per the basic approach in RFC3041.
17443 17449           */
17444 17450          addr = &v6addr->s6_addr8[8];
17445 17451          bcopy(hash + 8, addr, sizeof (uint64_t));
17446 17452          addr[0] &= ~0x2;                                /* set local bit */
17447 17453  }
17448 17454  
17449 17455  /*
17450 17456   * Map the multicast in6_addr_t in m_ip6addr to the physaddr for ethernet.
17451 17457   */
17452 17458  static void
17453 17459  ip_ether_v6_mapping(ill_t *ill, uchar_t *m_ip6addr, uchar_t *m_physaddr)
17454 17460  {
17455 17461          phyint_t *phyi = ill->ill_phyint;
17456 17462  
17457 17463          /*
17458 17464           * Check PHYI_MULTI_BCAST and length of physical
17459 17465           * address to determine if we use the mapping or the
17460 17466           * broadcast address.
17461 17467           */
17462 17468          if ((phyi->phyint_flags & PHYI_MULTI_BCAST) != 0 ||
17463 17469              ill->ill_phys_addr_length != ETHERADDRL) {
17464 17470                  ip_mbcast_mapping(ill, m_ip6addr, m_physaddr);
17465 17471                  return;
17466 17472          }
17467 17473          m_physaddr[0] = 0x33;
17468 17474          m_physaddr[1] = 0x33;
17469 17475          m_physaddr[2] = m_ip6addr[12];
17470 17476          m_physaddr[3] = m_ip6addr[13];
17471 17477          m_physaddr[4] = m_ip6addr[14];
17472 17478          m_physaddr[5] = m_ip6addr[15];
17473 17479  }
17474 17480  
17475 17481  /*
17476 17482   * Map the multicast ipaddr_t in m_ipaddr to the physaddr for ethernet.
17477 17483   */
17478 17484  static void
17479 17485  ip_ether_v4_mapping(ill_t *ill, uchar_t *m_ipaddr, uchar_t *m_physaddr)
17480 17486  {
17481 17487          phyint_t *phyi = ill->ill_phyint;
17482 17488  
17483 17489          /*
17484 17490           * Check PHYI_MULTI_BCAST and length of physical
17485 17491           * address to determine if we use the mapping or the
17486 17492           * broadcast address.
17487 17493           */
17488 17494          if ((phyi->phyint_flags & PHYI_MULTI_BCAST) != 0 ||
17489 17495              ill->ill_phys_addr_length != ETHERADDRL) {
17490 17496                  ip_mbcast_mapping(ill, m_ipaddr, m_physaddr);
17491 17497                  return;
17492 17498          }
17493 17499          m_physaddr[0] = 0x01;
17494 17500          m_physaddr[1] = 0x00;
17495 17501          m_physaddr[2] = 0x5e;
17496 17502          m_physaddr[3] = m_ipaddr[1] & 0x7f;
17497 17503          m_physaddr[4] = m_ipaddr[2];
17498 17504          m_physaddr[5] = m_ipaddr[3];
17499 17505  }
17500 17506  
17501 17507  /* ARGSUSED */
17502 17508  static void
17503 17509  ip_mbcast_mapping(ill_t *ill, uchar_t *m_ipaddr, uchar_t *m_physaddr)
17504 17510  {
17505 17511          /*
17506 17512           * for the MULTI_BCAST case and other cases when we want to
17507 17513           * use the link-layer broadcast address for multicast.
17508 17514           */
17509 17515          uint8_t *bphys_addr;
17510 17516          dl_unitdata_req_t *dlur;
17511 17517  
17512 17518          dlur = (dl_unitdata_req_t *)ill->ill_bcast_mp->b_rptr;
17513 17519          if (ill->ill_sap_length < 0) {
17514 17520                  bphys_addr = (uchar_t *)dlur +
17515 17521                      dlur->dl_dest_addr_offset;
17516 17522          } else  {
17517 17523                  bphys_addr = (uchar_t *)dlur +
17518 17524                      dlur->dl_dest_addr_offset + ill->ill_sap_length;
17519 17525          }
17520 17526  
17521 17527          bcopy(bphys_addr, m_physaddr, ill->ill_phys_addr_length);
17522 17528  }
17523 17529  
17524 17530  /*
17525 17531   * Derive IPoIB interface id from the link layer address.
17526 17532   */
17527 17533  static void
17528 17534  ip_ib_v6intfid(ill_t *ill, in6_addr_t *v6addr)
17529 17535  {
17530 17536          char            *addr;
17531 17537  
17532 17538          ASSERT(ill->ill_phys_addr_length == 20);
17533 17539          addr = (char *)&v6addr->s6_addr32[2];
17534 17540          bcopy(ill->ill_phys_addr + 12, addr, 8);
17535 17541          /*
17536 17542           * In IBA 1.1 timeframe, some vendors erroneously set the u/l bit
17537 17543           * in the globally assigned EUI-64 GUID to 1, in violation of IEEE
17538 17544           * rules. In these cases, the IBA considers these GUIDs to be in
17539 17545           * "Modified EUI-64" format, and thus toggling the u/l bit is not
17540 17546           * required; vendors are required not to assign global EUI-64's
17541 17547           * that differ only in u/l bit values, thus guaranteeing uniqueness
17542 17548           * of the interface identifier. Whether the GUID is in modified
17543 17549           * or proper EUI-64 format, the ipv6 identifier must have the u/l
17544 17550           * bit set to 1.
17545 17551           */
17546 17552          addr[0] |= 2;                   /* Set Universal/Local bit to 1 */
17547 17553  }
17548 17554  
17549 17555  /*
17550 17556   * Map the multicast ipaddr_t in m_ipaddr to the physaddr for InfiniBand.
17551 17557   * Note on mapping from multicast IP addresses to IPoIB multicast link
17552 17558   * addresses. IPoIB multicast link addresses are based on IBA link addresses.
17553 17559   * The format of an IPoIB multicast address is:
17554 17560   *
17555 17561   *  4 byte QPN      Scope Sign.  Pkey
17556 17562   * +--------------------------------------------+
17557 17563   * | 00FFFFFF | FF | 1X | X01B | Pkey | GroupID |
17558 17564   * +--------------------------------------------+
17559 17565   *
17560 17566   * The Scope and Pkey components are properties of the IBA port and
17561 17567   * network interface. They can be ascertained from the broadcast address.
17562 17568   * The Sign. part is the signature, and is 401B for IPv4 and 601B for IPv6.
17563 17569   */
17564 17570  static void
17565 17571  ip_ib_v4_mapping(ill_t *ill, uchar_t *m_ipaddr, uchar_t *m_physaddr)
17566 17572  {
17567 17573          static uint8_t ipv4_g_phys_ibmulti_addr[] = { 0x00, 0xff, 0xff, 0xff,
17568 17574              0xff, 0x10, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
17569 17575              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
17570 17576          uint8_t *bphys_addr;
17571 17577          dl_unitdata_req_t *dlur;
17572 17578  
17573 17579          bcopy(ipv4_g_phys_ibmulti_addr, m_physaddr, ill->ill_phys_addr_length);
17574 17580  
17575 17581          /*
17576 17582           * RFC 4391: IPv4 MGID is 28-bit long.
17577 17583           */
17578 17584          m_physaddr[16] = m_ipaddr[0] & 0x0f;
17579 17585          m_physaddr[17] = m_ipaddr[1];
17580 17586          m_physaddr[18] = m_ipaddr[2];
17581 17587          m_physaddr[19] = m_ipaddr[3];
17582 17588  
17583 17589  
17584 17590          dlur = (dl_unitdata_req_t *)ill->ill_bcast_mp->b_rptr;
17585 17591          if (ill->ill_sap_length < 0) {
17586 17592                  bphys_addr = (uchar_t *)dlur + dlur->dl_dest_addr_offset;
17587 17593          } else  {
17588 17594                  bphys_addr = (uchar_t *)dlur + dlur->dl_dest_addr_offset +
17589 17595                      ill->ill_sap_length;
17590 17596          }
17591 17597          /*
17592 17598           * Now fill in the IBA scope/Pkey values from the broadcast address.
17593 17599           */
17594 17600          m_physaddr[5] = bphys_addr[5];
17595 17601          m_physaddr[8] = bphys_addr[8];
17596 17602          m_physaddr[9] = bphys_addr[9];
17597 17603  }
17598 17604  
17599 17605  static void
17600 17606  ip_ib_v6_mapping(ill_t *ill, uchar_t *m_ipaddr, uchar_t *m_physaddr)
17601 17607  {
17602 17608          static uint8_t ipv4_g_phys_ibmulti_addr[] = { 0x00, 0xff, 0xff, 0xff,
17603 17609              0xff, 0x10, 0x60, 0x1b, 0x00, 0x00, 0x00, 0x00,
17604 17610              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
17605 17611          uint8_t *bphys_addr;
17606 17612          dl_unitdata_req_t *dlur;
17607 17613  
17608 17614          bcopy(ipv4_g_phys_ibmulti_addr, m_physaddr, ill->ill_phys_addr_length);
17609 17615  
17610 17616          /*
17611 17617           * RFC 4391: IPv4 MGID is 80-bit long.
17612 17618           */
17613 17619          bcopy(&m_ipaddr[6], &m_physaddr[10], 10);
17614 17620  
17615 17621          dlur = (dl_unitdata_req_t *)ill->ill_bcast_mp->b_rptr;
17616 17622          if (ill->ill_sap_length < 0) {
17617 17623                  bphys_addr = (uchar_t *)dlur + dlur->dl_dest_addr_offset;
17618 17624          } else  {
17619 17625                  bphys_addr = (uchar_t *)dlur + dlur->dl_dest_addr_offset +
17620 17626                      ill->ill_sap_length;
17621 17627          }
17622 17628          /*
17623 17629           * Now fill in the IBA scope/Pkey values from the broadcast address.
17624 17630           */
17625 17631          m_physaddr[5] = bphys_addr[5];
17626 17632          m_physaddr[8] = bphys_addr[8];
17627 17633          m_physaddr[9] = bphys_addr[9];
17628 17634  }
17629 17635  
17630 17636  /*
17631 17637   * Derive IPv6 interface id from an IPv4 link-layer address (e.g. from an IPv4
17632 17638   * tunnel).  The IPv4 address simply get placed in the lower 4 bytes of the
17633 17639   * IPv6 interface id.  This is a suggested mechanism described in section 3.7
17634 17640   * of RFC4213.
17635 17641   */
17636 17642  static void
17637 17643  ip_ipv4_genv6intfid(ill_t *ill, uint8_t *physaddr, in6_addr_t *v6addr)
17638 17644  {
17639 17645          ASSERT(ill->ill_phys_addr_length == sizeof (ipaddr_t));
17640 17646          v6addr->s6_addr32[2] = 0;
17641 17647          bcopy(physaddr, &v6addr->s6_addr32[3], sizeof (ipaddr_t));
17642 17648  }
17643 17649  
17644 17650  /*
17645 17651   * Derive IPv6 interface id from an IPv6 link-layer address (e.g. from an IPv6
17646 17652   * tunnel).  The lower 8 bytes of the IPv6 address simply become the interface
17647 17653   * id.
17648 17654   */
17649 17655  static void
17650 17656  ip_ipv6_genv6intfid(ill_t *ill, uint8_t *physaddr, in6_addr_t *v6addr)
17651 17657  {
17652 17658          in6_addr_t *v6lladdr = (in6_addr_t *)physaddr;
17653 17659  
17654 17660          ASSERT(ill->ill_phys_addr_length == sizeof (in6_addr_t));
17655 17661          bcopy(&v6lladdr->s6_addr32[2], &v6addr->s6_addr32[2], 8);
17656 17662  }
17657 17663  
17658 17664  static void
17659 17665  ip_ipv6_v6intfid(ill_t *ill, in6_addr_t *v6addr)
17660 17666  {
17661 17667          ip_ipv6_genv6intfid(ill, ill->ill_phys_addr, v6addr);
17662 17668  }
17663 17669  
17664 17670  static void
17665 17671  ip_ipv6_v6destintfid(ill_t *ill, in6_addr_t *v6addr)
17666 17672  {
17667 17673          ip_ipv6_genv6intfid(ill, ill->ill_dest_addr, v6addr);
17668 17674  }
17669 17675  
17670 17676  static void
17671 17677  ip_ipv4_v6intfid(ill_t *ill, in6_addr_t *v6addr)
17672 17678  {
17673 17679          ip_ipv4_genv6intfid(ill, ill->ill_phys_addr, v6addr);
17674 17680  }
17675 17681  
17676 17682  static void
17677 17683  ip_ipv4_v6destintfid(ill_t *ill, in6_addr_t *v6addr)
17678 17684  {
17679 17685          ip_ipv4_genv6intfid(ill, ill->ill_dest_addr, v6addr);
17680 17686  }
17681 17687  
17682 17688  /*
17683 17689   * Lookup an ill and verify that the zoneid has an ipif on that ill.
17684 17690   * Returns an held ill, or NULL.
17685 17691   */
17686 17692  ill_t *
17687 17693  ill_lookup_on_ifindex_zoneid(uint_t index, zoneid_t zoneid, boolean_t isv6,
17688 17694      ip_stack_t *ipst)
17689 17695  {
17690 17696          ill_t   *ill;
17691 17697          ipif_t  *ipif;
17692 17698  
17693 17699          ill = ill_lookup_on_ifindex(index, isv6, ipst);
17694 17700          if (ill == NULL)
17695 17701                  return (NULL);
17696 17702  
17697 17703          mutex_enter(&ill->ill_lock);
17698 17704          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
17699 17705                  if (IPIF_IS_CONDEMNED(ipif))
17700 17706                          continue;
17701 17707                  if (zoneid != ALL_ZONES && ipif->ipif_zoneid != zoneid &&
17702 17708                      ipif->ipif_zoneid != ALL_ZONES)
17703 17709                          continue;
17704 17710  
17705 17711                  mutex_exit(&ill->ill_lock);
17706 17712                  return (ill);
17707 17713          }
17708 17714          mutex_exit(&ill->ill_lock);
17709 17715          ill_refrele(ill);
17710 17716          return (NULL);
17711 17717  }
17712 17718  
17713 17719  /*
17714 17720   * Return a pointer to an ipif_t given a combination of (ill_idx,ipif_id)
17715 17721   * If a pointer to an ipif_t is returned then the caller will need to do
17716 17722   * an ill_refrele().
17717 17723   */
17718 17724  ipif_t *
17719 17725  ipif_getby_indexes(uint_t ifindex, uint_t lifidx, boolean_t isv6,
17720 17726      ip_stack_t *ipst)
17721 17727  {
17722 17728          ipif_t *ipif;
17723 17729          ill_t *ill;
17724 17730  
17725 17731          ill = ill_lookup_on_ifindex(ifindex, isv6, ipst);
17726 17732          if (ill == NULL)
17727 17733                  return (NULL);
17728 17734  
17729 17735          mutex_enter(&ill->ill_lock);
17730 17736          if (ill->ill_state_flags & ILL_CONDEMNED) {
17731 17737                  mutex_exit(&ill->ill_lock);
17732 17738                  ill_refrele(ill);
17733 17739                  return (NULL);
17734 17740          }
17735 17741  
17736 17742          for (ipif = ill->ill_ipif; ipif != NULL; ipif = ipif->ipif_next) {
17737 17743                  if (!IPIF_CAN_LOOKUP(ipif))
17738 17744                          continue;
17739 17745                  if (lifidx == ipif->ipif_id) {
17740 17746                          ipif_refhold_locked(ipif);
17741 17747                          break;
17742 17748                  }
17743 17749          }
17744 17750  
17745 17751          mutex_exit(&ill->ill_lock);
17746 17752          ill_refrele(ill);
17747 17753          return (ipif);
17748 17754  }
17749 17755  
17750 17756  /*
17751 17757   * Set ill_inputfn based on the current know state.
17752 17758   * This needs to be called when any of the factors taken into
17753 17759   * account changes.
17754 17760   */
17755 17761  void
17756 17762  ill_set_inputfn(ill_t *ill)
17757 17763  {
17758 17764          ip_stack_t      *ipst = ill->ill_ipst;
17759 17765  
17760 17766          if (ill->ill_isv6) {
17761 17767                  if (is_system_labeled())
17762 17768                          ill->ill_inputfn = ill_input_full_v6;
17763 17769                  else
17764 17770                          ill->ill_inputfn = ill_input_short_v6;
17765 17771          } else {
17766 17772                  if (is_system_labeled())
17767 17773                          ill->ill_inputfn = ill_input_full_v4;
17768 17774                  else if (ill->ill_dhcpinit != 0)
17769 17775                          ill->ill_inputfn = ill_input_full_v4;
17770 17776                  else if (ipst->ips_ipcl_proto_fanout_v4[IPPROTO_RSVP].connf_head
17771 17777                      != NULL)
17772 17778                          ill->ill_inputfn = ill_input_full_v4;
17773 17779                  else if (ipst->ips_ip_cgtp_filter &&
17774 17780                      ipst->ips_ip_cgtp_filter_ops != NULL)
17775 17781                          ill->ill_inputfn = ill_input_full_v4;
17776 17782                  else
17777 17783                          ill->ill_inputfn = ill_input_short_v4;
17778 17784          }
17779 17785  }
17780 17786  
17781 17787  /*
17782 17788   * Re-evaluate ill_inputfn for all the IPv4 ills.
17783 17789   * Used when RSVP and CGTP comes and goes.
17784 17790   */
17785 17791  void
17786 17792  ill_set_inputfn_all(ip_stack_t *ipst)
17787 17793  {
17788 17794          ill_walk_context_t      ctx;
17789 17795          ill_t                   *ill;
17790 17796  
17791 17797          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
17792 17798          ill = ILL_START_WALK_V4(&ctx, ipst);
17793 17799          for (; ill != NULL; ill = ill_next(&ctx, ill))
17794 17800                  ill_set_inputfn(ill);
17795 17801  
17796 17802          rw_exit(&ipst->ips_ill_g_lock);
17797 17803  }
17798 17804  
17799 17805  /*
17800 17806   * Set the physical address information for `ill' to the contents of the
17801 17807   * dl_notify_ind_t pointed to by `mp'.  Must be called as writer, and will be
17802 17808   * asynchronous if `ill' cannot immediately be quiesced -- in which case
17803 17809   * EINPROGRESS will be returned.
17804 17810   */
17805 17811  int
17806 17812  ill_set_phys_addr(ill_t *ill, mblk_t *mp)
17807 17813  {
17808 17814          ipsq_t *ipsq = ill->ill_phyint->phyint_ipsq;
17809 17815          dl_notify_ind_t *dlindp = (dl_notify_ind_t *)mp->b_rptr;
17810 17816  
17811 17817          ASSERT(IAM_WRITER_IPSQ(ipsq));
17812 17818  
17813 17819          if (dlindp->dl_data != DL_IPV6_LINK_LAYER_ADDR &&
17814 17820              dlindp->dl_data != DL_CURR_DEST_ADDR &&
17815 17821              dlindp->dl_data != DL_CURR_PHYS_ADDR) {
17816 17822                  /* Changing DL_IPV6_TOKEN is not yet supported */
17817 17823                  return (0);
17818 17824          }
17819 17825  
17820 17826          /*
17821 17827           * We need to store up to two copies of `mp' in `ill'.  Due to the
17822 17828           * design of ipsq_pending_mp_add(), we can't pass them as separate
17823 17829           * arguments to ill_set_phys_addr_tail().  Instead, chain them
17824 17830           * together here, then pull 'em apart in ill_set_phys_addr_tail().
17825 17831           */
17826 17832          if ((mp = copyb(mp)) == NULL || (mp->b_cont = copyb(mp)) == NULL) {
17827 17833                  freemsg(mp);
17828 17834                  return (ENOMEM);
17829 17835          }
17830 17836  
17831 17837          ipsq_current_start(ipsq, ill->ill_ipif, 0);
17832 17838  
17833 17839          /*
17834 17840           * Since we'll only do a logical down, we can't rely on ipif_down
17835 17841           * to turn on ILL_DOWN_IN_PROGRESS, or for the DL_BIND_ACK to reset
17836 17842           * ILL_DOWN_IN_PROGRESS. We instead manage this separately for this
17837 17843           * case, to quiesce ire's and nce's for ill_is_quiescent.
17838 17844           */
17839 17845          mutex_enter(&ill->ill_lock);
17840 17846          ill->ill_state_flags |= ILL_DOWN_IN_PROGRESS;
17841 17847          /* no more ire/nce addition allowed */
17842 17848          mutex_exit(&ill->ill_lock);
17843 17849  
17844 17850          /*
17845 17851           * If we can quiesce the ill, then set the address.  If not, then
17846 17852           * ill_set_phys_addr_tail() will be called from ipif_ill_refrele_tail().
17847 17853           */
17848 17854          ill_down_ipifs(ill, B_TRUE);
17849 17855          mutex_enter(&ill->ill_lock);
17850 17856          if (!ill_is_quiescent(ill)) {
17851 17857                  /* call cannot fail since `conn_t *' argument is NULL */
17852 17858                  (void) ipsq_pending_mp_add(NULL, ill->ill_ipif, ill->ill_rq,
17853 17859                      mp, ILL_DOWN);
17854 17860                  mutex_exit(&ill->ill_lock);
17855 17861                  return (EINPROGRESS);
17856 17862          }
17857 17863          mutex_exit(&ill->ill_lock);
17858 17864  
17859 17865          ill_set_phys_addr_tail(ipsq, ill->ill_rq, mp, NULL);
17860 17866          return (0);
17861 17867  }
17862 17868  
17863 17869  /*
17864 17870   * When the allowed-ips link property is set on the datalink, IP receives a
17865 17871   * DL_NOTE_ALLOWED_IPS notification that is processed in ill_set_allowed_ips()
17866 17872   * to initialize the ill_allowed_ips[] array in the ill_t. This array is then
17867 17873   * used to vet addresses passed to ip_sioctl_addr() and to ensure that the
17868 17874   * only IP addresses configured on the ill_t are those in the ill_allowed_ips[]
17869 17875   * array.
17870 17876   */
17871 17877  void
17872 17878  ill_set_allowed_ips(ill_t *ill, mblk_t *mp)
17873 17879  {
17874 17880          ipsq_t *ipsq = ill->ill_phyint->phyint_ipsq;
17875 17881          dl_notify_ind_t *dlip = (dl_notify_ind_t *)mp->b_rptr;
17876 17882          mac_protect_t *mrp;
17877 17883          int i;
17878 17884  
17879 17885          ASSERT(IAM_WRITER_IPSQ(ipsq));
17880 17886          mrp = (mac_protect_t *)&dlip[1];
17881 17887  
17882 17888          if (mrp->mp_ipaddrcnt == 0) { /* reset allowed-ips */
17883 17889                  kmem_free(ill->ill_allowed_ips,
17884 17890                      ill->ill_allowed_ips_cnt * sizeof (in6_addr_t));
17885 17891                  ill->ill_allowed_ips_cnt = 0;
17886 17892                  ill->ill_allowed_ips = NULL;
17887 17893                  mutex_enter(&ill->ill_phyint->phyint_lock);
17888 17894                  ill->ill_phyint->phyint_flags &= ~PHYI_L3PROTECT;
17889 17895                  mutex_exit(&ill->ill_phyint->phyint_lock);
17890 17896                  return;
17891 17897          }
17892 17898  
17893 17899          if (ill->ill_allowed_ips != NULL) {
17894 17900                  kmem_free(ill->ill_allowed_ips,
17895 17901                      ill->ill_allowed_ips_cnt * sizeof (in6_addr_t));
17896 17902          }
17897 17903          ill->ill_allowed_ips_cnt = mrp->mp_ipaddrcnt;
17898 17904          ill->ill_allowed_ips = kmem_alloc(
17899 17905              ill->ill_allowed_ips_cnt * sizeof (in6_addr_t), KM_SLEEP);
17900 17906          for (i = 0; i < mrp->mp_ipaddrcnt;  i++)
17901 17907                  ill->ill_allowed_ips[i] = mrp->mp_ipaddrs[i].ip_addr;
17902 17908  
17903 17909          mutex_enter(&ill->ill_phyint->phyint_lock);
17904 17910          ill->ill_phyint->phyint_flags |= PHYI_L3PROTECT;
17905 17911          mutex_exit(&ill->ill_phyint->phyint_lock);
17906 17912  }
17907 17913  
17908 17914  /*
17909 17915   * Once the ill associated with `q' has quiesced, set its physical address
17910 17916   * information to the values in `addrmp'.  Note that two copies of `addrmp'
17911 17917   * are passed (linked by b_cont), since we sometimes need to save two distinct
17912 17918   * copies in the ill_t, and our context doesn't permit sleeping or allocation
17913 17919   * failure (we'll free the other copy if it's not needed).  Since the ill_t
17914 17920   * is quiesced, we know any stale nce's with the old address information have
17915 17921   * already been removed, so we don't need to call nce_flush().
17916 17922   */
17917 17923  /* ARGSUSED */
17918 17924  static void
17919 17925  ill_set_phys_addr_tail(ipsq_t *ipsq, queue_t *q, mblk_t *addrmp, void *dummy)
17920 17926  {
17921 17927          ill_t           *ill = q->q_ptr;
17922 17928          mblk_t          *addrmp2 = unlinkb(addrmp);
17923 17929          dl_notify_ind_t *dlindp = (dl_notify_ind_t *)addrmp->b_rptr;
17924 17930          uint_t          addrlen, addroff;
17925 17931          int             status;
17926 17932  
17927 17933          ASSERT(IAM_WRITER_IPSQ(ipsq));
17928 17934  
17929 17935          addroff = dlindp->dl_addr_offset;
17930 17936          addrlen = dlindp->dl_addr_length - ABS(ill->ill_sap_length);
17931 17937  
17932 17938          switch (dlindp->dl_data) {
17933 17939          case DL_IPV6_LINK_LAYER_ADDR:
17934 17940                  ill_set_ndmp(ill, addrmp, addroff, addrlen);
17935 17941                  freemsg(addrmp2);
17936 17942                  break;
17937 17943  
17938 17944          case DL_CURR_DEST_ADDR:
17939 17945                  freemsg(ill->ill_dest_addr_mp);
17940 17946                  ill->ill_dest_addr = addrmp->b_rptr + addroff;
17941 17947                  ill->ill_dest_addr_mp = addrmp;
17942 17948                  if (ill->ill_isv6) {
17943 17949                          ill_setdesttoken(ill);
17944 17950                          ipif_setdestlinklocal(ill->ill_ipif);
17945 17951                  }
17946 17952                  freemsg(addrmp2);
17947 17953                  break;
17948 17954  
17949 17955          case DL_CURR_PHYS_ADDR:
17950 17956                  freemsg(ill->ill_phys_addr_mp);
17951 17957                  ill->ill_phys_addr = addrmp->b_rptr + addroff;
17952 17958                  ill->ill_phys_addr_mp = addrmp;
17953 17959                  ill->ill_phys_addr_length = addrlen;
17954 17960                  if (ill->ill_isv6)
17955 17961                          ill_set_ndmp(ill, addrmp2, addroff, addrlen);
17956 17962                  else
17957 17963                          freemsg(addrmp2);
17958 17964                  if (ill->ill_isv6) {
17959 17965                          ill_setdefaulttoken(ill);
17960 17966                          ipif_setlinklocal(ill->ill_ipif);
17961 17967                  }
17962 17968                  break;
17963 17969          default:
17964 17970                  ASSERT(0);
17965 17971          }
17966 17972  
17967 17973          /*
17968 17974           * reset ILL_DOWN_IN_PROGRESS so that we can successfully add ires
17969 17975           * as we bring the ipifs up again.
17970 17976           */
17971 17977          mutex_enter(&ill->ill_lock);
17972 17978          ill->ill_state_flags &= ~ILL_DOWN_IN_PROGRESS;
17973 17979          mutex_exit(&ill->ill_lock);
17974 17980          /*
17975 17981           * If there are ipifs to bring up, ill_up_ipifs() will return
17976 17982           * EINPROGRESS, and ipsq_current_finish() will be called by
17977 17983           * ip_rput_dlpi_writer() or arp_bringup_done() when the last ipif is
17978 17984           * brought up.
17979 17985           */
17980 17986          status = ill_up_ipifs(ill, q, addrmp);
17981 17987          if (status != EINPROGRESS)
17982 17988                  ipsq_current_finish(ipsq);
17983 17989  }
17984 17990  
17985 17991  /*
17986 17992   * Helper routine for setting the ill_nd_lla fields.
17987 17993   */
17988 17994  void
17989 17995  ill_set_ndmp(ill_t *ill, mblk_t *ndmp, uint_t addroff, uint_t addrlen)
17990 17996  {
17991 17997          freemsg(ill->ill_nd_lla_mp);
17992 17998          ill->ill_nd_lla = ndmp->b_rptr + addroff;
17993 17999          ill->ill_nd_lla_mp = ndmp;
17994 18000          ill->ill_nd_lla_len = addrlen;
17995 18001  }
17996 18002  
17997 18003  /*
17998 18004   * Replumb the ill.
17999 18005   */
18000 18006  int
18001 18007  ill_replumb(ill_t *ill, mblk_t *mp)
18002 18008  {
18003 18009          ipsq_t *ipsq = ill->ill_phyint->phyint_ipsq;
18004 18010  
18005 18011          ASSERT(IAM_WRITER_IPSQ(ipsq));
18006 18012  
18007 18013          ipsq_current_start(ipsq, ill->ill_ipif, 0);
18008 18014  
18009 18015          /*
18010 18016           * If we can quiesce the ill, then continue.  If not, then
18011 18017           * ill_replumb_tail() will be called from ipif_ill_refrele_tail().
18012 18018           */
18013 18019          ill_down_ipifs(ill, B_FALSE);
18014 18020  
18015 18021          mutex_enter(&ill->ill_lock);
18016 18022          if (!ill_is_quiescent(ill)) {
18017 18023                  /* call cannot fail since `conn_t *' argument is NULL */
18018 18024                  (void) ipsq_pending_mp_add(NULL, ill->ill_ipif, ill->ill_rq,
18019 18025                      mp, ILL_DOWN);
18020 18026                  mutex_exit(&ill->ill_lock);
18021 18027                  return (EINPROGRESS);
18022 18028          }
18023 18029          mutex_exit(&ill->ill_lock);
18024 18030  
18025 18031          ill_replumb_tail(ipsq, ill->ill_rq, mp, NULL);
18026 18032          return (0);
18027 18033  }
18028 18034  
18029 18035  /* ARGSUSED */
18030 18036  static void
18031 18037  ill_replumb_tail(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy)
18032 18038  {
18033 18039          ill_t *ill = q->q_ptr;
18034 18040          int err;
18035 18041          conn_t *connp = NULL;
18036 18042  
18037 18043          ASSERT(IAM_WRITER_IPSQ(ipsq));
18038 18044          freemsg(ill->ill_replumb_mp);
18039 18045          ill->ill_replumb_mp = copyb(mp);
18040 18046  
18041 18047          if (ill->ill_replumb_mp == NULL) {
18042 18048                  /* out of memory */
18043 18049                  ipsq_current_finish(ipsq);
18044 18050                  return;
18045 18051          }
18046 18052  
18047 18053          mutex_enter(&ill->ill_lock);
18048 18054          ill->ill_up_ipifs = ipsq_pending_mp_add(NULL, ill->ill_ipif,
18049 18055              ill->ill_rq, ill->ill_replumb_mp, 0);
18050 18056          mutex_exit(&ill->ill_lock);
18051 18057  
18052 18058          if (!ill->ill_up_ipifs) {
18053 18059                  /* already closing */
18054 18060                  ipsq_current_finish(ipsq);
18055 18061                  return;
18056 18062          }
18057 18063          ill->ill_replumbing = 1;
18058 18064          err = ill_down_ipifs_tail(ill);
18059 18065  
18060 18066          /*
18061 18067           * Successfully quiesced and brought down the interface, now we send
18062 18068           * the DL_NOTE_REPLUMB_DONE message down to the driver. Reuse the
18063 18069           * DL_NOTE_REPLUMB message.
18064 18070           */
18065 18071          mp = mexchange(NULL, mp, sizeof (dl_notify_conf_t), M_PROTO,
18066 18072              DL_NOTIFY_CONF);
18067 18073          ASSERT(mp != NULL);
18068 18074          ((dl_notify_conf_t *)mp->b_rptr)->dl_notification =
18069 18075              DL_NOTE_REPLUMB_DONE;
18070 18076          ill_dlpi_send(ill, mp);
18071 18077  
18072 18078          /*
18073 18079           * For IPv4, we would usually get EINPROGRESS because the ETHERTYPE_ARP
18074 18080           * streams have to be unbound. When all the DLPI exchanges are done,
18075 18081           * ipsq_current_finish() will be called by arp_bringup_done(). The
18076 18082           * remainder of ipif bringup via ill_up_ipifs() will also be done in
18077 18083           * arp_bringup_done().
18078 18084           */
18079 18085          ASSERT(ill->ill_replumb_mp != NULL);
18080 18086          if (err == EINPROGRESS)
18081 18087                  return;
18082 18088          else
18083 18089                  ill->ill_replumb_mp = ipsq_pending_mp_get(ipsq, &connp);
18084 18090          ASSERT(connp == NULL);
18085 18091          if (err == 0 && ill->ill_replumb_mp != NULL &&
18086 18092              ill_up_ipifs(ill, q, ill->ill_replumb_mp) == EINPROGRESS) {
18087 18093                  return;
18088 18094          }
18089 18095          ipsq_current_finish(ipsq);
18090 18096  }
18091 18097  
18092 18098  /*
18093 18099   * Issue ioctl `cmd' on `lh'; caller provides the initial payload in `buf'
18094 18100   * which is `bufsize' bytes.  On success, zero is returned and `buf' updated
18095 18101   * as per the ioctl.  On failure, an errno is returned.
18096 18102   */
18097 18103  static int
18098 18104  ip_ioctl(ldi_handle_t lh, int cmd, void *buf, uint_t bufsize, cred_t *cr)
18099 18105  {
18100 18106          int rval;
18101 18107          struct strioctl iocb;
18102 18108  
18103 18109          iocb.ic_cmd = cmd;
18104 18110          iocb.ic_timout = 15;
18105 18111          iocb.ic_len = bufsize;
18106 18112          iocb.ic_dp = buf;
18107 18113  
18108 18114          return (ldi_ioctl(lh, I_STR, (intptr_t)&iocb, FKIOCTL, cr, &rval));
18109 18115  }
18110 18116  
18111 18117  /*
18112 18118   * Issue an SIOCGLIFCONF for address family `af' and store the result into a
18113 18119   * dynamically-allocated `lifcp' that will be `bufsizep' bytes on success.
18114 18120   */
18115 18121  static int
18116 18122  ip_lifconf_ioctl(ldi_handle_t lh, int af, struct lifconf *lifcp,
18117 18123      uint_t *bufsizep, cred_t *cr)
18118 18124  {
18119 18125          int err;
18120 18126          struct lifnum lifn;
18121 18127  
18122 18128          bzero(&lifn, sizeof (lifn));
18123 18129          lifn.lifn_family = af;
18124 18130          lifn.lifn_flags = LIFC_UNDER_IPMP;
18125 18131  
18126 18132          if ((err = ip_ioctl(lh, SIOCGLIFNUM, &lifn, sizeof (lifn), cr)) != 0)
18127 18133                  return (err);
18128 18134  
18129 18135          /*
18130 18136           * Pad the interface count to account for additional interfaces that
18131 18137           * may have been configured between the SIOCGLIFNUM and SIOCGLIFCONF.
18132 18138           */
18133 18139          lifn.lifn_count += 4;
18134 18140          bzero(lifcp, sizeof (*lifcp));
18135 18141          lifcp->lifc_flags = LIFC_UNDER_IPMP;
18136 18142          lifcp->lifc_family = af;
18137 18143          lifcp->lifc_len = *bufsizep = lifn.lifn_count * sizeof (struct lifreq);
18138 18144          lifcp->lifc_buf = kmem_zalloc(*bufsizep, KM_SLEEP);
18139 18145  
18140 18146          err = ip_ioctl(lh, SIOCGLIFCONF, lifcp, sizeof (*lifcp), cr);
18141 18147          if (err != 0) {
18142 18148                  kmem_free(lifcp->lifc_buf, *bufsizep);
18143 18149                  return (err);
18144 18150          }
18145 18151  
18146 18152          return (0);
18147 18153  }
18148 18154  
18149 18155  /*
18150 18156   * Helper for ip_interface_cleanup() that removes the loopback interface.
18151 18157   */
18152 18158  static void
18153 18159  ip_loopback_removeif(ldi_handle_t lh, boolean_t isv6, cred_t *cr)
18154 18160  {
18155 18161          int err;
18156 18162          struct lifreq lifr;
18157 18163  
18158 18164          bzero(&lifr, sizeof (lifr));
18159 18165          (void) strcpy(lifr.lifr_name, ipif_loopback_name);
18160 18166  
18161 18167          /*
18162 18168           * Attempt to remove the interface.  It may legitimately not exist
18163 18169           * (e.g. the zone administrator unplumbed it), so ignore ENXIO.
18164 18170           */
18165 18171          err = ip_ioctl(lh, SIOCLIFREMOVEIF, &lifr, sizeof (lifr), cr);
18166 18172          if (err != 0 && err != ENXIO) {
18167 18173                  ip0dbg(("ip_loopback_removeif: IP%s SIOCLIFREMOVEIF failed: "
18168 18174                      "error %d\n", isv6 ? "v6" : "v4", err));
18169 18175          }
18170 18176  }
18171 18177  
18172 18178  /*
18173 18179   * Helper for ip_interface_cleanup() that ensures no IP interfaces are in IPMP
18174 18180   * groups and that IPMP data addresses are down.  These conditions must be met
18175 18181   * so that IPMP interfaces can be I_PUNLINK'd, as per ip_sioctl_plink_ipmp().
18176 18182   */
18177 18183  static void
18178 18184  ip_ipmp_cleanup(ldi_handle_t lh, boolean_t isv6, cred_t *cr)
18179 18185  {
18180 18186          int af = isv6 ? AF_INET6 : AF_INET;
18181 18187          int i, nifs;
18182 18188          int err;
18183 18189          uint_t bufsize;
18184 18190          uint_t lifrsize = sizeof (struct lifreq);
18185 18191          struct lifconf lifc;
18186 18192          struct lifreq *lifrp;
18187 18193  
18188 18194          if ((err = ip_lifconf_ioctl(lh, af, &lifc, &bufsize, cr)) != 0) {
18189 18195                  cmn_err(CE_WARN, "ip_ipmp_cleanup: cannot get interface list "
18190 18196                      "(error %d); any IPMP interfaces cannot be shutdown", err);
18191 18197                  return;
18192 18198          }
18193 18199  
18194 18200          nifs = lifc.lifc_len / lifrsize;
18195 18201          for (lifrp = lifc.lifc_req, i = 0; i < nifs; i++, lifrp++) {
18196 18202                  err = ip_ioctl(lh, SIOCGLIFFLAGS, lifrp, lifrsize, cr);
18197 18203                  if (err != 0) {
18198 18204                          cmn_err(CE_WARN, "ip_ipmp_cleanup: %s: cannot get "
18199 18205                              "flags: error %d", lifrp->lifr_name, err);
18200 18206                          continue;
18201 18207                  }
18202 18208  
18203 18209                  if (lifrp->lifr_flags & IFF_IPMP) {
18204 18210                          if ((lifrp->lifr_flags & (IFF_UP|IFF_DUPLICATE)) == 0)
18205 18211                                  continue;
18206 18212  
18207 18213                          lifrp->lifr_flags &= ~IFF_UP;
18208 18214                          err = ip_ioctl(lh, SIOCSLIFFLAGS, lifrp, lifrsize, cr);
18209 18215                          if (err != 0) {
18210 18216                                  cmn_err(CE_WARN, "ip_ipmp_cleanup: %s: cannot "
18211 18217                                      "bring down (error %d); IPMP interface may "
18212 18218                                      "not be shutdown", lifrp->lifr_name, err);
18213 18219                          }
18214 18220  
18215 18221                          /*
18216 18222                           * Check if IFF_DUPLICATE is still set -- and if so,
18217 18223                           * reset the address to clear it.
18218 18224                           */
18219 18225                          err = ip_ioctl(lh, SIOCGLIFFLAGS, lifrp, lifrsize, cr);
18220 18226                          if (err != 0 || !(lifrp->lifr_flags & IFF_DUPLICATE))
18221 18227                                  continue;
18222 18228  
18223 18229                          err = ip_ioctl(lh, SIOCGLIFADDR, lifrp, lifrsize, cr);
18224 18230                          if (err != 0 || (err = ip_ioctl(lh, SIOCGLIFADDR,
18225 18231                              lifrp, lifrsize, cr)) != 0) {
18226 18232                                  cmn_err(CE_WARN, "ip_ipmp_cleanup: %s: cannot "
18227 18233                                      "reset DAD (error %d); IPMP interface may "
18228 18234                                      "not be shutdown", lifrp->lifr_name, err);
18229 18235                          }
18230 18236                          continue;
18231 18237                  }
18232 18238  
18233 18239                  if (strchr(lifrp->lifr_name, IPIF_SEPARATOR_CHAR) == 0) {
18234 18240                          lifrp->lifr_groupname[0] = '\0';
18235 18241                          if ((err = ip_ioctl(lh, SIOCSLIFGROUPNAME, lifrp,
18236 18242                              lifrsize, cr)) != 0) {
18237 18243                                  cmn_err(CE_WARN, "ip_ipmp_cleanup: %s: cannot "
18238 18244                                      "leave IPMP group (error %d); associated "
18239 18245                                      "IPMP interface may not be shutdown",
18240 18246                                      lifrp->lifr_name, err);
18241 18247                                  continue;
18242 18248                          }
18243 18249                  }
18244 18250          }
18245 18251  
18246 18252          kmem_free(lifc.lifc_buf, bufsize);
18247 18253  }
18248 18254  
18249 18255  #define UDPDEV          "/devices/pseudo/udp@0:udp"
18250 18256  #define UDP6DEV         "/devices/pseudo/udp6@0:udp6"
18251 18257  
18252 18258  /*
18253 18259   * Remove the loopback interfaces and prep the IPMP interfaces to be torn down.
18254 18260   * Non-loopback interfaces are either I_LINK'd or I_PLINK'd; the former go away
18255 18261   * when the user-level processes in the zone are killed and the latter are
18256 18262   * cleaned up by str_stack_shutdown().
18257 18263   */
18258 18264  void
18259 18265  ip_interface_cleanup(ip_stack_t *ipst)
18260 18266  {
18261 18267          ldi_handle_t    lh;
18262 18268          ldi_ident_t     li;
18263 18269          cred_t          *cr;
18264 18270          int             err;
18265 18271          int             i;
18266 18272          char            *devs[] = { UDP6DEV, UDPDEV };
18267 18273          netstackid_t    stackid = ipst->ips_netstack->netstack_stackid;
18268 18274  
18269 18275          if ((err = ldi_ident_from_major(ddi_name_to_major("ip"), &li)) != 0) {
18270 18276                  cmn_err(CE_WARN, "ip_interface_cleanup: cannot get ldi ident:"
18271 18277                      " error %d", err);
18272 18278                  return;
18273 18279          }
18274 18280  
18275 18281          cr = zone_get_kcred(netstackid_to_zoneid(stackid));
18276 18282          ASSERT(cr != NULL);
18277 18283  
18278 18284          /*
18279 18285           * NOTE: loop executes exactly twice and is hardcoded to know that the
18280 18286           * first iteration is IPv6.  (Unrolling yields repetitious code, hence
18281 18287           * the loop.)
18282 18288           */
18283 18289          for (i = 0; i < 2; i++) {
18284 18290                  err = ldi_open_by_name(devs[i], FREAD|FWRITE, cr, &lh, li);
18285 18291                  if (err != 0) {
18286 18292                          cmn_err(CE_WARN, "ip_interface_cleanup: cannot open %s:"
18287 18293                              " error %d", devs[i], err);
18288 18294                          continue;
18289 18295                  }
18290 18296  
18291 18297                  ip_loopback_removeif(lh, i == 0, cr);
18292 18298                  ip_ipmp_cleanup(lh, i == 0, cr);
18293 18299  
18294 18300                  (void) ldi_close(lh, FREAD|FWRITE, cr);
18295 18301          }
18296 18302  
18297 18303          ldi_ident_release(li);
18298 18304          crfree(cr);
18299 18305  }
18300 18306  
18301 18307  /*
18302 18308   * This needs to be in-sync with nic_event_t definition
18303 18309   */
18304 18310  static const char *
18305 18311  ill_hook_event2str(nic_event_t event)
18306 18312  {
18307 18313          switch (event) {
18308 18314          case NE_PLUMB:
18309 18315                  return ("PLUMB");
18310 18316          case NE_UNPLUMB:
18311 18317                  return ("UNPLUMB");
18312 18318          case NE_UP:
18313 18319                  return ("UP");
18314 18320          case NE_DOWN:
18315 18321                  return ("DOWN");
18316 18322          case NE_ADDRESS_CHANGE:
18317 18323                  return ("ADDRESS_CHANGE");
18318 18324          case NE_LIF_UP:
18319 18325                  return ("LIF_UP");
18320 18326          case NE_LIF_DOWN:
18321 18327                  return ("LIF_DOWN");
18322 18328          case NE_IFINDEX_CHANGE:
18323 18329                  return ("IFINDEX_CHANGE");
18324 18330          default:
18325 18331                  return ("UNKNOWN");
18326 18332          }
18327 18333  }
18328 18334  
18329 18335  void
18330 18336  ill_nic_event_dispatch(ill_t *ill, lif_if_t lif, nic_event_t event,
18331 18337      nic_event_data_t data, size_t datalen)
18332 18338  {
18333 18339          ip_stack_t              *ipst = ill->ill_ipst;
18334 18340          hook_nic_event_int_t    *info;
18335 18341          const char              *str = NULL;
18336 18342  
18337 18343          /* create a new nic event info */
18338 18344          if ((info = kmem_alloc(sizeof (*info), KM_NOSLEEP)) == NULL)
18339 18345                  goto fail;
18340 18346  
18341 18347          info->hnei_event.hne_nic = ill->ill_phyint->phyint_ifindex;
18342 18348          info->hnei_event.hne_lif = lif;
18343 18349          info->hnei_event.hne_event = event;
18344 18350          info->hnei_event.hne_protocol = ill->ill_isv6 ?
18345 18351              ipst->ips_ipv6_net_data : ipst->ips_ipv4_net_data;
18346 18352          info->hnei_event.hne_data = NULL;
18347 18353          info->hnei_event.hne_datalen = 0;
18348 18354          info->hnei_stackid = ipst->ips_netstack->netstack_stackid;
18349 18355  
18350 18356          if (data != NULL && datalen != 0) {
18351 18357                  info->hnei_event.hne_data = kmem_alloc(datalen, KM_NOSLEEP);
18352 18358                  if (info->hnei_event.hne_data == NULL)
18353 18359                          goto fail;
18354 18360                  bcopy(data, info->hnei_event.hne_data, datalen);
18355 18361                  info->hnei_event.hne_datalen = datalen;
18356 18362          }
18357 18363  
18358 18364          if (ddi_taskq_dispatch(eventq_queue_nic, ip_ne_queue_func, info,
18359 18365              DDI_NOSLEEP) == DDI_SUCCESS)
18360 18366                  return;
18361 18367  
18362 18368  fail:
18363 18369          if (info != NULL) {
18364 18370                  if (info->hnei_event.hne_data != NULL) {
18365 18371                          kmem_free(info->hnei_event.hne_data,
18366 18372                              info->hnei_event.hne_datalen);
18367 18373                  }
18368 18374                  kmem_free(info, sizeof (hook_nic_event_t));
18369 18375          }
18370 18376          str = ill_hook_event2str(event);
18371 18377          ip2dbg(("ill_nic_event_dispatch: could not dispatch %s nic event "
18372 18378              "information for %s (ENOMEM)\n", str, ill->ill_name));
18373 18379  }
18374 18380  
18375 18381  static int
18376 18382  ipif_arp_up_done_tail(ipif_t *ipif, enum ip_resolver_action res_act)
18377 18383  {
18378 18384          int             err = 0;
18379 18385          const in_addr_t *addr = NULL;
18380 18386          nce_t           *nce = NULL;
18381 18387          ill_t           *ill = ipif->ipif_ill;
18382 18388          ill_t           *bound_ill;
18383 18389          boolean_t       added_ipif = B_FALSE;
18384 18390          uint16_t        state;
18385 18391          uint16_t        flags;
18386 18392  
18387 18393          DTRACE_PROBE3(ipif__downup, char *, "ipif_arp_up_done_tail",
18388 18394              ill_t *, ill, ipif_t *, ipif);
18389 18395          if (ipif->ipif_lcl_addr != INADDR_ANY) {
18390 18396                  addr = &ipif->ipif_lcl_addr;
18391 18397          }
18392 18398  
18393 18399          if ((ipif->ipif_flags & IPIF_UNNUMBERED) || addr == NULL) {
18394 18400                  if (res_act != Res_act_initial)
18395 18401                          return (EINVAL);
18396 18402          }
18397 18403  
18398 18404          if (addr != NULL) {
18399 18405                  ipmp_illgrp_t   *illg = ill->ill_grp;
18400 18406  
18401 18407                  /* add unicast nce for the local addr */
18402 18408  
18403 18409                  if (IS_IPMP(ill)) {
18404 18410                          /*
18405 18411                           * If we're here via ipif_up(), then the ipif
18406 18412                           * won't be bound yet -- add it to the group,
18407 18413                           * which will bind it if possible. (We would
18408 18414                           * add it in ipif_up(), but deleting on failure
18409 18415                           * there is gruesome.)  If we're here via
18410 18416                           * ipmp_ill_bind_ipif(), then the ipif has
18411 18417                           * already been added to the group and we
18412 18418                           * just need to use the binding.
18413 18419                           */
18414 18420                          if ((bound_ill = ipmp_ipif_bound_ill(ipif)) == NULL) {
18415 18421                                  bound_ill  = ipmp_illgrp_add_ipif(illg, ipif);
18416 18422                                  if (bound_ill == NULL) {
18417 18423                                          /*
18418 18424                                           * We couldn't bind the ipif to an ill
18419 18425                                           * yet, so we have nothing to publish.
18420 18426                                           * Mark the address as ready and return.
18421 18427                                           */
18422 18428                                          ipif->ipif_addr_ready = 1;
18423 18429                                          return (0);
18424 18430                                  }
18425 18431                                  added_ipif = B_TRUE;
18426 18432                          }
18427 18433                  } else {
18428 18434                          bound_ill = ill;
18429 18435                  }
18430 18436  
18431 18437                  flags = (NCE_F_MYADDR | NCE_F_PUBLISH | NCE_F_AUTHORITY |
18432 18438                      NCE_F_NONUD);
18433 18439                  /*
18434 18440                   * If this is an initial bring-up (or the ipif was never
18435 18441                   * completely brought up), do DAD.  Otherwise, we're here
18436 18442                   * because IPMP has rebound an address to this ill: send
18437 18443                   * unsolicited advertisements (ARP announcements) to
18438 18444                   * inform others.
18439 18445                   */
18440 18446                  if (res_act == Res_act_initial || !ipif->ipif_addr_ready) {
18441 18447                          state = ND_UNCHANGED; /* compute in nce_add_common() */
18442 18448                  } else {
18443 18449                          state = ND_REACHABLE;
18444 18450                          flags |= NCE_F_UNSOL_ADV;
18445 18451                  }
18446 18452  
18447 18453  retry:
18448 18454                  err = nce_lookup_then_add_v4(ill,
18449 18455                      bound_ill->ill_phys_addr, bound_ill->ill_phys_addr_length,
18450 18456                      addr, flags, state, &nce);
18451 18457  
18452 18458                  /*
18453 18459                   * note that we may encounter EEXIST if we are moving
18454 18460                   * the nce as a result of a rebind operation.
18455 18461                   */
18456 18462                  switch (err) {
18457 18463                  case 0:
18458 18464                          ipif->ipif_added_nce = 1;
18459 18465                          nce->nce_ipif_cnt++;
18460 18466                          break;
18461 18467                  case EEXIST:
18462 18468                          ip1dbg(("ipif_arp_up: NCE already exists for %s\n",
18463 18469                              ill->ill_name));
18464 18470                          if (!NCE_MYADDR(nce->nce_common)) {
18465 18471                                  /*
18466 18472                                   * A leftover nce from before this address
18467 18473                                   * existed
18468 18474                                   */
18469 18475                                  ncec_delete(nce->nce_common);
18470 18476                                  nce_refrele(nce);
18471 18477                                  nce = NULL;
18472 18478                                  goto retry;
18473 18479                          }
18474 18480                          if ((ipif->ipif_flags & IPIF_POINTOPOINT) == 0) {
18475 18481                                  nce_refrele(nce);
18476 18482                                  nce = NULL;
18477 18483                                  ip1dbg(("ipif_arp_up: NCE already exists "
18478 18484                                      "for %s:%u\n", ill->ill_name,
18479 18485                                      ipif->ipif_id));
18480 18486                                  goto arp_up_done;
18481 18487                          }
18482 18488                          /*
18483 18489                           * Duplicate local addresses are permissible for
18484 18490                           * IPIF_POINTOPOINT interfaces which will get marked
18485 18491                           * IPIF_UNNUMBERED later in
18486 18492                           * ip_addr_availability_check().
18487 18493                           *
18488 18494                           * The nce_ipif_cnt field tracks the number of
18489 18495                           * ipifs that have nce_addr as their local address.
18490 18496                           */
18491 18497                          ipif->ipif_addr_ready = 1;
18492 18498                          ipif->ipif_added_nce = 1;
18493 18499                          nce->nce_ipif_cnt++;
18494 18500                          err = 0;
18495 18501                          break;
18496 18502                  default:
18497 18503                          ASSERT(nce == NULL);
18498 18504                          goto arp_up_done;
18499 18505                  }
18500 18506                  if (arp_no_defense) {
18501 18507                          if ((ipif->ipif_flags & IPIF_UP) &&
18502 18508                              !ipif->ipif_addr_ready)
18503 18509                                  ipif_up_notify(ipif);
18504 18510                          ipif->ipif_addr_ready = 1;
18505 18511                  }
18506 18512          } else {
18507 18513                  /* zero address. nothing to publish */
18508 18514                  ipif->ipif_addr_ready = 1;
18509 18515          }
18510 18516          if (nce != NULL)
18511 18517                  nce_refrele(nce);
18512 18518  arp_up_done:
18513 18519          if (added_ipif && err != 0)
18514 18520                  ipmp_illgrp_del_ipif(ill->ill_grp, ipif);
18515 18521          return (err);
18516 18522  }
18517 18523  
18518 18524  int
18519 18525  ipif_arp_up(ipif_t *ipif, enum ip_resolver_action res_act, boolean_t was_dup)
18520 18526  {
18521 18527          int             err = 0;
18522 18528          ill_t           *ill = ipif->ipif_ill;
18523 18529          boolean_t       first_interface, wait_for_dlpi = B_FALSE;
18524 18530  
18525 18531          DTRACE_PROBE3(ipif__downup, char *, "ipif_arp_up",
18526 18532              ill_t *, ill, ipif_t *, ipif);
18527 18533  
18528 18534          /*
18529 18535           * need to bring up ARP or setup mcast mapping only
18530 18536           * when the first interface is coming UP.
18531 18537           */
18532 18538          first_interface = (ill->ill_ipif_up_count == 0 &&
18533 18539              ill->ill_ipif_dup_count == 0 && !was_dup);
18534 18540  
18535 18541          if (res_act == Res_act_initial && first_interface) {
18536 18542                  /*
18537 18543                   * Send ATTACH + BIND
18538 18544                   */
18539 18545                  err = arp_ll_up(ill);
18540 18546                  if (err != EINPROGRESS && err != 0)
18541 18547                          return (err);
18542 18548  
18543 18549                  /*
18544 18550                   * Add NCE for local address. Start DAD.
18545 18551                   * we'll wait to hear that DAD has finished
18546 18552                   * before using the interface.
18547 18553                   */
18548 18554                  if (err == EINPROGRESS)
18549 18555                          wait_for_dlpi = B_TRUE;
18550 18556          }
18551 18557  
18552 18558          if (!wait_for_dlpi)
18553 18559                  (void) ipif_arp_up_done_tail(ipif, res_act);
18554 18560  
18555 18561          return (!wait_for_dlpi ? 0 : EINPROGRESS);
18556 18562  }
18557 18563  
18558 18564  /*
18559 18565   * Finish processing of "arp_up" after all the DLPI message
18560 18566   * exchanges have completed between arp and the driver.
18561 18567   */
18562 18568  void
18563 18569  arp_bringup_done(ill_t *ill, int err)
18564 18570  {
18565 18571          mblk_t  *mp1;
18566 18572          ipif_t  *ipif;
18567 18573          conn_t *connp = NULL;
18568 18574          ipsq_t  *ipsq;
18569 18575          queue_t *q;
18570 18576  
18571 18577          ip1dbg(("arp_bringup_done(%s)\n", ill->ill_name));
18572 18578  
18573 18579          ASSERT(IAM_WRITER_ILL(ill));
18574 18580  
18575 18581          ipsq = ill->ill_phyint->phyint_ipsq;
18576 18582          ipif = ipsq->ipsq_xop->ipx_pending_ipif;
18577 18583          mp1 = ipsq_pending_mp_get(ipsq, &connp);
18578 18584          ASSERT(!((mp1 != NULL) ^ (ipif != NULL)));
18579 18585          if (mp1 == NULL) /* bringup was aborted by the user */
18580 18586                  return;
18581 18587  
18582 18588          /*
18583 18589           * If an IOCTL is waiting on this (ipsq_current_ioctl != 0), then we
18584 18590           * must have an associated conn_t.  Otherwise, we're bringing this
18585 18591           * interface back up as part of handling an asynchronous event (e.g.,
18586 18592           * physical address change).
18587 18593           */
18588 18594          if (ipsq->ipsq_xop->ipx_current_ioctl != 0) {
18589 18595                  ASSERT(connp != NULL);
18590 18596                  q = CONNP_TO_WQ(connp);
18591 18597          } else {
18592 18598                  ASSERT(connp == NULL);
18593 18599                  q = ill->ill_rq;
18594 18600          }
18595 18601          if (err == 0) {
18596 18602                  if (ipif->ipif_isv6) {
18597 18603                          if ((err = ipif_up_done_v6(ipif)) != 0)
18598 18604                                  ip0dbg(("arp_bringup_done: init failed\n"));
18599 18605                  } else {
18600 18606                          err = ipif_arp_up_done_tail(ipif, Res_act_initial);
18601 18607                          if (err != 0 ||
18602 18608                              (err = ipif_up_done(ipif)) != 0) {
18603 18609                                  ip0dbg(("arp_bringup_done: "
18604 18610                                      "init failed err %x\n", err));
18605 18611                                  (void) ipif_arp_down(ipif);
18606 18612                          }
18607 18613  
18608 18614                  }
18609 18615          } else {
18610 18616                  ip0dbg(("arp_bringup_done: DL_BIND_REQ failed\n"));
18611 18617          }
18612 18618  
18613 18619          if ((err == 0) && (ill->ill_up_ipifs)) {
18614 18620                  err = ill_up_ipifs(ill, q, mp1);
18615 18621                  if (err == EINPROGRESS)
18616 18622                          return;
18617 18623          }
18618 18624  
18619 18625          /*
18620 18626           * If we have a moved ipif to bring up, and everything has succeeded
18621 18627           * to this point, bring it up on the IPMP ill.  Otherwise, leave it
18622 18628           * down -- the admin can try to bring it up by hand if need be.
18623 18629           */
18624 18630          if (ill->ill_move_ipif != NULL) {
18625 18631                  ipif = ill->ill_move_ipif;
18626 18632                  ip1dbg(("bringing up ipif %p on ill %s\n", (void *)ipif,
18627 18633                      ipif->ipif_ill->ill_name));
18628 18634                  ill->ill_move_ipif = NULL;
18629 18635                  if (err == 0) {
18630 18636                          err = ipif_up(ipif, q, mp1);
18631 18637                          if (err == EINPROGRESS)
18632 18638                                  return;
18633 18639                  }
18634 18640          }
18635 18641  
18636 18642          /*
18637 18643           * The operation must complete without EINPROGRESS since
18638 18644           * ipsq_pending_mp_get() has removed the mblk from ipsq_pending_mp.
18639 18645           * Otherwise, the operation will be stuck forever in the ipsq.
18640 18646           */
18641 18647          ASSERT(err != EINPROGRESS);
18642 18648          if (ipsq->ipsq_xop->ipx_current_ioctl != 0) {
18643 18649                  DTRACE_PROBE4(ipif__ioctl, char *, "arp_bringup_done finish",
18644 18650                      int, ipsq->ipsq_xop->ipx_current_ioctl,
18645 18651                      ill_t *, ill, ipif_t *, ipif);
18646 18652                  ip_ioctl_finish(q, mp1, err, NO_COPYOUT, ipsq);
18647 18653          } else {
18648 18654                  ipsq_current_finish(ipsq);
18649 18655          }
18650 18656  }
18651 18657  
18652 18658  /*
18653 18659   * Finish processing of arp replumb after all the DLPI message
18654 18660   * exchanges have completed between arp and the driver.
18655 18661   */
18656 18662  void
18657 18663  arp_replumb_done(ill_t *ill, int err)
18658 18664  {
18659 18665          mblk_t  *mp1;
18660 18666          ipif_t  *ipif;
18661 18667          conn_t *connp = NULL;
18662 18668          ipsq_t  *ipsq;
18663 18669          queue_t *q;
18664 18670  
18665 18671          ASSERT(IAM_WRITER_ILL(ill));
18666 18672  
18667 18673          ipsq = ill->ill_phyint->phyint_ipsq;
18668 18674          ipif = ipsq->ipsq_xop->ipx_pending_ipif;
18669 18675          mp1 = ipsq_pending_mp_get(ipsq, &connp);
18670 18676          ASSERT(!((mp1 != NULL) ^ (ipif != NULL)));
18671 18677          if (mp1 == NULL) {
18672 18678                  ip0dbg(("arp_replumb_done: bringup aborted ioctl %x\n",
18673 18679                      ipsq->ipsq_xop->ipx_current_ioctl));
18674 18680                  /* bringup was aborted by the user */
18675 18681                  return;
18676 18682          }
18677 18683          /*
18678 18684           * If an IOCTL is waiting on this (ipsq_current_ioctl != 0), then we
18679 18685           * must have an associated conn_t.  Otherwise, we're bringing this
18680 18686           * interface back up as part of handling an asynchronous event (e.g.,
18681 18687           * physical address change).
18682 18688           */
18683 18689          if (ipsq->ipsq_xop->ipx_current_ioctl != 0) {
18684 18690                  ASSERT(connp != NULL);
18685 18691                  q = CONNP_TO_WQ(connp);
18686 18692          } else {
18687 18693                  ASSERT(connp == NULL);
18688 18694                  q = ill->ill_rq;
18689 18695          }
18690 18696          if ((err == 0) && (ill->ill_up_ipifs)) {
18691 18697                  err = ill_up_ipifs(ill, q, mp1);
18692 18698                  if (err == EINPROGRESS)
18693 18699                          return;
18694 18700          }
18695 18701          /*
18696 18702           * The operation must complete without EINPROGRESS since
18697 18703           * ipsq_pending_mp_get() has removed the mblk from ipsq_pending_mp.
18698 18704           * Otherwise, the operation will be stuck forever in the ipsq.
18699 18705           */
18700 18706          ASSERT(err != EINPROGRESS);
18701 18707          if (ipsq->ipsq_xop->ipx_current_ioctl != 0) {
18702 18708                  DTRACE_PROBE4(ipif__ioctl, char *,
18703 18709                      "arp_replumb_done finish",
18704 18710                      int, ipsq->ipsq_xop->ipx_current_ioctl,
18705 18711                      ill_t *, ill, ipif_t *, ipif);
18706 18712                  ip_ioctl_finish(q, mp1, err, NO_COPYOUT, ipsq);
18707 18713          } else {
18708 18714                  ipsq_current_finish(ipsq);
18709 18715          }
18710 18716  }
18711 18717  
18712 18718  void
18713 18719  ipif_up_notify(ipif_t *ipif)
18714 18720  {
18715 18721          ip_rts_ifmsg(ipif, RTSQ_DEFAULT);
18716 18722          ip_rts_newaddrmsg(RTM_ADD, 0, ipif, RTSQ_DEFAULT);
18717 18723          sctp_update_ipif(ipif, SCTP_IPIF_UP);
18718 18724          ill_nic_event_dispatch(ipif->ipif_ill, MAP_IPIF_ID(ipif->ipif_id),
18719 18725              NE_LIF_UP, NULL, 0);
18720 18726  }
18721 18727  
18722 18728  /*
18723 18729   * ILB ioctl uses cv_wait (such as deleting a rule or adding a server) and
18724 18730   * this assumes the context is cv_wait'able.  Hence it shouldnt' be used on
18725 18731   * TPI end points with STREAMS modules pushed above.  This is assured by not
18726 18732   * having the IPI_MODOK flag for the ioctl.  And IP ensures the ILB ioctl
18727 18733   * never ends up on an ipsq, otherwise we may end up processing the ioctl
18728 18734   * while unwinding from the ispq and that could be a thread from the bottom.
18729 18735   */
18730 18736  /* ARGSUSED */
18731 18737  int
18732 18738  ip_sioctl_ilb_cmd(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp,
18733 18739      ip_ioctl_cmd_t *ipip, void *arg)
18734 18740  {
18735 18741          mblk_t *cmd_mp = mp->b_cont->b_cont;
18736 18742          ilb_cmd_t command = *((ilb_cmd_t *)cmd_mp->b_rptr);
18737 18743          int ret = 0;
18738 18744          int i;
18739 18745          size_t size;
18740 18746          ip_stack_t *ipst;
18741 18747          zoneid_t zoneid;
18742 18748          ilb_stack_t *ilbs;
18743 18749  
18744 18750          ipst = CONNQ_TO_IPST(q);
18745 18751          ilbs = ipst->ips_netstack->netstack_ilb;
18746 18752          zoneid = Q_TO_CONN(q)->conn_zoneid;
18747 18753  
18748 18754          switch (command) {
18749 18755          case ILB_CREATE_RULE: {
18750 18756                  ilb_rule_cmd_t *cmd = (ilb_rule_cmd_t *)cmd_mp->b_rptr;
18751 18757  
18752 18758                  if (MBLKL(cmd_mp) != sizeof (ilb_rule_cmd_t)) {
18753 18759                          ret = EINVAL;
18754 18760                          break;
18755 18761                  }
18756 18762  
18757 18763                  ret = ilb_rule_add(ilbs, zoneid, cmd);
18758 18764                  break;
18759 18765          }
18760 18766          case ILB_DESTROY_RULE:
18761 18767          case ILB_ENABLE_RULE:
18762 18768          case ILB_DISABLE_RULE: {
18763 18769                  ilb_name_cmd_t *cmd = (ilb_name_cmd_t *)cmd_mp->b_rptr;
18764 18770  
18765 18771                  if (MBLKL(cmd_mp) != sizeof (ilb_name_cmd_t)) {
18766 18772                          ret = EINVAL;
18767 18773                          break;
18768 18774                  }
18769 18775  
18770 18776                  if (cmd->flags & ILB_RULE_ALLRULES) {
18771 18777                          if (command == ILB_DESTROY_RULE) {
18772 18778                                  ilb_rule_del_all(ilbs, zoneid);
18773 18779                                  break;
18774 18780                          } else if (command == ILB_ENABLE_RULE) {
18775 18781                                  ilb_rule_enable_all(ilbs, zoneid);
18776 18782                                  break;
18777 18783                          } else if (command == ILB_DISABLE_RULE) {
18778 18784                                  ilb_rule_disable_all(ilbs, zoneid);
18779 18785                                  break;
18780 18786                          }
18781 18787                  } else {
18782 18788                          if (command == ILB_DESTROY_RULE) {
18783 18789                                  ret = ilb_rule_del(ilbs, zoneid, cmd->name);
18784 18790                          } else if (command == ILB_ENABLE_RULE) {
18785 18791                                  ret = ilb_rule_enable(ilbs, zoneid, cmd->name,
18786 18792                                      NULL);
18787 18793                          } else if (command == ILB_DISABLE_RULE) {
18788 18794                                  ret = ilb_rule_disable(ilbs, zoneid, cmd->name,
18789 18795                                      NULL);
18790 18796                          }
18791 18797                  }
18792 18798                  break;
18793 18799          }
18794 18800          case ILB_NUM_RULES: {
18795 18801                  ilb_num_rules_cmd_t *cmd;
18796 18802  
18797 18803                  if (MBLKL(cmd_mp) != sizeof (ilb_num_rules_cmd_t)) {
18798 18804                          ret = EINVAL;
18799 18805                          break;
18800 18806                  }
18801 18807                  cmd = (ilb_num_rules_cmd_t *)cmd_mp->b_rptr;
18802 18808                  ilb_get_num_rules(ilbs, zoneid, &(cmd->num));
18803 18809                  break;
18804 18810          }
18805 18811          case ILB_RULE_NAMES: {
18806 18812                  ilb_rule_names_cmd_t *cmd;
18807 18813  
18808 18814                  cmd = (ilb_rule_names_cmd_t *)cmd_mp->b_rptr;
18809 18815                  if (MBLKL(cmd_mp) < sizeof (ilb_rule_names_cmd_t) ||
18810 18816                      cmd->num_names == 0) {
18811 18817                          ret = EINVAL;
18812 18818                          break;
18813 18819                  }
18814 18820                  size = cmd->num_names * ILB_RULE_NAMESZ;
18815 18821                  if (cmd_mp->b_rptr + offsetof(ilb_rule_names_cmd_t, buf) +
18816 18822                      size != cmd_mp->b_wptr) {
18817 18823                          ret = EINVAL;
18818 18824                          break;
18819 18825                  }
18820 18826                  ilb_get_rulenames(ilbs, zoneid, &cmd->num_names, cmd->buf);
18821 18827                  break;
18822 18828          }
18823 18829          case ILB_NUM_SERVERS: {
18824 18830                  ilb_num_servers_cmd_t *cmd;
18825 18831  
18826 18832                  if (MBLKL(cmd_mp) != sizeof (ilb_num_servers_cmd_t)) {
18827 18833                          ret = EINVAL;
18828 18834                          break;
18829 18835                  }
18830 18836                  cmd = (ilb_num_servers_cmd_t *)cmd_mp->b_rptr;
18831 18837                  ret = ilb_get_num_servers(ilbs, zoneid, cmd->name,
18832 18838                      &(cmd->num));
18833 18839                  break;
18834 18840          }
18835 18841          case ILB_LIST_RULE: {
18836 18842                  ilb_rule_cmd_t *cmd = (ilb_rule_cmd_t *)cmd_mp->b_rptr;
18837 18843  
18838 18844                  if (MBLKL(cmd_mp) != sizeof (ilb_rule_cmd_t)) {
18839 18845                          ret = EINVAL;
18840 18846                          break;
18841 18847                  }
18842 18848                  ret = ilb_rule_list(ilbs, zoneid, cmd);
18843 18849                  break;
18844 18850          }
18845 18851          case ILB_LIST_SERVERS: {
18846 18852                  ilb_servers_info_cmd_t *cmd;
18847 18853  
18848 18854                  cmd = (ilb_servers_info_cmd_t *)cmd_mp->b_rptr;
18849 18855                  if (MBLKL(cmd_mp) < sizeof (ilb_servers_info_cmd_t) ||
18850 18856                      cmd->num_servers == 0) {
18851 18857                          ret = EINVAL;
18852 18858                          break;
18853 18859                  }
18854 18860                  size = cmd->num_servers * sizeof (ilb_server_info_t);
18855 18861                  if (cmd_mp->b_rptr + offsetof(ilb_servers_info_cmd_t, servers) +
18856 18862                      size != cmd_mp->b_wptr) {
18857 18863                          ret = EINVAL;
18858 18864                          break;
18859 18865                  }
18860 18866  
18861 18867                  ret = ilb_get_servers(ilbs, zoneid, cmd->name, cmd->servers,
18862 18868                      &cmd->num_servers);
18863 18869                  break;
18864 18870          }
18865 18871          case ILB_ADD_SERVERS: {
18866 18872                  ilb_servers_info_cmd_t *cmd;
18867 18873                  ilb_rule_t *rule;
18868 18874  
18869 18875                  cmd = (ilb_servers_info_cmd_t *)cmd_mp->b_rptr;
18870 18876                  if (MBLKL(cmd_mp) < sizeof (ilb_servers_info_cmd_t)) {
18871 18877                          ret = EINVAL;
18872 18878                          break;
18873 18879                  }
18874 18880                  size = cmd->num_servers * sizeof (ilb_server_info_t);
18875 18881                  if (cmd_mp->b_rptr + offsetof(ilb_servers_info_cmd_t, servers) +
18876 18882                      size != cmd_mp->b_wptr) {
18877 18883                          ret = EINVAL;
18878 18884                          break;
18879 18885                  }
18880 18886                  rule = ilb_find_rule(ilbs, zoneid, cmd->name, &ret);
18881 18887                  if (rule == NULL) {
18882 18888                          ASSERT(ret != 0);
18883 18889                          break;
18884 18890                  }
18885 18891                  for (i = 0; i < cmd->num_servers; i++) {
18886 18892                          ilb_server_info_t *s;
18887 18893  
18888 18894                          s = &cmd->servers[i];
18889 18895                          s->err = ilb_server_add(ilbs, rule, s);
18890 18896                  }
18891 18897                  ILB_RULE_REFRELE(rule);
18892 18898                  break;
18893 18899          }
18894 18900          case ILB_DEL_SERVERS:
18895 18901          case ILB_ENABLE_SERVERS:
18896 18902          case ILB_DISABLE_SERVERS: {
18897 18903                  ilb_servers_cmd_t *cmd;
18898 18904                  ilb_rule_t *rule;
18899 18905                  int (*f)();
18900 18906  
18901 18907                  cmd = (ilb_servers_cmd_t *)cmd_mp->b_rptr;
18902 18908                  if (MBLKL(cmd_mp) < sizeof (ilb_servers_cmd_t)) {
18903 18909                          ret = EINVAL;
18904 18910                          break;
18905 18911                  }
18906 18912                  size = cmd->num_servers * sizeof (ilb_server_arg_t);
18907 18913                  if (cmd_mp->b_rptr + offsetof(ilb_servers_cmd_t, servers) +
18908 18914                      size != cmd_mp->b_wptr) {
18909 18915                          ret = EINVAL;
18910 18916                          break;
18911 18917                  }
18912 18918  
18913 18919                  if (command == ILB_DEL_SERVERS)
18914 18920                          f = ilb_server_del;
18915 18921                  else if (command == ILB_ENABLE_SERVERS)
18916 18922                          f = ilb_server_enable;
18917 18923                  else if (command == ILB_DISABLE_SERVERS)
18918 18924                          f = ilb_server_disable;
18919 18925  
18920 18926                  rule = ilb_find_rule(ilbs, zoneid, cmd->name, &ret);
18921 18927                  if (rule == NULL) {
18922 18928                          ASSERT(ret != 0);
18923 18929                          break;
18924 18930                  }
18925 18931  
18926 18932                  for (i = 0; i < cmd->num_servers; i++) {
18927 18933                          ilb_server_arg_t *s;
18928 18934  
18929 18935                          s = &cmd->servers[i];
18930 18936                          s->err = f(ilbs, zoneid, NULL, rule, &s->addr);
18931 18937                  }
18932 18938                  ILB_RULE_REFRELE(rule);
18933 18939                  break;
18934 18940          }
18935 18941          case ILB_LIST_NAT_TABLE: {
18936 18942                  ilb_list_nat_cmd_t *cmd;
18937 18943  
18938 18944                  cmd = (ilb_list_nat_cmd_t *)cmd_mp->b_rptr;
18939 18945                  if (MBLKL(cmd_mp) < sizeof (ilb_list_nat_cmd_t)) {
18940 18946                          ret = EINVAL;
18941 18947                          break;
18942 18948                  }
18943 18949                  size = cmd->num_nat * sizeof (ilb_nat_entry_t);
18944 18950                  if (cmd_mp->b_rptr + offsetof(ilb_list_nat_cmd_t, entries) +
18945 18951                      size != cmd_mp->b_wptr) {
18946 18952                          ret = EINVAL;
18947 18953                          break;
18948 18954                  }
18949 18955  
18950 18956                  ret = ilb_list_nat(ilbs, zoneid, cmd->entries, &cmd->num_nat,
18951 18957                      &cmd->flags);
18952 18958                  break;
18953 18959          }
18954 18960          case ILB_LIST_STICKY_TABLE: {
18955 18961                  ilb_list_sticky_cmd_t *cmd;
18956 18962  
18957 18963                  cmd = (ilb_list_sticky_cmd_t *)cmd_mp->b_rptr;
18958 18964                  if (MBLKL(cmd_mp) < sizeof (ilb_list_sticky_cmd_t)) {
18959 18965                          ret = EINVAL;
18960 18966                          break;
18961 18967                  }
18962 18968                  size = cmd->num_sticky * sizeof (ilb_sticky_entry_t);
18963 18969                  if (cmd_mp->b_rptr + offsetof(ilb_list_sticky_cmd_t, entries) +
18964 18970                      size != cmd_mp->b_wptr) {
18965 18971                          ret = EINVAL;
18966 18972                          break;
18967 18973                  }
18968 18974  
18969 18975                  ret = ilb_list_sticky(ilbs, zoneid, cmd->entries,
18970 18976                      &cmd->num_sticky, &cmd->flags);
18971 18977                  break;
18972 18978          }
18973 18979          default:
18974 18980                  ret = EINVAL;
18975 18981                  break;
18976 18982          }
18977 18983  done:
18978 18984          return (ret);
18979 18985  }
18980 18986  
18981 18987  /* Remove all cache entries for this logical interface */
18982 18988  void
18983 18989  ipif_nce_down(ipif_t *ipif)
18984 18990  {
18985 18991          ill_t *ill = ipif->ipif_ill;
18986 18992          nce_t *nce;
18987 18993  
18988 18994          DTRACE_PROBE3(ipif__downup, char *, "ipif_nce_down",
18989 18995              ill_t *, ill, ipif_t *, ipif);
18990 18996          if (ipif->ipif_added_nce) {
18991 18997                  if (ipif->ipif_isv6)
18992 18998                          nce = nce_lookup_v6(ill, &ipif->ipif_v6lcl_addr);
18993 18999                  else
18994 19000                          nce = nce_lookup_v4(ill, &ipif->ipif_lcl_addr);
18995 19001                  if (nce != NULL) {
18996 19002                          if (--nce->nce_ipif_cnt == 0)
18997 19003                                  ncec_delete(nce->nce_common);
18998 19004                          ipif->ipif_added_nce = 0;
18999 19005                          nce_refrele(nce);
19000 19006                  } else {
19001 19007                          /*
19002 19008                           * nce may already be NULL because it was already
19003 19009                           * flushed, e.g., due to a call to nce_flush
19004 19010                           */
19005 19011                          ipif->ipif_added_nce = 0;
19006 19012                  }
19007 19013          }
19008 19014          /*
19009 19015           * Make IPMP aware of the deleted data address.
19010 19016           */
19011 19017          if (IS_IPMP(ill))
19012 19018                  ipmp_illgrp_del_ipif(ill->ill_grp, ipif);
19013 19019  
19014 19020          /*
19015 19021           * Remove all other nces dependent on this ill when the last ipif
19016 19022           * is going away.
19017 19023           */
19018 19024          if (ill->ill_ipif_up_count == 0) {
19019 19025                  ncec_walk(ill, (pfi_t)ncec_delete_per_ill,
19020 19026                      (uchar_t *)ill, ill->ill_ipst);
19021 19027                  if (IS_UNDER_IPMP(ill))
19022 19028                          nce_flush(ill, B_TRUE);
19023 19029          }
19024 19030  }
19025 19031  
19026 19032  /*
19027 19033   * find the first interface that uses usill for its source address.
19028 19034   */
19029 19035  ill_t *
19030 19036  ill_lookup_usesrc(ill_t *usill)
19031 19037  {
19032 19038          ip_stack_t *ipst = usill->ill_ipst;
19033 19039          ill_t *ill;
19034 19040  
19035 19041          ASSERT(usill != NULL);
19036 19042  
19037 19043          /* ill_g_usesrc_lock protects ill_usesrc_grp_next */
19038 19044          rw_enter(&ipst->ips_ill_g_usesrc_lock, RW_WRITER);
19039 19045          rw_enter(&ipst->ips_ill_g_lock, RW_READER);
19040 19046          for (ill = usill->ill_usesrc_grp_next; ill != NULL && ill != usill;
19041 19047              ill = ill->ill_usesrc_grp_next) {
19042 19048                  if (!IS_UNDER_IPMP(ill) && (ill->ill_flags & ILLF_MULTICAST) &&
19043 19049                      !ILL_IS_CONDEMNED(ill)) {
19044 19050                          ill_refhold(ill);
19045 19051                          break;
19046 19052                  }
19047 19053          }
19048 19054          rw_exit(&ipst->ips_ill_g_lock);
19049 19055          rw_exit(&ipst->ips_ill_g_usesrc_lock);
19050 19056          return (ill);
19051 19057  }
19052 19058  
19053 19059  /*
19054 19060   * This comment applies to both ip_sioctl_get_ifhwaddr and
19055 19061   * ip_sioctl_get_lifhwaddr as the basic function of these two functions
19056 19062   * is the same.
19057 19063   *
19058 19064   * The goal here is to find an IP interface that corresponds to the name
19059 19065   * provided by the caller in the ifreq/lifreq structure held in the mblk_t
19060 19066   * chain and to fill out a sockaddr/sockaddr_storage structure with the
19061 19067   * mac address.
19062 19068   *
19063 19069   * The SIOCGIFHWADDR/SIOCGLIFHWADDR ioctl may return an error for a number
19064 19070   * of different reasons:
19065 19071   * ENXIO - the device name is not known to IP.
19066 19072   * EADDRNOTAVAIL - the device has no hardware address. This is indicated
19067 19073   * by ill_phys_addr not pointing to an actual address.
19068 19074   * EPFNOSUPPORT - this will indicate that a request is being made for a
19069 19075   * mac address that will not fit in the data structure supplier (struct
19070 19076   * sockaddr).
19071 19077   *
19072 19078   */
19073 19079  /* ARGSUSED */
19074 19080  int
19075 19081  ip_sioctl_get_ifhwaddr(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
19076 19082      ip_ioctl_cmd_t *ipip, void *if_req)
19077 19083  {
19078 19084          struct sockaddr *sock;
19079 19085          struct ifreq *ifr;
19080 19086          mblk_t *mp1;
19081 19087          ill_t *ill;
19082 19088  
19083 19089          ASSERT(ipif != NULL);
19084 19090          ill = ipif->ipif_ill;
19085 19091  
19086 19092          if (ill->ill_phys_addr == NULL) {
19087 19093                  return (EADDRNOTAVAIL);
19088 19094          }
19089 19095          if (ill->ill_phys_addr_length > sizeof (sock->sa_data)) {
19090 19096                  return (EPFNOSUPPORT);
19091 19097          }
19092 19098  
19093 19099          ip1dbg(("ip_sioctl_get_hwaddr(%s)\n", ill->ill_name));
19094 19100  
19095 19101          /* Existence of mp1 has been checked in ip_wput_nondata */
19096 19102          mp1 = mp->b_cont->b_cont;
19097 19103          ifr = (struct ifreq *)mp1->b_rptr;
19098 19104  
19099 19105          sock = &ifr->ifr_addr;
19100 19106          /*
19101 19107           * The "family" field in the returned structure is set to a value
19102 19108           * that represents the type of device to which the address belongs.
19103 19109           * The value returned may differ to that on Linux but it will still
19104 19110           * represent the correct symbol on Solaris.
19105 19111           */
19106 19112          sock->sa_family = arp_hw_type(ill->ill_mactype);
19107 19113          bcopy(ill->ill_phys_addr, &sock->sa_data, ill->ill_phys_addr_length);
19108 19114  
19109 19115          return (0);
19110 19116  }
19111 19117  
19112 19118  /*
19113 19119   * The expection of applications using SIOCGIFHWADDR is that data will
19114 19120   * be returned in the sa_data field of the sockaddr structure. With
19115 19121   * SIOCGLIFHWADDR, we're breaking new ground as there is no Linux
19116 19122   * equivalent. In light of this, struct sockaddr_dl is used as it
19117 19123   * offers more space for address storage in sll_data.
19118 19124   */
19119 19125  /* ARGSUSED */
19120 19126  int
19121 19127  ip_sioctl_get_lifhwaddr(ipif_t *ipif, sin_t *dummy_sin, queue_t *q, mblk_t *mp,
19122 19128      ip_ioctl_cmd_t *ipip, void *if_req)
19123 19129  {
19124 19130          struct sockaddr_dl *sock;
19125 19131          struct lifreq *lifr;
19126 19132          mblk_t *mp1;
19127 19133          ill_t *ill;
19128 19134  
19129 19135          ASSERT(ipif != NULL);
19130 19136          ill = ipif->ipif_ill;
19131 19137  
19132 19138          if (ill->ill_phys_addr == NULL) {
19133 19139                  return (EADDRNOTAVAIL);
19134 19140          }
19135 19141          if (ill->ill_phys_addr_length > sizeof (sock->sdl_data)) {
19136 19142                  return (EPFNOSUPPORT);
19137 19143          }
19138 19144  
19139 19145          ip1dbg(("ip_sioctl_get_lifhwaddr(%s)\n", ill->ill_name));
19140 19146  
19141 19147          /* Existence of mp1 has been checked in ip_wput_nondata */
19142 19148          mp1 = mp->b_cont->b_cont;
19143 19149          lifr = (struct lifreq *)mp1->b_rptr;
19144 19150  
19145 19151          /*
19146 19152           * sockaddr_ll is used here because it is also the structure used in
19147 19153           * responding to the same ioctl in sockpfp. The only other choice is
19148 19154           * sockaddr_dl which contains fields that are not required here
19149 19155           * because its purpose is different.
19150 19156           */
19151 19157          lifr->lifr_type = ill->ill_type;
19152 19158          sock = (struct sockaddr_dl *)&lifr->lifr_addr;
19153 19159          sock->sdl_family = AF_LINK;
19154 19160          sock->sdl_index = ill->ill_phyint->phyint_ifindex;
19155 19161          sock->sdl_type = ill->ill_mactype;
19156 19162          sock->sdl_nlen = 0;
19157 19163          sock->sdl_slen = 0;
19158 19164          sock->sdl_alen = ill->ill_phys_addr_length;
19159 19165          bcopy(ill->ill_phys_addr, sock->sdl_data, ill->ill_phys_addr_length);
19160 19166  
19161 19167          return (0);
19162 19168  }
  
    | 
      ↓ open down ↓ | 
    10248 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX