summaryrefslogtreecommitdiff
path: root/src/ipcpd/shim-eth-llc
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-09-18 06:27:43 +0200
committerdimitri staessens <[email protected]>2016-10-04 15:16:00 +0200
commitc96efb13edfaf9b2f2c626bd2a5d5d5afd38155f (patch)
treeacd08f09f5a094e897020e97961b2847209df043 /src/ipcpd/shim-eth-llc
parent2e561a634ae3e747b293a4e05eaf44726968dc1a (diff)
downloadouroboros-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')
-rw-r--r--src/ipcpd/shim-eth-llc/main.c978
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(&eth_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(&eth_llc_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);
}
- return -1;
-}
+ pthread_rwlock_init(&eth_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(&eth_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(&eth_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 *) &eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_llc_data.flows_lock);
+
+ fd = eth_llc_data.ef_to_fd[dsap];
+ if (fd < 0) {
+ pthread_rwlock_unlock(&eth_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(&eth_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(&eth_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(&eth_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(&eth_llc_data.sdu_reader,
NULL,
eth_llc_ipcp_sdu_reader,
NULL);
- pthread_create(&shim_data(_ipcp)->sdu_writer,
+ pthread_create(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_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(&eth_llc_data.flows_lock);
+ bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);
+ pthread_rwlock_unlock(&eth_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(&eth_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(&eth_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(&eth_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, &eth_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 = &eth_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();