From 7d7228fa0f9b5593fead5cfcb10bfc5bfaad4d08 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Wed, 22 Nov 2023 18:02:46 +0100 Subject: ipcpd: Fix eth management packets blocking rdrbuff The ipcpd-eth-* reserve a packet buffer slot for the N+1 data packets whenever receiving a frame. For management frames, that slot is not needed and it was not released, thus blocking the rdrbuff. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/eth/eth.c | 37 +++++++++++++++++-------------------- src/ipcpd/udp/main.c | 2 ++ 2 files changed, 19 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index 3b357067..999c1ac8 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -782,6 +782,8 @@ static void * eth_ipcp_mgmt_handler(void * o) { (void) o; + pthread_cleanup_push(__cleanup_mutex_unlock, ð_data.mgmt_lock); + while (true) { int ret = 0; struct timespec timeout = {(MGMT_TIMEO / 1000), @@ -793,8 +795,6 @@ static void * eth_ipcp_mgmt_handler(void * o) ts_add(&abstime, &timeout, &abstime); pthread_mutex_lock(ð_data.mgmt_lock); - pthread_cleanup_push(__cleanup_mutex_unlock, - ð_data.mgmt_lock); while (list_is_empty(ð_data.mgmt_frames) && ret != -ETIMEDOUT) @@ -807,7 +807,7 @@ static void * eth_ipcp_mgmt_handler(void * o) if (frame != NULL) list_del(&frame->next); - pthread_cleanup_pop(true); + pthread_mutex_unlock(ð_data.mgmt_lock); if (frame == NULL) continue; @@ -817,6 +817,8 @@ static void * eth_ipcp_mgmt_handler(void * o) free(frame); } + pthread_cleanup_pop(false); + return (void *) 0; } @@ -915,22 +917,14 @@ static void * eth_ipcp_packet_reader(void * o) #endif length = ntohs(e_frame->length); #if defined(BUILD_ETH_DIX) - if (e_frame->ethertype != eth_data.ethertype) { -#ifndef HAVE_NETMAP - ipcp_sdb_release(sdb); -#endif - continue; - } + if (e_frame->ethertype != eth_data.ethertype) + goto fail_frame; deid = ntohs(e_frame->eid); if (deid == MGMT_EID) { #elif defined (BUILD_ETH_LLC) - if (length > 0x05FF) { /* DIX */ -#ifndef HAVE_NETMAP - ipcp_sdb_release(sdb); -#endif - continue; - } + if (length > 0x05FF) /* DIX */ + goto fail_frame; length -= LLC_HEADER_SIZE; @@ -939,6 +933,8 @@ static void * eth_ipcp_packet_reader(void * o) if (ssap == MGMT_SAP && dsap == MGMT_SAP) { #endif + ipcp_sdb_release(sdb); /* No need for the N+1 buffer. */ + frame = malloc(sizeof(*frame)); if (frame == NULL) { log_err("Failed to allocate frame."); @@ -953,7 +949,6 @@ static void * eth_ipcp_packet_reader(void * o) list_add(&frame->next, ð_data.mgmt_frames); pthread_cond_signal(ð_data.mgmt_cond); pthread_mutex_unlock(ð_data.mgmt_lock); - } else { pthread_rwlock_rdlock(ð_data.flows_lock); @@ -1027,10 +1022,10 @@ static void * eth_ipcp_packet_writer(void * o) (void) o; - pthread_cleanup_push(cleanup_writer, fq); - ipcp_lock_to_core(); + pthread_cleanup_push(cleanup_writer, fq); + while (true) { fevent(eth_data.np1_flows, fq, NULL); while ((fd = fqueue_next(fq)) >= 0) { @@ -1048,6 +1043,7 @@ static void * eth_ipcp_packet_writer(void * o) == NULL) { log_dbg("Failed to allocate header."); ipcp_sdb_release(sdb); + continue; } pthread_rwlock_rdlock(ð_data.flows_lock); @@ -1063,14 +1059,15 @@ static void * eth_ipcp_packet_writer(void * o) pthread_rwlock_unlock(ð_data.flows_lock); - eth_ipcp_send_frame(r_addr, + if (eth_ipcp_send_frame(r_addr, #if defined(BUILD_ETH_DIX) deid, #elif defined(BUILD_ETH_LLC) dsap, ssap, #endif shm_du_buff_head(sdb), - len); + len)) + log_dbg("Failed to send frame."); ipcp_sdb_release(sdb); } } diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c index 91fdd71e..ddcf1a5b 100644 --- a/src/ipcpd/udp/main.c +++ b/src/ipcpd/udp/main.c @@ -431,6 +431,8 @@ static void * udp_ipcp_packet_reader(void * o) (void) o; + ipcp_lock_to_core(); + data = buf + sizeof(uint32_t); eid_p = (uint32_t *) buf; -- cgit v1.2.3