From 9177b0f3f72203cb6e18ee59c98b531a698d7f19 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Thu, 27 Apr 2017 19:13:29 +0200 Subject: ipcpd: normal: Split connection establishment Connection establishment was done at the same time as flow allocation. This splits it more cleanly, and allows to re-use the DT AE for other purposes. --- src/ipcpd/normal/CMakeLists.txt | 3 +- src/ipcpd/normal/dt.c | 112 ++++++-------- src/ipcpd/normal/dt.h | 10 +- src/ipcpd/normal/dt_const.h | 1 - src/ipcpd/normal/dt_pci.c | 149 +++++++++++++++++++ src/ipcpd/normal/dt_pci.h | 53 +++++++ src/ipcpd/normal/fa.c | 271 +++++++++++++++++++-------------- src/ipcpd/normal/fa.h | 7 +- src/ipcpd/normal/flow_alloc.proto | 5 +- src/ipcpd/normal/frct.c | 305 +++++++++++++------------------------- src/ipcpd/normal/frct.h | 22 +-- src/ipcpd/normal/frct_pci.c | 102 +++++++++++++ src/ipcpd/normal/frct_pci.h | 47 ++++++ src/ipcpd/normal/main.c | 4 - src/ipcpd/normal/shm_pci.c | 242 ------------------------------ src/ipcpd/normal/shm_pci.h | 64 -------- 16 files changed, 682 insertions(+), 715 deletions(-) create mode 100644 src/ipcpd/normal/dt_pci.c create mode 100644 src/ipcpd/normal/dt_pci.h create mode 100644 src/ipcpd/normal/frct_pci.c create mode 100644 src/ipcpd/normal/frct_pci.h delete mode 100644 src/ipcpd/normal/shm_pci.c delete mode 100644 src/ipcpd/normal/shm_pci.h (limited to 'src') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 9a220ba6..3f0f2612 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -23,9 +23,11 @@ set(SOURCE_FILES connmgr.c dir.c dt.c + dt_pci.c enroll.c fa.c frct.c + frct_pci.c gam.c graph.c main.c @@ -34,7 +36,6 @@ set(SOURCE_FILES ribmgr.c routing.c sdu_sched.c - shm_pci.c # Add policies last pol/complete.c pol/flat.c diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c index 8b10c84c..361af6b4 100644 --- a/src/ipcpd/normal/dt.c +++ b/src/ipcpd/normal/dt.c @@ -30,7 +30,7 @@ #include "dt.h" #include "connmgr.h" #include "ipcp.h" -#include "shm_pci.h" +#include "dt_pci.h" #include "pff.h" #include "neighbors.h" #include "gam.h" @@ -39,6 +39,7 @@ #include "frct.h" #include "ae.h" #include "ribconfig.h" +#include "fa.h" #include #include @@ -84,14 +85,14 @@ static int sdu_handler(int fd, qoscube_t qc, struct shm_du_buff * sdb) { - struct pci pci; + struct dt_pci dt_pci; - memset(&pci, 0, sizeof(pci)); + memset(&dt_pci, 0, sizeof(dt_pci)); - shm_pci_des(sdb, &pci); + dt_pci_des(sdb, &dt_pci); - if (pci.dst_addr != ipcpi.dt_addr) { - if (pci.ttl == 0) { + if (dt_pci.dst_addr != ipcpi.dt_addr) { + if (dt_pci.ttl == 0) { log_dbg("TTL was zero."); ipcp_sdb_release(sdb); return 0; @@ -99,10 +100,10 @@ static int sdu_handler(int fd, pff_lock(dt.pff[qc]); - fd = pff_nhop(dt.pff[qc], pci.dst_addr); + fd = pff_nhop(dt.pff[qc], dt_pci.dst_addr); if (fd < 0) { pff_unlock(dt.pff[qc]); - log_err("No next hop for %" PRIu64, pci.dst_addr); + log_err("No next hop for %" PRIu64, dt_pci.dst_addr); ipcp_sdb_release(sdb); return -1; } @@ -115,12 +116,27 @@ static int sdu_handler(int fd, return -1; } } else { - shm_pci_shrink(sdb); - - if (frct_post_sdu(&pci, sdb)) { - log_err("Failed to hand PDU to FRCT."); + dt_pci_shrink(sdb); + + switch (dt_pci.pdu_type) { + case PDU_TYPE_FRCT: + if (frct_post_sdu(sdb)) { + ipcp_sdb_release(sdb); + return -1; + } + break; + case PDU_TYPE_FA: + if (fa_post_sdu(sdb)) { + ipcp_sdb_release(sdb); + return -1; + } + break; + default: + log_err("Unknown PDU type received."); + ipcp_sdb_release(sdb); return -1; } + } return 0; @@ -132,8 +148,8 @@ int dt_init(void) int j; struct conn_info info; - if (shm_pci_init()) { - log_err("Failed to init shm pci."); + if (dt_pci_init()) { + log_err("Failed to init shm dt_pci."); return -1; } @@ -253,78 +269,40 @@ void dt_stop(void) sdu_sched_destroy(dt.sdu_sched); } -int dt_write_sdu(struct pci * pci, +int dt_write_sdu(uint64_t dst_addr, + qoscube_t qc, + uint8_t pdu_type, struct shm_du_buff * sdb) { - int fd; + int fd; + struct dt_pci dt_pci; - assert(pci); assert(sdb); - pff_lock(dt.pff[pci->qos_id]); + pff_lock(dt.pff[qc]); - fd = pff_nhop(dt.pff[pci->qos_id], pci->dst_addr); + fd = pff_nhop(dt.pff[qc], dst_addr); if (fd < 0) { - pff_unlock(dt.pff[pci->qos_id]); - log_err("Could not get nhop for address %" PRIu64, - pci->dst_addr); - ipcp_sdb_release(sdb); + pff_unlock(dt.pff[qc]); + log_err("Could not get nhop for address %" PRIu64, dst_addr); return -1; } - pff_unlock(dt.pff[pci->qos_id]); + pff_unlock(dt.pff[qc]); + + dt_pci.dst_addr = dst_addr; + dt_pci.qc = qc; + dt_pci.pdu_type = pdu_type; - if (shm_pci_ser(sdb, pci)) { + if (dt_pci_ser(sdb, &dt_pci)) { log_err("Failed to serialize PDU."); - ipcp_sdb_release(sdb); return -1; } if (ipcp_flow_write(fd, sdb)) { log_err("Failed to write SDU to fd %d.", fd); - ipcp_sdb_release(sdb); - return -1; - } - - return 0; -} - -int dt_write_buf(struct pci * pci, - buffer_t * buf) -{ - buffer_t * buffer; - int fd; - - assert(pci); - assert(buf); - assert(buf->data); - - pff_lock(dt.pff[pci->qos_id]); - - fd = pff_nhop(dt.pff[pci->qos_id], pci->dst_addr); - if (fd < 0) { - pff_unlock(dt.pff[pci->qos_id]); - log_err("Could not get nhop for address %" PRIu64, - pci->dst_addr); - return -1; - } - - pff_unlock(dt.pff[pci->qos_id]); - - buffer = shm_pci_ser_buf(buf, pci); - if (buffer == NULL) { - log_err("Failed to serialize buffer."); - return -1; - } - - if (flow_write(fd, buffer->data, buffer->len) == -1) { - log_err("Failed to write buffer to fd."); - free(buffer); return -1; } - free(buffer->data); - free(buffer); - return 0; } diff --git a/src/ipcpd/normal/dt.h b/src/ipcpd/normal/dt.h index dea9b91f..ec59d592 100644 --- a/src/ipcpd/normal/dt.h +++ b/src/ipcpd/normal/dt.h @@ -24,9 +24,8 @@ #define OUROBOROS_IPCPD_NORMAL_DT_H #include -#include -#include "shm_pci.h" +#include "dt_pci.h" int dt_init(void); @@ -36,10 +35,9 @@ int dt_start(void); void dt_stop(void); -int dt_write_sdu(struct pci * pci, +int dt_write_sdu(uint64_t dst_addr, + qoscube_t qc, + uint8_t pdu_type, struct shm_du_buff * sdb); -int dt_write_buf(struct pci * pci, - buffer_t * buf); - #endif /* OUROBOROS_IPCPD_NORMAL_DT_H */ diff --git a/src/ipcpd/normal/dt_const.h b/src/ipcpd/normal/dt_const.h index 327f51b8..b93d497c 100644 --- a/src/ipcpd/normal/dt_const.h +++ b/src/ipcpd/normal/dt_const.h @@ -29,7 +29,6 @@ struct dt_const { uint8_t addr_size; uint8_t cep_id_size; - uint8_t pdu_length_size; uint8_t seqno_size; bool has_ttl; bool has_chk; diff --git a/src/ipcpd/normal/dt_pci.c b/src/ipcpd/normal/dt_pci.c new file mode 100644 index 00000000..0e596803 --- /dev/null +++ b/src/ipcpd/normal/dt_pci.c @@ -0,0 +1,149 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Protocol Control Information of Data Transfer AE + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "dt_const.h" +#include "dt_pci.h" +#include "ribconfig.h" + +#include +#include +#include + +#define PDU_TYPE_SIZE 1 +#define QC_SIZE 1 +#define DEFAULT_TTL 60 +#define TTL_SIZE 1 +#define CHK_SIZE 4 + +struct { + struct dt_const dtc; + size_t head_size; + size_t tail_size; + + /* offsets */ + size_t qc_o; + size_t ttl_o; + size_t pdu_type_o; +} dt_pci_info; + +int dt_pci_init(void) +{ + /* read dt constants from the RIB */ + if (rib_read(BOOT_PATH "/dt/const/addr_size", + &dt_pci_info.dtc.addr_size, + sizeof(dt_pci_info.dtc.addr_size)) < 0 || + rib_read(BOOT_PATH "/dt/const/has_ttl", + &dt_pci_info.dtc.has_ttl, + sizeof(dt_pci_info.dtc.has_ttl)) < 0 || + rib_read(BOOT_PATH "/dt/const/has_chk", + &dt_pci_info.dtc.has_chk, + sizeof(dt_pci_info.dtc.has_chk)) < 0) + return -1; + + dt_pci_info.qc_o = dt_pci_info.dtc.addr_size; + dt_pci_info.ttl_o = dt_pci_info.qc_o + QC_SIZE; + + dt_pci_info.head_size = dt_pci_info.ttl_o + PDU_TYPE_SIZE; + + if (dt_pci_info.dtc.has_ttl) + dt_pci_info.head_size += TTL_SIZE; + + dt_pci_info.tail_size = dt_pci_info.dtc.has_chk ? CHK_SIZE : 0; + + return 0; +} + +void dt_pci_fini(void) { + return; +} + +int dt_pci_ser(struct shm_du_buff * sdb, + struct dt_pci * dt_pci) +{ + uint8_t * head; + uint8_t * tail; + uint8_t ttl = DEFAULT_TTL; + + assert(sdb); + assert(dt_pci); + + head = shm_du_buff_head_alloc(sdb, dt_pci_info.head_size); + if (head == NULL) + return -EPERM; + + /* FIXME: Add check and operations for Big Endian machines */ + memcpy(head, &dt_pci->dst_addr, dt_pci_info.dtc.addr_size); + memcpy(head + dt_pci_info.qc_o, &dt_pci->qc, QC_SIZE); + if (dt_pci_info.dtc.has_ttl) + memcpy(head + dt_pci_info.ttl_o, &ttl, TTL_SIZE); + memcpy(head + dt_pci_info.pdu_type_o, &dt_pci->pdu_type, PDU_TYPE_SIZE); + + if (dt_pci_info.dtc.has_chk) { + tail = shm_du_buff_tail_alloc(sdb, dt_pci_info.tail_size); + if (tail == NULL) { + shm_du_buff_head_release(sdb, dt_pci_info.head_size); + return -EPERM; + } + + *((uint32_t *) tail) = 0; + crc32((uint32_t *) tail, head, tail - head); + } + + return 0; +} + +void dt_pci_des(struct shm_du_buff * sdb, + struct dt_pci * dt_pci) +{ + uint8_t * head; + + assert(sdb); + assert(dt_pci); + + head = shm_du_buff_head(sdb); + + /* FIXME: Add check and operations for Big Endian machines */ + memcpy(&dt_pci->dst_addr, head, dt_pci_info.dtc.addr_size); + memcpy(&dt_pci->qc, head + dt_pci_info.qc_o, QC_SIZE); + + if (dt_pci_info.dtc.has_ttl) { + --*(head + dt_pci_info.ttl_o); /* decrease TTL */ + memcpy(&dt_pci->ttl, head + dt_pci_info.ttl_o, TTL_SIZE); + } else { + dt_pci->ttl = 1; + } + + memcpy(&dt_pci->pdu_type, head + dt_pci_info.pdu_type_o, PDU_TYPE_SIZE); +} + +void dt_pci_shrink(struct shm_du_buff * sdb) +{ + assert(sdb); + + shm_du_buff_head_release(sdb, dt_pci_info.head_size); + shm_du_buff_tail_release(sdb, dt_pci_info.tail_size); +} diff --git a/src/ipcpd/normal/dt_pci.h b/src/ipcpd/normal/dt_pci.h new file mode 100644 index 00000000..bec21188 --- /dev/null +++ b/src/ipcpd/normal/dt_pci.h @@ -0,0 +1,53 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Protocol Control Information of Data Transfer AE + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_DT_PCI_H +#define OUROBOROS_IPCPD_NORMAL_DT_PCI_H + +#include +#include + +#define PDU_TYPE_FA 0x40 +#define PDU_TYPE_FRCT 0x80 + +#define INVALID_ADDR 0 + +struct dt_pci { + uint64_t dst_addr; + qoscube_t qc; + uint8_t ttl; + uint8_t pdu_type; +}; + +int dt_pci_init(void); + +void dt_pci_fini(void); + +int dt_pci_ser(struct shm_du_buff * sdb, + struct dt_pci * dt_pci); + +void dt_pci_des(struct shm_du_buff * sdb, + struct dt_pci * dt_pci); + +void dt_pci_shrink(struct shm_du_buff * sdb); + +#endif /* OUROBOROS_IPCPD_NORMAL_DT_PCI_H */ diff --git a/src/ipcpd/normal/fa.c b/src/ipcpd/normal/fa.c index 131100db..b116c842 100644 --- a/src/ipcpd/normal/fa.c +++ b/src/ipcpd/normal/fa.c @@ -28,11 +28,14 @@ #include #include #include +#include +#include "dt_pci.h" #include "fa.h" #include "sdu_sched.h" #include "ipcp.h" #include "ribconfig.h" +#include "dt.h" #include #include @@ -108,20 +111,45 @@ void fa_stop(void) sdu_sched_destroy(fa.sdu_sched); } +static struct shm_du_buff * create_fa_sdb(flow_alloc_msg_t * msg) +{ + struct shm_du_buff * sdb; + size_t len; + + len = flow_alloc_msg__get_packed_size(msg); + if (len == 0) + return NULL; + + if (ipcp_sdb_reserve(&sdb, len)) + return NULL; + + flow_alloc_msg__pack(msg, shm_du_buff_head(sdb)); + + return sdb; +} + +static void destroy_conn(int fd, + cep_id_t cep_id) +{ + fa.fd_to_cep_id[fd] = INVALID_CEP_ID; + fa.cep_id_to_fd[cep_id] = -1; + frct_i_destroy(cep_id); +} + int fa_alloc(int fd, const uint8_t * dst, qoscube_t qc) { - cep_id_t cep_id; - buffer_t buf; - flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; - char path[RIB_MAX_PATH_LEN + 1]; - uint64_t addr; - ssize_t ch; - ssize_t i; - char ** children; - char hashstr[ipcp_dir_hash_strlen() + 1]; - char * dst_ipcp = NULL; + cep_id_t cep_id; + flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; + char path[RIB_MAX_PATH_LEN + 1]; + uint64_t addr; + ssize_t ch; + ssize_t i; + char ** children; + char hashstr[ipcp_dir_hash_strlen() + 1]; + char * dst_ipcp = NULL; + struct shm_du_buff * sdb; ipcp_hash_str(hashstr, dst); @@ -156,34 +184,36 @@ int fa_alloc(int fd, if (rib_read(path, &addr, sizeof(addr)) < 0) return -1; - msg.code = FLOW_ALLOC_CODE__FLOW_REQ; - msg.has_hash = true; - msg.hash.len = ipcp_dir_hash_len(); - msg.hash.data = (uint8_t *) dst; - msg.has_qoscube = true; - msg.qoscube = qc; - - buf.len = flow_alloc_msg__get_packed_size(&msg); - if (buf.len == 0) + cep_id = frct_i_create(addr, qc); + if (cep_id == INVALID_CEP_ID) return -1; - buf.data = malloc(buf.len); - if (buf.data == NULL) + msg.code = FLOW_ALLOC_CODE__FLOW_REQ; + msg.has_hash = true; + msg.hash.len = ipcp_dir_hash_len(); + msg.hash.data = (uint8_t *) dst; + msg.has_qc = true; + msg.qc = qc; + msg.has_s_cep_id = true; + msg.s_cep_id = cep_id; + msg.has_s_addr = true; + msg.s_addr = ipcpi.dt_addr; + + sdb = create_fa_sdb(&msg); + if (sdb == NULL) { + frct_i_destroy(cep_id); return -1; - - flow_alloc_msg__pack(&msg, buf.data); + } pthread_rwlock_wrlock(&fa.flows_lock); - cep_id = frct_i_create(addr, &buf, qc); - if (cep_id == INVALID_CEP_ID) { + if (dt_write_sdu(addr, qc, PDU_TYPE_FA, sdb)) { + frct_i_destroy(cep_id); pthread_rwlock_unlock(&fa.flows_lock); - free(buf.data); + ipcp_sdb_release(sdb); return -1; } - free(buf.data); - fa.fd_to_cep_id[fd] = cep_id; fa.cep_id_to_fd[cep_id] = fd; @@ -192,47 +222,13 @@ int fa_alloc(int fd, return 0; } -/* Call under flows lock */ -static int fa_flow_dealloc(int fd) -{ - flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; - buffer_t buf; - int ret; - - sdu_sched_del(fa.sdu_sched, fd); - - msg.code = FLOW_ALLOC_CODE__FLOW_DEALLOC; - - buf.len = flow_alloc_msg__get_packed_size(&msg); - if (buf.len == 0) - return -1; - - buf.data = malloc(buf.len); - if (buf.data == NULL) - return -ENOMEM; - - flow_alloc_msg__pack(&msg, buf.data); - - ret = frct_i_destroy(fa.fd_to_cep_id[fd], &buf); - - fa.cep_id_to_fd[fa.fd_to_cep_id[fd]] = -1; - fa.fd_to_cep_id[fd] = INVALID_CEP_ID; - - free(buf.data); - - return ret; -} - int fa_alloc_resp(int fd, int response) { - struct timespec ts = {0, TIMEOUT * 1000}; - flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; - buffer_t buf; - - msg.code = FLOW_ALLOC_CODE__FLOW_REPLY; - msg.response = response; - msg.has_response = true; + struct timespec ts = {0, TIMEOUT * 1000}; + flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; + struct shm_du_buff * sdb; + qoscube_t qc; pthread_mutex_lock(&ipcpi.alloc_lock); @@ -251,66 +247,102 @@ int fa_alloc_resp(int fd, pthread_mutex_unlock(&ipcpi.alloc_lock); - buf.len = flow_alloc_msg__get_packed_size(&msg); - if (buf.len == 0) - return -1; - - buf.data = malloc(buf.len); - if (buf.data == NULL) - return -ENOMEM; + pthread_rwlock_wrlock(&fa.flows_lock); - flow_alloc_msg__pack(&msg, buf.data); + msg.code = FLOW_ALLOC_CODE__FLOW_REPLY; + msg.has_cep_id = true; + msg.cep_id = frct_i_get_id(fa.fd_to_cep_id[fd]); + msg.s_cep_id = fa.fd_to_cep_id[fd]; + msg.has_s_cep_id = true; + msg.response = response; + msg.has_response = true; - pthread_rwlock_wrlock(&fa.flows_lock); + sdb = create_fa_sdb(&msg); + if (sdb == NULL) { + destroy_conn(fd, fa.fd_to_cep_id[fd]); + pthread_rwlock_unlock(&fa.flows_lock); + return -1; + } if (response < 0) { - frct_i_destroy(fa.fd_to_cep_id[fd], &buf); - free(buf.data); - fa.cep_id_to_fd[fa.fd_to_cep_id[fd]] - = INVALID_CEP_ID; - fa.fd_to_cep_id[fd] = -1; + destroy_conn(fd, fa.fd_to_cep_id[fd]); + ipcp_sdb_release(sdb); } else { - qoscube_t qc; - ipcp_flow_get_qoscube(fd, &qc); - if (frct_i_accept(fa.fd_to_cep_id[fd], &buf, qc)) { - pthread_rwlock_unlock(&fa.flows_lock); - free(buf.data); - return -1; - } sdu_sched_add(fa.sdu_sched, fd); } - pthread_rwlock_unlock(&fa.flows_lock); + ipcp_flow_get_qoscube(fd, &qc); - free(buf.data); + assert(qc >= 0 && qc < QOS_CUBE_MAX); + + if (dt_write_sdu(frct_i_get_addr(fa.fd_to_cep_id[fd]), + qc, + PDU_TYPE_FA, + sdb)) { + destroy_conn(fd, fa.fd_to_cep_id[fd]); + ipcp_sdb_release(sdb); + return -1; + } + + pthread_rwlock_unlock(&fa.flows_lock); return 0; } int fa_dealloc(int fd) { - int ret; + flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; + struct shm_du_buff * sdb; + qoscube_t qc; pthread_rwlock_wrlock(&fa.flows_lock); - ret = fa_flow_dealloc(fd); + sdu_sched_del(fa.sdu_sched, fd); + + destroy_conn(fd, fa.fd_to_cep_id[fd]); + + msg.code = FLOW_ALLOC_CODE__FLOW_DEALLOC; + msg.has_cep_id = true; + msg.cep_id = frct_i_get_id(fa.fd_to_cep_id[fd]); + + sdb = create_fa_sdb(&msg); + if (sdb == NULL) { + pthread_rwlock_unlock(&fa.flows_lock); + return -1; + } pthread_rwlock_unlock(&fa.flows_lock); - return ret; + ipcp_flow_get_qoscube(fd, &qc); + + assert(qc >= 0 && qc < QOS_CUBE_MAX); + + if (dt_write_sdu(frct_i_get_addr(fa.fd_to_cep_id[fd]), + qc, + PDU_TYPE_FA, + sdb)) { + ipcp_sdb_release(sdb); + return -1; + } + + return 0; } -int fa_post_buf(cep_id_t cep_id, - buffer_t * buf) +int fa_post_sdu(struct shm_du_buff * sdb) { struct timespec ts = {0, TIMEOUT * 1000}; - int ret = 0; int fd; flow_alloc_msg_t * msg; + cep_id_t cep_id; + + assert(sdb); /* Depending on the message call the function in ipcp-dev.h */ - msg = flow_alloc_msg__unpack(NULL, buf->len, buf->data); + msg = flow_alloc_msg__unpack(NULL, + shm_du_buff_tail(sdb) - + shm_du_buff_head(sdb), + shm_du_buff_head(sdb)); if (msg == NULL) { log_err("Failed to unpack flow alloc message"); return -1; @@ -323,6 +355,7 @@ int fa_post_buf(cep_id_t cep_id, if (!msg->has_hash) { log_err("Bad flow request."); pthread_mutex_unlock(&ipcpi.alloc_lock); + flow_alloc_msg__free_unpacked(msg, NULL); return -1; } @@ -335,17 +368,33 @@ int fa_post_buf(cep_id_t cep_id, if (ipcp_get_state() != IPCP_OPERATIONAL) { log_dbg("Won't allocate over non-operational IPCP."); pthread_mutex_unlock(&ipcpi.alloc_lock); + flow_alloc_msg__free_unpacked(msg, NULL); return -1; } assert(ipcpi.alloc_id == -1); + cep_id = frct_i_create(msg->s_addr, msg->qc); + if (cep_id == INVALID_CEP_ID) { + pthread_mutex_unlock(&ipcpi.alloc_lock); + flow_alloc_msg__free_unpacked(msg, NULL); + return -1; + } + + if (frct_i_set_id(cep_id, msg->s_cep_id)) { + pthread_mutex_unlock(&ipcpi.alloc_lock); + frct_i_destroy(cep_id); + flow_alloc_msg__free_unpacked(msg, NULL); + return -1; + } + fd = ipcp_flow_req_arr(getpid(), msg->hash.data, ipcp_dir_hash_len(), - msg->qoscube); + msg->qc); if (fd < 0) { pthread_mutex_unlock(&ipcpi.alloc_lock); + frct_i_destroy(cep_id); flow_alloc_msg__free_unpacked(msg, NULL); log_err("Failed to get fd for flow."); return -1; @@ -367,39 +416,43 @@ int fa_post_buf(cep_id_t cep_id, case FLOW_ALLOC_CODE__FLOW_REPLY: pthread_rwlock_wrlock(&fa.flows_lock); - fd = fa.cep_id_to_fd[cep_id]; - ret = ipcp_flow_alloc_reply(fd, msg->response); + fd = fa.cep_id_to_fd[msg->cep_id]; + ipcp_flow_alloc_reply(fd, msg->response); if (msg->response < 0) { - fa.fd_to_cep_id[fd] = INVALID_CEP_ID; - fa.cep_id_to_fd[cep_id] = -1; + destroy_conn(fd, msg->cep_id); } else { - sdu_sched_add(fa.sdu_sched, fa.cep_id_to_fd[cep_id]); + frct_i_set_id(msg->cep_id, msg->s_cep_id); + sdu_sched_add(fa.sdu_sched, + fa.cep_id_to_fd[msg->cep_id]); } pthread_rwlock_unlock(&fa.flows_lock); break; case FLOW_ALLOC_CODE__FLOW_DEALLOC: - fd = fa.cep_id_to_fd[cep_id]; + fd = fa.cep_id_to_fd[msg->cep_id]; sdu_sched_del(fa.sdu_sched, fd); - ret = flow_dealloc(fd); + flow_dealloc(fd); break; default: log_err("Got an unknown flow allocation message."); - ret = -1; - break; + flow_alloc_msg__free_unpacked(msg, NULL); + return -1; } flow_alloc_msg__free_unpacked(msg, NULL); + ipcp_sdb_release(sdb); - return ret; + return 0; } -int fa_post_sdu(cep_id_t cep_id, - struct shm_du_buff * sdb) +int fa_post_sdu_user(cep_id_t cep_id, + struct shm_du_buff * sdb) { int fd; + assert(sdb); + pthread_rwlock_rdlock(&fa.flows_lock); fd = fa.cep_id_to_fd[cep_id]; diff --git a/src/ipcpd/normal/fa.h b/src/ipcpd/normal/fa.h index d370a381..6ca705e4 100644 --- a/src/ipcpd/normal/fa.h +++ b/src/ipcpd/normal/fa.h @@ -45,10 +45,9 @@ int fa_alloc_resp(int fd, int fa_dealloc(int fd); -int fa_post_buf(cep_id_t cep_id, - buffer_t * buf); +int fa_post_sdu(struct shm_du_buff * sdb); -int fa_post_sdu(cep_id_t cep_id, - struct shm_du_buff * sdb); +int fa_post_sdu_user(cep_id_t cep_id, + struct shm_du_buff * sdb); #endif /* OUROBOROS_IPCPD_NORMAL_FA_H */ diff --git a/src/ipcpd/normal/flow_alloc.proto b/src/ipcpd/normal/flow_alloc.proto index 35624799..ee7f96e8 100644 --- a/src/ipcpd/normal/flow_alloc.proto +++ b/src/ipcpd/normal/flow_alloc.proto @@ -31,6 +31,9 @@ enum flow_alloc_code { message flow_alloc_msg { required flow_alloc_code code = 1; optional bytes hash = 2; - optional uint32 qoscube = 3; + optional uint32 qc = 3; optional sint32 response = 4; + optional uint32 cep_id = 5; + optional uint32 s_cep_id = 6; + optional uint64 s_addr = 7; }; diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c index 71e32bd1..1adcb299 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -90,309 +90,200 @@ static int release_cep_id(cep_id_t id) return ret; } -static int init_cep_ids(void) +int frct_init() { + int i; + + if (frct_pci_init()) + return -1; + if (pthread_mutex_init(&frct.cep_ids_lock, NULL)) return -1; frct.cep_ids = bmp_create(IRMD_MAX_FLOWS, (INVALID_CEP_ID + 1)); - if (frct.cep_ids == NULL) { - pthread_mutex_destroy(&frct.cep_ids_lock); - return -1; - } + if (frct.cep_ids == NULL) + goto fail_cep_ids_lock; + + if (pthread_mutex_init(&frct.instances_lock, NULL)) + goto fail_bmp; + + frct.instances = malloc(sizeof(*(frct.instances)) * IRMD_MAX_FLOWS); + if (frct.instances == NULL) + goto fail_instance_lock; + + for (i = 0; i < IRMD_MAX_FLOWS; i++) + frct.instances[i] = NULL; return 0; + + fail_instance_lock: + pthread_mutex_destroy(&frct.instances_lock); + fail_bmp: + bmp_destroy(frct.cep_ids); + fail_cep_ids_lock: + pthread_mutex_destroy(&frct.cep_ids_lock); + + return -1; } -static int init_instances(void) +int frct_fini() { - int i; + pthread_mutex_destroy(&frct.instances_lock); - if (pthread_mutex_init(&frct.instances_lock, NULL)) - return -1; + free(frct.instances); - frct.instances = malloc(sizeof(*(frct.instances)) * IRMD_MAX_FLOWS); - if (frct.instances == NULL) { - pthread_mutex_destroy(&frct.instances_lock); - return -1; - } + bmp_destroy(frct.cep_ids); - for (i = 0; i < IRMD_MAX_FLOWS; i++) - frct.instances[i] = NULL; + pthread_mutex_destroy(&frct.cep_ids_lock); return 0; } -static struct frct_i * create_frct_i(uint64_t address, - cep_id_t r_cep_id) +cep_id_t frct_i_create(uint64_t address, + qoscube_t cube) { struct frct_i * instance; cep_id_t id; + pthread_mutex_lock(&frct.instances_lock); + instance = malloc(sizeof(*instance)); if (instance == NULL) - return NULL; + return INVALID_CEP_ID; id = next_cep_id(); if (id == INVALID_CEP_ID) { free(instance); - return NULL; + return INVALID_CEP_ID; } instance->r_address = address; instance->cep_id = id; - instance->r_cep_id = r_cep_id; instance->state = CONN_PENDING; instance->seqno = 0; + instance->cube = cube; frct.instances[id] = instance; - return instance; -} - -static void destroy_frct_i(cep_id_t id) -{ - struct frct_i * instance; - - instance = frct.instances[id]; - frct.instances[id] = NULL; - - release_cep_id(instance->cep_id); - - free(instance); -} - -static void fini_cep_ids(void) -{ - pthread_mutex_lock(&frct.cep_ids_lock); - - bmp_destroy(frct.cep_ids); - - pthread_mutex_unlock(&frct.cep_ids_lock); + pthread_mutex_unlock(&frct.instances_lock); - pthread_mutex_destroy(&frct.cep_ids_lock); + return id; } -static void fini_instances(void) +int frct_i_destroy(cep_id_t cep_id) { - int i; + struct frct_i * instance; pthread_mutex_lock(&frct.instances_lock); - for (i = 0; i < IRMD_MAX_FLOWS; i++) - if (frct.instances[i] != NULL) - destroy_frct_i(i); - - pthread_mutex_unlock(&frct.instances_lock); - - pthread_mutex_destroy(&frct.instances_lock); - - free(frct.instances); -} - -int frct_init() -{ - if (init_cep_ids()) - return -1; - - if (init_instances()) { - fini_cep_ids(); + instance = frct.instances[cep_id]; + if (instance == NULL) { + pthread_mutex_unlock(&frct.instances_lock); + log_err("Invalid instance."); return -1; } - return 0; -} + frct.instances[cep_id] = NULL; -int frct_fini() -{ - fini_instances(); - fini_cep_ids(); + release_cep_id(instance->cep_id); + free(instance); + + pthread_mutex_unlock(&frct.instances_lock); return 0; } -int frct_post_sdu(struct pci * pci, - struct shm_du_buff * sdb) +int frct_i_set_id(cep_id_t cep_id, + cep_id_t r_cep_id) { struct frct_i * instance; - buffer_t buf; - cep_id_t id; - - assert(pci); - assert(sdb); - if (pci->pdu_type == PDU_TYPE_MGMT) { - pthread_mutex_lock(&frct.instances_lock); - - if (pci->dst_cep_id == INVALID_CEP_ID) { - instance = create_frct_i(pci->src_addr, - pci->src_cep_id); - if (instance == NULL) { - pthread_mutex_unlock(&frct.instances_lock); - ipcp_sdb_release(sdb); - return -ENOMEM; - } - id = instance->cep_id; - } else { - instance = frct.instances[pci->dst_cep_id]; - if (instance == NULL) { - pthread_mutex_unlock(&frct.instances_lock); - ipcp_sdb_release(sdb); - return -1; - } - id = pci->dst_cep_id; - instance->state = CONN_ESTABLISHED; - } - - instance->r_cep_id = pci->src_cep_id; + pthread_mutex_lock(&frct.instances_lock); + instance = frct.instances[cep_id]; + if (instance == NULL) { pthread_mutex_unlock(&frct.instances_lock); - - buf.len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb); - buf.data = shm_du_buff_head(sdb); - - if (fa_post_buf(id, &buf)) { - log_err("Failed to hand buffer to FA."); - ipcp_sdb_release(sdb); - return -1; - } - - ipcp_sdb_release(sdb); - } else { - /* FIXME: Known cep-ids are delivered to FA (minimal DTP) */ - if (fa_post_sdu(pci->dst_cep_id, sdb)) { - log_err("Failed to hand SDU to FA."); - ipcp_sdb_release(sdb); - return -1; - } + log_err("Invalid instance."); + return -1; } + instance->r_cep_id = r_cep_id; + instance->state = CONN_ESTABLISHED; + + pthread_mutex_unlock(&frct.instances_lock); + return 0; } -cep_id_t frct_i_create(uint64_t address, - buffer_t * buf, - qoscube_t cube) +cep_id_t frct_i_get_id(cep_id_t cep_id) { struct frct_i * instance; - struct pci pci; - cep_id_t id; - - assert(buf); - assert(buf->data); + cep_id_t r_cep_id; pthread_mutex_lock(&frct.instances_lock); - instance = create_frct_i(address, INVALID_CEP_ID); + instance = frct.instances[cep_id]; if (instance == NULL) { pthread_mutex_unlock(&frct.instances_lock); return INVALID_CEP_ID; } - id = instance->cep_id; - instance->cube = cube; + r_cep_id = instance->r_cep_id; pthread_mutex_unlock(&frct.instances_lock); - pci.pdu_type = PDU_TYPE_MGMT; - pci.dst_addr = address; - pci.src_addr = ipcpi.dt_addr; - pci.dst_cep_id = 0; - pci.src_cep_id = id; - pci.seqno = 0; - pci.qos_id = cube; - - if (dt_write_buf(&pci, buf)) { - pthread_mutex_lock(&frct.instances_lock); - destroy_frct_i(id); - pthread_mutex_unlock(&frct.instances_lock); - log_err("Failed to hand PDU to DT."); - return INVALID_CEP_ID; - } - - return id; + return r_cep_id; } -int frct_i_accept(cep_id_t id, - buffer_t * buf, - qoscube_t cube) +uint64_t frct_i_get_addr(cep_id_t cep_id) { - struct pci pci; struct frct_i * instance; - - assert(buf); - assert(buf->data); + uint64_t r_addr; pthread_mutex_lock(&frct.instances_lock); - instance = frct.instances[id]; + instance = frct.instances[cep_id]; if (instance == NULL) { pthread_mutex_unlock(&frct.instances_lock); - log_err("Invalid instance."); - return -1; - } - - if (instance->state != CONN_PENDING) { - pthread_mutex_unlock(&frct.instances_lock); - return -1; + return INVALID_ADDR; } - instance->state = CONN_ESTABLISHED; - instance->cube = cube; - instance->seqno = 0; - - pci.pdu_type = PDU_TYPE_MGMT; - pci.dst_addr = instance->r_address; - pci.src_addr = ipcpi.dt_addr; - pci.dst_cep_id = instance->r_cep_id; - pci.src_cep_id = instance->cep_id; - pci.seqno = 0; - pci.qos_id = cube; + r_addr = instance->r_address; pthread_mutex_unlock(&frct.instances_lock); - if (dt_write_buf(&pci, buf)) - return -1; - - return 0; + return r_addr; } -int frct_i_destroy(cep_id_t id, - buffer_t * buf) +int frct_post_sdu(struct shm_du_buff * sdb) { - struct pci pci; + struct frct_pci frct_pci; struct frct_i * instance; + assert(sdb); + + frct_pci_des(sdb, &frct_pci); + + /* Known cep-ids are delivered to FA (minimal DTP) */ pthread_mutex_lock(&frct.instances_lock); - instance = frct.instances[id]; + instance = frct.instances[frct_pci.dst_cep_id]; if (instance == NULL) { pthread_mutex_unlock(&frct.instances_lock); log_err("Invalid instance."); return -1; } - if (!(instance->state == CONN_PENDING || - instance->state == CONN_ESTABLISHED)) { + if (instance->state != CONN_ESTABLISHED) { pthread_mutex_unlock(&frct.instances_lock); + log_err("Connection is not established."); return -1; } - pci.pdu_type = PDU_TYPE_MGMT; - pci.dst_addr = instance->r_address; - pci.src_addr = ipcpi.dt_addr; - pci.dst_cep_id = instance->r_cep_id; - pci.src_cep_id = instance->cep_id; - pci.seqno = 0; - pci.qos_id = instance->cube; - - destroy_frct_i(id); - pthread_mutex_unlock(&frct.instances_lock); - if (buf != NULL && buf->data != NULL) - if (dt_write_buf(&pci, buf)) - return -1; + if (fa_post_sdu_user(frct_pci.dst_cep_id, sdb)) + return -1; return 0; } @@ -400,8 +291,8 @@ int frct_i_destroy(cep_id_t id, int frct_i_write_sdu(cep_id_t id, struct shm_du_buff * sdb) { - struct pci pci; struct frct_i * instance; + struct frct_pci frct_pci; assert(sdb); @@ -420,15 +311,19 @@ int frct_i_write_sdu(cep_id_t id, return -1; } - pci.pdu_type = PDU_TYPE_DTP; - pci.dst_addr = instance->r_address; - pci.src_addr = ipcpi.dt_addr; - pci.dst_cep_id = instance->r_cep_id; - pci.src_cep_id = instance->cep_id; - pci.seqno = (instance->seqno)++; - pci.qos_id = instance->cube; + frct_pci.dst_cep_id = instance->r_cep_id; + frct_pci.seqno = (instance->seqno)++; + + if (frct_pci_ser(sdb, &frct_pci)) { + pthread_mutex_unlock(&frct.instances_lock); + log_err("Failed to serialize."); + return -1; + } - if (dt_write_sdu(&pci, sdb)) { + if (dt_write_sdu(instance->r_address, + instance->cube, + PDU_TYPE_FRCT, + sdb)) { pthread_mutex_unlock(&frct.instances_lock); log_err("Failed to hand SDU to DT."); return -1; diff --git a/src/ipcpd/normal/frct.h b/src/ipcpd/normal/frct.h index b179e36b..03dec672 100644 --- a/src/ipcpd/normal/frct.h +++ b/src/ipcpd/normal/frct.h @@ -26,7 +26,7 @@ #include #include -#include "shm_pci.h" +#include "frct_pci.h" #define FRCT_PROTO "FRCT" @@ -36,21 +36,21 @@ int frct_init(void); int frct_fini(void); -cep_id_t frct_i_create(uint64_t address, - buffer_t * buf, - qoscube_t cube); +cep_id_t frct_i_create(uint64_t address, + qoscube_t cube); -int frct_i_accept(cep_id_t id, - buffer_t * buf, - qoscube_t cube); +int frct_i_destroy(cep_id_t cep_id); -int frct_i_destroy(cep_id_t id, - buffer_t * buf); +int frct_i_set_id(cep_id_t cep_id, + cep_id_t r_cep_id); + +cep_id_t frct_i_get_id(cep_id_t cep_id); + +uint64_t frct_i_get_addr(cep_id_t cep_id); int frct_i_write_sdu(cep_id_t id, struct shm_du_buff * sdb); -int frct_post_sdu(struct pci * pci, - struct shm_du_buff * sdb); +int frct_post_sdu(struct shm_du_buff * sdb); #endif /* OUROBOROS_IPCPD_NORMAL_FRCT_H */ diff --git a/src/ipcpd/normal/frct_pci.c b/src/ipcpd/normal/frct_pci.c new file mode 100644 index 00000000..a13df2f4 --- /dev/null +++ b/src/ipcpd/normal/frct_pci.c @@ -0,0 +1,102 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Protocol Control Information for FRCT + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "dt_const.h" +#include "frct_pci.h" +#include "ribconfig.h" + +#include +#include +#include + +struct { + struct dt_const dtc; + size_t head_size; + + /* offsets */ + size_t seqno_o; +} frct_pci_info; + +int frct_pci_init(void) +{ + /* read dt constants from the RIB */ + if (rib_read(BOOT_PATH "/dt/const/cep_id_size", + &frct_pci_info.dtc.cep_id_size, + sizeof(frct_pci_info.dtc.cep_id_size)) < 0 || + rib_read(BOOT_PATH "/dt/const/seqno_size", + &frct_pci_info.dtc.seqno_size, + sizeof(frct_pci_info.dtc.seqno_size)) < 0) + return -1; + + frct_pci_info.seqno_o = frct_pci_info.dtc.cep_id_size; + + frct_pci_info.head_size = frct_pci_info.seqno_o + + frct_pci_info.dtc.seqno_size; + + return 0; +} + +void frct_pci_fini(void) { + return; +} + +int frct_pci_ser(struct shm_du_buff * sdb, + struct frct_pci * frct_pci) +{ + uint8_t * head; + + assert(sdb); + assert(frct_pci); + + head = shm_du_buff_head_alloc(sdb, frct_pci_info.head_size); + if (head == NULL) + return -EPERM; + + /* FIXME: Add check and operations for Big Endian machines */ + memcpy(head, &frct_pci->dst_cep_id, frct_pci_info.dtc.cep_id_size); + memcpy(head + frct_pci_info.seqno_o, &frct_pci->seqno, + frct_pci_info.dtc.seqno_size); + + return 0; +} + +void frct_pci_des(struct shm_du_buff * sdb, + struct frct_pci * frct_pci) +{ + uint8_t * head; + + assert(sdb); + assert(frct_pci); + + head = shm_du_buff_head(sdb); + + /* FIXME: Add check and operations for Big Endian machines */ + memcpy(&frct_pci->dst_cep_id, head, frct_pci_info.dtc.cep_id_size); + memcpy(&frct_pci->seqno, head + frct_pci_info.seqno_o, + frct_pci_info.dtc.seqno_size); + + shm_du_buff_head_release(sdb, frct_pci_info.head_size); +} diff --git a/src/ipcpd/normal/frct_pci.h b/src/ipcpd/normal/frct_pci.h new file mode 100644 index 00000000..006fe8e7 --- /dev/null +++ b/src/ipcpd/normal/frct_pci.h @@ -0,0 +1,47 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Protocol Control Information for FRCT + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_FRCT_PCI_H +#define OUROBOROS_IPCPD_NORMAL_FRCT_PCI_H + +#include + +typedef uint32_t cep_id_t; + +#define INVALID_CEP_ID 0 + +struct frct_pci { + cep_id_t dst_cep_id; + uint64_t seqno; +}; + +int frct_pci_init(void); + +void frct_pci_fini(void); + +int frct_pci_ser(struct shm_du_buff * sdb, + struct frct_pci * frct_pci); + +void frct_pci_des(struct shm_du_buff * sdb, + struct frct_pci * frct_pci); + +#endif /* OUROBOROS_IPCPD_NORMAL_FRCT_PCI_H */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index ab8cf387..74406d54 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -264,7 +264,6 @@ const struct ros { {BOOT_PATH "/dt", "const"}, {BOOT_PATH "/dt/const", "addr_size"}, {BOOT_PATH "/dt/const", "cep_id_size"}, - {BOOT_PATH "/dt/const", "pdu_length_size"}, {BOOT_PATH "/dt/const", "seqno_size"}, {BOOT_PATH "/dt/const", "has_ttl"}, {BOOT_PATH "/dt/const", "has_chk"}, @@ -330,9 +329,6 @@ static int normal_ipcp_bootstrap(const struct ipcp_config * conf) rib_write(BOOT_PATH "/dt/const/seqno_size", &conf->seqno_size, sizeof(conf->seqno_size)) || - rib_write(BOOT_PATH "/dt/const/pdu_length_size", - &conf->pdu_length_size, - sizeof(conf->pdu_length_size)) || rib_write(BOOT_PATH "/dt/const/has_ttl", &conf->has_ttl, sizeof(conf->has_ttl)) || diff --git a/src/ipcpd/normal/shm_pci.c b/src/ipcpd/normal/shm_pci.c deleted file mode 100644 index e6cd1042..00000000 --- a/src/ipcpd/normal/shm_pci.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Protocol Control Information in Shared Memory Map - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -#include "dt_const.h" -#include "shm_pci.h" -#include "ribconfig.h" - -#include -#include -#include - -#define PDU_TYPE_SIZE 1 -#define QOS_ID_SIZE 1 -#define DEFAULT_TTL 60 -#define TTL_SIZE 1 -#define CHK_SIZE 4 - -struct { - struct dt_const dtc; - size_t head_size; - size_t tail_size; - - /* offsets */ - size_t dst_addr_o; - size_t src_addr_o; - size_t dst_cep_id_o; - size_t src_cep_id_o; - size_t pdu_length_o; - size_t seqno_o; - size_t qos_id_o; - size_t ttl_o; -} pci_info; - - -static void ser_pci_head(uint8_t * head, - struct pci * pci) -{ - uint8_t ttl = DEFAULT_TTL; - - assert(head); - assert(pci); - - /* FIXME: Add check and operations for Big Endian machines */ - memcpy(head, &pci->pdu_type, PDU_TYPE_SIZE); - memcpy(head + pci_info.dst_addr_o, &pci->dst_addr, - pci_info.dtc.addr_size); - memcpy(head + pci_info.src_addr_o, &pci->src_addr, - pci_info.dtc.addr_size); - memcpy(head + pci_info.dst_cep_id_o, &pci->dst_cep_id, - pci_info.dtc.cep_id_size); - memcpy(head + pci_info.src_cep_id_o, &pci->src_cep_id, - pci_info.dtc.cep_id_size); - memcpy(head + pci_info.pdu_length_o, &pci->pdu_length, - pci_info.dtc.pdu_length_size); - memcpy(head + pci_info.seqno_o, &pci->seqno, - pci_info.dtc.seqno_size); - memcpy(head + pci_info.qos_id_o, &pci->qos_id, QOS_ID_SIZE); - if (pci_info.dtc.has_ttl) - memcpy(head + pci_info.ttl_o, &ttl, TTL_SIZE); -} - -int shm_pci_init(void) -{ - /* read dt constants from the RIB */ - if (rib_read(BOOT_PATH "/dt/const/addr_size", - &pci_info.dtc.addr_size, - sizeof(pci_info.dtc.addr_size)) < 0 || - rib_read(BOOT_PATH "/dt/const/cep_id_size", - &pci_info.dtc.cep_id_size, - sizeof(pci_info.dtc.cep_id_size)) < 0 || - rib_read(BOOT_PATH "/dt/const/seqno_size", - &pci_info.dtc.seqno_size, - sizeof(pci_info.dtc.seqno_size)) < 0 || - rib_read(BOOT_PATH "/dt/const/pdu_length_size", - &pci_info.dtc.pdu_length_size, - sizeof(pci_info.dtc.pdu_length_size)) < 0 || - rib_read(BOOT_PATH "/dt/const/has_ttl", - &pci_info.dtc.has_ttl, - sizeof(pci_info.dtc.has_ttl)) < 0 || - rib_read(BOOT_PATH "/dt/const/has_chk", - &pci_info.dtc.has_chk, - sizeof(pci_info.dtc.has_chk)) < 0 || - rib_read(BOOT_PATH "/dt/const/min_pdu_size", - &pci_info.dtc.min_pdu_size, - sizeof(pci_info.dtc.min_pdu_size)) < 0 || - rib_read(BOOT_PATH "/dt/const/max_pdu_size", - &pci_info.dtc.max_pdu_size, - sizeof(pci_info.dtc.max_pdu_size)) < 0) - return -1; - - pci_info.dst_addr_o = PDU_TYPE_SIZE; - pci_info.src_addr_o = pci_info.dst_addr_o + pci_info.dtc.addr_size; - pci_info.dst_cep_id_o = pci_info.src_addr_o + pci_info.dtc.addr_size; - pci_info.src_cep_id_o = pci_info.dst_cep_id_o - + pci_info.dtc.cep_id_size; - pci_info.pdu_length_o = pci_info.src_cep_id_o - + pci_info.dtc.cep_id_size; - pci_info.seqno_o = pci_info.pdu_length_o + pci_info.dtc.pdu_length_size; - pci_info.qos_id_o = pci_info.seqno_o + pci_info.dtc.seqno_size; - pci_info.ttl_o = pci_info.qos_id_o + QOS_ID_SIZE; - - pci_info.head_size = pci_info.ttl_o; - - if (pci_info.dtc.has_ttl) - pci_info.head_size += TTL_SIZE; - - pci_info.tail_size = pci_info.dtc.has_chk ? CHK_SIZE : 0; - - return 0; -} - -void shm_pci_fini(void) { - return; -} - -int shm_pci_ser(struct shm_du_buff * sdb, - struct pci * pci) -{ - uint8_t * head; - uint8_t * tail; - - assert(sdb); - assert(pci); - - head = shm_du_buff_head_alloc(sdb, pci_info.head_size); - if (head == NULL) - return -EPERM; - - ser_pci_head(head, pci); - - if (pci_info.dtc.has_chk) { - tail = shm_du_buff_tail_alloc(sdb, pci_info.tail_size); - if (tail == NULL) { - shm_du_buff_head_release(sdb, pci_info.head_size); - return -EPERM; - } - - crc32((uint32_t *) tail, head, tail - head); - } - - return 0; -} - -buffer_t * shm_pci_ser_buf(buffer_t * buf, - struct pci * pci) -{ - buffer_t * buffer; - - assert(buf); - assert(pci); - - buffer = malloc(sizeof(*buffer)); - if (buffer == NULL) - return NULL; - - buffer->len = buf->len + pci_info.head_size + - pci_info.tail_size; - - buffer->data = malloc(buffer->len); - if (buffer->data == NULL) { - free(buffer); - return NULL; - } - - ser_pci_head(buffer->data, pci); - memcpy(buffer->data + pci_info.head_size, - buf->data, buf->len); - - if (pci_info.dtc.has_chk) - crc32((uint32_t *) (buffer->data + - pci_info.head_size + buf->len), - buffer->data, - pci_info.head_size + buf->len); - - return buffer; -} - -void shm_pci_des(struct shm_du_buff * sdb, - struct pci * pci) -{ - uint8_t * head; - - assert(sdb); - assert(pci); - - head = shm_du_buff_head(sdb); - - /* FIXME: Add check and operations for Big Endian machines */ - memcpy(&pci->pdu_type, head, PDU_TYPE_SIZE); - memcpy(&pci->dst_addr, head + pci_info.dst_addr_o, - pci_info.dtc.addr_size); - memcpy(&pci->src_addr, head + pci_info.src_addr_o, - pci_info.dtc.addr_size); - memcpy(&pci->dst_cep_id, head + pci_info.dst_cep_id_o, - pci_info.dtc.cep_id_size); - memcpy(&pci->src_cep_id, head + pci_info.src_cep_id_o, - pci_info.dtc.cep_id_size); - memcpy(&pci->pdu_length, head + pci_info.pdu_length_o, - pci_info.dtc.pdu_length_size); - memcpy(&pci->seqno, head + pci_info.seqno_o, - pci_info.dtc.seqno_size); - memcpy(&pci->qos_id, head + pci_info.qos_id_o, QOS_ID_SIZE); - - if (pci_info.dtc.has_ttl) { - --*(head + pci_info.ttl_o); /* decrease TTL */ - memcpy(&pci->ttl, head + pci_info.ttl_o, TTL_SIZE); - } else { - pci->ttl = 1; - } -} - -void shm_pci_shrink(struct shm_du_buff * sdb) -{ - assert(sdb); - - shm_du_buff_head_release(sdb, pci_info.head_size); - shm_du_buff_tail_release(sdb, pci_info.tail_size); -} diff --git a/src/ipcpd/normal/shm_pci.h b/src/ipcpd/normal/shm_pci.h deleted file mode 100644 index ff0b17ea..00000000 --- a/src/ipcpd/normal/shm_pci.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Protocol Control Information in Shared Memory Map - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef OUROBOROS_IPCPD_NORMAL_SHM_PCI_H -#define OUROBOROS_IPCPD_NORMAL_SHM_PCI_H - -#include -#include -#include - -#define PDU_TYPE_MGMT 0x40 -#define PDU_TYPE_DTP 0x80 - -typedef uint32_t cep_id_t; -#define INVALID_CEP_ID 0 -#define INVALID_ADDR 0 - -struct pci { - uint8_t pdu_type; - uint64_t dst_addr; - uint64_t src_addr; - cep_id_t dst_cep_id; - cep_id_t src_cep_id; - uint8_t qos_id; - uint32_t pdu_length; - uint64_t seqno; - uint8_t ttl; -}; - -int shm_pci_init(void); - -void shm_pci_fini(void); - -int shm_pci_ser(struct shm_du_buff * sdb, - struct pci * pci); - -buffer_t * shm_pci_ser_buf(buffer_t * buf, - struct pci * pci); - -void shm_pci_des(struct shm_du_buff * sdb, - struct pci * pci); - -void shm_pci_shrink(struct shm_du_buff * sdb); - -#endif /* OUROBOROS_IPCPD_NORMAL_SHM_PCI_H */ -- cgit v1.2.3