11759 return;
11760 }
11761 iocp->ioc_error = error;
11762
11763 done:
11764 mp->b_datap->db_type = M_IOCACK;
11765 if (iocp->ioc_error)
11766 iocp->ioc_count = 0;
11767 qreply(q, mp);
11768 }
11769
11770 /*
11771 * Assign a unique id for the ipif. This is used by sctp_addr.c
11772 * Note: remove if sctp_addr.c is redone to not shadow ill/ipif data structures.
11773 */
11774 static void
11775 ipif_assign_seqid(ipif_t *ipif)
11776 {
11777 ip_stack_t *ipst = ipif->ipif_ill->ill_ipst;
11778
11779 ipif->ipif_seqid = atomic_add_64_nv(&ipst->ips_ipif_g_seqid, 1);
11780 }
11781
11782 /*
11783 * Clone the contents of `sipif' to `dipif'. Requires that both ipifs are
11784 * administratively down (i.e., no DAD), of the same type, and locked. Note
11785 * that the clone is complete -- including the seqid -- and the expectation is
11786 * that the caller will either free or overwrite `sipif' before it's unlocked.
11787 */
11788 static void
11789 ipif_clone(const ipif_t *sipif, ipif_t *dipif)
11790 {
11791 ASSERT(MUTEX_HELD(&sipif->ipif_ill->ill_lock));
11792 ASSERT(MUTEX_HELD(&dipif->ipif_ill->ill_lock));
11793 ASSERT(!(sipif->ipif_flags & (IPIF_UP|IPIF_DUPLICATE)));
11794 ASSERT(!(dipif->ipif_flags & (IPIF_UP|IPIF_DUPLICATE)));
11795 ASSERT(sipif->ipif_ire_type == dipif->ipif_ire_type);
11796
11797 dipif->ipif_flags = sipif->ipif_flags;
11798 dipif->ipif_zoneid = sipif->ipif_zoneid;
11799 dipif->ipif_v6subnet = sipif->ipif_v6subnet;
12432 if (logical) {
12433 (void) ipif_logical_down(ipif, NULL, NULL);
12434 ipif_non_duplicate(ipif);
12435 (void) ipif_down_tail(ipif);
12436 } else {
12437 (void) ipif_down(ipif, NULL, NULL);
12438 }
12439 }
12440 }
12441
12442 /*
12443 * Redo source address selection. This makes IXAF_VERIFY_SOURCE take
12444 * a look again at valid source addresses.
12445 * This should be called each time after the set of source addresses has been
12446 * changed.
12447 */
12448 void
12449 ip_update_source_selection(ip_stack_t *ipst)
12450 {
12451 /* We skip past SRC_GENERATION_VERIFY */
12452 if (atomic_add_32_nv(&ipst->ips_src_generation, 1) ==
12453 SRC_GENERATION_VERIFY)
12454 atomic_add_32(&ipst->ips_src_generation, 1);
12455 }
12456
12457 /*
12458 * Finish the group join started in ip_sioctl_groupname().
12459 */
12460 /* ARGSUSED */
12461 static void
12462 ip_join_illgrps(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy)
12463 {
12464 ill_t *ill = q->q_ptr;
12465 phyint_t *phyi = ill->ill_phyint;
12466 ipmp_grp_t *grp = phyi->phyint_grp;
12467 ip_stack_t *ipst = ill->ill_ipst;
12468
12469 /* IS_UNDER_IPMP() won't work until ipmp_ill_join_illgrp() is called */
12470 ASSERT(!IS_IPMP(ill) && grp != NULL);
12471 ASSERT(IAM_WRITER_IPSQ(ipsq));
12472
12473 if (phyi->phyint_illv4 != NULL) {
12474 rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
|
11759 return;
11760 }
11761 iocp->ioc_error = error;
11762
11763 done:
11764 mp->b_datap->db_type = M_IOCACK;
11765 if (iocp->ioc_error)
11766 iocp->ioc_count = 0;
11767 qreply(q, mp);
11768 }
11769
11770 /*
11771 * Assign a unique id for the ipif. This is used by sctp_addr.c
11772 * Note: remove if sctp_addr.c is redone to not shadow ill/ipif data structures.
11773 */
11774 static void
11775 ipif_assign_seqid(ipif_t *ipif)
11776 {
11777 ip_stack_t *ipst = ipif->ipif_ill->ill_ipst;
11778
11779 ipif->ipif_seqid = atomic_inc_64_nv(&ipst->ips_ipif_g_seqid);
11780 }
11781
11782 /*
11783 * Clone the contents of `sipif' to `dipif'. Requires that both ipifs are
11784 * administratively down (i.e., no DAD), of the same type, and locked. Note
11785 * that the clone is complete -- including the seqid -- and the expectation is
11786 * that the caller will either free or overwrite `sipif' before it's unlocked.
11787 */
11788 static void
11789 ipif_clone(const ipif_t *sipif, ipif_t *dipif)
11790 {
11791 ASSERT(MUTEX_HELD(&sipif->ipif_ill->ill_lock));
11792 ASSERT(MUTEX_HELD(&dipif->ipif_ill->ill_lock));
11793 ASSERT(!(sipif->ipif_flags & (IPIF_UP|IPIF_DUPLICATE)));
11794 ASSERT(!(dipif->ipif_flags & (IPIF_UP|IPIF_DUPLICATE)));
11795 ASSERT(sipif->ipif_ire_type == dipif->ipif_ire_type);
11796
11797 dipif->ipif_flags = sipif->ipif_flags;
11798 dipif->ipif_zoneid = sipif->ipif_zoneid;
11799 dipif->ipif_v6subnet = sipif->ipif_v6subnet;
12432 if (logical) {
12433 (void) ipif_logical_down(ipif, NULL, NULL);
12434 ipif_non_duplicate(ipif);
12435 (void) ipif_down_tail(ipif);
12436 } else {
12437 (void) ipif_down(ipif, NULL, NULL);
12438 }
12439 }
12440 }
12441
12442 /*
12443 * Redo source address selection. This makes IXAF_VERIFY_SOURCE take
12444 * a look again at valid source addresses.
12445 * This should be called each time after the set of source addresses has been
12446 * changed.
12447 */
12448 void
12449 ip_update_source_selection(ip_stack_t *ipst)
12450 {
12451 /* We skip past SRC_GENERATION_VERIFY */
12452 if (atomic_inc_32_nv(&ipst->ips_src_generation) ==
12453 SRC_GENERATION_VERIFY)
12454 atomic_inc_32(&ipst->ips_src_generation);
12455 }
12456
12457 /*
12458 * Finish the group join started in ip_sioctl_groupname().
12459 */
12460 /* ARGSUSED */
12461 static void
12462 ip_join_illgrps(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy)
12463 {
12464 ill_t *ill = q->q_ptr;
12465 phyint_t *phyi = ill->ill_phyint;
12466 ipmp_grp_t *grp = phyi->phyint_grp;
12467 ip_stack_t *ipst = ill->ill_ipst;
12468
12469 /* IS_UNDER_IPMP() won't work until ipmp_ill_join_illgrp() is called */
12470 ASSERT(!IS_IPMP(ill) && grp != NULL);
12471 ASSERT(IAM_WRITER_IPSQ(ipsq));
12472
12473 if (phyi->phyint_illv4 != NULL) {
12474 rw_enter(&ipst->ips_ipmp_lock, RW_WRITER);
|