From 86b6d0ca1b871e629a95c9cf0ddceeeb7e1bd345 Mon Sep 17 00:00:00 2001
From: dimitri staessens <dimitri.staessens@intec.ugent.be>
Date: Mon, 31 Oct 2016 18:35:17 +0100
Subject: lib, ipcpd: Improve flow allocation

All calls for opening rbuffs are now concentrated on the dev side.
This allows some simplifications in the np1 calls. The ipcp_fini call
will not destroy the mutex associated with the state, since the final
state needs to be checked before shutting down an IPCP.
---
 src/ipcpd/shim-eth-llc/main.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

(limited to 'src/ipcpd/shim-eth-llc')

diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c
index 0d4c3903..3f3c0e1e 100644
--- a/src/ipcpd/shim-eth-llc/main.c
+++ b/src/ipcpd/shim-eth-llc/main.c
@@ -624,18 +624,22 @@ static void * eth_llc_ipcp_sdu_writer(void * o)
 
         (void) o;
 
-        while (true) {
-                if (flow_event_wait(eth_llc_data.np1_flows,
-                                    eth_llc_data.fq,
-                                    &timeout) == -ETIMEDOUT)
-                        continue;
+        while (flow_event_wait(eth_llc_data.np1_flows,
+                               eth_llc_data.fq,
+                               &timeout)) {
+                pthread_rwlock_rdlock(&ipcpi.state_lock);
+
+                if (ipcp_get_state() != IPCP_ENROLLED) {
+                        pthread_rwlock_unlock(&ipcpi.state_lock);
+                        return (void *) -1; /* -ENOTENROLLED */
+                }
 
                 while ((fd = fqueue_next(eth_llc_data.fq)) >= 0) {
                         if (ipcp_flow_read(fd, &sdb)) {
                                 LOG_ERR("Bad read from fd %d.", fd);
                                 continue;
                         }
-                        pthread_rwlock_rdlock(&ipcpi.state_lock);
+
                         pthread_rwlock_rdlock(&eth_llc_data.flows_lock);
 
                         ssap = reverse_bits(eth_llc_data.fd_to_ef[fd].sap);
@@ -645,7 +649,6 @@ static void * eth_llc_ipcp_sdu_writer(void * o)
                                MAC_SIZE);
 
                         pthread_rwlock_unlock(&eth_llc_data.flows_lock);
-                        pthread_rwlock_unlock(&ipcpi.state_lock);
 
                         eth_llc_ipcp_send_frame(r_addr, dsap, ssap,
                                                 shm_du_buff_head(sdb),
@@ -653,6 +656,8 @@ static void * eth_llc_ipcp_sdu_writer(void * o)
                                                 - shm_du_buff_head(sdb));
                         ipcp_flow_del(sdb);
                 }
+
+                pthread_rwlock_unlock(&ipcpi.state_lock);
         }
 
         return (void *) 1;
@@ -1045,6 +1050,13 @@ static int eth_llc_ipcp_flow_dealloc(int fd)
         ipcp_flow_fini(fd);
 
         pthread_rwlock_rdlock(&ipcpi.state_lock);
+
+        if (ipcp_get_state() != IPCP_ENROLLED) {
+                pthread_rwlock_unlock(&ipcpi.state_lock);
+                LOG_DBG("Won't register with non-enrolled IPCP.");
+                return -1; /* -ENOTENROLLED */
+        }
+
         pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
 
         flow_set_del(eth_llc_data.np1_flows, fd);
@@ -1058,11 +1070,11 @@ static int eth_llc_ipcp_flow_dealloc(int fd)
 
         eth_llc_data.ef_to_fd[sap] = -1;
 
+        flow_dealloc(fd);
+
         pthread_rwlock_unlock(&eth_llc_data.flows_lock);
         pthread_rwlock_unlock(&ipcpi.state_lock);
 
-        flow_dealloc(fd);
-
         LOG_DBG("Flow with fd %d deallocated.", fd);
 
         return 0;
-- 
cgit v1.2.3