From b28f0b55b00bde67f6be80d6623e2775b88026b8 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 3 Nov 2024 11:44:02 +0000 Subject: [PATCH] Improve handling of address changes. --- usrsctplib/netinet/sctp_bsd_addr.c | 7 +- usrsctplib/netinet/sctp_pcb.c | 135 ++++------------------------- usrsctplib/netinet/sctp_pcb.h | 14 +-- usrsctplib/user_recv_thread.c | 3 +- usrsctplib/user_socket.c | 3 +- 5 files changed, 24 insertions(+), 138 deletions(-) diff --git a/usrsctplib/netinet/sctp_bsd_addr.c b/usrsctplib/netinet/sctp_bsd_addr.c index d71426bf1..3e0df08f1 100755 --- a/usrsctplib/netinet/sctp_bsd_addr.c +++ b/usrsctplib/netinet/sctp_bsd_addr.c @@ -713,12 +713,11 @@ sctp_addr_change(struct ifaddr *ifa, int cmd) (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 diff --git a/usrsctplib/netinet/sctp_pcb.c b/usrsctplib/netinet/sctp_pcb.c index 37f9dc00d..83d2511af 100755 --- a/usrsctplib/netinet/sctp_pcb.c +++ b/usrsctplib/netinet/sctp_pcb.c @@ -252,12 +252,13 @@ sctp_find_ifn(void *ifn, uint32_t ifn_index) struct sctp_ifnlist *hash_ifn_head; 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) { - break; - } - if (ifn != NULL && sctp_ifnp->ifn_p == ifn) { + if (sctp_ifnp->ifn_index == ifn_index && + sctp_ifnp->ifn_p == ifn) { break; } } @@ -335,90 +336,6 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp) 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. @@ -504,9 +421,9 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap) 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; @@ -581,7 +498,8 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, 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) { + 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, @@ -748,8 +666,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, */ 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(); @@ -774,7 +691,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, 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; @@ -795,28 +712,12 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr, if (sctp_ifap != NULL) { /* Validate the delete */ if (sctp_ifap->ifn_p) { - bool valid = false; - /*- - * 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 = true; - } - } - if (!valid) { - /* last ditch check ifn_index */ - if (ifn_index == sctp_ifap->ifn_p->ifn_index) { - valid = true; - } - } - 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; } diff --git a/usrsctplib/netinet/sctp_pcb.h b/usrsctplib/netinet/sctp_pcb.h index d4c85c8c7..3d893bc43 100755 --- a/usrsctplib/netinet/sctp_pcb.h +++ b/usrsctplib/netinet/sctp_pcb.h @@ -681,18 +681,6 @@ 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, @@ -703,7 +691,7 @@ sctp_add_addr_to_vrf(uint32_t vrfid, 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 *); diff --git a/usrsctplib/user_recv_thread.c b/usrsctplib/user_recv_thread.c index 66be13d74..75c9076c7 100755 --- a/usrsctplib/user_recv_thread.c +++ b/usrsctplib/user_recv_thread.c @@ -135,8 +135,7 @@ sctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa 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); } diff --git a/usrsctplib/user_socket.c b/usrsctplib/user_socket.c index cde6ecc41..d1e091a8f 100755 --- a/usrsctplib/user_socket.c +++ b/usrsctplib/user_socket.c @@ -3154,8 +3154,7 @@ usrsctp_deregister_address(void *addr) 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 "