diff options
| author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-12-02 10:27:09 +0000 | 
|---|---|---|
| committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-12-02 10:27:09 +0000 | 
| commit | c39db00ac0bbed2ec1affa632e83cb52699baec3 (patch) | |
| tree | e44729348ea0fde27351c9b1759f4dc135a5dba5 /src/ipcpd/normal | |
| parent | 113e8f65b6294a46d472b99e39fc9f6d993e808b (diff) | |
| parent | b99037eae6a7af058cdb56f316d9c8e4ca603d86 (diff) | |
| download | ouroboros-c39db00ac0bbed2ec1affa632e83cb52699baec3.tar.gz ouroboros-c39db00ac0bbed2ec1affa632e83cb52699baec3.zip | |
Merged in sandervrijders/ouroboros/be-addr-pol (pull request #312)
Be addr pol
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 */ | 
