diff options
| -rw-r--r-- | src/ipcpd/normal/pol/graph.c | 114 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/graph.h | 19 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/link_state.c | 40 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/tests/graph_test.c | 130 | 
4 files changed, 197 insertions, 106 deletions
| diff --git a/src/ipcpd/normal/pol/graph.c b/src/ipcpd/normal/pol/graph.c index 9901fbaa..80a7de6f 100644 --- a/src/ipcpd/normal/pol/graph.c +++ b/src/ipcpd/normal/pol/graph.c @@ -438,40 +438,64 @@ static struct vertex ** dijkstra(struct graph * graph,          return prev;  } -ssize_t graph_routing_table(struct graph *           graph, -                            uint64_t                 s_addr, -                            struct routing_table *** table) +static void free_routing_table(struct list_head * table)  { -        struct vertex **   prevs; -        struct list_head * p = NULL; -        int                i = 0; -        int                index = 0; -        int                j = 0; -        int                k = 0; -        struct vertex *    prev; -        struct vertex *    nhop; -        struct vertex *    v; +        struct list_head * h; +        struct list_head * p; +        struct list_head * q; +        struct list_head * i; + +        list_for_each_safe(p, h, table) { +                struct routing_table * t = +                        list_entry(p, struct routing_table, next); +                list_for_each_safe(q, i, &t->nhops) { +                        struct nhop * n = +                                list_entry(q, struct nhop, next); +                        list_del(&n->next); +                        free(n); +                } +                list_del(&t->next); +                free(t); +        } +} + +void graph_free_routing_table(struct graph *     graph, +                              struct list_head * table) +{ +        assert(table); + +        pthread_mutex_lock(&graph->lock); + +        free_routing_table(table); + +        pthread_mutex_unlock(&graph->lock); +} + +int graph_routing_table(struct graph *     graph, +                        uint64_t           s_addr, +                        struct list_head * table) +{ +        struct vertex **       prevs; +        struct list_head *     p; +        int                    i = 0; +        int                    index = 0; +        struct vertex *        prev; +        struct vertex *        nhop; +        struct vertex *        v; +        struct routing_table * t; +        struct nhop *          n;          pthread_mutex_lock(&graph->lock);          /* We need at least 2 vertices for a table */ -        if (graph->nr_vertices < 2) { -                pthread_mutex_unlock(&graph->lock); -                return -1; -        } +        if (graph->nr_vertices < 2) +                goto fail_vertices;          prevs = dijkstra(graph, s_addr); -        if (prevs == NULL) { -                pthread_mutex_unlock(&graph->lock); -                return -1; -        } +        if (prevs == NULL) +                goto fail_vertices; -        *table = malloc(sizeof(**table) * (graph->nr_vertices - 1)); -        if (*table == NULL) { -                pthread_mutex_unlock(&graph->lock); -                free(prevs); -                return -1; -        } +        list_head_init(table);          /*           * Now loop through the list of predecessors @@ -495,19 +519,22 @@ ssize_t graph_routing_table(struct graph *           graph,                          index = get_vertex_index(graph, prev);                  } -                (*table)[j] = malloc(sizeof(***table)); -                if ((*table)[j] == NULL) { -                        pthread_mutex_unlock(&graph->lock); -                        for (k = 0; k < j; ++k) -                                free((*table)[k]); -                        free(*table); -                        free(prevs); -                        return -1; -                } +                t = malloc(sizeof(*t)); +                if (t == NULL) +                        goto fail_t; + +                list_head_init(&t->nhops); + +                n = malloc(sizeof(*n)); +                if (n == NULL) +                        goto fail_n; + +                t->dst = v->addr; +                n->nhop = nhop->addr; + +                list_add(&n->next, &t->nhops); +                list_add(&t->next, table); -                (*table)[j]->dst = v->addr; -                (*table)[j]->nhop = nhop->addr; -                j++;                  i++;          } @@ -515,5 +542,14 @@ ssize_t graph_routing_table(struct graph *           graph,          free(prevs); -        return j; +        return 0; + + fail_n: +        free(t); + fail_t: +        free_routing_table(table); +        free(prevs); + fail_vertices: +        pthread_mutex_unlock(&graph->lock); +        return -1;  } diff --git a/src/ipcpd/normal/pol/graph.h b/src/ipcpd/normal/pol/graph.h index 8d092524..7340ecb9 100644 --- a/src/ipcpd/normal/pol/graph.h +++ b/src/ipcpd/normal/pol/graph.h @@ -28,9 +28,15 @@  #include <inttypes.h> +struct nhop { +        struct list_head next; +        uint64_t         nhop; +}; +  struct routing_table { -        uint64_t dst; -        uint64_t nhop; +        struct list_head next; +        uint64_t         dst; +        struct list_head nhops;  };  struct graph * graph_create(void); @@ -46,8 +52,11 @@ int            graph_del_edge(struct graph * graph,                                uint64_t       s_addr,                                uint64_t       d_addr); -ssize_t        graph_routing_table(struct graph *           graph, -                                   uint64_t                 s_addr, -                                   struct routing_table *** table); +int            graph_routing_table(struct graph *     graph, +                                   uint64_t           s_addr, +                                   struct list_head * table); + +void           graph_free_routing_table(struct graph *     graph, +                                        struct list_head * table);  #endif /* OUROBOROS_IPCPD_NORMAL_GRAPH_H */ diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c index 26370682..ca837cc1 100644 --- a/src/ipcpd/normal/pol/link_state.c +++ b/src/ipcpd/normal/pol/link_state.c @@ -378,19 +378,18 @@ static int nbr_to_fd(uint64_t addr)  static void * calculate_pff(void * o)  { -        struct routing_i *      instance; -        struct routing_table ** table; -        ssize_t                 n_table; -        int                     i; -        int                     fd; +        struct routing_i * instance; +        int                i; +        int                fd; +        struct list_head   table; +        struct list_head * p; +        struct list_head * q; +        int                fds[1024];          instance = (struct routing_i *) o;          while (true) { -                table = NULL; -                n_table = graph_routing_table(ls.graph, -                                              ipcpi.dt_addr, &table); -                if (n_table < 0) { +                if (graph_routing_table(ls.graph, ipcpi.dt_addr, &table)) {                          sleep(RECALC_TIME);                          continue;                  } @@ -399,17 +398,28 @@ static void * calculate_pff(void * o)                  pff_flush(instance->pff); -                for (i = 0; i < n_table; i++) { -                        fd = nbr_to_fd(table[i]->nhop); -                        if (fd == -1) -                                continue; +                list_for_each(p, &table) { +                        struct routing_table * t = +                                list_entry(p, struct routing_table, next); + +                        list_for_each(q, &t->nhops) { +                                struct nhop * n = +                                        list_entry(q, struct nhop, next); + +                                fd = nbr_to_fd(n->nhop); +                                if (fd == -1) +                                        continue; -                        pff_add(instance->pff, table[i]->dst, &fd, 1); +                                fds[i++] = fd; +                        } + +                        pff_add(instance->pff, t->dst, fds, i);                  }                  pff_unlock(instance->pff); -                freepp(struct routing_table, table, n_table); +                graph_free_routing_table(ls.graph, &table); +                  sleep(RECALC_TIME);          } diff --git a/src/ipcpd/normal/pol/tests/graph_test.c b/src/ipcpd/normal/pol/tests/graph_test.c index 87574187..0baba6fc 100644 --- a/src/ipcpd/normal/pol/tests/graph_test.c +++ b/src/ipcpd/normal/pol/tests/graph_test.c @@ -30,80 +30,108 @@  #include "graph.c" -struct graph *          graph; -struct routing_table ** table; -ssize_t                 n_table; -qosspec_t               qs; +struct graph *   graph; +struct list_head table; +qosspec_t        qs;  int graph_test_entries(int entries)  { -        n_table = graph_routing_table(graph, 1, &table); +        struct list_head * p; +        int                i = 0; -        if (n_table != entries) { +        if (graph_routing_table(graph, 1, &table)) { +                printf("Failed to get routing table.\n"); +                return -1; +        } + +        list_for_each(p, &table) { +                i++; +        } + +        if (i != entries) {                  printf("Wrong number of entries.\n"); -                freepp(struct routing_table, table, n_table); +                graph_free_routing_table(graph, &table);                  return -1;          } -        freepp(struct routing_table, table, n_table); +        graph_free_routing_table(graph, &table);          return 0;  }  int graph_test_double_link(void)  { -        n_table = graph_routing_table(graph, 1, &table); -        if (n_table < 0 || table == NULL) { +        struct list_head * p; +        int                i = 0; + +        if (graph_routing_table(graph, 1, &table)) {                  printf("Failed to get routing table.\n");                  return -1;          } -        if (n_table != 2) { -                printf("Wrong number of entries.\n"); -                freepp(struct routing_table, table, n_table); -                return -1; +        list_for_each(p, &table) { +                i++;          } -        if ((table[0]->dst != 2 && table[0]->nhop != 2) || -            (table[0]->dst != 3 && table[0]->nhop != 2)) { -                printf("Wrong routing entry.\n"); -                freepp(struct routing_table, table, n_table); +        if (i != 2) { +                printf("Wrong number of entries.\n"); +                graph_free_routing_table(graph, &table);                  return -1;          } -        if ((table[1]->dst != 2 && table[1]->nhop != 2) || -            (table[0]->dst != 3 && table[0]->nhop != 2)) { -                printf("Wrong routing entry.\n"); -                freepp(struct routing_table, table, n_table); -                return -1; +        list_for_each(p, &table) { +                struct routing_table * t = +                        list_entry(p, struct routing_table, next); +                struct nhop *          n = +                        list_first_entry(&t->nhops, struct nhop, next); + +                if ((t->dst != 2 && n->nhop != 2) || +                    (t->dst != 3 && n->nhop != 2)) { +                        printf("Wrong routing entry.\n"); +                        graph_free_routing_table(graph, &table); +                        return -1; +                }          } -        freepp(struct routing_table, table, n_table); +        graph_free_routing_table(graph, &table);          return 0;  }  int graph_test_single_link(void)  { -        n_table = graph_routing_table(graph, 1, &table); -        if (n_table < 0 || table == NULL) { +        struct list_head * p; +        int                i = 0; + +        if (graph_routing_table(graph, 1, &table)) {                  printf("Failed to get routing table.\n");                  return -1;          } -        if (n_table != 1) { +        list_for_each(p, &table) { +                i++; +        } + +        if (i != 1) {                  printf("Wrong number of entries.\n"); -                freepp(struct routing_table, table, n_table); +                graph_free_routing_table(graph, &table);                  return -1;          } -        if (table[0]->dst != 2 && table[0]->nhop != 2) { -                printf("Wrong routing entry.\n"); -                freepp(struct routing_table, table, n_table); -                return -1; +        list_for_each(p, &table) { +                struct routing_table * t = +                        list_entry(p, struct routing_table, next); +                struct nhop *          n = +                        list_first_entry(&t->nhops, struct nhop, next); + +                if (t->dst != 2 && n->nhop != 2) { +                        printf("Wrong routing entry.\n"); +                        graph_free_routing_table(graph, &table); +                        return -1; +                }          } -        freepp(struct routing_table, table, n_table); +        graph_free_routing_table(graph, &table);          return 0;  } @@ -111,9 +139,9 @@ int graph_test_single_link(void)  int graph_test(int     argc,                 char ** argv)  { -        int i; -        int nhop; -        int dst; +        int                nhop; +        int                dst; +        struct list_head * p;          (void) argc;          (void) argv; @@ -192,50 +220,58 @@ int graph_test(int     argc,                  return -1;          } -        n_table = graph_routing_table(graph, 1, &table); +        if (graph_routing_table(graph, 1, &table)) { +                printf("Failed to get routing table.\n"); +                return -1; +        } + +        list_for_each(p, &table) { +                struct routing_table * t = +                        list_entry(p, struct routing_table, next); +                struct nhop *          n = +                        list_first_entry(&t->nhops, struct nhop, next); -        for (i = 0; i < 6; i++) { -                nhop = table[i]->nhop; -                dst = table[i]->dst; +                dst = t->dst; +                nhop = n->nhop;                  if (dst == 3 && nhop != 3) {                          printf("Wrong entry."); -                        freepp(struct routing_table, table, n_table); +                        graph_free_routing_table(graph, &table);                          return -1;                  }                  if (dst == 2 && nhop != 2) {                          printf("Wrong entry."); -                        freepp(struct routing_table, table, n_table); +                        graph_free_routing_table(graph, &table);                          return -1;                  }                  if (dst == 6 && nhop != 2) {                          printf("Wrong entry."); -                        freepp(struct routing_table, table, n_table); +                        graph_free_routing_table(graph, &table);                          return -1;                  }                  if (dst == 4 && nhop != 3) {                          printf("Wrong entry."); -                        freepp(struct routing_table, table, n_table); +                        graph_free_routing_table(graph, &table);                          return -1;                  }                  if (dst == 5 && nhop != 3) {                          printf("Wrong entry."); -                        freepp(struct routing_table, table, n_table); +                        graph_free_routing_table(graph, &table);                          return -1;                  }                  if (dst == 7 && nhop != 3) {                          printf("Wrong entry."); -                        freepp(struct routing_table, table, n_table); +                        graph_free_routing_table(graph, &table);                          return -1;                  }          } -        freepp(struct routing_table, table, n_table); +        graph_free_routing_table(graph, &table);          return 0;  } | 
