diff options
author | dimitri staessens <[email protected]> | 2016-09-18 06:27:43 +0200 |
---|---|---|
committer | dimitri staessens <[email protected]> | 2016-10-04 15:16:00 +0200 |
commit | c96efb13edfaf9b2f2c626bd2a5d5d5afd38155f (patch) | |
tree | acd08f09f5a094e897020e97961b2847209df043 /src/ipcpd/shim-eth-llc/main.c | |
parent | 2e561a634ae3e747b293a4e05eaf44726968dc1a (diff) | |
download | ouroboros-c96efb13edfaf9b2f2c626bd2a5d5d5afd38155f.tar.gz ouroboros-c96efb13edfaf9b2f2c626bd2a5d5d5afd38155f.zip |
lib, ipcp: Revise fast path and flow interfaces
IPCPs can now use ap_init() to initialize the memory. All flows are
accessed using flow descriptors, this greatly simplifies IPCP
development. Reverts the fast path to a single ap_rbuff per process.
Splits lib/ipcp into irmd/ipcp and lib/ipcp-dev. Adds a lib/shim-dev
holding tailored functions for shims. Moves the buffer_t to utils.h.
Fixes the shim-eth-llc length field. Removes the flow from shared.h.
Fixes #4
Fixes #5
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(); |