summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal/ribmgr.c
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-09-13 09:41:41 +0000
committerSander Vrijders <[email protected]>2017-09-13 09:41:41 +0000
commit888d3dbe7c3844d2efe9d6bc9823630db5d47a3b (patch)
treeed79946a5ff22267857cd6d5a864d15339c942a1 /src/ipcpd/normal/ribmgr.c
parent2e4cdc1f680d5ee9086adac76acebdec3bd1da3f (diff)
parent45c6615484ffe347654c34decb72ff1ef9bde0f3 (diff)
downloadouroboros-888d3dbe7c3844d2efe9d6bc9823630db5d47a3b.tar.gz
ouroboros-888d3dbe7c3844d2efe9d6bc9823630db5d47a3b.zip
Merged in dstaesse/ouroboros/be-rib-removal (pull request #589)
ipcpd: Revise internals of normal IPCP
Diffstat (limited to 'src/ipcpd/normal/ribmgr.c')
-rw-r--r--src/ipcpd/normal/ribmgr.c423
1 files changed, 0 insertions, 423 deletions
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
deleted file mode 100644
index a5e7d6ce..00000000
--- a/src/ipcpd/normal/ribmgr.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * RIB manager of the IPC Process
- *
- * Dimitri Staessens <[email protected]>
- * Sander Vrijders <[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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define _POSIX_C_SOURCE 200112L
-
-#define OUROBOROS_PREFIX "rib-manager"
-
-#include <ouroboros/logs.h>
-#include <ouroboros/cdap.h>
-#include <ouroboros/list.h>
-#include <ouroboros/time_utils.h>
-#include <ouroboros/ipcp-dev.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/dev.h>
-#include <ouroboros/fqueue.h>
-#include <ouroboros/rib.h>
-
-#include "ae.h"
-#include "connmgr.h"
-#include "ipcp.h"
-#include "neighbors.h"
-#include "ribconfig.h"
-#include "ribmgr.h"
-
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#define MGMT_AE "Management"
-#define RIB_SYNC_TIMEOUT 1
-
-enum ribmgr_state {
- RIBMGR_NULL = 0,
- RIBMGR_INIT,
- RIBMGR_OPERATIONAL,
- RIBMGR_SHUTDOWN
-};
-
-struct {
- struct cdap * cdap;
-
- pthread_t reader;
- pthread_t sync;
-
- struct nbs * nbs;
- struct ae * ae;
-
- struct nb_notifier nb_notifier;
-
- pthread_rwlock_t state_lock;
- enum ribmgr_state state;
-} ribmgr;
-
-static int ribmgr_neighbor_event(enum nb_event event,
- struct conn conn)
-{
- switch (event) {
- case NEIGHBOR_ADDED:
- cdap_add_flow(ribmgr.cdap, conn.flow_info.fd);
- break;
- case NEIGHBOR_REMOVED:
- cdap_del_flow(ribmgr.cdap, conn.flow_info.fd);
- break;
- default:
- /* Don't care about other events */
- break;
- }
-
- return 0;
-}
-
-static enum ribmgr_state ribmgr_get_state(void)
-{
- enum ribmgr_state state;
-
- pthread_rwlock_rdlock(&ribmgr.state_lock);
-
- state = ribmgr.state;
-
- pthread_rwlock_unlock(&ribmgr.state_lock);
-
- return state;
-}
-
-static void ribmgr_set_state(enum ribmgr_state state)
-{
- pthread_rwlock_wrlock(&ribmgr.state_lock);
-
- ribmgr.state = state;
-
- pthread_rwlock_unlock(&ribmgr.state_lock);
-}
-
-static void * reader(void * o)
-{
- cdap_key_t key;
- enum cdap_opcode oc;
- char * name;
- uint8_t * data;
- size_t len;
- ssize_t slen;
- uint32_t flags;
- uint8_t * buf;
- int rval;
-
- (void) o;
-
- while (ribmgr_get_state() == RIBMGR_OPERATIONAL) {
- key = cdap_request_wait(ribmgr.cdap, &oc, &name, &data,
- (size_t *) &len , &flags);
- assert(key != -EINVAL);
-
- if (key == INVALID_CDAP_KEY) {
- log_warn("Bad CDAP request.");
- continue;
- }
-
- assert(name);
- assert(strlen(name));
-
- switch (oc) {
- case CDAP_READ:
- assert(len == 0);
- slen = rib_pack(name, &buf, PACK_HASH_ROOT);
- if (slen < 0) {
- log_err("Failed to pack %s.", name);
- cdap_reply_send(ribmgr.cdap, key, -1, NULL, 0);
- free(name);
- continue;
- }
-
- log_dbg("Packed %s (%zu bytes).", name, slen);
-
- free(name);
-
- if (cdap_reply_send(ribmgr.cdap, key, 0, buf, slen)) {
- log_err("Failed to send CDAP reply.");
- free(buf);
- continue;
- }
-
- free(buf);
- break;
- case CDAP_WRITE:
- assert(len);
- assert(data);
-
- rval = rib_unpack(data, len, 0);
- switch(rval) {
- case 0:
- break;
- case -EFAULT:
- log_warn("Hash mismatch, not in sync.");
- free(data);
- break;
- default:
- log_warn("Error unpacking %s.", name);
- cdap_reply_send(ribmgr.cdap, key, -1, NULL, 0);
- free(name);
- free(data);
- continue;
- }
-
- free(name);
-
- if (cdap_reply_send(ribmgr.cdap, key, 0, NULL, 0)) {
- log_err("Failed to send CDAP reply.");
- continue;
- }
- break;
- case CDAP_CREATE:
- assert(len);
- assert(data);
-
- rval = rib_unpack(data, len, UNPACK_CREATE);
- switch(rval) {
- case 0:
- break;
- case -EFAULT:
- log_warn("Hash mismatch, not yet in sync.");
- free(data);
- break;
- default:
- log_warn("Error unpacking %s.", name);
- cdap_reply_send(ribmgr.cdap, key, -1, NULL, 0);
- free(name);
- free(data);
- continue;
- }
-
- free(name);
-
- if (cdap_reply_send(ribmgr.cdap, key, 0, NULL, 0)) {
- log_err("Failed to send CDAP reply.");
- continue;
- }
- break;
- case CDAP_DELETE:
- assert(len == 0);
- if (rib_del(name)) {
- log_warn("Failed deleting %s.", name);
- cdap_reply_send(ribmgr.cdap, key, -1, NULL, 0);
- }
-
- free(name);
-
- if (cdap_reply_send(ribmgr.cdap, key, 0, NULL, 0)) {
- log_err("Failed to send CDAP reply.");
- continue;
- }
- break;
- case CDAP_START:
- case CDAP_STOP:
- log_warn("Unsupported CDAP command.");
- if (len)
- free(data);
- break;
- default:
- log_err("Bad CDAP command.");
- if (len)
- free(data);
- break;
- }
- }
-
- return (void *) 0;
-}
-
-char path[RIB_MAX_PATH_LEN + 1];
-
-static void path_reset(void) {
- path[strlen(RIB_ROOT)] = '\0';
- assert(strcmp(path, RIB_ROOT) == 0);
-}
-
-static int ribmgr_sync(const char * path)
-{
- uint8_t * buf;
- ssize_t len;
- cdap_key_t * keys;
-
- len = rib_pack(path, &buf, PACK_HASH_ALL);
- if (len < 0) {
- log_warn("Failed to pack %s.", path);
- return -1;
- }
-
- keys = cdap_request_send(ribmgr.cdap, CDAP_CREATE, path, buf, len, 0);
- if (keys != NULL) {
- cdap_key_t * key = keys;
- while (*key != INVALID_CDAP_KEY)
- cdap_reply_wait(ribmgr.cdap, *(key++), NULL, NULL);
- free(keys);
- }
-
- free(buf);
-
- return 0;
-}
-
-/* FIXME: Temporary thread, syncs rib with neighbors every second */
-static void * sync_rib(void *o)
-{
- char ** children;
- ssize_t ch;
-
- (void) o;
-
- strcpy(path, RIB_ROOT);
-
- while (ribmgr_get_state() == RIBMGR_OPERATIONAL) {
- sleep(RIB_SYNC_TIMEOUT);
-
- ch = rib_children(RIB_ROOT, &children);
- if (ch <= 0)
- continue;
-
- while (ch > 0) {
- path_reset();
-
- rib_path_append(path, children[--ch]);
- free(children[ch]);
-
- /* Sync fsdb */
- if (strcmp(path, ROUTING_PATH) == 0)
- ribmgr_sync(path);
- }
-
- free(children);
- }
-
- return (void *) 0;
-}
-
-int ribmgr_init(void)
-{
- struct conn_info info;
-
- memset(&info, 0, sizeof(info));
-
- strcpy(info.ae_name, MGMT_AE);
- strcpy(info.protocol, CDAP_PROTO);
- info.pref_version = 1;
- info.pref_syntax = PROTO_GPB;
- info.addr = 0;
-
- ribmgr.nbs = nbs_create();
- if (ribmgr.nbs == NULL) {
- log_err("Failed to create neighbors.");
- goto fail_nbs_create;
- }
-
- if (connmgr_ae_init(AEID_MGMT, &info, ribmgr.nbs)) {
- log_err("Failed to register with connmgr.");
- goto fail_connmgr_ae_init;
- };
-
- ribmgr.cdap = cdap_create();
- if (ribmgr.cdap == NULL) {
- log_err("Failed to create CDAP instance.");
- goto fail_cdap_create;
- }
-
- ribmgr.nb_notifier.notify_call = ribmgr_neighbor_event;
- if (nbs_reg_notifier(ribmgr.nbs, &ribmgr.nb_notifier)) {
- log_err("Failed to register notifier.");
- goto fail_nbs_reg_notifier;
- }
-
- if (pthread_rwlock_init(&ribmgr.state_lock, NULL)) {
- log_err("Failed to init rwlock.");
- goto fail_rwlock_init;
- }
-
- ribmgr.state = RIBMGR_INIT;
-
- return 0;
-
- fail_rwlock_init:
- nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier);
- fail_nbs_reg_notifier:
- cdap_destroy(ribmgr.cdap);
- fail_cdap_create:
- connmgr_ae_fini(AEID_MGMT);
- fail_connmgr_ae_init:
- nbs_destroy(ribmgr.nbs);
- fail_nbs_create:
- return -1;
-}
-
-void ribmgr_fini(void)
-{
- if (ribmgr_get_state() == RIBMGR_SHUTDOWN) {
- pthread_join(ribmgr.reader, NULL);
- pthread_join(ribmgr.sync, NULL);
- }
-
- nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier);
- cdap_destroy(ribmgr.cdap);
- nbs_destroy(ribmgr.nbs);
-
- connmgr_ae_fini(AEID_MGMT);
-}
-
-int ribmgr_start(void)
-{
- ribmgr_set_state(RIBMGR_OPERATIONAL);
-
- if (pthread_create(&ribmgr.sync, NULL, sync_rib, NULL)) {
- ribmgr_set_state(RIBMGR_NULL);
- return -1;
- }
-
- if (pthread_create(&ribmgr.reader, NULL, reader, NULL)) {
- ribmgr_set_state(RIBMGR_SHUTDOWN);
- pthread_cancel(ribmgr.reader);
- return -1;
- }
-
- return 0;
-}
-
-void ribmgr_stop(void)
-{
- if (ribmgr_get_state() == RIBMGR_OPERATIONAL) {
- ribmgr_set_state(RIBMGR_SHUTDOWN);
- pthread_cancel(ribmgr.reader);
- }
-}
-
-int ribmgr_disseminate(char * path,
- enum diss_target target,
- enum diss_freq freq,
- size_t delay)
-{
- (void) path;
- (void) target;
- (void) freq;
- (void) delay;
-
- return 0;
-}