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) | 
