summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2017-04-27 19:13:29 +0200
committerSander Vrijders <[email protected]>2017-04-28 13:08:17 +0200
commit9177b0f3f72203cb6e18ee59c98b531a698d7f19 (patch)
tree524e72cf30f94613df32f06d5ec7bb9041fd11dc /src/ipcpd
parent1f8f2ebe3bb385593755b69bd264ff5f831a22ae (diff)
downloadouroboros-9177b0f3f72203cb6e18ee59c98b531a698d7f19.tar.gz
ouroboros-9177b0f3f72203cb6e18ee59c98b531a698d7f19.zip
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.
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/normal/CMakeLists.txt3
-rw-r--r--src/ipcpd/normal/dt.c112
-rw-r--r--src/ipcpd/normal/dt.h10
-rw-r--r--src/ipcpd/normal/dt_const.h1
-rw-r--r--src/ipcpd/normal/dt_pci.c149
-rw-r--r--src/ipcpd/normal/dt_pci.h53
-rw-r--r--src/ipcpd/normal/fa.c271
-rw-r--r--src/ipcpd/normal/fa.h7
-rw-r--r--src/ipcpd/normal/flow_alloc.proto5
-rw-r--r--src/ipcpd/normal/frct.c305
-rw-r--r--src/ipcpd/normal/frct.h22
-rw-r--r--src/ipcpd/normal/frct_pci.c102
-rw-r--r--src/ipcpd/normal/frct_pci.h (renamed from src/ipcpd/normal/shm_pci.h)41
-rw-r--r--src/ipcpd/normal/main.c4
-rw-r--r--src/ipcpd/normal/shm_pci.c242
15 files changed, 647 insertions, 680 deletions
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 <stdlib.h>
#include <stdbool.h>
@@ -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 <ouroboros/shm_rdrbuff.h>
-#include <ouroboros/utils.h>
-#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 <[email protected]>
+ * Sander Vrijders <[email protected]>
+ *
+ * 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 <ouroboros/config.h>
+#include <ouroboros/errno.h>
+#include <ouroboros/crc32.h>
+#include <ouroboros/rib.h>
+
+#include "dt_const.h"
+#include "dt_pci.h"
+#include "ribconfig.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#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 <[email protected]>
+ * Sander Vrijders <[email protected]>
+ *
+ * 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 <ouroboros/shm_du_buff.h>
+#include <ouroboros/shared.h>
+
+#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 <ouroboros/rib.h>
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
+#include <ouroboros/ipcp-dev.h>
+#include "dt_pci.h"
#include "fa.h"
#include "sdu_sched.h"
#include "ipcp.h"
#include "ribconfig.h"
+#include "dt.h"
#include <pthread.h>
#include <stdlib.h>
@@ -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 <ouroboros/shared.h>
#include <ouroboros/utils.h>
-#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 <[email protected]>
+ * Sander Vrijders <[email protected]>
+ *
+ * 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 <ouroboros/config.h>
+#include <ouroboros/errno.h>
+#include <ouroboros/rib.h>
+
+#include "dt_const.h"
+#include "frct_pci.h"
+#include "ribconfig.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+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/shm_pci.h b/src/ipcpd/normal/frct_pci.h
index ff0b17ea..006fe8e7 100644
--- a/src/ipcpd/normal/shm_pci.h
+++ b/src/ipcpd/normal/frct_pci.h
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * Protocol Control Information in Shared Memory Map
+ * Protocol Control Information for FRCT
*
* Dimitri Staessens <[email protected]>
* Sander Vrijders <[email protected]>
@@ -20,45 +20,28 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef OUROBOROS_IPCPD_NORMAL_SHM_PCI_H
-#define OUROBOROS_IPCPD_NORMAL_SHM_PCI_H
+#ifndef OUROBOROS_IPCPD_NORMAL_FRCT_PCI_H
+#define OUROBOROS_IPCPD_NORMAL_FRCT_PCI_H
#include <ouroboros/shm_du_buff.h>
-#include <ouroboros/utils.h>
-#include <ouroboros/qos.h>
-
-#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;
+struct frct_pci {
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);
+int frct_pci_init(void);
-buffer_t * shm_pci_ser_buf(buffer_t * buf,
- struct pci * pci);
+void frct_pci_fini(void);
-void shm_pci_des(struct shm_du_buff * sdb,
- struct pci * pci);
+int frct_pci_ser(struct shm_du_buff * sdb,
+ struct frct_pci * frct_pci);
-void shm_pci_shrink(struct shm_du_buff * sdb);
+void frct_pci_des(struct shm_du_buff * sdb,
+ struct frct_pci * frct_pci);
-#endif /* OUROBOROS_IPCPD_NORMAL_SHM_PCI_H */
+#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 <[email protected]>
- * Sander Vrijders <[email protected]>
- *
- * 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 <ouroboros/config.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/crc32.h>
-#include <ouroboros/rib.h>
-
-#include "dt_const.h"
-#include "shm_pci.h"
-#include "ribconfig.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#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);
-}