diff options
Diffstat (limited to 'src/ipcpd/normal')
-rw-r--r-- | src/ipcpd/normal/CMakeLists.txt | 26 | ||||
-rw-r--r-- | src/ipcpd/normal/addr_auth.c | 2 | ||||
-rw-r--r-- | src/ipcpd/normal/fmgr.c | 4 | ||||
-rw-r--r-- | src/ipcpd/normal/main.c | 32 | ||||
-rw-r--r-- | src/ipcpd/normal/path.c | 77 | ||||
-rw-r--r-- | src/ipcpd/normal/path.h (renamed from src/ipcpd/normal/flat.c) | 46 | ||||
-rw-r--r-- | src/ipcpd/normal/pol/flat.c | 255 | ||||
-rw-r--r-- | src/ipcpd/normal/pol/flat.h (renamed from src/ipcpd/normal/flat.h) | 0 | ||||
-rw-r--r-- | src/ipcpd/normal/ribmgr.c | 317 | ||||
-rw-r--r-- | src/ipcpd/normal/ribmgr.h | 4 | ||||
-rw-r--r-- | src/ipcpd/normal/ro.h | 28 |
11 files changed, 564 insertions, 227 deletions
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 06e41e9c..ca7e1ae2 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -23,17 +23,19 @@ protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS protobuf_generate_c(RO_SRCS RO_HDRS ro.proto) set(SOURCE_FILES - # Add source files here - addr_auth.c - cdap_request.c - crc32.c - flat.c - fmgr.c - frct.c - main.c - ribmgr.c - shm_pci.c -) + # Add source files here + addr_auth.c + cdap_request.c + crc32.c + fmgr.c + frct.c + main.c + path.c + ribmgr.c + shm_pci.c + # Add policies last + pol/flat.c + ) add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} ${STATIC_INFO_SRCS} ${FLOW_ALLOC_SRCS} ${RO_SRCS}) @@ -41,7 +43,7 @@ target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros) include(MacroAddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - macro_add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) + macro_add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index 71bcfafa..95e4bef4 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -26,7 +26,7 @@ #include <ouroboros/logs.h> #include "addr_auth.h" -#include "flat.h" +#include "pol/flat.h" #include <stdlib.h> #include <assert.h> diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 607308c0..35217283 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -127,7 +127,7 @@ static void * fmgr_nm1_acceptor(void * o) (void) o; while (true) { - ipcp_wait_state(IPCP_ENROLLED, NULL); + ipcp_wait_state(IPCP_RUNNING, NULL); pthread_rwlock_rdlock(&ipcpi.state_lock); @@ -412,7 +412,7 @@ int fmgr_np1_alloc(int fd, pthread_rwlock_rdlock(&ipcpi.state_lock); - if (ipcp_get_state() != IPCP_ENROLLED) { + if (ipcp_get_state() != IPCP_RUNNING) { pthread_rwlock_unlock(&ipcpi.state_lock); LOG_ERR("IPCP is not enrolled yet."); return -1; /* -ENOTINIT */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index a5161718..810fbca5 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -100,8 +100,6 @@ static int normal_ipcp_name_query(char * name) { LOG_MISSING; - (void) name; - /* * NOTE: For the moment we just return -1, * for testing purposes we may return zero here @@ -135,18 +133,26 @@ static int normal_ipcp_enroll(char * dif_name) return -1; } - if (ipcp_wait_state(IPCP_ENROLLED, &timeout) == -ETIMEDOUT) { - LOG_ERR("Enrollment timed out."); + if (ribmgr_enrol()) { + LOG_ERR("Failed to enrol IPCP."); return -1; } - pthread_rwlock_rdlock(&ipcpi.state_lock); + if (ipcp_wait_state(IPCP_BOOTING, &timeout) == -ETIMEDOUT) { + LOG_ERR("Enrollment timed out."); + return -1; + } - if (ipcp_get_state() != IPCP_ENROLLED) { + if (ribmgr_start_policies()) { + pthread_rwlock_wrlock(&ipcpi.state_lock); + ipcp_set_state(IPCP_INIT); pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("Failed to start policies."); return -1; } + pthread_rwlock_wrlock(&ipcpi.state_lock); + ipcp_set_state(IPCP_RUNNING); pthread_rwlock_unlock(&ipcpi.state_lock); /* FIXME: Remove once we obtain neighbors during enrollment */ @@ -174,8 +180,20 @@ static int normal_ipcp_bootstrap(struct dif_config * conf) return -1; } - ipcp_set_state(IPCP_ENROLLED); + ipcp_set_state(IPCP_BOOTING); + pthread_rwlock_unlock(&ipcpi.state_lock); + + if (ribmgr_start_policies()) { + pthread_rwlock_wrlock(&ipcpi.state_lock); + ipcp_set_state(IPCP_INIT); + pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("Failed to start policies."); + return -1; + } + + pthread_rwlock_wrlock(&ipcpi.state_lock); + ipcp_set_state(IPCP_RUNNING); ipcpi.data->dif_name = conf->dif_name; pthread_rwlock_unlock(&ipcpi.state_lock); diff --git a/src/ipcpd/normal/path.c b/src/ipcpd/normal/path.c new file mode 100644 index 00000000..d9b64968 --- /dev/null +++ b/src/ipcpd/normal/path.c @@ -0,0 +1,77 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 "path.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/flat.c b/src/ipcpd/normal/path.h index 8caa85b4..c43f3a26 100644 --- a/src/ipcpd/normal/flat.c +++ b/src/ipcpd/normal/path.h @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 * - * Policy for flat addresses in a distributed way + * Functions to construct pathnames * * Sander Vrijders <sander.vrijders@intec.ugent.be> * @@ -20,44 +20,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define OUROBOROS_PREFIX "flat-addr-auth" +#ifndef OUROBOROS_IPCPD_NORMAL_PATH_H +#define OUROBOROS_IPCPD_NORMAL_PATH_H -#include <ouroboros/config.h> -#include <ouroboros/logs.h> +#define PATH_DELIMITER "/" -#include <time.h> -#include <stdlib.h> -#include <math.h> +char * pathname_create(const char * name); -#include "shm_pci.h" -#include "ribmgr.h" +char * pathname_append(char * pname, + const char * name); -int flat_init(void) -{ - srand(time(NULL)); +void pathname_destroy(char * pname); - return 0; -} - -int flat_fini(void) -{ - return 0; -} - -uint64_t flat_address(void) -{ - uint64_t addr; - uint64_t max_addr; - struct dt_const * dtc; - - dtc = ribmgr_dt_const(); - if (dtc == NULL) - return INVALID_ADDR; - - max_addr = (1 << (8 * dtc->addr_size)) - 1; - addr = (rand() % (max_addr - 1)) + 1; - - /* FIXME: Add check for uniqueness of address */ - - return addr; -} +#endif /* OUROBOROS_IPCPD_NORMAL_PATH_H */ diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c new file mode 100644 index 00000000..a428da20 --- /dev/null +++ b/src/ipcpd/normal/pol/flat.c @@ -0,0 +1,255 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Policy for flat addresses in a distributed way + * + * 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 "flat-addr-auth" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> +#include <ouroboros/time_utils.h> + +#include "shm_pci.h" +#include "ribmgr.h" +#include "ro.h" +#include "path.h" + +#include <time.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <assert.h> + +#define POL_RO_ROOT "flat_addr" + +#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) +{ + 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; +} + +static void ro_created(const char * name, + uint8_t * data, + 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); + } +} + +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)); + + 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); +} + +static struct ro_sub_ops flat_sub_ops = { + .ro_created = ro_created, + .ro_updated = ro_updated, + .ro_deleted = NULL +}; + +int flat_init(void) +{ + struct ro_attr rattr; + pthread_condattr_t cattr; + char * name; + + srand(time(NULL)); + flat.addr_in_use = false; + + 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); + + 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; + } + + 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 (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; + } + + 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; + + dtc = ribmgr_dt_const(); + if (dtc == NULL) + return INVALID_ADDR; + + if (dtc->addr_size == 8) { + LOG_ERR("Policy cannot be used with 64 bit addresses."); + return INVALID_ADDR; + } + + 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_create(ro_name, &attr, buf, sizeof(*msg))) { + pthread_mutex_unlock(&flat.lock); + free(ro_name); + free(buf); + return INVALID_ADDR; + } + free(ro_name); + + while (flat.addr_in_use == false) { + ret = -pthread_cond_timedwait(&flat.cond, + &flat.lock, + &abstime); + if (ret == -ETIMEDOUT) + break; + } + pthread_mutex_unlock(&flat.lock); + } + + return flat.addr; +} diff --git a/src/ipcpd/normal/flat.h b/src/ipcpd/normal/pol/flat.h index 51cb511b..51cb511b 100644 --- a/src/ipcpd/normal/flat.h +++ b/src/ipcpd/normal/pol/flat.h diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 524c5a39..3e305ffe 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -44,6 +44,7 @@ #include "ipcp.h" #include "cdap_request.h" #include "ro.h" +#include "path.h" #include "static_info.pb-c.h" typedef StaticInfoMsg static_info_msg_t; @@ -58,15 +59,14 @@ typedef RoMsg ro_msg_t; #define ENROLLMENT "enrollment" -#define RIBMGR_PREFIX "/ribmgr" -#define STAT_INFO "/statinfo" -#define PATH_DELIMITER "/" +#define RIBMGR_PREFIX PATH_DELIMITER "ribmgr" +#define STAT_INFO PATH_DELIMITER "statinfo" /* RIB objects */ struct rnode { - char * name; - char * full_name; - uint64_t seqno; + char * name; + char * full_name; + uint64_t seqno; /* * NOTE: Naive implementation for now, could be replaced by @@ -75,12 +75,12 @@ struct rnode { */ /* If there are no children, this is a leaf */ - struct rnode * child; - struct rnode * sibling; + struct rnode * child; + struct rnode * sibling; - struct ro_props * props; - uint8_t * data; - size_t len; + struct ro_attr attr; + uint8_t * data; + size_t len; }; struct mgmt_flow { @@ -127,16 +127,17 @@ struct { pthread_mutex_t cdap_reqs_lock; struct addr_auth * addr_auth; + enum pol_addr_auth addr_auth_type; } rib; -int ribmgr_ro_created(const char * name, - uint8_t * data, - size_t len) +void ribmgr_ro_created(const char * name, + uint8_t * data, + size_t len) { static_info_msg_t * stat_msg; pthread_rwlock_wrlock(&ipcpi.state_lock); - if (ipcp_get_state() == IPCP_PENDING_ENROLL && + if (ipcp_get_state() == IPCP_CONFIG && strcmp(name, RIBMGR_PREFIX STAT_INFO) == 0) { LOG_DBG("Received static DIF information."); @@ -145,7 +146,7 @@ int ribmgr_ro_created(const char * name, ipcp_set_state(IPCP_INIT); pthread_rwlock_unlock(&ipcpi.state_lock); LOG_ERR("Failed to unpack static info message."); - return -1; + return; } rib.dtc.addr_size = stat_msg->addr_size; @@ -156,32 +157,19 @@ int ribmgr_ro_created(const char * name, 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 = addr_auth_create(stat_msg->addr_auth_type); - if (rib.addr_auth == NULL) { - ipcp_set_state(IPCP_INIT); - pthread_rwlock_unlock(&ipcpi.state_lock); - static_info_msg__free_unpacked(stat_msg, NULL); - LOG_ERR("Failed to create address authority"); - return -1; - } - - rib.address = rib.addr_auth->address(); - LOG_DBG("IPCP has address %lu", rib.address); + rib.addr_auth_type = stat_msg->addr_auth_type; if (frct_init()) { ipcp_set_state(IPCP_INIT); pthread_rwlock_unlock(&ipcpi.state_lock); static_info_msg__free_unpacked(stat_msg, NULL); LOG_ERR("Failed to init FRCT"); - return -1; + return; } static_info_msg__free_unpacked(stat_msg, NULL); } pthread_rwlock_unlock(&ipcpi.state_lock); - - return 0; } /* We only have a create operation for now */ @@ -234,10 +222,10 @@ static int ro_msg_create(struct rnode * node, { msg->address = rib.address; msg->seqno = node->seqno; - msg->recv_set = node->props->recv_set; - msg->enrol_sync = node->props->enrol_sync; - msg->sec = node->props->expiry.tv_sec; - msg->nsec = node->props->expiry.tv_nsec; + 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; @@ -319,10 +307,10 @@ static void ro_delete_timer(void * o) } } -static struct rnode * ribmgr_ro_create(const char * name, - struct ro_props * props, - uint8_t * data, - size_t len) +static struct rnode * ribmgr_ro_create(const char * name, + struct ro_attr attr, + uint8_t * data, + size_t len) { char * str; char * str1; @@ -397,7 +385,7 @@ static struct rnode * ribmgr_ro_create(const char * name, } new->seqno = 0; - new->props = props; + new->attr = attr; if (sibling) prev->sibling = new; @@ -411,12 +399,12 @@ static struct rnode * ribmgr_ro_create(const char * name, LOG_DBG("Created RO with name %s.", name); - if (!(props->expiry.tv_sec == 0 && - props->expiry.tv_nsec == 0)) { - timeout = props->expiry.tv_sec * 1000 + - props->expiry.tv_nsec * MILLION; + 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), + new->full_name, strlen(new->full_name) + 1, timeout)) { LOG_ERR("Failed to add deletion timer of RO."); } @@ -737,18 +725,14 @@ static int ribmgr_cdap_create(struct cdap * instance, struct list_head * p = NULL; size_t len_s, len_n; uint8_t * ro_data; - struct ro_props * props; + struct ro_attr attr; struct rnode * node; - props = malloc(sizeof(*props)); - if (props == NULL) { - cdap_send_reply(instance, invoke_id, -1, NULL, 0); - return -ENOMEM; - } - - props->expiry.tv_sec = msg->sec; - props->expiry.tv_nsec = msg->nsec; - props->enrol_sync = msg->enrol_sync; + 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); @@ -756,16 +740,14 @@ static int ribmgr_cdap_create(struct cdap * instance, if (ro_data == NULL) { pthread_mutex_unlock(&rib.ro_lock); cdap_send_reply(instance, invoke_id, -1, NULL, 0); - free(props); return -1; } memcpy(ro_data, msg->value.data, msg->value.len); - node = ribmgr_ro_create(name, props, ro_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_send_reply(instance, invoke_id, -1, NULL, 0); - free(props); free(ro_data); return -1; } @@ -922,7 +904,7 @@ static int ribmgr_enrol_sync(struct cdap * instance, int ret = 0; if (node != NULL) { - if (node->props->enrol_sync == true) { + if (node->attr.enrol_sync == true) { ro_msg_t msg = RO_MSG__INIT; if (ro_msg_create(node, &msg)) { @@ -954,7 +936,7 @@ static int ribmgr_cdap_start(struct cdap * instance, int iid = 0; pthread_rwlock_wrlock(&ipcpi.state_lock); - if (ipcp_get_state() == IPCP_ENROLLED && + if (ipcp_get_state() == IPCP_RUNNING && strcmp(name, ENROLLMENT) == 0) { LOG_DBG("New enrollment request."); @@ -1016,11 +998,11 @@ static int ribmgr_cdap_stop(struct cdap * instance, int ret = 0; pthread_rwlock_wrlock(&ipcpi.state_lock); - if (ipcp_get_state() == IPCP_PENDING_ENROLL && + if (ipcp_get_state() == IPCP_CONFIG && strcmp(name, ENROLLMENT) == 0) { LOG_DBG("Stop enrollment received."); - ipcp_set_state(IPCP_ENROLLED); + ipcp_set_state(IPCP_BOOTING); } else ret = -1; @@ -1183,7 +1165,6 @@ int ribmgr_add_flow(int fd) { struct cdap * instance = NULL; struct mgmt_flow * flow; - int iid = 0; flow = malloc(sizeof(*flow)); if (flow == NULL) @@ -1200,42 +1181,9 @@ int ribmgr_add_flow(int fd) flow->instance = instance; flow->fd = fd; - pthread_rwlock_wrlock(&ipcpi.state_lock); pthread_rwlock_wrlock(&rib.flows_lock); - if (list_empty(&rib.flows) && ipcp_get_state() == IPCP_INIT) { - ipcp_set_state(IPCP_PENDING_ENROLL); - - pthread_mutex_lock(&rib.cdap_reqs_lock); - iid = cdap_send_request(instance, - CDAP_START, - ENROLLMENT, - NULL, 0, 0); - if (iid < 0) { - pthread_mutex_unlock(&rib.cdap_reqs_lock); - pthread_rwlock_unlock(&rib.flows_lock); - pthread_rwlock_unlock(&ipcpi.state_lock); - LOG_ERR("Failed to start enrollment."); - cdap_destroy(instance); - free(flow); - return -1; - } - - if (cdap_result_wait(instance, CDAP_START, - ENROLLMENT, iid)) { - pthread_mutex_unlock(&rib.cdap_reqs_lock); - pthread_rwlock_unlock(&rib.flows_lock); - pthread_rwlock_unlock(&ipcpi.state_lock); - LOG_ERR("Failed to start enrollment."); - cdap_destroy(instance); - free(flow); - return -1; - } - pthread_mutex_unlock(&rib.cdap_reqs_lock); - } - list_add(&flow->next, &rib.flows); pthread_rwlock_unlock(&rib.flows_lock); - pthread_rwlock_unlock(&ipcpi.state_lock); return 0; } @@ -1267,7 +1215,7 @@ 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_props * props; + struct ro_attr attr; if (conf == NULL || conf->type != IPCP_NORMAL) { @@ -1275,20 +1223,11 @@ int ribmgr_bootstrap(struct dif_config * conf) return -1; } - props = malloc(sizeof(*props)); - if (props == NULL) { - LOG_ERR("Failed to allocate memory."); - return -1; - } - - props->enrol_sync = true; - props->recv_set = NEIGHBORS; - props->expiry.tv_sec = 0; - props->expiry.tv_nsec = 0; + ro_attr_init(&attr); + attr.enrol_sync = true; - if (ribmgr_ro_create(RIBMGR_PREFIX, props, NULL, 0) == NULL) { + if (ribmgr_ro_create(RIBMGR_PREFIX, attr, NULL, 0) == NULL) { LOG_ERR("Failed to create RIBMGR RO."); - free(props); return -1; } @@ -1301,15 +1240,7 @@ int ribmgr_bootstrap(struct dif_config * conf) 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; - - rib.addr_auth = addr_auth_create(conf->addr_auth_type); - if (rib.addr_auth == NULL) { - LOG_ERR("Failed to create address authority."); - ro_delete(RIBMGR_PREFIX); - return -1; - } - - stat_info.addr_auth_type = rib.addr_auth->type; + stat_info.addr_auth_type = rib.addr_auth_type = conf->addr_auth_type; len = static_info_msg__get_packed_size(&stat_info); if (len == 0) { @@ -1329,33 +1260,15 @@ int ribmgr_bootstrap(struct dif_config * conf) static_info_msg__pack(&stat_info, data); - props = malloc(sizeof(*props)); - if (props == NULL) { - LOG_ERR("Failed to allocate memory."); - free(data); - addr_auth_destroy(rib.addr_auth); - ribmgr_ro_delete(RIBMGR_PREFIX); - return -1; - } - - props->enrol_sync = true; - props->recv_set = NEIGHBORS; - props->expiry.tv_sec = 0; - props->expiry.tv_nsec = 0; - if (ribmgr_ro_create(RIBMGR_PREFIX STAT_INFO, - props, data, len) == NULL) { + attr, data, len) == NULL) { LOG_ERR("Failed to create static info RO."); free(data); - free(props); addr_auth_destroy(rib.addr_auth); ribmgr_ro_delete(RIBMGR_PREFIX); return -1; } - rib.address = rib.addr_auth->address(); - LOG_DBG("IPCP has address %lu", rib.address); - if (frct_init()) { LOG_ERR("Failed to initialize FRCT."); ribmgr_ro_delete(RIBMGR_PREFIX STAT_INFO); @@ -1369,6 +1282,84 @@ int ribmgr_bootstrap(struct dif_config * conf) return 0; } +int ribmgr_enrol(void) +{ + struct cdap * instance = NULL; + struct mgmt_flow * flow; + int iid = 0; + + pthread_rwlock_wrlock(&ipcpi.state_lock); + + if (ipcp_get_state() != IPCP_INIT) { + pthread_rwlock_unlock(&ipcpi.state_lock); + return -1; + } + + ipcp_set_state(IPCP_CONFIG); + + pthread_rwlock_wrlock(&rib.flows_lock); + if (list_empty(&rib.flows)) { + ipcp_set_state(IPCP_INIT); + pthread_rwlock_unlock(&rib.flows_lock); + pthread_rwlock_unlock(&ipcpi.state_lock); + return -1; + } + + flow = list_entry((&rib.flows)->next, struct mgmt_flow, next); + instance = flow->instance; + + pthread_mutex_lock(&rib.cdap_reqs_lock); + iid = cdap_send_request(instance, + CDAP_START, + ENROLLMENT, + NULL, 0, 0); + if (iid < 0) { + ipcp_set_state(IPCP_INIT); + pthread_mutex_unlock(&rib.cdap_reqs_lock); + pthread_rwlock_unlock(&rib.flows_lock); + pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("Failed to start enrollment."); + return -1; + } + + if (cdap_result_wait(instance, CDAP_START, + ENROLLMENT, iid)) { + ipcp_set_state(IPCP_INIT); + pthread_mutex_unlock(&rib.cdap_reqs_lock); + pthread_rwlock_unlock(&rib.flows_lock); + pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("Failed to start enrollment."); + return -1; + } + pthread_mutex_unlock(&rib.cdap_reqs_lock); + pthread_rwlock_unlock(&rib.flows_lock); + pthread_rwlock_unlock(&ipcpi.state_lock); + + return 0; +} + +int ribmgr_start_policies(void) +{ + pthread_rwlock_rdlock(&ipcpi.state_lock); + if (ipcp_get_state() != IPCP_BOOTING) { + pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("Cannot start policies in wrong state"); + return -1; + } + pthread_rwlock_unlock(&ipcpi.state_lock); + + 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", rib.address); + + return 0; +} + struct dt_const * ribmgr_dt_const() { return &(rib.dtc); @@ -1400,27 +1391,32 @@ static int send_neighbors_ro(char * name, return 0; } -int ro_create(const char * name, - struct ro_props * props, - uint8_t * data, - size_t len) +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; - if (name == NULL || props == NULL) - return -EINVAL; + assert(name); + + if (attr == NULL) { + ro_attr_init(&rattr); + attr = &rattr; + } pthread_mutex_lock(&rib.ro_lock); - node = ribmgr_ro_create(name, props, data, len); + node = ribmgr_ro_create(name, *attr, data, len); if (node == NULL) { pthread_mutex_unlock(&rib.ro_lock); LOG_ERR("Failed to create RO."); return -1; } - if (node->props->recv_set == NO_SYNC) { + if (node->attr.recv_set == NO_SYNC) { pthread_mutex_unlock(&rib.ro_lock); return 0; } @@ -1442,13 +1438,24 @@ int ro_create(const char * name, 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) { struct rnode * node; ro_msg_t msg = RO_MSG__INIT; - if (name == NULL) - return -EINVAL; + assert(name); pthread_mutex_lock(&rib.ro_lock); @@ -1459,7 +1466,7 @@ int ro_delete(const char * name) return -1; } - if (node->props->recv_set != NO_SYNC) { + 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."); @@ -1490,8 +1497,8 @@ int ro_write(const char * name, struct rnode * node; ro_msg_t msg = RO_MSG__INIT; - if (name == NULL || data == NULL) - return -EINVAL; + assert(name); + assert(data); pthread_mutex_lock(&rib.ro_lock); @@ -1503,7 +1510,7 @@ int ro_write(const char * name, } node->seqno++; - if (node->props->recv_set == NO_SYNC) { + if (node->attr.recv_set == NO_SYNC) { pthread_mutex_unlock(&rib.ro_lock); return 0; } @@ -1531,8 +1538,8 @@ ssize_t ro_read(const char * name, struct rnode * node; ssize_t len; - if (name == NULL || data == NULL) - return -EINVAL; + assert(name); + assert(data); pthread_mutex_lock(&rib.ro_lock); @@ -1561,8 +1568,8 @@ int ro_subscribe(const char * name, { struct ro_sub * sub; - if (name == NULL || ops == NULL) - return -EINVAL; + assert(name); + assert(ops); sub = malloc(sizeof(*sub)); if (sub == NULL) diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index 36f771c1..b76ff3bd 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -38,6 +38,10 @@ int ribmgr_remove_flow(int fd); 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); diff --git a/src/ipcpd/normal/ro.h b/src/ipcpd/normal/ro.h index 6fa1db2a..278c9213 100644 --- a/src/ipcpd/normal/ro.h +++ b/src/ipcpd/normal/ro.h @@ -29,18 +29,20 @@ enum ro_recv_set { ALL_MEMBERS }; -struct ro_props { +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 and props */ -int ro_create(const char * name, - struct ro_props * props, - uint8_t * data, - size_t len); +/* 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); @@ -54,13 +56,13 @@ ssize_t ro_read(const char * name, /* Callback passes ownership of the data */ struct ro_sub_ops { - int (* ro_created)(const char * name, - uint8_t * data, - size_t len); - int (* ro_updated)(const char * name, - uint8_t * data, - size_t len); - int (* ro_deleted)(const char * name); + 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 */ |