From 7ba8e234b6c45774b54d24e632cb14730a62b0b3 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 5 Apr 2017 14:45:41 +0200 Subject: ipcpd: normal: Add missing else clause A missing else clause was missing in the fast path, causing the PCI to be shrunk when it should not be. A double free has also been fixed. --- src/ipcpd/normal/fmgr.c | 15 ++++++--------- src/ipcpd/normal/pol/complete.c | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 56f1e099..3191eac5 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -186,8 +186,6 @@ void * fmgr_nm1_sdu_reader(void * o) shm_pci_des(sdb, &pci); if (pci.dst_addr != ipcpi.dt_addr) { - log_dbg("PDU needs to be forwarded."); - if (pci.ttl == 0) { log_dbg("TTL was zero."); ipcp_flow_del(sdb); @@ -211,14 +209,13 @@ void * fmgr_nm1_sdu_reader(void * o) ipcp_flow_del(sdb); continue; } - } + } else { + shm_pci_shrink(sdb); - shm_pci_shrink(sdb); - - if (frct_nm1_post_sdu(&pci, sdb)) { - log_err("Failed to hand PDU to FRCT."); - ipcp_flow_del(sdb); - continue; + if (frct_nm1_post_sdu(&pci, sdb)) { + log_err("Failed to hand PDU to FRCT."); + continue; + } } } } diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c index 1f3f6031..6c0be9ec 100644 --- a/src/ipcpd/normal/pol/complete.c +++ b/src/ipcpd/normal/pol/complete.c @@ -89,7 +89,7 @@ static void * allocator(void * o) /* FIXME: subscribe to members to keep the graph complete. */ len = rib_children("/" MEMBERS_NAME, &children); for (i = 0; i < len; ++i) { - if (strcmp(children[i], ipcpi.name) < 0) { + if (strcmp(children[i], ipcpi.name) != 0) { if (connmgr_alloc(complete->ae, children[i], &qs, -- cgit v1.2.3 From f309ed3048c0813262c2cf4c7db24befc1729b3a Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 5 Apr 2017 16:42:42 +0200 Subject: ipcpd: shim-eth-llc: Fix overwrite mgmt frames This fixes the overwriting of management frames by adding a list in the shim Ethernet that keeps track of management frames instead of a single buffer. --- src/ipcpd/shim-eth-llc/main.c | 63 ++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index 142ca680..34a25ee2 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -96,6 +96,13 @@ struct ef { uint8_t r_addr[MAC_SIZE]; }; +struct mgmt_frame { + struct list_head next; + uint8_t r_addr[MAC_SIZE]; + uint8_t buf[ETH_FRAME_SIZE]; + size_t len; +}; + struct { #ifdef __FreeBSD__ struct sockaddr_dl device; @@ -118,10 +125,8 @@ struct { pthread_t mgmt_handler; pthread_mutex_t mgmt_lock; pthread_cond_t mgmt_cond; - uint8_t mgmt_r_addr[MAC_SIZE]; - uint8_t mgmt_buf[ETH_FRAME_SIZE]; - size_t mgmt_len; - bool mgmt_arrived; + struct list_head mgmt_frames; + } eth_llc_data; static int eth_llc_data_init(void) @@ -183,6 +188,8 @@ static int eth_llc_data_init(void) if (pthread_cond_init(ð_llc_data.mgmt_cond, &cattr)) goto mgmt_lock_destroy; + list_head_init(ð_llc_data.mgmt_frames); + return 0; mgmt_lock_destroy: @@ -488,10 +495,11 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, static void * eth_llc_ipcp_mgmt_handler(void * o) { - int ret; - struct timespec timeout = {(MGMT_TIMEOUT / 1000), - (MGMT_TIMEOUT % 1000) * MILLION}; - struct timespec abstime; + int ret; + struct timespec timeout = {(MGMT_TIMEOUT / 1000), + (MGMT_TIMEOUT % 1000) * MILLION}; + struct timespec abstime; + struct mgmt_frame * frame; (void) o; @@ -506,7 +514,8 @@ static void * eth_llc_ipcp_mgmt_handler(void * o) pthread_mutex_lock(ð_llc_data.mgmt_lock); - while (!eth_llc_data.mgmt_arrived && ret != -ETIMEDOUT) + while (list_is_empty(ð_llc_data.mgmt_frames) && + ret != -ETIMEDOUT) ret = -pthread_cond_timedwait(ð_llc_data.mgmt_cond, ð_llc_data.mgmt_lock, &abstime); @@ -516,10 +525,18 @@ static void * eth_llc_ipcp_mgmt_handler(void * o) continue; } - eth_llc_ipcp_mgmt_frame(eth_llc_data.mgmt_buf, - eth_llc_data.mgmt_len, - eth_llc_data.mgmt_r_addr); - eth_llc_data.mgmt_arrived = false; + frame = list_first_entry((ð_llc_data.mgmt_frames), + struct mgmt_frame, next); + if (frame == NULL) { + pthread_mutex_unlock(ð_llc_data.mgmt_lock); + continue; + } + + eth_llc_ipcp_mgmt_frame(frame->buf, frame->len, frame->r_addr); + + list_del(&frame->next); + free(frame); + pthread_mutex_unlock(ð_llc_data.mgmt_lock); } } @@ -534,6 +551,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o) uint8_t buf[ETH_FRAME_SIZE]; int frame_len = 0; struct eth_llc_frame * llc_frame; + struct mgmt_frame * frame; (void) o; @@ -573,14 +591,17 @@ static void * eth_llc_ipcp_sdu_reader(void * o) if (ssap == MGMT_SAP && dsap == MGMT_SAP) { pthread_mutex_lock(ð_llc_data.mgmt_lock); - memcpy(eth_llc_data.mgmt_buf, - &llc_frame->payload, - length); - memcpy(eth_llc_data.mgmt_r_addr, - llc_frame->src_hwaddr, - MAC_SIZE); - eth_llc_data.mgmt_len = length; - eth_llc_data.mgmt_arrived = true; + + frame = malloc(sizeof(*frame)); + if (frame == NULL) { + pthread_mutex_unlock(ð_llc_data.mgmt_lock); + continue; + } + + memcpy(frame->buf, &llc_frame->payload, length); + memcpy(frame->r_addr, llc_frame->src_hwaddr, MAC_SIZE); + frame->len = length; + list_add(&frame->next, ð_llc_data.mgmt_frames); pthread_cond_signal(ð_llc_data.mgmt_cond); pthread_mutex_unlock(ð_llc_data.mgmt_lock); } else { -- cgit v1.2.3