diff options
| author | Sander Vrijders <sander.vrijders@ugent.be> | 2017-04-04 17:11:40 +0000 | 
|---|---|---|
| committer | dimitri staessens <dimitri.staessens@ugent.be> | 2017-04-04 17:11:40 +0000 | 
| commit | c6bda726506552db2135b15df97d3ba76d6ae0a5 (patch) | |
| tree | 5e8d34eca4fd489d98e79a15c67c7c2403a2b56c /src/ipcpd | |
| parent | 7647833ec5bafd7b9c54e97ffde31227f4d220a2 (diff) | |
| parent | 488742a9b3692a50f9a6b9f1efead56e6815c877 (diff) | |
| download | ouroboros-c6bda726506552db2135b15df97d3ba76d6ae0a5.tar.gz ouroboros-c6bda726506552db2135b15df97d3ba76d6ae0a5.zip | |
Merged in sandervrijders/ouroboros/be-eth-mgmt (pull request #459)
Be eth mgmt
Diffstat (limited to 'src/ipcpd')
| -rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 459 | 
1 files changed, 164 insertions, 295 deletions
| diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index d9f2d49f..5a80aa91 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -33,6 +33,7 @@  #include <ouroboros/ipcp-dev.h>  #include <ouroboros/fqueue.h>  #include <ouroboros/logs.h> +#include <ouroboros/time_utils.h>  #include "ipcp.h"  #include "shim_eth_llc_messages.pb-c.h" @@ -77,6 +78,7 @@ typedef ShimEthLlcMsg shim_eth_llc_msg_t;  #define EVENT_WAIT_TIMEOUT 100 /* us */  #define NAME_QUERY_TIMEOUT 100000000 /* ns */ +#define MGMT_TIMEOUT 100 /* ms */  struct eth_llc_frame {          uint8_t dst_hwaddr[MAC_SIZE]; @@ -103,12 +105,6 @@ struct {          int                s_fd;          struct bmp *       saps; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        uint8_t *          rx_ring; -        uint8_t *          tx_ring; -        int                tx_offset; -        pthread_mutex_t    tx_lock; -#endif          flow_set_t *       np1_flows;          fqueue_t *         fq;          int *              ef_to_fd; @@ -117,11 +113,22 @@ struct {          pthread_t          sdu_writer;          pthread_t          sdu_reader; + +        /* Handle mgmt frames in a different thread */ +        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;  } eth_llc_data;  static int eth_llc_data_init(void)  { -        int i; +        int                i; +        int                ret = -1; +        pthread_condattr_t cattr;          eth_llc_data.fd_to_ef = malloc(sizeof(struct ef) * IRMD_MAX_FLOWS);          if (eth_llc_data.fd_to_ef == NULL) @@ -129,32 +136,26 @@ static int eth_llc_data_init(void)          eth_llc_data.ef_to_fd = malloc(sizeof(struct ef) * MAX_SAPS);          if (eth_llc_data.ef_to_fd == NULL) { -                free(eth_llc_data.fd_to_ef); -                return -ENOMEM; +                ret = -ENOMEM; +                goto free_fd_to_ef;          }          eth_llc_data.saps = bmp_create(MAX_SAPS, 2);          if (eth_llc_data.saps == NULL) { -                free(eth_llc_data.ef_to_fd); -                free(eth_llc_data.fd_to_ef); -                return -ENOMEM; +                ret = -ENOMEM; +                goto free_ef_to_fd;          }          eth_llc_data.np1_flows = flow_set_create();          if (eth_llc_data.np1_flows == NULL) { -                bmp_destroy(eth_llc_data.saps); -                free(eth_llc_data.ef_to_fd); -                free(eth_llc_data.fd_to_ef); -                return -ENOMEM; +                ret = -ENOMEM; +                goto bmp_destroy;          }          eth_llc_data.fq = fqueue_create();          if (eth_llc_data.fq == NULL) { -                flow_set_destroy(eth_llc_data.np1_flows); -                bmp_destroy(eth_llc_data.saps); -                free(eth_llc_data.ef_to_fd); -                free(eth_llc_data.fd_to_ef); -                return -ENOMEM; +                ret = -ENOMEM; +                goto flow_set_destroy;          }          for (i = 0; i < MAX_SAPS; ++i) @@ -166,26 +167,52 @@ static int eth_llc_data_init(void)                  memset(ð_llc_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);          } -        pthread_rwlock_init(ð_llc_data.flows_lock, NULL); +        if (pthread_rwlock_init(ð_llc_data.flows_lock, NULL)) +                goto fqueue_destroy; + +        if (pthread_mutex_init(ð_llc_data.mgmt_lock, NULL)) +                goto flow_lock_destroy; + +        if (pthread_condattr_init(&cattr)) +                goto mgmt_lock_destroy;; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        pthread_mutex_init(ð_llc_data.tx_lock, NULL); +#ifndef __APPLE__ +        pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);  #endif +        if (pthread_cond_init(ð_llc_data.mgmt_cond, &cattr)) +                goto mgmt_lock_destroy; +          return 0; + + mgmt_lock_destroy: +        pthread_mutex_destroy(ð_llc_data.mgmt_lock); + flow_lock_destroy: +        pthread_rwlock_destroy(ð_llc_data.flows_lock); + fqueue_destroy: +        fqueue_destroy(eth_llc_data.fq); + flow_set_destroy: +        flow_set_destroy(eth_llc_data.np1_flows); + bmp_destroy: +        bmp_destroy(eth_llc_data.saps); + free_ef_to_fd: +        free(eth_llc_data.ef_to_fd); + free_fd_to_ef: +        free(eth_llc_data.fd_to_ef); + +        return ret;  }  void eth_llc_data_fini(void)  { -        bmp_destroy(eth_llc_data.saps); -        flow_set_destroy(eth_llc_data.np1_flows); +        pthread_cond_destroy(ð_llc_data.mgmt_cond); +        pthread_mutex_destroy(ð_llc_data.mgmt_lock); +        pthread_rwlock_destroy(ð_llc_data.flows_lock);          fqueue_destroy(eth_llc_data.fq); +        flow_set_destroy(eth_llc_data.np1_flows); +        bmp_destroy(eth_llc_data.saps);          free(eth_llc_data.fd_to_ef);          free(eth_llc_data.ef_to_fd); -        pthread_rwlock_destroy(ð_llc_data.flows_lock); -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        pthread_mutex_destroy(ð_llc_data.tx_lock); -#endif  }  static uint8_t reverse_bits(uint8_t b) @@ -203,16 +230,10 @@ static int eth_llc_ipcp_send_frame(uint8_t * dst_addr,                                     uint8_t * payload,                                     size_t    len)  { -        uint32_t frame_len = 0; -        uint8_t cf = 0x03; -        uint16_t length; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        struct pollfd pfd; -        struct tpacket_hdr * header; -        uint8_t * frame; -#else -        uint8_t frame[SHIM_ETH_LLC_MAX_SDU_SIZE]; -#endif +        uint32_t               frame_len = 0; +        uint8_t                cf = 0x03; +        uint16_t               length; +        uint8_t                frame[SHIM_ETH_LLC_MAX_SDU_SIZE];          struct eth_llc_frame * llc_frame;          if (payload == NULL) { @@ -223,37 +244,6 @@ static int eth_llc_ipcp_send_frame(uint8_t * dst_addr,          if (len > SHIM_ETH_LLC_MAX_SDU_SIZE)                  return -1; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        pthread_mutex_lock(ð_llc_data.tx_lock); - -        header = (void *) (eth_llc_data.tx_ring + -                           eth_llc_data.tx_offset * SHM_RDRB_BLOCK_SIZE); - -        while (header->tp_status != TP_STATUS_AVAILABLE) { -                pfd.fd = eth_llc_data.s_fd; -                pfd.revents = 0; -                pfd.events = POLLIN | POLLRDNORM | POLLERR; - -                pthread_mutex_unlock(ð_llc_data.tx_lock); - -                if (poll(&pfd, 1, -1) <= 0) { -                        log_err("Failed to poll."); -                        pthread_mutex_lock(ð_llc_data.tx_lock); -                        continue; -                } - -                pthread_mutex_lock(ð_llc_data.tx_lock); - -                header = (void *) (eth_llc_data.tx_ring -                                   + eth_llc_data.tx_offset -                                   * SHM_RDRB_BLOCK_SIZE); -        } - -        frame = (uint8_t *) header -                + TPACKET_HDRLEN - sizeof(struct sockaddr_ll); - -        pthread_mutex_unlock(ð_llc_data.tx_lock); -#endif          llc_frame = (struct eth_llc_frame *) frame;          memcpy(llc_frame->dst_hwaddr, dst_addr, MAC_SIZE); @@ -274,23 +264,6 @@ static int eth_llc_ipcp_send_frame(uint8_t * dst_addr,          frame_len = ETH_HEADER_SIZE + LLC_HEADER_SIZE + len; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        pthread_mutex_lock(ð_llc_data.tx_lock); - -        header->tp_len = frame_len; -        header->tp_status = TP_STATUS_SEND_REQUEST; - -        if (send(eth_llc_data.s_fd, NULL, 0, MSG_DONTWAIT) < 0) { -                pthread_mutex_unlock(ð_llc_data.tx_lock); -                log_err("Failed to write frame into TX_RING."); -                return -1; -        } - -        eth_llc_data.tx_offset = -                (eth_llc_data.tx_offset + 1) & ((SHM_BUFFER_SIZE) - 1); - -        pthread_mutex_unlock(ð_llc_data.tx_lock); -#else          if (sendto(eth_llc_data.s_fd,                     frame,                     frame_len, @@ -300,7 +273,7 @@ static int eth_llc_ipcp_send_frame(uint8_t * dst_addr,                  log_err("Failed to send message.");                  return -1;          } -#endif +          return 0;  } @@ -374,21 +347,19 @@ static int eth_llc_ipcp_sap_req(uint8_t   r_sap,  {          int fd; -        /* reply to IRM */ +        pthread_rwlock_wrlock(ð_llc_data.flows_lock); + +        /* reply to IRM, called under lock to prevent race */          fd = ipcp_flow_req_arr(getpid(), dst_name, cube);          if (fd < 0) {                  log_err("Could not get new flow from IRMd.");                  return -1;          } -        pthread_rwlock_rdlock(&ipcpi.state_lock); -        pthread_rwlock_wrlock(ð_llc_data.flows_lock); -          eth_llc_data.fd_to_ef[fd].r_sap = r_sap;          memcpy(eth_llc_data.fd_to_ef[fd].r_addr, r_addr, MAC_SIZE);          pthread_rwlock_unlock(ð_llc_data.flows_lock); -        pthread_rwlock_unlock(&ipcpi.state_lock);          log_dbg("New flow request, fd %d, remote SAP %d.", fd, r_sap); @@ -403,13 +374,11 @@ static int eth_llc_ipcp_sap_alloc_reply(uint8_t   ssap,          int ret = 0;          int fd = -1; -        pthread_rwlock_rdlock(&ipcpi.state_lock); -        pthread_rwlock_wrlock(& eth_llc_data.flows_lock); +        pthread_rwlock_wrlock(ð_llc_data.flows_lock);          fd = eth_llc_data.ef_to_fd[dsap];          if (fd < 0) {                  pthread_rwlock_unlock(& eth_llc_data.flows_lock); -                pthread_rwlock_unlock(&ipcpi.state_lock);                  log_err("No flow found with that SAP.");                  return -1; /* -EFLOWNOTFOUND */          } @@ -422,7 +391,6 @@ static int eth_llc_ipcp_sap_alloc_reply(uint8_t   ssap,          }          pthread_rwlock_unlock(ð_llc_data.flows_lock); -        pthread_rwlock_unlock(&ipcpi.state_lock);          log_dbg("Flow reply, fd %d, SSAP %d, DSAP %d.", fd, ssap, dsap); @@ -451,7 +419,7 @@ static int eth_llc_ipcp_name_query_req(char *    name,  static int eth_llc_ipcp_name_query_reply(char *    name,                                           uint8_t * r_addr)  { -        uint64_t address = 0; +        uint64_t           address = 0;          struct list_head * pos;          memcpy(&address, r_addr, MAC_SIZE); @@ -475,7 +443,9 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf,                                     size_t    len,                                     uint8_t * r_addr)  { -        shim_eth_llc_msg_t * msg = shim_eth_llc_msg__unpack(NULL, len, buf); +        shim_eth_llc_msg_t * msg; + +        msg = shim_eth_llc_msg__unpack(NULL, len, buf);          if (msg == NULL) {                  log_err("Failed to unpack.");                  return -1; @@ -512,65 +482,68 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf,          return 0;  } -static void * eth_llc_ipcp_sdu_reader(void * o) +static void * eth_llc_ipcp_mgmt_handler(void * o)  { -        uint8_t br_addr[MAC_SIZE]; -        uint16_t length; -        uint8_t dsap; -        uint8_t ssap; -        int fd; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        struct pollfd pfd; -        int offset = 0; -        struct tpacket_hdr * header; -        uint8_t * buf = NULL; -#else -        uint8_t buf[ETH_FRAME_SIZE]; -        int frame_len = 0; -#endif -        struct eth_llc_frame * llc_frame; +        int             ret; +        struct timespec timeout = {(MGMT_TIMEOUT / 1000), +                                   (MGMT_TIMEOUT % 1000) * MILLION}; +        struct timespec abstime;          (void) o; -        memset(br_addr, 0xff, MAC_SIZE * sizeof(uint8_t)); -          while (true) { -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                pthread_mutex_lock(ð_llc_data.tx_lock); +                ret = 0; -                header = (void *) (eth_llc_data.rx_ring + -                                   offset * SHM_RDRB_BLOCK_SIZE); +                if (ipcp_get_state() != IPCP_OPERATIONAL) +                        return (void *) 0; -                while (!(header->tp_status & TP_STATUS_USER)) { -                        pfd.fd = eth_llc_data.s_fd; -                        pfd.revents = 0; -                        pfd.events = POLLIN | POLLRDNORM | POLLERR; +                clock_gettime(PTHREAD_COND_CLOCK, &abstime); +                ts_add(&abstime, &timeout, &abstime); -                        pthread_mutex_unlock(ð_llc_data.tx_lock); - -                        if (poll(&pfd, 1, -1) <= 0) { -                                log_err("Failed to poll."); -                                pthread_mutex_lock(ð_llc_data.tx_lock); -                                continue; -                        } +                pthread_mutex_lock(ð_llc_data.mgmt_lock); -                        pthread_mutex_lock(ð_llc_data.tx_lock); +                while (!eth_llc_data.mgmt_arrived && ret != -ETIMEDOUT) +                        ret = -pthread_cond_timedwait(ð_llc_data.mgmt_cond, +                                                      ð_llc_data.mgmt_lock, +                                                      &abstime); -                        header = (void *) (eth_llc_data.rx_ring + -                                           offset * SHM_RDRB_BLOCK_SIZE); +                if (ret == -ETIMEDOUT) { +                        pthread_mutex_unlock(ð_llc_data.mgmt_lock); +                        continue;                  } -                buf = (uint8_t * ) header + header->tp_mac; +                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; +                pthread_mutex_unlock(ð_llc_data.mgmt_lock); +        } +} -                pthread_mutex_unlock(ð_llc_data.tx_lock); -#else +static void * eth_llc_ipcp_sdu_reader(void * o) +{ +        uint8_t                br_addr[MAC_SIZE]; +        uint16_t               length; +        uint8_t                dsap; +        uint8_t                ssap; +        int                    fd; +        uint8_t                buf[ETH_FRAME_SIZE]; +        int                    frame_len = 0; +        struct eth_llc_frame * llc_frame; + +        (void) o; + +        memset(br_addr, 0xff, MAC_SIZE * sizeof(uint8_t)); + +        while (true) {                  frame_len = recv(eth_llc_data.s_fd, buf,                                   SHIM_ETH_LLC_MAX_SDU_SIZE, 0); -                if (frame_len < 0) { -                        log_err("Failed to receive frame."); +                if (frame_len < 0)                          continue; -                } -#endif + +                if (ipcp_get_state() != IPCP_OPERATIONAL) +                        return (void *) 0; +                  llc_frame = (struct eth_llc_frame *) buf;  #ifdef __FreeBSD__ @@ -580,28 +553,14 @@ static void * eth_llc_ipcp_sdu_reader(void * o)  #endif                             llc_frame->dst_hwaddr,                             MAC_SIZE) && -                    memcmp(br_addr, llc_frame->dst_hwaddr, MAC_SIZE)) { -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                        offset = (offset + 1) & ((SHM_BUFFER_SIZE) - 1); -                        header->tp_status = TP_STATUS_KERNEL; -#endif +                           memcmp(br_addr, llc_frame->dst_hwaddr, MAC_SIZE))                          continue; -                }                  memcpy(&length, &llc_frame->length, sizeof(length));                  length = ntohs(length); -                if (length > 0x05FF) { /* DIX */ -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                        pthread_mutex_lock(ð_llc_data.tx_lock); - -                        offset = (offset + 1) & ((SHM_BUFFER_SIZE) -1); -                        header->tp_status = TP_STATUS_KERNEL; - -                        pthread_mutex_unlock(ð_llc_data.tx_lock); -#endif +                if (length > 0x05FF) /* DIX */                          continue; -                }                  length -= LLC_HEADER_SIZE; @@ -609,23 +568,23 @@ static void * eth_llc_ipcp_sdu_reader(void * o)                  ssap = reverse_bits(llc_frame->ssap);                  if (ssap == MGMT_SAP && dsap == MGMT_SAP) { -                        eth_llc_ipcp_mgmt_frame(&llc_frame->payload, -                                                length, -                                                llc_frame->src_hwaddr); +                        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; +                        pthread_cond_signal(ð_llc_data.mgmt_cond); +                        pthread_mutex_unlock(ð_llc_data.mgmt_lock);                  } else {                          pthread_rwlock_rdlock(ð_llc_data.flows_lock);                          fd = eth_llc_data.ef_to_fd[dsap];                          if (fd < 0) {                                  pthread_rwlock_unlock(ð_llc_data.flows_lock); -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                                pthread_mutex_lock(ð_llc_data.tx_lock); - -                                offset = (offset + 1) & ((SHM_BUFFER_SIZE) - 1); -                                header->tp_status = TP_STATUS_KERNEL; - -                                pthread_mutex_unlock(ð_llc_data.tx_lock); -#endif                                  continue;                          } @@ -633,14 +592,6 @@ static void * eth_llc_ipcp_sdu_reader(void * o)                              || memcmp(eth_llc_data.fd_to_ef[fd].r_addr,                                        llc_frame->src_hwaddr, MAC_SIZE)) {                                  pthread_rwlock_unlock(ð_llc_data.flows_lock); -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                                pthread_mutex_lock(ð_llc_data.tx_lock); - -                                offset = (offset + 1) & ((SHM_BUFFER_SIZE) -1); -                                header->tp_status = TP_STATUS_KERNEL; - -                                pthread_mutex_unlock(ð_llc_data.tx_lock); -#endif                                  continue;                          } @@ -648,14 +599,6 @@ static void * eth_llc_ipcp_sdu_reader(void * o)                          flow_write(fd, &llc_frame->payload, length);                  } -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                pthread_mutex_lock(ð_llc_data.tx_lock); - -                offset = (offset + 1) & ((SHM_BUFFER_SIZE) - 1); -                header->tp_status = TP_STATUS_KERNEL; - -                pthread_mutex_unlock(ð_llc_data.tx_lock); -#endif          }          return (void *) 0; @@ -663,49 +606,42 @@ static void * eth_llc_ipcp_sdu_reader(void * o)  static void * eth_llc_ipcp_sdu_writer(void * o)  { -        int fd; +        int                  fd;          struct shm_du_buff * sdb; -        uint8_t ssap; -        uint8_t dsap; -        uint8_t r_addr[MAC_SIZE]; -        struct timespec timeout = {0, EVENT_WAIT_TIMEOUT * 1000}; +        uint8_t              ssap; +        uint8_t              dsap; +        uint8_t              r_addr[MAC_SIZE]; +        struct timespec      timeout = {0, EVENT_WAIT_TIMEOUT * 1000};          (void) o;          while (flow_event_wait(eth_llc_data.np1_flows,                                 eth_llc_data.fq,                                 &timeout)) { + +                if (ipcp_get_state() != IPCP_OPERATIONAL) +                        return (void *) 0; + +                pthread_rwlock_rdlock(ð_llc_data.flows_lock);                  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); - -                        if (ipcp_get_state() != IPCP_OPERATIONAL) { -                                pthread_rwlock_unlock(&ipcpi.state_lock); -                                ipcp_flow_del(sdb); -                                return (void *) -1; /* -ENOTENROLLED */ -                        } - -                        pthread_rwlock_rdlock(ð_llc_data.flows_lock); -                          ssap = reverse_bits(eth_llc_data.fd_to_ef[fd].sap);                          dsap = reverse_bits(eth_llc_data.fd_to_ef[fd].r_sap);                          memcpy(r_addr,                                 eth_llc_data.fd_to_ef[fd].r_addr,                                 MAC_SIZE); -                        pthread_rwlock_unlock(ð_llc_data.flows_lock); -                        pthread_rwlock_unlock(&ipcpi.state_lock); -                          eth_llc_ipcp_send_frame(r_addr, dsap, ssap,                                                  shm_du_buff_head(sdb),                                                  shm_du_buff_tail(sdb)                                                  - shm_du_buff_head(sdb));                          ipcp_flow_del(sdb);                  } +                pthread_rwlock_unlock(ð_llc_data.flows_lock);          }          return (void *) 1; @@ -722,15 +658,11 @@ void ipcp_sig_handler(int         sig,          case SIGTERM:          case SIGHUP:                  if (info->si_pid == ipcpi.irmd_api) { -                        pthread_rwlock_wrlock(&ipcpi.state_lock); -                          if (ipcp_get_state() == IPCP_INIT)                                  ipcp_set_state(IPCP_NULL);                          if (ipcp_get_state() == IPCP_OPERATIONAL)                                  ipcp_set_state(IPCP_SHUTDOWN); - -                        pthread_rwlock_unlock(&ipcpi.state_lock);                  }          default:                  return; @@ -739,20 +671,17 @@ void ipcp_sig_handler(int         sig,  static int eth_llc_ipcp_bootstrap(struct dif_config * conf)  { -        int skfd = -1; -        struct ifreq ifr; -        int idx; +        int                skfd = -1; +        struct ifreq       ifr; +        int                idx;  #ifdef __FreeBSD__ -        struct ifaddrs * ifaddr; -        struct ifaddrs * ifa; +        struct ifaddrs *   ifaddr; +        struct ifaddrs *   ifa;          struct sockaddr_dl device;  #else          struct sockaddr_ll device;  #endif - -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        struct tpacket_req req; -#endif +        struct timeval tv = {0, EVENT_WAIT_TIMEOUT * 1000};          assert(conf);          assert(conf->type == THIS_TYPE); @@ -831,68 +760,35 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)                  return -1;          } -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        if (SHIM_ETH_LLC_MAX_SDU_SIZE > SHM_RDRB_BLOCK_SIZE) { -                log_err("Max SDU size is bigger than DU map block size."); -                close(skfd); -                return -1; -        } - -        req.tp_block_size = SHM_RDRB_BLOCK_SIZE; -        req.tp_frame_size = SHM_RDRB_BLOCK_SIZE; -        req.tp_block_nr = SHM_BUFFER_SIZE; -        req.tp_frame_nr = SHM_BUFFER_SIZE; - -        if (setsockopt(skfd, SOL_PACKET, PACKET_RX_RING, -                       (void *) &req, sizeof(req))) { -                log_err("Failed to set sockopt PACKET_RX_RING"); -                close(skfd); -                return -1; -        } - -        if (setsockopt(skfd, SOL_PACKET, PACKET_TX_RING, -                       (void *) &req, sizeof(req))) { -                log_err("Failed to set sockopt PACKET_TX_RING"); -                close(skfd); -                return -1; -        } -#endif          if (bind(skfd, (struct sockaddr *) &device, sizeof(device))) {                  log_err("Failed to bind socket to interface");                  close(skfd);                  return -1;          } -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        eth_llc_data.rx_ring = mmap(NULL, 2 * SHM_RDRB_BLOCK_SIZE -                                    * (SHM_BUFFER_SIZE), -                                    PROT_READ | PROT_WRITE, MAP_SHARED, -                                    skfd, 0); -        if (eth_llc_data.rx_ring == NULL) { -                log_err("Failed to mmap"); +        if (setsockopt(skfd, SOL_SOCKET, SO_RCVTIMEO, +                       (void *) &tv, sizeof(tv))) { +                log_err("Failed to set socket timeout");                  close(skfd);                  return -1;          } -        eth_llc_data.tx_ring = eth_llc_data.rx_ring -                + SHM_RDRB_BLOCK_SIZE * (SHM_BUFFER_SIZE); -#endif -        pthread_rwlock_wrlock(&ipcpi.state_lock); -          if (ipcp_get_state() != IPCP_INIT) { -                pthread_rwlock_unlock(&ipcpi.state_lock);                  log_err("IPCP in wrong state."); +                close(skfd);                  return -1;          }          eth_llc_data.s_fd = skfd;          eth_llc_data.device = device; -#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        eth_llc_data.tx_offset = 0; -#endif          ipcp_set_state(IPCP_OPERATIONAL); +        pthread_create(ð_llc_data.mgmt_handler, +                       NULL, +                       eth_llc_ipcp_mgmt_handler, +                       NULL); +          pthread_create(ð_llc_data.sdu_reader,                         NULL,                         eth_llc_ipcp_sdu_reader, @@ -903,8 +799,6 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)                         eth_llc_ipcp_sdu_writer,                         NULL); -        pthread_rwlock_unlock(&ipcpi.state_lock); -          log_dbg("Bootstrapped shim IPCP over Ethernet with LLC with api %d.",                  getpid()); @@ -913,23 +807,20 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)  static int eth_llc_ipcp_name_reg(char * name)  { -        char * name_dup = strdup(name); +        char * name_dup; + +        name_dup = strdup(name);          if (name_dup == NULL) {                  log_err("Failed to duplicate name.");                  return -ENOMEM;          } -        pthread_rwlock_rdlock(&ipcpi.state_lock); -          if (shim_data_reg_add_entry(ipcpi.shim_data, name_dup)) { -                pthread_rwlock_unlock(&ipcpi.state_lock);                  log_err("Failed to add %s to local registry.", name);                  free(name_dup);                  return -1;          } -        pthread_rwlock_unlock(&ipcpi.state_lock); -          log_dbg("Registered %s.", name);          return 0; @@ -937,22 +828,18 @@ static int eth_llc_ipcp_name_reg(char * name)  static int eth_llc_ipcp_name_unreg(char * name)  { -        pthread_rwlock_rdlock(&ipcpi.state_lock); -          shim_data_reg_del_entry(ipcpi.shim_data, name); -        pthread_rwlock_unlock(&ipcpi.state_lock); -          return 0;  }  static int eth_llc_ipcp_name_query(char * name)  { -        uint8_t r_addr[MAC_SIZE]; -        struct timespec timeout = {0, NAME_QUERY_TIMEOUT}; +        uint8_t            r_addr[MAC_SIZE]; +        struct timespec    timeout = {0, NAME_QUERY_TIMEOUT};          shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;          struct dir_query * query; -        int ret; +        int                ret;          if (shim_data_dir_has(ipcpi.shim_data, name))                  return 0; @@ -986,8 +873,8 @@ static int eth_llc_ipcp_flow_alloc(int       fd,                                     char *    dst_name,                                     qoscube_t cube)  { -        uint8_t ssap = 0; -        uint8_t r_addr[MAC_SIZE]; +        uint8_t  ssap = 0; +        uint8_t  r_addr[MAC_SIZE];          uint64_t addr = 0;          log_dbg("Allocating flow to %s.", dst_name); @@ -1000,16 +887,12 @@ static int eth_llc_ipcp_flow_alloc(int       fd,                  return -1;          } -        pthread_rwlock_rdlock(&ipcpi.state_lock); -          if (ipcp_get_state() != IPCP_OPERATIONAL) { -                pthread_rwlock_unlock(&ipcpi.state_lock);                  log_dbg("Won't allocate flow with non-enrolled IPCP.");                  return -1; /* -ENOTENROLLED */          }          if (!shim_data_dir_has(ipcpi.shim_data, dst_name)) { -                pthread_rwlock_unlock(&ipcpi.state_lock);                  log_err("Destination unreachable.");                  return -1;          } @@ -1020,7 +903,6 @@ static int eth_llc_ipcp_flow_alloc(int       fd,          ssap =  bmp_allocate(eth_llc_data.saps);          if (!bmp_is_id_valid(eth_llc_data.saps, ssap)) {                  pthread_rwlock_unlock(ð_llc_data.flows_lock); -                pthread_rwlock_unlock(&ipcpi.state_lock);                  return -1;          } @@ -1028,18 +910,15 @@ static int eth_llc_ipcp_flow_alloc(int       fd,          eth_llc_data.ef_to_fd[ssap]   = fd;          pthread_rwlock_unlock(ð_llc_data.flows_lock); -        pthread_rwlock_unlock(&ipcpi.state_lock);          memcpy(r_addr, &addr, MAC_SIZE);          if (eth_llc_ipcp_sap_alloc(r_addr, ssap, dst_name, cube) < 0) { -                pthread_rwlock_rdlock(&ipcpi.state_lock);                  pthread_rwlock_wrlock(ð_llc_data.flows_lock);                  bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);                  eth_llc_data.fd_to_ef[fd].sap = -1;                  eth_llc_data.ef_to_fd[ssap]   = -1;                  pthread_rwlock_unlock(ð_llc_data.flows_lock); -                pthread_rwlock_unlock(&ipcpi.state_lock);                  return -1;          } @@ -1057,13 +936,11 @@ static int eth_llc_ipcp_flow_alloc_resp(int fd,          uint8_t r_sap = 0;          uint8_t r_addr[MAC_SIZE]; -        pthread_rwlock_rdlock(&ipcpi.state_lock);          pthread_rwlock_wrlock(ð_llc_data.flows_lock);          ssap = bmp_allocate(eth_llc_data.saps);          if (!bmp_is_id_valid(eth_llc_data.saps, ssap)) {                  pthread_rwlock_unlock(ð_llc_data.flows_lock); -                pthread_rwlock_unlock(&ipcpi.state_lock);                  return -1;          } @@ -1073,14 +950,11 @@ static int eth_llc_ipcp_flow_alloc_resp(int fd,          eth_llc_data.ef_to_fd[ssap] = fd;          pthread_rwlock_unlock(ð_llc_data.flows_lock); -        pthread_rwlock_unlock(&ipcpi.state_lock);          if (eth_llc_ipcp_sap_alloc_resp(r_addr, ssap, r_sap, response) < 0) { -                pthread_rwlock_rdlock(&ipcpi.state_lock);                  pthread_rwlock_wrlock(ð_llc_data.flows_lock);                  bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);                  pthread_rwlock_unlock(ð_llc_data.flows_lock); -                pthread_rwlock_unlock(&ipcpi.state_lock);                  return -1;          } @@ -1098,10 +972,7 @@ static int eth_llc_ipcp_flow_dealloc(int fd)          ipcp_flow_fini(fd); -        pthread_rwlock_rdlock(&ipcpi.state_lock); -          if (ipcp_get_state() != IPCP_OPERATIONAL) { -                pthread_rwlock_unlock(&ipcpi.state_lock);                  log_dbg("Won't register with non-enrolled IPCP.");                  return -1; /* -ENOTENROLLED */          } @@ -1120,7 +991,6 @@ static int eth_llc_ipcp_flow_dealloc(int fd)          eth_llc_data.ef_to_fd[sap] = -1;          pthread_rwlock_unlock(ð_llc_data.flows_lock); -        pthread_rwlock_unlock(&ipcpi.state_lock);          flow_dealloc(fd); @@ -1201,10 +1071,9 @@ int main(int    argc,          ipcp_shutdown();          if (ipcp_get_state() == IPCP_SHUTDOWN) { -                pthread_cancel(eth_llc_data.sdu_reader); -                pthread_cancel(eth_llc_data.sdu_writer);                  pthread_join(eth_llc_data.sdu_writer, NULL);                  pthread_join(eth_llc_data.sdu_reader, NULL); +                pthread_join(eth_llc_data.mgmt_handler, NULL);          }          eth_llc_data_fini(); | 
