diff options
author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2017-02-06 16:05:44 +0100 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2017-02-06 20:04:34 +0100 |
commit | 373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7 (patch) | |
tree | 8711a4edbc2a6defaab63f0dcc2b0690252307b4 | |
parent | 4b11f952c521315883f64571e1790389e8d20f64 (diff) | |
download | ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.tar.gz ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.zip |
ipcpd, lib: Revise normal IPCP
This PR updates the normal IPCP to use the new RIB. The old ribmgr is
removed and replaced by a stub that needs to be implemented. All
components (dir, fmgr, frct) were adapted to the new RIB API. A lot
of functionality was moved outside of the ribmgr, such as the
addr_auth, which is now a component of the IPCP. The address is also
stored to the ipcpi struct. The irm tool has an option to set the gam
policy of the rib manager.
31 files changed, 1045 insertions, 2550 deletions
diff --git a/include/ouroboros/config.h.in b/include/ouroboros/config.h.in index 5597bb0b..b95fe927 100644 --- a/include/ouroboros/config.h.in +++ b/include/ouroboros/config.h.in @@ -47,7 +47,7 @@ #define SHM_RBUFF_PREFIX "/ouroboros.rbuff." #define SHM_FLOW_SET_PREFIX "/ouroboros.sets." #define IRMD_MAX_FLOWS 4096 -#define IRMD_THREADPOOL_SIZE 5 +#define IRMD_THREADPOOL_SIZE 16 #define IPCPD_THREADPOOL_SIZE 3 #define IPCPD_MAX_CONNS IRMD_MAX_FLOWS #define LOG_DIR "/@LOG_DIR@/" @@ -61,6 +61,11 @@ #define SOCKET_TIMEOUT 4000 #define CDAP_REPLY_TIMEOUT 1000 #define ENROLL_TIMEOUT 2000 +/* RIB configuration for normal */ #define RIB_MAX_PATH_LEN 256 +#define BOOT_NAME "boot" +#define MEMBERS_NAME "members" +#define DIF_NAME "dif_name" +#define DIR_NAME "directory" -#endif +#endif /* OUROBOROS_CONFIG */ diff --git a/include/ouroboros/irm_config.h b/include/ouroboros/irm_config.h index c4a81c23..2be4273e 100644 --- a/include/ouroboros/irm_config.h +++ b/include/ouroboros/irm_config.h @@ -47,6 +47,10 @@ enum pol_gam { COMPLETE = 0 }; +enum pol_cacep { + NO_AUTH = 0 +}; + struct dif_config { char * dif_name; enum ipcp_type type; @@ -57,7 +61,6 @@ struct dif_config { uint8_t addr_size; uint8_t cep_id_size; uint8_t pdu_length_size; - uint8_t qos_id_size; uint8_t seqno_size; bool has_ttl; @@ -68,6 +71,7 @@ struct dif_config { enum pol_addr_auth addr_auth_type; enum pol_gam dt_gam_type; + enum pol_gam rm_gam_type; }; /* Shim UDP */ struct { diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 2115f7c1..fe87fbd9 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -119,7 +119,6 @@ static void * ipcp_main_loop(void * o) conf.cep_id_size = conf_msg->cep_id_size; conf.pdu_length_size = conf_msg->pdu_length_size; - conf.qos_id_size = conf_msg->qos_id_size; conf.seqno_size = conf_msg->seqno_size; conf.has_ttl = conf_msg->has_ttl; conf.has_chk = conf_msg->has_chk; @@ -127,6 +126,7 @@ static void * ipcp_main_loop(void * o) conf.max_pdu_size = conf_msg->max_pdu_size; conf.addr_auth_type = conf_msg->addr_auth_type; conf.dt_gam_type = conf_msg->dt_gam_type; + conf.rm_gam_type = conf_msg->rm_gam_type; } if (conf_msg->ipcp_type == IPCP_SHIM_UDP) { conf.ip_addr = conf_msg->ip_addr; diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index a75186ba..8b590cc2 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -41,6 +41,8 @@ struct ipcp { int irmd_api; char * name; + uint64_t address; + struct ipcp_data * data; struct ipcp_ops * ops; int irmd_fd; 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..6b21cdbf 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; @@ -167,10 +164,10 @@ void * fmgr_nm1_sdu_reader(void * o) continue; } - 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->has_ttl) { if (pci->ttl == 0) { LOG_DBG("TTL was zero."); ipcp_flow_del(sdb); @@ -269,8 +266,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 +305,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 +339,7 @@ int fmgr_init() return 0; } -int fmgr_fini() +void fmgr_fini() { struct list_head * pos = NULL; struct list_head * n = NULL; @@ -359,8 +374,6 @@ int fmgr_fini() pthread_rwlock_destroy(&fmgr.np1_flows_lock); fmgr_destroy_flows(); - - return 0; } int fmgr_np1_alloc(int fd, @@ -371,27 +384,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); + + strcpy(path, "/" DIR_NAME); + + rib_path_append(path, dst_ap_name); - path = pathname_append(path, dst_ap_name); - if (path == NULL) { - pathname_destroy(path); + 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 +429,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 +442,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..735bdee1 100644 --- a/src/ipcpd/normal/shm_pci.c +++ b/src/ipcpd/normal/shm_pci.c @@ -20,91 +20,119 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define OUROBOROS_PREFIX "ipcpd/shm_pci" +#define OUROBOROS_PREFIX "shm-pci" +#include <ouroboros/config.h> #include <ouroboros/logs.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" - #define PDU_TYPE_SIZE 1 #define QOS_ID_SIZE 1 #define DEFAULT_TTL 60 #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; +} pci_info; - if (dtc->has_ttl) - len += TTL_SIZE; - return len; -} - -static size_t shm_pci_tail_size(struct dt_const * dtc) -{ - return dtc->has_chk ? CHK_SIZE : 0; -} - -static void ser_pci_head(uint8_t * head, - struct pci * pci, - struct dt_const * dtc) +static void ser_pci_head(uint8_t * head, + struct pci * pci) { int offset = 0; uint8_t ttl = DEFAULT_TTL; 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->dst_addr, pci_info.dtc.addr_size); + offset += pci_info.dtc.addr_size; + memcpy(head + offset, &pci->src_addr, pci_info.dtc.addr_size); + offset += pci_info.dtc.addr_size; + memcpy(head + offset, &pci->dst_cep_id, pci_info.dtc.cep_id_size); + offset += pci_info.dtc.cep_id_size; + memcpy(head + offset, &pci->src_cep_id, pci_info.dtc.cep_id_size); + offset += pci_info.dtc.cep_id_size; + memcpy(head + offset, &pci->pdu_length, pci_info.dtc.pdu_length_size); + offset += pci_info.dtc.pdu_length_size; + memcpy(head + offset, &pci->seqno, pci_info.dtc.seqno_size); + offset += pci_info.dtc.seqno_size; memcpy(head + offset, &pci->qos_id, QOS_ID_SIZE); offset += QOS_ID_SIZE; - if (dtc->has_ttl) + if (pci_info.dtc.has_ttl) memcpy(head + offset, &ttl, TTL_SIZE); } +int shm_pci_init(void) +{ + /* read dt constants from the RIB */ + if (rib_read(BOOT_PATH "/dt/const/addr_size", + &pci_info.dtc.addr_size, + sizeof(pci_info.dtc.addr_size)) || + 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; + + pci_info.head_size = PDU_TYPE_SIZE + pci_info.dtc.addr_size * 2 + + pci_info.dtc.cep_id_size * 2 + pci_info.dtc.pdu_length_size + + pci_info.dtc.seqno_size + QOS_ID_SIZE; + + if (pci_info.dtc.has_ttl) + pci_info.head_size += TTL_SIZE; + + pci_info.tail_size = pci_info.dtc.has_chk ? CHK_SIZE : 0; + + return 0; +} + +void shm_pci_fini(void) { + return ; +} + int shm_pci_ser(struct shm_du_buff * sdb, struct pci * pci) { uint8_t * head; uint8_t * tail; - struct dt_const * dtc; - dtc = ribmgr_dt_const(); - if (dtc == NULL) - return -1; - - 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; - 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)); + shm_du_buff_head_release(sdb, pci_info.head_size); return -1; } @@ -118,22 +146,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; - 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,17 +163,17 @@ 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; } @@ -161,38 +183,34 @@ struct pci * shm_pci_des(struct shm_du_buff * sdb) uint8_t * head; struct pci * pci; int offset = 0; - struct dt_const * dtc; if (sdb == NULL) return NULL; head = shm_du_buff_head(sdb); - dtc = ribmgr_dt_const(); - if (dtc == NULL) - return NULL; - pci = malloc(sizeof(*pci)); if (pci == NULL) return NULL; 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->dst_addr, head + offset, pci_info.dtc.addr_size); + offset += pci_info.dtc.addr_size; + memcpy(&pci->src_addr, head + offset, pci_info.dtc.addr_size); + offset += pci_info.dtc.addr_size; + memcpy(&pci->dst_cep_id, head + offset, pci_info.dtc.cep_id_size); + offset += pci_info.dtc.cep_id_size; + memcpy(&pci->src_cep_id, head + offset, pci_info.dtc.cep_id_size); + offset += pci_info.dtc.cep_id_size; + memcpy(&pci->pdu_length, head + offset, pci_info.dtc.pdu_length_size); + offset += pci_info.dtc.pdu_length_size; + memcpy(&pci->seqno, head + offset, pci_info.dtc.seqno_size); + offset += pci_info.dtc.seqno_size; memcpy(&pci->qos_id, head + offset, QOS_ID_SIZE); offset += QOS_ID_SIZE; - if (dtc->has_ttl) + pci->has_ttl = pci_info.dtc.has_ttl; + if (pci_info.dtc.has_ttl) memcpy(&pci->ttl, head + offset, TTL_SIZE); return pci; @@ -200,21 +218,15 @@ struct pci * shm_pci_des(struct shm_du_buff * sdb) 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))) { + if (shm_du_buff_head_release(sdb, pci_info.head_size)) { LOG_ERR("Failed to shrink head."); return -1; } - if (shm_du_buff_tail_release(sdb, shm_pci_tail_size(dtc))) { + if (shm_du_buff_tail_release(sdb, pci_info.tail_size)) { LOG_ERR("Failed to shrink tail."); return -1; } @@ -224,27 +236,19 @@ int shm_pci_shrink(struct shm_du_buff * sdb) int shm_pci_dec_ttl(struct shm_du_buff * sdb) { - struct dt_const * dtc; - size_t offset = 0; uint8_t * head; uint8_t * tail; - dtc = ribmgr_dt_const(); - if (dtc == NULL) - return -1; - - if (dtc->has_ttl == false) + if (pci_info.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]--; + head[pci_info.head_size - TTL_SIZE]--; - if (dtc->has_chk) { + if (pci_info.dtc.has_chk) { tail = shm_du_buff_tail(sdb); if (tail == NULL) return -1; diff --git a/src/ipcpd/normal/shm_pci.h b/src/ipcpd/normal/shm_pci.h index c1d823bf..9fe3d9aa 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,9 +44,14 @@ struct pci { uint32_t pdu_length; uint64_t seqno; uint8_t ttl; - uint8_t flags; + /* FIXME: Deprecate this and the dec_ttl call */ + int has_ttl; }; +int shm_pci_init(void); + +void shm_pci_fini(void); + int shm_pci_ser(struct shm_du_buff * sdb, struct pci * pci); 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 diff --git a/src/lib/dif_config.proto b/src/lib/dif_config.proto index f1f8747b..d47af049 100644 --- a/src/lib/dif_config.proto +++ b/src/lib/dif_config.proto @@ -30,14 +30,14 @@ message dif_config_msg { optional uint32 addr_size = 3; optional uint32 cep_id_size = 4; optional uint32 pdu_length_size = 5; - optional uint32 qos_id_size = 6; - optional uint32 seqno_size = 7; - optional bool has_ttl = 8; - optional bool has_chk = 9; - optional uint32 min_pdu_size = 10; - optional uint32 max_pdu_size = 11; - optional uint32 addr_auth_type = 12; - optional uint32 dt_gam_type = 13; + optional uint32 seqno_size = 6; + optional bool has_ttl = 7; + optional bool has_chk = 8; + optional uint32 min_pdu_size = 9; + optional uint32 max_pdu_size = 10; + optional uint32 addr_auth_type = 11; + optional uint32 dt_gam_type = 12; + optional uint32 rm_gam_type = 13; // Config for shim UDP optional uint32 ip_addr = 14; optional uint32 dns_addr = 15; diff --git a/src/lib/irm.c b/src/lib/irm.c index ade38b6f..8b312833 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -113,7 +113,6 @@ int irm_bootstrap_ipcp(pid_t api, config.has_addr_size = true; config.has_cep_id_size = true; config.has_pdu_length_size = true; - config.has_qos_id_size = true; config.has_seqno_size = true; config.has_has_ttl = true; config.has_has_chk = true; @@ -121,11 +120,11 @@ int irm_bootstrap_ipcp(pid_t api, config.has_max_pdu_size = true; config.has_addr_auth_type = true; config.has_dt_gam_type = true; + config.has_rm_gam_type = true; config.addr_size = conf->addr_size; config.cep_id_size = conf->cep_id_size; config.pdu_length_size = conf->pdu_length_size; - config.qos_id_size = conf->qos_id_size; config.seqno_size = conf->seqno_size; config.has_ttl = conf->has_ttl; config.has_chk = conf->has_chk; @@ -133,6 +132,7 @@ int irm_bootstrap_ipcp(pid_t api, config.max_pdu_size = conf->max_pdu_size; config.addr_auth_type = conf->addr_auth_type; config.dt_gam_type = conf->dt_gam_type; + config.rm_gam_type = conf->rm_gam_type; break; case IPCP_SHIM_UDP: config.has_ip_addr = true; diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 4c7f2168..10c89060 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -46,9 +46,11 @@ #define DEFAULT_DDNS 0 #define DEFAULT_ADDR_AUTH FLAT_RANDOM #define DEFAULT_DT_GAM COMPLETE +#define DEFAULT_RM_GAM COMPLETE #define ADDR_AUTH_FLAT "flat" #define DT_GAM_COMPLETE "complete" +#define RM_GAM_COMPLETE "complete" static void usage(void) { @@ -71,6 +73,8 @@ static void usage(void) " [addr_auth <address policy> (default: %s)]\n" " [dt_gam <data transfer graph adjacency manager>" "(default: %s)]\n" + " [rm_gam <rib manager graph adjacency manager>" + "(default: %s)]\n" "if TYPE == " SHIM_UDP "\n" " ip <IP address in dotted notation>\n" " [dns <DDNS IP address in dotted notation>" @@ -80,7 +84,7 @@ static void usage(void) DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE, DEFAULT_PDU_LEN_SIZE, DEFAULT_SEQ_NO_SIZE, DEFAULT_MIN_PDU_SIZE, DEFAULT_MAX_PDU_SIZE, - ADDR_AUTH_FLAT, DT_GAM_COMPLETE, DEFAULT_DDNS); + ADDR_AUTH_FLAT, DT_GAM_COMPLETE, RM_GAM_COMPLETE, DEFAULT_DDNS); } int do_bootstrap_ipcp(int argc, char ** argv) @@ -98,6 +102,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) uint32_t max_pdu_size = DEFAULT_MAX_PDU_SIZE; enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH; enum pol_gam dt_gam_type = DEFAULT_DT_GAM; + enum pol_gam rm_gam_type = DEFAULT_RM_GAM; uint32_t ip_addr = 0; uint32_t dns_addr = DEFAULT_DDNS; char * ipcp_type = NULL; @@ -152,6 +157,9 @@ int do_bootstrap_ipcp(int argc, char ** argv) } else if (matches(*argv, "dt_gam") == 0) { if (strcmp(DT_GAM_COMPLETE, *(argv + 1)) == 0) dt_gam_type = COMPLETE; + } else if (matches(*argv, "rm_gam") == 0) { + if (strcmp(RM_GAM_COMPLETE, *(argv + 1)) == 0) + rm_gam_type = COMPLETE; } else { printf("\"%s\" is unknown, try \"irm " "ipcp bootstrap\".\n", *argv); @@ -181,6 +189,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) conf.max_pdu_size = max_pdu_size; conf.addr_auth_type = addr_auth_type; conf.dt_gam_type = dt_gam_type; + conf.rm_gam_type = rm_gam_type; } else if (strcmp(ipcp_type, SHIM_UDP) == 0) { conf.type = IPCP_SHIM_UDP; if (ip_addr == 0) { |