From 60a6970f4d004a3bdaedc5af4e1581890ab9b462 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Tue, 29 Nov 2016 11:48:17 +0100 Subject: ipcpd: normal: Complete flat address policy This will add a check in the flat address policy to see if the address is in use or not. --- src/ipcpd/normal/CMakeLists.txt | 25 ++-- src/ipcpd/normal/addr_auth.c | 2 +- src/ipcpd/normal/flat.c | 63 ---------- src/ipcpd/normal/flat.h | 30 ----- src/ipcpd/normal/pol/flat.c | 261 ++++++++++++++++++++++++++++++++++++++++ src/ipcpd/normal/pol/flat.h | 30 +++++ src/ipcpd/normal/ribmgr.c | 2 +- 7 files changed, 306 insertions(+), 107 deletions(-) delete mode 100644 src/ipcpd/normal/flat.c delete mode 100644 src/ipcpd/normal/flat.h create mode 100644 src/ipcpd/normal/pol/flat.c create mode 100644 src/ipcpd/normal/pol/flat.h diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 06e41e9c..c4525b1a 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -23,17 +23,18 @@ 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 + 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 +42,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 #include "addr_auth.h" -#include "flat.h" +#include "pol/flat.h" #include #include diff --git a/src/ipcpd/normal/flat.c b/src/ipcpd/normal/flat.c deleted file mode 100644 index 8caa85b4..00000000 --- a/src/ipcpd/normal/flat.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Policy for flat addresses in a distributed way - * - * Sander Vrijders - * - * 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 -#include - -#include -#include -#include - -#include "shm_pci.h" -#include "ribmgr.h" - -int flat_init(void) -{ - srand(time(NULL)); - - 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; -} diff --git a/src/ipcpd/normal/flat.h b/src/ipcpd/normal/flat.h deleted file mode 100644 index 51cb511b..00000000 --- a/src/ipcpd/normal/flat.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Policy for flat addresses in a distributed way - * - * Sander Vrijders - * - * 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. - */ - -#ifndef OUROBOROS_FLAT -#define OUROBOROS_FLAT - -int flat_init(void); -int flat_fini(void); -uint64_t flat_address(void); - -#endif /* OUROBOROS_FLAT */ diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c new file mode 100644 index 00000000..4946d538 --- /dev/null +++ b/src/ipcpd/normal/pol/flat.c @@ -0,0 +1,261 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Policy for flat addresses in a distributed way + * + * Sander Vrijders + * + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "shm_pci.h" +#include "ribmgr.h" +#include "ro.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 * my_name(void) +{ + char * name; + char addr_name[100]; + + name = malloc(STR_SIZE); + if (name == NULL) + return NULL; + + sprintf(addr_name, "%lu", (unsigned long) flat.addr); + strcpy(name, POL_RO_ROOT); + strcat(name, "/"); + strcat(name, addr_name); + + return name; +} + +/* FIXME: We should return void */ +static int 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); + } + + return 0; +} + +static int 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 = my_name(); + if (ro_name == NULL) + return -1; + + 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 +}; + +int flat_init(void) +{ + struct ro_props * props; + pthread_condattr_t cattr; + + srand(time(NULL)); + flat.addr_in_use = false; + + props = malloc(sizeof(*props)); + if (props == NULL) + return -ENOMEM; + + 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); + free(props); + return -1; + } + + props->enrol_sync = false; + props->recv_set = NO_SYNC; + props->expiry.tv_sec = 0; + props->expiry.tv_nsec = 0; + + if (ro_create(POL_RO_ROOT, props, NULL, 0)) { + LOG_ERR("Could not create RO."); + pthread_cond_destroy(&flat.cond); + pthread_mutex_destroy(&flat.lock); + free(props); + ro_unsubscribe(flat.sid); + return -1; + } + + 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_props * props; + struct flat_addr_msg * msg; + uint8_t * buf; + char * ro_name; + + dtc = ribmgr_dt_const(); + if (dtc == NULL) + 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; + + /* FIXME: We must change this to stack memory */ + props = malloc(sizeof(*props)); + if (props == NULL) + return INVALID_ADDR; + + props->enrol_sync = false; + props->recv_set = ALL_MEMBERS; + props->expiry.tv_sec = TIMEOUT / 1000; + props->expiry.tv_nsec = (TIMEOUT % 1000) * MILLION; + + buf = malloc(sizeof(*msg)); + if (buf == NULL) { + free(props); + return INVALID_ADDR; + } + + msg = (struct flat_addr_msg *) buf; + msg->code = FLAT_ADDR_REQ; + msg->addr = flat.addr; + + /* FIXME: We may require functions to construct pathnames */ + ro_name = my_name(); + if (ro_name == NULL) { + free(props); + return INVALID_ADDR; + } + + pthread_mutex_lock(&flat.lock); + if (ro_create(ro_name, props, buf, sizeof(*msg))) { + pthread_mutex_unlock(&flat.lock); + free(props); + free(ro_name); + 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/pol/flat.h b/src/ipcpd/normal/pol/flat.h new file mode 100644 index 00000000..51cb511b --- /dev/null +++ b/src/ipcpd/normal/pol/flat.h @@ -0,0 +1,30 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Policy for flat addresses in a distributed way + * + * Sander Vrijders + * + * 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. + */ + +#ifndef OUROBOROS_FLAT +#define OUROBOROS_FLAT + +int flat_init(void); +int flat_fini(void); +uint64_t flat_address(void); + +#endif /* OUROBOROS_FLAT */ diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 524c5a39..79422909 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -414,7 +414,7 @@ static struct rnode * ribmgr_ro_create(const char * name, if (!(props->expiry.tv_sec == 0 && props->expiry.tv_nsec == 0)) { timeout = props->expiry.tv_sec * 1000 + - props->expiry.tv_nsec * MILLION; + props->expiry.tv_nsec / MILLION; if (timerwheel_add(rib.wheel, ro_delete_timer, new->full_name, strlen(new->full_name), timeout)) { -- cgit v1.2.3 From 959882e45f430e59d089bf34ed455afafa08cf29 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Tue, 29 Nov 2016 14:59:42 +0100 Subject: ipcpd: normal: Change ro_attr initialization This changes the way RIB object attributes are set. Previously the struct was called ro_props and it had to be allocated on the heap. Now it follows the model of pthreads closely. This commit also changes the callbacks of the RO subscribers to return void instead of int. --- src/ipcpd/normal/pol/flat.c | 77 ++++++++--------------- src/ipcpd/normal/ribmgr.c | 148 ++++++++++++++++++++------------------------ src/ipcpd/normal/ro.h | 28 +++++---- 3 files changed, 109 insertions(+), 144 deletions(-) diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index 4946d538..544d4f7e 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -76,8 +76,7 @@ static char * my_name(void) return name; } -/* FIXME: We should return void */ -static int ro_created(const char * name, +static void ro_created(const char * name, uint8_t * data, size_t len) { @@ -93,13 +92,11 @@ static int ro_created(const char * name, msg->code = FLAT_ADDR_REPLY; ro_write(name, data, len); } - - return 0; } -static int ro_updated(const char * name, - uint8_t * data, - size_t len) +static void ro_updated(const char * name, + uint8_t * data, + size_t len) { struct flat_addr_msg * msg; char * ro_name; @@ -109,8 +106,10 @@ static int ro_updated(const char * name, assert(len >= sizeof(*msg)); ro_name = my_name(); - if (ro_name == NULL) - return -1; + if (ro_name == NULL) { + free(data); + return; + } msg = (struct flat_addr_msg *) data; if (msg->code == FLAT_ADDR_REPLY && @@ -123,8 +122,6 @@ static int ro_updated(const char * name, free(data); free(ro_name); - - return 0; } static struct ro_sub_ops flat_sub_ops = { @@ -135,16 +132,13 @@ static struct ro_sub_ops flat_sub_ops = { int flat_init(void) { - struct ro_props * props; + struct ro_attr rattr; pthread_condattr_t cattr; srand(time(NULL)); flat.addr_in_use = false; - props = malloc(sizeof(*props)); - if (props == NULL) - return -ENOMEM; - + ro_attr_init(&rattr); pthread_mutex_init(&flat.lock, NULL); pthread_condattr_init(&cattr); #ifndef __APPLE__ @@ -158,20 +152,13 @@ int flat_init(void) LOG_ERR("Could not subscribe to RIB."); pthread_cond_destroy(&flat.cond); pthread_mutex_destroy(&flat.lock); - free(props); return -1; } - props->enrol_sync = false; - props->recv_set = NO_SYNC; - props->expiry.tv_sec = 0; - props->expiry.tv_nsec = 0; - - if (ro_create(POL_RO_ROOT, props, NULL, 0)) { + if (ro_create(POL_RO_ROOT, &rattr, NULL, 0)) { LOG_ERR("Could not create RO."); pthread_cond_destroy(&flat.cond); pthread_mutex_destroy(&flat.lock); - free(props); ro_unsubscribe(flat.sid); return -1; } @@ -189,16 +176,16 @@ int flat_fini(void) 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_props * props; + 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; + uint8_t * buf; + char * ro_name; dtc = ribmgr_dt_const(); if (dtc == NULL) @@ -211,21 +198,14 @@ uint64_t flat_address(void) max_addr = (1 << (8 * dtc->addr_size)) - 1; flat.addr = (rand() % (max_addr - 1)) + 1; - /* FIXME: We must change this to stack memory */ - props = malloc(sizeof(*props)); - if (props == NULL) - return INVALID_ADDR; - - props->enrol_sync = false; - props->recv_set = ALL_MEMBERS; - props->expiry.tv_sec = TIMEOUT / 1000; - props->expiry.tv_nsec = (TIMEOUT % 1000) * MILLION; + 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) { - free(props); + if (buf == NULL) return INVALID_ADDR; - } msg = (struct flat_addr_msg *) buf; msg->code = FLAT_ADDR_REQ; @@ -233,15 +213,12 @@ uint64_t flat_address(void) /* FIXME: We may require functions to construct pathnames */ ro_name = my_name(); - if (ro_name == NULL) { - free(props); + if (ro_name == NULL) return INVALID_ADDR; - } pthread_mutex_lock(&flat.lock); - if (ro_create(ro_name, props, buf, sizeof(*msg))) { + if (ro_create(ro_name, &attr, buf, sizeof(*msg))) { pthread_mutex_unlock(&flat.lock); - free(props); free(ro_name); return INVALID_ADDR; } diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 79422909..5f9ea301 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -64,9 +64,9 @@ typedef RoMsg ro_msg_t; /* 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 { @@ -129,9 +129,9 @@ struct { struct addr_auth * addr_auth; } 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; @@ -145,7 +145,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; @@ -163,7 +163,7 @@ int ribmgr_ro_created(const char * name, pthread_rwlock_unlock(&ipcpi.state_lock); static_info_msg__free_unpacked(stat_msg, NULL); LOG_ERR("Failed to create address authority"); - return -1; + return; } rib.address = rib.addr_auth->address(); @@ -174,14 +174,12 @@ int ribmgr_ro_created(const char * name, 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 +232,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 +317,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 +395,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,10 +409,10 @@ 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), timeout)) { @@ -737,18 +735,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 +750,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 +914,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)) { @@ -1267,7 +1259,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 +1267,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; - } + ro_attr_init(&attr); + attr.enrol_sync = true; - props->enrol_sync = true; - props->recv_set = NEIGHBORS; - props->expiry.tv_sec = 0; - props->expiry.tv_nsec = 0; - - 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; } @@ -1329,25 +1312,10 @@ 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; @@ -1400,27 +1368,33 @@ 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) + if (name == NULL) return -EINVAL; + 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,6 +1416,18 @@ 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; @@ -1459,7 +1445,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."); @@ -1503,7 +1489,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; } 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 */ -- cgit v1.2.3 From fb4cf92a8f2d2e074d302f4b94385e5e95d6a7d4 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Tue, 29 Nov 2016 16:01:09 +0100 Subject: ipcpd: normal: Add helper functions for pathnames This adds some helper functions to construct pathnames. Users of the RIB manager may find these handy when constructing RIB objects. --- src/ipcpd/normal/CMakeLists.txt | 1 + src/ipcpd/normal/path.c | 77 +++++++++++++++++++++++++++++++++++++++++ src/ipcpd/normal/path.h | 35 +++++++++++++++++++ src/ipcpd/normal/pol/flat.c | 35 ++++++++++++------- src/ipcpd/normal/ribmgr.c | 6 ++-- 5 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 src/ipcpd/normal/path.c create mode 100644 src/ipcpd/normal/path.h diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index c4525b1a..ca7e1ae2 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -30,6 +30,7 @@ set(SOURCE_FILES fmgr.c frct.c main.c + path.c ribmgr.c shm_pci.c # Add policies last diff --git a/src/ipcpd/normal/path.c b/src/ipcpd/normal/path.c new file mode 100644 index 00000000..08d33347 --- /dev/null +++ b/src/ipcpd/normal/path.c @@ -0,0 +1,77 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Functions to construct pathnames + * + * Sander Vrijders + * + * 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 +#include +#include + +#include +#include +#include + +#include "path.h" + +char * pathname_create(const char * name) +{ + char * tmp; + + assert(name); + + tmp = malloc(strlen(name) + strlen(PATH_DELIMITER)); + 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)); + 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/path.h b/src/ipcpd/normal/path.h new file mode 100644 index 00000000..022120d9 --- /dev/null +++ b/src/ipcpd/normal/path.h @@ -0,0 +1,35 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Functions to construct pathnames + * + * Sander Vrijders + * + * 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. + */ + +#ifndef OUROBOROS_PATHNAME +#define OUROBOROS_PATHNAME + +#define PATH_DELIMITER "/" + +char * pathname_create(const char * name); + +char * pathname_append(char * pname, + const char * name); + +void pathname_destroy(char * pname); + +#endif diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index 544d4f7e..bbfc85a4 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -36,8 +36,9 @@ #include "shm_pci.h" #include "ribmgr.h" #include "ro.h" +#include "path.h" -#define POL_RO_ROOT "/flat_addr" +#define POL_RO_ROOT "flat_addr" #define TIMEOUT 100 /* ms */ #define STR_SIZE 100 @@ -59,20 +60,18 @@ struct { pthread_mutex_t lock; } flat; -static char * my_name(void) +static char * addr_name(void) { char * name; - char addr_name[100]; + char addr_name[100]; - name = malloc(STR_SIZE); + sprintf(addr_name, "%lu", (unsigned long) flat.addr); + + name = pathname_create(POL_RO_ROOT); if (name == NULL) return NULL; - sprintf(addr_name, "%lu", (unsigned long) flat.addr); - strcpy(name, POL_RO_ROOT); - strcat(name, "/"); - strcat(name, addr_name); - + name = pathname_append(name, addr_name); return name; } @@ -105,7 +104,7 @@ static void ro_updated(const char * name, assert(data); assert(len >= sizeof(*msg)); - ro_name = my_name(); + ro_name = addr_name(); if (ro_name == NULL) { free(data); return; @@ -134,6 +133,7 @@ int flat_init(void) { struct ro_attr rattr; pthread_condattr_t cattr; + char * name; srand(time(NULL)); flat.addr_in_use = false; @@ -155,13 +155,23 @@ int flat_init(void) return -1; } - if (ro_create(POL_RO_ROOT, &rattr, NULL, 0)) { + 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; } @@ -211,8 +221,7 @@ uint64_t flat_address(void) msg->code = FLAT_ADDR_REQ; msg->addr = flat.addr; - /* FIXME: We may require functions to construct pathnames */ - ro_name = my_name(); + ro_name = addr_name(); if (ro_name == NULL) return INVALID_ADDR; diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 5f9ea301..0f76d960 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,9 +59,8 @@ 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 { -- cgit v1.2.3 From 8e0165c2ee9659ee57934947369659c093db621e Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 30 Nov 2016 15:34:04 +0100 Subject: ipcpd: Split IPCP state PENDING_ENROL This will split the IPCP state PENDING_ENROL into IPCP_CONFIG and IPCP_BOOTING. IPCP_CONFIG is concerned only with configuring the IPCP with the bare essence. When in IPCP_BOOTING, the IPCP will complete its configuration by starting its policies, and thus making the IPCP completely functioning. --- src/ipcpd/ipcp.h | 5 +- src/ipcpd/local/main.c | 10 +-- src/ipcpd/normal/fmgr.c | 4 +- src/ipcpd/normal/main.c | 32 +++++++-- src/ipcpd/normal/ribmgr.c | 147 ++++++++++++++++++++++++------------------ src/ipcpd/normal/ribmgr.h | 4 ++ src/ipcpd/shim-eth-llc/main.c | 10 +-- src/ipcpd/shim-udp/main.c | 14 ++-- 8 files changed, 136 insertions(+), 90 deletions(-) diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index c89fe438..58cb6309 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -34,8 +34,9 @@ enum ipcp_state { IPCP_NULL = 0, IPCP_INIT, - IPCP_PENDING_ENROLL, - IPCP_ENROLLED, + IPCP_CONFIG, + IPCP_BOOTING, + IPCP_RUNNING, IPCP_DISCONNECTED, IPCP_SHUTDOWN }; diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index f0c85084..d8614afb 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -94,7 +94,7 @@ static void * ipcp_local_sdu_loop(void * o) pthread_rwlock_rdlock(&ipcpi.state_lock); - if (ipcp_get_state() != IPCP_ENROLLED) { + if (ipcp_get_state() != IPCP_RUNNING) { pthread_rwlock_unlock(&ipcpi.state_lock); return (void *) 1; /* -ENOTENROLLED */ } @@ -137,7 +137,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c) if (ipcp_get_state() == IPCP_INIT) ipcp_set_state(IPCP_NULL); - if (ipcp_get_state() == IPCP_ENROLLED) + if (ipcp_get_state() == IPCP_RUNNING) ipcp_set_state(IPCP_SHUTDOWN); pthread_rwlock_unlock(&ipcpi.state_lock); @@ -163,7 +163,7 @@ static int ipcp_local_bootstrap(struct dif_config * conf) /* this IPCP doesn't need to maintain its dif_name */ free(conf->dif_name); - ipcp_set_state(IPCP_ENROLLED); + ipcp_set_state(IPCP_RUNNING); pthread_create(&local_data.sduloop, NULL, ipcp_local_sdu_loop, NULL); @@ -234,7 +234,7 @@ static int ipcp_local_flow_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_DBG("Won't register with non-enrolled IPCP."); return -1; /* -ENOTENROLLED */ @@ -296,7 +296,7 @@ static int ipcp_local_flow_dealloc(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_DBG("Won't register with non-enrolled IPCP."); return -1; /* -ENOTENROLLED */ 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/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 0f76d960..3cebde0c 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -127,6 +127,7 @@ struct { pthread_mutex_t cdap_reqs_lock; struct addr_auth * addr_auth; + enum pol_addr_auth addr_auth_type; } rib; void ribmgr_ro_created(const char * name, @@ -136,7 +137,7 @@ void ribmgr_ro_created(const char * name, 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."); @@ -156,18 +157,7 @@ void 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; - } - - 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); @@ -946,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."); @@ -1008,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; @@ -1175,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) @@ -1192,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; } @@ -1284,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) { @@ -1321,9 +1269,6 @@ int ribmgr_bootstrap(struct dif_config * conf) 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); @@ -1337,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); 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/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index fafe8651..fe2c3336 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -629,7 +629,7 @@ static void * eth_llc_ipcp_sdu_writer(void * o) &timeout)) { pthread_rwlock_rdlock(&ipcpi.state_lock); - if (ipcp_get_state() != IPCP_ENROLLED) { + if (ipcp_get_state() != IPCP_RUNNING) { pthread_rwlock_unlock(&ipcpi.state_lock); return (void *) -1; /* -ENOTENROLLED */ } @@ -680,7 +680,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c) if (ipcp_get_state() == IPCP_INIT) ipcp_set_state(IPCP_NULL); - if (ipcp_get_state() == IPCP_ENROLLED) + if (ipcp_get_state() == IPCP_RUNNING) ipcp_set_state(IPCP_SHUTDOWN); pthread_rwlock_unlock(&ipcpi.state_lock); @@ -845,7 +845,7 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf) eth_llc_data.tx_offset = 0; #endif - ipcp_set_state(IPCP_ENROLLED); + ipcp_set_state(IPCP_RUNNING); pthread_create(ð_llc_data.sdu_reader, NULL, @@ -951,7 +951,7 @@ static int eth_llc_ipcp_flow_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_DBG("Won't allocate flow with non-enrolled IPCP."); return -1; /* -ENOTENROLLED */ @@ -1051,7 +1051,7 @@ static int eth_llc_ipcp_flow_dealloc(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_DBG("Won't register with non-enrolled IPCP."); return -1; /* -ENOTENROLLED */ diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index eff0bd94..67161d90 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -486,7 +486,7 @@ static void * ipcp_udp_sdu_loop(void * o) while (flow_event_wait(udp_data.np1_flows, udp_data.fq, &timeout)) { pthread_rwlock_rdlock(&ipcpi.state_lock); - if (ipcp_get_state() != IPCP_ENROLLED) { + if (ipcp_get_state() != IPCP_RUNNING) { pthread_rwlock_unlock(&ipcpi.state_lock); return (void *) -1; /* -ENOTENROLLED */ } @@ -531,7 +531,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c) if (ipcp_get_state() == IPCP_INIT) ipcp_set_state(IPCP_NULL); - if (ipcp_get_state() == IPCP_ENROLLED) + if (ipcp_get_state() == IPCP_RUNNING) ipcp_set_state(IPCP_SHUTDOWN); pthread_rwlock_unlock(&ipcpi.state_lock); @@ -616,7 +616,7 @@ static int ipcp_udp_bootstrap(struct dif_config * conf) FD_CLR(udp_data.s_fd, &udp_data.flow_fd_s); - ipcp_set_state(IPCP_ENROLLED); + ipcp_set_state(IPCP_RUNNING); pthread_create(&udp_data.handler, NULL, @@ -890,7 +890,7 @@ static int ipcp_udp_name_query(char * name) 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_DBG("Won't query a name on a non-enrolled IPCP."); return -1; /* -ENOTENROLLED */ @@ -915,7 +915,7 @@ static int ipcp_udp_name_query(char * name) 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_DBG("Won't add name to the directory."); return -1; /* -ENOTENROLLED */ @@ -991,7 +991,7 @@ static int ipcp_udp_flow_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_DBG("Won't allocate flow with non-enrolled IPCP."); close(skfd); @@ -1113,7 +1113,7 @@ static int ipcp_udp_flow_dealloc(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_DBG("Won't register with non-enrolled IPCP."); return -1; /* -ENOTENROLLED */ -- cgit v1.2.3 From b99037eae6a7af058cdb56f316d9c8e4ca603d86 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Thu, 1 Dec 2016 11:15:41 +0100 Subject: ipcpd: normal: Address review comments This addresses some comments after a code review by Dimitri. --- src/ipcpd/normal/path.c | 4 ++-- src/ipcpd/normal/path.h | 6 +++--- src/ipcpd/normal/pol/flat.c | 34 +++++++++++++++++++++------------- src/ipcpd/normal/ribmgr.c | 20 +++++++++----------- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/ipcpd/normal/path.c b/src/ipcpd/normal/path.c index 08d33347..d9b64968 100644 --- a/src/ipcpd/normal/path.c +++ b/src/ipcpd/normal/path.c @@ -38,7 +38,7 @@ char * pathname_create(const char * name) assert(name); - tmp = malloc(strlen(name) + strlen(PATH_DELIMITER)); + tmp = malloc(strlen(name) + strlen(PATH_DELIMITER) + 1); if (tmp == NULL) return NULL; @@ -58,7 +58,7 @@ char * pathname_append(char * pname, tmp = malloc(strlen(pname) + strlen(PATH_DELIMITER) + - strlen(name)); + strlen(name) + 1); if (tmp == NULL) return NULL; diff --git a/src/ipcpd/normal/path.h b/src/ipcpd/normal/path.h index 022120d9..c43f3a26 100644 --- a/src/ipcpd/normal/path.h +++ b/src/ipcpd/normal/path.h @@ -20,8 +20,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef OUROBOROS_PATHNAME -#define OUROBOROS_PATHNAME +#ifndef OUROBOROS_IPCPD_NORMAL_PATH_H +#define OUROBOROS_IPCPD_NORMAL_PATH_H #define PATH_DELIMITER "/" @@ -32,4 +32,4 @@ char * pathname_append(char * pname, void pathname_destroy(char * pname); -#endif +#endif /* OUROBOROS_IPCPD_NORMAL_PATH_H */ diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index bbfc85a4..a428da20 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -27,17 +27,17 @@ #include #include +#include "shm_pci.h" +#include "ribmgr.h" +#include "ro.h" +#include "path.h" + #include #include #include #include #include -#include "shm_pci.h" -#include "ribmgr.h" -#include "ro.h" -#include "path.h" - #define POL_RO_ROOT "flat_addr" #define TIMEOUT 100 /* ms */ @@ -63,7 +63,8 @@ struct { static char * addr_name(void) { char * name; - char addr_name[100]; + /* uint64_t as a string has 25 chars */ + char addr_name[30]; sprintf(addr_name, "%lu", (unsigned long) flat.addr); @@ -76,8 +77,8 @@ static char * addr_name(void) } static void ro_created(const char * name, - uint8_t * data, - size_t len) + uint8_t * data, + size_t len) { struct flat_addr_msg * msg; @@ -86,8 +87,7 @@ static void ro_created(const char * name, assert(len >= sizeof(*msg)); msg = (struct flat_addr_msg *) data; - if (msg->code == FLAT_ADDR_REQ && - msg->addr == flat.addr) { + if (msg->code == FLAT_ADDR_REQ && msg->addr == flat.addr) { msg->code = FLAT_ADDR_REPLY; ro_write(name, data, len); } @@ -146,8 +146,7 @@ int flat_init(void) #endif pthread_cond_init(&flat.cond, &cattr); - flat.sid = ro_subscribe(POL_RO_ROOT, - &flat_sub_ops); + 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); @@ -171,6 +170,7 @@ int flat_init(void) ro_unsubscribe(flat.sid); return -1; } + pathname_destroy(name); return 0; @@ -201,6 +201,11 @@ uint64_t flat_address(void) 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); @@ -222,13 +227,16 @@ uint64_t flat_address(void) msg->addr = flat.addr; ro_name = addr_name(); - if (ro_name == NULL) + 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); diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 3cebde0c..3e305ffe 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -404,7 +404,7 @@ static struct rnode * ribmgr_ro_create(const char * name, 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."); } @@ -1400,8 +1400,7 @@ int ro_create(const char * name, ro_msg_t msg = RO_MSG__INIT; struct ro_attr rattr; - if (name == NULL) - return -EINVAL; + assert(name); if (attr == NULL) { ro_attr_init(&rattr); @@ -1456,8 +1455,7 @@ 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); @@ -1499,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); @@ -1540,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); @@ -1570,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) -- cgit v1.2.3