From 25ddfa73bf24734765e892cfa1c4304b714fd9cc Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Mon, 13 Mar 2017 16:09:45 +0100 Subject: ipcpd: normal: Add Flow State Objects to RIB This makes the routing component create a Flow State Database (FSDB). An FSDB contains Flow State Objects (FSOs). An FSO is created when a neighbor is added, it is deleted when a neighbor is removed and its QoS is updated when a neighbor's QoS changes. --- src/ipcpd/normal/fmgr.c | 23 +++++-- src/ipcpd/normal/routing.c | 147 ++++++++++++++++++++++++++++++++------------- src/ipcpd/normal/routing.h | 10 ++- 3 files changed, 132 insertions(+), 48 deletions(-) (limited to 'src/ipcpd/normal') diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 2593e8fd..184baf82 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -68,7 +68,7 @@ struct { pthread_t nm1_sdu_reader; struct pff * pff[QOS_CUBE_MAX]; - struct routing * routing[QOS_CUBE_MAX]; + struct routing_i * routing[QOS_CUBE_MAX]; struct gam * gam; struct nbs * nbs; @@ -238,7 +238,7 @@ static void fmgr_destroy_routing(void) int i; for (i = 0; i < QOS_CUBE_MAX; ++i) - routing_destroy(fmgr.routing[i]); + routing_i_destroy(fmgr.routing[i]); } static void fmgr_destroy_pff(void) @@ -316,9 +316,18 @@ int fmgr_init(void) return -1; } + if (routing_init(fmgr.nbs)) { + log_err("Failed to init routing."); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } + fmgr.nb_notifier.notify_call = fmgr_neighbor_event; if (nbs_reg_notifier(fmgr.nbs, &fmgr.nb_notifier)) { log_err("Failed to register notifier."); + routing_fini(); nbs_destroy(fmgr.nbs); fmgr_destroy_flows(); connmgr_ae_destroy(fmgr.ae); @@ -328,6 +337,7 @@ int fmgr_init(void) if (pthread_rwlock_init(&fmgr.np1_flows_lock, NULL)) { gam_destroy(fmgr.gam); nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + routing_fini(); nbs_destroy(fmgr.nbs); fmgr_destroy_flows(); connmgr_ae_destroy(fmgr.ae); @@ -341,19 +351,21 @@ int fmgr_init(void) pff_destroy(fmgr.pff[j]); pthread_rwlock_destroy(&fmgr.np1_flows_lock); nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + routing_fini(); nbs_destroy(fmgr.nbs); fmgr_destroy_flows(); connmgr_ae_destroy(fmgr.ae); return -1; } - fmgr.routing[i] = routing_create(fmgr.pff[i], fmgr.nbs); + fmgr.routing[i] = routing_i_create(fmgr.pff[i]); if (fmgr.routing[i] == NULL) { for (j = 0; j < i; ++j) - routing_destroy(fmgr.routing[j]); + routing_i_destroy(fmgr.routing[j]); fmgr_destroy_pff(); pthread_rwlock_destroy(&fmgr.np1_flows_lock); nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + routing_fini(); nbs_destroy(fmgr.nbs); fmgr_destroy_flows(); connmgr_ae_destroy(fmgr.ae); @@ -368,6 +380,7 @@ int fmgr_init(void) fmgr_destroy_pff(); pthread_rwlock_destroy(&fmgr.np1_flows_lock); nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + routing_fini(); nbs_destroy(fmgr.nbs); fmgr_destroy_flows(); connmgr_ae_destroy(fmgr.ae); @@ -396,6 +409,8 @@ void fmgr_fini() fmgr_destroy_pff(); + routing_fini(); + fmgr_destroy_flows(); connmgr_ae_destroy(fmgr.ae); diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c index 449c9379..e699fd77 100644 --- a/src/ipcpd/normal/routing.c +++ b/src/ipcpd/normal/routing.c @@ -26,17 +26,26 @@ #include #include #include +#include #include "routing.h" #include "ribmgr.h" +#include "ribconfig.h" +#include "ipcp.h" #include #include #include +#include + +#define ADDR_SIZE 30 struct edge { - struct vertex * ep; - qosspec_t qs; + struct list_head next; + + uint64_t addr; + + qosspec_t qs; }; struct vertex { @@ -47,34 +56,16 @@ struct vertex { struct list_head edges; }; -struct routing { - struct pff * pff; - struct nbs * nbs; - - struct nb_notifier nb_notifier; - - struct list_head vertices; +struct routing_i { + struct pff * pff; + struct list_head vertices; }; -static int routing_neighbor_event(enum nb_event event, - struct conn conn) -{ - (void) conn; - - /* FIXME: React to events here */ - switch (event) { - case NEIGHBOR_ADDED: - break; - case NEIGHBOR_REMOVED: - break; - case NEIGHBOR_QOS_CHANGE: - break; - default: - break; - } - - return 0; -} +struct { + struct nbs * nbs; + struct nb_notifier nb_notifier; + char fso_path[RIB_MAX_PATH_LEN + 1]; +} routing; #if 0 /* FIXME: If zeroed since it is not used currently */ @@ -97,10 +88,9 @@ static int add_vertex(struct routing * instance, } #endif -struct routing * routing_create(struct pff * pff, - struct nbs * nbs) +struct routing_i * routing_i_create(struct pff * pff) { - struct routing * tmp; + struct routing_i * tmp; assert(pff); @@ -109,24 +99,99 @@ struct routing * routing_create(struct pff * pff, return NULL; tmp->pff = pff; - tmp->nbs = nbs; list_head_init(&tmp->vertices); - tmp->nb_notifier.notify_call = routing_neighbor_event; - if (nbs_reg_notifier(tmp->nbs, &tmp->nb_notifier)) { - free(tmp); - return NULL; - } - return tmp; } -void routing_destroy(struct routing * instance) +void routing_i_destroy(struct routing_i * instance) { assert(instance); - nbs_unreg_notifier(instance->nbs, &instance->nb_notifier); - free(instance); } + +static int routing_neighbor_event(enum nb_event event, + struct conn conn) +{ + char addr[ADDR_SIZE]; + char path[RIB_MAX_PATH_LEN + 1]; + + strcpy(path, routing.fso_path); + snprintf(addr, ADDR_SIZE, "%" PRIx64, conn.conn_info.addr); + rib_path_append(path, addr); + + switch (event) { + case NEIGHBOR_ADDED: + if (rib_add(routing.fso_path, addr)) { + log_err("Failed to add FSO."); + return -1; + } + + if (rib_write(path, &conn.flow_info.qs, + sizeof(conn.flow_info.qs))) { + log_err("Failed to write qosspec to FSO."); + rib_del(path); + return -1; + } + + break; + case NEIGHBOR_REMOVED: + if (rib_del(path)) { + log_err("Failed to remove FSO."); + return -1; + } + + break; + case NEIGHBOR_QOS_CHANGE: + if (rib_write(path, &conn.flow_info.qs, + sizeof(conn.flow_info.qs))) { + log_err("Failed to write qosspec to FSO."); + return -1; + } + + break; + default: + log_info("Unsupported event for routing."); + break; + } + + return 0; +} + +int routing_init(struct nbs * nbs) +{ + char addr[ADDR_SIZE]; + + if (rib_add(RIB_ROOT, ROUTING_NAME)) + return -1; + + rib_path_append(routing.fso_path, ROUTING_NAME); + + snprintf(addr, ADDR_SIZE, "%" PRIx64, ipcpi.dt_addr); + + if (rib_add(routing.fso_path, addr)) { + rib_del(ROUTING_PATH); + return -1; + } + + rib_path_append(routing.fso_path, addr); + + routing.nbs = nbs; + + routing.nb_notifier.notify_call = routing_neighbor_event; + if (nbs_reg_notifier(routing.nbs, &routing.nb_notifier)) { + rib_del(ROUTING_PATH); + return -1; + } + + return 0; +} + +void routing_fini(void) +{ + rib_del(ROUTING_PATH); + + nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); +} diff --git a/src/ipcpd/normal/routing.h b/src/ipcpd/normal/routing.h index 81208ffa..20dc72f9 100644 --- a/src/ipcpd/normal/routing.h +++ b/src/ipcpd/normal/routing.h @@ -34,9 +34,13 @@ * Routing will take a type in the future, * to allow different policies. */ -struct routing * routing_create(struct pff * pff, - struct nbs * nbs); -void routing_destroy(struct routing * instance); +int routing_init(struct nbs * nbs); + +void routing_fini(void); + +struct routing_i * routing_i_create(struct pff * pff); + +void routing_i_destroy(struct routing_i * instance); #endif /* OUROBOROS_IPCPD_NORMAL_ROUTING_H */ -- cgit v1.2.3