summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2017-02-07 10:35:49 +0000
committerSander Vrijders <sander.vrijders@intec.ugent.be>2017-02-07 10:35:49 +0000
commit1bf2dd6aef3af6c81794c0551278373e44310b5c (patch)
tree2c5bb331021e0b15eb43827d05cd06082b6c8edb /src/ipcpd/normal
parent129d5e06d627346cb30ce60cdf43f8a1ae023dcb (diff)
parentd64f05e8bf1277132b648bda2e1175ad8c1d2d5c (diff)
downloadouroboros-1bf2dd6aef3af6c81794c0551278373e44310b5c.tar.gz
ouroboros-1bf2dd6aef3af6c81794c0551278373e44310b5c.zip
Merged in dstaesse/ouroboros/be-wip (pull request #362)
ipcpd, lib: Revise normal IPCP
Diffstat (limited to 'src/ipcpd/normal')
-rw-r--r--src/ipcpd/normal/CMakeLists.txt9
-rw-r--r--src/ipcpd/normal/addr_auth.c12
-rw-r--r--src/ipcpd/normal/ae.h5
-rw-r--r--src/ipcpd/normal/dir.c158
-rw-r--r--src/ipcpd/normal/dir.h2
-rw-r--r--src/ipcpd/normal/enroll.c263
-rw-r--r--src/ipcpd/normal/enroll.h (renamed from src/ipcpd/normal/ro.proto)20
-rw-r--r--src/ipcpd/normal/fmgr.c138
-rw-r--r--src/ipcpd/normal/fmgr.h38
-rw-r--r--src/ipcpd/normal/frct.c16
-rw-r--r--src/ipcpd/normal/gam.c32
-rw-r--r--src/ipcpd/normal/main.c352
-rw-r--r--src/ipcpd/normal/pathname.c76
-rw-r--r--src/ipcpd/normal/pathname.h34
-rw-r--r--src/ipcpd/normal/pol-gam-ops.h4
-rw-r--r--src/ipcpd/normal/pol/complete.c103
-rw-r--r--src/ipcpd/normal/pol/complete.h6
-rw-r--r--src/ipcpd/normal/pol/flat.c292
-rw-r--r--src/ipcpd/normal/ribmgr.c1663
-rw-r--r--src/ipcpd/normal/ribmgr.h34
-rw-r--r--src/ipcpd/normal/ro.h82
-rw-r--r--src/ipcpd/normal/shm_pci.c297
-rw-r--r--src/ipcpd/normal/shm_pci.h15
-rw-r--r--src/ipcpd/normal/static_info.proto36
24 files changed, 1060 insertions, 2627 deletions
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt
index bae2f69a..f2e48cbc 100644
--- a/src/ipcpd/normal/CMakeLists.txt
+++ b/src/ipcpd/normal/CMakeLists.txt
@@ -14,23 +14,18 @@ include_directories(${CMAKE_BINARY_DIR}/include)
set(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET")
-protobuf_generate_c(STATIC_INFO_SRCS STATIC_INFO_HDRS
- static_info.proto)
-
protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS
flow_alloc.proto)
-protobuf_generate_c(RO_SRCS RO_HDRS ro.proto)
-
set(SOURCE_FILES
# Add source files here
addr_auth.c
dir.c
+ enroll.c
fmgr.c
frct.c
gam.c
main.c
- pathname.c
pff.c
ribmgr.c
shm_pci.c
@@ -40,7 +35,7 @@ set(SOURCE_FILES
)
add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES}
- ${STATIC_INFO_SRCS} ${FLOW_ALLOC_SRCS} ${RO_SRCS})
+ ${FLOW_ALLOC_SRCS})
target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros)
include(MacroAddCompileFlags)
diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c
index a4084ac5..c41ffcd2 100644
--- a/src/ipcpd/normal/addr_auth.c
+++ b/src/ipcpd/normal/addr_auth.c
@@ -35,16 +35,13 @@ struct addr_auth * addr_auth_create(enum pol_addr_auth type)
struct addr_auth * tmp;
tmp = malloc(sizeof(*tmp));
- if (tmp == NULL)
+ if (tmp == NULL) {
+ LOG_ERR("Failed to malloc addr auth.");
return NULL;
+ }
switch (type) {
case FLAT_RANDOM:
- if (flat_init()) {
- free(tmp);
- return NULL;
- }
-
tmp->address = flat_address;
tmp->type = type;
break;
@@ -63,9 +60,6 @@ int addr_auth_destroy(struct addr_auth * instance)
switch (instance->type) {
case FLAT_RANDOM:
- if (flat_fini()) {
- return -1;
- }
break;
default:
LOG_ERR("Unknown address authority type.");
diff --git a/src/ipcpd/normal/ae.h b/src/ipcpd/normal/ae.h
index 229ff4aa..882625dd 100644
--- a/src/ipcpd/normal/ae.h
+++ b/src/ipcpd/normal/ae.h
@@ -23,7 +23,8 @@
#ifndef OUROBOROS_IPCPD_NORMAL_AE_H
#define OUROBOROS_IPCPD_NORMAL_AE_H
-#define MGMT_AE "Management"
-#define DT_AE "Data transfer"
+#define MGMT_AE "Management"
+#define DT_AE "Data transfer"
+#define ENROLL_AE "Enrollment"
#endif /* OUROBOROS_IPCPD_NORMAL_AE_H */
diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c
index 49283529..d30b9ec0 100644
--- a/src/ipcpd/normal/dir.c
+++ b/src/ipcpd/normal/dir.c
@@ -3,7 +3,8 @@
*
* DIF directory
*
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
*
* 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
@@ -19,164 +20,119 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define OUROBOROS_PREFIX "directory"
-
#include <ouroboros/config.h>
-#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
+#include <ouroboros/rib.h>
#include "dir.h"
-#include "ro.h"
-#include "pathname.h"
-#include "ribmgr.h"
+#include "ipcp.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-char * create_path(char * name)
-{
- char * path;
-
- path = pathname_create(RO_DIR);
- if (path == NULL)
- return NULL;
-
- path = pathname_append(path, name);
- if (path == NULL) {
- pathname_destroy(path);
- return NULL;
- }
+static char dir_path[RIB_MAX_PATH_LEN + 1];
- return path;
+static void dir_path_reset(void) {
+ dir_path[strlen("/" DIR_NAME)]= '\0';
+ assert(strcmp("/" DIR_NAME, dir_path) == 0);
}
int dir_init(void)
{
- char * path;
- struct ro_attr attr;
+ /*FIXME: set ribmgr dissemination here */
- ro_attr_init(&attr);
- attr.enrol_sync = true;
- attr.recv_set = ALL_MEMBERS;
-
- path = pathname_create(RO_DIR);
- if (path == NULL)
- return -1;
-
- if (ro_create(path, &attr, NULL, 0)) {
- pathname_destroy(path);
- LOG_ERR("Failed to create RIB object.");
+ if (rib_add(RIB_ROOT, DIR_NAME))
return -1;
- }
- pathname_destroy(path);
+ strcpy(dir_path, "/" DIR_NAME);
return 0;
}
int dir_fini(void)
{
- char * path;
+ /* FIXME: remove ribmgr dissemination here*/
- path = pathname_create(RO_DIR);
- if (path == NULL)
- return -1;
-
- ro_delete(path);
- pathname_destroy(path);
+ dir_path_reset();
+ rib_del(dir_path);
return 0;
}
int dir_name_reg(char * name)
{
- struct ro_attr attr;
- char * path;
- uint64_t * addr;
+ int ret;
assert(name);
- ro_attr_init(&attr);
- attr.enrol_sync = true;
- attr.recv_set = ALL_MEMBERS;
+ dir_path_reset();
- path = create_path(name);
- if (path == NULL)
+ ret = rib_add(dir_path, name);
+ if (ret == -ENOMEM)
return -ENOMEM;
- addr = malloc(sizeof(*addr));
- if (addr == NULL) {
- pathname_destroy(path);
+ rib_path_append(dir_path, name);
+ ret = rib_add(dir_path, ipcpi.name);
+ if (ret == -EPERM)
+ return -EPERM;
+ if (ret == -ENOMEM) {
+ if (rib_children(dir_path, NULL) == 0)
+ rib_del(dir_path);
return -ENOMEM;
}
- *addr = ribmgr_address();
-
- if (ro_create(path, &attr, (uint8_t *) addr, sizeof(*addr))) {
- pathname_destroy(path);
- free(addr);
- LOG_ERR("Failed to create RIB object.");
- return -1;
- }
-
- LOG_DBG("Registered %s.", name);
- pathname_destroy(path);
-
return 0;
}
int dir_name_unreg(char * name)
{
- char * path;
+ size_t len;
assert(name);
- path = create_path(name);
- if (path == NULL)
- return -ENOMEM;
+ dir_path_reset();
- if (ro_delete(path)) {
- pathname_destroy(path);
- LOG_ERR("No such RIB object exists.");
- return -1;
- }
+ rib_path_append(dir_path, name);
+
+ if (!rib_has(dir_path))
+ return 0;
+
+ len = strlen(dir_path);
+
+ rib_path_append(dir_path, ipcpi.name);
- pathname_destroy(path);
+ rib_del(dir_path);
+
+ dir_path[len] = '\0';
+
+ if (rib_children(dir_path, NULL) == 0)
+ rib_del(dir_path);
return 0;
}
int dir_name_query(char * name)
{
- char * path;
- int ret = -1;
- uint8_t * ro_data;
- uint64_t addr;
- struct dt_const * dtc;
-
- path = create_path(name);
- if (path == NULL)
- return -ENOMEM;
+ size_t len;
- if (ro_exists(path)) {
- if (ro_read(path, &ro_data) < 0) {
- pathname_destroy(path);
- return -1;
- }
- addr = *((uint64_t *) ro_data);
- free(ro_data);
+ dir_path_reset();
- dtc = ribmgr_dt_const();
- if (dtc == NULL) {
- pathname_destroy(path);
- return -1;
- }
+ rib_path_append(dir_path, name);
- ret = (addr == ribmgr_address()) ? -1 : 0;
- }
+ if (!rib_has(dir_path))
+ return -1;
+
+ /* FIXME: assert after local IPCP is deprecated */
+ len = strlen(dir_path);
- pathname_destroy(path);
+ rib_path_append(dir_path, ipcpi.name);
- return ret;
+ if (rib_has(dir_path)) {
+ dir_path[len] = '\0';
+ if (rib_children(dir_path, NULL) == 1)
+ return -1;
+ }
+
+ return 0;
}
diff --git a/src/ipcpd/normal/dir.h b/src/ipcpd/normal/dir.h
index 867cb87a..925fc823 100644
--- a/src/ipcpd/normal/dir.h
+++ b/src/ipcpd/normal/dir.h
@@ -22,8 +22,6 @@
#ifndef OUROBOROS_IPCPD_NORMAL_DIR_H
#define OUROBOROS_IPCPD_NORMAL_DIR_H
-#define RO_DIR "directory"
-
int dir_init(void);
int dir_fini(void);
diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c
new file mode 100644
index 00000000..695ceb1d
--- /dev/null
+++ b/src/ipcpd/normal/enroll.c
@@ -0,0 +1,263 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Enrollment Task
+ *
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
+ *
+ * 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.
+ */
+#define OUROBOROS_PREFIX "enrollment"
+
+#include <ouroboros/config.h>
+#include <ouroboros/cdap.h>
+#include <ouroboros/dev.h>
+#include <ouroboros/logs.h>
+#include <ouroboros/rib.h>
+
+#include "ae.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DLR "/"
+#define DIF_PATH DLR DIF_NAME
+#define BOOT_PATH DLR BOOT_NAME
+#define MEMBERS_PATH DLR MEMBERS_NAME
+
+int enroll_handle(int fd)
+{
+ struct cdap * ci;
+ cdap_key_t key;
+ enum cdap_opcode oc;
+ char * name;
+ uint8_t * buf;
+ uint8_t * data;
+ ssize_t len;
+ uint32_t flags;
+
+ bool boot_r = false;
+ bool members_r = false;
+ bool dif_name_r = false;
+
+ char * boot_ro = BOOT_PATH;
+ char * members_ro = MEMBERS_PATH;
+ char * dif_ro = DIF_PATH;
+
+ if (flow_alloc_resp(fd, 0) < 0) {
+ flow_dealloc(fd);
+ LOG_ERR("Could not respond to request.");
+ return -1;
+ }
+
+ ci = cdap_create(fd);
+ if (ci == NULL) {
+ flow_dealloc(fd);
+ LOG_ERR("Failed to create CDAP instance.");
+ return -1;
+ }
+
+ while (!(boot_r && members_r && dif_name_r)) {
+ key = cdap_request_wait(ci, &oc, &name, &data,
+ (size_t *) &len , &flags);
+
+ assert(key >= 0);
+ assert(name);
+
+ if (data != NULL) {
+ free(data);
+ LOG_WARN("Received data with enrollment request.");
+ }
+
+ if (oc != CDAP_READ) {
+ LOG_WARN("Invalid request.");
+ cdap_reply_send(ci, key, -1, NULL, 0);
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ free(name);
+ return -1;
+ }
+
+ if (strcmp(name, boot_ro) == 0) {
+ boot_r = true;
+ } else if (strcmp(name, members_ro) == 0) {
+ members_r = true;
+ } else if (strcmp(name, dif_ro) == 0) {
+ dif_name_r = true;
+ } else {
+ LOG_WARN("Illegal read: %s.", name);
+ cdap_reply_send(ci, key, -1, NULL, 0);
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ free(name);
+ return -1;
+ }
+
+ len = rib_pack(name, &buf, PACK_HASH_ROOT);
+ if (len < 0) {
+ LOG_ERR("Failed to pack %s.", name);
+ cdap_reply_send(ci, key, -1, NULL, 0);
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ free(name);
+ return -1;
+ }
+
+ LOG_DBG("Packed %s (%lu bytes).", name, len);
+
+ free(name);
+
+ if (cdap_reply_send(ci, key, 0, buf, len)) {
+ LOG_ERR("Failed to send CDAP reply.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ free(buf);
+ }
+
+ LOG_DBG("Sent boot info to new member.");
+
+ cdap_destroy(ci);
+
+ flow_dealloc(fd);
+
+ return 0;
+}
+
+int enroll_boot(char * dst_name)
+{
+ struct cdap * ci;
+ cdap_key_t key;
+ uint8_t * data;
+ size_t len;
+ int fd;
+
+ char * boot_ro = BOOT_PATH;
+ char * members_ro = MEMBERS_PATH;
+ char * dif_ro = DIF_PATH;
+
+ fd = flow_alloc(dst_name, ENROLL_AE, NULL);
+ if (fd < 0) {
+ LOG_ERR("Failed to allocate flow.");
+ return -1;
+ }
+
+ if (flow_alloc_res(fd)) {
+ LOG_ERR("Flow allocation failed.");
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ ci = cdap_create(fd);
+ if (ci == NULL) {
+ LOG_ERR("Failed to create CDAP instance.");
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Getting boot information from %s.", dst_name);
+
+ key = cdap_request_send(ci, CDAP_READ, boot_ro, NULL, 0, 0);
+ if (key < 0) {
+ LOG_ERR("Failed to send CDAP request.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ if (cdap_reply_wait(ci, key, &data, &len)) {
+ LOG_ERR("Failed to get CDAP reply.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Packed information received (%lu bytes).", len);
+
+ if (rib_unpack(data, len, UNPACK_CREATE)) {
+ LOG_WARN("Error unpacking RIB data.");
+ rib_del(boot_ro);
+ free(data);
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Packed information inserted into RIB.");
+
+ key = cdap_request_send(ci, CDAP_READ, members_ro, NULL, 0, 0);
+ if (key < 0) {
+ LOG_ERR("Failed to send CDAP request.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ if (cdap_reply_wait(ci, key, &data, &len)) {
+ LOG_ERR("Failed to get CDAP reply.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Packed information received (%lu bytes).", len);
+
+ if (rib_unpack(data, len, UNPACK_CREATE)) {
+ LOG_WARN("Error unpacking RIB data.");
+ rib_del(boot_ro);
+ free(data);
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Packed information inserted into RIB.");
+
+ key = cdap_request_send(ci, CDAP_READ, dif_ro, NULL, 0, 0);
+ if (key < 0) {
+ LOG_ERR("Failed to send CDAP request.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ if (cdap_reply_wait(ci, key, &data, &len)) {
+ LOG_ERR("Failed to get CDAP reply.");
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Packed information received (%lu bytes).", len);
+
+ if (rib_unpack(data, len, UNPACK_CREATE)) {
+ LOG_WARN("Error unpacking RIB data.");
+ rib_del(boot_ro);
+ free(data);
+ cdap_destroy(ci);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ LOG_DBG("Packed information inserted into RIB.");
+
+ cdap_destroy(ci);
+
+ flow_dealloc(fd);
+
+ return 0;
+}
diff --git a/src/ipcpd/normal/ro.proto b/src/ipcpd/normal/enroll.h
index cceaae7c..2980c380 100644
--- a/src/ipcpd/normal/ro.proto
+++ b/src/ipcpd/normal/enroll.h
@@ -1,10 +1,9 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * RIB object message
+ * Enrollment Task
*
* Dimitri Staessens <dimitri.staessens@intec.ugent.be>
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
*
* 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
@@ -20,14 +19,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-syntax = "proto2";
+#ifndef OUROBOROS_IPCPD_NORMAL_ENROLL_H
+#define OUROBOROS_IPCPD_NORMAL_ENROLL_H
-message ro_msg {
- required uint64 address = 1;
- required uint64 seqno = 2;
- required int32 recv_set = 3;
- required bool enrol_sync = 4;
- required uint32 sec = 5;
- required uint64 nsec = 6;
- required bytes value = 7;
-} \ No newline at end of file
+int enroll_handle(int fd);
+
+int enroll_boot(char * dst_name);
+
+#endif /* OUROBOROS_IPCPD_NORMAL_ENROLL_H */
diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c
index 6fe6fb60..b79d20b4 100644
--- a/src/ipcpd/normal/fmgr.c
+++ b/src/ipcpd/normal/fmgr.c
@@ -29,22 +29,19 @@
#include <ouroboros/fqueue.h>
#include <ouroboros/errno.h>
#include <ouroboros/cacep.h>
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <string.h>
+#include <ouroboros/rib.h>
#include "fmgr.h"
-#include "ribmgr.h"
#include "frct.h"
#include "ipcp.h"
#include "shm_pci.h"
-#include "dir.h"
-#include "pathname.h"
-#include "ro.h"
#include "gam.h"
+#include <stdlib.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <string.h>
+
#include "flow_alloc.pb-c.h"
typedef FlowAllocMsg flow_alloc_msg_t;
@@ -132,13 +129,15 @@ void * fmgr_nm1_sdu_reader(void * o)
{
struct timespec timeout = {0, FD_UPDATE_TIMEOUT};
struct shm_du_buff * sdb;
- struct pci * pci;
+ struct pci pci;
int fd;
int i = 0;
int ret;
(void) o;
+ memset(&pci, 0, sizeof(pci));
+
while (true) {
/* FIXME: replace with scheduling policy call */
i = (i + 1) % QOS_CUBE_MAX;
@@ -160,30 +159,15 @@ void * fmgr_nm1_sdu_reader(void * o)
continue;
}
- pci = shm_pci_des(sdb);
- if (pci == NULL) {
- LOG_ERR("Failed to get PCI.");
- ipcp_flow_del(sdb);
- continue;
- }
+ shm_pci_des(sdb, &pci);
- if (pci->dst_addr != ribmgr_address()) {
+ if (pci.dst_addr != ipcpi.address) {
LOG_DBG("PDU needs to be forwarded.");
- if (ribmgr_dt_const()->has_ttl) {
- if (pci->ttl == 0) {
- LOG_DBG("TTL was zero.");
- ipcp_flow_del(sdb);
- free(pci);
- continue;
- }
-
- if (shm_pci_dec_ttl(sdb)) {
- LOG_ERR("Failed to dec TTL.");
- ipcp_flow_del(sdb);
- free(pci);
- continue;
- }
+ if (pci.ttl == 0) {
+ LOG_DBG("TTL was zero.");
+ ipcp_flow_del(sdb);
+ continue;
}
/*
@@ -191,21 +175,14 @@ void * fmgr_nm1_sdu_reader(void * o)
* we don't have a PFF yet
*/
ipcp_flow_del(sdb);
- free(pci);
continue;
}
- if (shm_pci_shrink(sdb)) {
- LOG_ERR("Failed to shrink PDU.");
- ipcp_flow_del(sdb);
- free(pci);
- continue;
- }
+ shm_pci_shrink(sdb);
- if (frct_nm1_post_sdu(pci, sdb)) {
+ if (frct_nm1_post_sdu(&pci, sdb)) {
LOG_ERR("Failed to hand PDU to FRCT.");
ipcp_flow_del(sdb);
- free(pci);
continue;
}
}
@@ -269,8 +246,11 @@ static void fmgr_destroy_flows(void)
}
}
-int fmgr_init()
+int fmgr_init(void)
{
+ enum pol_cacep pc;
+ enum pol_gam pg;
+
int i;
for (i = 0; i < AP_MAX_FLOWS; ++i)
@@ -305,7 +285,22 @@ int fmgr_init()
}
}
- fmgr.gam = gam_create(ribmgr_dt_gam(), DT_AE);
+ if (rib_read("/" BOOT_NAME "/dt/gam/type", &pg, sizeof(pg))
+ != sizeof(pg)) {
+ LOG_ERR("Failed to read policy for ribmgr gam.");
+ return -1;
+ }
+
+ if (rib_read("/" BOOT_NAME "/dt/gam/cacep", &pc, sizeof(pc))
+ != sizeof(pc)) {
+ LOG_ERR("Failed to read CACEP policy for ribmgr gam.");
+ return -1;
+ }
+
+ /* FIXME: Implement cacep policies */
+ (void) pc;
+
+ fmgr.gam = gam_create(pg, DT_AE);
if (fmgr.gam == NULL) {
LOG_ERR("Failed to create graph adjacency manager.");
fmgr_destroy_flows();
@@ -324,7 +319,7 @@ int fmgr_init()
return 0;
}
-int fmgr_fini()
+void fmgr_fini()
{
struct list_head * pos = NULL;
struct list_head * n = NULL;
@@ -359,8 +354,6 @@ int fmgr_fini()
pthread_rwlock_destroy(&fmgr.np1_flows_lock);
fmgr_destroy_flows();
-
- return 0;
}
int fmgr_np1_alloc(int fd,
@@ -371,27 +364,43 @@ int fmgr_np1_alloc(int fd,
cep_id_t cep_id;
buffer_t buf;
flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT;
- char * path;
- uint8_t * ro_data;
+ char path[RIB_MAX_PATH_LEN + 1];
uint64_t addr;
+ ssize_t ch;
+ ssize_t i;
+ char ** children;
+ char * dst_ipcp = NULL;
- path = pathname_create(RO_DIR);
- if (path == NULL)
- return -1;
+ assert(strlen(dst_ap_name) + strlen("/" DIR_NAME) + 1
+ < RIB_MAX_PATH_LEN);
- path = pathname_append(path, dst_ap_name);
- if (path == NULL) {
- pathname_destroy(path);
+ strcpy(path, "/" DIR_NAME);
+
+ rib_path_append(path, dst_ap_name);
+
+ ch = rib_children(path, &children);
+ if (ch <= 0)
return -1;
- }
- if (ro_read(path, &ro_data) < 0) {
- pathname_destroy(path);
+ for (i = 0; i < ch; ++i)
+ if (dst_ipcp == NULL && strcmp(children[i], ipcpi.name) != 0)
+ dst_ipcp = children[i];
+ else
+ free(children[i]);
+
+ free(children);
+
+ if (dst_ipcp == NULL)
return -1;
- }
- addr = *((uint64_t *) ro_data);
- pathname_destroy(path);
+ strcpy(path, "/" MEMBERS_NAME);
+
+ rib_path_append(path, dst_ipcp);
+
+ free(dst_ipcp);
+
+ if (rib_read(path, &addr, sizeof(addr)) < 0)
+ return -1;
msg.code = FLOW_ALLOC_CODE__FLOW_REQ;
msg.dst_name = dst_ap_name;
@@ -400,16 +409,12 @@ int fmgr_np1_alloc(int fd,
msg.qoscube = cube;
buf.len = flow_alloc_msg__get_packed_size(&msg);
- if (buf.len == 0) {
- free(ro_data);
+ if (buf.len == 0)
return -1;
- }
buf.data = malloc(buf.len);
- if (buf.data == NULL) {
- free(ro_data);
+ if (buf.data == NULL)
return -1;
- }
flow_alloc_msg__pack(&msg, buf.data);
@@ -417,14 +422,11 @@ int fmgr_np1_alloc(int fd,
cep_id = frct_i_create(addr, &buf, cube);
if (cep_id == INVALID_CEP_ID) {
- free(ro_data);
free(buf.data);
pthread_rwlock_unlock(&fmgr.np1_flows_lock);
return -1;
}
- free(ro_data);
-
fmgr.np1_fd_to_cep_id[fd] = cep_id;
fmgr.np1_cep_id_to_fd[cep_id] = fd;
diff --git a/src/ipcpd/normal/fmgr.h b/src/ipcpd/normal/fmgr.h
index ae5c8ea8..3c61f55a 100644
--- a/src/ipcpd/normal/fmgr.h
+++ b/src/ipcpd/normal/fmgr.h
@@ -28,34 +28,34 @@
#include "ae.h"
#include "frct.h"
-int fmgr_init(void);
+int fmgr_init(void);
-int fmgr_fini(void);
+void fmgr_fini(void);
-int fmgr_np1_alloc(int fd,
- char * dst_ap_name,
- char * src_ae_name,
- qoscube_t qos);
+int fmgr_np1_alloc(int fd,
+ char * dst_ap_name,
+ char * src_ae_name,
+ qoscube_t qos);
-int fmgr_np1_alloc_resp(int fd,
- int response);
+int fmgr_np1_alloc_resp(int fd,
+ int response);
-int fmgr_np1_dealloc(int fd);
+int fmgr_np1_dealloc(int fd);
-int fmgr_np1_post_buf(cep_id_t id,
- buffer_t * buf);
+int fmgr_np1_post_buf(cep_id_t id,
+ buffer_t * buf);
-int fmgr_np1_post_sdu(cep_id_t id,
- struct shm_du_buff * sdb);
-
-int fmgr_nm1_write_sdu(struct pci * pci,
+int fmgr_np1_post_sdu(cep_id_t id,
struct shm_du_buff * sdb);
-int fmgr_nm1_write_buf(struct pci * pci,
- buffer_t * buf);
+int fmgr_nm1_write_sdu(struct pci * pci,
+ struct shm_du_buff * sdb);
+
+int fmgr_nm1_write_buf(struct pci * pci,
+ buffer_t * buf);
-int fmgr_nm1_flow_arr(int fd,
- qosspec_t qs);
+int fmgr_nm1_flow_arr(int fd,
+ qosspec_t qs);
#endif /* OUROBOROS_IPCPD_NORMAL_FMGR_H */
diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c
index 6cd68f18..ce316ca2 100644
--- a/src/ipcpd/normal/frct.c
+++ b/src/ipcpd/normal/frct.c
@@ -26,14 +26,14 @@
#include <ouroboros/bitmap.h>
#include <ouroboros/list.h>
+#include "frct.h"
+#include "fmgr.h"
+#include "ipcp.h"
+
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
-#include "frct.h"
-#include "fmgr.h"
-#include "ribmgr.h"
-
enum conn_state {
CONN_PENDING = 0,
CONN_ESTABLISHED
@@ -285,7 +285,7 @@ cep_id_t frct_i_create(uint64_t address,
pci.pdu_type = PDU_TYPE_MGMT;
pci.dst_addr = address;
- pci.src_addr = ribmgr_address();
+ pci.src_addr = ipcpi.address;
pci.dst_cep_id = 0;
pci.src_cep_id = id;
pci.seqno = 0;
@@ -330,7 +330,7 @@ int frct_i_accept(cep_id_t id,
pci.pdu_type = PDU_TYPE_MGMT;
pci.dst_addr = instance->r_address;
- pci.src_addr = ribmgr_address();
+ pci.src_addr = ipcpi.address;
pci.dst_cep_id = instance->r_cep_id;
pci.src_cep_id = instance->cep_id;
pci.seqno = 0;
@@ -367,7 +367,7 @@ int frct_i_destroy(cep_id_t id,
pci.pdu_type = PDU_TYPE_MGMT;
pci.dst_addr = instance->r_address;
- pci.src_addr = ribmgr_address();
+ pci.src_addr = ipcpi.address;
pci.dst_cep_id = instance->r_cep_id;
pci.src_cep_id = instance->cep_id;
pci.seqno = 0;
@@ -413,7 +413,7 @@ int frct_i_write_sdu(cep_id_t id,
pci.pdu_type = PDU_TYPE_DTP;
pci.dst_addr = instance->r_address;
- pci.src_addr = ribmgr_address();
+ pci.src_addr = ipcpi.address;
pci.dst_cep_id = instance->r_cep_id;
pci.src_cep_id = instance->cep_id;
pci.seqno = (instance->seqno)++;
diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c
index 0e626115..c337afd0 100644
--- a/src/ipcpd/normal/gam.c
+++ b/src/ipcpd/normal/gam.c
@@ -27,8 +27,8 @@
#include <ouroboros/logs.h>
#include <ouroboros/list.h>
#include <ouroboros/errno.h>
+#include <ouroboros/rib.h>
-#include "ribmgr.h"
#include "ipcp.h"
#include "gam.h"
#include "pol-gam-ops.h"
@@ -72,6 +72,7 @@ struct gam * gam_create(enum pol_gam gam_type,
tmp->ops = &complete_ops;
break;
default:
+ LOG_ERR("Unknown gam policy: %d.", gam_type);
free(tmp);
return NULL;
}
@@ -106,6 +107,14 @@ struct gam * gam_create(enum pol_gam gam_type,
return NULL;
}
+ if (tmp->ops->start(tmp->ops_o)) {
+ pthread_cond_destroy(&tmp->gas_cond);
+ pthread_mutex_destroy(&tmp->gas_lock);
+ free(tmp->ae_name);
+ free(tmp);
+ return NULL;
+ }
+
return tmp;
}
@@ -116,19 +125,25 @@ void gam_destroy(struct gam * instance)
assert(instance);
- instance->ops->destroy(instance->ops_o);
+ instance->ops->stop(instance->ops_o);
- pthread_mutex_destroy(&instance->gas_lock);
- pthread_cond_destroy(&instance->gas_cond);
+ pthread_mutex_lock(&instance->gas_lock);
list_for_each_safe(p, n, &instance->gas) {
struct ga * e = list_entry(p, struct ga, next);
list_del(&e->next);
+ free(e->info->name);
free(e->info);
free(e);
}
+ pthread_mutex_unlock(&instance->gas_lock);
+
+ pthread_mutex_destroy(&instance->gas_lock);
+ pthread_cond_destroy(&instance->gas_cond);
+
free(instance->ae_name);
+ instance->ops->destroy(instance->ops_o);
free(instance);
}
@@ -154,6 +169,8 @@ static int add_ga(struct gam * instance,
pthread_cond_signal(&instance->gas_cond);
pthread_mutex_unlock(&instance->gas_lock);
+ LOG_INFO("Added %s flow to %s.", instance->ae_name, info->name);
+
return 0;
}
@@ -170,7 +187,7 @@ int gam_flow_arr(struct gam * instance,
return -1;
}
- cacep = cacep_create(fd, ipcpi.name, ribmgr_address());
+ cacep = cacep_create(fd, ipcpi.name, ipcpi.address);
if (cacep == NULL) {
LOG_ERR("Failed to create CACEP instance.");
return -1;
@@ -187,12 +204,14 @@ int gam_flow_arr(struct gam * instance,
if (instance->ops->accept_flow(instance->ops_o, qs, info)) {
flow_dealloc(fd);
+ free(info->name);
free(info);
return 0;
}
if (add_ga(instance, fd, qs, info)) {
LOG_ERR("Failed to add ga to graph adjacency manager list.");
+ free(info->name);
free(info);
return -1;
}
@@ -208,6 +227,7 @@ int gam_flow_alloc(struct gam * instance,
struct cacep_info * info;
int fd;
+
fd = flow_alloc(dst_name, instance->ae_name, NULL);
if (fd < 0) {
LOG_ERR("Failed to allocate flow to %s.", dst_name);
@@ -220,7 +240,7 @@ int gam_flow_alloc(struct gam * instance,
return -1;
}
- cacep = cacep_create(fd, ipcpi.name, ribmgr_address());
+ cacep = cacep_create(fd, ipcpi.name, ipcpi.address);
if (cacep == NULL) {
LOG_ERR("Failed to create CACEP instance.");
return -1;
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index c1bae0d6..b9cc6e57 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -3,7 +3,8 @@
*
* Normal IPC Process
*
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
*
* 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
@@ -27,12 +28,17 @@
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/irm.h>
+#include <ouroboros/rib.h>
+#include <ouroboros/irm_config.h>
+#include "addr_auth.h"
+#include "ae.h"
+#include "dir.h"
+#include "enroll.h"
#include "fmgr.h"
-#include "ribmgr.h"
-#include "ipcp.h"
#include "frct.h"
-#include "dir.h"
+#include "ipcp.h"
+#include "ribmgr.h"
#include <stdbool.h>
#include <signal.h>
@@ -40,13 +46,19 @@
#include <pthread.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
-#define THIS_TYPE IPCP_NORMAL
+#define DLR "/"
+#define DIF_PATH DLR DIF_NAME
+#define BOOT_PATH DLR BOOT_NAME
+#define MEMBERS_PATH DLR MEMBERS_NAME
-/* global for trapping signal */
-int irmd_api;
+#define THIS_TYPE IPCP_NORMAL
-pthread_t acceptor;
+struct {
+ pthread_t acceptor;
+ struct addr_auth * auth;
+} normal;
void ipcp_sig_handler(int sig,
siginfo_t * info,
@@ -101,8 +113,10 @@ static void * flow_acceptor(void * o)
LOG_DBG("New flow allocation request for AE %s.", ae_name);
- if (strcmp(ae_name, MGMT_AE) == 0) {
- ribmgr_add_nm1_flow(fd);
+ if (strcmp(ae_name, ENROLL_AE) == 0) {
+ enroll_handle(fd);
+ } else if (strcmp(ae_name, MGMT_AE) == 0) {
+ ribmgr_flow_arr(fd, qs);
} else if (strcmp(ae_name, DT_AE) == 0) {
fmgr_nm1_flow_arr(fd, qs);
} else {
@@ -119,164 +133,269 @@ static void * flow_acceptor(void * o)
return (void *) 0;
}
-static int normal_ipcp_enroll(char * dst_name)
+/*
+ * Boots the IPCP off information in the rib.
+ * Common function after bootstrap or enroll.
+ * Call under ipcpi.state_lock
+ */
+static int boot_components(void)
{
- int ret;
+ char buf[256];
+ ssize_t len;
+ enum pol_addr_auth pa;
- pthread_rwlock_wrlock(&ipcpi.state_lock);
+ len = rib_read(DIF_PATH, &buf, 256);
+ if (len < 0) {
+ LOG_ERR("Failed to read DIF name: %ld.", len);
+ return -1;
+ }
- if (ipcp_get_state() != IPCP_INIT) {
- pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Won't enroll an IPCP that is not in INIT.");
- return -1; /* -ENOTINIT */
+ ipcpi.data->dif_name = strdup(buf);
+ if (ipcpi.data->dif_name == NULL) {
+ LOG_ERR("Failed to set DIF name.");
+ return -1;
}
- if (ribmgr_init()) {
- LOG_ERR("Failed to initialise RIB manager.");
- pthread_rwlock_unlock(&ipcpi.state_lock);
+ if (rib_add(MEMBERS_PATH, ipcpi.name)) {
+ LOG_WARN("Failed to add name to " MEMBERS_PATH);
return -1;
}
- if (ribmgr_nm1_mgt_flow(dst_name)) {
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
- LOG_ERR("Failed to establish management flow.");
- pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_DBG("Starting components.");
+
+ if (rib_read(BOOT_PATH "/addr_auth/type", &pa, sizeof(pa))
+ != sizeof(pa)) {
+ LOG_ERR("Failed to read policy for address authority.");
return -1;
}
- ret = ribmgr_enrol();
- if (ret < 0) {
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
- pthread_rwlock_unlock(&ipcpi.state_lock);
- if (ret == -ETIMEDOUT)
- LOG_ERR("Enrollment timed out.");
- else
- LOG_ERR("Failed to enrol IPCP: %d.", ret);
+ normal.auth = addr_auth_create(pa);
+ if (normal.auth == NULL) {
+ LOG_ERR("Failed to init address authority.");
return -1;
}
- if (ribmgr_start_policies()) {
- pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to start policies.");
+ ipcpi.address = normal.auth->address();
+ if (ipcpi.address == 0) {
+ LOG_ERR("Failed to get a valid address.");
+ addr_auth_destroy(normal.auth);
+ return -1;
+ }
+
+ LOG_DBG("IPCP got address %lu.", ipcpi.address);
+
+ LOG_DBG("Starting ribmgr.");
+
+ if (ribmgr_init()) {
+ LOG_ERR("Failed to initialize RIB manager.");
+ addr_auth_destroy(normal.auth);
return -1;
}
+ if (dir_init()) {
+ LOG_ERR("Failed to initialize directory.");
+ ribmgr_fini();
+ addr_auth_destroy(normal.auth);
+ return -1;
+ }
+
+ LOG_DBG("Ribmgr started.");
+
if (fmgr_init()) {
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
- pthread_rwlock_unlock(&ipcpi.state_lock);
+ dir_fini();
+ ribmgr_fini();
+ addr_auth_destroy(normal.auth);
LOG_ERR("Failed to start flow manager.");
return -1;
}
if (frct_init()) {
- if (fmgr_fini())
- LOG_WARN("Failed to finalize flow manager.");
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
- pthread_rwlock_unlock(&ipcpi.state_lock);
+ fmgr_fini();
+ dir_fini();
+ ribmgr_fini();
+ addr_auth_destroy(normal.auth);
LOG_ERR("Failed to initialize FRCT.");
return -1;
}
ipcp_set_state(IPCP_OPERATIONAL);
- if (pthread_create(&acceptor, NULL, flow_acceptor, NULL)) {
- if (frct_fini())
- LOG_WARN("Failed to finalize frct.");
- if (fmgr_fini())
- LOG_WARN("Failed to finalize flow manager.");
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
+ if (pthread_create(&normal.acceptor, NULL, flow_acceptor, NULL)) {
ipcp_set_state(IPCP_INIT);
- pthread_rwlock_unlock(&ipcpi.state_lock);
+ fmgr_fini();
+ dir_fini();
+ ribmgr_fini();
+ addr_auth_destroy(normal.auth);
LOG_ERR("Failed to create acceptor thread.");
return -1;
}
- pthread_rwlock_unlock(&ipcpi.state_lock);
-
- LOG_DBG("Enrolled with %s.", dst_name);
-
return 0;
}
-static int normal_ipcp_bootstrap(struct dif_config * conf)
+static int normal_ipcp_enroll(char * dst_name)
{
- if (conf == NULL || conf->type != THIS_TYPE) {
- LOG_ERR("Bad DIF configuration.");
- return -EINVAL;
- }
-
pthread_rwlock_wrlock(&ipcpi.state_lock);
if (ipcp_get_state() != IPCP_INIT) {
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Won't bootstrap an IPCP that is not in INIT.");
+ LOG_ERR("IPCP in wrong state.");
return -1; /* -ENOTINIT */
}
- ipcpi.data->dif_name = strdup(conf->dif_name);
- if (ipcpi.data->dif_name == NULL) {
+ if (rib_add(RIB_ROOT, MEMBERS_NAME)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to set DIF name.");
+ LOG_ERR("Failed to create members.");
return -1;
}
- if (ribmgr_init()) {
- LOG_ERR("Failed to initialise RIB manager.");
+ /* Get boot state from peer */
+ if (enroll_boot(dst_name)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_ERR("Failed to boot IPCP components.");
return -1;
}
- if (ribmgr_bootstrap(conf)) {
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
+ if (boot_components()) {
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to bootstrap RIB manager.");
+ LOG_ERR("Failed to boot IPCP components.");
return -1;
}
- if (ribmgr_start_policies()) {
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+
+ LOG_DBG("Enrolled with %s.", dst_name);
+
+ return 0;
+}
+
+const struct ros {
+ char * parent;
+ char * child;
+} ros[] = {
+ /* GENERAL IPCP INFO */
+ {RIB_ROOT, DIF_NAME},
+ /* BOOT INFO */
+ {RIB_ROOT, BOOT_NAME},
+ /* OTHER RIB STRUCTURES */
+ {RIB_ROOT, MEMBERS_NAME},
+ /* DT COMPONENT */
+ {BOOT_PATH, "dt"},
+
+ {BOOT_PATH "/dt", "gam"},
+ {BOOT_PATH "/dt/gam", "type"},
+ {BOOT_PATH "/dt/gam", "cacep"},
+ {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"},
+ {BOOT_PATH "/dt/const", "min_pdu_size"},
+ {BOOT_PATH "/dt/const", "max_pdu_size"},
+
+ /* RIB MGR COMPONENT */
+ {BOOT_PATH, "rm"},
+
+ {BOOT_PATH "/rm","gam"},
+ {BOOT_PATH "/rm/gam", "type"},
+ {BOOT_PATH "/rm/gam", "cacep"},
+
+ /* ADDR AUTH COMPONENT */
+ {BOOT_PATH, "addr_auth"},
+ {BOOT_PATH "/addr_auth", "type"},
+ {NULL, NULL}
+};
+
+int normal_rib_init(void)
+{
+ struct ros * r;
+
+ for (r = (struct ros *) ros; r->parent; ++r) {
+ if (rib_add(r->parent, r->child)) {
+ LOG_ERR("Failed to create %s/%s",
+ r->parent, r->child);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int normal_ipcp_bootstrap(struct dif_config * conf)
+{
+ /* FIXME: get CACEP policies from conf */
+ enum pol_cacep pol = NO_AUTH;
+
+ (void) pol;
+
+ if (conf == NULL || conf->type != THIS_TYPE) {
+ LOG_ERR("Bad DIF configuration.");
+ return -EINVAL;
+ }
+
+ pthread_rwlock_wrlock(&ipcpi.state_lock);
+
+ if (ipcp_get_state() != IPCP_INIT) {
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to start policies.");
- return -1;
+ LOG_ERR("IPCP in wrong state.");
+ return -1; /* -ENOTINIT */
}
- if (fmgr_init()) {
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
+ if (normal_rib_init()) {
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to start flow manager.");
+ LOG_ERR("Failed to write initial structure to the RIB.");
return -1;
}
- if (frct_init()) {
- if (fmgr_fini())
- LOG_WARN("Failed to finalize flow manager.");
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
+ if (rib_write(DIF_PATH,
+ conf->dif_name,
+ strlen(conf->dif_name) + 1) ||
+ rib_write(BOOT_PATH "/dt/const/addr_size",
+ &conf->addr_size,
+ sizeof(conf->addr_size)) ||
+ rib_write(BOOT_PATH "/dt/const/cep_id_size",
+ &conf->cep_id_size,
+ sizeof(conf->cep_id_size)) ||
+ rib_write(BOOT_PATH "/dt/const/seqno_size",
+ &conf->seqno_size,
+ sizeof(conf->seqno_size)) ||
+ rib_write(BOOT_PATH "/dt/const/has_ttl",
+ &conf->has_ttl,
+ sizeof(conf->has_ttl)) ||
+ rib_write(BOOT_PATH "/dt/const/has_chk",
+ &conf->has_chk,
+ sizeof(conf->has_chk)) ||
+ rib_write(BOOT_PATH "/dt/const/min_pdu_size",
+ &conf->min_pdu_size,
+ sizeof(conf->min_pdu_size)) ||
+ rib_write(BOOT_PATH "/dt/const/max_pdu_size",
+ &conf->max_pdu_size,
+ sizeof(conf->max_pdu_size)) ||
+ rib_write(BOOT_PATH "/dt/gam/type",
+ &conf->dt_gam_type,
+ sizeof(conf->dt_gam_type)) ||
+ rib_write(BOOT_PATH "/rm/gam/type",
+ &conf->rm_gam_type,
+ sizeof(conf->rm_gam_type)) ||
+ rib_write(BOOT_PATH "/rm/gam/cacep",
+ &pol,
+ sizeof(pol)) ||
+ rib_write(BOOT_PATH "/dt/gam/cacep",
+ &pol,
+ sizeof(pol)) ||
+ rib_write(BOOT_PATH "/addr_auth/type",
+ &conf->addr_auth_type,
+ sizeof(conf->addr_auth_type))) {
+ LOG_ERR("Failed to write boot info to RIB.");
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to initialize FRCT.");
return -1;
}
- ipcp_set_state(IPCP_OPERATIONAL);
-
- if (pthread_create(&acceptor, NULL, flow_acceptor, NULL)) {
- if (frct_fini())
- LOG_WARN("Failed to finalize frct.");
- if (fmgr_fini())
- LOG_WARN("Failed to finalize flow manager.");
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
- ipcp_set_state(IPCP_INIT);
+ if (boot_components()) {
+ LOG_ERR("Failed to boot IPCP components.");
pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_ERR("Failed to create acceptor thread.");
return -1;
}
@@ -293,9 +412,9 @@ static struct ipcp_ops normal_ops = {
.ipcp_name_reg = dir_name_reg,
.ipcp_name_unreg = dir_name_unreg,
.ipcp_name_query = dir_name_query,
- .ipcp_flow_alloc = fmgr_np1_alloc,
- .ipcp_flow_alloc_resp = fmgr_np1_alloc_resp,
- .ipcp_flow_dealloc = fmgr_np1_dealloc
+ .ipcp_flow_alloc = NULL, /* fmgr_np1_alloc, */
+ .ipcp_flow_alloc_resp = NULL, /* fmgr_np1_alloc_resp, */
+ .ipcp_flow_dealloc = NULL, /* fmgr_np1_dealloc */
};
int main(int argc,
@@ -338,8 +457,15 @@ int main(int argc,
sigaction(SIGHUP, &sig_act, NULL);
sigaction(SIGPIPE, &sig_act, NULL);
+ if (rib_init()) {
+ LOG_ERR("Failed to initialize RIB.");
+ close_logfile();
+ exit(EXIT_FAILURE);
+ }
+
if (ipcp_init(THIS_TYPE, &normal_ops) < 0) {
LOG_ERR("Failed to create instance.");
+ rib_fini();
close_logfile();
exit(EXIT_FAILURE);
}
@@ -348,6 +474,8 @@ int main(int argc,
if (ipcp_boot() < 0) {
LOG_ERR("Failed to boot IPCP.");
+ ipcp_fini();
+ rib_fini();
close_logfile();
exit(EXIT_FAILURE);
}
@@ -357,6 +485,7 @@ int main(int argc,
if (ipcp_create_r(getpid())) {
LOG_ERR("Failed to notify IRMd we are initialized.");
ipcp_fini();
+ rib_fini();
close_logfile();
exit(EXIT_FAILURE);
}
@@ -364,17 +493,18 @@ int main(int argc,
ipcp_shutdown();
if (ipcp_get_state() == IPCP_SHUTDOWN) {
- pthread_cancel(acceptor);
- pthread_join(acceptor, NULL);
-
- if (frct_fini())
- LOG_WARN("Failed to finalize FRCT.");
- if (fmgr_fini())
- LOG_WARN("Failed to finalize flow manager.");
- if (ribmgr_fini())
- LOG_WARN("Failed to finalize RIB manager.");
+ pthread_cancel(normal.acceptor);
+ pthread_join(normal.acceptor, NULL);
}
+ ribmgr_fini();
+
+ dir_fini();
+
+ addr_auth_destroy(normal.auth);
+
+ rib_fini();
+
ipcp_fini();
close_logfile();
diff --git a/src/ipcpd/normal/pathname.c b/src/ipcpd/normal/pathname.c
deleted file mode 100644
index d6d4fd79..00000000
--- a/src/ipcpd/normal/pathname.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Functions to construct pathnames
- *
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
- *
- * 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.
- */
-
-#define OUROBOROS_PREFIX "pathnames"
-
-#include <ouroboros/config.h>
-#include <ouroboros/logs.h>
-#include <ouroboros/errno.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "pathname.h"
-
-char * pathname_create(const char * name)
-{
- char * tmp;
-
- assert(name);
-
- tmp = malloc(strlen(name) + strlen(PATH_DELIMITER) + 1);
- if (tmp == NULL)
- return NULL;
-
- strcpy(tmp, PATH_DELIMITER);
- strcat(tmp, name);
-
- return tmp;
-}
-
-char * pathname_append(char * pname,
- const char * name)
-{
- char * tmp;
-
- assert(pname);
- assert(name);
-
- tmp = malloc(strlen(pname) +
- strlen(PATH_DELIMITER) +
- strlen(name) + 1);
- if (tmp == NULL)
- return NULL;
-
- strcpy(tmp, pname);
- strcat(tmp, PATH_DELIMITER);
- strcat(tmp, name);
-
- free(pname);
-
- return tmp;
-}
-
-void pathname_destroy(char * pname)
-{
- free(pname);
-}
diff --git a/src/ipcpd/normal/pathname.h b/src/ipcpd/normal/pathname.h
deleted file mode 100644
index 1d7fffa2..00000000
--- a/src/ipcpd/normal/pathname.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Functions to construct pathnames
- *
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
- *
- * 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_PATHNAME_H
-#define OUROBOROS_IPCPD_NORMAL_PATHNAME_H
-
-#define PATH_DELIMITER "/"
-
-char * pathname_create(const char * name);
-
-char * pathname_append(char * pname,
- const char * name);
-
-void pathname_destroy(char * pname);
-
-#endif /* OUROBOROS_IPCPD_NORMAL_PATHNAME_H */
diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h
index eeece8d9..0721136c 100644
--- a/src/ipcpd/normal/pol-gam-ops.h
+++ b/src/ipcpd/normal/pol-gam-ops.h
@@ -30,6 +30,10 @@ struct pol_gam_ops {
void (* destroy)(void * o);
+ int (* start)(void * o);
+
+ int (* stop)(void * o);
+
int (* accept_new_flow)(void * o);
int (* accept_flow)(void * o,
diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c
index 89e1b91f..f85fd749 100644
--- a/src/ipcpd/normal/pol/complete.c
+++ b/src/ipcpd/normal/pol/complete.c
@@ -26,16 +26,14 @@
#include <ouroboros/logs.h>
#include <ouroboros/list.h>
#include <ouroboros/qos.h>
+#include <ouroboros/rib.h>
-#include "pathname.h"
-#include "ro.h"
#include "ipcp.h"
#include "gam.h"
#include <string.h>
#include <stdlib.h>
-
-#define RO_DIR "neighbors"
+#include <assert.h>
struct neighbor {
struct list_head next;
@@ -56,73 +54,39 @@ static void * allocator(void * o)
qosspec_t qs;
ssize_t len;
char ** children;
- int i;
- char * ro_name;
+ ssize_t i;
struct complete * complete = (struct complete *) o;
+ assert(complete);
+ assert(complete->gam);
+
qs.delay = 0;
qs.jitter = 0;
- ro_name = pathname_create(RO_DIR);
- if (ro_name == NULL)
- return (void *) -1;
-
- len = ro_children(ro_name, &children);
- if (len > 0) {
- for (i = 0; i < len; i++) {
- if (strcmp(children[i], ipcpi.name) == 0)
- continue;
+ /* FIXME: subscribe to members to keep the graph complete. */
+ len = rib_children("/" MEMBERS_NAME, &children);
+ for (i = 0; i < len; ++i) {
+ if (strcmp(children[i], ipcpi.name) < 0)
gam_flow_alloc(complete->gam, children[i], qs);
- }
+ free(children[i]);
}
- pathname_destroy(ro_name);
+ if (len > 0)
+ free(children);
return (void *) 0;
}
void * complete_create(struct gam * gam)
{
- struct ro_attr attr;
- char * ro_name;
struct complete * complete;
- ro_attr_init(&attr);
- attr.enrol_sync = true;
- attr.recv_set = ALL_MEMBERS;
+ assert(gam);
complete = malloc(sizeof(*complete));
if (complete == NULL)
return NULL;
- ro_name = pathname_create(RO_DIR);
- if (ro_name == NULL) {
- free(complete);
- return NULL;
- }
-
- if (!ro_exists(RO_DIR)) {
- if (ro_create(ro_name, &attr, NULL, 0)) {
- free(complete);
- pathname_destroy(ro_name);
- return NULL;
- }
- }
-
- ro_name = pathname_append(ro_name, ipcpi.name);
- if (ro_name == NULL) {
- free(complete);
- pathname_destroy(ro_name);
- return NULL;
- }
-
- if (ro_create(ro_name, &attr, NULL, 0)) {
- free(complete);
- pathname_destroy(ro_name);
- return NULL;
- }
- pathname_destroy(ro_name);
-
list_head_init(&complete->neighbors);
complete->gam = gam;
@@ -131,14 +95,34 @@ void * complete_create(struct gam * gam)
return NULL;
}
+ return (void *) complete;
+}
+
+int complete_start(void * o)
+{
+ struct complete * complete = (struct complete *) o;
+
+ assert(complete);
+ assert(complete->gam);
+
if (pthread_create(&complete->allocator, NULL,
allocator, (void *) complete)) {
- free(complete);
pthread_mutex_destroy(&complete->neighbors_lock);
- return NULL;
+ free(complete);
+ return -1;
}
- return (void *) complete;
+ /* FIXME: Handle flooding of the flow allocator before detaching.*/
+ pthread_join(complete->allocator, NULL);
+
+ return 0;
+}
+
+int complete_stop(void * o)
+{
+ (void) o;
+
+ return 0;
}
void complete_destroy(void * o)
@@ -147,15 +131,16 @@ void complete_destroy(void * o)
struct list_head * n = NULL;
struct complete * complete = (struct complete *) o;
- pthread_cancel(complete->allocator);
- pthread_join(complete->allocator, NULL);
-
list_for_each_safe(p, n, &complete->neighbors) {
struct neighbor * e = list_entry(p, struct neighbor, next);
list_del(&e->next);
free(e->neighbor);
free(e);
}
+
+ pthread_mutex_destroy(&complete->neighbors_lock);
+
+ free(complete);
}
int complete_accept_new_flow(void * o)
@@ -175,6 +160,8 @@ int complete_accept_flow(void * o,
(void) qs;
+ assert(complete);
+
pthread_mutex_lock(&complete->neighbors_lock);
list_for_each(pos, &complete->neighbors) {
@@ -183,6 +170,10 @@ int complete_accept_flow(void * o,
pthread_mutex_unlock(&complete->neighbors_lock);
return -1;
}
+
+ assert(complete);
+ assert(&complete->neighbors_lock);
+ assert(pos->nxt);
}
n = malloc(sizeof(*n));
diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h
index 8fcc87ba..3f08c2e5 100644
--- a/src/ipcpd/normal/pol/complete.h
+++ b/src/ipcpd/normal/pol/complete.h
@@ -30,6 +30,10 @@ void * complete_create(struct gam * instance);
void complete_destroy(void * o);
+int complete_start(void * o);
+
+int complete_stop(void * o);
+
int complete_accept_new_flow(void * o);
int complete_accept_flow(void * o,
@@ -39,6 +43,8 @@ int complete_accept_flow(void * o,
struct pol_gam_ops complete_ops = {
.create = complete_create,
.destroy = complete_destroy,
+ .start = complete_start,
+ .stop = complete_stop,
.accept_new_flow = complete_accept_new_flow,
.accept_flow = complete_accept_flow
};
diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c
index abcb1ad4..31fcd4e8 100644
--- a/src/ipcpd/normal/pol/flat.c
+++ b/src/ipcpd/normal/pol/flat.c
@@ -3,7 +3,8 @@
*
* Policy for flat addresses in a distributed way
*
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
*
* 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
@@ -25,11 +26,9 @@
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
#include <ouroboros/time_utils.h>
+#include <ouroboros/rib.h>
-#include "shm_pci.h"
-#include "ribmgr.h"
-#include "ro.h"
-#include "pathname.h"
+#include "ipcp.h"
#include <time.h>
#include <stdlib.h>
@@ -37,235 +36,120 @@
#include <string.h>
#include <assert.h>
-#define POL_RO_ROOT "flat_addr"
+#define NAME_LEN 8
+#define REC_DIF_SIZE 10000
-#define TIMEOUT 100 /* ms */
-#define STR_SIZE 100
-
-#define FLAT_ADDR_REQ 0
-#define FLAT_ADDR_REPLY 1
-
-struct flat_addr_msg {
- uint8_t code;
- uint64_t addr;
-};
-
-struct {
- int sid;
- uint64_t addr;
- bool addr_in_use;
-
- pthread_cond_t cond;
- pthread_mutex_t lock;
-} flat;
-
-static char * addr_name(void)
+/* convert 32 bit addr to a hex string */
+static void addr_name(char * name,
+ uint32_t addr)
{
- char * name;
- /* uint64_t as a string has 25 chars */
- char addr_name[30];
-
- sprintf(addr_name, "%lu", (unsigned long) flat.addr);
-
- name = pathname_create(POL_RO_ROOT);
- if (name == NULL)
- return NULL;
-
- name = pathname_append(name, addr_name);
- return name;
+ sprintf(name, "%8x", (uint32_t) (addr));
}
-static void ro_created(const char * name,
- uint8_t * data,
- size_t len)
+#define freepp(type, ptr, len) \
+ do { \
+ if (len == 0) \
+ break; \
+ while (len > 0) \
+ free(((type **) ptr)[--len]); \
+ free(ptr); \
+ } while (0);
+
+static int addr_taken(char * name,
+ char ** members,
+ size_t len)
{
- struct flat_addr_msg * msg;
-
- assert(name);
- assert(data);
- assert(len >= sizeof(*msg));
-
- msg = (struct flat_addr_msg *) data;
- if (msg->code == FLAT_ADDR_REQ && msg->addr == flat.addr) {
- msg->code = FLAT_ADDR_REPLY;
- ro_write(name, data, len);
+ size_t i;
+ char path[RIB_MAX_PATH_LEN + 1];
+
+ size_t reset;
+ strcpy(path, "/" MEMBERS_NAME);
+
+ reset = strlen(path);
+
+ for (i = 0; i < len; ++i) {
+ ssize_t j;
+ ssize_t c;
+ char ** addrs;
+ rib_path_append(path, members[i]);
+ c = rib_children(path, &addrs);
+ for (j = 0; j < c; ++j)
+ if (strcmp(addrs[j], name) == 0) {
+ freepp(char, addrs, c);
+ return 1;
+ }
+ freepp(char, addrs, c);
+ path[reset] = '\0';
}
-}
-static void ro_updated(const char * name,
- uint8_t * data,
- size_t len)
-{
- struct flat_addr_msg * msg;
- char * ro_name;
-
- assert(name);
- assert(data);
- assert(len >= sizeof(*msg));
- (void) len;
-
- ro_name = addr_name();
- if (ro_name == NULL) {
- free(data);
- return;
- }
-
- msg = (struct flat_addr_msg *) data;
- if (msg->code == FLAT_ADDR_REPLY &&
- strcmp(name, ro_name) == 0) {
- pthread_mutex_lock(&flat.lock);
- flat.addr_in_use = true;
- pthread_cond_broadcast(&flat.cond);
- pthread_mutex_unlock(&flat.lock);
- }
-
- free(data);
- free(ro_name);
+ return 0;
}
-static struct ro_sub_ops flat_sub_ops = {
- .ro_created = ro_created,
- .ro_updated = ro_updated,
- .ro_deleted = NULL
-};
+#define INVALID_ADDRESS 0
-int flat_init(void)
+uint64_t flat_address(void)
{
- struct ro_attr rattr;
- pthread_condattr_t cattr;
- struct timespec t;
- char * name;
+ struct timespec t;
- clock_gettime(CLOCK_REALTIME, &t);
+ char path[RIB_MAX_PATH_LEN];
+ char name[NAME_LEN + 1];
+ uint32_t addr;
+ uint8_t addr_size;
- srand(t.tv_nsec);
- flat.addr_in_use = false;
+ char ** members;
+ ssize_t n_members;
- ro_attr_init(&rattr);
- pthread_mutex_init(&flat.lock, NULL);
- pthread_condattr_init(&cattr);
-#ifndef __APPLE__
- pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
-#endif
- pthread_cond_init(&flat.cond, &cattr);
+ strcpy(path, "/" MEMBERS_NAME);
- flat.sid = ro_subscribe(POL_RO_ROOT, &flat_sub_ops);
- if (flat.sid < 0) {
- LOG_ERR("Could not subscribe to RIB.");
- pthread_cond_destroy(&flat.cond);
- pthread_mutex_destroy(&flat.lock);
- return -1;
+ if (!rib_has(path)) {
+ LOG_ERR("Could not read members from RIB.");
+ return INVALID_ADDRESS;
}
- name = pathname_create(POL_RO_ROOT);
- if (name == NULL) {
- pthread_cond_destroy(&flat.cond);
- pthread_mutex_destroy(&flat.lock);
- ro_unsubscribe(flat.sid);
- return -1;
+ if (rib_read("/" BOOT_NAME "/dt/const/addr_size",
+ &addr_size, sizeof(addr_size)) != sizeof(addr_size)) {
+ LOG_ERR("Failed to read address size.");
+ return INVALID_ADDRESS;
}
- if (!ro_exists(name)) {
- rattr.enrol_sync = true;
- if (ro_create(name, &rattr, NULL, 0)) {
- LOG_ERR("Could not create RO.");
- pathname_destroy(name);
- pthread_cond_destroy(&flat.cond);
- pthread_mutex_destroy(&flat.lock);
- ro_unsubscribe(flat.sid);
- return -1;
- }
+ if (addr_size != 4) {
+ LOG_ERR("Flat address policy mandates 4 byte addresses.");
+ return INVALID_ADDRESS;
}
- pathname_destroy(name);
-
- return 0;
-}
-
-int flat_fini(void)
-{
- pthread_cond_destroy(&flat.cond);
- pthread_mutex_destroy(&flat.lock);
- ro_unsubscribe(flat.sid);
- return 0;
-}
-uint64_t flat_address(void)
-{
- int ret = 0;
- uint64_t max_addr;
- struct dt_const * dtc;
- struct timespec timeout = {(TIMEOUT / 1000),
- (TIMEOUT % 1000) * MILLION};
- struct timespec abstime;
- struct ro_attr attr;
- struct flat_addr_msg * msg;
- uint8_t * buf;
- char * ro_name;
+ n_members = rib_children(path, &members);
+ if (n_members > REC_DIF_SIZE)
+ LOG_WARN("DIF exceeding recommended size for flat addresses.");
- dtc = ribmgr_dt_const();
- if (dtc == NULL)
- return INVALID_ADDR;
+ rib_path_append(path, ipcpi.name);
- if (dtc->addr_size == 8) {
- LOG_ERR("Policy cannot be used with 64 bit addresses.");
- return INVALID_ADDR;
+ if (!rib_has(path)) {
+ LOG_ERR("This ipcp is not a member.");
+ freepp(char, members, n_members);
+ return INVALID_ADDRESS;
}
- while (ret != -ETIMEDOUT) {
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, &timeout, &abstime);
-
- max_addr = (1 << (8 * dtc->addr_size)) - 1;
- flat.addr = (rand() % (max_addr - 1)) + 1;
-
- ro_attr_init(&attr);
- attr.recv_set = ALL_MEMBERS;
- attr.expiry.tv_sec = TIMEOUT / 1000;
- attr.expiry.tv_nsec = (TIMEOUT % 1000) * MILLION;
-
- buf = malloc(sizeof(*msg));
- if (buf == NULL)
- return INVALID_ADDR;
-
- msg = (struct flat_addr_msg *) buf;
- msg->code = FLAT_ADDR_REQ;
- msg->addr = flat.addr;
-
- ro_name = addr_name();
- if (ro_name == NULL) {
- free(buf);
- return INVALID_ADDR;
- }
-
- pthread_mutex_lock(&flat.lock);
-
- if (ro_exists(ro_name)) {
- pthread_mutex_unlock(&flat.lock);
- free(ro_name);
- free(buf);
- continue;
- }
+ clock_gettime(CLOCK_REALTIME, &t);
+ srand(t.tv_nsec);
+ assert(n_members > 0);
- if (ro_create(ro_name, &attr, buf, sizeof(*msg))) {
- pthread_mutex_unlock(&flat.lock);
- free(ro_name);
- free(buf);
- return INVALID_ADDR;
- }
+ do {
+ addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF;
+ addr_name(name, addr);
+ } while (addr_taken(name, members, n_members));
- free(ro_name);
+ freepp(char, members, n_members);
- while (flat.addr_in_use == false) {
- ret = -pthread_cond_timedwait(&flat.cond,
- &flat.lock,
- &abstime);
- if (ret == -ETIMEDOUT)
- break;
- }
+ if (rib_add(path, name)) {
+ LOG_ERR("Failed to add address to RIB.");
+ return INVALID_ADDRESS;
+ }
- pthread_mutex_unlock(&flat.lock);
+ if (rib_write(path, &addr, sizeof(addr))) {
+ LOG_ERR("Failed to write address in RIB.");
+ return INVALID_ADDRESS;
}
- return flat.addr;
+ return addr;
}
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
index 993fe62a..4ff316dc 100644
--- a/src/ipcpd/normal/ribmgr.c
+++ b/src/ipcpd/normal/ribmgr.c
@@ -27,1670 +27,103 @@
#include <ouroboros/list.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/ipcp-dev.h>
-#include <ouroboros/bitmap.h>
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
+#include <ouroboros/fqueue.h>
+#include <ouroboros/rib.h>
#include "timerwheel.h"
#include "addr_auth.h"
#include "ribmgr.h"
-#include "dt_const.h"
-#include "ro.h"
-#include "pathname.h"
-#include "dir.h"
+#include "gam.h"
#include "ae.h"
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
-#include "static_info.pb-c.h"
-typedef StaticInfoMsg static_info_msg_t;
+#define BOOT_PATH "/" BOOT_NAME
-#include "ro.pb-c.h"
-typedef RoMsg ro_msg_t;
-
-#define SUBS_SIZE 25
-#define WHEEL_RESOLUTION 1000 /* ms */
-#define WHEEL_DELAY 3600000 /* ms */
-#define RO_ID_TIMEOUT 1000 /* ms */
-
-#define ENROLLMENT "enrollment"
-
-#define RIBMGR_PREFIX PATH_DELIMITER "ribmgr"
-#define STAT_INFO PATH_DELIMITER "statinfo"
-
-/* RIB objects */
-struct rnode {
- char * name;
- char * full_name;
- uint64_t seqno;
-
- /*
- * NOTE: Naive implementation for now, could be replaced by
- * for instance taking a hash of the pathname and using that
- * as an index in a B-tree
- */
-
- /* If there are no children, this is a leaf. */
- struct rnode * child;
- struct rnode * sibling;
-
- struct ro_attr attr;
- uint8_t * data;
- size_t len;
-};
-
-struct mgmt_flow {
- struct list_head next;
-
- struct cdap * instance;
- int fd;
-
- pthread_t handler;
-};
-
-struct ro_sub {
- struct list_head next;
-
- int sid;
-
- char * name;
- struct ro_sub_ops * ops;
-};
-
-struct ro_id {
- struct list_head next;
-
- uint64_t seqno;
- char * full_name;
-};
-
-enum ribmgr_state {
- RIBMGR_NULL,
- RIBMGR_INIT,
- RIBMGR_OPERATIONAL,
- RIBMGR_SHUTDOWN
-};
-
-/* FIXME: Extract rib from ribmgr. */
struct {
- struct rnode * root;
- pthread_mutex_t ro_lock;
-
- struct list_head subs;
- struct bmp * sids;
- pthread_mutex_t subs_lock;
- int ribmgr_sid;
-
- struct dt_const dtc;
-
- uint64_t address;
-
- struct timerwheel * wheel;
-
- struct list_head ro_ids;
- pthread_mutex_t ro_ids_lock;
-
- struct list_head flows;
- pthread_rwlock_t flows_lock;
-
- struct addr_auth * addr_auth;
- enum pol_addr_auth addr_auth_type;
-
- enum pol_gam dt_gam_type;
-
- enum ribmgr_state state;
- pthread_cond_t state_cond;
- pthread_mutex_t state_lock;
-} rib;
-
-void ribmgr_ro_created(const char * name,
- uint8_t * data,
- size_t len)
-{
- static_info_msg_t * stat_msg;
-
- if (strcmp(name, RIBMGR_PREFIX STAT_INFO) == 0) {
- LOG_DBG("Received static DIF information.");
-
- stat_msg = static_info_msg__unpack(NULL, len, data);
- if (stat_msg == NULL) {
- LOG_ERR("Failed to unpack static info message.");
- return;
- }
-
- rib.dtc.addr_size = stat_msg->addr_size;
- rib.dtc.cep_id_size = stat_msg->cep_id_size;
- rib.dtc.pdu_length_size = stat_msg->pdu_length_size;
- rib.dtc.seqno_size = stat_msg->seqno_size;
- rib.dtc.has_ttl = stat_msg->has_ttl;
- rib.dtc.has_chk = stat_msg->has_chk;
- rib.dtc.min_pdu_size = stat_msg->min_pdu_size;
- rib.dtc.max_pdu_size = stat_msg->max_pdu_size;
- rib.addr_auth_type = stat_msg->addr_auth_type;
- rib.dt_gam_type = stat_msg->dt_gam_type;
-
- static_info_msg__free_unpacked(stat_msg, NULL);
- }
-}
-
-/* We only have a create operation for now. */
-static struct ro_sub_ops ribmgr_sub_ops = {
- .ro_created = ribmgr_ro_created,
- .ro_updated = NULL,
- .ro_deleted = NULL
-};
-
-static struct rnode * find_rnode_by_name(const char * name)
-{
- char * str;
- char * str1;
- char * token;
- struct rnode * node;
-
- str = strdup(name);
- if (str == NULL)
- return NULL;
-
- node = rib.root;
-
- for (str1 = str; node != NULL; str1 = NULL) {
- token = strtok(str1, PATH_DELIMITER);
- if (token == NULL)
- break;
-
- node = node->child;
-
- while (node != NULL)
- if (strcmp(node->name, token) == 0)
- break;
- else
- node = node->sibling;
- }
-
- free(str);
- return node;
-}
-
-/* Call under RIB object lock. */
-static int ro_msg_create(struct rnode * node,
- ro_msg_t * msg)
-{
- msg->address = rib.address;
- msg->seqno = node->seqno;
- msg->recv_set = node->attr.recv_set;
- msg->enrol_sync = node->attr.enrol_sync;
- msg->sec = node->attr.expiry.tv_sec;
- msg->nsec = node->attr.expiry.tv_nsec;
- msg->value.data = node->data;
- msg->value.len = node->len;
-
- return 0;
-}
-
-static int ribmgr_ro_delete(const char * name)
-{
- char * str;
- char * str1;
- char * saveptr;
- char * token;
- struct rnode * node;
- struct rnode * prev;
- bool sibling = false;
-
- str = strdup(name);
- if (str == NULL)
- return -1;
-
- node = rib.root;
- prev = NULL;
-
- for (str1 = str; ; str1 = NULL) {
- token = strtok_r(str1, PATH_DELIMITER, &saveptr);
- if (token == NULL)
- break;
-
- prev = node;
- node = node->child;
- sibling = false;
-
- while (node != NULL) {
- if (strcmp(node->name, token) == 0) {
- break;
- } else {
- prev = node;
- node = node->sibling;
- sibling = true;
- }
- }
-
- if (node == NULL) {
- free(str);
- return -1;
- }
- }
-
- if (node == rib.root) {
- LOG_ERR("Won't remove root.");
- free(str);
- return -1;
- }
-
- free(node->name);
- free(node->full_name);
- if (node->data != NULL)
- free(node->data);
-
- if (sibling)
- prev->sibling = node->sibling;
- else
- prev->child = node->sibling;
-
- free(node);
- free(str);
-
- LOG_DBG("Deleted RO with name %s.", name);
-
- return 0;
-}
-
-static void ro_delete_timer(void * o)
-{
- char * name = (char *) o;
-
- pthread_mutex_lock(&rib.ro_lock);
-
- if (ribmgr_ro_delete(name))
- LOG_ERR("Failed to delete %s.", name);
-
- pthread_mutex_unlock(&rib.ro_lock);
-}
-
-static struct rnode * ribmgr_ro_create(const char * name,
- struct ro_attr attr,
- uint8_t * data,
- size_t len)
-{
- char * str;
- char * str1;
- char * saveptr = NULL;
- char * token = NULL;
- char * token2;
- struct rnode * node = NULL;
- struct rnode * new = NULL;
- struct rnode * prev = NULL;
- bool sibling = false;
- int timeout;
-
- str = strdup(name);
- if (str == NULL)
- return NULL;
-
- node = rib.root;
-
- assert(node);
-
- for (str1 = str; node != NULL; str1 = NULL) {
- token = strtok_r(str1, PATH_DELIMITER, &saveptr);
- if (token == NULL) {
- LOG_ERR("RO already exists.");
- free(str);
- return NULL;
- }
-
- prev = node;
- node = node->child;
- sibling = false;
-
- /* Search horizontally. */
- while (node != NULL) {
- if (strcmp(node->name, token) == 0) {
- break;
- } else {
- prev = node;
- node = node->sibling;
- sibling = true;
- }
- }
- }
-
- assert(token);
- assert(prev);
-
- token2 = strtok_r(NULL, PATH_DELIMITER, &saveptr);
- if (token2 != NULL) {
- LOG_ERR("Part of the pathname does not exist.");
- free(str);
- return NULL;
- }
-
- new = malloc(sizeof(*new));
- if (new == NULL) {
- free(str);
- return NULL;
- }
-
- new->name = strdup(token);
- if (new->name == NULL) {
- free(str);
- free(new);
- return NULL;
- }
-
- free(str);
-
- new->full_name = strdup(name);
- if (new->full_name == NULL) {
- free(new);
- return NULL;
- }
-
- new->seqno = 0;
- new->attr = attr;
-
- if (sibling)
- prev->sibling = new;
- else
- prev->child = new;
-
- new->data = data;
- new->len = len;
- new->child = NULL;
- new->sibling = NULL;
-
- LOG_DBG("Created RO with name %s.", name);
-
- if (!(attr.expiry.tv_sec == 0 && attr.expiry.tv_nsec == 0)) {
- timeout = attr.expiry.tv_sec * 1000 +
- attr.expiry.tv_nsec / MILLION;
- if (timerwheel_add(rib.wheel, ro_delete_timer, new->full_name,
- strlen(new->full_name) + 1, timeout))
- LOG_ERR("Failed to add deletion timer of RO.");
- }
-
- return new;
-}
-
-static struct rnode * ribmgr_ro_write(const char * name,
- uint8_t * data,
- size_t len)
-{
- struct rnode * node;
-
- node = find_rnode_by_name(name);
- if (node == NULL)
- return NULL;
-
- free(node->data);
-
- node->data = data;
- node->len = len;
-
- LOG_DBG("Updated RO with name %s.", name);
-
- return node;
-}
-
-static int write_ro_msg(struct cdap * neighbor,
- ro_msg_t * msg,
- char * name,
- enum cdap_opcode code)
-{
- uint8_t * data;
- size_t len;
- cdap_key_t key;
- int ret;
-
- len = ro_msg__get_packed_size(msg);
- if (len == 0)
- return -1;
-
- data = malloc(len);
- if (data == NULL)
- return -ENOMEM;
-
- ro_msg__pack(msg, data);
-
- key = cdap_request_send(neighbor, code, name, data, len, 0);
- if (key < 0) {
- LOG_ERR("Failed to send CDAP request.");
- free(data);
- return -1;
- }
-
- free(data);
-
- ret = cdap_reply_wait(neighbor, key, NULL, NULL);
- if (ret < 0) {
- LOG_ERR("CDAP command with code %d and name %s failed: %d.",
- code, name, ret);
- return -1;
- }
-
- return 0;
-}
-
-int ribmgr_init()
-{
- list_head_init(&rib.flows);
- list_head_init(&rib.subs);
- list_head_init(&rib.ro_ids);
-
- rib.root = malloc(sizeof(*(rib.root)));
- if (rib.root == NULL)
- return -1;
-
- rib.root->name = "root";
- rib.root->child = NULL;
- rib.root->sibling = NULL;
-
- if (pthread_rwlock_init(&rib.flows_lock, NULL)) {
- LOG_ERR("Failed to initialize rwlock.");
- free(rib.root);
- return -1;
- }
-
- if (pthread_mutex_init(&rib.ro_lock, NULL)) {
- LOG_ERR("Failed to initialize mutex.");
- pthread_rwlock_destroy(&rib.flows_lock);
- free(rib.root);
- return -1;
- }
-
- if (pthread_mutex_init(&rib.subs_lock, NULL)) {
- LOG_ERR("Failed to initialize mutex.");
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- free(rib.root);
- return -1;
- }
-
- if (pthread_mutex_init(&rib.ro_ids_lock, NULL)) {
- LOG_ERR("Failed to initialize mutex.");
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_mutex_destroy(&rib.subs_lock);
- free(rib.root);
- return -1;
- }
-
- rib.sids = bmp_create(SUBS_SIZE, 0);
- if (rib.sids == NULL) {
- LOG_ERR("Failed to create bitmap.");
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_mutex_destroy(&rib.subs_lock);
- pthread_mutex_destroy(&rib.ro_ids_lock);
- free(rib.root);
- return -1;
- }
-
- rib.wheel = timerwheel_create(WHEEL_RESOLUTION, WHEEL_DELAY);
- if (rib.wheel == NULL) {
- LOG_ERR("Failed to create timerwheel.");
- bmp_destroy(rib.sids);
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_mutex_destroy(&rib.subs_lock);
- pthread_mutex_destroy(&rib.ro_ids_lock);
- free(rib.root);
- return -1;
- }
-
- rib.ribmgr_sid = ro_subscribe(RIBMGR_PREFIX, &ribmgr_sub_ops);
- if (rib.ribmgr_sid < 0) {
- LOG_ERR("Failed to subscribe.");
- timerwheel_destroy(rib.wheel);
- bmp_destroy(rib.sids);
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_mutex_destroy(&rib.subs_lock);
- pthread_mutex_destroy(&rib.ro_ids_lock);
- free(rib.root);
- return -1;
- }
-
- if (pthread_cond_init(&rib.state_cond, NULL)) {
- LOG_ERR("Failed to init condvar.");
- timerwheel_destroy(rib.wheel);
- bmp_destroy(rib.sids);
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_mutex_destroy(&rib.subs_lock);
- pthread_mutex_destroy(&rib.ro_ids_lock);
- free(rib.root);
- return -1;
- }
-
- if (pthread_mutex_init(&rib.state_lock, NULL)) {
- LOG_ERR("Failed to init mutex.");
- pthread_cond_destroy(&rib.state_cond);
- timerwheel_destroy(rib.wheel);
- bmp_destroy(rib.sids);
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_mutex_destroy(&rib.subs_lock);
- pthread_mutex_destroy(&rib.ro_ids_lock);
- free(rib.root);
- return -1;
- }
-
- rib.state = RIBMGR_INIT;
-
- return 0;
-}
-
-static enum ribmgr_state ribmgr_get_state(void)
-{
- enum ribmgr_state state;
-
- pthread_mutex_lock(&rib.state_lock);
-
- state = rib.state;
-
- pthread_mutex_unlock(&rib.state_lock);
-
- return state;
-}
-
-static void ribmgr_set_state(enum ribmgr_state state)
-{
- pthread_mutex_lock(&rib.state_lock);
-
- rib.state = state;
-
- pthread_cond_broadcast(&rib.state_cond);
-
- pthread_mutex_unlock(&rib.state_lock);
-}
-
-static int ribmgr_wait_state(enum ribmgr_state state,
- const struct timespec * timeout)
-{
- struct timespec abstime;
- int ret = 0;
-
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
-
- pthread_mutex_lock(&rib.state_lock);
-
- while (rib.state != state
- && rib.state != RIBMGR_SHUTDOWN
- && rib.state != RIBMGR_NULL) {
- if (timeout == NULL)
- ret = -pthread_cond_wait(&rib.state_cond,
- &rib.state_lock);
- else
- ret = -pthread_cond_timedwait(&rib.state_cond,
- &rib.state_lock,
- &abstime);
- }
-
- pthread_mutex_unlock(&rib.state_lock);
-
- return ret;
-}
-
-static void rtree_destroy(struct rnode * node)
-{
- if (node != NULL) {
- rtree_destroy(node->child);
- rtree_destroy(node->sibling);
- free(node->name);
- if (node->data != NULL)
- free(node->data);
- free(node);
- }
-}
-
-int ribmgr_fini()
-{
- struct list_head * pos = NULL;
- struct list_head * n = NULL;
-
- pthread_mutex_lock(&rib.state_lock);
- rib.state = RIBMGR_SHUTDOWN;
- pthread_cond_broadcast(&rib.state_cond);
- pthread_mutex_unlock(&rib.state_lock);
-
- pthread_rwlock_wrlock(&rib.flows_lock);
-
- list_for_each_safe(pos, n, &rib.flows) {
- struct mgmt_flow * flow =
- list_entry(pos, struct mgmt_flow, next);
- if (cdap_destroy(flow->instance))
- LOG_ERR("Failed to destroy CDAP instance.");
- list_del(&flow->next);
- free(flow);
- }
-
- pthread_rwlock_unlock(&rib.flows_lock);
-
- ro_unsubscribe(rib.ribmgr_sid);
-
- if (rib.addr_auth != NULL)
- addr_auth_destroy(rib.addr_auth);
-
- pthread_mutex_lock(&rib.ro_lock);
-
- rtree_destroy(rib.root->child);
- free(rib.root);
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- bmp_destroy(rib.sids);
- timerwheel_destroy(rib.wheel);
-
- pthread_mutex_destroy(&rib.subs_lock);
- pthread_mutex_destroy(&rib.ro_lock);
- pthread_rwlock_destroy(&rib.flows_lock);
- pthread_mutex_destroy(&rib.ro_ids_lock);
-
- pthread_cond_destroy(&rib.state_cond);
- pthread_mutex_destroy(&rib.state_lock);
-
- return 0;
-}
-
-static int ribmgr_cdap_create(struct cdap * instance,
- cdap_key_t key,
- char * name,
- ro_msg_t * msg)
-{
- int ret = 0;
- struct list_head * p = NULL;
- size_t len_s, len_n;
- uint8_t * ro_data;
- struct ro_attr attr;
- struct rnode * node;
-
- assert(instance);
-
- ro_attr_init(&attr);
- attr.expiry.tv_sec = msg->sec;
- attr.expiry.tv_nsec = msg->nsec;
- attr.enrol_sync = msg->enrol_sync;
- attr.recv_set = msg->recv_set;
-
- pthread_mutex_lock(&rib.ro_lock);
-
- ro_data = malloc(msg->value.len);
- if (ro_data == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- cdap_reply_send(instance, key, -1, NULL, 0);
- return -1;
- }
- memcpy(ro_data, msg->value.data, msg->value.len);
-
- node = ribmgr_ro_create(name, attr, ro_data, msg->value.len);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- cdap_reply_send(instance, key, -1, NULL, 0);
- free(ro_data);
- return -1;
- }
-
- pthread_mutex_lock(&rib.subs_lock);
- list_for_each(p, &rib.subs) {
- struct ro_sub * e = list_entry(p, struct ro_sub, next);
- len_s = strlen(e->name);
- len_n = strlen(name);
-
- if (len_n < len_s)
- continue;
-
- if (memcmp(name, e->name, len_s) == 0) {
- if (e->ops->ro_created == NULL)
- continue;
-
- ro_data = malloc(node->len);
- if (ro_data == NULL)
- continue;
-
- memcpy(ro_data, node->data, node->len);
- e->ops->ro_created(name, ro_data, node->len);
- }
- }
-
- pthread_mutex_unlock(&rib.subs_lock);
- pthread_mutex_unlock(&rib.ro_lock);
-
- if (cdap_reply_send(instance, key, ret, NULL, 0)) {
- LOG_ERR("Failed to send reply to create request.");
- return -1;
- }
-
- return 0;
-}
-
-static int ribmgr_cdap_delete(struct cdap * instance,
- cdap_key_t key,
- char * name)
-{
- struct list_head * p = NULL;
- size_t len_s;
- size_t len_n;
-
- pthread_mutex_lock(&rib.ro_lock);
-
- if (ribmgr_ro_delete(name)) {
- pthread_mutex_unlock(&rib.ro_lock);
- cdap_reply_send(instance, key, -1, NULL, 0);
- return -1;
- }
-
- pthread_mutex_lock(&rib.subs_lock);
-
- list_for_each(p, &rib.subs) {
- struct ro_sub * e = list_entry(p, struct ro_sub, next);
- len_s = strlen(e->name);
- len_n = strlen(name);
-
- if (len_n < len_s)
- continue;
-
- if (memcmp(name, e->name, len_s) == 0) {
- if (e->ops->ro_deleted == NULL)
- continue;
-
- e->ops->ro_deleted(name);
- }
- }
-
- pthread_mutex_unlock(&rib.subs_lock);
- pthread_mutex_unlock(&rib.ro_lock);
-
- if (cdap_reply_send(instance, key, 0, NULL, 0)) {
- LOG_ERR("Failed to send reply to create request.");
- return -1;
- }
-
- return 0;
-}
-
-static int ribmgr_cdap_write(struct cdap * instance,
- cdap_key_t key,
- char * name,
- ro_msg_t * msg,
- uint32_t flags)
-{
- int ret = 0;
- struct list_head * p = NULL;
- size_t len_s;
- size_t len_n;
- uint8_t * ro_data;
- struct rnode * node;
-
- (void) flags;
-
- pthread_mutex_lock(&rib.ro_lock);
-
- ro_data = malloc(msg->value.len);
- if (ro_data == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- cdap_reply_send(instance, key, -1, NULL, 0);
- return -1;
- }
- memcpy(ro_data, msg->value.data, msg->value.len);
-
- node = ribmgr_ro_write(name, msg->value.data, msg->value.len);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- free(ro_data);
- cdap_reply_send(instance, key, -1, NULL, 0);
- return -1;
- }
- node->seqno = msg->seqno;
-
- pthread_mutex_lock(&rib.subs_lock);
-
- list_for_each(p, &rib.subs) {
- struct ro_sub * e = list_entry(p, struct ro_sub, next);
- len_s = strlen(e->name);
- len_n = strlen(name);
-
- if (len_n < len_s)
- continue;
-
- if (memcmp(name, e->name, len_s) == 0) {
- if (e->ops->ro_updated == NULL)
- continue;
-
- ro_data = malloc(node->len);
- if (ro_data == NULL)
- continue;
-
- memcpy(ro_data, node->data, node->len);
- e->ops->ro_updated(name, ro_data, node->len);
- }
- }
-
- pthread_mutex_unlock(&rib.subs_lock);
- pthread_mutex_unlock(&rib.ro_lock);
-
- if (cdap_reply_send(instance, key, ret, NULL, 0)) {
- LOG_ERR("Failed to send reply to write request.");
- return -1;
- }
+ flow_set_t * fs;
+ fqueue_t * fq;
+ struct gam * gam;
+} ribmgr;
- return 0;
-}
-
-static int ribmgr_enrol_sync(struct cdap * instance, struct rnode * node)
-{
- int ret = 0;
-
- if (node != NULL) {
- if (node->attr.enrol_sync == true) {
- ro_msg_t msg = RO_MSG__INIT;
-
- if (ro_msg_create(node, &msg)) {
- LOG_ERR("Failed to create RO msg.");
- return -1;
- }
-
- LOG_DBG("Syncing RO with name %s.", node->full_name);
-
- if (write_ro_msg(instance, &msg,
- node->full_name, CDAP_CREATE)) {
- LOG_ERR("Failed to send RO msg.");
- return -1;
- }
- }
-
- ret = ribmgr_enrol_sync(instance, node->child);
- if (ret == 0)
- ret = ribmgr_enrol_sync(instance, node->sibling);
- }
-
- return ret;
-}
-
-static int ribmgr_cdap_start(struct cdap * instance,
- cdap_key_t key,
- char * name)
-{
- if (strcmp(name, ENROLLMENT) == 0) {
- LOG_DBG("New enrollment request.");
-
- if (cdap_reply_send(instance, key, 0, NULL, 0)) {
- LOG_ERR("Failed to send reply to enrollment request.");
- return -1;
- }
-
- /* Loop through rtree and send correct objects. */
- LOG_DBG("Sending ROs that need to be sent on enrolment...");
-
- pthread_mutex_lock(&rib.ro_lock);
- if (ribmgr_enrol_sync(instance, rib.root->child)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to sync part of the RIB.");
- return -1;
- }
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- LOG_DBGF("Sending stop enrollment...");
-
- key = cdap_request_send(instance, CDAP_STOP, ENROLLMENT,
- NULL, 0, 0);
- if (key < 0) {
- LOG_ERR("Failed to send stop of enrollment.");
- return -1;
- }
-
- if (cdap_reply_wait(instance, key, NULL, NULL)) {
- LOG_ERR("Remote failed to complete enrollment.");
- return -1;
- }
- } else {
- LOG_WARN("Request to start unknown operation.");
- if (cdap_reply_send(instance, key, -1, NULL, 0))
- LOG_ERR("Failed to send negative reply.");
- }
-
- return 0;
-}
-
-static int ribmgr_cdap_stop(struct cdap * instance, cdap_key_t key, char * name)
-{
- int ret = 0;
-
- if (strcmp(name, ENROLLMENT) == 0) {
- LOG_DBG("Stop enrollment received.");
- /* FIXME: don't use states to match start to stop. */
- ribmgr_set_state(RIBMGR_OPERATIONAL);
- } else {
- ret = -1;
- }
-
- if (cdap_reply_send(instance, key, ret, NULL, 0)) {
- LOG_ERR("Failed to send reply to stop request.");
- return -1;
- }
-
- return 0;
-}
-
-static void ro_id_delete(void * o)
-{
- struct ro_id * ro_id = *((struct ro_id **) o);
-
- pthread_mutex_lock(&rib.ro_ids_lock);
- list_del(&ro_id->next);
- free(ro_id->full_name);
- free(ro_id);
- pthread_mutex_unlock(&rib.ro_ids_lock);
-}
-
-static int ro_id_create(char * name, ro_msg_t * msg)
-{
- struct ro_id * tmp;
-
- tmp = malloc(sizeof(*tmp));
- if (tmp == NULL)
- return -ENOMEM;
-
- tmp->seqno = msg->seqno;
- tmp->full_name = strdup(name);
- list_head_init(&tmp->next);
-
- if (tmp->full_name == NULL) {
- free(tmp);
- return -ENOMEM;
- }
-
- pthread_mutex_lock(&rib.ro_ids_lock);
- list_add(&tmp->next, &rib.ro_ids);
-
- if (timerwheel_add(rib.wheel, ro_id_delete,
- &tmp, sizeof(tmp), RO_ID_TIMEOUT)) {
- LOG_ERR("Failed to add item to timerwheel.");
- pthread_mutex_unlock(&rib.ro_ids_lock);
- free(tmp->full_name);
- free(tmp);
- return -1;
- }
- pthread_mutex_unlock(&rib.ro_ids_lock);
-
- return 0;
-}
-
-static void * cdap_req_handler(void * o)
-{
- struct cdap * instance = (struct cdap *) o;
- enum cdap_opcode opcode;
- char * name;
- uint8_t * data;
- size_t len;
- uint32_t flags;
- ro_msg_t * msg;
- struct list_head * p = NULL;
-
- assert(instance);
-
- while (true) {
- cdap_key_t key = cdap_request_wait(instance,
- &opcode,
- &name,
- &data,
- &len,
- &flags);
- assert(key >= 0);
-
- if (opcode == CDAP_START) {
- if (ribmgr_cdap_start(instance, key, name))
- LOG_WARN("CDAP start failed.");
- free(name);
- continue;
- }
- else if (opcode == CDAP_STOP) {
- if (ribmgr_cdap_stop(instance, key, name))
- LOG_WARN("CDAP stop failed.");
- free(name);
- continue;
- }
-
- assert(len > 0);
-
- msg = ro_msg__unpack(NULL, len, data);
- if (msg == NULL) {
- cdap_reply_send(instance, key, -1, NULL, 0);
- LOG_WARN("Failed to unpack RO message");
- free(data);
- continue;
- }
-
- pthread_mutex_lock(&rib.ro_ids_lock);
- list_for_each(p, &rib.ro_ids) {
- struct ro_id * e = list_entry(p, struct ro_id, next);
-
- if (strcmp(e->full_name, name) == 0 &&
- e->seqno == msg->seqno) {
- pthread_mutex_unlock(&rib.ro_ids_lock);
- ro_msg__free_unpacked(msg, NULL);
- cdap_reply_send(instance, key, 0, NULL, 0);
- LOG_DBG("Already received this RO.");
- free(name);
- continue;
- }
- }
- pthread_mutex_unlock(&rib.ro_ids_lock);
-
- if (opcode == CDAP_CREATE) {
- if (ribmgr_cdap_create(instance, key, name, msg)) {
- LOG_WARN("CDAP create failed.");
- ro_msg__free_unpacked(msg, NULL);
- free(name);
- continue;
- }
- } else if (opcode == CDAP_WRITE) {
- if (ribmgr_cdap_write(instance, key, name,
- msg, flags)) {
- LOG_WARN("CDAP write failed.");
- ro_msg__free_unpacked(msg, NULL);
- free(name);
- continue;
- }
- } else if (opcode == CDAP_DELETE) {
- if (ribmgr_cdap_delete(instance, key, name)) {
- LOG_WARN("CDAP delete failed.");
- ro_msg__free_unpacked(msg, NULL);
- free(name);
- continue;
- }
- } else {
- LOG_INFO("Unsupported opcode received.");
- ro_msg__free_unpacked(msg, NULL);
- cdap_reply_send(instance, key, -1, NULL, 0);
- free(name);
- continue;
- }
-
- if (ro_id_create(name, msg)) {
- LOG_WARN("Failed to create RO id.");
- ro_msg__free_unpacked(msg, NULL);
- free(name);
- continue;
- }
-
- if (msg->recv_set == ALL_MEMBERS) {
- pthread_rwlock_rdlock(&rib.flows_lock);
- list_for_each(p, &rib.flows) {
- struct mgmt_flow * e =
- list_entry(p, struct mgmt_flow, next);
-
- /* Don't send it back. */
- if (e->instance == instance)
- continue;
-
- if (write_ro_msg(e->instance, msg,
- name, opcode))
- LOG_WARN("Failed to send to neighbor.");
- }
- pthread_rwlock_unlock(&rib.flows_lock);
- }
-
- free(name);
- ro_msg__free_unpacked(msg, NULL);
- }
- return (void *) 0;
-}
-
-static int ribmgr_add_flow(int fd)
-{
- struct cdap * instance = NULL;
- struct mgmt_flow * flow;
-
- flow = malloc(sizeof(*flow));
- if (flow == NULL)
- return -ENOMEM;
-
- instance = cdap_create(fd);
- if (instance == NULL) {
- LOG_ERR("Failed to create CDAP instance");
- free(flow);
- return -1;
- }
-
- list_head_init(&flow->next);
- flow->instance = instance;
- flow->fd = fd;
-
- if (pthread_create(&flow->handler, NULL,
- cdap_req_handler, instance)) {
- LOG_ERR("Failed to start handler thread for mgt flow.");
- free(flow);
- return -1;
- }
-
- pthread_rwlock_wrlock(&rib.flows_lock);
-
- list_add(&flow->next, &rib.flows);
-
- pthread_rwlock_unlock(&rib.flows_lock);
-
- return 0;
-}
-
-int ribmgr_remove_flow(int fd)
+int ribmgr_init(void)
{
- struct list_head * pos, * n = NULL;
-
- pthread_rwlock_wrlock(&rib.flows_lock);
- list_for_each_safe(pos, n, &rib.flows) {
- struct mgmt_flow * flow =
- list_entry(pos, struct mgmt_flow, next);
- if (flow->fd == fd) {
- pthread_cancel(flow->handler);
- if (cdap_destroy(flow->instance))
- LOG_ERR("Failed to destroy CDAP instance.");
- list_del(&flow->next);
- pthread_rwlock_unlock(&rib.flows_lock);
- free(flow);
- return 0;
- }
- }
- pthread_rwlock_unlock(&rib.flows_lock);
-
- return -1;
-}
-
-/* FIXME: do this in a topologymanager instance */
-int ribmgr_add_nm1_flow(int fd)
-{
- if (flow_alloc_resp(fd, 0) < 0) {
- LOG_ERR("Could not respond to new flow.");
- return -1;
- }
-
- return ribmgr_add_flow(fd);
-}
-
-int ribmgr_nm1_mgt_flow(char * dst_name)
-{
- int fd;
- int result;
-
- /* FIXME: Request retransmission. */
- fd = flow_alloc(dst_name, MGMT_AE, NULL);
- if (fd < 0) {
- LOG_ERR("Failed to allocate flow to %s.", dst_name);
- return -1;
- }
-
- result = flow_alloc_res(fd);
- if (result < 0) {
- LOG_ERR("Result of flow allocation to %s is %d.",
- dst_name, result);
- flow_dealloc(fd);
- return -1;
- }
+ enum pol_cacep pc;
+ enum pol_gam pg;
- if (ribmgr_add_flow(fd)) {
- LOG_ERR("Failed to add file descriptor.");
- flow_dealloc(fd);
+ if (rib_read(BOOT_PATH "/rm/gam/type", &pg, sizeof(pg))
+ != sizeof(pg)) {
+ LOG_ERR("Failed to read policy for ribmgr gam.");
return -1;
}
- return fd;
-}
-
-int ribmgr_bootstrap(struct dif_config * conf)
-{
- static_info_msg_t stat_info = STATIC_INFO_MSG__INIT;
- uint8_t * data = NULL;
- size_t len = 0;
- struct ro_attr attr;
-
- ro_attr_init(&attr);
- attr.enrol_sync = true;
-
- if (ribmgr_ro_create(RIBMGR_PREFIX, attr, NULL, 0) == NULL) {
- LOG_ERR("Failed to create RIBMGR RO.");
+ if (rib_read(BOOT_PATH "/rm/gam/cacep", &pc, sizeof(pc))
+ != sizeof(pc)) {
+ LOG_ERR("Failed to read CACEP policy for ribmgr gam.");
return -1;
}
- stat_info.addr_size = rib.dtc.addr_size = conf->addr_size;
- stat_info.cep_id_size = rib.dtc.cep_id_size = conf->cep_id_size;
- stat_info.pdu_length_size = rib.dtc.pdu_length_size
- = conf->pdu_length_size;
- stat_info.seqno_size = rib.dtc.seqno_size = conf->seqno_size;
- stat_info.has_ttl = rib.dtc.has_ttl = conf->has_ttl;
- stat_info.has_chk = rib.dtc.has_chk = conf->has_chk;
- stat_info.min_pdu_size = rib.dtc.min_pdu_size = conf->min_pdu_size;
- stat_info.max_pdu_size = rib.dtc.max_pdu_size = conf->max_pdu_size;
- stat_info.addr_auth_type = rib.addr_auth_type = conf->addr_auth_type;
- stat_info.dt_gam_type = rib.dt_gam_type = conf->dt_gam_type;
+ /* FIXME: Implement cacep policies */
+ (void) pc;
- len = static_info_msg__get_packed_size(&stat_info);
- if (len == 0) {
- LOG_ERR("Failed to get size of static information.");
- ribmgr_ro_delete(RIBMGR_PREFIX);
+ ribmgr.gam = gam_create(pg, MGMT_AE);
+ if (ribmgr.gam == NULL) {
+ LOG_ERR("Failed to create gam.");
return -1;
}
- data = malloc(len);
- if (data == NULL) {
- LOG_ERR("Failed to allocate memory.");
- ribmgr_ro_delete(RIBMGR_PREFIX);
+ ribmgr.fs = flow_set_create();
+ if (ribmgr.fs == NULL) {
+ LOG_ERR("Failed to create flow set.");
+ gam_destroy(ribmgr.gam);
return -1;
}
- static_info_msg__pack(&stat_info, data);
-
- if (ribmgr_ro_create(RIBMGR_PREFIX STAT_INFO,
- attr, data, len) == NULL) {
- LOG_ERR("Failed to create static info RO.");
- free(data);
- ribmgr_ro_delete(RIBMGR_PREFIX);
+ ribmgr.fq = fqueue_create();
+ if (ribmgr.fq == NULL) {
+ LOG_ERR("Failed to create fq.");
+ flow_set_destroy(ribmgr.fs);
+ gam_destroy(ribmgr.gam);
return -1;
}
- if (dir_init()) {
- LOG_ERR("Failed to init directory");
- ribmgr_ro_delete(RIBMGR_PREFIX STAT_INFO);
- ribmgr_ro_delete(RIBMGR_PREFIX);
- return -1;
- }
-
- LOG_DBG("Bootstrapped RIB Manager.");
-
return 0;
}
-int ribmgr_enrol()
+void ribmgr_fini(void)
{
- struct cdap * instance = NULL;
- struct mgmt_flow * flow;
- cdap_key_t key;
- int ret;
- struct timespec timeout = {(ENROLL_TIMEOUT / 1000),
- (ENROLL_TIMEOUT % 1000) * MILLION};
-
- pthread_rwlock_wrlock(&rib.flows_lock);
-
- assert(!list_is_empty(&rib.flows));
-
- flow = list_first_entry((&rib.flows), struct mgmt_flow, next);
- instance = flow->instance;
-
- key = cdap_request_send(instance, CDAP_START, ENROLLMENT, NULL, 0, 0);
- if (key < 0) {
- pthread_rwlock_unlock(&rib.flows_lock);
- LOG_ERR("Failed to start enrollment.");
- return -1;
- }
-
- ret = cdap_reply_wait(instance, key, NULL, NULL);
- if (ret) {
- pthread_rwlock_unlock(&rib.flows_lock);
- LOG_ERR("Failed to enroll: %d.", ret);
- return -1;
- }
-
- pthread_rwlock_unlock(&rib.flows_lock);
-
- if (ribmgr_wait_state(RIBMGR_OPERATIONAL, &timeout) == -ETIMEDOUT)
- LOG_ERR("Enrollment of RIB timed out.");
-
- if (ribmgr_get_state() != RIBMGR_OPERATIONAL)
- return -1;
-
- return 0;
+ flow_set_destroy(ribmgr.fs);
+ fqueue_destroy(ribmgr.fq);
+ gam_destroy(ribmgr.gam);
}
-int ribmgr_start_policies(void)
+int ribmgr_flow_arr(int fd,
+ qosspec_t qs)
{
- rib.addr_auth = addr_auth_create(rib.addr_auth_type);
- if (rib.addr_auth == NULL) {
- LOG_ERR("Failed to create address authority.");
- return -1;
- }
-
- rib.address = rib.addr_auth->address();
- LOG_DBG("IPCP has address %lu.", (unsigned long) rib.address);
+ assert(ribmgr.gam);
- return 0;
-}
-
-struct dt_const * ribmgr_dt_const(void)
-{
- return &(rib.dtc);
-}
-
-uint64_t ribmgr_address(void)
-{
- return rib.address;
-}
-
-enum pol_gam ribmgr_dt_gam(void)
-{
- return rib.dt_gam_type;
-}
-
-static int send_neighbors_ro(char * name, ro_msg_t * msg, enum cdap_opcode code)
-{
- struct list_head * p = NULL;
-
- pthread_rwlock_rdlock(&rib.flows_lock);
-
- list_for_each(p, &rib.flows) {
- struct mgmt_flow * e = list_entry(p, struct mgmt_flow, next);
- if (write_ro_msg(e->instance, msg, name, code)) {
- pthread_rwlock_unlock(&rib.flows_lock);
- LOG_ERR("Failed to send to a neighbor.");
- return -1;
- }
- }
-
- pthread_rwlock_unlock(&rib.flows_lock);
-
- return 0;
-}
-
-int ro_create(const char * name,
- struct ro_attr * attr,
- uint8_t * data,
- size_t len)
-{
- struct rnode * node;
- ro_msg_t msg = RO_MSG__INIT;
- struct ro_attr rattr;
-
- assert(name);
-
- if (attr == NULL) {
- ro_attr_init(&rattr);
- attr = &rattr;
- }
-
- pthread_mutex_lock(&rib.ro_lock);
-
- node = ribmgr_ro_create(name, *attr, data, len);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
+ if (gam_flow_arr(ribmgr.gam, fd, qs))
return -1;
- }
-
- if (node->attr.recv_set == NO_SYNC) {
- pthread_mutex_unlock(&rib.ro_lock);
- return 0;
- }
-
- if (ro_msg_create(node, &msg)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to create RO msg.");
- return -1;
- }
-
- if (send_neighbors_ro(node->full_name, &msg, CDAP_CREATE)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to send to neighbors.");
- return -1;
- }
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- return 0;
-}
-
-int ro_attr_init(struct ro_attr * attr)
-{
- assert(attr);
-
- attr->enrol_sync = false;
- attr->recv_set = NO_SYNC;
- attr->expiry.tv_sec = 0;
- attr->expiry.tv_nsec = 0;
return 0;
}
-int ro_delete(const char * name)
+int ribmgr_disseminate(char * path,
+ enum diss_target target,
+ enum diss_freq freq,
+ size_t delay)
{
- struct rnode * node;
- ro_msg_t msg = RO_MSG__INIT;
-
- assert(name);
-
- pthread_mutex_lock(&rib.ro_lock);
-
- node = find_rnode_by_name(name);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to sync RO.");
- return -1;
- }
-
- if (node->attr.recv_set != NO_SYNC) {
- if (ro_msg_create(node, &msg)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to create RO msg.");
- return -1;
- }
-
- if (send_neighbors_ro(node->full_name, &msg, CDAP_DELETE)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to send to neighbors.");
- return -1;
- }
- }
-
- if (ribmgr_ro_delete(name)) {
- pthread_mutex_unlock(&rib.ro_lock);
- return -1;
- }
-
- pthread_mutex_unlock(&rib.ro_lock);
+ (void) path;
+ (void) target;
+ (void) freq;
+ (void) delay;
return 0;
}
-
-int ro_write(const char * name, uint8_t * data, size_t len)
-{
- struct rnode * node;
- ro_msg_t msg = RO_MSG__INIT;
-
- assert(name);
- assert(data);
-
- pthread_mutex_lock(&rib.ro_lock);
-
- node = ribmgr_ro_write(name, data, len);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to create RO.");
- return -1;
- }
- node->seqno++;
-
- if (node->attr.recv_set == NO_SYNC) {
- pthread_mutex_unlock(&rib.ro_lock);
- return 0;
- }
-
- if (ro_msg_create(node, &msg)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to create RO msg.");
- return -1;
- }
-
- if (send_neighbors_ro(node->full_name, &msg, CDAP_WRITE)) {
- pthread_mutex_unlock(&rib.ro_lock);
- LOG_ERR("Failed to send to neighbors.");
- return -1;
- }
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- return 0;
-}
-
-ssize_t ro_read(const char * name, uint8_t ** data)
-{
- struct rnode * node;
- ssize_t len;
-
- assert(name);
- assert(data);
-
- pthread_mutex_lock(&rib.ro_lock);
-
- node = find_rnode_by_name(name);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- return -1;
- }
-
- *data = malloc(node->len);
- if (*data == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- return -1;
- }
-
- memcpy(*data, node->data, node->len);
- len = node->len;
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- return len;
-}
-
-ssize_t ro_children(const char * name, char *** children)
-{
- struct rnode * node;
- struct rnode * child;
- ssize_t len = 0;
- int i = 0;
-
- assert(name);
- assert(children);
-
- pthread_mutex_lock(&rib.ro_lock);
-
- node = find_rnode_by_name(name);
- if (node == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- return -1;
- }
-
- child = node->child;
- while (child != NULL) {
- len++;
- child = child->sibling;
- }
- child = node->child;
-
- *children = malloc(len);
- if (*children == NULL) {
- pthread_mutex_unlock(&rib.ro_lock);
- return -1;
- }
-
- for (i = 0; i < len; i++) {
- (*children)[i] = strdup(child->name);
- if ((*children)[i] == NULL) {
- while (i >= 0) {
- free((*children)[i]);
- i--;
- }
- free(*children);
- pthread_mutex_unlock(&rib.ro_lock);
- return -1;
- }
- child = child->sibling;
- }
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- return len;
-}
-
-bool ro_exists(const char * name)
-{
- struct rnode * node;
- bool found;
-
- assert(name);
-
- pthread_mutex_lock(&rib.ro_lock);
-
- node = find_rnode_by_name(name);
- found = (node == NULL) ? false : true;
-
- pthread_mutex_unlock(&rib.ro_lock);
-
- return found;
-}
-
-int ro_subscribe(const char * name, struct ro_sub_ops * ops)
-{
- struct ro_sub * sub;
- int sid;
-
- assert(name);
- assert(ops);
-
- sub = malloc(sizeof(*sub));
- if (sub == NULL)
- return -ENOMEM;
-
- list_head_init(&sub->next);
-
- sub->name = strdup(name);
- if (sub->name == NULL) {
- free(sub);
- return -1;
- }
-
- sub->ops = ops;
-
- pthread_mutex_lock(&rib.subs_lock);
-
- sid = bmp_allocate(rib.sids);
- if (sid < 0) {
- pthread_mutex_unlock(&rib.subs_lock);
- free(sub->name);
- free(sub);
- LOG_ERR("Failed to get sub id.");
- return -1;
- }
- sub->sid = sid;
-
- list_add(&sub->next, &rib.subs);
-
- pthread_mutex_unlock(&rib.subs_lock);
-
- return sid;
-}
-
-int ro_unsubscribe(int sid)
-{
- struct list_head * pos = NULL;
- struct list_head * n = NULL;
-
- pthread_mutex_lock(&rib.subs_lock);
-
- list_for_each_safe(pos, n, &(rib.subs)) {
- struct ro_sub * e = list_entry(pos, struct ro_sub, next);
- if (sid == e->sid) {
- bmp_release(rib.sids, sid);
- list_del(&e->next);
- free(e->name);
- free(e);
- pthread_mutex_unlock(&rib.subs_lock);
- return 0;
- }
- }
-
- pthread_mutex_unlock(&rib.subs_lock);
-
- LOG_ERR("No such subscription found.");
-
- return -1;
-}
diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h
index 22212de9..12f407ab 100644
--- a/src/ipcpd/normal/ribmgr.h
+++ b/src/ipcpd/normal/ribmgr.h
@@ -24,27 +24,29 @@
#include <ouroboros/irm_config.h>
#include <ouroboros/utils.h>
+#include <ouroboros/qos.h>
-#include "dt_const.h"
+enum diss_target {
+ NONE = 0,
+ NEIGHBORS,
+ ALL_MEMBERS
+};
-int ribmgr_init(void);
+enum diss_freq {
+ SINGLE = 0,
+ PERIODIC
+};
-int ribmgr_fini(void);
+int ribmgr_init(void);
-int ribmgr_add_nm1_flow(int fd);
+void ribmgr_fini(void);
-int ribmgr_nm1_mgt_flow(char * dst_name);
+int ribmgr_flow_arr(int fd,
+ qosspec_t qs);
-int ribmgr_bootstrap(struct dif_config * conf);
-
-int ribmgr_enrol(void);
-
-int ribmgr_start_policies(void);
-
-struct dt_const * ribmgr_dt_const(void);
-
-uint64_t ribmgr_address(void);
-
-enum pol_gam ribmgr_dt_gam(void);
+int ribmgr_disseminate(char * path,
+ enum diss_target target,
+ enum diss_freq freq,
+ size_t delay);
#endif /* OUROBOROS_IPCPD_NORMAL_RIBMGR_H */
diff --git a/src/ipcpd/normal/ro.h b/src/ipcpd/normal/ro.h
deleted file mode 100644
index 6fda2adf..00000000
--- a/src/ipcpd/normal/ro.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * RIB objects
- *
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
- *
- * 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_RO_H
-#define OUROBOROS_IPCPD_NORMAL_RO_H
-
-#include <stdbool.h>
-#include <time.h>
-#include <stdint.h>
-
-enum ro_recv_set {
- NO_SYNC = 0,
- NEIGHBORS,
- ALL_MEMBERS
-};
-
-struct ro_attr {
- bool enrol_sync;
- enum ro_recv_set recv_set;
- struct timespec expiry;
-};
-
-/* All RIB-objects have a pathname, separated by a slash. */
-/* Takes ownership of the data */
-int ro_create(const char * name,
- struct ro_attr * attr,
- uint8_t * data,
- size_t len);
-
-int ro_attr_init(struct ro_attr * attr);
-
-int ro_delete(const char * name);
-
-int ro_write(const char * name,
- uint8_t * data,
- size_t len);
-
-/* Reader takes ownership of data */
-ssize_t ro_read(const char * name,
- uint8_t ** data);
-
-ssize_t ro_children(const char * name,
- char *** children);
-
-bool ro_exists(const char * name);
-
-/* Callback passes ownership of the data */
-struct ro_sub_ops {
- void (* ro_created)(const char * name,
- uint8_t * data,
- size_t len);
- void (* ro_updated)(const char * name,
- uint8_t * data,
- size_t len);
- void (* ro_deleted)(const char * name);
-};
-
-/* Returns subscriber-id */
-int ro_subscribe(const char * name,
- struct ro_sub_ops * ops);
-
-int ro_unsubscribe(int sid);
-
-#endif /* OUROBOROS_IPCPD_NORMAL_RO_H */
diff --git a/src/ipcpd/normal/shm_pci.c b/src/ipcpd/normal/shm_pci.c
index 4d66bf06..1c2cee54 100644
--- a/src/ipcpd/normal/shm_pci.c
+++ b/src/ipcpd/normal/shm_pci.c
@@ -20,18 +20,17 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define OUROBOROS_PREFIX "ipcpd/shm_pci"
-
-#include <ouroboros/logs.h>
+#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/crc32.h>
+#include <ouroboros/rib.h>
+
+#include "shm_pci.h"
+#include "dt_const.h"
#include <stdlib.h>
#include <string.h>
-
-#include "shm_pci.h"
-#include "frct.h"
-#include "ribmgr.h"
+#include <assert.h>
#define PDU_TYPE_SIZE 1
#define QOS_ID_SIZE 1
@@ -39,73 +38,124 @@
#define TTL_SIZE 1
#define CHK_SIZE 4
-static size_t shm_pci_head_size(struct dt_const * dtc)
-{
- size_t len = 0;
+#define BOOT_PATH "/" BOOT_NAME
- len = PDU_TYPE_SIZE + dtc->addr_size * 2 + dtc->cep_id_size * 2
- + dtc->pdu_length_size + dtc->seqno_size + QOS_ID_SIZE;
+struct {
+ struct dt_const dtc;
+ size_t head_size;
+ size_t tail_size;
- if (dtc->has_ttl)
- len += TTL_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;
- return len;
-}
-static size_t shm_pci_tail_size(struct dt_const * dtc)
+static void ser_pci_head(uint8_t * head,
+ struct pci * pci)
{
- return dtc->has_chk ? CHK_SIZE : 0;
+ 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);
}
-static void ser_pci_head(uint8_t * head,
- struct pci * pci,
- struct dt_const * dtc)
+int shm_pci_init(void)
{
- int offset = 0;
- uint8_t ttl = DEFAULT_TTL;
+ /* 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)) ||
+ rib_read(BOOT_PATH "/dt/const/cep_id_size",
+ &pci_info.dtc.cep_id_size,
+ sizeof(pci_info.dtc.cep_id_size)) ||
+ rib_read(BOOT_PATH "/dt/const/seqno_size",
+ &pci_info.dtc.seqno_size,
+ sizeof(pci_info.dtc.seqno_size)) ||
+ rib_read(BOOT_PATH "/dt/const/has_ttl",
+ &pci_info.dtc.has_ttl,
+ sizeof(pci_info.dtc.has_ttl)) ||
+ rib_read(BOOT_PATH "/dt/const/has_chk",
+ &pci_info.dtc.has_chk,
+ sizeof(pci_info.dtc.has_chk)) ||
+ rib_read(BOOT_PATH "/dt/const/min_pdu_size",
+ &pci_info.dtc.min_pdu_size,
+ sizeof(pci_info.dtc.min_pdu_size)) ||
+ rib_read(BOOT_PATH "/dt/const/max_pdu_size",
+ &pci_info.dtc.max_pdu_size,
+ sizeof(pci_info.dtc.max_pdu_size)))
+ return -1;
- memcpy(head, &pci->pdu_type, PDU_TYPE_SIZE);
- offset += PDU_TYPE_SIZE;
- memcpy(head + offset, &pci->dst_addr, dtc->addr_size);
- offset += dtc->addr_size;
- memcpy(head + offset, &pci->src_addr, dtc->addr_size);
- offset += dtc->addr_size;
- memcpy(head + offset, &pci->dst_cep_id, dtc->cep_id_size);
- offset += dtc->cep_id_size;
- memcpy(head + offset, &pci->src_cep_id, dtc->cep_id_size);
- offset += dtc->cep_id_size;
- memcpy(head + offset, &pci->pdu_length, dtc->pdu_length_size);
- offset += dtc->pdu_length_size;
- memcpy(head + offset, &pci->seqno, dtc->seqno_size);
- offset += dtc->seqno_size;
- memcpy(head + offset, &pci->qos_id, QOS_ID_SIZE);
- offset += QOS_ID_SIZE;
- if (dtc->has_ttl)
- memcpy(head + offset, &ttl, TTL_SIZE);
+ 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.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)
+ struct pci * pci)
{
uint8_t * head;
uint8_t * tail;
- struct dt_const * dtc;
- dtc = ribmgr_dt_const();
- if (dtc == NULL)
- return -1;
+ assert(sdb);
+ assert(pci);
- head = shm_du_buff_head_alloc(sdb, shm_pci_head_size(dtc));
+ head = shm_du_buff_head_alloc(sdb, pci_info.head_size);
if (head == NULL)
- return -1;
+ return -EPERM;
- ser_pci_head(head, pci, dtc);
+ ser_pci_head(head, pci);
- if (dtc->has_chk) {
- tail = shm_du_buff_tail_alloc(sdb, shm_pci_tail_size(dtc));
+ 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, shm_pci_tail_size(dtc));
- return -1;
+ shm_du_buff_head_release(sdb, pci_info.head_size);
+ return -EPERM;
}
crc32((uint32_t *) tail, head, tail - head);
@@ -118,22 +168,16 @@ buffer_t * shm_pci_ser_buf(buffer_t * buf,
struct pci * pci)
{
buffer_t * buffer;
- struct dt_const * dtc;
- if (buf == NULL || pci == NULL)
- return NULL;
-
- dtc = ribmgr_dt_const();
- if (dtc == NULL)
- return NULL;
+ assert(buf);
+ assert(pci);
buffer = malloc(sizeof(*buffer));
if (buffer == NULL)
return NULL;
- buffer->len = buf->len +
- shm_pci_head_size(dtc) +
- shm_pci_tail_size(dtc);
+ buffer->len = buf->len + pci_info.head_size +
+ pci_info.tail_size;
buffer->data = malloc(buffer->len);
if (buffer->data == NULL) {
@@ -141,118 +185,59 @@ buffer_t * shm_pci_ser_buf(buffer_t * buf,
return NULL;
}
- ser_pci_head(buffer->data, pci, dtc);
- memcpy(buffer->data + shm_pci_head_size(dtc),
+ ser_pci_head(buffer->data, pci);
+ memcpy(buffer->data + pci_info.head_size,
buf->data, buf->len);
free(buf->data);
- if (dtc->has_chk)
- crc32((uint32_t *) buffer->data +
- shm_pci_head_size(dtc) + buf->len,
+ if (pci_info.dtc.has_chk)
+ crc32((uint32_t *) (buffer->data +
+ pci_info.head_size + buf->len),
buffer->data,
- shm_pci_head_size(dtc) + buf->len);
+ pci_info.head_size + buf->len);
return buffer;
}
-struct pci * shm_pci_des(struct shm_du_buff * sdb)
+void shm_pci_des(struct shm_du_buff * sdb,
+ struct pci * pci)
{
uint8_t * head;
- struct pci * pci;
- int offset = 0;
- struct dt_const * dtc;
- if (sdb == NULL)
- return NULL;
+ assert(sdb);
+ assert(pci);
head = shm_du_buff_head(sdb);
- dtc = ribmgr_dt_const();
- if (dtc == NULL)
- return NULL;
-
- pci = malloc(sizeof(*pci));
- if (pci == NULL)
- return NULL;
-
+ /* FIXME: Add check and operations for Big Endian machines */
memcpy(&pci->pdu_type, head, PDU_TYPE_SIZE);
- offset += PDU_TYPE_SIZE;
- memcpy(&pci->dst_addr, head + offset, dtc->addr_size);
- offset += dtc->addr_size;
- memcpy(&pci->src_addr, head + offset, dtc->addr_size);
- offset += dtc->addr_size;
- memcpy(&pci->dst_cep_id, head + offset, dtc->cep_id_size);
- offset += dtc->cep_id_size;
- memcpy(&pci->src_cep_id, head + offset, dtc->cep_id_size);
- offset += dtc->cep_id_size;
- memcpy(&pci->pdu_length, head + offset, dtc->pdu_length_size);
- offset += dtc->pdu_length_size;
- memcpy(&pci->seqno, head + offset, dtc->seqno_size);
- offset += dtc->seqno_size;
- memcpy(&pci->qos_id, head + offset, QOS_ID_SIZE);
- offset += QOS_ID_SIZE;
- if (dtc->has_ttl)
- memcpy(&pci->ttl, head + offset, TTL_SIZE);
-
- return pci;
-}
-
-int shm_pci_shrink(struct shm_du_buff * sdb)
-{
- struct dt_const * dtc;
-
- if (sdb == NULL)
- return -1;
-
- dtc = ribmgr_dt_const();
- if (dtc == NULL)
- return -1;
-
- if (shm_du_buff_head_release(sdb, shm_pci_head_size(dtc))) {
- LOG_ERR("Failed to shrink head.");
- return -1;
- }
-
- if (shm_du_buff_tail_release(sdb, shm_pci_tail_size(dtc))) {
- LOG_ERR("Failed to shrink tail.");
- return -1;
+ 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;
}
-
- return 0;
}
-int shm_pci_dec_ttl(struct shm_du_buff * sdb)
+void shm_pci_shrink(struct shm_du_buff * sdb)
{
- struct dt_const * dtc;
- size_t offset = 0;
- uint8_t * head;
- uint8_t * tail;
+ assert(sdb);
- dtc = ribmgr_dt_const();
- if (dtc == NULL)
- return -1;
-
- if (dtc->has_ttl == false)
- return 0;
-
- offset = shm_pci_head_size(dtc) - 1;
-
- head = shm_du_buff_head(sdb);
- if (head == NULL)
- return -1;
-
- head[offset]--;
-
- if (dtc->has_chk) {
- tail = shm_du_buff_tail(sdb);
- if (tail == NULL)
- return -1;
-
- tail -= CHK_SIZE;
-
- crc32((uint32_t *) tail, head, tail - head);
- }
-
- return 0;
+ 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
index c1d823bf..17ce5cdd 100644
--- a/src/ipcpd/normal/shm_pci.h
+++ b/src/ipcpd/normal/shm_pci.h
@@ -25,8 +25,7 @@
#include <ouroboros/shm_rdrbuff.h>
#include <ouroboros/utils.h>
-
-#include "dt_const.h"
+#include <ouroboros/qos.h>
#define PDU_TYPE_MGMT 0x40
#define PDU_TYPE_DTP 0x80
@@ -45,19 +44,21 @@ struct pci {
uint32_t pdu_length;
uint64_t seqno;
uint8_t ttl;
- uint8_t flags;
};
+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);
-struct pci * shm_pci_des(struct shm_du_buff * sdb);
-
-int shm_pci_shrink(struct shm_du_buff * sdb);
+void shm_pci_des(struct shm_du_buff * sdb,
+ struct pci * pci);
-int shm_pci_dec_ttl(struct shm_du_buff * sdb);
+void shm_pci_shrink(struct shm_du_buff * sdb);
#endif /* OUROBOROS_IPCPD_NORMAL_SHM_PCI_H */
diff --git a/src/ipcpd/normal/static_info.proto b/src/ipcpd/normal/static_info.proto
deleted file mode 100644
index bb6f8c4e..00000000
--- a/src/ipcpd/normal/static_info.proto
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Static information message
- *
- * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
- * Sander Vrijders <sander.vrijders@intec.ugent.be>
- *
- * 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.
- */
-
-syntax = "proto2";
-
-message static_info_msg {
- required uint32 addr_size = 1;
- required uint32 cep_id_size = 2;
- required uint32 pdu_length_size = 3;
- required uint32 seqno_size = 4;
- required bool has_ttl = 5;
- required bool has_chk = 6;
- required uint32 min_pdu_size = 7;
- required uint32 max_pdu_size = 8;
- required uint32 addr_auth_type = 9;
- required uint32 dt_gam_type = 10;
-} \ No newline at end of file