diff options
author | vi117747 <none@none> | 2007-01-30 00:04:35 -0800 |
---|---|---|
committer | vi117747 <none@none> | 2007-01-30 00:04:35 -0800 |
commit | e35d2278fa5447def80bb5a191ce0f1c6b6836de (patch) | |
tree | eff5d8c8c47d17a8d4f9319983624a79bf60f8f3 | |
parent | 691b55abbc2aa71b47338f7971838df72745f2da (diff) | |
download | illumos-gate-e35d2278fa5447def80bb5a191ce0f1c6b6836de.tar.gz |
6473179 SCTP assoc. should be resilient to addrs. being un-plumbed and re-plumbed on a diff. interface
-rw-r--r-- | usr/src/uts/common/inet/ip/ip.c | 27 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6.c | 13 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_if.c | 39 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/sadb.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_addr.c | 584 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_addr.h | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_common.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_cookie.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_hash.c | 64 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_impl.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_input.c | 7 | ||||
-rw-r--r-- | usr/src/uts/common/inet/sctp_ip.h | 11 |
12 files changed, 511 insertions, 268 deletions
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 83e13a8bd1..83b9fcd4a4 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -2137,7 +2137,7 @@ icmp_get_nexthop_addr(ipha_t *ipha, ill_t *ill, zoneid_t zoneid, mblk_t *mp) ((uint16_t *)&ports)[1] = up[0]; connp = sctp_find_conn(&map_src, &map_dst, ports, - 0, zoneid, ipst->ips_netstack->netstack_sctp); + zoneid, ipst->ips_netstack->netstack_sctp); if (connp == NULL) { connp = ipcl_classify_raw(mp, IPPROTO_SCTP, zoneid, ports, ipha, ipst); @@ -2562,7 +2562,7 @@ icmp_inbound_error_fanout(queue_t *q, ill_t *ill, mblk_t *mp, /* Have to change db_type after any pullupmsg */ DB_TYPE(mp) = M_CTL; ip_fanout_sctp(first_mp, recv_ill, &ripha, ports, 0, - mctl_present, ip_policy, 0, zoneid); + mctl_present, ip_policy, zoneid); return; case IPPROTO_ESP: @@ -13624,7 +13624,6 @@ ip_sctp_input(mblk_t *mp, ipha_t *ipha, ill_t *recv_ill, boolean_t mctl_present, uint32_t pktsum; uint32_t calcsum; uint32_t ports; - uint_t ipif_seqid; in6_addr_t map_src, map_dst; ill_t *ill = (ill_t *)q->q_ptr; ip_stack_t *ipst; @@ -13720,12 +13719,11 @@ find_sctp_client: /* get the ports */ ports = *(uint32_t *)&sctph->sh_sport; - ipif_seqid = ire->ire_ipif->ipif_seqid; IRE_REFRELE(ire); IN6_IPADDR_TO_V4MAPPED(ipha->ipha_dst, &map_dst); IN6_IPADDR_TO_V4MAPPED(ipha->ipha_src, &map_src); - if ((connp = sctp_fanout(&map_src, &map_dst, ports, ipif_seqid, zoneid, - mp, sctps)) == NULL) { + if ((connp = sctp_fanout(&map_src, &map_dst, ports, zoneid, mp, + sctps)) == NULL) { /* Check for raw socket or OOTB handling */ goto no_conn; } @@ -13737,7 +13735,7 @@ find_sctp_client: no_conn: ip_fanout_sctp_raw(first_mp, recv_ill, ipha, B_TRUE, - ports, mctl_present, flags, B_TRUE, ipif_seqid, zoneid); + ports, mctl_present, flags, B_TRUE, zoneid); return; ipoptions: @@ -16333,8 +16331,13 @@ ip_rput_dlpi_writer(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *dummy_arg) ASSERT(ill->ill_ipif->ipif_id == 0); if (ipif != NULL && - IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr)) + IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr)) { + in6_addr_t ov6addr; + + ov6addr = ipif->ipif_v6lcl_addr; (void) ipif_setlinklocal(ipif); + sctp_update_ipif_addr(ipif, ov6addr); + } break; } case DL_OK_ACK: @@ -25389,8 +25392,7 @@ ip_wput_local(queue_t *q, ill_t *ill, ipha_t *ipha, mblk_t *mp, ire_t *ire, bcopy(rptr + IPH_HDR_LENGTH(ipha), &ports, sizeof (ports)); ip_fanout_sctp(first_mp, ill, ipha, ports, fanout_flags | IP_FF_SEND_ICMP | IP_FF_HDR_COMPLETE | - IP_FF_IPINFO, - mctl_present, B_FALSE, 0, zoneid); + IP_FF_IPINFO, mctl_present, B_FALSE, zoneid); return; } @@ -29770,7 +29772,7 @@ icmp_kstat_update(kstat_t *kp, int rw) void ip_fanout_sctp_raw(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, boolean_t isv4, uint32_t ports, boolean_t mctl_present, uint_t flags, boolean_t ip_policy, - uint_t ipif_seqid, zoneid_t zoneid) + zoneid_t zoneid) { conn_t *connp; queue_t *rq; @@ -29792,8 +29794,7 @@ ip_fanout_sctp_raw(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, boolean_t isv4, connp = ipcl_classify_raw(mp, IPPROTO_SCTP, zoneid, ports, ipha, ipst); if (connp == NULL) { - sctp_ootb_input(first_mp, recv_ill, ipif_seqid, zoneid, - mctl_present); + sctp_ootb_input(first_mp, recv_ill, zoneid, mctl_present); return; } rq = connp->conn_rq; diff --git a/usr/src/uts/common/inet/ip/ip6.c b/usr/src/uts/common/inet/ip/ip6.c index 49938b8eac..2bbf82030f 100644 --- a/usr/src/uts/common/inet/ip/ip6.c +++ b/usr/src/uts/common/inet/ip/ip6.c @@ -952,7 +952,7 @@ icmp_inbound_error_fanout_v6(queue_t *q, mblk_t *mp, ip6_t *ip6h, ((uint16_t *)&ports)[0] = up[1]; ((uint16_t *)&ports)[1] = up[0]; ip_fanout_sctp(mp, ill, (ipha_t *)ip6h, ports, 0, mctl_present, - IP6_NO_IPPOLICY, 0, zoneid); + IP6_NO_IPPOLICY, zoneid); return; case IPPROTO_ESP: case IPPROTO_AH: { @@ -7266,7 +7266,6 @@ ip_rput_data_v6(queue_t *q, ill_t *inill, mblk_t *mp, ip6_t *ip6h, conn_t *connp; ilm_t *ilm; uint32_t ports; - uint_t ipif_id = 0; zoneid_t zoneid = GLOBAL_ZONEID; uint16_t hck_flags, reass_hck_flags; uint32_t reass_sum; @@ -7504,7 +7503,6 @@ ip_rput_data_v6(queue_t *q, ill_t *inill, mblk_t *mp, ip6_t *ip6h, ALL_ZONES, ipst); return; } - ipif_id = ire->ire_ipif->ipif_seqid; /* we have a matching IRE */ if (ire->ire_stq != NULL) { ill_group_t *ill_group; @@ -7925,12 +7923,12 @@ tcp_fanout: sctph->sh_chksum = pktsum; ports = *(uint32_t *)(mp->b_rptr + hdr_len); if ((connp = sctp_fanout(&ip6h->ip6_src, &ip6h->ip6_dst, - ports, ipif_id, zoneid, mp, sctps)) == NULL) { + ports, zoneid, mp, sctps)) == NULL) { ip_fanout_sctp_raw(first_mp, ill, (ipha_t *)ip6h, B_FALSE, ports, mctl_present, (flags|IP_FF_SEND_ICMP|IP_FF_IPINFO), - B_TRUE, ipif_id, zoneid); + B_TRUE, zoneid); return; } BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers); @@ -10732,13 +10730,10 @@ ip_wput_local_v6(queue_t *q, ill_t *ill, ip6_t *ip6h, mblk_t *first_mp, case IPPROTO_SCTP: { - uint_t ipif_seqid = ire->ire_ipif->ipif_seqid; - ports = *(uint32_t *)(mp->b_rptr + hdr_length); ip_fanout_sctp(mp, ill, (ipha_t *)ip6h, ports, fanout_flags|IP_FF_SEND_ICMP|IP_FF_IPINFO, - mctl_present, IP6_NO_IPPOLICY, ipif_seqid, - ire->ire_zoneid); + mctl_present, IP6_NO_IPPOLICY, ire->ire_zoneid); return; } case IPPROTO_ICMPV6: { diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c index a7aac93eda..4f0694b33b 100644 --- a/usr/src/uts/common/inet/ip/ip_if.c +++ b/usr/src/uts/common/inet/ip/ip_if.c @@ -5029,6 +5029,7 @@ ill_lookup_on_name(char *name, boolean_t do_alloc, boolean_t isv6, kstat_named_t *kn; boolean_t isloopback; ipsq_t *old_ipsq; + in6_addr_t ov6addr; isloopback = mi_strcmp(name, ipif_loopback_name) == 0; @@ -5126,6 +5127,7 @@ ill_lookup_on_name(char *name, boolean_t do_alloc, boolean_t isv6, ill->ill_flags = ILLF_MULTICAST; + ov6addr = ipif->ipif_v6lcl_addr; /* Set up default loopback address and mask. */ if (!isv6) { ipaddr_t inaddr_loopback = htonl(INADDR_LOOPBACK); @@ -5164,8 +5166,13 @@ ill_lookup_on_name(char *name, boolean_t do_alloc, boolean_t isv6, /* Let SCTP know so that it can add this to its list */ sctp_update_ill(ill, SCTP_ILL_INSERT); - /* Let SCTP know about this IPIF, so that it can add it to its list */ - sctp_update_ipif(ipif, SCTP_IPIF_INSERT); + /* + * We have already assigned ipif_v6lcl_addr above, but we need to + * call sctp_update_ipif_addr() after SCTP_ILL_INSERT, which + * requires to be after ill_glist_insert() since we need the + * ill_index set. Pass on ipv6_loopback as the old address. + */ + sctp_update_ipif_addr(ipif, ov6addr); /* * If the ipsq was changed in ill_phyint_reinit free the old ipsq. @@ -11391,6 +11398,7 @@ ip_sioctl_addr_tail(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp, boolean_t need_up) { in6_addr_t v6addr; + in6_addr_t ov6addr; ipaddr_t addr; sin6_t *sin6; int sinlen; @@ -11421,7 +11429,9 @@ ip_sioctl_addr_tail(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp, sinlen = sizeof (struct sockaddr_in); } mutex_enter(&ill->ill_lock); + ov6addr = ipif->ipif_v6lcl_addr; ipif->ipif_v6lcl_addr = v6addr; + sctp_update_ipif_addr(ipif, ov6addr); if (ipif->ipif_flags & (IPIF_ANYCAST | IPIF_NOLOCAL)) { ipif->ipif_v6src_addr = ipv6_all_zeros; } else { @@ -11536,12 +11546,6 @@ ip_sioctl_addr_tail(ipif_t *ipif, sin_t *sin, queue_t *q, mblk_t *mp, * ip_rput_dlpi when we see the DL_BIND_ACK. */ err = ipif_up(ipif, q, mp); - } else { - /* - * Update the IPIF list in SCTP, ipif_up_done() will do it - * if need_up is true. - */ - sctp_update_ipif(ipif, SCTP_IPIF_UPDATE); } if (need_dl_down) @@ -12347,9 +12351,13 @@ ip_sioctl_flags_tail(ipif_t *ipif, uint64_t flags, queue_t *q, mblk_t *mp, if (((turn_on | turn_off) & (PHYI_FAILED|PHYI_STANDBY|PHYI_OFFLINE))) ip_redo_nomination(phyi); - if (set_linklocal) - (void) ipif_setlinklocal(ipif); + if (set_linklocal) { + in6_addr_t ov6addr; + ov6addr = ipif->ipif_v6lcl_addr; + (void) ipif_setlinklocal(ipif); + sctp_update_ipif_addr(ipif, ov6addr); + } if (zero_source) ipif->ipif_v6src_addr = ipv6_all_zeros; else @@ -12382,6 +12390,8 @@ ip_sioctl_flags_tail(ipif_t *ipif, uint64_t flags, queue_t *q, mblk_t *mp, ip_rts_ifmsg(ipif); } } + /* Update the flags in SCTP's IPIF list */ + sctp_update_ipif(ipif, SCTP_IPIF_UPDATE); return (err); } @@ -13645,11 +13655,9 @@ ipif_allocate(ill_t *ill, int id, uint_t ire_type, boolean_t initialize) id = ipif->ipif_id; ASSERT(id >= 0); - if (ill->ill_name[0] != '\0') { + if (ill->ill_name[0] != '\0') ipif_assign_seqid(ipif); - if (ill->ill_phyint->phyint_ifindex != 0) - sctp_update_ipif(ipif, SCTP_IPIF_INSERT); - } + /* * Keep a copy of original id in ipif_orig_ipifid. Failback * will attempt to restore the original id. The SIOCSLIFOINDEX @@ -23267,9 +23275,6 @@ ipif_set_values(queue_t *q, mblk_t *mp, char *interf_name, uint_t *new_ppa_ptr) /* Let SCTP know about this ILL */ sctp_update_ill(ill, SCTP_ILL_INSERT); - /* and also about the first ipif */ - sctp_update_ipif(ipif, SCTP_IPIF_INSERT); - ipsq = ipsq_try_enter(NULL, ill, q, mp, ip_reprocess_ioctl, NEW_OP, B_TRUE); diff --git a/usr/src/uts/common/inet/ip/sadb.c b/usr/src/uts/common/inet/ip/sadb.c index 70d1f1f23d..51e6be5278 100644 --- a/usr/src/uts/common/inet/ip/sadb.c +++ b/usr/src/uts/common/inet/ip/sadb.c @@ -5681,11 +5681,11 @@ ipsec_sctp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, IN6_IPADDR_TO_V4MAPPED(sel->ips_remote_addr_v4, &dst); IN6_IPADDR_TO_V4MAPPED(sel->ips_local_addr_v4, &src); - connp = sctp_find_conn(&dst, &src, ports, 0, ALL_ZONES, + connp = sctp_find_conn(&dst, &src, ports, ALL_ZONES, ipst->ips_netstack->netstack_sctp); } else { connp = sctp_find_conn(&sel->ips_remote_addr_v6, - &sel->ips_local_addr_v6, ports, 0, ALL_ZONES, + &sel->ips_local_addr_v6, ports, ALL_ZONES, ipst->ips_netstack->netstack_sctp); } if (connp == NULL) diff --git a/usr/src/uts/common/inet/sctp/sctp_addr.c b/usr/src/uts/common/inet/sctp/sctp_addr.c index 946d85b3b1..d181162fd3 100644 --- a/usr/src/uts/common/inet/sctp/sctp_addr.c +++ b/usr/src/uts/common/inet/sctp/sctp_addr.c @@ -50,13 +50,13 @@ static void sctp_ipif_inactive(sctp_ipif_t *); static sctp_ipif_t *sctp_lookup_ipif_addr(in6_addr_t *, boolean_t, - sctp_t *, uint_t); + zoneid_t, boolean_t, uint_t, uint_t, boolean_t, + sctp_stack_t *); static int sctp_get_all_ipifs(sctp_t *, int); int sctp_valid_addr_list(sctp_t *, const void *, uint32_t, uchar_t *, size_t); -sctp_saddr_ipif_t *sctp_ipif_lookup(sctp_t *, uint_t); static int sctp_ipif_hash_insert(sctp_t *, sctp_ipif_t *, int, - boolean_t dontsrc); + boolean_t, boolean_t); static void sctp_ipif_hash_remove(sctp_t *, sctp_ipif_t *); static int sctp_compare_ipif_list(sctp_ipif_hash_t *, sctp_ipif_hash_t *); @@ -76,6 +76,19 @@ int sctp_getmyaddrs(void *, void *, int *); void sctp_saddr_init(sctp_stack_t *); void sctp_saddr_fini(sctp_stack_t *); +#define SCTP_ADDR4_HASH(addr) \ + (((addr) ^ ((addr) >> 8) ^ ((addr) >> 16) ^ ((addr) >> 24)) & \ + (SCTP_IPIF_HASH - 1)) + +#define SCTP_ADDR6_HASH(addr) \ + (((addr).s6_addr32[3] ^ \ + (((addr).s6_addr32[3] ^ (addr).s6_addr32[2]) >> 12)) & \ + (SCTP_IPIF_HASH - 1)) + +#define SCTP_IPIF_ADDR_HASH(addr, isv6) \ + ((isv6) ? SCTP_ADDR6_HASH((addr)) : \ + SCTP_ADDR4_HASH((addr)._S6_un._S6_u32[3])) + #define SCTP_IPIF_USABLE(sctp_ipif_state) \ ((sctp_ipif_state) == SCTP_IPIFS_UP || \ (sctp_ipif_state) == SCTP_IPIFS_DOWN) @@ -98,27 +111,21 @@ void sctp_saddr_fini(sctp_stack_t *); IPCL_ZONE_MATCH((sctp)->sctp_connp, (ipif)->sctp_ipif_zoneid) #define SCTP_ILL_HASH_FN(index) ((index) % SCTP_ILL_HASH) -#define SCTP_IPIF_HASH_FN(seqid) ((seqid) % SCTP_IPIF_HASH) #define SCTP_ILL_TO_PHYINDEX(ill) ((ill)->ill_phyint->phyint_ifindex) /* - * - * * SCTP Interface list manipulation functions, locking used. - * - * */ /* * Delete an SCTP IPIF from the list if the refcount goes to 0 and it is * marked as condemned. Also, check if the ILL needs to go away. - * Called with no locks held. */ static void sctp_ipif_inactive(sctp_ipif_t *sctp_ipif) { sctp_ill_t *sctp_ill; - uint_t ipif_index; + uint_t hindex; uint_t ill_index; sctp_stack_t *sctps = sctp_ipif->sctp_ipif_ill-> sctp_ill_netstack->netstack_sctp; @@ -126,7 +133,9 @@ sctp_ipif_inactive(sctp_ipif_t *sctp_ipif) rw_enter(&sctps->sctps_g_ills_lock, RW_READER); rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER); - ipif_index = SCTP_IPIF_HASH_FN(sctp_ipif->sctp_ipif_id); + hindex = SCTP_IPIF_ADDR_HASH(sctp_ipif->sctp_ipif_saddr, + sctp_ipif->sctp_ipif_isv6); + sctp_ill = sctp_ipif->sctp_ipif_ill; ASSERT(sctp_ill != NULL); ill_index = SCTP_ILL_HASH_FN(sctp_ill->sctp_ill_index); @@ -136,9 +145,9 @@ sctp_ipif_inactive(sctp_ipif_t *sctp_ipif) rw_exit(&sctps->sctps_g_ills_lock); return; } - list_remove(&sctps->sctps_g_ipifs[ipif_index].sctp_ipif_list, + list_remove(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif); - sctps->sctps_g_ipifs[ipif_index].ipif_count--; + sctps->sctps_g_ipifs[hindex].ipif_count--; sctps->sctps_g_ipifs_count--; rw_destroy(&sctp_ipif->sctp_ipif_lock); kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); @@ -163,41 +172,67 @@ sctp_ipif_inactive(sctp_ipif_t *sctp_ipif) /* * Lookup an SCTP IPIF given an IP address. Increments sctp_ipif refcnt. - * Called with no locks held. + * We are either looking for a IPIF with the given address before + * inserting it into the global list or looking for an IPIF for an + * address given an SCTP. In the former case we always check the zoneid, + * but for the latter case, check_zid could be B_FALSE if the connp + * for the sctp has conn_all_zones set. When looking for an address we + * give preference to one that is up, so even though we may find one that + * is not up we keep looking if there is one up, we hold the down addr + * in backup_ipif in case we don't find one that is up - i.e. we return + * the backup_ipif in that case. Note that if we are looking for. If we + * are specifically looking for an up address, then usable will be set + * to true. */ static sctp_ipif_t * -sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, sctp_t *sctp, - uint_t ifindex) +sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid, + boolean_t check_zid, uint_t ifindex, uint_t seqid, boolean_t usable, + sctp_stack_t *sctps) { - int i; int j; sctp_ipif_t *sctp_ipif; - sctp_stack_t *sctps = sctp->sctp_sctps; + sctp_ipif_t *backup_ipif = NULL; + int hindex; + + hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr)); - ASSERT(sctp->sctp_zoneid != ALL_ZONES); rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER); - for (i = 0; i < SCTP_IPIF_HASH; i++) { - if (sctps->sctps_g_ipifs[i].ipif_count == 0) - continue; - sctp_ipif = list_head(&sctps->sctps_g_ipifs[i].sctp_ipif_list); - for (j = 0; j < sctps->sctps_g_ipifs[i].ipif_count; j++) { - rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); - if (SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) && - SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) && - (ifindex == 0 || ifindex == - sctp_ipif->sctp_ipif_ill->sctp_ill_index) && - IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr, - addr)) { + if (sctps->sctps_g_ipifs[hindex].ipif_count == 0) { + rw_exit(&sctps->sctps_g_ipifs_lock); + return (NULL); + } + sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); + for (j = 0; j < sctps->sctps_g_ipifs[hindex].ipif_count; j++) { + rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); + if ((!check_zid || + (sctp_ipif->sctp_ipif_zoneid == ALL_ZONES || + zoneid == sctp_ipif->sctp_ipif_zoneid)) && + (ifindex == 0 || ifindex == + sctp_ipif->sctp_ipif_ill->sctp_ill_index) && + ((seqid != 0 && seqid == sctp_ipif->sctp_ipif_id) || + (IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr, + addr)))) { + if (!usable || sctp_ipif->sctp_ipif_state == + SCTP_IPIFS_UP) { rw_exit(&sctp_ipif->sctp_ipif_lock); if (refhold) SCTP_IPIF_REFHOLD(sctp_ipif); rw_exit(&sctps->sctps_g_ipifs_lock); return (sctp_ipif); + } else if (sctp_ipif->sctp_ipif_state == + SCTP_IPIFS_DOWN && backup_ipif == NULL) { + backup_ipif = sctp_ipif; } - rw_exit(&sctp_ipif->sctp_ipif_lock); - sctp_ipif = list_next( - &sctps->sctps_g_ipifs[i].sctp_ipif_list, sctp_ipif); } + rw_exit(&sctp_ipif->sctp_ipif_lock); + sctp_ipif = list_next( + &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif); + } + if (backup_ipif != NULL) { + if (refhold) + SCTP_IPIF_REFHOLD(backup_ipif); + rw_exit(&sctps->sctps_g_ipifs_lock); + return (backup_ipif); } rw_exit(&sctps->sctps_g_ipifs_lock); return (NULL); @@ -240,8 +275,8 @@ sctp_get_all_ipifs(sctp_t *sctp, int sleep) rw_exit(&sctp_ipif->sctp_ipif_lock); SCTP_IPIF_REFHOLD(sctp_ipif); error = sctp_ipif_hash_insert(sctp, sctp_ipif, sleep, - B_FALSE); - if (error != 0) + B_FALSE, B_FALSE); + if (error != 0 && error != EALREADY) goto free_stuff; sctp_ipif = list_next( &sctps->sctps_g_ipifs[i].sctp_ipif_list, @@ -360,8 +395,9 @@ sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt, goto free_ret; } if (lookup_saddr) { - ipif = sctp_lookup_ipif_addr(&addr, B_TRUE, sctp, - ifindex); + ipif = sctp_lookup_ipif_addr(&addr, B_TRUE, + sctp->sctp_zoneid, !sctp->sctp_connp->conn_allzones, + ifindex, 0, B_TRUE, sctp->sctp_sctps); if (ipif == NULL) { /* Address not in the list */ err = EINVAL; @@ -382,7 +418,7 @@ sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt, * get the ASCONF ACK for this address. */ err = sctp_ipif_hash_insert(sctp, ipif, KM_SLEEP, - check_addrs ? B_TRUE : B_FALSE); + check_addrs ? B_TRUE : B_FALSE, B_FALSE); if (err != 0) { SCTP_IPIF_REFRELE(ipif); if (check_addrs && err == EALREADY) @@ -426,39 +462,35 @@ free_ret: return (err); } -sctp_saddr_ipif_t * -sctp_ipif_lookup(sctp_t *sctp, uint_t ipif_index) -{ - int cnt; - int seqid = SCTP_IPIF_HASH_FN(ipif_index); - sctp_saddr_ipif_t *ipif_obj; - - if (sctp->sctp_saddrs[seqid].ipif_count == 0) - return (NULL); - - ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list); - for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) { - if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif_index) - return (ipif_obj); - ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list, - ipif_obj); - } - return (NULL); -} - static int sctp_ipif_hash_insert(sctp_t *sctp, sctp_ipif_t *ipif, int sleep, - boolean_t dontsrc) + boolean_t dontsrc, boolean_t allow_dup) { int cnt; sctp_saddr_ipif_t *ipif_obj; - int seqid = SCTP_IPIF_HASH_FN(ipif->sctp_ipif_id); - - ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list); - for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) { - if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif->sctp_ipif_id) - return (EALREADY); - ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list, + int hindex; + + hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr, + ipif->sctp_ipif_isv6); + ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list); + for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) { + if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr, + &ipif->sctp_ipif_saddr)) { + if (ipif->sctp_ipif_id != + ipif_obj->saddr_ipifp->sctp_ipif_id && + ipif_obj->saddr_ipifp->sctp_ipif_state == + SCTP_IPIFS_DOWN && ipif->sctp_ipif_state == + SCTP_IPIFS_UP) { + SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp); + ipif_obj->saddr_ipifp = ipif; + ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0; + return (0); + } else if (!allow_dup || ipif->sctp_ipif_id == + ipif_obj->saddr_ipifp->sctp_ipif_id) { + return (EALREADY); + } + } + ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj); } ipif_obj = kmem_zalloc(sizeof (sctp_saddr_ipif_t), sleep); @@ -468,8 +500,8 @@ sctp_ipif_hash_insert(sctp_t *sctp, sctp_ipif_t *ipif, int sleep, } ipif_obj->saddr_ipifp = ipif; ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0; - list_insert_tail(&sctp->sctp_saddrs[seqid].sctp_ipif_list, ipif_obj); - sctp->sctp_saddrs[seqid].ipif_count++; + list_insert_tail(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj); + sctp->sctp_saddrs[hindex].ipif_count++; sctp->sctp_nsaddrs++; return (0); } @@ -479,20 +511,23 @@ sctp_ipif_hash_remove(sctp_t *sctp, sctp_ipif_t *ipif) { int cnt; sctp_saddr_ipif_t *ipif_obj; - int seqid = SCTP_IPIF_HASH_FN(ipif->sctp_ipif_id); - - ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list); - for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) { - if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif->sctp_ipif_id) { - list_remove(&sctp->sctp_saddrs[seqid].sctp_ipif_list, + int hindex; + + hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr, + ipif->sctp_ipif_isv6); + ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list); + for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) { + if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr, + &ipif->sctp_ipif_saddr)) { + list_remove(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj); + sctp->sctp_saddrs[hindex].ipif_count--; sctp->sctp_nsaddrs--; - sctp->sctp_saddrs[seqid].ipif_count--; SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp); kmem_free(ipif_obj, sizeof (sctp_saddr_ipif_t)); break; } - ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list, + ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj); } } @@ -510,8 +545,9 @@ sctp_compare_ipif_list(sctp_ipif_hash_t *list1, sctp_ipif_hash_t *list2) for (i = 0; i < list1->ipif_count; i++) { obj2 = list_head(&list2->sctp_ipif_list); for (j = 0; j < list2->ipif_count; j++) { - if (obj1->saddr_ipifp->sctp_ipif_id == - obj2->saddr_ipifp->sctp_ipif_id) { + if (IN6_ARE_ADDR_EQUAL( + &obj1->saddr_ipifp->sctp_ipif_saddr, + &obj2->saddr_ipifp->sctp_ipif_saddr)) { overlap++; break; } @@ -559,7 +595,8 @@ sctp_copy_ipifs(sctp_ipif_hash_t *list1, sctp_t *sctp2, int sleep) for (i = 0; i < list1->ipif_count; i++) { SCTP_IPIF_REFHOLD(obj->saddr_ipifp); error = sctp_ipif_hash_insert(sctp2, obj->saddr_ipifp, sleep, - B_FALSE); + B_FALSE, B_FALSE); + ASSERT(error != EALREADY); if (error != 0) return (error); obj = list_next(&list1->sctp_ipif_list, obj); @@ -628,8 +665,6 @@ sctp_update_ill(ill_t *ill, int op) netstack_t *ns = ill->ill_ipst->ips_netstack; sctp_stack_t *sctps = ns->netstack_sctp; - ip2dbg(("sctp_update_ill: %s\n", ill->ill_name)); - rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER); index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); @@ -657,8 +692,8 @@ sctp_update_ill(ill_t *ill, int op) rw_exit(&sctps->sctps_g_ills_lock); return; } - sctp_ill->sctp_ill_name = - kmem_zalloc(ill->ill_name_length, KM_NOSLEEP); + sctp_ill->sctp_ill_name = kmem_zalloc(ill->ill_name_length, + KM_NOSLEEP); if (sctp_ill->sctp_ill_name == NULL) { ip1dbg(("sctp_ill_insert: mem error..\n")); kmem_free(sctp_ill, sizeof (sctp_ill_t)); @@ -708,7 +743,7 @@ sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill) sctp_ill_t *fsctp_ill = NULL; sctp_ill_t *tsctp_ill = NULL; sctp_ipif_t *sctp_ipif; - uint_t index; + uint_t hindex; int i; netstack_t *ns = ipif->ipif_ill->ill_ipst->ips_netstack; sctp_stack_t *sctps = ns->netstack_sctp; @@ -716,31 +751,32 @@ sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill) rw_enter(&sctps->sctps_g_ills_lock, RW_READER); rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER); - index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill)); - fsctp_ill = list_head(&sctps->sctps_g_ills[index].sctp_ill_list); - for (i = 0; i < sctps->sctps_g_ills[index].ill_count; i++) { + hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill)); + fsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list); + for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) { if (fsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(f_ill)) break; - fsctp_ill = list_next(&sctps->sctps_g_ills[index].sctp_ill_list, - fsctp_ill); + fsctp_ill = list_next( + &sctps->sctps_g_ills[hindex].sctp_ill_list, fsctp_ill); } - index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill)); - tsctp_ill = list_head(&sctps->sctps_g_ills[index].sctp_ill_list); - for (i = 0; i < sctps->sctps_g_ills[index].ill_count; i++) { + hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill)); + tsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list); + for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) { if (tsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(t_ill)) break; - tsctp_ill = list_next(&sctps->sctps_g_ills[index].sctp_ill_list, - tsctp_ill); + tsctp_ill = list_next( + &sctps->sctps_g_ills[hindex].sctp_ill_list, tsctp_ill); } - index = SCTP_IPIF_HASH_FN(ipif->ipif_seqid); - sctp_ipif = list_head(&sctps->sctps_g_ipifs[index].sctp_ipif_list); - for (i = 0; i < sctps->sctps_g_ipifs[index].ipif_count; i++) { + hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, + ipif->ipif_ill->ill_isv6); + sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); + for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) { if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) break; sctp_ipif = list_next( - &sctps->sctps_g_ipifs[index].sctp_ipif_list, sctp_ipif); + &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif); } /* Should be an ASSERT? */ if (fsctp_ill == NULL || tsctp_ill == NULL || sctp_ipif == NULL) { @@ -760,6 +796,246 @@ sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill) rw_exit(&sctps->sctps_g_ills_lock); } +/* + * Walk the list of SCTPs and find each that has oipif in it's saddr list, and + * if so replace it with nipif. + */ +void +sctp_update_saddrs(sctp_ipif_t *oipif, sctp_ipif_t *nipif, int idx, + sctp_stack_t *sctps) +{ + sctp_t *sctp; + sctp_t *sctp_prev = NULL; + sctp_saddr_ipif_t *sobj; + int count; + + sctp = sctps->sctps_gsctp; + mutex_enter(&sctps->sctps_g_lock); + while (sctp != NULL && oipif->sctp_ipif_refcnt > 0) { + mutex_enter(&sctp->sctp_reflock); + if (sctp->sctp_condemned || + sctp->sctp_saddrs[idx].ipif_count <= 0) { + mutex_exit(&sctp->sctp_reflock); + sctp = list_next(&sctps->sctps_g_list, sctp); + continue; + } + sctp->sctp_refcnt++; + mutex_exit(&sctp->sctp_reflock); + mutex_exit(&sctps->sctps_g_lock); + if (sctp_prev != NULL) + SCTP_REFRELE(sctp_prev); + + RUN_SCTP(sctp); + sobj = list_head(&sctp->sctp_saddrs[idx].sctp_ipif_list); + for (count = 0; count < + sctp->sctp_saddrs[idx].ipif_count; count++) { + if (sobj->saddr_ipifp == oipif) { + SCTP_IPIF_REFHOLD(nipif); + sobj->saddr_ipifp = nipif; + ASSERT(oipif->sctp_ipif_refcnt > 0); + /* We have the writer lock */ + oipif->sctp_ipif_refcnt--; + /* + * Can't have more than one referring + * to the same sctp_ipif. + */ + break; + } + sobj = list_next(&sctp->sctp_saddrs[idx].sctp_ipif_list, + sobj); + } + WAKE_SCTP(sctp); + sctp_prev = sctp; + mutex_enter(&sctps->sctps_g_lock); + sctp = list_next(&sctps->sctps_g_list, sctp); + } + mutex_exit(&sctps->sctps_g_lock); + if (sctp_prev != NULL) + SCTP_REFRELE(sctp_prev); +} + +/* + * Given an ipif, walk the hash list in the global ipif table and for + * any other SCTP ipif with the same address and non-zero reference, walk + * the SCTP list and update the saddr list, if required, to point to the + * new SCTP ipif. + */ +void +sctp_chk_and_updt_saddr(int hindex, sctp_ipif_t *ipif, sctp_stack_t *sctps) +{ + int cnt; + sctp_ipif_t *sipif; + + ASSERT(sctps->sctps_g_ipifs[hindex].ipif_count > 0); + ASSERT(ipif->sctp_ipif_state == SCTP_IPIFS_UP); + + sipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); + for (cnt = 0; cnt < sctps->sctps_g_ipifs[hindex].ipif_count; cnt++) { + rw_enter(&sipif->sctp_ipif_lock, RW_WRITER); + if (sipif->sctp_ipif_id != ipif->sctp_ipif_id && + IN6_ARE_ADDR_EQUAL(&sipif->sctp_ipif_saddr, + &ipif->sctp_ipif_saddr) && sipif->sctp_ipif_refcnt > 0) { + /* + * There can only be one address up at any time + * and we are here because ipif has been brought + * up. + */ + ASSERT(sipif->sctp_ipif_state != SCTP_IPIFS_UP); + /* + * Someone has a reference to this we need to update to + * point to the new sipif. + */ + sctp_update_saddrs(sipif, ipif, hindex, sctps); + } + rw_exit(&sipif->sctp_ipif_lock); + sipif = list_next(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list, + sipif); + } +} + +/* + * Insert a new SCTP ipif using 'ipif'. v6addr is the address that existed + * prior to the current address in 'ipif'. Only when an existing address + * is changed on an IPIF, will v6addr be specified. If the IPIF already + * exists in the global SCTP ipif table, then we either removed it, if + * it doesn't have any existing reference, or mark it condemned otherwise. + * If an address is being brought up (IPIF_UP), then we need to scan + * the SCTP list to check if there is any SCTP that points to the *same* + * address on a different SCTP ipif and update in that case. + */ +void +sctp_update_ipif_addr(ipif_t *ipif, in6_addr_t v6addr) +{ + ill_t *ill = ipif->ipif_ill; + int i; + sctp_ill_t *sctp_ill; + sctp_ill_t *osctp_ill; + sctp_ipif_t *sctp_ipif = NULL; + sctp_ipif_t *osctp_ipif = NULL; + uint_t ill_index; + int hindex; + sctp_stack_t *sctps; + + + sctps = ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp; + + /* Index for new address */ + hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, ill->ill_isv6); + + /* + * The address on this IPIF is changing, we need to look for + * this old address and mark it condemned, before creating + * one for the new address. + */ + osctp_ipif = sctp_lookup_ipif_addr(&v6addr, B_FALSE, + ipif->ipif_zoneid, B_TRUE, SCTP_ILL_TO_PHYINDEX(ill), + ipif->ipif_seqid, B_FALSE, sctps); + + rw_enter(&sctps->sctps_g_ills_lock, RW_READER); + rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER); + + ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); + sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list); + for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) { + if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill)) + break; + sctp_ill = list_next( + &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill); + } + + if (sctp_ill == NULL) { + ip1dbg(("sctp_ipif_insert: ill not found ..\n")); + rw_exit(&sctps->sctps_g_ipifs_lock); + rw_exit(&sctps->sctps_g_ills_lock); + } + + if (osctp_ipif != NULL) { + + /* The address is the same? */ + if (IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6lcl_addr, &v6addr)) { + boolean_t chk_n_updt = B_FALSE; + + rw_downgrade(&sctps->sctps_g_ipifs_lock); + rw_enter(&osctp_ipif->sctp_ipif_lock, RW_WRITER); + if (ipif->ipif_flags & IPIF_UP && + osctp_ipif->sctp_ipif_state != SCTP_IPIFS_UP) { + osctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; + chk_n_updt = B_TRUE; + } else { + osctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; + } + osctp_ipif->sctp_ipif_flags = ipif->ipif_flags; + rw_exit(&osctp_ipif->sctp_ipif_lock); + if (chk_n_updt) { + sctp_chk_and_updt_saddr(hindex, osctp_ipif, + sctps); + } + rw_exit(&sctps->sctps_g_ipifs_lock); + rw_exit(&sctps->sctps_g_ills_lock); + return; + } + /* + * We are effectively removing this address from the ILL. + */ + if (osctp_ipif->sctp_ipif_refcnt != 0) { + osctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED; + } else { + list_t *ipif_list; + int ohindex; + + osctp_ill = osctp_ipif->sctp_ipif_ill; + /* hash index for the old one */ + ohindex = SCTP_IPIF_ADDR_HASH( + osctp_ipif->sctp_ipif_saddr, + osctp_ipif->sctp_ipif_isv6); + + ipif_list = + &sctps->sctps_g_ipifs[ohindex].sctp_ipif_list; + + list_remove(ipif_list, (void *)osctp_ipif); + sctps->sctps_g_ipifs[ohindex].ipif_count--; + sctps->sctps_g_ipifs_count--; + rw_destroy(&osctp_ipif->sctp_ipif_lock); + kmem_free(osctp_ipif, sizeof (sctp_ipif_t)); + (void) atomic_add_32_nv(&osctp_ill->sctp_ill_ipifcnt, + -1); + } + } + + sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP); + /* Try again? */ + if (sctp_ipif == NULL) { + ip1dbg(("sctp_ipif_insert: mem failure..\n")); + rw_exit(&sctps->sctps_g_ipifs_lock); + rw_exit(&sctps->sctps_g_ills_lock); + return; + } + sctps->sctps_g_ipifs_count++; + rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL); + sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr; + sctp_ipif->sctp_ipif_ill = sctp_ill; + sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6; + sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; + sctp_ipif->sctp_ipif_id = ipif->ipif_seqid; + if (ipif->ipif_flags & IPIF_UP) + sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; + else + sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; + sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; + /* + * We add it to the head so that it is quicker to find good/recent + * additions. + */ + list_insert_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list, + (void *)sctp_ipif); + sctps->sctps_g_ipifs[hindex].ipif_count++; + atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1); + if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_UP) + sctp_chk_and_updt_saddr(hindex, sctp_ipif, sctps); + rw_exit(&sctps->sctps_g_ipifs_lock); + rw_exit(&sctps->sctps_g_ills_lock); +} + /* Insert, Remove, Mark up or Mark down the ipif */ void sctp_update_ipif(ipif_t *ipif, int op) @@ -769,7 +1045,7 @@ sctp_update_ipif(ipif_t *ipif, int op) sctp_ill_t *sctp_ill; sctp_ipif_t *sctp_ipif; uint_t ill_index; - uint_t ipif_index; + uint_t hindex; netstack_t *ns = ipif->ipif_ill->ill_ipst->ips_netstack; sctp_stack_t *sctps = ns->netstack_sctp; @@ -792,66 +1068,34 @@ sctp_update_ipif(ipif_t *ipif, int op) return; } - ipif_index = SCTP_IPIF_HASH_FN(ipif->ipif_seqid); - sctp_ipif = list_head(&sctps->sctps_g_ipifs[ipif_index].sctp_ipif_list); - for (i = 0; i < sctps->sctps_g_ipifs[ipif_index].ipif_count; i++) { - if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) + hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, + ipif->ipif_ill->ill_isv6); + sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); + for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) { + if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) { + ASSERT(IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr, + &ipif->ipif_v6lcl_addr)); break; + } sctp_ipif = list_next( - &sctps->sctps_g_ipifs[ipif_index].sctp_ipif_list, + &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif); } - if (op != SCTP_IPIF_INSERT && sctp_ipif == NULL) { + if (sctp_ipif == NULL) { ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op)); rw_exit(&sctps->sctps_g_ipifs_lock); rw_exit(&sctps->sctps_g_ills_lock); return; } -#ifdef DEBUG - if (sctp_ipif != NULL) - ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill); -#endif + ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill); switch (op) { - case SCTP_IPIF_INSERT: - if (sctp_ipif != NULL) { - if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) - sctp_ipif->sctp_ipif_state = SCTP_IPIFS_INVALID; - rw_exit(&sctps->sctps_g_ipifs_lock); - rw_exit(&sctps->sctps_g_ills_lock); - return; - } - sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP); - /* Try again? */ - if (sctp_ipif == NULL) { - ip1dbg(("sctp_ipif_insert: mem failure..\n")); - rw_exit(&sctps->sctps_g_ipifs_lock); - rw_exit(&sctps->sctps_g_ills_lock); - return; - } - sctp_ipif->sctp_ipif_id = ipif->ipif_seqid; - sctp_ipif->sctp_ipif_ill = sctp_ill; - sctp_ipif->sctp_ipif_state = SCTP_IPIFS_INVALID; - sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; - sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; - sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6; - sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; - rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL); - list_insert_tail( - &sctps->sctps_g_ipifs[ipif_index].sctp_ipif_list, - (void *)sctp_ipif); - sctps->sctps_g_ipifs[ipif_index].ipif_count++; - sctps->sctps_g_ipifs_count++; - atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1); - - break; - case SCTP_IPIF_REMOVE: { list_t *ipif_list; list_t *ill_list; ill_list = &sctps->sctps_g_ills[ill_index].sctp_ill_list; - ipif_list = &sctps->sctps_g_ipifs[ipif_index].sctp_ipif_list; + ipif_list = &sctps->sctps_g_ipifs[hindex].sctp_ipif_list; if (sctp_ipif->sctp_ipif_refcnt != 0) { sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED; rw_exit(&sctps->sctps_g_ipifs_lock); @@ -859,7 +1103,7 @@ sctp_update_ipif(ipif_t *ipif, int op) return; } list_remove(ipif_list, (void *)sctp_ipif); - sctps->sctps_g_ipifs[ipif_index].ipif_count--; + sctps->sctps_g_ipifs[hindex].ipif_count--; sctps->sctps_g_ipifs_count--; rw_destroy(&sctp_ipif->sctp_ipif_lock); kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); @@ -884,10 +1128,11 @@ sctp_update_ipif(ipif_t *ipif, int op) rw_downgrade(&sctps->sctps_g_ipifs_lock); rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; - sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr; - sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; + sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; rw_exit(&sctp_ipif->sctp_ipif_lock); + sctp_chk_and_updt_saddr(hindex, sctp_ipif, + ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp); break; @@ -896,7 +1141,6 @@ sctp_update_ipif(ipif_t *ipif, int op) rw_downgrade(&sctps->sctps_g_ipifs_lock); rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; - sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr; sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; rw_exit(&sctp_ipif->sctp_ipif_lock); @@ -908,6 +1152,8 @@ sctp_update_ipif(ipif_t *ipif, int op) rw_downgrade(&sctps->sctps_g_ipifs_lock); rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; + sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; + sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; rw_exit(&sctp_ipif->sctp_ipif_lock); break; @@ -917,12 +1163,8 @@ sctp_update_ipif(ipif_t *ipif, int op) } /* - * - * * SCTP source address list manipulaton, locking not used (except for * sctp locking by the caller. - * - * */ /* Remove a specific saddr from the list */ @@ -984,8 +1226,9 @@ sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt, ifindex = sin6->sin6_scope_id; break; } - sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE, sctp, - ifindex); + sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE, + sctp->sctp_zoneid, !sctp->sctp_connp->conn_allzones, + ifindex, 0, B_TRUE, sctp->sctp_sctps); ASSERT(sctp_ipif != NULL); sctp_ipif_hash_remove(sctp, sctp_ipif); } @@ -1007,15 +1250,31 @@ sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt, sctp_saddr_ipif_t * sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex) { - sctp_saddr_ipif_t *saddr_ipifs; + int cnt; + sctp_saddr_ipif_t *ipif_obj; + int hindex; sctp_ipif_t *sctp_ipif; - sctp_ipif = sctp_lookup_ipif_addr(addr, B_FALSE, sctp, ifindex); - if (sctp_ipif == NULL) + hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr)); + if (sctp->sctp_saddrs[hindex].ipif_count == 0) return (NULL); - saddr_ipifs = sctp_ipif_lookup(sctp, sctp_ipif->sctp_ipif_id); - return (saddr_ipifs); + ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list); + for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) { + sctp_ipif = ipif_obj->saddr_ipifp; + /* + * Zone check shouldn't be needed. + */ + if (IN6_ARE_ADDR_EQUAL(addr, &sctp_ipif->sctp_ipif_saddr) && + (ifindex == 0 || + ifindex == sctp_ipif->sctp_ipif_ill->sctp_ill_index) && + SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state)) { + return (ipif_obj); + } + ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list, + ipif_obj); + } + return (NULL); } /* Given an address, add it to the source address list */ @@ -1024,11 +1283,14 @@ sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex) { sctp_ipif_t *sctp_ipif; - sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, sctp, ifindex); + sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, sctp->sctp_zoneid, + !sctp->sctp_connp->conn_allzones, ifindex, 0, B_TRUE, + sctp->sctp_sctps); if (sctp_ipif == NULL) return (EINVAL); - if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE) != 0) { + if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE, + B_FALSE) != 0) { SCTP_IPIF_REFRELE(sctp_ipif); return (EINVAL); } diff --git a/usr/src/uts/common/inet/sctp/sctp_addr.h b/usr/src/uts/common/inet/sctp/sctp_addr.h index 4e1eaf78e2..2625b2e06a 100644 --- a/usr/src/uts/common/inet/sctp/sctp_addr.h +++ b/usr/src/uts/common/inet/sctp/sctp_addr.h @@ -132,13 +132,18 @@ typedef struct sctp_ill_hash_s { #define SCTP_IPIF_REFHOLD(sctp_ipif) { \ atomic_add_32(&(sctp_ipif)->sctp_ipif_refcnt, 1); \ - ASSERT((sctp_ipif)->sctp_ipif_refcnt != 0); \ } #define SCTP_IPIF_REFRELE(sctp_ipif) { \ + rw_enter(&(sctp_ipif)->sctp_ipif_lock, RW_WRITER); \ ASSERT((sctp_ipif)->sctp_ipif_refcnt != 0); \ - if (atomic_add_32_nv(&(sctp_ipif)->sctp_ipif_refcnt, -1) == 0) \ + if (--(sctp_ipif)->sctp_ipif_refcnt == 0 && \ + (sctp_ipif)->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) { \ + rw_exit(&(sctp_ipif)->sctp_ipif_lock); \ sctp_ipif_inactive(sctp_ipif); \ + } else { \ + rw_exit(&(sctp_ipif)->sctp_ipif_lock); \ + } \ } /* Address set comparison results. */ @@ -164,7 +169,6 @@ extern void sctp_del_saddr(sctp_t *, sctp_saddr_ipif_t *); extern void sctp_free_saddrs(sctp_t *); extern void sctp_saddr_init(sctp_stack_t *); extern void sctp_saddr_fini(sctp_stack_t *); -extern sctp_saddr_ipif_t *sctp_ipif_lookup(sctp_t *, uint_t); extern int sctp_getmyaddrs(void *, void *, int *); extern int sctp_saddr_add_addr(sctp_t *, in6_addr_t *, uint_t); extern void sctp_check_saddr(sctp_t *, int, boolean_t); diff --git a/usr/src/uts/common/inet/sctp/sctp_common.c b/usr/src/uts/common/inet/sctp/sctp_common.c index 101cd49ecc..2930c15337 100644 --- a/usr/src/uts/common/inet/sctp/sctp_common.c +++ b/usr/src/uts/common/inet/sctp/sctp_common.c @@ -90,7 +90,6 @@ sctp_get_ire(sctp_t *sctp, sctp_faddr_t *fp) ipaddr_t addr4; in6_addr_t laddr; sctp_saddr_ipif_t *sp; - uint_t ipif_seqid; int hdrlen; ts_label_t *tsl; sctp_stack_t *sctps = sctp->sctp_sctps; @@ -151,7 +150,6 @@ sctp_get_ire(sctp_t *sctp, sctp_faddr_t *fp) goto check_current; } - ipif_seqid = ire->ire_ipif->ipif_seqid; dprint(2, ("ire2faddr: got ire for %x:%x:%x:%x, ", SCTP_PRINTADDR(fp->faddr))); if (fp->isv4) { @@ -162,8 +160,8 @@ sctp_get_ire(sctp_t *sctp, sctp_faddr_t *fp) } /* Make sure the laddr is part of this association */ - if ((sp = sctp_ipif_lookup(sctp, ipif_seqid)) != NULL && - !sp->saddr_ipif_dontsrc) { + if ((sp = sctp_saddr_lookup(sctp, &ire->ire_ipif->ipif_v6lcl_addr, + 0)) != NULL && !sp->saddr_ipif_dontsrc) { if (sp->saddr_ipif_unconfirmed == 1) sp->saddr_ipif_unconfirmed = 0; fp->saddr = laddr; diff --git a/usr/src/uts/common/inet/sctp/sctp_cookie.c b/usr/src/uts/common/inet/sctp/sctp_cookie.c index dcb94c2ccd..036f069257 100644 --- a/usr/src/uts/common/inet/sctp/sctp_cookie.c +++ b/usr/src/uts/common/inet/sctp/sctp_cookie.c @@ -1319,7 +1319,7 @@ sctp_process_cookie(sctp_t *sctp, sctp_chunk_hdr_t *ch, mblk_t *cmp, */ sctp_t * sctp_addrlist2sctp(mblk_t *mp, sctp_hdr_t *sctph, sctp_chunk_hdr_t *ich, - uint_t ipif_seqid, zoneid_t zoneid, sctp_stack_t *sctps) + zoneid_t zoneid, sctp_stack_t *sctps) { int isv4; ipha_t *iph; @@ -1366,8 +1366,8 @@ sctp_addrlist2sctp(mblk_t *mp, sctp_hdr_t *sctph, sctp_chunk_hdr_t *ich, IN6_INADDR_TO_V4MAPPED((struct in_addr *)(ph + 1), &src); - sctp = sctp_conn_match(&src, &dst, ports, ipif_seqid, - zoneid, sctps); + sctp = sctp_conn_match(&src, &dst, ports, zoneid, + sctps); dprint(1, ("sctp_addrlist2sctp: src=%x:%x:%x:%x, sctp=%p\n", @@ -1379,8 +1379,8 @@ sctp_addrlist2sctp(mblk_t *mp, sctp_hdr_t *sctph, sctp_chunk_hdr_t *ich, } } else if (ph->sph_type == PARM_ADDR6) { src = *(in6_addr_t *)(ph + 1); - sctp = sctp_conn_match(&src, &dst, ports, ipif_seqid, - zoneid, sctps); + sctp = sctp_conn_match(&src, &dst, ports, zoneid, + sctps); dprint(1, ("sctp_addrlist2sctp: src=%x:%x:%x:%x, sctp=%p\n", diff --git a/usr/src/uts/common/inet/sctp/sctp_hash.c b/usr/src/uts/common/inet/sctp/sctp_hash.c index f6b3666da5..9c55d72193 100644 --- a/usr/src/uts/common/inet/sctp/sctp_hash.c +++ b/usr/src/uts/common/inet/sctp/sctp_hash.c @@ -312,7 +312,7 @@ cl_sctp_walk_list_stack(int (*cl_callback)(cl_sctp_info_t *, void *), sctp_t * sctp_conn_match(in6_addr_t *faddr, in6_addr_t *laddr, uint32_t ports, - uint_t ipif_seqid, zoneid_t zoneid, sctp_stack_t *sctps) + zoneid_t zoneid, sctp_stack_t *sctps) { sctp_tf_t *tf; sctp_t *sctp; @@ -334,24 +334,16 @@ sctp_conn_match(in6_addr_t *faddr, in6_addr_t *laddr, uint32_t ports, } } - if (!fp) { - /* no faddr match; keep looking */ + /* no faddr match; keep looking */ + if (fp == NULL) continue; - } /* check for laddr match */ - if (ipif_seqid == 0) { - if (sctp_saddr_lookup(sctp, laddr, 0) != NULL) { - SCTP_REFHOLD(sctp); - goto done; - } - } else { - if (sctp_ipif_lookup(sctp, ipif_seqid) != NULL) { - SCTP_REFHOLD(sctp); - goto done; - } - /* no match; continue to the next in the chain */ + if (sctp_saddr_lookup(sctp, laddr, 0) != NULL) { + SCTP_REFHOLD(sctp); + goto done; } + /* no match; continue to the next in the chain */ } done: @@ -360,8 +352,8 @@ done: } static sctp_t * -listen_match(in6_addr_t *laddr, uint32_t ports, uint_t ipif_seqid, - zoneid_t zoneid, sctp_stack_t *sctps) +listen_match(in6_addr_t *laddr, uint32_t ports, zoneid_t zoneid, + sctp_stack_t *sctps) { sctp_t *sctp; sctp_tf_t *tf; @@ -378,16 +370,9 @@ listen_match(in6_addr_t *laddr, uint32_t ports, uint_t ipif_seqid, continue; } - if (ipif_seqid == 0) { - if (sctp_saddr_lookup(sctp, laddr, 0) != NULL) { - SCTP_REFHOLD(sctp); - goto done; - } - } else { - if (sctp_ipif_lookup(sctp, ipif_seqid) != NULL) { - SCTP_REFHOLD(sctp); - goto done; - } + if (sctp_saddr_lookup(sctp, laddr, 0) != NULL) { + SCTP_REFHOLD(sctp); + goto done; } /* no match; continue to the next in the chain */ } @@ -400,31 +385,27 @@ done: /* called by ipsec_sctp_pol */ conn_t * sctp_find_conn(in6_addr_t *src, in6_addr_t *dst, uint32_t ports, - uint_t ipif_seqid, zoneid_t zoneid, sctp_stack_t *sctps) + zoneid_t zoneid, sctp_stack_t *sctps) { sctp_t *sctp; - if ((sctp = sctp_conn_match(src, dst, ports, ipif_seqid, - zoneid, sctps)) == NULL) { + if ((sctp = sctp_conn_match(src, dst, ports, zoneid, sctps)) == NULL) { /* Not in conn fanout; check listen fanout */ - if ((sctp = listen_match(dst, ports, ipif_seqid, - zoneid, sctps)) == NULL) { + if ((sctp = listen_match(dst, ports, zoneid, sctps)) == NULL) return (NULL); - } } return (sctp->sctp_connp); } conn_t * sctp_fanout(in6_addr_t *src, in6_addr_t *dst, uint32_t ports, - uint_t ipif_seqid, zoneid_t zoneid, mblk_t *mp, sctp_stack_t *sctps) + zoneid_t zoneid, mblk_t *mp, sctp_stack_t *sctps) { sctp_t *sctp; boolean_t shared_addr; - if ((sctp = sctp_conn_match(src, dst, ports, ipif_seqid, - zoneid, sctps)) == NULL) { + if ((sctp = sctp_conn_match(src, dst, ports, zoneid, sctps)) == NULL) { shared_addr = (zoneid == ALL_ZONES); if (shared_addr) { /* @@ -445,10 +426,8 @@ sctp_fanout(in6_addr_t *src, in6_addr_t *dst, uint32_t ports, return (NULL); } /* Not in conn fanout; check listen fanout */ - if ((sctp = listen_match(dst, ports, ipif_seqid, - zoneid, sctps)) == NULL) { + if ((sctp = listen_match(dst, ports, zoneid, sctps)) == NULL) return (NULL); - } /* * On systems running trusted extensions, check if dst * should accept the packet. "IPV6_VERSION" indicates @@ -478,7 +457,7 @@ sctp_fanout(in6_addr_t *src, in6_addr_t *dst, uint32_t ports, void ip_fanout_sctp(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, uint32_t ports, uint_t flags, boolean_t mctl_present, boolean_t ip_policy, - uint_t ipif_seqid, zoneid_t zoneid) + zoneid_t zoneid) { sctp_t *sctp; boolean_t isv4; @@ -522,11 +501,10 @@ ip_fanout_sctp(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, dst = &map_dst; isv4 = B_TRUE; } - connp = sctp_find_conn(src, dst, ports, ipif_seqid, zoneid, sctps); + connp = sctp_find_conn(src, dst, ports, zoneid, sctps); if (connp == NULL) { ip_fanout_sctp_raw(first_mp, recv_ill, ipha, isv4, - ports, mctl_present, flags, ip_policy, - ipif_seqid, zoneid); + ports, mctl_present, flags, ip_policy, zoneid); return; } sctp = CONN2SCTP(connp); diff --git a/usr/src/uts/common/inet/sctp/sctp_impl.h b/usr/src/uts/common/inet/sctp/sctp_impl.h index e405703a29..453f911f5f 100644 --- a/usr/src/uts/common/inet/sctp/sctp_impl.h +++ b/usr/src/uts/common/inet/sctp/sctp_impl.h @@ -925,7 +925,7 @@ extern mblk_t *sctp_add_proto_hdr(sctp_t *, sctp_faddr_t *, mblk_t *, int, int *); extern void sctp_addr_req(sctp_t *, mblk_t *); extern sctp_t *sctp_addrlist2sctp(mblk_t *, sctp_hdr_t *, sctp_chunk_hdr_t *, - uint_t, zoneid_t, sctp_stack_t *); + zoneid_t, sctp_stack_t *); extern void sctp_add_hdr(sctp_t *, uchar_t *, size_t); extern void sctp_check_adv_ack_pt(sctp_t *, mblk_t *, mblk_t *); extern void sctp_assoc_event(sctp_t *, uint16_t, uint16_t, @@ -947,7 +947,7 @@ extern int sctp_compare_faddrsets(sctp_faddr_t *, sctp_faddr_t *); extern void sctp_congest_reset(sctp_t *); extern void sctp_conn_hash_insert(sctp_tf_t *, sctp_t *, int); extern void sctp_conn_hash_remove(sctp_t *); -extern sctp_t *sctp_conn_match(in6_addr_t *, in6_addr_t *, uint32_t, uint_t, +extern sctp_t *sctp_conn_match(in6_addr_t *, in6_addr_t *, uint32_t, zoneid_t, sctp_stack_t *); extern sctp_t *sctp_conn_request(sctp_t *, mblk_t *, uint_t, uint_t, sctp_init_chunk_t *, mblk_t *); diff --git a/usr/src/uts/common/inet/sctp/sctp_input.c b/usr/src/uts/common/inet/sctp/sctp_input.c index 4169486856..0b15712122 100644 --- a/usr/src/uts/common/inet/sctp/sctp_input.c +++ b/usr/src/uts/common/inet/sctp/sctp_input.c @@ -3183,8 +3183,8 @@ sctp_check_in_policy(mblk_t *mp, mblk_t *ipsec_mp) /* Handle out-of-the-blue packets */ void -sctp_ootb_input(mblk_t *mp, ill_t *recv_ill, uint_t ipif_seqid, - zoneid_t zoneid, boolean_t mctl_present) +sctp_ootb_input(mblk_t *mp, ill_t *recv_ill, zoneid_t zoneid, + boolean_t mctl_present) { sctp_t *sctp; sctp_chunk_hdr_t *ch; @@ -3272,8 +3272,7 @@ sctp_ootb_input(mblk_t *mp, ill_t *recv_ill, uint_t ipif_seqid, break; case CHUNK_INIT_ACK: /* check for changed src addr */ - sctp = sctp_addrlist2sctp(mp, sctph, ch, ipif_seqid, zoneid, - sctps); + sctp = sctp_addrlist2sctp(mp, sctph, ch, zoneid, sctps); if (sctp != NULL) { /* success; proceed to normal path */ mutex_enter(&sctp->sctp_lock); diff --git a/usr/src/uts/common/inet/sctp_ip.h b/usr/src/uts/common/inet/sctp_ip.h index 89b5730f90..567a600671 100644 --- a/usr/src/uts/common/inet/sctp_ip.h +++ b/usr/src/uts/common/inet/sctp_ip.h @@ -38,18 +38,18 @@ extern "C" { /* SCTP routines for IP to call. */ extern void ip_fanout_sctp(mblk_t *, ill_t *, ipha_t *, uint32_t, - uint_t, boolean_t, boolean_t, uint_t, zoneid_t); + uint_t, boolean_t, boolean_t, zoneid_t); extern void sctp_ddi_g_init(void); extern void sctp_ddi_g_destroy(void); -extern conn_t *sctp_find_conn(in6_addr_t *, in6_addr_t *, uint32_t, uint_t, +extern conn_t *sctp_find_conn(in6_addr_t *, in6_addr_t *, uint32_t, zoneid_t, sctp_stack_t *); -extern conn_t *sctp_fanout(in6_addr_t *, in6_addr_t *, uint32_t, uint_t, +extern conn_t *sctp_fanout(in6_addr_t *, in6_addr_t *, uint32_t, zoneid_t, mblk_t *, sctp_stack_t *); extern void sctp_input(conn_t *, ipha_t *, mblk_t *, mblk_t *, ill_t *, boolean_t, boolean_t); extern void sctp_wput(queue_t *, mblk_t *); -extern void sctp_ootb_input(mblk_t *, ill_t *, uint_t, zoneid_t, boolean_t); +extern void sctp_ootb_input(mblk_t *, ill_t *, zoneid_t, boolean_t); extern void sctp_hash_init(sctp_stack_t *); extern void sctp_hash_destroy(sctp_stack_t *); extern uint32_t sctp_cksum(mblk_t *, int); @@ -78,6 +78,7 @@ extern void sctp_free(conn_t *); extern void sctp_update_ill(ill_t *, int); extern void sctp_update_ipif(ipif_t *, int); extern void sctp_move_ipif(ipif_t *, ill_t *, ill_t *); +extern void sctp_update_ipif_addr(ipif_t *, in6_addr_t); #define SCTP_ILL_INSERT 1 #define SCTP_ILL_REMOVE 2 @@ -89,7 +90,7 @@ extern void sctp_move_ipif(ipif_t *, ill_t *, ill_t *); /* IP routines for SCTP to call. */ extern void ip_fanout_sctp_raw(mblk_t *, ill_t *, ipha_t *, boolean_t, - uint32_t, boolean_t, uint_t, boolean_t, uint_t, zoneid_t); + uint32_t, boolean_t, uint_t, boolean_t, zoneid_t); extern void sctp_ire_cache_flush(ipif_t *); /* |