diff options
Diffstat (limited to 'src/ipcpd/unicast/routing')
| -rw-r--r-- | src/ipcpd/unicast/routing/graph.c | 158 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/graph.h | 2 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/link-state.c | 560 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/link-state.h | 9 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/ops.h | 9 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/pol.h | 2 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/tests/CMakeLists.txt | 40 | ||||
| -rw-r--r-- | src/ipcpd/unicast/routing/tests/graph_test.c | 2 |
8 files changed, 421 insertions, 361 deletions
diff --git a/src/ipcpd/unicast/routing/graph.c b/src/ipcpd/unicast/routing/graph.c index 32f3e6fb..13939915 100644 --- a/src/ipcpd/unicast/routing/graph.c +++ b/src/ipcpd/unicast/routing/graph.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Undirected graph structure * @@ -57,8 +57,8 @@ struct edge { }; struct graph { - size_t nr_vertices; - struct list_head vertices; + struct llist vertices; + pthread_mutex_t lock; }; @@ -67,7 +67,7 @@ static struct edge * find_edge_by_addr(struct vertex * vertex, { struct list_head * p; - assert(vertex); + assert(vertex != NULL); list_for_each(p, &vertex->edges) { struct edge * e = list_entry(p, struct edge, next); @@ -85,7 +85,7 @@ static struct vertex * find_vertex_by_addr(struct graph * graph, assert(graph); - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { struct vertex * e = list_entry(p, struct vertex, next); if (e->addr == addr) return e; @@ -99,8 +99,8 @@ static struct edge * add_edge(struct vertex * vertex, { struct edge * edge; - assert(vertex); - assert(nb); + assert(vertex != NULL); + assert(nb != NULL); edge = malloc(sizeof(*edge)); if (edge == NULL) @@ -139,7 +139,7 @@ static struct vertex * add_vertex(struct graph * graph, vertex->addr = addr; /* Keep them ordered on address. */ - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > addr) break; @@ -148,17 +148,15 @@ static struct vertex * add_vertex(struct graph * graph, vertex->index = i; - list_add_tail(&vertex->next, p); + llist_add_tail_at(&vertex->next, p, &graph->vertices); /* Increase the index of the vertices to the right. */ - list_for_each(p, &graph->vertices) { + list_for_each(p, &vertex->next) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > addr) v->index++; } - graph->nr_vertices++; - return vertex; } @@ -168,13 +166,13 @@ static void del_vertex(struct graph * graph, struct list_head * p; struct list_head * h; - assert(graph); - assert(vertex); + assert(graph != NULL); + assert(vertex != NULL); - list_del(&vertex->next); + llist_del(&vertex->next, &graph->vertices); /* Decrease the index of the vertices to the right. */ - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > vertex->addr) v->index--; @@ -186,8 +184,6 @@ static void del_vertex(struct graph * graph, } free(vertex); - - graph->nr_vertices--; } struct graph * graph_create(void) @@ -203,8 +199,7 @@ struct graph * graph_create(void) return NULL; } - graph->nr_vertices = 0; - list_head_init(&graph->vertices); + llist_init(&graph->vertices); return graph; } @@ -218,7 +213,7 @@ void graph_destroy(struct graph * graph) pthread_mutex_lock(&graph->lock); - list_for_each_safe(p, n, &graph->vertices) { + llist_for_each_safe(p, n, &graph->vertices) { struct vertex * e = list_entry(p, struct vertex, next); del_vertex(graph, e); } @@ -227,6 +222,8 @@ void graph_destroy(struct graph * graph) pthread_mutex_destroy(&graph->lock); + assert(llist_is_empty(&graph->vertices)); + free(graph); } @@ -240,63 +237,35 @@ int graph_update_edge(struct graph * graph, struct vertex * nb; struct edge * nb_e; - assert(graph); + assert(graph != NULL); pthread_mutex_lock(&graph->lock); v = find_vertex_by_addr(graph, s_addr); - if (v == NULL) { - v = add_vertex(graph, s_addr); - if (v == NULL) { - pthread_mutex_unlock(&graph->lock); - log_err("Failed to add vertex."); - return -ENOMEM; - } + if (v == NULL && ((v = add_vertex(graph, s_addr)) == NULL)) {; + log_err("Failed to add src vertex."); + goto fail_add_s; } nb = find_vertex_by_addr(graph, d_addr); - if (nb == NULL) { - nb = add_vertex(graph, d_addr); - if (nb == NULL) { - if (list_is_empty(&v->edges)) - del_vertex(graph, v); - pthread_mutex_unlock(&graph->lock); - log_err("Failed to add vertex."); - return -ENOMEM; - } + if (nb == NULL && ((nb = add_vertex(graph, d_addr)) == NULL)) { + log_err("Failed to add dst vertex."); + goto fail_add_d; } e = find_edge_by_addr(v, d_addr); - if (e == NULL) { - e = add_edge(v, nb); - if (e == NULL) { - if (list_is_empty(&v->edges)) - del_vertex(graph, v); - if (list_is_empty(&nb->edges)) - del_vertex(graph, nb); - pthread_mutex_unlock(&graph->lock); - log_err("Failed to add edge."); - return -ENOMEM; - } + if (e == NULL && ((e = add_edge(v, nb)) == NULL)) { + log_err("Failed to add edge to dst."); + goto fail_add_edge_d; } e->announced++; e->qs = qs; nb_e = find_edge_by_addr(nb, s_addr); - if (nb_e == NULL) { - nb_e = add_edge(nb, v); - if (nb_e == NULL) { - if (--e->announced == 0) - del_edge(e); - if (list_is_empty(&v->edges)) - del_vertex(graph, v); - if (list_is_empty(&nb->edges)) - del_vertex(graph, nb); - pthread_mutex_unlock(&graph->lock); - log_err("Failed to add edge."); - return -ENOMEM; - } + if (nb_e == NULL && ((nb_e = add_edge(nb, v)) == NULL)) {; + log_err("Failed to add edge to src."); + goto fail_add_edge_s; } nb_e->announced++; @@ -305,6 +274,19 @@ int graph_update_edge(struct graph * graph, pthread_mutex_unlock(&graph->lock); return 0; + fail_add_edge_s: + if (--e->announced == 0) + del_edge(e); + fail_add_edge_d: + if (list_is_empty(&nb->edges)) + del_vertex(graph, nb); + fail_add_d: + if (list_is_empty(&v->edges)) + del_vertex(graph, v); + fail_add_s: + pthread_mutex_unlock(&graph->lock); + return -ENOMEM; + } int graph_del_edge(struct graph * graph, @@ -322,30 +304,26 @@ int graph_del_edge(struct graph * graph, v = find_vertex_by_addr(graph, s_addr); if (v == NULL) { - pthread_mutex_unlock(&graph->lock); - log_err("No such source vertex."); - return -1; + log_err("Failed to find src vertex."); + goto fail; } nb = find_vertex_by_addr(graph, d_addr); if (nb == NULL) { - pthread_mutex_unlock(&graph->lock); log_err("No such destination vertex."); - return -1; + goto fail; } e = find_edge_by_addr(v, d_addr); if (e == NULL) { - pthread_mutex_unlock(&graph->lock); log_err("No such source edge."); - return -1; + goto fail; } nb_e = find_edge_by_addr(nb, s_addr); if (nb_e == NULL) { - pthread_mutex_unlock(&graph->lock); log_err("No such destination edge."); - return -1; + goto fail; } if (--e->announced == 0) @@ -362,6 +340,10 @@ int graph_del_edge(struct graph * graph, pthread_mutex_unlock(&graph->lock); return 0; + + fail: + pthread_mutex_unlock(&graph->lock); + return -1; } static int get_min_vertex(struct graph * graph, @@ -381,7 +363,7 @@ static int get_min_vertex(struct graph * graph, *v = NULL; - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { if (!used[i] && dist[i] < min) { min = dist[i]; index = i; @@ -413,24 +395,24 @@ static int dijkstra(struct graph * graph, assert(nhops); assert(dist); - *nhops = malloc(sizeof(**nhops) * graph->nr_vertices); + *nhops = malloc(sizeof(**nhops) * graph->vertices.len); if (*nhops == NULL) goto fail_pnhops; - *dist = malloc(sizeof(**dist) * graph->nr_vertices); + *dist = malloc(sizeof(**dist) * graph->vertices.len); if (*dist == NULL) goto fail_pdist; - used = malloc(sizeof(*used) * graph->nr_vertices); + used = malloc(sizeof(*used) * graph->vertices.len); if (used == NULL) goto fail_used; /* Init the data structures */ - memset(used, 0, sizeof(*used) * graph->nr_vertices); - memset(*nhops, 0, sizeof(**nhops) * graph->nr_vertices); - memset(*dist, 0, sizeof(**dist) * graph->nr_vertices); + memset(used, 0, sizeof(*used) * graph->vertices.len); + memset(*nhops, 0, sizeof(**nhops) * graph->vertices.len); + memset(*dist, 0, sizeof(**dist) * graph->vertices.len); - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); (*dist)[i++] = (v->addr == src) ? 0 : INT_MAX; } @@ -527,7 +509,7 @@ static int graph_routing_table_simple(struct graph * graph, assert(dist); /* We need at least 2 vertices for a table */ - if (graph->nr_vertices < 2) + if (graph->vertices.len < 2) goto fail_vertices; if (dijkstra(graph, s_addr, &nhops, dist)) @@ -536,7 +518,7 @@ static int graph_routing_table_simple(struct graph * graph, list_head_init(table); /* Now construct the routing table from the nhops. */ - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); /* This is the src */ @@ -634,7 +616,7 @@ static int graph_routing_table_lfa(struct graph * graph, addrs[j] = -1; } - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr != s_addr) @@ -660,7 +642,7 @@ static int graph_routing_table_lfa(struct graph * graph, } /* Loop though all nodes to see if we have a LFA for them. */ - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr == s_addr) @@ -717,14 +699,14 @@ static int graph_routing_table_ecmp(struct graph * graph, assert(graph); assert(dist); - if (graph-> nr_vertices < 2) + if (graph->vertices.len < 2) goto fail_vertices; - forwarding = malloc(sizeof(*forwarding) * graph->nr_vertices); + forwarding = malloc(sizeof(*forwarding) * graph->vertices.len); if (forwarding == NULL) goto fail_vertices; - for (i = 0; i < graph->nr_vertices; ++i) + for (i = 0; i < graph->vertices.len; ++i) list_head_init(&forwarding[i]); if (dijkstra(graph, s_addr, &nhops, dist)) @@ -745,7 +727,7 @@ static int graph_routing_table_ecmp(struct graph * graph, free(nhops); - list_for_each(h, &graph->vertices) { + llist_for_each(h, &graph->vertices) { v = list_entry(h, struct vertex, next); if (tmp_dist[v->index] + 1 == (*dist)[v->index]) { n = malloc(sizeof(*n)); @@ -763,7 +745,7 @@ static int graph_routing_table_ecmp(struct graph * graph, list_head_init(table); i = 0; - list_for_each(p, &graph->vertices) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr == s_addr) { ++i; diff --git a/src/ipcpd/unicast/routing/graph.h b/src/ipcpd/unicast/routing/graph.h index 8190cc6c..f3766771 100644 --- a/src/ipcpd/unicast/routing/graph.h +++ b/src/ipcpd/unicast/routing/graph.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Undirected graph structure * diff --git a/src/ipcpd/unicast/routing/link-state.c b/src/ipcpd/unicast/routing/link-state.c index 57c0c7cb..051dd98d 100644 --- a/src/ipcpd/unicast/routing/link-state.c +++ b/src/ipcpd/unicast/routing/link-state.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Link state routing policy * @@ -42,6 +42,7 @@ #include <ouroboros/rib.h> #include <ouroboros/utils.h> +#include "addr-auth.h" #include "common/comp.h" #include "common/connmgr.h" #include "graph.h" @@ -54,16 +55,19 @@ #include <inttypes.h> #include <string.h> -#define RECALC_TIME 4 -#define LS_UPDATE_TIME 15 -#define LS_TIMEO 60 #define LS_ENTRY_SIZE 104 -#define LSDB "lsdb" +#define lsdb "lsdb" #ifndef CLOCK_REALTIME_COARSE #define CLOCK_REALTIME_COARSE CLOCK_REALTIME #endif +#define LINK_FMT ADDR_FMT32 "--" ADDR_FMT32 +#define LINK_VAL(src, dst) ADDR_VAL32(&src), ADDR_VAL32(&dst) + +#define LSU_FMT "LSU ["ADDR_FMT32 " -- " ADDR_FMT32 " seq: %09" PRIu64 "]" +#define LSU_VAL(src, dst, seqno) ADDR_VAL32(&src), ADDR_VAL32(&dst), seqno + struct lsa { uint64_t d_addr; uint64_t s_addr; @@ -106,30 +110,37 @@ struct nb { }; struct { - struct list_head nbs; - size_t nbs_len; + uint64_t addr; + + enum routing_algo routing_algo; + + struct ls_config conf; + fset_t * mgmt_set; - struct list_head db; - size_t db_len; + struct graph * graph; - pthread_rwlock_t db_lock; + struct { + struct llist nbs; + struct llist db; + pthread_rwlock_t lock; + }; - struct graph * graph; + struct { + struct list_head list; + pthread_mutex_t mtx; + } instances; pthread_t lsupdate; pthread_t lsreader; pthread_t listener; - - struct list_head routing_instances; - pthread_mutex_t routing_i_lock; - - enum routing_algo routing_algo; } ls; struct routing_ops link_state_ops = { - .init = link_state_init, + .init = (int (*)(void *, enum pol_pff *)) link_state_init, .fini = link_state_fini, + .start = link_state_start, + .stop = link_state_stop, .routing_i_create = link_state_routing_i_create, .routing_i_destroy = link_state_routing_i_destroy }; @@ -138,7 +149,7 @@ static int str_adj(struct adjacency * adj, char * buf, size_t len) { - char tmbuf[64]; + char tmstr[RIB_TM_STRLEN]; char srcbuf[64]; char dstbuf[64]; char seqnobuf[64]; @@ -149,15 +160,16 @@ static int str_adj(struct adjacency * adj, if (len < LS_ENTRY_SIZE) return -1; - tm = localtime(&adj->stamp); - strftime(tmbuf, sizeof(tmbuf), "%F %T", tm); /* 19 chars */ + tm = gmtime(&adj->stamp); + strftime(tmstr, sizeof(tmstr), RIB_TM_FORMAT, tm); - sprintf(srcbuf, "%" PRIu64, adj->src); - sprintf(dstbuf, "%" PRIu64, adj->dst); + sprintf(srcbuf, ADDR_FMT32, ADDR_VAL32(&adj->src)); + sprintf(dstbuf, ADDR_FMT32, ADDR_VAL32(&adj->dst)); sprintf(seqnobuf, "%" PRIu64, adj->seqno); - sprintf(buf, "src: %20s\ndst: %20s\nseqno: %18s\nupd: %20s\n", - srcbuf, dstbuf, seqnobuf, tmbuf); + sprintf(buf, "src: %20s\ndst: %20s\nseqno: %18s\n" + "upd: %s\n", + srcbuf, dstbuf, seqnobuf, tmstr); return LS_ENTRY_SIZE; } @@ -169,9 +181,9 @@ static struct adjacency * get_adj(const char * path) assert(path); - list_for_each(p, &ls.db) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); - sprintf(entry, "%" PRIu64 ".%" PRIu64, a->src, a->dst); + sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst)); if (strcmp(entry, path) == 0) return a; } @@ -194,7 +206,7 @@ static int lsdb_rib_getattr(const char * path, clock_gettime(CLOCK_REALTIME_COARSE, &now); - pthread_rwlock_rdlock(&ls.db_lock); + pthread_rwlock_rdlock(&ls.lock); adj = get_adj(entry); if (adj != NULL) { @@ -205,7 +217,7 @@ static int lsdb_rib_getattr(const char * path, attr->size = 0; } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return 0; } @@ -223,9 +235,9 @@ static int lsdb_rib_read(const char * path, entry = strstr(path, RIB_SEPARATOR) + 1; assert(entry); - pthread_rwlock_rdlock(&ls.db_lock); + pthread_rwlock_rdlock(&ls.lock); - if (ls.db_len + ls.nbs_len == 0) + if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) goto fail; a = get_adj(entry); @@ -236,11 +248,11 @@ static int lsdb_rib_read(const char * path, if (size < 0) goto fail; - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return size; fail: - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return -1; } @@ -250,60 +262,52 @@ static int lsdb_rib_readdir(char *** buf) char entry[RIB_PATH_LEN + 1]; ssize_t idx = 0; - assert(buf); + assert(buf != NULL); - pthread_rwlock_rdlock(&ls.db_lock); + pthread_rwlock_rdlock(&ls.lock); - if (ls.db_len + ls.nbs_len == 0) { - pthread_rwlock_unlock(&ls.db_lock); - return 0; + if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) { + *buf = NULL; + goto no_entries; } - *buf = malloc(sizeof(**buf) * (ls.db_len + ls.nbs_len)); - if (*buf == NULL) { - pthread_rwlock_unlock(&ls.db_lock); - return -ENOMEM; - } - list_for_each(p, &ls.nbs) { + *buf = malloc(sizeof(**buf) * (ls.db.len + ls.nbs.len)); + if (*buf == NULL) + goto fail_entries; + + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); - char * str = (nb->type == NB_DT ? "dt." : "mgmt."); - sprintf(entry, "%s%" PRIu64, str, nb->addr); + char * str = (nb->type == NB_DT ? ".dt " : ".mgmt "); + sprintf(entry, "%s" ADDR_FMT32 , str, ADDR_VAL32(&nb->addr)); (*buf)[idx] = malloc(strlen(entry) + 1); - if ((*buf)[idx] == NULL) { - while (idx-- > 0) - free((*buf)[idx]); - free(*buf); - pthread_rwlock_unlock(&ls.db_lock); - return -ENOMEM; - } - - strcpy((*buf)[idx], entry); + if ((*buf)[idx] == NULL) + goto fail_entry; - idx++; + strcpy((*buf)[idx++], entry); } - list_for_each(p, &ls.db) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); - sprintf(entry, "%" PRIu64 ".%" PRIu64, a->src, a->dst); + sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst)); (*buf)[idx] = malloc(strlen(entry) + 1); - if ((*buf)[idx] == NULL) { - ssize_t j; - for (j = 0; j < idx; ++j) - free(*buf[j]); - free(buf); - pthread_rwlock_unlock(&ls.db_lock); - return -ENOMEM; - } - - strcpy((*buf)[idx], entry); + if ((*buf)[idx] == NULL) + goto fail_entry; - idx++; + strcpy((*buf)[idx++], entry); } - - pthread_rwlock_unlock(&ls.db_lock); + no_entries: + pthread_rwlock_unlock(&ls.lock); return idx; + + fail_entry: + while (idx-- > 0) + free((*buf)[idx]); + free(*buf); + fail_entries: + pthread_rwlock_unlock(&ls.lock); + return -ENOMEM; } static struct rib_ops r_ops = { @@ -319,28 +323,28 @@ static int lsdb_add_nb(uint64_t addr, struct list_head * p; struct nb * nb; - pthread_rwlock_wrlock(&ls.db_lock); + pthread_rwlock_wrlock(&ls.lock); - list_for_each(p, &ls.nbs) { + llist_for_each(p, &ls.nbs) { struct nb * el = list_entry(p, struct nb, next); - if (el->addr == addr && el->type == type) { - log_dbg("Already know %s neighbor %" PRIu64 ".", - type == NB_DT ? "dt" : "mgmt", addr); - if (el->fd != fd) { - log_warn("Existing neighbor assigned new fd."); - el->fd = fd; - } - pthread_rwlock_unlock(&ls.db_lock); - return -EPERM; - } - if (addr > el->addr) break; + if (el->addr != addr || el->type != type) + continue; + + log_dbg("Already know %s neighbor " ADDR_FMT32 ".", + type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); + if (el->fd != fd) { + log_warn("Existing neighbor assigned new fd."); + el->fd = fd; + } + pthread_rwlock_unlock(&ls.lock); + return -EPERM; } nb = malloc(sizeof(*nb)); if (nb == NULL) { - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return -ENOMEM; } @@ -348,14 +352,12 @@ static int lsdb_add_nb(uint64_t addr, nb->fd = fd; nb->type = type; - list_add_tail(&nb->next, p); + llist_add_tail_at(&nb->next, p, &ls.nbs); - ++ls.nbs_len; + log_dbg("Type %s neighbor " ADDR_FMT32 " added.", + nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); - log_dbg("Type %s neighbor %" PRIu64 " added.", - nb->type == NB_DT ? "dt" : "mgmt", addr); - - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return 0; } @@ -366,22 +368,22 @@ static int lsdb_del_nb(uint64_t addr, struct list_head * p; struct list_head * h; - pthread_rwlock_wrlock(&ls.db_lock); + pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.nbs) { + llist_for_each_safe(p, h, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); - if (nb->addr == addr && nb->fd == fd) { - list_del(&nb->next); - --ls.nbs_len; - pthread_rwlock_unlock(&ls.db_lock); - log_dbg("Type %s neighbor %" PRIu64 " deleted.", - nb->type == NB_DT ? "dt" : "mgmt", addr); - free(nb); - return 0; - } + if (nb->addr != addr || nb->fd != fd) + continue; + + llist_del(&nb->next, &ls.nbs); + pthread_rwlock_unlock(&ls.lock); + log_dbg("Type %s neighbor " ADDR_FMT32 " deleted.", + nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); + free(nb); + return 0; } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return -EPERM; } @@ -391,18 +393,18 @@ static int nbr_to_fd(uint64_t addr) struct list_head * p; int fd; - pthread_rwlock_rdlock(&ls.db_lock); + pthread_rwlock_rdlock(&ls.lock); - list_for_each(p, &ls.nbs) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->addr == addr && nb->type == NB_DT) { fd = nb->fd; - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return fd; } } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return -1; } @@ -417,8 +419,7 @@ static void calculate_pff(struct routing_i * instance) assert(instance); - if (graph_routing_table(ls.graph, ls.routing_algo, - ipcpi.dt_addr, &table)) + if (graph_routing_table(ls.graph, ls.routing_algo, ls.addr, &table)) return; pff_lock(instance->pff); @@ -453,8 +454,8 @@ static void set_pff_modified(bool calc) { struct list_head * p; - pthread_mutex_lock(&ls.routing_i_lock); - list_for_each(p, &ls.routing_instances) { + pthread_mutex_lock(&ls.instances.mtx); + list_for_each(p, &ls.instances.list) { struct routing_i * inst = list_entry(p, struct routing_i, next); pthread_mutex_lock(&inst->lock); @@ -463,7 +464,7 @@ static void set_pff_modified(bool calc) if (calc) calculate_pff(inst); } - pthread_mutex_unlock(&ls.routing_i_lock); + pthread_mutex_unlock(&ls.instances.mtx); } static int lsdb_add_link(uint64_t src, @@ -480,9 +481,9 @@ static int lsdb_add_link(uint64_t src, clock_gettime(CLOCK_REALTIME_COARSE, &now); - pthread_rwlock_wrlock(&ls.db_lock); + pthread_rwlock_wrlock(&ls.lock); - list_for_each(p, &ls.db) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); if (a->dst == dst && a->src == src) { if (a->seqno < seqno) { @@ -490,7 +491,7 @@ static int lsdb_add_link(uint64_t src, a->seqno = seqno; ret = 0; } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return ret; } @@ -500,7 +501,7 @@ static int lsdb_add_link(uint64_t src, adj = malloc(sizeof(*adj)); if (adj == NULL) { - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return -ENOMEM; } @@ -509,14 +510,12 @@ static int lsdb_add_link(uint64_t src, adj->seqno = seqno; adj->stamp = now.tv_sec; - list_add_tail(&adj->next, p); - - ls.db_len++; + llist_add_tail_at(&adj->next, p, &ls.db); if (graph_update_edge(ls.graph, src, dst, *qs)) log_warn("Failed to add edge to graph."); - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); set_pff_modified(true); @@ -529,25 +528,23 @@ static int lsdb_del_link(uint64_t src, struct list_head * p; struct list_head * h; - pthread_rwlock_wrlock(&ls.db_lock); + pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.db) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); if (a->dst == dst && a->src == src) { - list_del(&a->next); + llist_del(&a->next, &ls.db); if (graph_del_edge(ls.graph, src, dst)) log_warn("Failed to delete edge from graph."); - ls.db_len--; - - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); set_pff_modified(false); free(a); return 0; } } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); return -EPERM; } @@ -570,7 +567,7 @@ static void * periodic_recalc_pff(void * o) if (modified) calculate_pff(inst); - sleep(RECALC_TIME); + sleep(ls.conf.t_recalc); } return (void *) 0; @@ -587,10 +584,20 @@ static void send_lsm(uint64_t src, lsm.s_addr = hton64(src); lsm.seqno = hton64(seqno); - list_for_each(p, &ls.nbs) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); - if (nb->type == NB_MGMT) - flow_write(nb->fd, &lsm, sizeof(lsm)); + if (nb->type != NB_MGMT) + continue; + + if (flow_write(nb->fd, &lsm, sizeof(lsm)) < 0) + log_err("Failed to send LSM to " ADDR_FMT32, + ADDR_VAL32(&nb->addr)); +#ifdef DEBUG_PROTO_LS + else + log_proto(LSU_FMT " --> " ADDR_FMT32, + LSU_VAL(src, dst, seqno), + ADDR_VAL32(&nb->addr)); +#endif } } @@ -604,9 +611,9 @@ static void lsdb_replicate(int fd) list_head_init(©); /* Lock the lsdb, copy the lsms and send outside of lock. */ - pthread_rwlock_rdlock(&ls.db_lock); + pthread_rwlock_rdlock(&ls.lock); - list_for_each(p, &ls.db) { + llist_for_each(p, &ls.db) { struct adjacency * adj; struct adjacency * cpy; adj = list_entry(p, struct adjacency, next); @@ -623,7 +630,7 @@ static void lsdb_replicate(int fd) list_add_tail(&cpy->next, ©); } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); list_for_each_safe(p, h, ©) { struct lsa lsm; @@ -649,17 +656,17 @@ static void * lsupdate(void * o) while (true) { clock_gettime(CLOCK_REALTIME_COARSE, &now); - pthread_rwlock_wrlock(&ls.db_lock); + pthread_rwlock_wrlock(&ls.lock); - pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.db_lock); + pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - list_for_each_safe(p, h, &ls.db) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * adj; adj = list_entry(p, struct adjacency, next); - if (now.tv_sec - adj->stamp > LS_TIMEO) { - list_del(&adj->next); - log_dbg("%" PRIu64 " - %" PRIu64" timed out.", - adj->src, adj->dst); + if (now.tv_sec > adj->stamp + ls.conf.t_timeo) { + llist_del(&adj->next, &ls.db); + log_dbg(LINK_FMT " timed out.", + LINK_VAL(adj->src, adj->dst)); if (graph_del_edge(ls.graph, adj->src, adj->dst)) log_err("Failed to del edge."); @@ -667,7 +674,7 @@ static void * lsupdate(void * o) continue; } - if (adj->src == ipcpi.dt_addr) { + if (adj->src == ls.addr) { adj->seqno++; send_lsm(adj->src, adj->dst, adj->seqno); adj->stamp = now.tv_sec; @@ -676,7 +683,7 @@ static void * lsupdate(void * o) pthread_cleanup_pop(true); - sleep(LS_UPDATE_TIME); + sleep(ls.conf.t_update); } return (void *) 0; @@ -708,15 +715,36 @@ static void forward_lsm(uint8_t * buf, int in_fd) { struct list_head * p; +#ifdef DEBUG_PROTO_LS + struct lsa lsm; + + assert(buf); + assert(len >= sizeof(struct lsa)); + + memcpy(&lsm, buf, sizeof(lsm)); - pthread_rwlock_rdlock(&ls.db_lock); + lsm.s_addr = ntoh64(lsm.s_addr); + lsm.d_addr = ntoh64(lsm.d_addr); + lsm.seqno = ntoh64(lsm.seqno); +#endif + pthread_rwlock_rdlock(&ls.lock); - pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.db_lock); + pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - list_for_each(p, &ls.nbs) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); - if (nb->type == NB_MGMT && nb->fd != in_fd) - flow_write(nb->fd, buf, len); + if (nb->type != NB_MGMT || nb->fd == in_fd) + continue; + + if (flow_write(nb->fd, buf, len) < 0) + log_err("Failed to forward LSM to " ADDR_FMT32, + ADDR_VAL32(&nb->addr)); +#ifdef DEBUG_PROTO_LS + else + log_proto(LSU_FMT " --> " ADDR_FMT32 " [forwarded]", + LSU_VAL(lsm.s_addr, lsm.d_addr, lsm.seqno), + ADDR_VAL32(&nb->addr)); +#endif } pthread_cleanup_pop(true); @@ -729,13 +757,13 @@ static void cleanup_fqueue(void * fq) static void * lsreader(void * o) { - fqueue_t * fq; - int ret; - uint8_t buf[sizeof(struct lsa)]; - int fd; - qosspec_t qs; - struct lsa * msg; - size_t len; + fqueue_t * fq; + int ret; + uint8_t buf[sizeof(struct lsa)]; + int fd; + qosspec_t qs; + struct lsa msg; + size_t len; (void) o; @@ -758,15 +786,22 @@ static void * lsreader(void * o) if (fqueue_type(fq) != FLOW_PKT) continue; - len = flow_read(fd, buf, sizeof(*msg)); - if (len <= 0 || len != sizeof(*msg)) + len = flow_read(fd, buf, sizeof(msg)); + if (len <= 0 || len != sizeof(msg)) continue; - msg = (struct lsa *) buf; - - if (lsdb_add_link(ntoh64(msg->s_addr), - ntoh64(msg->d_addr), - ntoh64(msg->seqno), + memcpy(&msg, buf, sizeof(msg)); + msg.s_addr = ntoh64(msg.s_addr); + msg.d_addr = ntoh64(msg.d_addr); + msg.seqno = ntoh64(msg.seqno); +#ifdef DEBUG_PROTO_LS + log_proto(LSU_FMT " <-- " ADDR_FMT32, + LSU_VAL(msg.s_addr, msg.d_addr, msg.seqno), + ADDR_VAL32(&ls.addr)); +#endif + if (lsdb_add_link(msg.s_addr, + msg.d_addr, + msg.seqno, &qs)) continue; @@ -787,14 +822,14 @@ static void flow_event(int fd, log_dbg("Notifying routing instances of flow event."); - pthread_mutex_lock(&ls.routing_i_lock); + pthread_mutex_lock(&ls.instances.mtx); - list_for_each(p, &ls.routing_instances) { + list_for_each(p, &ls.instances.list) { struct routing_i * ri = list_entry(p, struct routing_i, next); pff_flow_state_change(ri->pff, fd, up); } - pthread_mutex_unlock(&ls.routing_i_lock); + pthread_mutex_unlock(&ls.instances.mtx); } static void handle_event(void * self, @@ -816,27 +851,27 @@ static void handle_event(void * self, switch (event) { case NOTIFY_DT_CONN_ADD: - pthread_rwlock_rdlock(&ls.db_lock); + pthread_rwlock_rdlock(&ls.lock); - pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.db_lock); + pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - send_lsm(ipcpi.dt_addr, c->conn_info.addr, 0); + send_lsm(ls.addr, c->conn_info.addr, 0); pthread_cleanup_pop(true); if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_DT)) - log_dbg("Failed to add neighbor to LSDB."); + log_dbg("Failed to add neighbor to lsdb."); - if (lsdb_add_link(ipcpi.dt_addr, c->conn_info.addr, 0, &qs)) - log_dbg("Failed to add new adjacency to LSDB."); + if (lsdb_add_link(ls.addr, c->conn_info.addr, 0, &qs)) + log_dbg("Failed to add new adjacency to lsdb."); break; case NOTIFY_DT_CONN_DEL: flow_event(c->flow_info.fd, false); if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd)) - log_dbg("Failed to delete neighbor from LSDB."); + log_dbg("Failed to delete neighbor from lsdb."); - if (lsdb_del_link(ipcpi.dt_addr, c->conn_info.addr)) - log_dbg("Local link was not in LSDB."); + if (lsdb_del_link(ls.addr, c->conn_info.addr)) + log_dbg("Local link was not in lsdb."); break; case NOTIFY_DT_CONN_QOS: log_dbg("QoS changes currently unsupported."); @@ -852,14 +887,14 @@ static void handle_event(void * self, fccntl(c->flow_info.fd, FLOWSFLAGS, flags | FLOWFRNOPART); fset_add(ls.mgmt_set, c->flow_info.fd); if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_MGMT)) - log_warn("Failed to add mgmt neighbor to LSDB."); + log_warn("Failed to add mgmt neighbor to lsdb."); /* replicate the entire lsdb */ lsdb_replicate(c->flow_info.fd); break; case NOTIFY_MGMT_CONN_DEL: fset_del(ls.mgmt_set, c->flow_info.fd); if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd)) - log_warn("Failed to delete mgmt neighbor from LSDB."); + log_warn("Failed to delete mgmt neighbor from lsdb."); break; default: break; @@ -886,11 +921,11 @@ struct routing_i * link_state_routing_i_create(struct pff * pff) periodic_recalc_pff, tmp)) goto fail_pthread_create_lsupdate; - pthread_mutex_lock(&ls.routing_i_lock); + pthread_mutex_lock(&ls.instances.mtx); - list_add(&tmp->next, &ls.routing_instances); + list_add(&tmp->next, &ls.instances.list); - pthread_mutex_unlock(&ls.routing_i_lock); + pthread_mutex_unlock(&ls.instances.mtx); return tmp; @@ -906,11 +941,11 @@ void link_state_routing_i_destroy(struct routing_i * instance) { assert(instance); - pthread_mutex_lock(&ls.routing_i_lock); + pthread_mutex_lock(&ls.instances.mtx); list_del(&instance->next); - pthread_mutex_unlock(&ls.routing_i_lock); + pthread_mutex_unlock(&ls.instances.mtx); pthread_cancel(instance->calculator); @@ -921,96 +956,143 @@ void link_state_routing_i_destroy(struct routing_i * instance) free(instance); } -int link_state_init(enum pol_routing pr) +int link_state_start(void) +{ + if (notifier_reg(handle_event, NULL)) { + log_err("Failed to register link-state with notifier."); + goto fail_notifier_reg; + } + + if (pthread_create(&ls.lsupdate, NULL, lsupdate, NULL)) { + log_err("Failed to create lsupdate thread."); + goto fail_pthread_create_lsupdate; + } + + if (pthread_create(&ls.lsreader, NULL, lsreader, NULL)) { + log_err("Failed to create lsreader thread."); + goto fail_pthread_create_lsreader; + } + + if (pthread_create(&ls.listener, NULL, ls_conn_handle, NULL)) { + log_err("Failed to create listener thread."); + goto fail_pthread_create_listener; + } + + return 0; + + fail_pthread_create_listener: + pthread_cancel(ls.lsreader); + pthread_join(ls.lsreader, NULL); + fail_pthread_create_lsreader: + pthread_cancel(ls.lsupdate); + pthread_join(ls.lsupdate, NULL); + fail_pthread_create_lsupdate: + notifier_unreg(handle_event); + fail_notifier_reg: + return -1; +} + +void link_state_stop(void) +{ + pthread_cancel(ls.listener); + pthread_cancel(ls.lsreader); + pthread_cancel(ls.lsupdate); + + pthread_join(ls.listener, NULL); + pthread_join(ls.lsreader, NULL); + pthread_join(ls.lsupdate, NULL); + + notifier_unreg(handle_event); +} + + +int link_state_init(struct ls_config * conf, + enum pol_pff * pff_type) { struct conn_info info; + assert(conf != NULL); + assert(pff_type != NULL); + memset(&info, 0, sizeof(info)); + ls.addr = addr_auth_address(); + strcpy(info.comp_name, LS_COMP); strcpy(info.protocol, LS_PROTO); info.pref_version = 1; info.pref_syntax = PROTO_GPB; - info.addr = ipcpi.dt_addr; + info.addr = ls.addr; - switch (pr) { - case ROUTING_LINK_STATE: - log_dbg("Using link state routing policy."); + ls.conf = *conf; + + switch (conf->pol) { + case LS_SIMPLE: + *pff_type = PFF_SIMPLE; ls.routing_algo = ROUTING_SIMPLE; + log_dbg("Using Link State Routing policy."); break; - case ROUTING_LINK_STATE_LFA: - log_dbg("Using Loop-Free Alternates policy."); + case LS_LFA: ls.routing_algo = ROUTING_LFA; + *pff_type = PFF_ALTERNATE; + log_dbg("Using Loop-Free Alternates policy."); break; - case ROUTING_LINK_STATE_ECMP: - log_dbg("Using Equal-Cost Multipath policy."); + case LS_ECMP: ls.routing_algo = ROUTING_ECMP; + *pff_type = PFF_MULTIPATH; + log_dbg("Using Equal-Cost Multipath policy."); break; default: goto fail_graph; } + log_dbg("LS update interval: %ld seconds.", ls.conf.t_update); + log_dbg("LS link timeout : %ld seconds.", ls.conf.t_timeo); + log_dbg("LS recalc interval: %ld seconds.", ls.conf.t_recalc); + ls.graph = graph_create(); if (ls.graph == NULL) goto fail_graph; - if (notifier_reg(handle_event, NULL)) - goto fail_notifier_reg; - - if (pthread_rwlock_init(&ls.db_lock, NULL)) - goto fail_db_lock_init; + if (pthread_rwlock_init(&ls.lock, NULL)) { + log_err("Failed to init lock."); + goto fail_lock_init; + } - if (pthread_mutex_init(&ls.routing_i_lock, NULL)) + if (pthread_mutex_init(&ls.instances.mtx, NULL)) { + log_err("Failed to init instances mutex."); goto fail_routing_i_lock_init; + } - if (connmgr_comp_init(COMPID_MGMT, &info)) + if (connmgr_comp_init(COMPID_MGMT, &info)) { + log_err("Failed to init connmgr."); goto fail_connmgr_comp_init; + } ls.mgmt_set = fset_create(); - if (ls.mgmt_set == NULL) + if (ls.mgmt_set == NULL) { + log_err("Failed to create fset."); goto fail_fset_create; + } - list_head_init(&ls.db); - list_head_init(&ls.nbs); - list_head_init(&ls.routing_instances); - - if (pthread_create(&ls.lsupdate, NULL, lsupdate, NULL)) - goto fail_pthread_create_lsupdate; - - if (pthread_create(&ls.lsreader, NULL, lsreader, NULL)) - goto fail_pthread_create_lsreader; - - if (pthread_create(&ls.listener, NULL, ls_conn_handle, NULL)) - goto fail_pthread_create_listener; + llist_init(&ls.db); + llist_init(&ls.nbs); + list_head_init(&ls.instances.list); - if (rib_reg(LSDB, &r_ops)) + if (rib_reg(lsdb, &r_ops)) goto fail_rib_reg; - ls.db_len = 0; - ls.nbs_len = 0; - return 0; fail_rib_reg: - pthread_cancel(ls.listener); - pthread_join(ls.listener, NULL); - fail_pthread_create_listener: - pthread_cancel(ls.lsreader); - pthread_join(ls.lsreader, NULL); - fail_pthread_create_lsreader: - pthread_cancel(ls.lsupdate); - pthread_join(ls.lsupdate, NULL); - fail_pthread_create_lsupdate: fset_destroy(ls.mgmt_set); fail_fset_create: connmgr_comp_fini(COMPID_MGMT); fail_connmgr_comp_init: - pthread_mutex_destroy(&ls.routing_i_lock); + pthread_mutex_destroy(&ls.instances.mtx); fail_routing_i_lock_init: - pthread_rwlock_destroy(&ls.db_lock); - fail_db_lock_init: - notifier_unreg(handle_event); - fail_notifier_reg: + pthread_rwlock_destroy(&ls.lock); + fail_lock_init: graph_destroy(ls.graph); fail_graph: return -1; @@ -1021,17 +1103,7 @@ void link_state_fini(void) struct list_head * p; struct list_head * h; - rib_unreg(LSDB); - - notifier_unreg(handle_event); - - pthread_cancel(ls.listener); - pthread_cancel(ls.lsreader); - pthread_cancel(ls.lsupdate); - - pthread_join(ls.listener, NULL); - pthread_join(ls.lsreader, NULL); - pthread_join(ls.lsupdate, NULL); + rib_unreg(lsdb); fset_destroy(ls.mgmt_set); @@ -1039,17 +1111,17 @@ void link_state_fini(void) graph_destroy(ls.graph); - pthread_rwlock_wrlock(&ls.db_lock); + pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.db) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); - list_del(&a->next); + llist_del(&a->next, &ls.db); free(a); } - pthread_rwlock_unlock(&ls.db_lock); + pthread_rwlock_unlock(&ls.lock); - pthread_rwlock_destroy(&ls.db_lock); + pthread_rwlock_destroy(&ls.lock); - pthread_mutex_destroy(&ls.routing_i_lock); + pthread_mutex_destroy(&ls.instances.mtx); } diff --git a/src/ipcpd/unicast/routing/link-state.h b/src/ipcpd/unicast/routing/link-state.h index d77d72df..38e19065 100644 --- a/src/ipcpd/unicast/routing/link-state.h +++ b/src/ipcpd/unicast/routing/link-state.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Link state routing policy * @@ -28,10 +28,15 @@ #include "ops.h" -int link_state_init(enum pol_routing pr); +int link_state_init(struct ls_config * ls, + enum pol_pff * pff_type); void link_state_fini(void); +int link_state_start(void); + +void link_state_stop(void); + struct routing_i * link_state_routing_i_create(struct pff * pff); void link_state_routing_i_destroy(struct routing_i * instance); diff --git a/src/ipcpd/unicast/routing/ops.h b/src/ipcpd/unicast/routing/ops.h index 8a79b7ec..b19c5176 100644 --- a/src/ipcpd/unicast/routing/ops.h +++ b/src/ipcpd/unicast/routing/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Routing policy ops * @@ -26,10 +26,15 @@ #include "pff.h" struct routing_ops { - int (* init)(enum pol_routing pr); + int (* init)(void * conf, + enum pol_pff * pff_type); void (* fini)(void); + int (* start)(void); + + void (* stop)(void); + struct routing_i * (* routing_i_create)(struct pff * pff); void (* routing_i_destroy)(struct routing_i * instance); diff --git a/src/ipcpd/unicast/routing/pol.h b/src/ipcpd/unicast/routing/pol.h index b6a6f150..545f5df2 100644 --- a/src/ipcpd/unicast/routing/pol.h +++ b/src/ipcpd/unicast/routing/pol.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Routing policies * diff --git a/src/ipcpd/unicast/routing/tests/CMakeLists.txt b/src/ipcpd/unicast/routing/tests/CMakeLists.txt index 9d24bf03..be2de72c 100644 --- a/src/ipcpd/unicast/routing/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/routing/tests/CMakeLists.txt @@ -3,36 +3,32 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR get_filename_component(CURRENT_BINARY_PARENT_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${CURRENT_SOURCE_PARENT_DIR}) -include_directories(${CURRENT_BINARY_PARENT_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) +compute_test_prefix() + create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here graph_test.c ) -add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) -target_link_libraries(${PARENT_DIR}_test ouroboros-common) +add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests}) + +target_include_directories(${PARENT_DIR}_test PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CURRENT_SOURCE_PARENT_DIR} + ${CURRENT_BINARY_PARENT_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include + ${CMAKE_SOURCE_DIR}/src/ipcpd + ${CMAKE_BINARY_DIR}/src/ipcpd +) -add_dependencies(check ${PARENT_DIR}_test) +disable_test_logging_for_target(${PARENT_DIR}_test) +target_link_libraries(${PARENT_DIR}_test PRIVATE ouroboros-common) -set(tests_to_run ${${PARENT_DIR}_tests}) -if(CMAKE_VERSION VERSION_LESS "3.29.0") - remove(tests_to_run test_suite.c) -else () - list(POP_FRONT tests_to_run) -endif() +add_dependencies(build_tests ${PARENT_DIR}_test) -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) +ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests}) diff --git a/src/ipcpd/unicast/routing/tests/graph_test.c b/src/ipcpd/unicast/routing/tests/graph_test.c index d805640c..40a744ff 100644 --- a/src/ipcpd/unicast/routing/tests/graph_test.c +++ b/src/ipcpd/unicast/routing/tests/graph_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Test of the graph structure * |
