diff options
| author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-10-04 15:23:54 +0200 | 
|---|---|---|
| committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-10-04 15:23:54 +0200 | 
| commit | 1a7c0923206cfb98d43122621a585027c67040ea (patch) | |
| tree | acd08f09f5a094e897020e97961b2847209df043 /src/ipcpd/shim-eth-llc/main.c | |
| parent | ecdf47b97abb8c5107846f4ef4a17bd62ba6dc82 (diff) | |
| parent | c96efb13edfaf9b2f2c626bd2a5d5d5afd38155f (diff) | |
| download | ouroboros-1a7c0923206cfb98d43122621a585027c67040ea.tar.gz ouroboros-1a7c0923206cfb98d43122621a585027c67040ea.zip | |
Merged in dstaesse/ouroboros/be-unify (pull request #251)
lib, ipcp: Revise fast path and flow interfaces
Diffstat (limited to 'src/ipcpd/shim-eth-llc/main.c')
| -rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 978 | 
1 files changed, 333 insertions, 645 deletions
| diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index d74984cc..2cf46e51 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -24,24 +24,19 @@  #define _DEFAULT_SOURCE -#include "ipcp.h" -#include "flow.h"  #include <ouroboros/errno.h> -#include <ouroboros/shm_rdrbuff.h> -#include <ouroboros/shm_ap_rbuff.h>  #include <ouroboros/list.h>  #include <ouroboros/utils.h> -#include <ouroboros/ipcp.h> -#include <ouroboros/irm_config.h> -#include <ouroboros/sockets.h>  #include <ouroboros/bitmap.h> -#include <ouroboros/flow.h>  #include <ouroboros/dev.h> +#include <ouroboros/ipcp-dev.h>  #define OUROBOROS_PREFIX "ipcpd/shim-eth-llc"  #include <ouroboros/logs.h> +#include "ipcp.h" +  #include <net/if.h>  #include <signal.h>  #include <stdlib.h> @@ -79,18 +74,12 @@ typedef ShimEthLlcMsg shim_eth_llc_msg_t;  #define LLC_HEADER_SIZE 3  #define MAX_SAPS 64  #define ETH_HEADER_SIZE (2 * MAC_SIZE + 2) -#define ETH_FRAME_SIZE (SHIM_ETH_LLC_MAX_SDU_SIZE + ETH_HEADER_SIZE +       \ -                        LLC_HEADER_SIZE + 2) +#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + LLC_HEADER_SIZE \ +                        + SHIM_ETH_LLC_MAX_SDU_SIZE)  /* global for trapping signal */  int irmd_api; -struct ipcp * _ipcp; - -#define shim_data(type) ((struct eth_llc_ipcp_data *) type->data) - -#define ipcp_flow(index) ((struct flow *) &(shim_data(_ipcp)->flows[index])) -  struct eth_llc_frame {          uint8_t dst_hwaddr[MAC_SIZE];          uint8_t src_hwaddr[MAC_SIZE]; @@ -98,196 +87,78 @@ struct eth_llc_frame {          uint8_t dsap;          uint8_t ssap;          uint8_t cf; -        uint8_t size[2];          uint8_t payload;  }; -struct eth_llc_flow { -        struct flow flow; -        uint8_t     sap; -        uint8_t     r_sap; -        uint8_t     r_addr[MAC_SIZE]; +struct ef { +        int8_t  sap; +        int8_t  r_sap; +        uint8_t r_addr[MAC_SIZE];  }; -struct eth_llc_ipcp_data { -        /* Keep ipcp_data first for polymorphism. */ -        struct ipcp_data      ipcp_data; - +struct {  #ifdef __FreeBSD__ -        struct sockaddr_dl    device; +        struct sockaddr_dl device;  #else -        struct sockaddr_ll    device; +        struct sockaddr_ll device;  #endif -        int                   s_fd; - -        struct bmp *          indices; -        struct bmp *          saps; +        int                s_fd; -        struct shm_rdrbuff *  rdrb; -        struct shm_ap_rbuff * rb; - -        uint8_t *             rx_ring; -        uint8_t *             tx_ring; -        int                   tx_offset; - -        struct eth_llc_flow   flows[AP_MAX_FLOWS]; -        pthread_rwlock_t      flows_lock; +        struct bmp *       saps; +#if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) +        uint8_t *          rx_ring; +        uint8_t *          tx_ring; +        int                tx_offset; +#endif +        int *              ef_to_fd; +        struct ef *        fd_to_ef; +        pthread_rwlock_t   flows_lock; -        pthread_t             mainloop; -        pthread_t             sdu_writer; -        pthread_t             sdu_reader; -}; +        pthread_t          sdu_writer; +        pthread_t          sdu_reader; +} eth_llc_data; -struct eth_llc_ipcp_data * eth_llc_ipcp_data_create() +static int eth_llc_data_init()  { -        struct eth_llc_ipcp_data * eth_llc_data; -        enum ipcp_type             ipcp_type; - -        eth_llc_data = malloc(sizeof(*eth_llc_data)); -        if (eth_llc_data == NULL) { -                LOG_ERR("Failed to allocate."); -                return NULL; -        } - -        ipcp_type = THIS_TYPE; -        if (ipcp_data_init((struct ipcp_data *) eth_llc_data, -                           ipcp_type) == NULL) { -                free(eth_llc_data); -                return NULL; -        } - -        eth_llc_data->rdrb = shm_rdrbuff_open(); -        if (eth_llc_data->rdrb == NULL) { -                free(eth_llc_data); -                return NULL; -        } - -        eth_llc_data->rb = shm_ap_rbuff_create_n(); -        if (eth_llc_data->rb == NULL) { -                shm_rdrbuff_close(eth_llc_data->rdrb); -                free(eth_llc_data); -                return NULL; -        } +        int i; -        eth_llc_data->indices = bmp_create(AP_MAX_FLOWS, 0); -        if (eth_llc_data->indices == NULL) { -                shm_ap_rbuff_destroy(eth_llc_data->rb); -                shm_rdrbuff_close(eth_llc_data->rdrb); -                free(eth_llc_data); -                return NULL; -        } +        eth_llc_data.fd_to_ef = malloc(sizeof(struct ef) * IRMD_MAX_FLOWS); +        if (eth_llc_data.fd_to_ef == NULL) +                return -ENOMEM; -        eth_llc_data->saps = bmp_create(MAX_SAPS, 2); -        if (eth_llc_data->indices == NULL) { -                bmp_destroy(eth_llc_data->indices); -                shm_ap_rbuff_destroy(eth_llc_data->rb); -                shm_rdrbuff_close(eth_llc_data->rdrb); -                free(eth_llc_data); -                return NULL; +        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;          } -        pthread_rwlock_init(ð_llc_data->flows_lock, NULL); - -        return eth_llc_data; -} - -void eth_llc_ipcp_data_destroy() -{ -        int i = 0; - -        if (_ipcp == NULL) -                return; - -        pthread_rwlock_rdlock(&_ipcp->state_lock); - -        if (ipcp_get_state(_ipcp) != IPCP_SHUTDOWN) -                LOG_WARN("Cleaning up while not in shutdown."); - -        /* remove all remaining sdus */ -        while ((i = shm_ap_rbuff_peek_idx(shim_data(_ipcp)->rb)) >= 0) -                shm_rdrbuff_remove(shim_data(_ipcp)->rdrb, i); - -        if (shim_data(_ipcp)->rdrb != NULL) -                shm_rdrbuff_close(shim_data(_ipcp)->rdrb); -        if (shim_data(_ipcp)->rb != NULL) -                shm_ap_rbuff_destroy(shim_data(_ipcp)->rb); -        if (shim_data(_ipcp)->indices != NULL) -                bmp_destroy(shim_data(_ipcp)->indices); -        if (shim_data(_ipcp)->saps != NULL) -                bmp_destroy(shim_data(_ipcp)->saps); - -        pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); - -        for (i = 0; i < AP_MAX_FLOWS; i ++) -                if (ipcp_flow(i)->rb != NULL) -                        shm_ap_rbuff_close(ipcp_flow(i)->rb); - -        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -        pthread_rwlock_unlock(&_ipcp->state_lock); - -        ipcp_data_destroy(_ipcp->data); -} - -/* only call this under flows_lock */ -static int port_id_to_index(int port_id) -{ -        int i; - -        for (i = 0; i < AP_MAX_FLOWS; ++i) { -                if (ipcp_flow(i)->port_id == port_id -                    && ipcp_flow(i)->state != FLOW_NULL) -                        return i; +        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;          } -        return -1; -} +        for (i = 0; i < MAX_SAPS; ++i) +                eth_llc_data.ef_to_fd[i] = -1; -/* only call this under flows_lock */ -static int addr_and_saps_to_index(const uint8_t * r_addr, -                                  uint8_t   r_sap, -                                  uint8_t   sap) -{ -        int i = 0; - -        for (i = 0; i < AP_MAX_FLOWS; i++) { -                if (ipcp_flow(i)->state == FLOW_ALLOCATED && -                    shim_data(_ipcp)->flows[i].r_sap == r_sap && -                    shim_data(_ipcp)->flows[i].sap == sap && -                    !memcmp(shim_data(_ipcp)->flows[i].r_addr, -                            r_addr, -                            MAC_SIZE)) { -                        return i; -                } +        for (i = 0; i < IRMD_MAX_FLOWS; ++i) { +                eth_llc_data.fd_to_ef[i].sap   = -1; +                eth_llc_data.fd_to_ef[i].r_sap = -1; +                memset(ð_llc_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);          } -        return -1; -} +        pthread_rwlock_init(ð_llc_data.flows_lock, NULL); -/* only call this under flows_lock */ -static int sap_to_index(uint8_t sap) -{ -        int i = 0; - -        for (i = 0; i < AP_MAX_FLOWS; i++) { -                if (shim_data(_ipcp)->flows[i].sap == sap) { -                        return i; -                } -        } - -        return -1; +        return 0;  } -/* only call this under flows_lock */ -static void destroy_ipcp_flow(int index) +void eth_llc_data_fini()  { -        ipcp_flow(index)->port_id = -1; -        if (ipcp_flow(index)->rb != NULL) -                shm_ap_rbuff_close(ipcp_flow(index)->rb); -        ipcp_flow(index)->rb = NULL; -        ipcp_flow(index)->state = FLOW_NULL; -        bmp_release(shim_data(_ipcp)->indices, index); -        bmp_release(shim_data(_ipcp)->saps, -                    shim_data(_ipcp)->flows[index].sap); +        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);  }  static uint8_t reverse_bits(uint8_t b) @@ -299,7 +170,7 @@ static uint8_t reverse_bits(uint8_t b)          return b;  } -static int eth_llc_ipcp_send_frame(uint8_t   dst_addr[MAC_SIZE], +static int eth_llc_ipcp_send_frame(uint8_t * dst_addr,                                     uint8_t   dsap,                                     uint8_t   ssap,                                     uint8_t * payload, @@ -307,24 +178,16 @@ static int eth_llc_ipcp_send_frame(uint8_t   dst_addr[MAC_SIZE],  {          int frame_len = 0;          uint8_t cf = 0x03; -        int fd; - -        uint16_t size;          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]; -#ifdef __FreeBSD__ -        struct sockaddr_dl    device; -#else -        struct sockaddr_ll    device; -#endif  #endif          struct eth_llc_frame * llc_frame; +          if (payload == NULL) {                  LOG_ERR("Payload was NULL.");                  return -1; @@ -333,79 +196,75 @@ static int eth_llc_ipcp_send_frame(uint8_t   dst_addr[MAC_SIZE],          if (len > SHIM_ETH_LLC_MAX_SDU_SIZE)                  return -1; -        fd = (shim_data(_ipcp))->s_fd; -  #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        header = (void *) shim_data(_ipcp)->tx_ring + -                (shim_data(_ipcp)->tx_offset * SHM_RDRB_BLOCK_SIZE); +        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 = fd; +                pfd.fd = eth_llc_data.s_fd;                  pfd.revents = 0;                  pfd.events = POLLIN | POLLRDNORM | POLLERR;                  if (poll(&pfd, 1, -1) <= 0) { -                        LOG_ERR("Failed to poll: %s.", strerror(errno)); +                        LOG_ERR("Failed to poll.");                          continue;                  } -                header = (void *) shim_data(_ipcp)->tx_ring + -                        (shim_data(_ipcp)->tx_offset * SHM_RDRB_BLOCK_SIZE); +                header = (void *) (eth_llc_data.tx_ring +                                   + eth_llc_data.tx_offset +                                   * SHM_RDRB_BLOCK_SIZE);          } -        frame = (void *) header + TPACKET_HDRLEN - sizeof(struct sockaddr_ll); +        frame = (uint8_t *) header +                + TPACKET_HDRLEN - sizeof(struct sockaddr_ll);  #endif -          llc_frame = (struct eth_llc_frame *) frame; -        memcpy(&llc_frame->dst_hwaddr, dst_addr, MAC_SIZE); -        memcpy(&llc_frame->src_hwaddr, +        memcpy(llc_frame->dst_hwaddr, dst_addr, MAC_SIZE); +        memcpy(llc_frame->src_hwaddr,  #ifdef __FreeBSD__ -               LLADDR(&shim_data(_ipcp)->device), +               LLADDR(ð_llc_data.device),  #else -               shim_data(_ipcp)->device.sll_addr, +               eth_llc_data.device.sll_addr,  #endif                 MAC_SIZE); -        length = htons(LLC_HEADER_SIZE + sizeof(size) + len); +        length = htons(LLC_HEADER_SIZE + len);          memcpy(&llc_frame->length, &length, sizeof(length));          llc_frame->dsap = dsap;          llc_frame->ssap = ssap; -        llc_frame->cf = cf; -        /* write the payload length, can't trust the driver */ -        size = htons(len); -        memcpy(&llc_frame->size, &size, sizeof(size)); +        llc_frame->cf   = cf;          memcpy(&llc_frame->payload, payload, len); -        frame_len = ETH_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(uint16_t) + len; +        frame_len = ETH_HEADER_SIZE + LLC_HEADER_SIZE + len;  #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING)          header->tp_len = frame_len;          header->tp_status = TP_STATUS_SEND_REQUEST; -        if (send(fd, NULL, 0, MSG_DONTWAIT) < 0) { +        if (send(eth_llc_data.s_fd, NULL, 0, MSG_DONTWAIT) < 0) {                  LOG_ERR("Failed to write frame into TX_RING.");                  return -1;          } -        shim_data(_ipcp)->tx_offset = -                (shim_data(_ipcp)->tx_offset + 1) -                & (SHM_BUFFER_SIZE -1); +        eth_llc_data.tx_offset = +                (eth_llc_data.tx_offset + 1) & (SHM_BUFFER_SIZE - 1);  #else -        device = (shim_data(_ipcp))->device; - -        if (sendto(fd, frame, frame_len, 0, -                   (struct sockaddr *) &device, sizeof(device)) <= 0) { +        if (sendto(eth_llc_data.s_fd, +                   frame, +                   frame_len, +                   0, +                   (struct sockaddr *) ð_llc_data.device, +                   sizeof(eth_llc_data.device)) <= 0) {                  LOG_ERR("Failed to send message.");                  return -1;          }  #endif -          return 0;  }  static int eth_llc_ipcp_send_mgmt_frame(shim_eth_llc_msg_t * msg, -                                        uint8_t              dst_addr[MAC_SIZE]) +                                        uint8_t *            dst_addr)  {          size_t    len;          uint8_t * buf; @@ -423,6 +282,7 @@ static int eth_llc_ipcp_send_mgmt_frame(shim_eth_llc_msg_t * msg,          if (eth_llc_ipcp_send_frame(dst_addr, reverse_bits(MGMT_SAP),                                      reverse_bits(MGMT_SAP), buf, len)) {                  LOG_ERR("Failed to send management frame."); +                free(buf);                  return -1;          } @@ -431,10 +291,10 @@ static int eth_llc_ipcp_send_mgmt_frame(shim_eth_llc_msg_t * msg,          return 0;  } -static int eth_llc_ipcp_port_alloc(uint8_t dst_addr[MAC_SIZE], -                                   uint8_t ssap, -                                   char *  dst_name, -                                   char *  src_ae_name) +static int eth_llc_ipcp_sap_alloc(uint8_t * dst_addr, +                                  uint8_t   ssap, +                                  char *    dst_name, +                                  char *    src_ae_name)  {          shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT; @@ -446,10 +306,10 @@ static int eth_llc_ipcp_port_alloc(uint8_t dst_addr[MAC_SIZE],          return eth_llc_ipcp_send_mgmt_frame(&msg, dst_addr);  } -static int eth_llc_ipcp_port_alloc_resp(uint8_t dst_addr[MAC_SIZE], -                                        uint8_t ssap, -                                        uint8_t dsap, -                                        int     response) +static int eth_llc_ipcp_sap_alloc_resp(uint8_t * dst_addr, +                                       uint8_t   ssap, +                                       uint8_t   dsap, +                                       int       response)  {          shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT; @@ -463,8 +323,7 @@ static int eth_llc_ipcp_port_alloc_resp(uint8_t dst_addr[MAC_SIZE],          return eth_llc_ipcp_send_mgmt_frame(&msg, dst_addr);  } -static int eth_llc_ipcp_port_dealloc(uint8_t dst_addr[MAC_SIZE], -                                     uint8_t ssap) +static int eth_llc_ipcp_sap_dealloc(uint8_t * dst_addr, uint8_t ssap)  {          shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT; @@ -474,142 +333,102 @@ static int eth_llc_ipcp_port_dealloc(uint8_t dst_addr[MAC_SIZE],          return eth_llc_ipcp_send_mgmt_frame(&msg, dst_addr);  } -static int eth_llc_ipcp_port_req(uint8_t r_sap, -                                 uint8_t r_addr[MAC_SIZE], -                                 char *  dst_name, -                                 char *  src_ae_name) +static int eth_llc_ipcp_sap_req(uint8_t   r_sap, +                                uint8_t * r_addr, +                                char *    dst_name, +                                char *    src_ae_name)  { -        int port_id; -        ssize_t index = 0; -        int i; +        int fd; -        pthread_rwlock_rdlock(&_ipcp->state_lock); -        pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); - -        index = bmp_allocate(shim_data(_ipcp)->indices); -        if (index < 0) { -                pthread_rwlock_unlock(&_ipcp->state_lock); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                LOG_ERR("Out of free indices."); -                return -1; -        } +        pthread_rwlock_rdlock(&ipcpi.state_lock); +        pthread_rwlock_wrlock(ð_llc_data.flows_lock);          /* reply to IRM */ -        port_id = ipcp_flow_req_arr(getpid(), -                                    dst_name, -                                    src_ae_name); - -        if (port_id < 0) { -                bmp_release(shim_data(_ipcp)->indices, index); -                pthread_rwlock_unlock(&_ipcp->state_lock); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                LOG_ERR("Could not get port id from IRMd."); +        fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name); +        if (fd < 0) { +                pthread_rwlock_unlock(ð_llc_data.flows_lock); +                pthread_rwlock_unlock(&ipcpi.state_lock); +                LOG_ERR("Could not get new flow from IRMd.");                  return -1;          } -        ipcp_flow(index)->port_id = port_id; -        ipcp_flow(index)->rb      = NULL; -        ipcp_flow(index)->state   = FLOW_PENDING; -        shim_data(_ipcp)->flows[index].r_sap = r_sap; -        for (i = 0; i < MAC_SIZE; i++) { -                shim_data(_ipcp)->flows[index].r_addr[i] = r_addr[i]; -        } +        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(&shim_data(_ipcp)->flows_lock); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(ð_llc_data.flows_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock); -        LOG_DBG("New flow request, port_id %d, remote SAP %d.", port_id, r_sap); +        LOG_DBG("New flow request, fd %d, remote SAP %d.", fd, r_sap);          return 0;  } -static int eth_llc_ipcp_port_alloc_reply(uint8_t ssap, -                                         uint8_t r_addr[MAC_SIZE], -                                         int     dsap, -                                         int     response) +static int eth_llc_ipcp_sap_alloc_reply(uint8_t   ssap, +                                        uint8_t * r_addr, +                                        int       dsap, +                                        int       response)  { -        int index = -1;          int ret = 0; -        int port_id = -1; -        int i; +        int fd = -1; -        pthread_rwlock_rdlock(&_ipcp->state_lock); -        pthread_rwlock_rdlock(&shim_data(_ipcp)->flows_lock); +        pthread_rwlock_rdlock(&ipcpi.state_lock); +        pthread_rwlock_rdlock(& eth_llc_data.flows_lock); -        index = sap_to_index(ssap); -        if (index < 0) { -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_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 */          } -        if (ipcp_flow(index)->state != FLOW_PENDING) { -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); -                return -1; /* -EFLOWNOTPENDING */ -        } - -        port_id = ipcp_flow(index)->port_id; -          if (response) { -                destroy_ipcp_flow(index); +                bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);          } else { -                ipcp_flow(index)->state = FLOW_ALLOCATED; -                shim_data(_ipcp)->flows[index].r_sap = dsap; -                for (i = 0; i < MAC_SIZE; i++) { -                        shim_data(_ipcp)->flows[index].r_addr[i] = r_addr[i]; -                } +                eth_llc_data.fd_to_ef[fd].r_sap = ssap; +                memcpy(eth_llc_data.fd_to_ef[fd].r_addr, r_addr, MAC_SIZE);          } -        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(ð_llc_data.flows_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock); -        LOG_DBG("Flow reply, port_id %d, remote SAP %d.", port_id, dsap); +        LOG_DBG("Flow reply, fd %d, SSAP %d, DSAP %d.", fd, ssap, dsap); -        if ((ret = ipcp_flow_alloc_reply(getpid(), -                                         port_id, -                                         response)) < 0) { -                return -1; /* -EPIPE */ -        } +        if ((ret = ipcp_flow_alloc_reply(fd, response)) < 0) +                return -1;          return ret;  } -static int eth_llc_ipcp_flow_dealloc_req(uint8_t ssap, -                                         uint8_t r_addr[MAC_SIZE]) +static int eth_llc_ipcp_flow_dealloc_req(uint8_t ssap, uint8_t * r_addr)  { -        int port_id = -1; -        int i = 0; +        int fd = -1; -        pthread_rwlock_rdlock(&_ipcp->state_lock); -        pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); +        pthread_rwlock_rdlock(&ipcpi.state_lock); +        pthread_rwlock_wrlock(ð_llc_data.flows_lock); -        i = sap_to_index(ssap); -        if (i < 0) { -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); +        fd = eth_llc_data.ef_to_fd[ssap]; +        if (fd < 0) { +                pthread_rwlock_unlock(ð_llc_data.flows_lock); +                pthread_rwlock_unlock(&ipcpi.state_lock);                  LOG_ERR("No flow found for remote deallocation request.");                  return 0;          } -        port_id = ipcp_flow(i)->port_id; -        destroy_ipcp_flow(i); +        bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap); -        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(ð_llc_data.flows_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock); -        irm_flow_dealloc(port_id); +        flow_dealloc(fd); -        LOG_DBG("Flow with port_id %d deallocated.", port_id); +        LOG_DBG("Flow with fd %d deallocated.", fd);          return 0;  } -static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, -                                   size_t    len, -                                   uint8_t   r_addr[MAC_SIZE]) +static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, size_t len, uint8_t * r_addr)  {          shim_eth_llc_msg_t * msg = NULL; @@ -621,27 +440,24 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf,          switch (msg->code) {          case SHIM_ETH_LLC_MSG_CODE__FLOW_REQ: -                if (ipcp_data_is_in_registry(_ipcp->data, -                                             msg->dst_name)) { -                        eth_llc_ipcp_port_req(msg->ssap, -                                              r_addr, -                                              msg->dst_name, -                                              msg->src_ae_name); +                if (ipcp_data_is_in_registry(ipcpi.data, msg->dst_name)) { +                        eth_llc_ipcp_sap_req(msg->ssap, +                                             r_addr, +                                             msg->dst_name, +                                             msg->src_ae_name);                  }                  break;          case SHIM_ETH_LLC_MSG_CODE__FLOW_REPLY: -                eth_llc_ipcp_port_alloc_reply(msg->ssap, -                                              r_addr, -                                              msg->dsap, -                                              msg->response); +                eth_llc_ipcp_sap_alloc_reply(msg->ssap, +                                             r_addr, +                                             msg->dsap, +                                             msg->response);                  break;          case SHIM_ETH_LLC_MSG_CODE__FLOW_DEALLOC: -                eth_llc_ipcp_flow_dealloc_req(msg->ssap, -                                              r_addr); +                eth_llc_ipcp_flow_dealloc_req(msg->ssap, r_addr);                  break;          default: -                LOG_ERR("Unknown message received %d.", -                        msg->code); +                LOG_ERR("Unknown message received %d.", msg->code);                  shim_eth_llc_msg__free_unpacked(msg, NULL);                  return -1;          } @@ -652,15 +468,11 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf,  static void * eth_llc_ipcp_sdu_reader(void * o)  { -        ssize_t index; -        struct rb_entry e;          uint8_t br_addr[MAC_SIZE]; +        uint16_t length;          uint8_t dsap;          uint8_t ssap; -        int i = 0; -        struct eth_llc_frame * llc_frame; -        uint16_t size; - +        int fd;  #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING)          struct pollfd pfd;          int offset = 0; @@ -670,43 +482,43 @@ static void * eth_llc_ipcp_sdu_reader(void * o)          uint8_t buf[ETH_FRAME_SIZE];          int frame_len = 0;  #endif +        struct eth_llc_frame * llc_frame;          memset(br_addr, 0xff, MAC_SIZE * sizeof(uint8_t));          while (true) {  #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -                header = (void *) shim_data(_ipcp)->rx_ring + -                        (offset * SHM_RDRB_BLOCK_SIZE); +                header = (void *) (eth_llc_data.rx_ring + +                                   offset * SHM_RDRB_BLOCK_SIZE);                  while (!(header->tp_status & TP_STATUS_USER)) { -                        pfd.fd = shim_data(_ipcp)->s_fd; +                        pfd.fd = eth_llc_data.s_fd;                          pfd.revents = 0;                          pfd.events = POLLIN | POLLRDNORM | POLLERR;                          if (poll(&pfd, 1, -1) <= 0) { -                                LOG_ERR("Failed to poll: %s.", strerror(errno)); +                                LOG_ERR("Failed to poll.");                                  continue;                          } -                        header = (void *) shim_data(_ipcp)->rx_ring + -                                (offset * SHM_RDRB_BLOCK_SIZE); +                        header = (void *) (eth_llc_data.rx_ring + +                                           offset * SHM_RDRB_BLOCK_SIZE);                  } -                buf = (void * ) header + header->tp_mac; +                buf = (uint8_t * ) header + header->tp_mac;  #else -                frame_len = recv(shim_data(_ipcp)->s_fd, buf, +                frame_len = recv(eth_llc_data.s_fd, buf,                                   SHIM_ETH_LLC_MAX_SDU_SIZE, 0);                  if (frame_len < 0) { -                        LOG_ERR("Failed to recv frame."); +                        LOG_ERR("Failed to receive frame.");                          continue;                  }  #endif -                  llc_frame = (struct eth_llc_frame *) buf;  #ifdef __FreeBSD__ -                if (memcmp(LLADDR(&shim_data(_ipcp)->device), +                if (memcmp(LLADDR(ð_llc_data.device),  #else -                if (memcmp(shim_data(_ipcp)->device.sll_addr, +                if (memcmp(eth_llc_data.device.sll_addr,  #endif                             &llc_frame->dst_hwaddr,                             MAC_SIZE) && @@ -721,46 +533,29 @@ static void * eth_llc_ipcp_sdu_reader(void * o)                  dsap = reverse_bits(llc_frame->dsap);                  ssap = reverse_bits(llc_frame->ssap); -                memcpy(&size, &llc_frame->size, sizeof(size)); +                memcpy(&length, &llc_frame->length, sizeof(length)); +                length = ntohs(length) - LLC_HEADER_SIZE;                  if (ssap == MGMT_SAP && dsap == MGMT_SAP) {                          eth_llc_ipcp_mgmt_frame(&llc_frame->payload, -                                                ntohs(size), +                                                length,                                                  llc_frame->src_hwaddr);                  } else { -                        pthread_rwlock_rdlock(&shim_data(_ipcp)->flows_lock); - -                        i = addr_and_saps_to_index(llc_frame->src_hwaddr, -                                                   ssap, -                                                   dsap); -                        if (i < 0) { -                                pthread_rwlock_unlock(&shim_data(_ipcp)-> -                                                      flows_lock); +                        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) -                                offset = (offset + 1) -                                        & (SHM_BUFFER_SIZE - 1); +                                offset = (offset + 1) & (SHM_BUFFER_SIZE - 1);                                  header->tp_status = TP_STATUS_KERNEL;  #endif                                  continue;                          } -                        while ((index = -                                shm_rdrbuff_write(shim_data(_ipcp)->rdrb, -                                                 ipcp_flow(i)->api, -                                                 0, -                                                 0, -                                                 &llc_frame->payload, -                                                 ntohs(size))) -                                < 0) -                                ; - -                        e.index = index; -                        e.port_id = ipcp_flow(i)->port_id; - -                        while (shm_ap_rbuff_write(ipcp_flow(i)->rb, &e) < 0) -                                ; +                        pthread_rwlock_unlock(ð_llc_data.flows_lock); -                        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); +                        flow_write(fd, &llc_frame->payload, length);                  }  #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING)                  offset = (offset + 1) & (SHM_BUFFER_SIZE -1); @@ -774,51 +569,34 @@ static void * eth_llc_ipcp_sdu_reader(void * o)  static void * eth_llc_ipcp_sdu_writer(void * o)  {          while (true) { -                struct rb_entry * e; -                int i; -                int len = 0; -                uint8_t * buf; +                int fd; +                struct shm_du_buff * sdb;                  uint8_t ssap;                  uint8_t dsap; +                uint8_t r_addr[MAC_SIZE]; -                e = shm_ap_rbuff_read(shim_data(_ipcp)->rb); -                if (e == NULL) -                        continue; - -                pthread_rwlock_rdlock(&_ipcp->state_lock); - -                len = shm_rdrbuff_read((uint8_t **) &buf, -                                      shim_data(_ipcp)->rdrb, -                                      e->index); -                if (len <= 0) { -                        free(e); -                        LOG_ERR("Length of du map read was %d.", len); -                        continue; -                } +                pthread_rwlock_rdlock(&ipcpi.state_lock); -                pthread_rwlock_rdlock(&shim_data(_ipcp)->flows_lock); - -                i = port_id_to_index(e->port_id); -                if (i < 0) { -                        free(e); -                        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); +                fd = ipcp_flow_read(&sdb); +                if (fd < 0) { +                        pthread_rwlock_unlock(&ipcpi.state_lock);                          continue;                  } -                ssap = reverse_bits(shim_data(_ipcp)->flows[i].sap); -                dsap = reverse_bits(shim_data(_ipcp)->flows[i].r_sap); - -                eth_llc_ipcp_send_frame(shim_data(_ipcp)->flows[i].r_addr, -                                        dsap, ssap, buf, len); - -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); +                pthread_rwlock_rdlock(ð_llc_data.flows_lock); -                if (shim_data(_ipcp)->rdrb != NULL) -                        shm_rdrbuff_remove(shim_data(_ipcp)->rdrb, e->index); +                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(&_ipcp->state_lock); +                pthread_rwlock_unlock(ð_llc_data.flows_lock); +                pthread_rwlock_unlock(&ipcpi.state_lock); -                free(e); +                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);          }          return (void *) 1; @@ -826,10 +604,6 @@ static void * eth_llc_ipcp_sdu_writer(void * o)  void ipcp_sig_handler(int sig, siginfo_t * info, void * c)  { -        sigset_t  sigset; -        sigemptyset(&sigset); -        sigaddset(&sigset, SIGINT); -          switch(sig) {          case SIGINT:          case SIGTERM: @@ -838,12 +612,11 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)                          LOG_DBG("IPCP %d terminating by order of %d. Bye.",                                  getpid(), info->si_pid); -                        pthread_rwlock_wrlock(&_ipcp->state_lock); - -                        ipcp_set_state(_ipcp, IPCP_SHUTDOWN); +                        pthread_rwlock_wrlock(&ipcpi.state_lock); -                        pthread_rwlock_unlock(&_ipcp->state_lock); +                        ipcp_set_state(IPCP_SHUTDOWN); +                        pthread_rwlock_unlock(&ipcpi.state_lock);                  }          default:                  return; @@ -852,7 +625,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)  static int eth_llc_ipcp_bootstrap(struct dif_config * conf)  { -        int fd = -1; +        int skfd = -1;          struct ifreq ifr;          int idx;  #ifdef __FreeBSD__ @@ -882,17 +655,10 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)          memset(&ifr, 0, sizeof(ifr)); -        fd = socket(AF_UNIX, SOCK_STREAM, 0); -        if (fd < 0) { -                LOG_ERR("Failed to open socket."); -                return -1; -        } -          memcpy(ifr.ifr_name, conf->if_name, strlen(conf->if_name));  #ifdef __FreeBSD__          if (getifaddrs(&ifaddr) < 0)  { -                close(fd);                  LOG_ERR("Could not get interfaces.");                  return -1;          } @@ -900,8 +666,7 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)          for (ifa = ifaddr, idx = 0; ifa != NULL; ifa = ifa->ifa_next, ++idx) {                  if (strcmp(ifa->ifa_name, conf->if_name))                          continue; -                LOG_DBGF("Interface %s found.", conf->if_name); - +                LOG_DBG("Interface %s found.", conf->if_name);                  memcpy(&ifr.ifr_addr, ifa->ifa_addr, sizeof(*ifa->ifa_addr));                  break;          } @@ -913,30 +678,33 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)          }          freeifaddrs(ifaddr); -  #else -        if (ioctl(fd, SIOCGIFHWADDR, &ifr)) { -                close(fd); -                LOG_ERR("Failed to ioctl: %s.", strerror(errno)); +        skfd = socket(AF_UNIX, SOCK_STREAM, 0); +        if (skfd < 0) { +                LOG_ERR("Failed to open socket."); +                return -1; +        } + +        if (ioctl(skfd, SIOCGIFHWADDR, &ifr)) { +                LOG_ERR("Failed to ioctl."); +                close(skfd);                  return -1;          } +        close(skfd); +          idx = if_nametoindex(conf->if_name);          if (idx == 0) {                  LOG_ERR("Failed to retrieve interface index."); +                close(skfd);                  return -1;          }  #endif - -        close(fd); -          memset(&(device), 0, sizeof(device));  #ifdef __FreeBSD__          device.sdl_index = idx;          device.sdl_family = AF_LINK; -        memcpy(LLADDR(&device), -               ifr.ifr_addr.sa_data, -               MAC_SIZE * sizeof (uint8_t)); +        memcpy(LLADDR(&device), ifr.ifr_addr.sa_data, MAC_SIZE);          device.sdl_alen = MAC_SIZE;          /* TODO: replace socket calls with bpf for BSD */          LOG_MISSING; @@ -944,23 +712,21 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)  #else          device.sll_ifindex = idx;          device.sll_family = AF_PACKET; -        memcpy(device.sll_addr, -               ifr.ifr_hwaddr.sa_data, -               MAC_SIZE * sizeof (uint8_t)); +        memcpy(device.sll_addr, ifr.ifr_hwaddr.sa_data, MAC_SIZE);          device.sll_halen = MAC_SIZE;          device.sll_protocol = htons(ETH_P_ALL); -        fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_802_2)); +        skfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_802_2));  #endif -        if (fd < 0) { -                LOG_ERR("Failed to create socket: %s.", strerror(errno)); +        if (skfd < 0) { +                LOG_ERR("Failed to create socket.");                  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(fd); +                close(skfd);                  return -1;          } @@ -969,68 +735,68 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)          req.tp_block_nr = SHM_BUFFER_SIZE;          req.tp_frame_nr = SHM_BUFFER_SIZE; -        if (setsockopt(fd, SOL_PACKET, PACKET_RX_RING, +        if (setsockopt(skfd, SOL_PACKET, PACKET_RX_RING,                         (void *) &req, sizeof(req))) {                  LOG_ERR("Failed to set sockopt PACKET_RX_RING"); -                close(fd); +                close(skfd);                  return -1;          } -        if (setsockopt(fd, SOL_PACKET, PACKET_TX_RING, +        if (setsockopt(skfd, SOL_PACKET, PACKET_TX_RING,                         (void *) &req, sizeof(req))) {                  LOG_ERR("Failed to set sockopt PACKET_TX_RING"); -                close(fd); +                close(skfd);                  return -1;          }  #endif - -        if (bind(fd,(struct sockaddr *) &device, sizeof(device))) { +        if (bind(skfd, (struct sockaddr *) &device, sizeof(device))) {                  LOG_ERR("Failed to bind socket to interface"); -                close(fd); +                close(skfd);                  return -1;          }  #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) -        shim_data(_ipcp)->rx_ring = mmap(NULL, -                                         2 * SHM_RDRB_BLOCK_SIZE -                                         * SHM_BUFFER_SIZE, -                                         PROT_READ | PROT_WRITE, MAP_SHARED, -                                         fd, 0); -        if (shim_data(_ipcp)->rx_ring == NULL) { +        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"); -                close(fd); +                close(skfd);                  return -1;          } -        shim_data(_ipcp)->tx_ring = shim_data(_ipcp)->rx_ring -                + (SHM_RDRB_BLOCK_SIZE * SHM_BUFFER_SIZE); +        eth_llc_data.tx_ring = eth_llc_data.rx_ring +                + SHM_RDRB_BLOCK_SIZE * SHM_BUFFER_SIZE;  #endif -        pthread_rwlock_wrlock(&_ipcp->state_lock); +        pthread_rwlock_wrlock(&ipcpi.state_lock); -        if (ipcp_get_state(_ipcp) != IPCP_INIT) { -                pthread_rwlock_unlock(&_ipcp->state_lock); +        if (ipcp_get_state() != IPCP_INIT) { +                pthread_rwlock_unlock(&ipcpi.state_lock);                  LOG_ERR("IPCP in wrong state."); -                close(fd); +                close(skfd);                  return -1;          } -        shim_data(_ipcp)->s_fd = fd; -        shim_data(_ipcp)->device = device; -        shim_data(_ipcp)->tx_offset = 0; +        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, IPCP_ENROLLED); +        ipcp_set_state(IPCP_ENROLLED); -        pthread_create(&shim_data(_ipcp)->sdu_reader, +        pthread_create(ð_llc_data.sdu_reader,                         NULL,                         eth_llc_ipcp_sdu_reader,                         NULL); -        pthread_create(&shim_data(_ipcp)->sdu_writer, +        pthread_create(ð_llc_data.sdu_writer,                         NULL,                         eth_llc_ipcp_sdu_writer,                         NULL); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock);          LOG_DBG("Bootstrapped shim IPCP over Ethernet with LLC with api %d.",                  getpid()); @@ -1040,15 +806,15 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf)  static int eth_llc_ipcp_name_reg(char * name)  { -        pthread_rwlock_rdlock(&_ipcp->state_lock); +        pthread_rwlock_rdlock(&ipcpi.state_lock); -        if (ipcp_data_add_reg_entry(_ipcp->data, name)) { -                pthread_rwlock_unlock(&_ipcp->state_lock); +        if (ipcp_data_add_reg_entry(ipcpi.data, name)) { +                pthread_rwlock_unlock(&ipcpi.state_lock);                  LOG_ERR("Failed to add %s to local registry.", name);                  return -1;          } -        pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock);          LOG_DBG("Registered %s.", name); @@ -1057,25 +823,22 @@ static int eth_llc_ipcp_name_reg(char * name)  static int eth_llc_ipcp_name_unreg(char * name)  { -        pthread_rwlock_rdlock(&_ipcp->state_lock); +        pthread_rwlock_rdlock(&ipcpi.state_lock); -        ipcp_data_del_reg_entry(_ipcp->data, name); +        ipcp_data_del_reg_entry(ipcpi.data, name); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock);          return 0;  } -static int eth_llc_ipcp_flow_alloc(pid_t         n_api, -                                   int           port_id, +static int eth_llc_ipcp_flow_alloc(int           fd,                                     char *        dst_name,                                     char *        src_ae_name,                                     enum qos_cube qos)  { -        struct shm_ap_rbuff * rb;          uint8_t ssap = 0;          uint8_t r_addr[MAC_SIZE]; -        int index = 0;          LOG_INFO("Allocating flow to %s.", dst_name); @@ -1083,182 +846,122 @@ static int eth_llc_ipcp_flow_alloc(pid_t         n_api,                  return -1;          if (qos != QOS_CUBE_BE) -                LOG_DBGF("QoS requested. Ethernet LLC can't do that. For now."); - -        rb = shm_ap_rbuff_open_s(n_api); -        if (rb == NULL) -                return -1; /* -ENORBUFF */ +                LOG_DBG("QoS requested. Ethernet LLC can't do that. For now."); -        pthread_rwlock_rdlock(&_ipcp->state_lock); +        pthread_rwlock_rdlock(&ipcpi.state_lock); -        if (ipcp_get_state(_ipcp) != IPCP_ENROLLED) { -                pthread_rwlock_unlock(&_ipcp->state_lock); -                shm_ap_rbuff_close(rb); -                LOG_DBGF("Won't allocate flow with non-enrolled IPCP."); +        if (ipcp_get_state() != IPCP_ENROLLED) { +                pthread_rwlock_unlock(&ipcpi.state_lock); +                LOG_DBG("Won't allocate flow with non-enrolled IPCP.");                  return -1; /* -ENOTENROLLED */          } -        index = bmp_allocate(shim_data(_ipcp)->indices); -        if (index < 0) { -                pthread_rwlock_unlock(&_ipcp->state_lock); -                shm_ap_rbuff_close(rb); -                return -1; -        } - -        pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); +        pthread_rwlock_wrlock(ð_llc_data.flows_lock); -        ssap = bmp_allocate(shim_data(_ipcp)->saps); +        ssap = bmp_allocate(eth_llc_data.saps);          if (ssap < 0) { -                shm_ap_rbuff_close(rb); -                bmp_release(shim_data(_ipcp)->indices, index); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); +                pthread_rwlock_unlock(ð_llc_data.flows_lock); +                pthread_rwlock_unlock(&ipcpi.state_lock);                  return -1;          } -        ipcp_flow(index)->port_id = port_id; -        ipcp_flow(index)->state = FLOW_PENDING; -        ipcp_flow(index)->rb = rb; -        shim_data(_ipcp)->flows[index].sap = ssap; - -        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -        pthread_rwlock_unlock(&_ipcp->state_lock); - -        memset(r_addr, 0xff, MAC_SIZE * sizeof(uint8_t)); - -        if (eth_llc_ipcp_port_alloc(r_addr, ssap, -                                    dst_name, -                                    src_ae_name) < 0) { -                LOG_DBGF("Port alloc returned -1."); -                pthread_rwlock_rdlock(&_ipcp->state_lock); -                pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); -                destroy_ipcp_flow(index); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); +        eth_llc_data.fd_to_ef[fd].sap = ssap; +        eth_llc_data.ef_to_fd[ssap]   = fd; + +        pthread_rwlock_unlock(ð_llc_data.flows_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock); + +        memset(r_addr, 0xff, MAC_SIZE); + +        if (eth_llc_ipcp_sap_alloc(r_addr, ssap, dst_name, src_ae_name) < 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;          } -        LOG_DBG("Pending flow with port_id %d on SAP %d.", -                port_id, ssap); +        LOG_DBG("Pending flow with fd %d on SAP %d.", fd, ssap); -        return index; +        return 0;  } -static int eth_llc_ipcp_flow_alloc_resp(pid_t n_api, -                                        int   port_id, -                                        int   response) +static int eth_llc_ipcp_flow_alloc_resp(int fd, int response)  { -        struct shm_ap_rbuff * rb; -        int index = -1;          uint8_t ssap = 0; +        uint8_t r_sap = 0; +        uint8_t r_addr[MAC_SIZE]; -        pthread_rwlock_rdlock(&_ipcp->state_lock); -        pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); - -        index = port_id_to_index(port_id); -        if (index < 0) { -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); -                LOG_DBGF("Could not find flow with port_id %d.", port_id); -                return -1; -        } - -        if (ipcp_flow(index)->state != FLOW_PENDING) { -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); -                LOG_DBGF("Flow was not pending."); -                return -1; -        } - -        rb = shm_ap_rbuff_open_s(n_api); -        if (rb == NULL) { -                LOG_ERR("Could not open N + 1 ringbuffer."); -                ipcp_flow(index)->state = FLOW_NULL; -                ipcp_flow(index)->port_id = -1; -                bmp_release(shim_data(_ipcp)->indices, index); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); -                return -1; -        } +        pthread_rwlock_rdlock(&ipcpi.state_lock); +        pthread_rwlock_wrlock(ð_llc_data.flows_lock); -        ssap = bmp_allocate(shim_data(_ipcp)->saps); +        ssap = bmp_allocate(eth_llc_data.saps);          if (ssap < 0) { -                ipcp_flow(index)->state = FLOW_NULL; -                ipcp_flow(index)->port_id = -1; -                shm_ap_rbuff_close(ipcp_flow(index)->rb); -                bmp_release(shim_data(_ipcp)->indices, index); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); +                pthread_rwlock_unlock(ð_llc_data.flows_lock); +                pthread_rwlock_unlock(&ipcpi.state_lock);                  return -1;          } -        ipcp_flow(index)->state = FLOW_ALLOCATED; -        ipcp_flow(index)->rb = rb; -        shim_data(_ipcp)->flows[index].sap = ssap; - -        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        eth_llc_data.fd_to_ef[fd].sap = ssap; +        memcpy(r_addr, eth_llc_data.fd_to_ef[fd].r_addr, MAC_SIZE); +        r_sap = eth_llc_data.fd_to_ef[fd].r_sap; +        eth_llc_data.ef_to_fd[ssap] = fd; -        if (eth_llc_ipcp_port_alloc_resp(shim_data(_ipcp)->flows[index].r_addr, -                                         shim_data(_ipcp)->flows[index].r_sap, -                                         ssap, -                                         response) < 0) { -                pthread_rwlock_rdlock(&_ipcp->state_lock); -                pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); -                destroy_ipcp_flow(index); -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); +        pthread_rwlock_unlock(ð_llc_data.flows_lock); +        pthread_rwlock_unlock(&ipcpi.state_lock); -                LOG_DBGF("Could not send response."); +        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;          } -        LOG_DBG("Accepted flow, port_id %d, SAP %d.", port_id, ssap); +        LOG_DBG("Accepted flow, fd %d, SAP %d.", fd, ssap);          return 0;  } -static int eth_llc_ipcp_flow_dealloc(int port_id) +static int eth_llc_ipcp_flow_dealloc(int fd)  { -        int index = -1;          uint8_t sap;          uint8_t addr[MAC_SIZE]; -        int i;          int ret; -        pthread_rwlock_rdlock(&_ipcp->state_lock); -        pthread_rwlock_wrlock(&shim_data(_ipcp)->flows_lock); +        pthread_rwlock_rdlock(&ipcpi.state_lock); +        pthread_rwlock_wrlock(ð_llc_data.flows_lock); -        index = port_id_to_index(port_id); -        if (index < 0) { -                pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); -                pthread_rwlock_unlock(&_ipcp->state_lock); -                return 0; -        } +        sap = eth_llc_data.fd_to_ef[fd].r_sap; +        memcpy(addr, eth_llc_data.fd_to_ef[fd].r_addr, MAC_SIZE); -        sap = shim_data(_ipcp)->flows[index].r_sap; -        for (i = 0; i < MAC_SIZE; i++) { -                addr[i] = shim_data(_ipcp)->flows[index].r_addr[i]; -        } +        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.fd_to_ef[fd].r_sap = -1; +        memset(ð_llc_data.fd_to_ef[fd].r_addr, 0, MAC_SIZE); -        destroy_ipcp_flow(index); +        eth_llc_data.ef_to_fd[sap] = -1; -        pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); +        pthread_rwlock_unlock(ð_llc_data.flows_lock); -        ret = eth_llc_ipcp_port_dealloc(addr, sap); -        pthread_rwlock_unlock(&_ipcp->state_lock); +        ret = eth_llc_ipcp_sap_dealloc(addr, sap); +        pthread_rwlock_unlock(&ipcpi.state_lock);          if (ret < 0) -                LOG_DBGF("Could not notify remote."); +                LOG_DBG("Could not notify remote."); -        LOG_DBG("Flow with port_id %d deallocated.", port_id); +        LOG_DBG("Flow with fd %d deallocated.", fd);          return 0;  }  static struct ipcp_ops eth_llc_ops = {          .ipcp_bootstrap       = eth_llc_ipcp_bootstrap, -        .ipcp_enroll          = NULL,                       /* shim */ +        .ipcp_enroll          = NULL,          .ipcp_name_reg        = eth_llc_ipcp_name_reg,          .ipcp_name_unreg      = eth_llc_ipcp_name_unreg,          .ipcp_flow_alloc      = eth_llc_ipcp_flow_alloc, @@ -1270,7 +973,6 @@ int main(int argc, char * argv[])  {          struct sigaction sig_act;          sigset_t  sigset; -        int i = 0;          sigemptyset(&sigset);          sigaddset(&sigset, SIGINT); @@ -1283,6 +985,14 @@ int main(int argc, char * argv[])                  exit(EXIT_FAILURE);          } +        if (eth_llc_data_init() < 0) +                exit(EXIT_FAILURE); + +        if (ap_init(NULL) < 0) { +                close_logfile(); +                exit(EXIT_FAILURE); +        } +          /* store the process id of the irmd */          irmd_api = atoi(argv[1]); @@ -1298,35 +1008,13 @@ int main(int argc, char * argv[])          sigaction(SIGHUP,  &sig_act, NULL);          sigaction(SIGPIPE, &sig_act, NULL); -        _ipcp = ipcp_instance_create(); -        if (_ipcp == NULL) { -                LOG_ERR("Failed to create instance."); -                close_logfile(); -                exit(EXIT_FAILURE); -        } +        pthread_sigmask(SIG_BLOCK, &sigset, NULL); -        _ipcp->data = (struct ipcp_data *) eth_llc_ipcp_data_create(); -        if (_ipcp->data == NULL) { -                LOG_ERR("Failed to create instance data."); -                free(_ipcp); +        if (ipcp_init(THIS_TYPE, ð_llc_ops) < 0) {                  close_logfile();                  exit(EXIT_FAILURE);          } -        for (i = 0; i < AP_MAX_FLOWS; i++) { -                ipcp_flow(i)->rb = NULL; -                ipcp_flow(i)->port_id = -1; -                ipcp_flow(i)->state = FLOW_NULL; -        } - -        _ipcp->ops = ð_llc_ops; -        _ipcp->state = IPCP_INIT; - -        pthread_sigmask(SIG_BLOCK, &sigset, NULL); - -        pthread_create(&shim_data(_ipcp)->mainloop, NULL, -                       ipcp_main_loop, _ipcp); -          pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);          if (ipcp_create_r(getpid())) { @@ -1335,17 +1023,17 @@ int main(int argc, char * argv[])                  exit(EXIT_FAILURE);          } -        pthread_join(shim_data(_ipcp)->mainloop, NULL); +        ipcp_fini(); -        pthread_cancel(shim_data(_ipcp)->sdu_reader); -        pthread_cancel(shim_data(_ipcp)->sdu_writer); +        pthread_cancel(eth_llc_data.sdu_reader); +        pthread_cancel(eth_llc_data.sdu_writer); -        pthread_join(shim_data(_ipcp)->sdu_writer, NULL); -        pthread_join(shim_data(_ipcp)->sdu_reader, NULL); +        pthread_join(eth_llc_data.sdu_writer, NULL); +        pthread_join(eth_llc_data.sdu_reader, NULL); -        eth_llc_ipcp_data_destroy(); +        ap_fini(); -        free(_ipcp); +        eth_llc_data_fini();          close_logfile(); | 
