diff options
author | dimitri staessens <[email protected]> | 2017-02-06 16:05:44 +0100 |
---|---|---|
committer | dimitri staessens <[email protected]> | 2017-02-06 20:04:34 +0100 |
commit | 373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7 (patch) | |
tree | 8711a4edbc2a6defaab63f0dcc2b0690252307b4 /src/ipcpd/normal/main.c | |
parent | 4b11f952c521315883f64571e1790389e8d20f64 (diff) | |
download | ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.tar.gz ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.zip |
ipcpd, lib: Revise normal IPCP
This PR updates the normal IPCP to use the new RIB. The old ribmgr is
removed and replaced by a stub that needs to be implemented. All
components (dir, fmgr, frct) were adapted to the new RIB API. A lot
of functionality was moved outside of the ribmgr, such as the
addr_auth, which is now a component of the IPCP. The address is also
stored to the ipcpi struct. The irm tool has an option to set the gam
policy of the rib manager.
Diffstat (limited to 'src/ipcpd/normal/main.c')
-rw-r--r-- | src/ipcpd/normal/main.c | 352 |
1 files changed, 241 insertions, 111 deletions
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 <[email protected]> + * Sander Vrijders <[email protected]> + * Dimitri Staessens <[email protected]> * * 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(); |