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