diff options
author | Sander Vrijders <[email protected]> | 2016-07-15 16:01:02 +0200 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2016-07-15 16:28:32 +0200 |
commit | 90cc3234d147c403c877f819fbde3cf5c8220a06 (patch) | |
tree | 6e6595986c9744647404e3c8f404321dd1b476fd /src/ipcpd/normal | |
parent | 71956f22abec7bb15f6bfc52b4168ff85499eea1 (diff) | |
download | ouroboros-90cc3234d147c403c877f819fbde3cf5c8220a06.tar.gz ouroboros-90cc3234d147c403c877f819fbde3cf5c8220a06.zip |
ipcpd: normal: Add main loop to normal IPCP
This adds the main loop to the normal IPCP, just like it is present in
the shim IPCPs. So in essence, the normal IPCP now reacts to all
operations from ipcp.h.
Diffstat (limited to 'src/ipcpd/normal')
-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) |