summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/normal/routing.c')
-rw-r--r--src/ipcpd/normal/routing.c325
1 files changed, 14 insertions, 311 deletions
diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c
index cc6cdca8..e1459c15 100644
--- a/src/ipcpd/normal/routing.c
+++ b/src/ipcpd/normal/routing.c
@@ -23,338 +23,41 @@
#define OUROBOROS_PREFIX "routing"
#include <ouroboros/config.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/list.h>
#include <ouroboros/logs.h>
-#include <ouroboros/rib.h>
-#include <ouroboros/rqueue.h>
-#include <ouroboros/utils.h>
#include "routing.h"
-#include "ribmgr.h"
-#include "ribconfig.h"
-#include "ipcp.h"
-#include "graph.h"
-#include "neighbors.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <string.h>
-
-#include "fso.pb-c.h"
-typedef Fso fso_t;
-
-#define BUF_SIZE 256
-#define RECALC_TIME 4
-
-struct routing_i {
- struct pff * pff;
- pthread_t calculator;
-};
+#include "pol/link_state.h"
struct {
- struct nbs * nbs;
- struct nb_notifier nb_notifier;
-
- struct graph * graph;
-
- ro_set_t * set;
- rqueue_t * queue;
- pthread_t rib_listener;
+ struct pol_routing_ops * ops;
} routing;
-/* Take under neighbors lock */
-static int addr_to_fd(uint64_t addr)
-{
- struct list_head * p = NULL;
-
- list_for_each(p, &routing.nbs->list) {
- struct nb * e = list_entry(p, struct nb, next);
- if (e->conn.conn_info.addr == addr)
- return e->conn.flow_info.fd;
- }
-
- return -1;
-}
-
-static void * calculate_pff(void * o)
-{
- struct routing_i * instance;
- struct routing_table ** table;
- ssize_t n_table;
- int i;
- int fd;
-
- instance = (struct routing_i *) o;
-
- while (true) {
- table = NULL;
- n_table = graph_routing_table(routing.graph,
- ipcpi.dt_addr, &table);
- if (n_table < 0) {
- sleep(RECALC_TIME);
- continue;
- }
-
- pthread_mutex_lock(&routing.nbs->list_lock);
- pff_lock(instance->pff);
-
- pff_flush(instance->pff);
-
- for (i = 0; i < n_table; i++) {
- fd = addr_to_fd(table[i]->nhop);
- if (fd == -1)
- continue;
-
- pff_add(instance->pff, table[i]->dst, fd);
- }
-
- pff_unlock(instance->pff);
- pthread_mutex_unlock(&routing.nbs->list_lock);
-
- freepp(struct routing_table, table, n_table);
- sleep(RECALC_TIME);
- }
-
- return (void *) 0;
-}
-
-struct routing_i * routing_i_create(struct pff * pff)
-{
- struct routing_i * tmp;
-
- assert(pff);
-
- tmp = malloc(sizeof(*tmp));
- if (tmp == NULL)
- return NULL;
-
- tmp->pff = pff;
-
- pthread_create(&tmp->calculator, NULL, calculate_pff, (void *) tmp);
-
- return tmp;
-}
-
-void routing_i_destroy(struct routing_i * instance)
-{
- assert(instance);
-
- pthread_cancel(instance->calculator);
-
- pthread_join(instance->calculator, NULL);
-
- free(instance);
-}
-
-static int routing_neighbor_event(enum nb_event event,
- struct conn conn)
+int routing_init(enum pol_routing pr,
+ struct nbs * nbs)
{
- char path[RIB_MAX_PATH_LEN + 1];
- char fso_name[RIB_MAX_PATH_LEN + 1];
- fso_t fso = FSO__INIT;
- size_t len;
- uint8_t * data;
-
- /* Only announce the flow if our address is bigger */
- if (ipcpi.dt_addr < conn.conn_info.addr)
- return 0;
-
- path[0] = '\0';
- sprintf(fso_name, "%" PRIu64 "-%" PRIu64,
- ipcpi.dt_addr, conn.conn_info.addr);
- rib_path_append(rib_path_append(path, ROUTING_NAME), fso_name);
-
- switch (event) {
- case NEIGHBOR_ADDED:
- fso.s_addr = ipcpi.dt_addr;
- fso.d_addr = conn.conn_info.addr;
-
- len = fso__get_packed_size(&fso);
- if (len == 0)
- return -1;
-
- data = malloc(len);
- if (data == NULL)
- return -1;
-
- fso__pack(&fso, data);
-
- if (rib_add(ROUTING_PATH, fso_name)) {
- log_err("Failed to add FSO.");
- free(data);
- return -1;
- }
-
- if (rib_put(path, data, len)) {
- log_err("Failed to put FSO in RIB.");
- rib_del(path);
- free(data);
- return -1;
- }
-
- log_dbg("Added %s to RIB.", path);
-
- break;
- case NEIGHBOR_REMOVED:
- if (rib_del(path)) {
- log_err("Failed to remove FSO.");
- return -1;
- }
-
- log_dbg("Removed %s from RIB.", path);
-
- break;
- case NEIGHBOR_QOS_CHANGE:
- log_info("Not currently supported.");
+ switch (pr) {
+ case LINK_STATE:
+ routing.ops = &link_state_ops;
break;
default:
- log_info("Unsupported event for routing.");
- break;
- }
-
- return 0;
-}
-
-static int read_fso(char * path,
- int32_t flag)
-{
- ssize_t len;
- uint8_t ro[BUF_SIZE];
- fso_t * fso;
- qosspec_t qs;
-
- memset(&qs, 0, sizeof(qs));
-
- len = rib_read(path, ro, BUF_SIZE);
- if (len < 0) {
- log_err("Failed to read FSO.");
- return -1;
- }
-
- fso = fso__unpack(NULL, len, ro);
- if (fso == NULL) {
- log_err("Failed to unpack.");
+ log_err("Unknown routing type.");
return -1;
}
- if (flag & RO_MODIFY) {
- if (graph_update_edge(routing.graph,
- fso->s_addr, fso->d_addr, qs)) {
- fso__free_unpacked(fso, NULL);
- return -1;
- }
- } else if (flag & RO_DELETE) {
- if (graph_del_edge(routing.graph, fso->s_addr, fso->d_addr)) {
- fso__free_unpacked(fso, NULL);
- return -1;
- }
- }
-
- fso__free_unpacked(fso, NULL);
-
- return 0;
+ return routing.ops->init(nbs);
}
-static void * rib_listener(void * o)
+struct routing_i * routing_i_create(struct pff * pff)
{
- int32_t flag;
- char path[RIB_MAX_PATH_LEN + 1];
- char ** children;
- ssize_t len;
- int i;
-
- (void) o;
-
- if (ro_set_add(routing.set, ROUTING_PATH, RO_MODIFY | RO_DELETE)) {
- log_err("Failed to add to RO set");
- return (void * ) -1;
- }
-
- len = rib_children(ROUTING_PATH, &children);
- if (len < 0) {
- log_err("Failed to retrieve children.");
- return (void *) -1;
- }
-
- for (i = 0; i < len; i++) {
- if (read_fso(children[i], RO_CREATE)) {
- log_err("Failed to parse FSO.");
- continue;
- }
- }
-
- while (rib_event_wait(routing.set, routing.queue, NULL) == 0) {
- path[0] = '\0';
- flag = rqueue_next(routing.queue, path);
- if (flag < 0)
- continue;
-
- if (read_fso(path, flag)) {
- log_err("Failed to parse FSO.");
- continue;
- }
- }
-
- return (void *) 0;
+ return routing.ops->routing_i_create(pff);
}
-int routing_init(struct nbs * nbs)
+void routing_i_destroy(struct routing_i * instance)
{
- routing.graph = graph_create();
- if (routing.graph == NULL)
- return -1;
-
- if (rib_add(RIB_ROOT, ROUTING_NAME)) {
- graph_destroy(routing.graph);
- return -1;
- }
-
- routing.nbs = nbs;
-
- routing.nb_notifier.notify_call = routing_neighbor_event;
- if (nbs_reg_notifier(routing.nbs, &routing.nb_notifier)) {
- graph_destroy(routing.graph);
- rib_del(ROUTING_PATH);
- return -1;
- }
-
- routing.set = ro_set_create();
- if (routing.set == NULL) {
- nbs_unreg_notifier(routing.nbs, &routing.nb_notifier);
- graph_destroy(routing.graph);
- rib_del(ROUTING_PATH);
- return -1;
- }
-
- routing.queue = rqueue_create();
- if (routing.queue == NULL) {
- ro_set_destroy(routing.set);
- nbs_unreg_notifier(routing.nbs, &routing.nb_notifier);
- graph_destroy(routing.graph);
- rib_del(ROUTING_PATH);
- return -1;
- }
-
- pthread_create(&routing.rib_listener, NULL, rib_listener, NULL);
-
- return 0;
+ return routing.ops->routing_i_destroy(instance);
}
void routing_fini(void)
{
- pthread_cancel(routing.rib_listener);
-
- pthread_join(routing.rib_listener, NULL);
-
- rqueue_destroy(routing.queue);
-
- ro_set_destroy(routing.set);
-
- graph_destroy(routing.graph);
-
- rib_del(ROUTING_PATH);
-
- nbs_unreg_notifier(routing.nbs, &routing.nb_notifier);
+ routing.ops->fini();
}