diff options
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(); |