diff options
Diffstat (limited to 'src/ipcpd')
-rw-r--r-- | src/ipcpd/normal/frct.c | 4 | ||||
-rw-r--r-- | src/ipcpd/normal/main.c | 263 | ||||
-rw-r--r-- | src/ipcpd/normal/ribmgr.c | 4 |
3 files changed, 261 insertions, 10 deletions
diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c index 9ea2fd48..22f8a9fc 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -34,14 +34,14 @@ int frct_init(struct dt_const * dt_const) { LOG_MISSING; - return -1; + return 0; } int frct_fini() { LOG_MISSING; - return -1; + return 0; } struct frct_i * frct_i_create(int port_id, diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 3433b116..2d97f435 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -1,25 +1,276 @@ #define OUROBOROS_PREFIX "normal-ipcp" +#include <ouroboros/config.h> #include <ouroboros/logs.h> +#include <ouroboros/shm_du_map.h> +#include <ouroboros/shm_ap_rbuff.h> +#include <ouroboros/dev.h> + #include <stdbool.h> +#include <signal.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> #include "fmgr.h" #include "ribmgr.h" +#include "ipcp.h" +#include "frct.h" + +#define THIS_TYPE IPCP_NORMAL + +/* global for trapping signal */ +int irmd_api; + +struct ipcp * _ipcp; + +#define normal_data(type) ((struct normal_ipcp_data *) type->data) + +struct normal_ipcp_data { + /* Keep ipcp_data first for polymorphism. */ + struct ipcp_data ipcp_data; -int main() + struct shm_du_map * dum; + struct shm_ap_rbuff * rb; + + pthread_t mainloop; +}; + +void ipcp_sig_handler(int sig, siginfo_t * info, void * c) { - if (fmgr_init()) { + sigset_t sigset; + sigemptyset(&sigset); + sigaddset(&sigset, SIGINT); + + switch(sig) { + case SIGINT: + case SIGTERM: + case SIGHUP: + if (info->si_pid == irmd_api) { + LOG_DBG("Terminating by order of %d. Bye.", + info->si_pid); + + pthread_rwlock_wrlock(&_ipcp->state_lock); + + _ipcp->state = IPCP_SHUTDOWN; + + pthread_rwlock_unlock(&_ipcp->state_lock); + + pthread_cancel(normal_data(_ipcp)->mainloop); + + if (ribmgr_fini()) + LOG_ERR("Failed to finalize RIB manager."); + + if (frct_fini()) + LOG_ERR("Failed to finalize FRCT."); + + if (fmgr_fini()) + LOG_ERR("Failed to finalize flow manager."); + } + default: + return; + } +} + +static int normal_ipcp_name_reg(char * name) +{ + pthread_rwlock_rdlock(&_ipcp->state_lock); + + if (_ipcp->state != IPCP_ENROLLED) { + pthread_rwlock_unlock(&_ipcp->state_lock); + LOG_DBGF("Won't register with non-enrolled IPCP."); + return -1; /* -ENOTENROLLED */ + } + + if (ipcp_data_add_reg_entry(_ipcp->data, name)) { + pthread_rwlock_unlock(&_ipcp->state_lock); + LOG_ERR("Failed to add %s to local registry.", name); return -1; } + pthread_rwlock_unlock(&_ipcp->state_lock); + + LOG_DBG("Registered %s.", name); + + return 0; +} + +static int normal_ipcp_name_unreg(char * name) +{ + pthread_rwlock_rdlock(&_ipcp->state_lock); + + ipcp_data_del_reg_entry(_ipcp->data, name); + + pthread_rwlock_unlock(&_ipcp->state_lock); + + return 0; +} + +static int normal_ipcp_enroll(char * dif_name) +{ + LOG_MISSING; + + return -1; +} + +static int normal_ipcp_bootstrap(struct dif_config * conf) +{ + LOG_MISSING; + + return -1; +} + +static struct ipcp_ops normal_ops = { + .ipcp_bootstrap = normal_ipcp_bootstrap, + .ipcp_enroll = normal_ipcp_enroll, + .ipcp_name_reg = normal_ipcp_name_reg, + .ipcp_name_unreg = normal_ipcp_name_unreg, + .ipcp_flow_alloc = fmgr_flow_alloc, + .ipcp_flow_alloc_resp = fmgr_flow_alloc_resp, + .ipcp_flow_dealloc = fmgr_flow_dealloc +}; + +struct normal_ipcp_data * normal_ipcp_data_create() +{ + struct normal_ipcp_data * normal_data; + enum ipcp_type ipcp_type; + + normal_data = malloc(sizeof(*normal_data)); + if (normal_data == NULL) { + LOG_ERR("Failed to allocate."); + return NULL; + } + + ipcp_type = THIS_TYPE; + if (ipcp_data_init((struct ipcp_data *) normal_data, + ipcp_type) == NULL) { + free(normal_data); + return NULL; + } + + normal_data->dum = shm_du_map_open(); + if (normal_data->dum == NULL) { + free(normal_data); + return NULL; + } + + normal_data->rb = shm_ap_rbuff_open(getpid()); + if (normal_data->rb == NULL) { + shm_du_map_close(normal_data->dum); + free(normal_data); + return NULL; + } + + return normal_data; +} + + +void normal_ipcp_data_destroy() +{ + if (_ipcp == NULL) + return; + + pthread_rwlock_wrlock(&_ipcp->state_lock); + + if (_ipcp->state != IPCP_SHUTDOWN) + LOG_WARN("Cleaning up while not in shutdown."); + + if (normal_data(_ipcp)->dum != NULL) + shm_du_map_close_on_exit(normal_data(_ipcp)->dum); + if (normal_data(_ipcp)->rb != NULL) + shm_ap_rbuff_close(normal_data(_ipcp)->rb); + + pthread_rwlock_unlock(&_ipcp->state_lock); + + free(_ipcp->data); +} + +int main(int argc, char * argv[]) +{ + struct sigaction sig_act; + sigset_t sigset; + + if (ap_init(argv[0])) { + LOG_ERR("Failed to init AP"); + exit(EXIT_FAILURE); + } + + sigemptyset(&sigset); + sigaddset(&sigset, SIGINT); + sigaddset(&sigset, SIGQUIT); + sigaddset(&sigset, SIGHUP); + sigaddset(&sigset, SIGPIPE); + + if (ipcp_parse_arg(argc, argv)) { + LOG_ERR("Failed to parse arguments."); + exit(EXIT_FAILURE); + } + + /* store the process id of the irmd */ + irmd_api = atoi(argv[1]); + + /* init sig_act */ + memset(&sig_act, 0, sizeof(sig_act)); + + /* install signal traps */ + sig_act.sa_sigaction = &ipcp_sig_handler; + sig_act.sa_flags = SA_SIGINFO; + + sigaction(SIGINT, &sig_act, NULL); + sigaction(SIGTERM, &sig_act, NULL); + sigaction(SIGHUP, &sig_act, NULL); + sigaction(SIGPIPE, &sig_act, NULL); + + _ipcp = ipcp_instance_create(); + if (_ipcp == NULL) { + LOG_ERR("Failed to create instance."); + close_logfile(); + exit(EXIT_FAILURE); + } + + _ipcp->data = (struct ipcp_data *) normal_ipcp_data_create(); + if (_ipcp->data == NULL) { + LOG_ERR("Failed to create instance data."); + free(_ipcp); + close_logfile(); + exit(EXIT_FAILURE); + } + + _ipcp->ops = &normal_ops; + _ipcp->state = IPCP_INIT; + + if (fmgr_init()) { + normal_ipcp_data_destroy(); + free(_ipcp); + close_logfile(); + exit(EXIT_FAILURE); + } + if (ribmgr_init()) { + normal_ipcp_data_destroy(); fmgr_fini(); - return -1; + free(_ipcp); + close_logfile(); + exit(EXIT_FAILURE); } - while (true) { + pthread_rwlock_wrlock(&_ipcp->state_lock); - } + pthread_sigmask(SIG_BLOCK, &sigset, NULL); - return 0; + pthread_create(&normal_data(_ipcp)->mainloop, NULL, + ipcp_main_loop, _ipcp); + + pthread_sigmask(SIG_UNBLOCK, &sigset, NULL); + + pthread_rwlock_unlock(&_ipcp->state_lock); + + pthread_join(normal_data(_ipcp)->mainloop, NULL); + + normal_ipcp_data_destroy(); + free(_ipcp); + close_logfile(); + + ap_fini(); + exit(EXIT_SUCCESS); } diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 39723e5a..98ed38c6 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -30,14 +30,14 @@ int ribmgr_init() { LOG_MISSING; - return -1; + return 0; } int ribmgr_fini() { LOG_MISSING; - return -1; + return 0; } int ribmgr_mgmt_flow(int fd) |