From 9d2fbef7b8569aac930c95ca1afb92a5dec79dac Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Thu, 2 Mar 2017 15:29:11 +0100 Subject: ipcpd: normal: Add connection manager This adds the connection manager which allows the different AEs of the normal IPCP to register with it. An AE can then use the connection manager to allocate a flow to a neighbor, or to wait for a new connection from a neighbor. --- src/ipcpd/normal/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ipcpd/normal/CMakeLists.txt') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 7e10cc0d..70742336 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -20,6 +20,7 @@ set(SOURCE_FILES # Add source files here addr_auth.c cdap_flow.c + connmgr.c dir.c enroll.c fmgr.c -- cgit v1.2.3 From a409fd81dfc6d22f9a287f15394b86490dea5273 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Thu, 23 Feb 2017 14:31:31 +0100 Subject: ipcpd: normal: Refactor application entities and add neighbors struct This refactors the different Application Entities of the normal IPCP. They all listen to and use the connection manager to establish new application connections. This commit also adds a neighbors struct to the normal IPCP. It contains neighbor structs that contain application connection. Notifiers can be registered in case a neighbor changes (added, removed, QoS changed). The flow manager has an instance of this neighbors struct and listens to these events to update its flow set. The routing component also listens to these events so that it can update the FSDB if needed. The flow manager now also creates the PFF instances and the routing instances per QoS cube. The RIB manager also uses this an instance of the neighbors struct and listens to neighbor events as well. --- src/ipcpd/normal/CMakeLists.txt | 2 + src/ipcpd/normal/connmgr.c | 8 +- src/ipcpd/normal/connmgr.h | 2 +- src/ipcpd/normal/enroll.c | 292 +++++++++++++++++++++++---------------- src/ipcpd/normal/enroll.h | 10 +- src/ipcpd/normal/fmgr.c | 283 +++++++++++++++++++++++--------------- src/ipcpd/normal/fmgr.h | 4 - src/ipcpd/normal/frct.c | 16 +-- src/ipcpd/normal/frct.h | 2 + src/ipcpd/normal/gam.c | 296 +++------------------------------------- src/ipcpd/normal/gam.h | 21 +-- src/ipcpd/normal/main.c | 54 ++++++-- src/ipcpd/normal/neighbors.c | 213 +++++++++++++++++++++++++++++ src/ipcpd/normal/neighbors.h | 81 +++++++++++ src/ipcpd/normal/pff.c | 7 +- src/ipcpd/normal/pff.h | 4 +- src/ipcpd/normal/pol-gam-ops.h | 14 +- src/ipcpd/normal/pol/complete.c | 189 ++++++++++--------------- src/ipcpd/normal/pol/complete.h | 29 ++-- src/ipcpd/normal/ribconfig.h | 2 + src/ipcpd/normal/ribmgr.c | 84 +++++++++--- src/ipcpd/normal/ribmgr.h | 3 - src/ipcpd/normal/routing.c | 132 ++++++++++++++++++ src/ipcpd/normal/routing.h | 42 ++++++ 24 files changed, 1065 insertions(+), 725 deletions(-) create mode 100644 src/ipcpd/normal/neighbors.c create mode 100644 src/ipcpd/normal/neighbors.h create mode 100644 src/ipcpd/normal/routing.c create mode 100644 src/ipcpd/normal/routing.h (limited to 'src/ipcpd/normal/CMakeLists.txt') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 70742336..772d5212 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -27,8 +27,10 @@ set(SOURCE_FILES frct.c gam.c main.c + neighbors.c pff.c ribmgr.c + routing.c shm_pci.c # Add policies last pol/complete.c diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c index 387c38fd..0c908cd1 100644 --- a/src/ipcpd/normal/connmgr.c +++ b/src/ipcpd/normal/connmgr.c @@ -42,8 +42,6 @@ #include #include -#define FRCT_PROTO "frct" - struct ae_conn { struct list_head next; struct conn conn; @@ -272,7 +270,7 @@ void connmgr_ae_destroy(struct ae * ae) int connmgr_alloc(struct ae * ae, char * dst_name, - qosspec_t qs, + qosspec_t * qs, struct conn * conn) { assert(ae); @@ -281,13 +279,13 @@ int connmgr_alloc(struct ae * ae, memset(&conn->conn_info, 0, sizeof(conn->conn_info)); - conn->flow_info.fd = flow_alloc(dst_name, &qs); + conn->flow_info.fd = flow_alloc(dst_name, qs); if (conn->flow_info.fd < 0) { log_err("Failed to allocate flow to %s.", dst_name); return -1; } - conn->flow_info.qs = qs; + conn->flow_info.qs = *qs; if (flow_alloc_res(conn->flow_info.fd)) { log_err("Flow allocation to %s failed.", dst_name); diff --git a/src/ipcpd/normal/connmgr.h b/src/ipcpd/normal/connmgr.h index bfb3d762..5dbf2bcc 100644 --- a/src/ipcpd/normal/connmgr.h +++ b/src/ipcpd/normal/connmgr.h @@ -48,7 +48,7 @@ void connmgr_ae_destroy(struct ae * ae); int connmgr_alloc(struct ae * ae, char * dst_name, - qosspec_t qs, + qosspec_t * qs, struct conn * conn); int connmgr_wait(struct ae * ae, diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c index 9c3b9973..25460161 100644 --- a/src/ipcpd/normal/enroll.c +++ b/src/ipcpd/normal/enroll.c @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include #include @@ -29,29 +31,35 @@ #include #include "ae.h" -#include "cdap_flow.h" +#include "connmgr.h" #include "ribconfig.h" #include #include #include +#include /* Symbolic, will return current time */ #define TIME_NAME "localtime" #define TIME_PATH DLR TIME_NAME #define ENROLL_WARN_TIME_OFFSET 20 -int enroll_handle(int fd) +struct { + struct ae * ae; + pthread_t listener; +} enroll; + +static void * enroll_handle(void * o) { - struct cdap_flow * flow; - struct conn_info info; - cdap_key_t key; - enum cdap_opcode oc; - char * name; - uint8_t * buf; - uint8_t * data; - ssize_t len; - uint32_t flags; + struct cdap * cdap; + struct conn conn; + cdap_key_t key; + enum cdap_opcode oc; + char * name; + uint8_t * buf; + uint8_t * data; + ssize_t len; + uint32_t flags; bool boot_r = false; bool members_r = false; @@ -61,98 +69,107 @@ int enroll_handle(int fd) char * members_ro = MEMBERS_PATH; char * dif_ro = DIF_PATH; - memset(&info, 0, sizeof(info)); - - strcpy(info.ae_name, ENROLL_AE); - strcpy(info.protocol, CDAP_PROTO); - info.pref_version = 1; - info.pref_syntax = PROTO_GPB; + (void) o; - flow = cdap_flow_arr(fd, 0, &info); - if (flow == NULL) { - log_err("Failed to auth enrollment request."); - flow_dealloc(fd); - return -1; - } - - while (!(boot_r && members_r && dif_name_r)) { - key = cdap_request_wait(flow->ci, &oc, &name, &data, - (size_t *) &len , &flags); - assert(key >= 0); - assert(name); - - if (data != NULL) { - free(data); - log_warn("Received data with enrollment request."); - } - - if (oc != CDAP_READ) { - log_warn("Invalid request."); - cdap_reply_send(flow->ci, key, -1, NULL, 0); - cdap_flow_dealloc(flow); - free(name); - return -1; + while (true) { + if (connmgr_wait(enroll.ae, &conn)) { + log_err("Failed to get next connection."); + continue; } - if (strcmp(name, boot_ro) == 0) { - boot_r = true; - } else if (strcmp(name, members_ro) == 0) { - members_r = true; - } else if (strcmp(name, dif_ro) == 0) { - dif_name_r = true; - } else if (strcmp(name, TIME_PATH) == 0) { - struct timespec t; - uint64_t buf[2]; - clock_gettime(CLOCK_REALTIME, &t); - buf[0] = hton64(t.tv_sec); - buf[1] = hton64(t.tv_nsec); - cdap_reply_send(flow->ci, key, 0, buf, sizeof(buf)); - free(name); + cdap = cdap_create(conn.flow_info.fd); + if (cdap == NULL) { + log_err("Failed to instantiate CDAP."); + flow_dealloc(conn.flow_info.fd); continue; - } else { - log_warn("Illegal read: %s.", name); - cdap_reply_send(flow->ci, key, -1, NULL, 0); - cdap_flow_dealloc(flow); - free(name); - return -1; } - len = rib_pack(name, &buf, PACK_HASH_ROOT); - if (len < 0) { - log_err("Failed to pack %s.", name); - cdap_reply_send(flow->ci, key, -1, NULL, 0); - cdap_flow_dealloc(flow); - free(name); - return -1; - } + while (!(boot_r && members_r && dif_name_r)) { + key = cdap_request_wait(cdap, &oc, &name, &data, + (size_t *) &len , &flags); + assert(key >= 0); + assert(name); + + if (data != NULL) { + free(data); + log_warn("Received data with enroll request."); + } + + if (oc != CDAP_READ) { + log_warn("Invalid request."); + cdap_reply_send(cdap, key, -1, NULL, 0); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + free(name); + continue; + } + + if (strcmp(name, boot_ro) == 0) { + boot_r = true; + } else if (strcmp(name, members_ro) == 0) { + members_r = true; + } else if (strcmp(name, dif_ro) == 0) { + dif_name_r = true; + } else if (strcmp(name, TIME_PATH) == 0) { + struct timespec t; + uint64_t buf[2]; + clock_gettime(CLOCK_REALTIME, &t); + buf[0] = hton64(t.tv_sec); + buf[1] = hton64(t.tv_nsec); + cdap_reply_send(cdap, key, 0, buf, sizeof(buf)); + free(name); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + continue; + } else { + log_warn("Illegal read: %s.", name); + cdap_reply_send(cdap, key, -1, NULL, 0); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + free(name); + continue; + } + + len = rib_pack(name, &buf, PACK_HASH_ROOT); + if (len < 0) { + log_err("Failed to pack %s.", name); + cdap_reply_send(cdap, key, -1, NULL, 0); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + free(name); + continue; + } + + log_dbg("Packed %s (%zu bytes).", name, len); - log_dbg("Packed %s (%zu bytes).", name, len); + free(name); - free(name); + if (cdap_reply_send(cdap, key, 0, buf, len)) { + log_err("Failed to send CDAP reply."); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + continue; + } - if (cdap_reply_send(flow->ci, key, 0, buf, len)) { - log_err("Failed to send CDAP reply."); - cdap_flow_dealloc(flow); - return -1; + free(buf); } - free(buf); - } - - log_dbg("Sent boot info to new member."); + log_dbg("Sent boot info to new member."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + } return 0; } int enroll_boot(char * dst_name) { - struct cdap_flow * flow; - struct conn_info info; - cdap_key_t key; - uint8_t * data; - size_t len; + struct cdap * cdap; + cdap_key_t key; + uint8_t * data; + size_t len; + struct conn conn; struct timespec t0; struct timespec rtt; @@ -163,16 +180,14 @@ int enroll_boot(char * dst_name) char * members_ro = MEMBERS_PATH; char * dif_ro = DIF_PATH; - memset(&info, 0, sizeof(info)); - - strcpy(info.ae_name, ENROLL_AE); - strcpy(info.protocol, CDAP_PROTO); - info.pref_version = 1; - info.pref_syntax = PROTO_GPB; + if (connmgr_alloc(enroll.ae, dst_name, NULL, &conn)) { + log_err("Failed to get connection."); + return -1; + } - flow = cdap_flow_alloc(dst_name, NULL, &info); - if (flow == NULL) { - log_err("Failed to allocate flow for enrollment request."); + cdap = cdap_create(conn.flow_info.fd); + if (cdap == NULL) { + log_err("Failed to instantiate CDAP."); return -1; } @@ -180,16 +195,18 @@ int enroll_boot(char * dst_name) clock_gettime(CLOCK_REALTIME, &t0); - key = cdap_request_send(flow->ci, CDAP_READ, TIME_PATH, NULL, 0, 0); + key = cdap_request_send(cdap, CDAP_READ, TIME_PATH, NULL, 0, 0); if (key < 0) { log_err("Failed to send CDAP request."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(flow->ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key, &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } @@ -207,16 +224,18 @@ int enroll_boot(char * dst_name) free(data); - key = cdap_request_send(flow->ci, CDAP_READ, boot_ro, NULL, 0, 0); + key = cdap_request_send(cdap, CDAP_READ, boot_ro, NULL, 0, 0); if (key < 0) { log_err("Failed to send CDAP request."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(flow->ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key, &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } @@ -226,22 +245,25 @@ int enroll_boot(char * dst_name) log_warn("Error unpacking RIB data."); rib_del(boot_ro); free(data); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } log_dbg("Packed information inserted into RIB."); - key = cdap_request_send(flow->ci, CDAP_READ, members_ro, NULL, 0, 0); + key = cdap_request_send(cdap, CDAP_READ, members_ro, NULL, 0, 0); if (key < 0) { log_err("Failed to send CDAP request."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(flow->ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key, &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } @@ -251,22 +273,25 @@ int enroll_boot(char * dst_name) log_warn("Error unpacking RIB data."); rib_del(boot_ro); free(data); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } log_dbg("Packed information inserted into RIB."); - key = cdap_request_send(flow->ci, CDAP_READ, dif_ro, NULL, 0, 0); + key = cdap_request_send(cdap, CDAP_READ, dif_ro, NULL, 0, 0); if (key < 0) { log_err("Failed to send CDAP request."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(flow->ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key, &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } @@ -276,13 +301,52 @@ int enroll_boot(char * dst_name) log_warn("Error unpacking RIB data."); rib_del(boot_ro); free(data); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } log_dbg("Packed information inserted into RIB."); - cdap_flow_dealloc(flow); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + + return 0; +} + +int enroll_init(void) +{ + struct conn_info info; + + memset(&info, 0, sizeof(info)); + + strcpy(info.ae_name, ENROLL_AE); + strcpy(info.protocol, CDAP_PROTO); + info.pref_version = 1; + info.pref_syntax = PROTO_GPB; + + enroll.ae = connmgr_ae_create(info); + if (enroll.ae == NULL) + return -1; + + return 0; +} + +void enroll_fini(void) +{ + connmgr_ae_destroy(enroll.ae); +} + +int enroll_start(void) +{ + if (pthread_create(&enroll.listener, NULL, enroll_handle, NULL)) + return -1; return 0; } + +void enroll_stop(void) +{ + pthread_cancel(enroll.listener); + pthread_join(enroll.listener, NULL); +} diff --git a/src/ipcpd/normal/enroll.h b/src/ipcpd/normal/enroll.h index 2980c380..3c81ae25 100644 --- a/src/ipcpd/normal/enroll.h +++ b/src/ipcpd/normal/enroll.h @@ -22,8 +22,14 @@ #ifndef OUROBOROS_IPCPD_NORMAL_ENROLL_H #define OUROBOROS_IPCPD_NORMAL_ENROLL_H -int enroll_handle(int fd); +int enroll_init(void); -int enroll_boot(char * dst_name); +void enroll_fini(void); + +int enroll_start(void); + +void enroll_stop(void); + +int enroll_boot(char * dst_name); #endif /* OUROBOROS_IPCPD_NORMAL_ENROLL_H */ diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 34724ddd..b7a99f6c 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -31,12 +31,16 @@ #include #include +#include "connmgr.h" #include "fmgr.h" #include "frct.h" #include "ipcp.h" #include "shm_pci.h" -#include "gam.h" #include "ribconfig.h" +#include "pff.h" +#include "neighbors.h" +#include "gam.h" +#include "routing.h" #include #include @@ -48,19 +52,7 @@ typedef FlowAllocMsg flow_alloc_msg_t; #define FD_UPDATE_TIMEOUT 100000 /* nanoseconds */ -struct nm1_flow { - struct list_head next; - int fd; - qosspec_t qs; - struct conn_info * info; -}; - struct { - flow_set_t * nm1_set[QOS_CUBE_MAX]; - fqueue_t * nm1_fqs[QOS_CUBE_MAX]; - struct list_head nm1_flows; - pthread_rwlock_t nm1_flows_lock; - flow_set_t * np1_set[QOS_CUBE_MAX]; fqueue_t * np1_fqs[QOS_CUBE_MAX]; pthread_rwlock_t np1_flows_lock; @@ -69,15 +61,43 @@ struct { int np1_cep_id_to_fd[IPCPD_MAX_CONNS]; pthread_t np1_sdu_reader; + + flow_set_t * nm1_set[QOS_CUBE_MAX]; + fqueue_t * nm1_fqs[QOS_CUBE_MAX]; pthread_t nm1_sdu_reader; - pthread_t nm1_flow_wait; - /* FIXME: Replace with PFF */ - int fd; + struct pff * pff[QOS_CUBE_MAX]; + struct routing * routing[QOS_CUBE_MAX]; struct gam * gam; + struct nbs * nbs; + struct ae * ae; + + struct nb_notifier nb_notifier; } fmgr; +static int fmgr_neighbor_event(enum nb_event event, + struct conn conn) +{ + qoscube_t cube; + + /* We are only interested in neighbors being added and removed. */ + switch (event) { + case NEIGHBOR_ADDED: + ipcp_flow_get_qoscube(conn.flow_info.fd, &cube); + flow_set_add(fmgr.nm1_set[cube], conn.flow_info.fd); + break; + case NEIGHBOR_REMOVED: + ipcp_flow_get_qoscube(conn.flow_info.fd, &cube); + flow_set_del(fmgr.nm1_set[cube], conn.flow_info.fd); + break; + default: + break; + } + + return 0; +} + static void * fmgr_np1_sdu_reader(void * o) { struct shm_du_buff * sdb; @@ -171,12 +191,20 @@ void * fmgr_nm1_sdu_reader(void * o) continue; } - /* - * FIXME: Dropping for now, since - * we don't have a PFF yet - */ - ipcp_flow_del(sdb); - continue; + fd = pff_nhop(fmgr.pff[i], pci.dst_addr); + if (fd < 0) { + log_err("No next hop for %lu", + pci.dst_addr); + ipcp_flow_del(sdb); + continue; + } + + if (ipcp_flow_write(fd, sdb)) { + log_err("Failed to write SDU to fd %d.", + fd); + ipcp_flow_del(sdb); + continue; + } } shm_pci_shrink(sdb); @@ -192,49 +220,6 @@ void * fmgr_nm1_sdu_reader(void * o) return (void *) 0; } -static void * fmgr_nm1_flow_wait(void * o) -{ - qoscube_t cube; - struct conn_info * info; - int fd; - qosspec_t qs; - struct nm1_flow * flow; - - (void) o; - - while (true) { - if (gam_flow_wait(fmgr.gam, &fd, &info, &qs)) { - log_err("Failed to get next flow descriptor."); - continue; - } - - ipcp_flow_get_qoscube(fd, &cube); - flow_set_add(fmgr.nm1_set[cube], fd); - - /* FIXME: Temporary, until we have a PFF */ - fmgr.fd = fd; - - pthread_rwlock_wrlock(&fmgr.nm1_flows_lock); - flow = malloc(sizeof(*flow)); - if (flow == NULL) { - free(info); - pthread_rwlock_unlock(&fmgr.nm1_flows_lock); - continue; - } - - flow->info = info; - flow->fd = fd; - flow->qs = qs; - - list_head_init(&flow->next); - list_add(&flow->next, &fmgr.nm1_flows); - - pthread_rwlock_unlock(&fmgr.nm1_flows_lock); - } - - return (void *) 0; -} - static void fmgr_destroy_flows(void) { int i; @@ -247,12 +232,29 @@ static void fmgr_destroy_flows(void) } } -int fmgr_init(void) +static void fmgr_destroy_routing(void) { - enum pol_gam pg; + int i; + + for (i = 0; i < QOS_CUBE_MAX; ++i) + routing_destroy(fmgr.routing[i]); +} +static void fmgr_destroy_pff(void) +{ int i; + for (i = 0; i < QOS_CUBE_MAX; ++i) + pff_destroy(fmgr.pff[i]); +} + +int fmgr_init(void) +{ + enum pol_gam pg; + int i; + int j; + struct conn_info info; + for (i = 0; i < AP_MAX_FLOWS; ++i) fmgr.np1_fd_to_cep_id[i] = INVALID_CEP_ID; @@ -288,63 +290,116 @@ int fmgr_init(void) if (rib_read(BOOT_PATH "/dt/gam/type", &pg, sizeof(pg)) != sizeof(pg)) { log_err("Failed to read policy for ribmgr gam."); + fmgr_destroy_flows(); return -1; } - fmgr.gam = gam_create(pg); - if (fmgr.gam == NULL) { - log_err("Failed to create graph adjacency manager."); + strcpy(info.ae_name, DT_AE); + strcpy(info.protocol, FRCT_PROTO); + info.pref_version = 1; + info.pref_syntax = PROTO_FIXED; + info.addr = ipcpi.dt_addr; + + fmgr.ae = connmgr_ae_create(info); + if (fmgr.ae == NULL) { + log_err("Failed to create AE struct."); fmgr_destroy_flows(); return -1; } - list_head_init(&fmgr.nm1_flows); + fmgr.nbs = nbs_create(); + if (fmgr.nbs == NULL) { + log_err("Failed to create neighbors struct."); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } - pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL); - pthread_rwlock_init(&fmgr.np1_flows_lock, NULL); + fmgr.nb_notifier.notify_call = fmgr_neighbor_event; + if (nbs_reg_notifier(fmgr.nbs, &fmgr.nb_notifier)) { + log_err("Failed to register notifier."); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } + + if (pthread_rwlock_init(&fmgr.np1_flows_lock, NULL)) { + gam_destroy(fmgr.gam); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } + + for (i = 0; i < QOS_CUBE_MAX; ++i) { + fmgr.pff[i] = pff_create(); + if (fmgr.pff[i] == NULL) { + for (j = 0; j < i; ++j) + pff_destroy(fmgr.pff[j]); + pthread_rwlock_destroy(&fmgr.np1_flows_lock); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } + + fmgr.routing[i] = routing_create(fmgr.pff[i], fmgr.nbs); + if (fmgr.routing[i] == NULL) { + for (j = 0; j < i; ++j) + routing_destroy(fmgr.routing[j]); + fmgr_destroy_pff(); + pthread_rwlock_destroy(&fmgr.np1_flows_lock); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } + } + + fmgr.gam = gam_create(pg, fmgr.nbs, fmgr.ae); + if (fmgr.gam == NULL) { + log_err("Failed to init dt graph adjacency manager."); + fmgr_destroy_routing(); + fmgr_destroy_pff(); + pthread_rwlock_destroy(&fmgr.np1_flows_lock); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } pthread_create(&fmgr.np1_sdu_reader, NULL, fmgr_np1_sdu_reader, NULL); pthread_create(&fmgr.nm1_sdu_reader, NULL, fmgr_nm1_sdu_reader, NULL); - pthread_create(&fmgr.nm1_flow_wait, NULL, fmgr_nm1_flow_wait, NULL); return 0; } void fmgr_fini() { - struct list_head * pos = NULL; - struct list_head * n = NULL; - qoscube_t cube; - pthread_cancel(fmgr.np1_sdu_reader); pthread_cancel(fmgr.nm1_sdu_reader); - pthread_cancel(fmgr.nm1_flow_wait); pthread_join(fmgr.np1_sdu_reader, NULL); pthread_join(fmgr.nm1_sdu_reader, NULL); - pthread_join(fmgr.nm1_flow_wait, NULL); - gam_destroy(fmgr.gam); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); - pthread_rwlock_wrlock(&fmgr.nm1_flows_lock); - - list_for_each_safe(pos, n, &fmgr.nm1_flows) { - struct nm1_flow * flow = - list_entry(pos, struct nm1_flow, next); - list_del(&flow->next); - flow_dealloc(flow->fd); - ipcp_flow_get_qoscube(flow->fd, &cube); - flow_set_del(fmgr.nm1_set[cube], flow->fd); - free(flow->info); - free(flow); - } + gam_destroy(fmgr.gam); - pthread_rwlock_unlock(&fmgr.nm1_flows_lock); + fmgr_destroy_routing(); - pthread_rwlock_destroy(&fmgr.nm1_flows_lock); - pthread_rwlock_destroy(&fmgr.np1_flows_lock); + fmgr_destroy_pff(); fmgr_destroy_flows(); + + connmgr_ae_destroy(fmgr.ae); + + nbs_destroy(fmgr.nbs); } int fmgr_np1_alloc(int fd, @@ -601,24 +656,20 @@ int fmgr_np1_post_sdu(cep_id_t cep_id, return 0; } -int fmgr_nm1_flow_arr(int fd, - qosspec_t qs) -{ - assert(fmgr.gam); - - if (gam_flow_arr(fmgr.gam, fd, qs)) { - log_err("Failed to hand to graph adjacency manager."); - return -1; - } - - return 0; -} - int fmgr_nm1_write_sdu(struct pci * pci, struct shm_du_buff * sdb) { + int fd; + if (pci == NULL || sdb == NULL) + return -EINVAL; + + fd = pff_nhop(fmgr.pff[pci->qos_id], pci->dst_addr); + if (fd < 0) { + log_err("Could not get nhop for address %lu", pci->dst_addr); + ipcp_flow_del(sdb); return -1; + } if (shm_pci_ser(sdb, pci)) { log_err("Failed to serialize PDU."); @@ -626,8 +677,8 @@ int fmgr_nm1_write_sdu(struct pci * pci, return -1; } - if (ipcp_flow_write(fmgr.fd, sdb)) { - log_err("Failed to write SDU to fd %d.", fmgr.fd); + if (ipcp_flow_write(fd, sdb)) { + log_err("Failed to write SDU to fd %d.", fd); ipcp_flow_del(sdb); return -1; } @@ -639,9 +690,17 @@ int fmgr_nm1_write_buf(struct pci * pci, buffer_t * buf) { buffer_t * buffer; + int fd; if (pci == NULL || buf == NULL || buf->data == NULL) + return -EINVAL; + + fd = pff_nhop(fmgr.pff[pci->qos_id], pci->dst_addr); + if (fd < 0) { + log_err("Could not get nhop for address %lu", pci->dst_addr); + free(buf->data); return -1; + } buffer = shm_pci_ser_buf(buf, pci); if (buffer == NULL) { @@ -650,7 +709,7 @@ int fmgr_nm1_write_buf(struct pci * pci, return -1; } - if (flow_write(fmgr.fd, buffer->data, buffer->len) == -1) { + if (flow_write(fd, buffer->data, buffer->len) == -1) { log_err("Failed to write buffer to fd."); free(buffer); return -1; diff --git a/src/ipcpd/normal/fmgr.h b/src/ipcpd/normal/fmgr.h index e75417f3..06eab0a1 100644 --- a/src/ipcpd/normal/fmgr.h +++ b/src/ipcpd/normal/fmgr.h @@ -53,8 +53,4 @@ int fmgr_nm1_write_sdu(struct pci * pci, int fmgr_nm1_write_buf(struct pci * pci, buffer_t * buf); -int fmgr_nm1_flow_arr(int fd, - qosspec_t qs); - - #endif /* OUROBOROS_IPCPD_NORMAL_FMGR_H */ diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c index c9b23060..b5a42db4 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -198,12 +198,12 @@ int frct_fini() return 0; } -int frct_nm1_post_sdu(struct pci * pci, +int frct_nm1_post_sdu(struct pci * pci, struct shm_du_buff * sdb) { struct frct_i * instance; - buffer_t buf; - cep_id_t id; + buffer_t buf; + cep_id_t id; if (pci == NULL || sdb == NULL) return -1; @@ -267,8 +267,8 @@ cep_id_t frct_i_create(uint64_t address, qoscube_t cube) { struct frct_i * instance; - struct pci pci; - cep_id_t id; + struct pci pci; + cep_id_t id; if (buf == NULL || buf->data == NULL) return INVALID_CEP_ID; @@ -304,7 +304,7 @@ int frct_i_accept(cep_id_t id, buffer_t * buf, qoscube_t cube) { - struct pci pci; + struct pci pci; struct frct_i * instance; if (buf == NULL || buf->data == NULL) @@ -347,7 +347,7 @@ int frct_i_accept(cep_id_t id, int frct_i_destroy(cep_id_t id, buffer_t * buf) { - struct pci pci; + struct pci pci; struct frct_i * instance; pthread_mutex_lock(&frct.instances_lock); @@ -390,7 +390,7 @@ int frct_i_destroy(cep_id_t id, int frct_i_write_sdu(cep_id_t id, struct shm_du_buff * sdb) { - struct pci pci; + struct pci pci; struct frct_i * instance; if (sdb == NULL) diff --git a/src/ipcpd/normal/frct.h b/src/ipcpd/normal/frct.h index 462b8cc3..d85d11f5 100644 --- a/src/ipcpd/normal/frct.h +++ b/src/ipcpd/normal/frct.h @@ -27,6 +27,8 @@ #include "shm_pci.h" +#define FRCT_PROTO "FRCT" + struct frct_i; int frct_init(void); diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c index 212cfd83..cb4e662f 100644 --- a/src/ipcpd/normal/gam.c +++ b/src/ipcpd/normal/gam.c @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Data transfer graph adjacency manager * * Dimitri Staessens * Sander Vrijders @@ -20,7 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define OUROBOROS_PREFIX "graph-adjacency-manager" +#define OUROBOROS_PREFIX "dt-gam" #include #include @@ -40,305 +40,43 @@ #include #include -struct ga { - struct list_head next; - - qosspec_t qs; - int fd; - struct conn_info * info; -}; - struct gam { - struct list_head gas; - pthread_mutex_t gas_lock; - pthread_cond_t gas_cond; - struct pol_gam_ops * ops; void * ops_o; }; -struct gam * gam_create(enum pol_gam gam_type) +struct gam * gam_create(enum pol_gam gam_type, + struct nbs * nbs, + struct ae * ae) { - struct gam * tmp; + struct gam * gam; - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) + gam = malloc(sizeof(*gam)); + if (gam == NULL) return NULL; switch (gam_type) { case COMPLETE: - tmp->ops = &complete_ops; + gam->ops = &complete_ops; break; default: log_err("Unknown gam policy: %d.", gam_type); - free(tmp); - return NULL; - } - - list_head_init(&tmp->gas); - - if (pthread_mutex_init(&tmp->gas_lock, NULL)) { - free(tmp); - return NULL; - } - - if (pthread_cond_init(&tmp->gas_cond, NULL)) { - pthread_mutex_destroy(&tmp->gas_lock); - free(tmp); return NULL; } - tmp->ops_o = tmp->ops->create(tmp); - if (tmp->ops_o == NULL) { - pthread_cond_destroy(&tmp->gas_cond); - pthread_mutex_destroy(&tmp->gas_lock); - free(tmp); + gam->ops_o = gam->ops->create(nbs, ae); + if (gam->ops_o == NULL) { + free(gam); return NULL; } - if (tmp->ops->start(tmp->ops_o)) { - pthread_cond_destroy(&tmp->gas_cond); - pthread_mutex_destroy(&tmp->gas_lock); - free(tmp); - return NULL; - } - - return tmp; -} - -void gam_destroy(struct gam * instance) -{ - struct list_head * p = NULL; - struct list_head * n = NULL; - - assert(instance); - - instance->ops->stop(instance->ops_o); - - pthread_mutex_lock(&instance->gas_lock); - - list_for_each_safe(p, n, &instance->gas) { - struct ga * e = list_entry(p, struct ga, next); - list_del(&e->next); - free(e->info); - free(e); - } - - pthread_mutex_unlock(&instance->gas_lock); - - pthread_mutex_destroy(&instance->gas_lock); - pthread_cond_destroy(&instance->gas_cond); - - instance->ops->destroy(instance->ops_o); - free(instance); -} - -static int add_ga(struct gam * instance, - int fd, - qosspec_t qs, - struct conn_info * info) -{ - struct ga * ga; - - ga = malloc(sizeof(*ga)); - if (ga == NULL) - return -ENOMEM; - - ga->fd = fd; - ga->info = info; - ga->qs = qs; - - list_head_init(&ga->next); - - pthread_mutex_lock(&instance->gas_lock); - list_add(&ga->next, &instance->gas); - pthread_cond_signal(&instance->gas_cond); - pthread_mutex_unlock(&instance->gas_lock); - - log_info("Added flow."); - - return 0; -} - -int gam_flow_arr(struct gam * instance, - int fd, - qosspec_t qs) -{ - struct conn_info * rcv_info; - struct conn_info snd_info; - - if (flow_alloc_resp(fd, instance->ops->accept_new_flow(instance->ops_o)) - < 0) { - log_err("Could not respond to new flow."); - return -1; - } - - rcv_info = malloc(sizeof(*rcv_info)); - if (rcv_info == NULL) - return -ENOMEM; - - memset(&snd_info, 0, sizeof(snd_info)); - memset(rcv_info, 0, sizeof(*rcv_info)); - - /* FIXME: send correct AE */ - strcpy(snd_info.ae_name, "FIXME:CORRECT_AE"); - strcpy(snd_info.protocol, CDAP_PROTO); - snd_info.pref_version = 1; - snd_info.pref_syntax = PROTO_GPB; - snd_info.addr = ipcpi.dt_addr; - - if (cacep_rcv(fd, rcv_info)) { - log_err("Error establishing application connection."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (cacep_snd(fd, &snd_info)) { - log_err("Failed to respond to application connection request."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (strcmp(snd_info.ae_name, rcv_info->ae_name)) { - log_err("Received connection for wrong AE."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (strcmp(snd_info.protocol, rcv_info->protocol) || - snd_info.pref_version != rcv_info->pref_version || - snd_info.pref_syntax != rcv_info->pref_syntax) { - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (instance->ops->accept_flow(instance->ops_o, qs, rcv_info)) { - flow_dealloc(fd); - free(rcv_info); - return 0; - } - - if (add_ga(instance, fd, qs, rcv_info)) { - log_err("Failed to add ga to graph adjacency manager list."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - return 0; + return gam; } -int gam_flow_alloc(struct gam * instance, - char * dst_name, - qosspec_t qs) +void gam_destroy(struct gam * gam) { - struct conn_info * rcv_info; - struct conn_info snd_info; - int fd; - - log_dbg("Allocating flow to %s.", dst_name); - - rcv_info = malloc(sizeof(*rcv_info)); - if (rcv_info == NULL) - return -ENOMEM; - - fd = flow_alloc(dst_name, NULL); - if (fd < 0) { - log_err("Failed to allocate flow to %s.", dst_name); - return -1; - } - - if (flow_alloc_res(fd)) { - log_err("Flow allocation to %s failed.", dst_name); - flow_dealloc(fd); - return -1; - } - - memset(&snd_info, 0, sizeof(snd_info)); - memset(rcv_info, 0, sizeof(*rcv_info)); - - /* FIXME: send correct AE */ - strcpy(snd_info.ae_name, "FIXME:CORRECT_AE"); - strcpy(snd_info.protocol, CDAP_PROTO); - snd_info.pref_version = 1; - snd_info.pref_syntax = PROTO_GPB; - snd_info.addr = ipcpi.dt_addr; - - if (cacep_snd(fd, &snd_info)) { - log_err("Failed to create application connection."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (cacep_rcv(fd, rcv_info)) { - log_err("Failed to connect to application."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (strcmp(snd_info.protocol, rcv_info->protocol) || - snd_info.pref_version != rcv_info->pref_version || - snd_info.pref_syntax != rcv_info->pref_syntax) { - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - if (instance->ops->accept_flow(instance->ops_o, qs, rcv_info)) { - flow_dealloc(fd); - free(rcv_info); - return 0; - } - - if (add_ga(instance, fd, qs, rcv_info)) { - log_err("Failed to add GA to graph adjacency manager list."); - flow_dealloc(fd); - free(rcv_info); - return -1; - } - - return 0; -} - -int gam_flow_wait(struct gam * instance, - int * fd, - struct conn_info ** info, - qosspec_t * qs) -{ - struct ga * ga; - - assert(fd); - assert(info); - assert(qs); - - pthread_mutex_lock(&instance->gas_lock); - - pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, - (void *) &instance->gas_lock); - - while (list_is_empty(&instance->gas)) - pthread_cond_wait(&instance->gas_cond, &instance->gas_lock); - - ga = list_first_entry((&instance->gas), struct ga, next); - if (ga == NULL) { - pthread_mutex_unlock(&instance->gas_lock); - return -1; - } - - *fd = ga->fd; - *info = ga->info; - *qs = ga->qs; - - list_del(&ga->next); - free(ga); - - pthread_cleanup_pop(true); + assert(gam); - return 0; + gam->ops->destroy(gam->ops_o); + free(gam); } diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h index 58b028b9..01a6e40e 100644 --- a/src/ipcpd/normal/gam.h +++ b/src/ipcpd/normal/gam.h @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Data transfer graph adjacency manager * * Dimitri Staessens * Sander Vrijders @@ -26,21 +26,12 @@ #include #include -struct gam * gam_create(enum pol_gam gam_type); +#include "neighbors.h" -void gam_destroy(struct gam * instance); +struct gam * gam_create(enum pol_gam gam_type, + struct nbs * nbs, + struct ae * ae); -int gam_flow_arr(struct gam * instance, - int fd, - qosspec_t qs); - -int gam_flow_alloc(struct gam * instance, - char * dst_name, - qosspec_t qs); - -int gam_flow_wait(struct gam * instance, - int * fd, - struct conn_info ** info, - qosspec_t * qs); +void gam_destroy(struct gam * gam); #endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 3e5907a8..8b9a7c09 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -105,11 +105,6 @@ static int boot_components(void) log_dbg("Starting components."); - if (connmgr_init()) { - log_err("Failed to init ap connection manager"); - return -1; - } - if (rib_read(BOOT_PATH "/addr_auth/type", &pa, sizeof(pa)) != sizeof(pa)) { log_err("Failed to read policy for address authority."); @@ -126,7 +121,6 @@ static int boot_components(void) if (ipcpi.dt_addr == 0) { log_err("Failed to get a valid address."); addr_auth_fini(); - connmgr_fini(); return -1; } @@ -137,7 +131,6 @@ static int boot_components(void) if (ribmgr_init()) { log_err("Failed to initialize RIB manager."); addr_auth_fini(); - connmgr_fini(); return -1; } @@ -145,7 +138,6 @@ static int boot_components(void) log_err("Failed to initialize directory."); ribmgr_fini(); addr_auth_fini(); - connmgr_fini(); return -1; } @@ -155,7 +147,6 @@ static int boot_components(void) dir_fini(); ribmgr_fini(); addr_auth_fini(); - connmgr_fini(); log_err("Failed to start flow manager."); return -1; } @@ -165,20 +156,29 @@ static int boot_components(void) dir_fini(); ribmgr_fini(); addr_auth_fini(); - connmgr_fini(); log_err("Failed to initialize FRCT."); return -1; } + if (enroll_start()) { + fmgr_fini(); + dir_fini(); + ribmgr_fini(); + addr_auth_fini(); + log_err("Failed to start enroll."); + return -1; + } + ipcp_set_state(IPCP_OPERATIONAL); if (connmgr_start()) { ipcp_set_state(IPCP_INIT); + enroll_stop(); + frct_fini(); fmgr_fini(); dir_fini(); ribmgr_fini(); addr_auth_fini(); - connmgr_fini(); log_err("Failed to start AP connection manager."); return -1; } @@ -190,6 +190,8 @@ void shutdown_components(void) { connmgr_stop(); + enroll_stop(); + frct_fini(); fmgr_fini(); @@ -199,8 +201,6 @@ void shutdown_components(void) ribmgr_fini(); addr_auth_fini(); - - connmgr_fini(); } static int normal_ipcp_enroll(char * dst_name) @@ -418,11 +418,33 @@ int main(int argc, exit(EXIT_FAILURE); } + + if (connmgr_init()) { + log_err("Failed to initialize connection manager."); + ipcp_create_r(getpid(), -1); + rib_fini(); + irm_unbind_api(getpid(), ipcpi.name); + ipcp_fini(); + exit(EXIT_FAILURE); + } + + if (enroll_init()) { + log_err("Failed to initialize enroll component."); + ipcp_create_r(getpid(), -1); + connmgr_fini(); + rib_fini(); + irm_unbind_api(getpid(), ipcpi.name); + ipcp_fini(); + exit(EXIT_FAILURE); + } + pthread_sigmask(SIG_BLOCK, &sigset, NULL); if (ipcp_boot() < 0) { log_err("Failed to boot IPCP."); ipcp_create_r(getpid(), -1); + enroll_fini(); + connmgr_fini(); rib_fini(); irm_unbind_api(getpid(), ipcpi.name); ipcp_fini(); @@ -435,6 +457,8 @@ int main(int argc, log_err("Failed to notify IRMd we are initialized."); ipcp_set_state(IPCP_NULL); ipcp_shutdown(); + enroll_fini(); + connmgr_fini(); rib_fini(); irm_unbind_api(getpid(), ipcpi.name); ipcp_fini(); @@ -448,6 +472,10 @@ int main(int argc, rib_fini(); + connmgr_fini(); + + enroll_fini(); + irm_unbind_api(getpid(), ipcpi.name); ipcp_fini(); diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c new file mode 100644 index 00000000..40ef0d73 --- /dev/null +++ b/src/ipcpd/normal/neighbors.c @@ -0,0 +1,213 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "neighbors" + +#include +#include +#include +#include +#include + +#include "neighbors.h" + +#include +#include +#include + +static void notify_listeners(enum nb_event event, + struct nb * nb, + struct nbs * nbs) +{ + struct list_head * p = NULL; + + list_for_each(p, &nbs->notifiers) { + struct nb_notifier * e = + list_entry(p, struct nb_notifier, next); + if (e->notify_call(event, nb->conn)) + log_err("Listener reported an error."); + } +} + +struct nbs * nbs_create(void) +{ + struct nbs * nbs; + + nbs = malloc(sizeof(*nbs)); + if (nbs == NULL) + return NULL; + + list_head_init(&nbs->list); + list_head_init(&nbs->notifiers); + + if (pthread_mutex_init(&nbs->list_lock, NULL)) + return NULL; + + if (pthread_mutex_init(&nbs->notifiers_lock, NULL)) { + pthread_mutex_destroy(&nbs->list_lock); + return NULL; + } + + return nbs; +} + +void nbs_destroy(struct nbs * nbs) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each_safe(p, n, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + list_del(&e->next); + free(e); + } + + pthread_mutex_unlock(&nbs->list_lock); + + pthread_mutex_destroy(&nbs->list_lock); + pthread_mutex_destroy(&nbs->notifiers_lock); +} + +int nbs_add(struct nbs * nbs, + struct conn conn) +{ + struct nb * nb; + + assert(nbs); + + nb = malloc(sizeof(*nb)); + if (nb == NULL) + return -ENOMEM; + + nb->conn = conn; + + list_head_init(&nb->next); + + pthread_mutex_lock(&nbs->list_lock); + + list_add(&nb->next, &nbs->list); + + notify_listeners(NEIGHBOR_ADDED, nb, nbs); + + pthread_mutex_unlock(&nbs->list_lock); + + log_info("Added neighbor with address %" PRIu64 " to list.", + conn.conn_info.addr); + + return 0; +} + +int nbs_update_qos(struct nbs * nbs, + int fd, + qosspec_t qs) +{ + struct list_head * p = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each(p, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + if (e->conn.flow_info.fd == fd) { + e->conn.flow_info.qs = qs; + + notify_listeners(NEIGHBOR_QOS_CHANGE, e, nbs); + + pthread_mutex_unlock(&nbs->list_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->list_lock); + + return -1; +} + +int nbs_del(struct nbs * nbs, + int fd) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each_safe(p, n, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + if (e->conn.flow_info.fd == fd) { + notify_listeners(NEIGHBOR_REMOVED, e, nbs); + list_del(&e->next); + free(e); + pthread_mutex_unlock(&nbs->list_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->list_lock); + + return -1; +} + +int nbs_reg_notifier(struct nbs * nbs, + struct nb_notifier * notify) +{ + assert(nbs); + assert(notify); + + pthread_mutex_lock(&nbs->notifiers_lock); + + list_head_init(¬ify->next); + list_add(¬ify->next, &nbs->notifiers); + + pthread_mutex_unlock(&nbs->notifiers_lock); + + return 0; +} + +int nbs_unreg_notifier(struct nbs * nbs, + struct nb_notifier * notify) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + pthread_mutex_lock(&nbs->notifiers_lock); + + list_for_each_safe(p, n, &nbs->notifiers) { + struct nb_notifier * e = + list_entry(p, struct nb_notifier, next); + if (e == notify) { + list_del(&e->next); + pthread_mutex_unlock(&nbs->notifiers_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->notifiers_lock); + + return -1; +} diff --git a/src/ipcpd/normal/neighbors.h b/src/ipcpd/normal/neighbors.h new file mode 100644 index 00000000..743bc7b8 --- /dev/null +++ b/src/ipcpd/normal/neighbors.h @@ -0,0 +1,81 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_NEIGHBORS_H +#define OUROBOROS_IPCPD_NORMAL_NEIGHBORS_H + +#include +#include +#include +#include +#include + +#include "connmgr.h" + +enum nb_event { + NEIGHBOR_ADDED, + NEIGHBOR_REMOVED, + NEIGHBOR_QOS_CHANGE +}; + +typedef int (* nb_notify_t)(enum nb_event event, + struct conn conn); + +struct nb_notifier { + struct list_head next; + nb_notify_t notify_call; +}; + +struct nb { + struct list_head next; + struct conn conn; +}; + +struct nbs { + struct list_head notifiers; + pthread_mutex_t notifiers_lock; + + struct list_head list; + pthread_mutex_t list_lock; +}; + +struct nbs * nbs_create(void); + +void nbs_destroy(struct nbs * nbs); + +int nbs_add(struct nbs * nbs, + struct conn conn); + +int nbs_update_qos(struct nbs * nbs, + int fd, + qosspec_t qs); + +int nbs_del(struct nbs * nbs, + int fd); + +int nbs_reg_notifier(struct nbs * nbs, + struct nb_notifier * notify); + +int nbs_unreg_notifier(struct nbs * nbs, + struct nb_notifier * notify); + +#endif diff --git a/src/ipcpd/normal/pff.c b/src/ipcpd/normal/pff.c index 2f7d554b..b44f79bf 100644 --- a/src/ipcpd/normal/pff.c +++ b/src/ipcpd/normal/pff.c @@ -55,15 +55,16 @@ struct pff * pff_create(void) return tmp; } -int pff_destroy(struct pff * instance) +void pff_destroy(struct pff * instance) { assert(instance); + pthread_mutex_lock(&instance->lock); htable_destroy(instance->table); + pthread_mutex_unlock(&instance->lock); + pthread_mutex_destroy(&instance->lock); free(instance); - - return 0; } int pff_add(struct pff * instance, uint64_t addr, int fd) diff --git a/src/ipcpd/normal/pff.h b/src/ipcpd/normal/pff.h index b4a1400b..d4edb90c 100644 --- a/src/ipcpd/normal/pff.h +++ b/src/ipcpd/normal/pff.h @@ -25,8 +25,6 @@ #include -struct pff; - /* * PFF will take a type in the future, * to allow different policies. @@ -34,7 +32,7 @@ struct pff; */ struct pff * pff_create(void); -int pff_destroy(struct pff * instance); +void pff_destroy(struct pff * instance); int pff_add(struct pff * instance, uint64_t addr, diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h index 264f252b..a7753b8b 100644 --- a/src/ipcpd/normal/pol-gam-ops.h +++ b/src/ipcpd/normal/pol-gam-ops.h @@ -24,21 +24,13 @@ #define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H #include +#include struct pol_gam_ops { - void * (* create)(struct gam * instance); + void * (* create)(struct nbs * nbs, + struct ae * ae); void (* destroy)(void * o); - - int (* start)(void * o); - - int (* stop)(void * o); - - int (* accept_new_flow)(void * o); - - int (* accept_flow)(void * o, - qosspec_t qs, - const struct conn_info * info); }; #endif /* OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H */ diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c index daf8c9bf..f84c3a23 100644 --- a/src/ipcpd/normal/pol/complete.c +++ b/src/ipcpd/normal/pol/complete.c @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Sets up a complete graph * * Dimitri Staessens * Sander Vrijders @@ -20,35 +20,54 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define OUROBOROS_PREFIX "complete-graph-adjacency-manager" +#define OUROBOROS_PREFIX "complete" #include -#include -#include -#include +#include #include +#include +#include +#include +#include -#include "ipcp.h" -#include "gam.h" +#include "neighbors.h" +#include "frct.h" #include "ribconfig.h" +#include "ipcp.h" +#include "ae.h" #include #include #include -struct neighbor { - struct list_head next; - uint64_t neighbor; +struct complete { + struct nbs * nbs; + struct ae * ae; + pthread_t allocator; + pthread_t listener; }; -struct complete { - struct list_head neighbors; - pthread_mutex_t neighbors_lock; +static void * listener(void * o) +{ + struct complete * complete; + struct conn conn; - pthread_t allocator; + complete = (struct complete *) o; - struct gam * gam; -}; + while (true) { + if (connmgr_wait(complete->ae, &conn)) { + log_err("Error while getting next connection."); + continue; + } + + if (nbs_add(complete->nbs, conn)) { + log_err("Failed to add neighbor."); + continue; + } + } + + return (void *) 0; +} static void * allocator(void * o) { @@ -56,10 +75,10 @@ static void * allocator(void * o) ssize_t len; char ** children; ssize_t i; - struct complete * complete = (struct complete *) o; + struct complete * complete; + struct conn conn; - assert(complete); - assert(complete->gam); + complete = (struct complete *) o; qs.delay = 0; qs.jitter = 0; @@ -67,8 +86,23 @@ static void * allocator(void * o) /* FIXME: subscribe to members to keep the graph complete. */ len = rib_children("/" MEMBERS_NAME, &children); for (i = 0; i < len; ++i) { - if (strcmp(children[i], ipcpi.name) < 0) - gam_flow_alloc(complete->gam, children[i], qs); + if (strcmp(children[i], ipcpi.name) < 0) { + if (connmgr_alloc(complete->ae, + children[i], + &qs, + &conn)) { + log_warn("Failed to get a conn to neighbor."); + free(children[i]); + continue; + } + + if (nbs_add(complete->nbs, conn)) { + log_err("Failed to add neighbor."); + free(children[i]); + continue; + } + + } free(children[i]); } @@ -78,118 +112,41 @@ static void * allocator(void * o) return (void *) 0; } -void * complete_create(struct gam * gam) +void * complete_create(struct nbs * nbs, + struct ae * ae) { struct complete * complete; - assert(gam); - complete = malloc(sizeof(*complete)); if (complete == NULL) return NULL; - list_head_init(&complete->neighbors); - complete->gam = gam; - - if (pthread_mutex_init(&complete->neighbors_lock, NULL)) { - free(complete); - return NULL; - } - - return (void *) complete; -} - -int complete_start(void * o) -{ - struct complete * complete = (struct complete *) o; - - assert(complete); - assert(complete->gam); + complete->nbs = nbs; + complete->ae = ae; if (pthread_create(&complete->allocator, NULL, - allocator, (void *) complete)) { - pthread_mutex_destroy(&complete->neighbors_lock); - free(complete); - return -1; - } + allocator, (void *) complete)) + return NULL; - /* FIXME: Handle flooding of the flow allocator before detaching.*/ - pthread_join(complete->allocator, NULL); + if (pthread_create(&complete->listener, NULL, + listener, (void *) complete)) + return NULL; - return 0; + return complete; } -int complete_stop(void * o) +void complete_destroy(void * ops_o) { - (void) o; + struct complete * complete; - return 0; -} + assert(ops_o); -void complete_destroy(void * o) -{ - struct list_head * p = NULL; - struct list_head * n = NULL; - struct complete * complete = (struct complete *) o; - - list_for_each_safe(p, n, &complete->neighbors) { - struct neighbor * e = list_entry(p, struct neighbor, next); - list_del(&e->next); - free(e); - } + complete = (struct complete *) ops_o; - pthread_mutex_destroy(&complete->neighbors_lock); + pthread_cancel(complete->allocator); + pthread_cancel(complete->listener); + pthread_join(complete->allocator, NULL); + pthread_join(complete->listener, NULL); free(complete); } - -int complete_accept_new_flow(void * o) -{ - (void) o; - - return 0; -} - -int complete_accept_flow(void * o, - qosspec_t qs, - const struct conn_info * info) -{ - struct list_head * pos = NULL; - struct neighbor * n; - struct complete * complete = (struct complete *) o; - - (void) qs; - - assert(complete); - - pthread_mutex_lock(&complete->neighbors_lock); - - list_for_each(pos, &complete->neighbors) { - struct neighbor * e = list_entry(pos, struct neighbor, next); - /* FIXME: figure out union type and check name or address */ - if (e->neighbor == info->addr) { - pthread_mutex_unlock(&complete->neighbors_lock); - return -1; - } - - assert(complete); - assert(&complete->neighbors_lock); - assert(pos->nxt); - } - - n = malloc(sizeof(*n)); - if (n == NULL) { - pthread_mutex_unlock(&complete->neighbors_lock); - return -1; - } - - list_head_init(&n->next); - - n->neighbor = info->addr; - - list_add(&n->next, &complete->neighbors); - - pthread_mutex_unlock(&complete->neighbors_lock); - - return 0; -} diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h index 8fe1437f..40aca69d 100644 --- a/src/ipcpd/normal/pol/complete.h +++ b/src/ipcpd/normal/pol/complete.h @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Sets up a complete graph * * Dimitri Staessens * Sander Vrijders @@ -23,30 +23,19 @@ #ifndef OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H #define OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H -#include "gam.h" -#include "pol-gam-ops.h" - -void * complete_create(struct gam * instance); - -void complete_destroy(void * o); +#include +#include -int complete_start(void * o); - -int complete_stop(void * o); +#include "pol-gam-ops.h" -int complete_accept_new_flow(void * o); +void * complete_create(struct nbs * nbs, + struct ae * ae); -int complete_accept_flow(void * o, - qosspec_t qs, - const struct conn_info * info); +void complete_destroy(void * ops_o); struct pol_gam_ops complete_ops = { - .create = complete_create, - .destroy = complete_destroy, - .start = complete_start, - .stop = complete_stop, - .accept_new_flow = complete_accept_new_flow, - .accept_flow = complete_accept_flow + .create = complete_create, + .destroy = complete_destroy }; #endif /* OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H */ diff --git a/src/ipcpd/normal/ribconfig.h b/src/ipcpd/normal/ribconfig.h index 15b65ce2..5ecdaab3 100644 --- a/src/ipcpd/normal/ribconfig.h +++ b/src/ipcpd/normal/ribconfig.h @@ -31,9 +31,11 @@ #define MEMBERS_NAME "members" #define DIF_NAME "dif_name" #define DIR_NAME "directory" +#define ROUTING_NAME "fsdb" #define DIF_PATH DLR DIF_NAME #define DIR_PATH DLR DIR_NAME #define BOOT_PATH DLR BOOT_NAME #define MEMBERS_PATH DLR MEMBERS_NAME +#define ROUTING_PATH DLR ROUTING_NAME #endif /* OUROBOROS_IPCPD_NORMAL_RIB_CONFIG_H */ diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 25f1687e..e8fa77a4 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -45,25 +45,70 @@ #include struct { - flow_set_t * fs; - fqueue_t * fq; - struct gam * gam; + flow_set_t * fs; + fqueue_t * fq; + + struct gam * gam; + struct nbs * nbs; + struct ae * ae; + + struct nb_notifier nb_notifier; } ribmgr; +static int ribmgr_neighbor_event(enum nb_event event, + struct conn conn) +{ + /* We are only interested in neighbors being added and removed. */ + switch (event) { + case NEIGHBOR_ADDED: + flow_set_add(ribmgr.fs, conn.flow_info.fd); + break; + case NEIGHBOR_REMOVED: + flow_set_del(ribmgr.fs, conn.flow_info.fd); + break; + default: + break; + } + + return 0; +} int ribmgr_init(void) { - enum pol_gam pg; + enum pol_gam pg; + struct conn_info info; + + strcpy(info.ae_name, MGMT_AE); + strcpy(info.protocol, CDAP_PROTO); + info.pref_version = 1; + info.pref_syntax = PROTO_GPB; + + ribmgr.nbs = nbs_create(); + if (ribmgr.nbs == NULL) { + log_err("Failed to create neighbors."); + return -1; + } + + ribmgr.ae = connmgr_ae_create(info); + if (ribmgr.ae == NULL) { + log_err("Failed to create AE struct."); + nbs_destroy(ribmgr.nbs); + return -1; + } if (rib_read(BOOT_PATH "/rm/gam/type", &pg, sizeof(pg)) != sizeof(pg)) { log_err("Failed to read policy for ribmgr gam."); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } - ribmgr.gam = gam_create(pg); + ribmgr.gam = gam_create(pg, ribmgr.nbs, ribmgr.ae); if (ribmgr.gam == NULL) { log_err("Failed to create gam."); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } @@ -71,6 +116,8 @@ int ribmgr_init(void) if (ribmgr.fs == NULL) { log_err("Failed to create flow set."); gam_destroy(ribmgr.gam); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } @@ -79,6 +126,19 @@ int ribmgr_init(void) log_err("Failed to create fq."); flow_set_destroy(ribmgr.fs); gam_destroy(ribmgr.gam); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); + return -1; + } + + ribmgr.nb_notifier.notify_call = ribmgr_neighbor_event; + if (nbs_reg_notifier(ribmgr.nbs, &ribmgr.nb_notifier)) { + log_err("Failed to register notifier."); + fqueue_destroy(ribmgr.fq); + flow_set_destroy(ribmgr.fs); + gam_destroy(ribmgr.gam); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } @@ -87,20 +147,12 @@ int ribmgr_init(void) void ribmgr_fini(void) { + nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier); flow_set_destroy(ribmgr.fs); fqueue_destroy(ribmgr.fq); gam_destroy(ribmgr.gam); -} - -int ribmgr_flow_arr(int fd, - qosspec_t qs) -{ - assert(ribmgr.gam); - - if (gam_flow_arr(ribmgr.gam, fd, qs)) - return -1; - - return 0; + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); } int ribmgr_disseminate(char * path, diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index 12f407ab..f3f4cc24 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -41,9 +41,6 @@ int ribmgr_init(void); void ribmgr_fini(void); -int ribmgr_flow_arr(int fd, - qosspec_t qs); - int ribmgr_disseminate(char * path, enum diss_target target, enum diss_freq freq, diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c new file mode 100644 index 00000000..48c2c16d --- /dev/null +++ b/src/ipcpd/normal/routing.c @@ -0,0 +1,132 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing component of the IPCP + * + * Sander Vrijders + * Dimitri Staessens + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "routing" + +#include +#include +#include +#include + +#include "routing.h" +#include "ribmgr.h" + +#include +#include +#include + +struct edge { + struct vertex * ep; + qosspec_t qs; +}; + +struct vertex { + struct list_head next; + + uint64_t addr; + + struct list_head edges; +}; + +struct routing { + struct pff * pff; + struct nbs * nbs; + + struct nb_notifier nb_notifier; + + 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; +} + +#if 0 +/* FIXME: If zeroed since it is not used currently */ +static int add_vertex(struct routing * instance, + uint64_t addr) +{ + struct vertex * vertex; + + vertex = malloc(sizeof(*vertex)); + if (vertex == NULL) + return -1; + + list_head_init(&vertex->next); + list_head_init(&vertex->edges); + vertex->addr = addr; + + list_add(&vertex->next, &instance->vertices); + + return 0; +} +#endif + +struct routing * routing_create(struct pff * pff, + struct nbs * nbs) +{ + struct routing * tmp; + + assert(pff); + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + 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) +{ + assert(instance); + + nbs_unreg_notifier(instance->nbs, &instance->nb_notifier); + + free(instance); +} diff --git a/src/ipcpd/normal/routing.h b/src/ipcpd/normal/routing.h new file mode 100644 index 00000000..624763ec --- /dev/null +++ b/src/ipcpd/normal/routing.h @@ -0,0 +1,42 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing component of the IPCP + * + * Sander Vrijders + * Dimitri Staessens + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_ROUTING_H +#define OUROBOROS_IPCPD_NORMAL_ROUTING_H + +#include + +#include "pff.h" +#include "neighbors.h" + +#include + +/* + * 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); + +#endif /* OUROBOROS_IPCPD_NORMAL_ROUTING_H */ -- cgit v1.2.3 From e2616e184f023da7ce535efb5a676715283c092c Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Fri, 3 Mar 2017 14:40:29 +0100 Subject: ipcpd: normal: Deprecate CDAP flow This removes the CDAP flow class, which is no longer needed. --- src/ipcpd/normal/CMakeLists.txt | 1 - src/ipcpd/normal/cdap_flow.c | 186 ---------------------------------------- src/ipcpd/normal/cdap_flow.h | 46 ---------- 3 files changed, 233 deletions(-) delete mode 100644 src/ipcpd/normal/cdap_flow.c delete mode 100644 src/ipcpd/normal/cdap_flow.h (limited to 'src/ipcpd/normal/CMakeLists.txt') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 772d5212..6319c3ef 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -19,7 +19,6 @@ protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto) set(SOURCE_FILES # Add source files here addr_auth.c - cdap_flow.c connmgr.c dir.c enroll.c diff --git a/src/ipcpd/normal/cdap_flow.c b/src/ipcpd/normal/cdap_flow.c deleted file mode 100644 index c694e637..00000000 --- a/src/ipcpd/normal/cdap_flow.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Normal IPC Process - Authenticated CDAP Flow Allocator - * - * Sander Vrijders - * Dimitri Staessens - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define OUROBOROS_PREFIX "cdap-flow" - -#include -#include -#include - -#include "cdap_flow.h" - -#include -#include -#include - -static void cdap_flow_destroy(struct cdap_flow * flow) -{ - assert(flow); - - if (flow->ci != NULL) - cdap_destroy(flow->ci); - - free(flow); -} - -struct cdap_flow * cdap_flow_arr(int fd, - int resp, - const struct conn_info * info) -{ - struct cdap_flow * flow; - - if (flow_alloc_resp(fd, resp) < 0) { - log_err("Could not respond to new flow."); - return NULL; - } - - if (resp) - return NULL; - - flow = malloc(sizeof(*flow)); - if (flow == NULL) { - log_err("Failed to malloc."); - return NULL; - } - - memset(&flow->info, 0, sizeof(flow->info)); - - flow->fd = fd; - flow->ci = NULL; - - if (cacep_rcv(fd, &flow->info)) { - log_err("Error establishing application connection."); - cdap_flow_destroy(flow); - return NULL; - } - - if (cacep_snd(fd, info)) { - log_err("Failed to respond to application connection request."); - cdap_flow_destroy(flow); - return NULL; - } - - if (strcmp(flow->info.ae_name, info->ae_name)) { - log_err("Received connection for wrong AE."); - cdap_flow_destroy(flow); - return NULL; - } - - if (strcmp(flow->info.protocol, info->protocol) || - flow->info.pref_version != info->pref_version || - flow->info.pref_syntax != info->pref_syntax) { - log_err("Unknown protocol."); - cdap_flow_destroy(flow); - return NULL; - } - - flow->ci = cdap_create(fd); - if (flow->ci == NULL) { - log_err("Failed to create CDAP instance."); - cdap_flow_destroy(flow); - return NULL; - } - - return flow; -} - -struct cdap_flow * cdap_flow_alloc(const char * dst_name, - qosspec_t * qs, - const struct conn_info * info) -{ - struct cdap_flow * flow; - int fd; - - log_dbg("Allocating flow to %s.", dst_name); - - if (dst_name == NULL) { - log_err("Not enough info to establish flow."); - return NULL; - } - - fd = flow_alloc(dst_name, qs); - if (fd < 0) { - log_err("Failed to allocate flow to %s.", dst_name); - return NULL; - } - - if (flow_alloc_res(fd)) { - log_err("Flow allocation to %s failed.", dst_name); - return NULL; - } - - flow = malloc(sizeof(*flow)); - if (flow == NULL) { - log_err("Failed to malloc."); - flow_dealloc(fd); - return NULL; - } - - memset(&flow->info, 0, sizeof(flow->info)); - - flow->fd = fd; - flow->ci = NULL; - - if (cacep_snd(fd, info)) { - log_err("Failed to send connection request."); - cdap_flow_dealloc(flow); - return NULL; - } - - if (cacep_rcv(fd, &flow->info)) { - log_err("Failed to connect to application."); - cdap_flow_dealloc(flow); - return NULL; - } - - if (strcmp(flow->info.ae_name, info->ae_name)) { - log_err("Received connection for wrong AE."); - cdap_flow_destroy(flow); - return NULL; - } - - if (strcmp(flow->info.protocol, info->protocol) || - flow->info.pref_version != info->pref_version || - flow->info.pref_syntax != info->pref_syntax) { - log_err("Unknown protocol."); - cdap_flow_destroy(flow); - return NULL; - } - - flow->ci = cdap_create(fd); - if (flow->ci == NULL) { - log_err("Failed to create CDAP instance."); - cdap_flow_dealloc(flow); - return NULL; - } - - return flow; -} - -void cdap_flow_dealloc(struct cdap_flow * flow) -{ - int fd = flow->fd; - - cdap_flow_destroy(flow); - - flow_dealloc(fd); -} diff --git a/src/ipcpd/normal/cdap_flow.h b/src/ipcpd/normal/cdap_flow.h deleted file mode 100644 index 761f3463..00000000 --- a/src/ipcpd/normal/cdap_flow.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Normal IPC Process - Authenticated CDAP Flow Allocator - * - * Sander Vrijders - * Dimitri Staessens - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef OUROBOROS_IPCPD_NORMAL_CDAP_FLOW_H -#define OUROBOROS_IPCPD_NORMAL_CDAP_FLOW_H - -#include -#include -#include - -struct cdap_flow { - int fd; - struct cdap * ci; - struct conn_info info; -}; - -struct cdap_flow * cdap_flow_arr(int fd, - int resp, - const struct conn_info * info); - -struct cdap_flow * cdap_flow_alloc(const char * dst_name, - qosspec_t * qs, - const struct conn_info * info); - -void cdap_flow_dealloc(struct cdap_flow * flow); - -#endif /* OUROBOROS_IPCPD_NORMAL_CDAP_FLOW_H */ -- cgit v1.2.3 From 2852bb1bac8fcc111364d516c2bd31628ad264c7 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Fri, 3 Mar 2017 15:01:50 +0100 Subject: build: Format CMakeLists.txt files The CMakeLists files are now properly indented. --- CMakeLists.txt | 16 +++++----- cmake/AddCompileFlags.cmake | 17 ++++++++++ cmake/CmakeUninstall.cmake.in | 21 +++++++++++++ cmake/CompilerUtils.cmake | 2 +- cmake/FindProtobufC.cmake | 44 +++++++++++++------------- cmake/GitVersionGen.cmake | 58 +++++++++++++++++------------------ cmake/MacroAddCompileFlags.cmake | 19 ------------ cmake/cmake_uninstall.cmake.in | 21 ------------- src/ipcpd/CMakeLists.txt | 14 ++++----- src/ipcpd/local/CMakeLists.txt | 10 +++--- src/ipcpd/normal/CMakeLists.txt | 8 ++--- src/ipcpd/shim-eth-llc/CMakeLists.txt | 14 ++++----- src/ipcpd/shim-udp/CMakeLists.txt | 14 ++++----- src/ipcpd/tests/CMakeLists.txt | 10 +++--- src/irmd/CMakeLists.txt | 22 ++++++------- src/lib/CMakeLists.txt | 18 +++++------ src/lib/tests/CMakeLists.txt | 20 ++++++------ src/nsmd/CMakeLists.txt | 14 ++++----- src/tools/cbr/CMakeLists.txt | 6 ++-- src/tools/echo/CMakeLists.txt | 6 ++-- src/tools/irm/CMakeLists.txt | 42 ++++++++++++------------- src/tools/operf/CMakeLists.txt | 6 ++-- src/tools/oping/CMakeLists.txt | 6 ++-- 23 files changed, 203 insertions(+), 205 deletions(-) create mode 100644 cmake/AddCompileFlags.cmake create mode 100644 cmake/CmakeUninstall.cmake.in delete mode 100644 cmake/MacroAddCompileFlags.cmake delete mode 100644 cmake/cmake_uninstall.cmake.in (limited to 'src/ipcpd/normal/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index 52c82a80..e6c33c16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") project(ouroboros C) include(GitVersionGen) -GIT_VERSION_GEN() +git_version_gen() include(GNUInstallDirs) @@ -23,11 +23,11 @@ set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) -LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES +list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/usr/lib" isSystemDir) -IF("${isSystemDir}" STREQUAL "-1") - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/usr/lib") -ENDIF("${isSystemDir}" STREQUAL "-1") +IF ("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/usr/lib") +ENDIF ("${isSystemDir}" STREQUAL "-1") message(STATUS "Package name is: ${PACKAGE_NAME}") message(STATUS "Package description is: ${PACKAGE_DESCRIPTION}") @@ -86,12 +86,12 @@ add_subdirectory(include) # Uninstall target configure_file( - "${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" - "${CMAKE_BINARY_DIR}/cmake/cmake_uninstall.cmake" + "${CMAKE_SOURCE_DIR}/cmake/CmakeUninstall.cmake.in" + "${CMAKE_BINARY_DIR}/cmake/CmakeUninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/cmake_uninstall.cmake) + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/CmakeUninstall.cmake) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE_DESCRIPTION}") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README") diff --git a/cmake/AddCompileFlags.cmake b/cmake/AddCompileFlags.cmake new file mode 100644 index 00000000..8f3877d9 --- /dev/null +++ b/cmake/AddCompileFlags.cmake @@ -0,0 +1,17 @@ +# - MACRO_ADD_COMPILE_FLAGS(<_target> "flags...") + +# Copyright (c) 2006, Oswald Buddenhagen, +# +# Redistribution and use is allowed according to the terms of the BSD license. + +macro(add_compile_flags _target _flg) + + get_target_property(_flags ${_target} COMPILE_FLAGS) + if (_flags) + set(_flags "${_flags} ${_flg}") + else (_flags) + set(_flags "${_flg}") + endif (_flags) + set_target_properties(${_target} PROPERTIES COMPILE_FLAGS "${_flags}") + +endmacro(add_compile_flags) diff --git a/cmake/CmakeUninstall.cmake.in b/cmake/CmakeUninstall.cmake.in new file mode 100644 index 00000000..4c07dc7b --- /dev/null +++ b/cmake/CmakeUninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/cmake/CompilerUtils.cmake b/cmake/CompilerUtils.cmake index 5cea44b6..fb81b7e7 100644 --- a/cmake/CompilerUtils.cmake +++ b/cmake/CompilerUtils.cmake @@ -9,7 +9,7 @@ function(test_and_set_c_compiler_flag_global _flag) message(STATUS "Compiler supports flag ${_flag}, added globally") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}" PARENT_SCOPE) else(${_retval}) - message(STATUS "Compiler does not support flag ${_flag}, discarded") + message(STATUS "Compiler does not support flag ${_flag}, discarded") endif() endfunction(test_and_set_c_compiler_flag_global) diff --git a/cmake/FindProtobufC.cmake b/cmake/FindProtobufC.cmake index 6b81d751..ff532a46 100644 --- a/cmake/FindProtobufC.cmake +++ b/cmake/FindProtobufC.cmake @@ -1,22 +1,22 @@ function(PROTOBUF_GENERATE_C SRCS HDRS) - if(NOT ARGN) + if (NOT ARGN) message(SEND_ERROR "Error: PROTOBUF_GENERATE_C() called without any proto files") return() - endif() + endif () - if(PROTOBUF_GENERATE_C_APPEND_PATH) + if (PROTOBUF_GENERATE_C_APPEND_PATH) # Create an include path for each file specified - foreach(FIL ${ARGN}) + foreach (FIL ${ARGN}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(ABS_PATH ${ABS_FIL} PATH) list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() - else() + if (${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif () + endforeach () + else () set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) - endif() + endif () set(${SRCS}) set(${HDRS}) @@ -29,7 +29,7 @@ function(PROTOBUF_GENERATE_C SRCS HDRS) add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb-c.c" - "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb-c.h" + "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb-c.h" COMMAND ${PROTOBUF_PROTOC_C_EXECUTABLE} ARGS --c_out=${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_C_EXECUTABLE} @@ -44,31 +44,31 @@ endfunction() # By default have PROTOBUF_GENERATE_C macro pass -I to protoc # for each directory where a proto file is referenced. -if(NOT DEFINED PROTOBUF_GENERATE_C_APPEND_PATH) +if (NOT DEFINED PROTOBUF_GENERATE_C_APPEND_PATH) set(PROTOBUF_GENERATE_C_APPEND_PATH TRUE) -endif() +endif () # Find library find_library(PROTOBUF_C_LIBRARY - NAMES libprotobuf-c.so libprotobuf-c libprotobuf-c.dylib -) + NAMES libprotobuf-c.so libprotobuf-c libprotobuf-c.dylib + ) mark_as_advanced(PROTOBUF_C_LIBRARY) # Find the include directory find_path(PROTOBUF_C_INCLUDE_DIR - google/protobuf-c/protobuf-c.h -) + google/protobuf-c/protobuf-c.h + ) mark_as_advanced(PROTOBUF_C_INCLUDE_DIR) # Find the protoc-c Executable find_program(PROTOBUF_PROTOC_C_EXECUTABLE - NAMES protoc-c - DOC "The Google Protocol Buffers C Compiler" -) + NAMES protoc-c + DOC "The Google Protocol Buffers C Compiler" + ) mark_as_advanced(PROTOBUF_PROTOC_C_EXECUTABLE) find_package(PackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(ProtobufC DEFAULT_MSG - PROTOBUF_C_LIBRARY PROTOBUF_C_INCLUDE_DIR PROTOBUF_PROTOC_C_EXECUTABLE) +find_package_handle_standard_args(ProtobufC DEFAULT_MSG + PROTOBUF_C_LIBRARY PROTOBUF_C_INCLUDE_DIR PROTOBUF_PROTOC_C_EXECUTABLE) set(PROTOBUF_C_INCLUDE_DIRS ${PROTOBUF_C_INCLUDE_DIR}) diff --git a/cmake/GitVersionGen.cmake b/cmake/GitVersionGen.cmake index 53ac166d..718ec8a3 100644 --- a/cmake/GitVersionGen.cmake +++ b/cmake/GitVersionGen.cmake @@ -1,23 +1,23 @@ -macro(GIT_VERSION_GEN) +macro(git_version_gen) -include(FindGit) -if(NOT GIT_FOUND) - message(FATAL_ERROR "This is not a git repository") -endif() + include(FindGit) + if (NOT GIT_FOUND) + message(FATAL_ERROR "This is not a git repository") + endif () -find_program(SORT "sort") -mark_as_advanced(SORT) -if (${SORT} STREQUAL "") - message(FATAL_ERROR "Cannot find the sort executable") -endif() + find_program(SORT "sort") + mark_as_advanced(SORT) + if (${SORT} STREQUAL "") + message(FATAL_ERROR "Cannot find the sort executable") + endif () -find_program(TAIL "tail") -mark_as_advanced(TAIL) -if (${TAIL} STREQUAL "") - message(FATAL_ERROR "Cannot find the tail executable") -endif() + find_program(TAIL "tail") + mark_as_advanced(TAIL) + if (${TAIL} STREQUAL "") + message(FATAL_ERROR "Cannot find the tail executable") + endif () -execute_process( + execute_process( COMMAND ${GIT_EXECUTABLE} tag -l -n0 COMMAND ${SORT} -V COMMAND ${TAIL} -n 1 @@ -25,19 +25,19 @@ execute_process( OUTPUT_VARIABLE _git_tag RESULT_VARIABLE _git_result OUTPUT_STRIP_TRAILING_WHITESPACE) -if(NOT ${_git_result} EQUAL 0) - message(FATAL_ERROR "Cannot fetch repository tag") -endif() -message(STATUS "Repository tag is: ${_git_tag}") + if (NOT ${_git_result} EQUAL 0) + message(FATAL_ERROR "Cannot fetch repository tag") + endif () + message(STATUS "Repository tag is: ${_git_tag}") -string(REGEX REPLACE - "[^0-9]*([0-9]+)\\.[0-9]+.*" "\\1" - _version_major "${_git_tag}") -string(REGEX REPLACE - "[^0-9]*[0-9]+\\.([0-9]+).*" "\\1" - _version_minor "${_git_tag}") + string(REGEX REPLACE + "[^0-9]*([0-9]+)\\.[0-9]+.*" "\\1" + _version_major "${_git_tag}") + string(REGEX REPLACE + "[^0-9]*[0-9]+\\.([0-9]+).*" "\\1" + _version_minor "${_git_tag}") -set(PACKAGE_VERSION_MAJOR "${_version_major}") -set(PACKAGE_VERSION_MINOR "${_version_minor}") + set(PACKAGE_VERSION_MAJOR "${_version_major}") + set(PACKAGE_VERSION_MINOR "${_version_minor}") -endmacro(GIT_VERSION_GEN) +endmacro(git_version_gen) diff --git a/cmake/MacroAddCompileFlags.cmake b/cmake/MacroAddCompileFlags.cmake deleted file mode 100644 index 41f3797c..00000000 --- a/cmake/MacroAddCompileFlags.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# - MACRO_ADD_COMPILE_FLAGS(<_target> "flags...") - -# Copyright (c) 2006, Oswald Buddenhagen, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -macro(MACRO_ADD_COMPILE_FLAGS _target _flg) - - get_target_property(_flags ${_target} COMPILE_FLAGS) - if (_flags) - set(_flags "${_flags} ${_flg}") - else (_flags) - set(_flags "${_flg}") - endif (_flags) - set_target_properties(${_target} PROPERTIES COMPILE_FLAGS "${_flags}") - -endmacro(MACRO_ADD_COMPILE_FLAGS) diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in deleted file mode 100644 index 4c07dc7b..00000000 --- a/cmake/cmake_uninstall.cmake.in +++ /dev/null @@ -1,21 +0,0 @@ -if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") - message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") -endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") - -file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) -string(REGEX REPLACE "\n" ";" files "${files}") -foreach(file ${files}) - message(STATUS "Uninstalling $ENV{DESTDIR}${file}") - if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - if(NOT "${rm_retval}" STREQUAL 0) - message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") - endif(NOT "${rm_retval}" STREQUAL 0) - else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - message(STATUS "File $ENV{DESTDIR}${file} does not exist.") - endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") -endforeach(file) diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index 9c77683a..00baa762 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -1,14 +1,14 @@ set(IPCP_SOURCES - # Add source files here - ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c - ${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c - ${CMAKE_CURRENT_SOURCE_DIR}/timerwheel.c -) + # Add source files here + ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c + ${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c + ${CMAKE_CURRENT_SOURCE_DIR}/timerwheel.c + ) add_subdirectory(local) add_subdirectory(normal) add_subdirectory(shim-udp) -if(NOT APPLE) +if (NOT APPLE) add_subdirectory(shim-eth-llc) -endif() +endif () add_subdirectory(tests) diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt index cc19aad0..824b4ca6 100644 --- a/src/ipcpd/local/CMakeLists.txt +++ b/src/ipcpd/local/CMakeLists.txt @@ -12,18 +12,18 @@ include_directories(${CURRENT_BINARY_PARENT_DIR}) include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) -SET(IPCP_LOCAL_TARGET ipcpd-local CACHE STRING "IPCP_LOCAL") +set(IPCP_LOCAL_TARGET ipcpd-local CACHE STRING "IPCP_LOCAL") set(SHIM_LOCAL_SOURCES # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -add_executable (ipcpd-local ${SHIM_LOCAL_SOURCES} ${IPCP_SOURCES}) -target_link_libraries (ipcpd-local LINK_PUBLIC ouroboros) +add_executable(ipcpd-local ${SHIM_LOCAL_SOURCES} ${IPCP_SOURCES}) +target_link_libraries(ipcpd-local LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd-local -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-local -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-local RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 6319c3ef..af99b3f9 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -36,13 +36,13 @@ set(SOURCE_FILES pol/flat.c ) -add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} +add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} ${FLOW_ALLOC_SRCS}) -target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros) +target_link_libraries(ipcpd-normal LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - macro_add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/shim-eth-llc/CMakeLists.txt b/src/ipcpd/shim-eth-llc/CMakeLists.txt index bd9add74..bd3049a2 100644 --- a/src/ipcpd/shim-eth-llc/CMakeLists.txt +++ b/src/ipcpd/shim-eth-llc/CMakeLists.txt @@ -15,21 +15,21 @@ include_directories(${CMAKE_BINARY_DIR}/include) protobuf_generate_c(SHIM_ETH_LLC_PROTO_SRCS SHIM_ETH_LLC_PROTO_HDRS shim_eth_llc_messages.proto) -SET(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc +set(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc CACHE STRING "IPCP_SHIM_ETH_LLC_TARGET") set(SHIM_ETH_LLC_SOURCES # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -add_executable (ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES} - ${SHIM_ETH_LLC_PROTO_SRCS}) -target_link_libraries (ipcpd-shim-eth-llc LINK_PUBLIC ouroboros - ${PROTOBUF_C_LIBRARY}) +add_executable(ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES} + ${SHIM_ETH_LLC_PROTO_SRCS}) +target_link_libraries(ipcpd-shim-eth-llc LINK_PUBLIC ouroboros + ${PROTOBUF_C_LIBRARY}) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-eth-llc -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-shim-eth-llc -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-shim-eth-llc RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt index cc60cfb7..2560f242 100644 --- a/src/ipcpd/shim-udp/CMakeLists.txt +++ b/src/ipcpd/shim-udp/CMakeLists.txt @@ -19,15 +19,15 @@ configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/shim_udp_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h") -SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") +set(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") set(SHIM_UDP_SOURCES # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES} +add_executable(ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES} ${SHIM_UDP_PROTO_SRCS} "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h") -target_link_libraries (ipcpd-shim-udp LINK_PUBLIC ouroboros +target_link_libraries(ipcpd-shim-udp LINK_PUBLIC ouroboros ${PROTOBUF_C_LIBRARY}) # Find the nsupdate executable @@ -40,6 +40,7 @@ find_program(NSLOOKUP_EXECUTABLE NAMES nslookup DOC "The nslookup tool that resolves DNS names") +include(AddCompileFlags) if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND") message("-- Could not find nsupdate. Disabling DDNS functionality.") elseif (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND") @@ -47,12 +48,11 @@ elseif (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND") else () message("-- Found nsupdate: ${NSUPDATE_EXECUTABLE}") message("-- Found nslookup: ${NSLOOKUP_EXECUTABLE}") - MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_ENABLE_DNS) -endif() + add_compile_flags(ipcpd-shim-udp -DCONFIG_OUROBOROS_ENABLE_DNS) +endif () -include(MacroAddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/tests/CMakeLists.txt b/src/ipcpd/tests/CMakeLists.txt index 57a910c8..07430127 100644 --- a/src/ipcpd/tests/CMakeLists.txt +++ b/src/ipcpd/tests/CMakeLists.txt @@ -13,9 +13,9 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) create_test_sourcelist(${src_folder}_tests test_suite.c - # Add new tests here - timerwheel_test.c -) + # Add new tests here + timerwheel_test.c + ) add_executable(${src_folder}_test EXCLUDE_FROM_ALL ${${src_folder}_tests}) target_link_libraries(${src_folder}_test ouroboros) @@ -25,7 +25,7 @@ add_dependencies(check ${src_folder}_test) set(tests_to_run ${${src_folder}_tests}) remove(tests_to_run test_suite.c) -foreach(test ${tests_to_run}) +foreach (test ${tests_to_run}) get_filename_component(test_name ${test} NAME_WE) add_test(${test_name} ${C_TEST_PATH}/${src_folder}_test ${test_name}) -endforeach(test) +endforeach (test) diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt index 16b53414..930c7b05 100644 --- a/src/irmd/CMakeLists.txt +++ b/src/irmd/CMakeLists.txt @@ -5,23 +5,23 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - api_table.c - apn_table.c - ipcp.c - irm_flow.c - main.c - registry.c - utils.c -) + # Add source files here + api_table.c + apn_table.c + ipcp.c + irm_flow.c + main.c + registry.c + utils.c + ) add_executable (irmd ${SOURCE_FILES}) target_link_libraries (irmd LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(irmd -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(irmd -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS irmd RUNTIME DESTINATION sbin) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 03452705..f6a30ef7 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -12,19 +12,19 @@ protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS cdap.proto) protobuf_generate_c(RO_PROTO_SRCS RO_PROTO_HDRS ro.proto) protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto) -if(NOT APPLE) +if (NOT APPLE) find_library(LIBRT_LIBRARIES rt) - if(NOT LIBRT_LIBRARIES) + if (NOT LIBRT_LIBRARIES) message(FATAL_ERROR "librt not found") - endif() -else() + endif () +else () set(LIBRT_LIBRARIES "") -endif() +endif () find_library(LIBPTHREAD_LIBRARIES pthread) -if(NOT LIBPTHREAD_LIBRARIES) +if (NOT LIBPTHREAD_LIBRARIES) message(FATAL_ERROR "libpthread not found") -endif() +endif () set(SOURCE_FILES # Add source files here @@ -58,9 +58,9 @@ add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS} target_link_libraries(ouroboros ${LIBRT_LIBRARIES} ${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY}) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ouroboros -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ouroboros -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ouroboros LIBRARY DESTINATION usr/lib) diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt index e4ea3920..a9f38c6f 100644 --- a/src/lib/tests/CMakeLists.txt +++ b/src/lib/tests/CMakeLists.txt @@ -2,14 +2,14 @@ get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) create_test_sourcelist(${PARENT_DIR}_tests test_suite.c - # Add new tests here - bitmap_test.c - btree_test.c - crc32_test.c - hashtable_test.c - rib_test.c - sha3_test.c -) + # Add new tests here + bitmap_test.c + btree_test.c + crc32_test.c + hashtable_test.c + rib_test.c + sha3_test.c + ) add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) target_link_libraries(${PARENT_DIR}_test ouroboros) @@ -19,7 +19,7 @@ add_dependencies(check ${PARENT_DIR}_test) set(tests_to_run ${${PARENT_DIR}_tests}) remove(tests_to_run test_suite.c) -foreach(test ${tests_to_run}) +foreach (test ${tests_to_run}) get_filename_component(test_name ${test} NAME_WE) add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) -endforeach(test) +endforeach (test) diff --git a/src/nsmd/CMakeLists.txt b/src/nsmd/CMakeLists.txt index b916170b..2995b725 100644 --- a/src/nsmd/CMakeLists.txt +++ b/src/nsmd/CMakeLists.txt @@ -5,17 +5,17 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - main.c -) + # Add source files here + main.c + ) -add_executable (nsmd ${SOURCE_FILES}) +add_executable(nsmd ${SOURCE_FILES}) -target_link_libraries (nsmd LINK_PUBLIC ouroboros) +target_link_libraries(nsmd LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(nsmd -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(nsmd -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS nsmd RUNTIME DESTINATION sbin) diff --git a/src/tools/cbr/CMakeLists.txt b/src/tools/cbr/CMakeLists.txt index 232bea36..1883141c 100644 --- a/src/tools/cbr/CMakeLists.txt +++ b/src/tools/cbr/CMakeLists.txt @@ -5,9 +5,9 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - cbr.c -) + # Add source files here + cbr.c + ) add_executable(cbr ${SOURCE_FILES}) diff --git a/src/tools/echo/CMakeLists.txt b/src/tools/echo/CMakeLists.txt index 42bcdbfe..7cecfe50 100644 --- a/src/tools/echo/CMakeLists.txt +++ b/src/tools/echo/CMakeLists.txt @@ -5,9 +5,9 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - echo.c -) + # Add source files here + echo.c + ) add_executable(echo-app ${SOURCE_FILES}) diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt index f59d9af0..300ad982 100644 --- a/src/tools/irm/CMakeLists.txt +++ b/src/tools/irm/CMakeLists.txt @@ -5,28 +5,28 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - irm.c - irm_bind_ap.c - irm_bind_api.c - irm_bind_ipcp.c - irm_ipcp_create.c - irm_ipcp_destroy.c - irm_ipcp_bootstrap.c - irm_ipcp_enroll.c - irm_unbind_ap.c - irm_unbind_api.c - irm_unbind_ipcp.c - irm_unbind.c - irm_bind.c - irm_ipcp.c - irm_register.c - irm_unregister.c - irm_utils.c -) + # Add source files here + irm.c + irm_bind_ap.c + irm_bind_api.c + irm_bind_ipcp.c + irm_ipcp_create.c + irm_ipcp_destroy.c + irm_ipcp_bootstrap.c + irm_ipcp_enroll.c + irm_unbind_ap.c + irm_unbind_api.c + irm_unbind_ipcp.c + irm_unbind.c + irm_bind.c + irm_ipcp.c + irm_register.c + irm_unregister.c + irm_utils.c + ) -add_executable (irm ${SOURCE_FILES}) +add_executable(irm ${SOURCE_FILES}) -target_link_libraries (irm LINK_PUBLIC ouroboros) +target_link_libraries(irm LINK_PUBLIC ouroboros) install(TARGETS irm RUNTIME DESTINATION sbin) diff --git a/src/tools/operf/CMakeLists.txt b/src/tools/operf/CMakeLists.txt index b63d24ee..906bab7b 100644 --- a/src/tools/operf/CMakeLists.txt +++ b/src/tools/operf/CMakeLists.txt @@ -10,9 +10,9 @@ if(NOT LIBM_LIBRARIES) endif() set(SOURCE_FILES - # Add source files here - operf.c -) + # Add source files here + operf.c + ) add_executable(operf ${SOURCE_FILES}) diff --git a/src/tools/oping/CMakeLists.txt b/src/tools/oping/CMakeLists.txt index a8fc7d86..f129a02b 100644 --- a/src/tools/oping/CMakeLists.txt +++ b/src/tools/oping/CMakeLists.txt @@ -10,9 +10,9 @@ if(NOT LIBM_LIBRARIES) endif() set(SOURCE_FILES - # Add source files here - oping.c -) + # Add source files here + oping.c + ) add_executable(oping ${SOURCE_FILES}) -- cgit v1.2.3 From 7714673b65daf1fd0266d2855d9bfc91d735b51a Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Tue, 14 Mar 2017 16:06:33 +0100 Subject: ipcpd: normal: Add graph structure This adds a graph structure which will be updated by routing when it is notified about a new RIB event. The routing can then use this graph as input for calculating the shortest path to a destination. --- src/ipcpd/normal/CMakeLists.txt | 1 + src/ipcpd/normal/graph.c | 277 ++++++++++++++++++++++++++++++++++++++++ src/ipcpd/normal/graph.h | 67 ++++++++++ src/ipcpd/normal/routing.c | 57 +++------ src/ipcpd/normal/routing.h | 1 - 5 files changed, 365 insertions(+), 38 deletions(-) create mode 100644 src/ipcpd/normal/graph.c create mode 100644 src/ipcpd/normal/graph.h (limited to 'src/ipcpd/normal/CMakeLists.txt') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index af99b3f9..39ced7bc 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -25,6 +25,7 @@ set(SOURCE_FILES fmgr.c frct.c gam.c + graph.c main.c neighbors.c pff.c diff --git a/src/ipcpd/normal/graph.c b/src/ipcpd/normal/graph.c new file mode 100644 index 00000000..85bb3fe2 --- /dev/null +++ b/src/ipcpd/normal/graph.c @@ -0,0 +1,277 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph structure + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "graph" + +#include +#include +#include +#include + +#include "graph.h" + +#include +#include +#include + +static struct edge * find_edge_by_addr(struct vertex * vertex, + uint64_t dst_addr) +{ + struct list_head * p = NULL; + + list_for_each(p, &vertex->edges) { + struct edge * e = list_entry(p, struct edge, next); + if (e->dst_addr == dst_addr) + return e; + } + + return NULL; +} + +static struct vertex * find_vertex_by_addr(struct graph * graph, + uint64_t addr) +{ + struct list_head * p = NULL; + + list_for_each(p, &graph->vertices) { + struct vertex * e = list_entry(p, struct vertex, next); + if (e->addr == addr) + return e; + } + + return NULL; +} + +static int add_edge(struct vertex * vertex, + uint64_t dst_addr, + qosspec_t qs) +{ + struct edge * edge; + + edge = malloc(sizeof(*edge)); + if (edge == NULL) + return -ENOMEM; + + list_head_init(&edge->next); + edge->dst_addr = dst_addr; + edge->qs = qs; + + list_add(&edge->next, &vertex->edges); + + return 0; +} + +static void del_edge(struct edge * edge) +{ + list_del(&edge->next); + free(edge); +} + +static int add_vertex(struct graph * graph, + uint64_t addr) +{ + struct vertex * vertex; + struct list_head * p; + + vertex = malloc(sizeof(*vertex)); + if (vertex == NULL) + return -1; + + list_head_init(&vertex->next); + list_head_init(&vertex->edges); + vertex->addr = addr; + + list_for_each(p, &graph->vertices) { + struct vertex * v = list_entry(p, struct vertex, next); + if (v->addr > addr) + break; + } + + list_add_tail(&vertex->next, p); + + graph->nr_vertices++; + + return 0; +} + +static void del_vertex(struct graph * graph, + struct vertex * vertex) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + list_del(&vertex->next); + + list_for_each_safe(p, n, &vertex->edges) { + struct edge * e = list_entry(p, struct edge, next); + del_edge(e); + } + + free(vertex); + + graph->nr_vertices--; +} + +struct graph * graph_create(void) +{ + struct graph * graph; + + graph = malloc(sizeof(*graph)); + if (graph == NULL) + return NULL; + + if (pthread_mutex_init(&graph->lock, NULL)) { + free(graph); + return NULL; + } + + graph->nr_vertices = 0; + list_head_init(&graph->vertices); + + return graph; +} + +void graph_destroy(struct graph * graph) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + list_for_each_safe(p, n, &graph->vertices) { + struct vertex * e = list_entry(p, struct vertex, next); + del_vertex(graph, e); + } + + pthread_mutex_unlock(&graph->lock); + + pthread_mutex_destroy(&graph->lock); +} + +int graph_add_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs) +{ + struct vertex * v; + struct edge * e; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + v = find_vertex_by_addr(graph, s_addr); + if (v == NULL) { + if (add_vertex(graph, s_addr)) { + pthread_mutex_unlock(&graph->lock); + return -ENOMEM; + } + } + + e = find_edge_by_addr(v, d_addr); + if (e != NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("Edge already exists."); + return -1; + } + + if (add_edge(v, d_addr, qs)) { + pthread_mutex_unlock(&graph->lock); + log_err("Failed to add edge."); + return -1; + } + + pthread_mutex_unlock(&graph->lock); + + return 0; +} + +int graph_update_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs) +{ + struct vertex * v; + struct edge * e; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + v = find_vertex_by_addr(graph, s_addr); + if (v == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such vertex."); + return -1; + } + + e = find_edge_by_addr(v, d_addr); + if (e == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such edge."); + return -1; + } + + e->qs = qs; + + pthread_mutex_unlock(&graph->lock); + + return 0; +} + +int graph_del_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr) +{ + struct vertex * v; + struct edge * e; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + v = find_vertex_by_addr(graph, s_addr); + if (v == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such vertex."); + return -1; + } + + e = find_edge_by_addr(v, d_addr); + if (e == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such edge."); + return -1; + } + + del_edge(e); + + /* Removing vertex if it was the last edge */ + if (list_is_empty(&v->edges)) + del_vertex(graph, v); + + pthread_mutex_unlock(&graph->lock); + + return 0; +} diff --git a/src/ipcpd/normal/graph.h b/src/ipcpd/normal/graph.h new file mode 100644 index 00000000..9653efd7 --- /dev/null +++ b/src/ipcpd/normal/graph.h @@ -0,0 +1,67 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph structure + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_GRAPH_H +#define OUROBOROS_IPCPD_NORMAL_GRAPH_H + +#include +#include + +#include + +struct edge { + struct list_head next; + uint64_t dst_addr; + qosspec_t qs; +}; + +struct vertex { + struct list_head next; + uint64_t addr; + struct list_head edges; +}; + +struct graph { + size_t nr_vertices; + struct list_head vertices; + pthread_mutex_t lock; +}; + +struct graph * graph_create(void); + +void graph_destroy(struct graph * graph); + +int graph_add_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs); + +int graph_update_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs); + +int graph_del_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr); + +#endif /* OUROBOROS_IPCPD_NORMAL_GRAPH_H */ diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c index e699fd77..46c2be08 100644 --- a/src/ipcpd/normal/routing.c +++ b/src/ipcpd/normal/routing.c @@ -32,6 +32,7 @@ #include "ribmgr.h" #include "ribconfig.h" #include "ipcp.h" +#include "graph.h" #include #include @@ -40,53 +41,25 @@ #define ADDR_SIZE 30 -struct edge { +struct routing_table_entry { struct list_head next; - - uint64_t addr; - - qosspec_t qs; -}; - -struct vertex { - struct list_head next; - - uint64_t addr; - - struct list_head edges; + uint64_t dst; + uint64_t nhop; }; struct routing_i { struct pff * pff; - struct list_head vertices; + struct list_head routing_table; }; 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 */ -static int add_vertex(struct routing * instance, - uint64_t addr) -{ - struct vertex * vertex; - vertex = malloc(sizeof(*vertex)); - if (vertex == NULL) - return -1; - - list_head_init(&vertex->next); - list_head_init(&vertex->edges); - vertex->addr = addr; - - list_add(&vertex->next, &instance->vertices); + char fso_path[RIB_MAX_PATH_LEN + 1]; - return 0; -} -#endif + struct graph * graph; +} routing; struct routing_i * routing_i_create(struct pff * pff) { @@ -100,7 +73,7 @@ struct routing_i * routing_i_create(struct pff * pff) tmp->pff = pff; - list_head_init(&tmp->vertices); + list_head_init(&tmp->routing_table); return tmp; } @@ -164,14 +137,21 @@ int routing_init(struct nbs * nbs) { char addr[ADDR_SIZE]; - if (rib_add(RIB_ROOT, ROUTING_NAME)) + routing.graph = graph_create(); + if (routing.graph == NULL) return -1; + if (rib_add(RIB_ROOT, ROUTING_NAME)) { + graph_destroy(routing.graph); + 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)) { + graph_destroy(routing.graph); rib_del(ROUTING_PATH); return -1; } @@ -182,6 +162,7 @@ int routing_init(struct 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; } @@ -191,6 +172,8 @@ int routing_init(struct nbs * nbs) void routing_fini(void) { + graph_destroy(routing.graph); + 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 20dc72f9..0794ef28 100644 --- a/src/ipcpd/normal/routing.h +++ b/src/ipcpd/normal/routing.h @@ -34,7 +34,6 @@ * Routing will take a type in the future, * to allow different policies. */ - int routing_init(struct nbs * nbs); void routing_fini(void); -- cgit v1.2.3 From 5fde9be8b30f284b4a249fbf13b08af290b868b1 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 15 Mar 2017 17:15:19 +0100 Subject: ipcpd: normal: routing: Listen to RIB events This lets the routing component listen to RIB events. It listens to /fsdb which is populated with FSOs. The graph that is kept within the routing component is updated depending on the event that was received. --- src/ipcpd/normal/CMakeLists.txt | 3 +- src/ipcpd/normal/fso.proto | 29 +++++++ src/ipcpd/normal/routing.c | 184 +++++++++++++++++++++++++++++++++------- 3 files changed, 182 insertions(+), 34 deletions(-) create mode 100644 src/ipcpd/normal/fso.proto (limited to 'src/ipcpd/normal/CMakeLists.txt') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 39ced7bc..06292c50 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories(${CMAKE_BINARY_DIR}/include) set(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET") protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto) +protobuf_generate_c(FSO_SRCS FSO_HDRS fso.proto) set(SOURCE_FILES # Add source files here @@ -38,7 +39,7 @@ set(SOURCE_FILES ) add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} - ${FLOW_ALLOC_SRCS}) + ${FLOW_ALLOC_SRCS} ${FSO_SRCS}) target_link_libraries(ipcpd-normal LINK_PUBLIC ouroboros) include(AddCompileFlags) diff --git a/src/ipcpd/normal/fso.proto b/src/ipcpd/normal/fso.proto new file mode 100644 index 00000000..32b281d6 --- /dev/null +++ b/src/ipcpd/normal/fso.proto @@ -0,0 +1,29 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Flow State Object message + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +syntax = "proto2"; + +message fso { + required uint64 s_addr = 1; + required uint64 d_addr = 2; + /* Add QoS parameters of link here */ +}; diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c index 46c2be08..745d1812 100644 --- a/src/ipcpd/normal/routing.c +++ b/src/ipcpd/normal/routing.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "routing.h" #include "ribmgr.h" @@ -39,7 +40,10 @@ #include #include -#define ADDR_SIZE 30 +#include "fso.pb-c.h" +typedef Fso fso_t; + +#define BUF_SIZE 256 struct routing_table_entry { struct list_head next; @@ -48,17 +52,18 @@ struct routing_table_entry { }; struct routing_i { - struct pff * pff; - struct list_head routing_table; + struct pff * pff; }; struct { struct nbs * nbs; struct nb_notifier nb_notifier; - char fso_path[RIB_MAX_PATH_LEN + 1]; - struct graph * graph; + + ro_set_t * set; + rqueue_t * queue; + pthread_t rib_listener; } routing; struct routing_i * routing_i_create(struct pff * pff) @@ -73,8 +78,6 @@ struct routing_i * routing_i_create(struct pff * pff) tmp->pff = pff; - list_head_init(&tmp->routing_table); - return tmp; } @@ -88,24 +91,41 @@ void routing_i_destroy(struct routing_i * instance) static int routing_neighbor_event(enum nb_event event, struct conn conn) { - char addr[ADDR_SIZE]; - char path[RIB_MAX_PATH_LEN + 1]; + 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; - strcpy(path, routing.fso_path); - snprintf(addr, ADDR_SIZE, "%" PRIx64, conn.conn_info.addr); - rib_path_append(path, addr); + sprintf(fso_name, "%" PRIx64 "-%" PRIx64, + ipcpi.dt_addr, conn.conn_info.addr); + rib_path_append(rib_path_append(path, ROUTING_PATH), fso_name); switch (event) { case NEIGHBOR_ADDED: - if (rib_add(routing.fso_path, addr)) { + 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_write(path, &conn.flow_info.qs, - sizeof(conn.flow_info.qs))) { - log_err("Failed to write qosspec to FSO."); + if (rib_put(path, data, len)) { + log_err("Failed to put FSO in RIB."); rib_del(path); + free(data); return -1; } @@ -118,12 +138,7 @@ static int routing_neighbor_event(enum nb_event event, 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; - } - + log_info("Not currently supported."); break; default: log_info("Unsupported event for routing."); @@ -133,10 +148,98 @@ static int routing_neighbor_event(enum nb_event event, return 0; } -int routing_init(struct nbs * nbs) +static int read_fso(char * path, + int32_t flag) +{ + ssize_t len; + uint8_t ro[BUF_SIZE]; + fso_t * fso; + qosspec_t 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."); + return -1; + } + + if (flag & RO_CREATE) { + if (graph_add_edge(routing.graph, + fso->s_addr, fso->d_addr, qs)) { + log_err("Failed to add edge to graph."); + fso__free_unpacked(fso, NULL); + return -1; + } + } else if (flag & RO_MODIFY) { + if (graph_update_edge(routing.graph, + fso->s_addr, fso->d_addr, qs)) { + log_err("Failed to update edge of graph."); + fso__free_unpacked(fso, NULL); + return -1; + } + } else if (flag & RO_DELETE) { + if (graph_del_edge(routing.graph, fso->s_addr, fso->d_addr)) { + log_err("Failed to del edge of graph."); + fso__free_unpacked(fso, NULL); + return -1; + } + } + + fso__free_unpacked(fso, NULL); + + return 0; +} + +static void * rib_listener(void * o) { - char addr[ADDR_SIZE]; + 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_CREATE | 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)) { + flag = rqueue_next(routing.queue, path); + if (flag < 0) + continue; + if (read_fso(children[i], flag)) { + log_err("Failed to parse FSO."); + continue; + } + } + + return (void *) 0; +} + +int routing_init(struct nbs * nbs) +{ routing.graph = graph_create(); if (routing.graph == NULL) return -1; @@ -146,32 +249,47 @@ int routing_init(struct nbs * nbs) return -1; } - rib_path_append(routing.fso_path, ROUTING_NAME); - - snprintf(addr, ADDR_SIZE, "%" PRIx64, ipcpi.dt_addr); + routing.nbs = nbs; - if (rib_add(routing.fso_path, addr)) { + 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; } - rib_path_append(routing.fso_path, addr); - - routing.nbs = nbs; + 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.nb_notifier.notify_call = routing_neighbor_event; - if (nbs_reg_notifier(routing.nbs, &routing.nb_notifier)) { + 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; } 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); -- cgit v1.2.3