diff --git a/netwerk/sctp/src/moz.yaml b/netwerk/sctp/src/moz.yaml --- a/netwerk/sctp/src/moz.yaml +++ b/netwerk/sctp/src/moz.yaml @@ -8,12 +8,12 @@ name: sctp description: userland SCTP stack url: https://github.com/sctplab/usrsctp/blob/master/Manual.md - release: 1330843b6ffd0c5c2d7483b07050049eedda8077 (2024-08-03T12:00:29Z). - revision: 1330843b6ffd0c5c2d7483b07050049eedda8077 + release: 2e1ab1050bbb6c710f6a475f1601acf1ae7ecb78 (2025-01-09T11:49:06Z). + revision: 2e1ab1050bbb6c710f6a475f1601acf1ae7ecb78 license: BSD-3-Clause vendoring: url: https://github.com/sctplab/usrsctp diff --git a/netwerk/sctp/src/netinet/sctp_asconf.c b/netwerk/sctp/src/netinet/sctp_asconf.c --- a/netwerk/sctp/src/netinet/sctp_asconf.c +++ b/netwerk/sctp/src/netinet/sctp_asconf.c @@ -1345,17 +1345,17 @@ TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next); #ifdef SCTP_DEBUG if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) { if (type == SCTP_ADD_IP_ADDRESS) { - SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: "); + SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: "); SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } else if (type == SCTP_DEL_IP_ADDRESS) { - SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: "); + SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: "); SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } else { - SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: "); + SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: "); SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } } #endif diff --git a/netwerk/sctp/src/netinet/sctp_bsd_addr.c b/netwerk/sctp/src/netinet/sctp_bsd_addr.c --- a/netwerk/sctp/src/netinet/sctp_bsd_addr.c +++ b/netwerk/sctp/src/netinet/sctp_bsd_addr.c @@ -711,16 +711,15 @@ ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname, #endif (void *)ifa, ifa->ifa_addr, ifa_flags, 1); } else { sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, + (void *)ifa->ifa_ifp, #if defined(__APPLE__) && !defined(__Userspace__) - ifnet_index(ifa->ifa_ifp), - ifnet_name(ifa->ifa_ifp)); + ifnet_index(ifa->ifa_ifp)); #else - ifa->ifa_ifp->if_index, - ifa->ifa_ifp->if_xname); + ifa->ifa_ifp->if_index); #endif /* We don't bump refcount here so when it completes * the final delete will happen. */ diff --git a/netwerk/sctp/src/netinet/sctp_output.c b/netwerk/sctp/src/netinet/sctp_output.c --- a/netwerk/sctp/src/netinet/sctp_output.c +++ b/netwerk/sctp/src/netinet/sctp_output.c @@ -15072,27 +15072,27 @@ } ifa = (struct ifaddr *)sifa->ifa; mask = (struct sockaddr_in *)(ifa->ifa_netmask); sin = &sifa->address.sin; srcnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr); - SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: src address is "); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "match_nexthop4: src address is "); SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &sifa->address.sa); - SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", srcnetaddr.s_addr); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "network address is %x\n", srcnetaddr.s_addr); #if defined(__FreeBSD__) sin = &ro->ro_nh->gw4_sa; #else sin = (struct sockaddr_in *)ro->ro_rt->rt_gateway; #endif gwnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr); - SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: nexthop is "); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "match_nexthop4: nexthop is "); #if defined(__FreeBSD__) SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &ro->ro_nh->gw_sa); #else SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway); #endif - SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", gwnetaddr.s_addr); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "network address is %x\n", gwnetaddr.s_addr); if (srcnetaddr.s_addr == gwnetaddr.s_addr) { return (1); } #endif return (0); diff --git a/netwerk/sctp/src/netinet/sctp_pcb.h b/netwerk/sctp/src/netinet/sctp_pcb.h --- a/netwerk/sctp/src/netinet/sctp_pcb.h +++ b/netwerk/sctp/src/netinet/sctp_pcb.h @@ -679,36 +679,21 @@ struct sctp_vrf *sctp_allocate_vrf(int vrfid); struct sctp_vrf *sctp_find_vrf(uint32_t vrfid); void sctp_free_vrf(struct sctp_vrf *vrf); -/*- - * Change address state, can be used if - * O/S supports telling transports about - * changes to IFA/IFN's (link layer triggers). - * If a ifn goes down, we will do src-addr-selection - * and NOT use that, as a source address. This does - * not stop the routing system from routing out - * that interface, but we won't put it as a source. - */ -void sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index); -void sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index); - struct sctp_ifa * sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index, uint32_t ifn_type, const char *if_name, void *ifa, struct sockaddr *addr, uint32_t ifa_flags, int dynamic_add); -void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu); - -void sctp_free_ifn(struct sctp_ifn *sctp_ifnp); void sctp_free_ifa(struct sctp_ifa *sctp_ifap); void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr, - uint32_t ifn_index, const char *if_name); + void *ifn, uint32_t ifn_index); struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *); struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int, uint32_t); diff --git a/netwerk/sctp/src/netinet/sctp_pcb.c b/netwerk/sctp/src/netinet/sctp_pcb.c --- a/netwerk/sctp/src/netinet/sctp_pcb.c +++ b/netwerk/sctp/src/netinet/sctp_pcb.c @@ -249,24 +249,22 @@ sctp_find_ifn(void *ifn, uint32_t ifn_index) { struct sctp_ifn *sctp_ifnp; struct sctp_ifnlist *hash_ifn_head; - /* We assume the lock is held for the addresses - * if that's wrong problems could occur :-) - */ SCTP_IPI_ADDR_LOCK_ASSERT(); +#if defined(__FreeBSD__) && !defined(__Userspace__) + KASSERT(ifn != NULL, ("sctp_find_ifn(NULL, %u) called", ifn_index)); +#endif hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))]; LIST_FOREACH(sctp_ifnp, hash_ifn_head, next_bucket) { - if (sctp_ifnp->ifn_index == ifn_index) { - return (sctp_ifnp); - } - if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) { - return (sctp_ifnp); - } - } - return (NULL); + if (sctp_ifnp->ifn_index == ifn_index && + sctp_ifnp->ifn_p == ifn) { + break; + } + } + return (sctp_ifnp); } struct sctp_vrf * sctp_find_vrf(uint32_t vrf_id) { @@ -284,22 +282,22 @@ void sctp_free_vrf(struct sctp_vrf *vrf) { if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) { - if (vrf->vrf_addr_hash) { - SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); - vrf->vrf_addr_hash = NULL; - } + if (vrf->vrf_addr_hash) { + SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); + vrf->vrf_addr_hash = NULL; + } /* We zero'd the count */ LIST_REMOVE(vrf, next_vrf); SCTP_FREE(vrf, SCTP_M_VRF); atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_vrfs), 1); } } -void +static void sctp_free_ifn(struct sctp_ifn *sctp_ifnp) { if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) { /* We zero'd the count */ if (sctp_ifnp->vrf) { @@ -309,21 +307,10 @@ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifns), 1); } } void -sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu) -{ - struct sctp_ifn *sctp_ifnp; - - sctp_ifnp = sctp_find_ifn((void *)NULL, ifn_index); - if (sctp_ifnp != NULL) { - sctp_ifnp->ifn_mtu = mtu; - } -} - -void sctp_free_ifa(struct sctp_ifa *sctp_ifap) { if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifap->refcount)) { /* We zero'd the count */ if (sctp_ifap->ifn_p) { @@ -333,127 +320,34 @@ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifas), 1); } } static void -sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock) +sctp_delete_ifn(struct sctp_ifn *sctp_ifnp) { - struct sctp_ifn *found; - - found = sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index); - if (found == NULL) { + + SCTP_IPI_ADDR_WLOCK_ASSERT(); + if (sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index) == NULL) { /* Not in the list.. sorry */ return; } - if (hold_addr_lock == 0) { - SCTP_IPI_ADDR_WLOCK(); - } else { - SCTP_IPI_ADDR_WLOCK_ASSERT(); - } LIST_REMOVE(sctp_ifnp, next_bucket); LIST_REMOVE(sctp_ifnp, next_ifn); - if (hold_addr_lock == 0) { - SCTP_IPI_ADDR_WUNLOCK(); - } /* Take away the reference, and possibly free it */ sctp_free_ifn(sctp_ifnp); } -void -sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, - const char *if_name, uint32_t ifn_index) -{ - struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap; - - SCTP_IPI_ADDR_RLOCK(); - vrf = sctp_find_vrf(vrf_id); - if (vrf == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id); - goto out; - } - sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n"); - goto out; - } - if (sctp_ifap->ifn_p == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unusable\n"); - goto out; - } - if (if_name) { - if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n", - sctp_ifap->ifn_p->ifn_name, if_name); - goto out; - } - } else { - if (sctp_ifap->ifn_p->ifn_index != ifn_index) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n", - sctp_ifap->ifn_p->ifn_index, ifn_index); - goto out; - } - } - - sctp_ifap->localifa_flags &= (~SCTP_ADDR_VALID); - sctp_ifap->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE; - out: - SCTP_IPI_ADDR_RUNLOCK(); -} - -void -sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, - const char *if_name, uint32_t ifn_index) -{ - struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap; - - SCTP_IPI_ADDR_RLOCK(); - vrf = sctp_find_vrf(vrf_id); - if (vrf == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id); - goto out; - } - sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n"); - goto out; - } - if (sctp_ifap->ifn_p == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unusable\n"); - goto out; - } - if (if_name) { - if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n", - sctp_ifap->ifn_p->ifn_name, if_name); - goto out; - } - } else { - if (sctp_ifap->ifn_p->ifn_index != ifn_index) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n", - sctp_ifap->ifn_p->ifn_index, ifn_index); - goto out; - } - } - - sctp_ifap->localifa_flags &= (~SCTP_ADDR_IFA_UNUSEABLE); - sctp_ifap->localifa_flags |= SCTP_ADDR_VALID; - out: - SCTP_IPI_ADDR_RUNLOCK(); -} - /*- * Add an ifa to an ifn. * Register the interface as necessary. - * NOTE: ADDR write lock MUST be held. */ static void sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap) { int ifa_af; + SCTP_IPI_ADDR_WLOCK_ASSERT(); LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); sctp_ifap->ifn_p = sctp_ifnp; atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); /* update address counts */ sctp_ifnp->ifa_count++; @@ -480,15 +374,15 @@ /*- * Remove an ifa from its ifn. * If no more addresses exist, remove the ifn too. Otherwise, re-register * the interface based on the remaining address families left. - * NOTE: ADDR write lock MUST be held. */ static void sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap) { + SCTP_IPI_ADDR_WLOCK_ASSERT(); LIST_REMOVE(sctp_ifap, next_ifa); if (sctp_ifap->ifn_p) { /* update address counts */ sctp_ifap->ifn_p->ifa_count--; switch (sctp_ifap->address.sa.sa_family) { @@ -506,11 +400,11 @@ break; } if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) { /* remove the ifn, possibly freeing it */ - sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED); + sctp_delete_ifn(sctp_ifap->ifn_p); } else { /* re-register address family type, if needed */ if ((sctp_ifap->ifn_p->num_v6 == 0) && (sctp_ifap->ifn_p->registered_af == AF_INET6)) { sctp_ifap->ifn_p->registered_af = AF_INET; @@ -525,21 +419,20 @@ } } struct sctp_ifa * sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, - uint32_t ifn_type, const char *if_name, void *ifa, - struct sockaddr *addr, uint32_t ifa_flags, - int dynamic_add) + uint32_t ifn_type, const char *if_name, void *ifa, + struct sockaddr *addr, uint32_t ifa_flags, + int dynamic_add) { struct sctp_vrf *vrf; struct sctp_ifn *sctp_ifnp, *new_sctp_ifnp; struct sctp_ifa *sctp_ifap, *new_sctp_ifap; struct sctp_ifalist *hash_addr_head; struct sctp_ifnlist *hash_ifn_head; uint32_t hash_of_addr; - int new_ifn_af = 0; #ifdef SCTP_DEBUG SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: adding address: ", vrf_id); SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr); #endif @@ -598,63 +491,68 @@ hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))]; LIST_INIT(&sctp_ifnp->ifalist); LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket); LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifns), 1); - new_ifn_af = 1; } sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap) { - /* Hmm, it already exists? */ - if ((sctp_ifap->ifn_p) && - (sctp_ifap->ifn_p->ifn_index == ifn_index)) { - SCTPDBG(SCTP_DEBUG_PCB4, "Using existing ifn %s (0x%x) for ifa %p\n", - sctp_ifap->ifn_p->ifn_name, ifn_index, - (void *)sctp_ifap); - if (new_ifn_af) { - /* Remove the created one that we don't want */ - sctp_delete_ifn(sctp_ifnp, SCTP_ADDR_LOCKED); - } - if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { - /* easy to solve, just switch back to active */ - SCTPDBG(SCTP_DEBUG_PCB4, "Clearing deleted ifa flag\n"); - sctp_ifap->localifa_flags = SCTP_ADDR_VALID; - sctp_ifap->ifn_p = sctp_ifnp; - atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); - } - exit_stage_left: - SCTP_IPI_ADDR_WUNLOCK(); - if (new_sctp_ifnp != NULL) { - SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN); - } - SCTP_FREE(new_sctp_ifap, SCTP_M_IFA); - return (sctp_ifap); - } else { - if (sctp_ifap->ifn_p) { + if (sctp_ifap != NULL) { + /* The address being added is already or still known. */ + if (sctp_ifap->ifn_p != NULL) { + if (sctp_ifap->ifn_p->ifn_index == ifn_index && + sctp_ifap->ifn_p->ifn_p == ifn) { + SCTPDBG(SCTP_DEBUG_PCB4, + "Using existing ifn %s (0x%x) for ifa %p\n", + sctp_ifap->ifn_p->ifn_name, ifn_index, + (void *)sctp_ifap); + if (new_sctp_ifnp == NULL) { + /* Remove the created one not used. */ + sctp_delete_ifn(sctp_ifnp); + } + if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { + /* Switch back to active. */ + SCTPDBG(SCTP_DEBUG_PCB4, + "Clearing deleted ifa flag\n"); + sctp_ifap->localifa_flags = SCTP_ADDR_VALID; + sctp_ifap->ifn_p = sctp_ifnp; + atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); + } + } else { /* * The last IFN gets the address, remove the - * old one + * old one. */ - SCTPDBG(SCTP_DEBUG_PCB4, "Moving ifa %p from %s (0x%x) to %s (0x%x)\n", - (void *)sctp_ifap, sctp_ifap->ifn_p->ifn_name, - sctp_ifap->ifn_p->ifn_index, if_name, - ifn_index); + SCTPDBG(SCTP_DEBUG_PCB4, + "Moving ifa %p from %s (0x%x) to %s (0x%x)\n", + (void *)sctp_ifap, + sctp_ifap->ifn_p->ifn_name, + sctp_ifap->ifn_p->ifn_index, if_name, + ifn_index); /* remove the address from the old ifn */ sctp_remove_ifa_from_ifn(sctp_ifap); /* move the address over to the new ifn */ sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap); - goto exit_stage_left; - } else { - /* repair ifnp which was NULL ? */ - sctp_ifap->localifa_flags = SCTP_ADDR_VALID; - SCTPDBG(SCTP_DEBUG_PCB4, "Repairing ifn %p for ifa %p\n", - (void *)sctp_ifnp, (void *)sctp_ifap); - sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap); - } - goto exit_stage_left; - } - } + } + } else { + /* Repair ifn_p, which was NULL... */ + sctp_ifap->localifa_flags = SCTP_ADDR_VALID; + SCTPDBG(SCTP_DEBUG_PCB4, + "Repairing ifn %p for ifa %p\n", + (void *)sctp_ifnp, (void *)sctp_ifap); + sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap); + } + SCTP_IPI_ADDR_WUNLOCK(); + if (new_sctp_ifnp != NULL) { + SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN); + } + SCTP_FREE(new_sctp_ifap, SCTP_M_IFA); + return (sctp_ifap); + } + KASSERT(sctp_ifnp != NULL, + ("sctp_add_addr_to_vrf: sctp_ifnp == NULL")); + KASSERT(sctp_ifap == NULL, + ("sctp_add_addr_to_vrf: sctp_ifap (%p) != NULL", sctp_ifap)); sctp_ifap = new_sctp_ifap; memset(sctp_ifap, 0, sizeof(struct sctp_ifa)); sctp_ifap->ifn_p = sctp_ifnp; atomic_add_int(&sctp_ifnp->refcount, 1); sctp_ifap->vrf_id = vrf_id; @@ -699,12 +597,12 @@ } if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { sctp_ifap->src_is_priv = 1; } sctp_ifnp->num_v4++; - if (new_ifn_af) - new_ifn_af = AF_INET; + if (new_sctp_ifnp == NULL) + sctp_ifnp->registered_af = AF_INET; break; } #endif #ifdef INET6 case AF_INET6: @@ -719,23 +617,22 @@ } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { sctp_ifap->src_is_priv = 1; } sctp_ifnp->num_v6++; - if (new_ifn_af) - new_ifn_af = AF_INET6; + if (new_sctp_ifnp == NULL) + sctp_ifnp->registered_af = AF_INET6; break; } #endif #if defined(__Userspace__) case AF_CONN: - if (new_ifn_af) - new_ifn_af = AF_CONN; + if (new_sctp_ifnp == NULL) + sctp_ifnp->registered_af = AF_CONN; break; #endif default: - new_ifn_af = 0; break; } hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); if ((sctp_ifap->src_is_priv == 0) && @@ -747,13 +644,10 @@ sctp_ifap->refcount = 1; LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); sctp_ifnp->ifa_count++; vrf->total_ifa_count++; atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifas), 1); - if (new_ifn_af) { - sctp_ifnp->registered_af = new_ifn_af; - } SCTP_IPI_ADDR_WUNLOCK(); if (new_sctp_ifnp != NULL) { SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN); } @@ -770,12 +664,11 @@ * Gak, what can we do? We have lost an address * change can you say HOSED? */ SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n"); /* Opps, must decrement the count */ - sctp_del_addr_from_vrf(vrf_id, addr, ifn_index, - if_name); + sctp_del_addr_from_vrf(vrf_id, addr, ifn, ifn_index); return (NULL); } SCTP_INCR_LADDR_COUNT(); memset(wi, 0, sizeof(*wi)); (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); @@ -796,52 +689,37 @@ return (sctp_ifap); } void sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr, - uint32_t ifn_index, const char *if_name) + void *ifn, uint32_t ifn_index) { struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifa *sctp_ifap; SCTP_IPI_ADDR_WLOCK(); vrf = sctp_find_vrf(vrf_id); if (vrf == NULL) { SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id); - goto out_now; + SCTP_IPI_ADDR_WUNLOCK(); + return; } #ifdef SCTP_DEBUG SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: deleting address:", vrf_id); SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr); #endif sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap) { + if (sctp_ifap != NULL) { /* Validate the delete */ if (sctp_ifap->ifn_p) { - int valid = 0; - /*- - * The name has priority over the ifn_index - * if its given. - */ - if (if_name) { - if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) == 0) { - /* They match its a correct delete */ - valid = 1; - } - } - if (!valid) { - /* last ditch check ifn_index */ - if (ifn_index == sctp_ifap->ifn_p->ifn_index) { - valid = 1; - } - } - if (!valid) { - SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s does not match addresses\n", - ifn_index, ((if_name == NULL) ? "NULL" : if_name)); - SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s - ignoring delete\n", - sctp_ifap->ifn_p->ifn_index, sctp_ifap->ifn_p->ifn_name); + if (ifn_index != sctp_ifap->ifn_p->ifn_index || + ifn != sctp_ifap->ifn_p->ifn_p) { + SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d (%p) ifname:%s - ignoring delete\n", + sctp_ifap->ifn_p->ifn_index, + sctp_ifap->ifn_p->ifn_p, + sctp_ifap->ifn_p->ifn_name); SCTP_IPI_ADDR_WUNLOCK(); return; } } SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap); @@ -859,17 +737,16 @@ } #ifdef SCTP_DEBUG else { SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:", ifn_index); - SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr); - } -#endif - - out_now: + SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr); + } +#endif + SCTP_IPI_ADDR_WUNLOCK(); - if (sctp_ifap) { + if (sctp_ifap != NULL) { struct sctp_laddr *wi; wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr); if (wi == NULL) { /* diff --git a/netwerk/sctp/src/netinet/sctp_sysctl.c b/netwerk/sctp/src/netinet/sctp_sysctl.c --- a/netwerk/sctp/src/netinet/sctp_sysctl.c +++ b/netwerk/sctp/src/netinet/sctp_sysctl.c @@ -1130,11 +1130,11 @@ } \ } \ return (error); \ } \ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, flags, NULL, 0, \ - sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC) + sctp_sysctl_handle_##mib_name, "IU", prefix##_DESC) #define SCTP_UINT_SYSCTL_RDTUN(mib_name, var_name, prefix) \ SYSCTL_UINT(_net_inet_sctp, OID_AUTO, mib_name, \ CTLFLAG_VNET|CTLFLAG_RDTUN|CTLFLAG_NOFETCH, \ &VNET_NAME(system_base_info.sctpsysctl.var_name), 0, \ diff --git a/netwerk/sctp/src/user_recv_thread.c b/netwerk/sctp/src/user_recv_thread.c --- a/netwerk/sctp/src/user_recv_thread.c +++ b/netwerk/sctp/src/user_recv_thread.c @@ -133,12 +133,11 @@ sa, 0, 1); } else { sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, - if_nametoindex(ifa->ifa_name), - ifa->ifa_name); + NULL, if_nametoindex(ifa->ifa_name)); } freeifaddrs(ifas); } static void * diff --git a/netwerk/sctp/src/user_socket.c b/netwerk/sctp/src/user_socket.c --- a/netwerk/sctp/src/user_socket.c +++ b/netwerk/sctp/src/user_socket.c @@ -3152,12 +3152,11 @@ #endif sconn.sconn_port = 0; sconn.sconn_addr = addr; sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, (struct sockaddr *)&sconn, - 0xffffffff, - "conn"); + NULL, 0xffffffff); } #define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06ld " #define PREAMBLE_LENGTH 19 #define HEADER "0000 "