summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ipcpd/normal/frct.c4
-rw-r--r--src/ipcpd/normal/main.c263
-rw-r--r--src/ipcpd/normal/ribmgr.c4
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)