diff options
| author | Sander Vrijders <sander.vrijders@ugent.be> | 2017-05-15 16:25:08 +0000 | 
|---|---|---|
| committer | dimitri staessens <dimitri.staessens@ugent.be> | 2017-05-15 16:25:08 +0000 | 
| commit | 1b3079ce9ad79e9c9b267fde3d09b9c8166ed1e5 (patch) | |
| tree | ea57e4a1e634d3b7e7325b61f6dba36d941e03ae /src/ipcpd/normal | |
| parent | 0fc0f3701ef4f504e71eadcc92a93faf1dd33bf4 (diff) | |
| parent | 5d87cec1757c4e1c23ae778f2814363c1e39b43c (diff) | |
| download | ouroboros-1b3079ce9ad79e9c9b267fde3d09b9c8166ed1e5.tar.gz ouroboros-1b3079ce9ad79e9c9b267fde3d09b9c8166ed1e5.zip | |
Merged in sandervrijders/ouroboros/be-routing-policy (pull request #506)
ipcpd: normal: Make routing a policy
Diffstat (limited to 'src/ipcpd/normal')
| -rw-r--r-- | src/ipcpd/normal/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/ipcpd/normal/dt.c | 9 | ||||
| -rw-r--r-- | src/ipcpd/normal/main.c | 17 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol-routing-ops.h | 38 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/fso.proto (renamed from src/ipcpd/normal/fso.proto) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/graph.c (renamed from src/ipcpd/normal/graph.c) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/graph.h (renamed from src/ipcpd/normal/graph.h) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/link_state.c | 360 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/link_state.h | 43 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/tests/CMakeLists.txt (renamed from src/ipcpd/normal/tests/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/tests/graph_test.c (renamed from src/ipcpd/normal/tests/graph_test.c) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/ribconfig.h | 18 | ||||
| -rw-r--r-- | src/ipcpd/normal/routing.c | 325 | ||||
| -rw-r--r-- | src/ipcpd/normal/routing.h | 8 | 
14 files changed, 490 insertions, 337 deletions
| diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 984ebd3d..336b0e8f 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -15,7 +15,8 @@ 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) +# Add GPB sources of policies last +protobuf_generate_c(FSO_SRCS FSO_HDRS pol/fso.proto)  set(SOURCE_FILES    # Add source files here @@ -27,7 +28,6 @@ set(SOURCE_FILES    enroll.c    fa.c    gam.c -  graph.c    main.c    neighbors.c    pff.c @@ -37,6 +37,8 @@ set(SOURCE_FILES    # Add policies last    pol/complete.c    pol/flat.c +  pol/link_state.c +  pol/graph.c    )  add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} @@ -50,5 +52,4 @@ endif (CMAKE_BUILD_TYPE MATCHES Debug)  install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin) -# Enable once ipcp-normal has tests -add_subdirectory(tests) +add_subdirectory(pol/tests) diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c index 33070fa2..b22fb59c 100644 --- a/src/ipcpd/normal/dt.c +++ b/src/ipcpd/normal/dt.c @@ -143,6 +143,13 @@ int dt_init(void)          int              i;          int              j;          struct conn_info info; +        enum pol_routing pr; + +        if (rib_read(BOOT_PATH "/dt/routing/type", &pr, sizeof(pr)) +            != sizeof(pr)) { +                log_err("Failed to read policy for routing."); +                return -1; +        }          if (dt_pci_init()) {                  log_err("Failed to init shm dt_pci."); @@ -175,7 +182,7 @@ int dt_init(void)                  goto fail_nbs;          } -        if (routing_init(dt.nbs)) { +        if (routing_init(pr, dt.nbs)) {                  log_err("Failed to init routing.");                  goto fail_nbs_notifier;          } diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index f9718041..0b8a26ab 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -88,7 +88,7 @@ static int boot_components(void)          log_dbg("Starting components."); -        if (rib_read(BOOT_PATH "/addr_auth/type", &pa, sizeof(pa)) +        if (rib_read(BOOT_PATH "/dt/addr_auth/type", &pa, sizeof(pa))              != sizeof(pa)) {                  log_err("Failed to read policy for address authority.");                  goto fail_addr_auth; @@ -261,17 +261,17 @@ const struct ros {          {BOOT_PATH "/dt/const", "addr_size"},          {BOOT_PATH "/dt/const", "fd_size"},          {BOOT_PATH "/dt/const", "has_ttl"}, +        {BOOT_PATH "/dt", "addr_auth"}, +        {BOOT_PATH "/dt/addr_auth", "type"}, +        {BOOT_PATH "/dt", "routing"}, +        {BOOT_PATH "/dt/routing", "type"},          /* RIB MGR COMPONENT */          {BOOT_PATH, "rm"}, -          {BOOT_PATH "/rm","gam"},          {BOOT_PATH "/rm/gam", "type"},          {BOOT_PATH "/rm/gam", "cacep"}, -        /* ADDR AUTH COMPONENT */ -        {BOOT_PATH, "addr_auth"}, -        {BOOT_PATH "/addr_auth", "type"},          {NULL, NULL}  }; @@ -327,9 +327,12 @@ static int normal_ipcp_bootstrap(const struct ipcp_config * conf)              rib_write(BOOT_PATH "/rm/gam/type",                        &conf->rm_gam_type,                        sizeof(conf->rm_gam_type)) || -            rib_write(BOOT_PATH "/addr_auth/type", +            rib_write(BOOT_PATH "/dt/addr_auth/type",                        &conf->addr_auth_type, -                      sizeof(conf->addr_auth_type))) { +                      sizeof(conf->addr_auth_type)) || +            rib_write(BOOT_PATH "/dt/routing/type", +                      &conf->routing_type, +                      sizeof(conf->routing_type))) {                  log_err("Failed to write boot info to RIB.");                  return -1;          } diff --git a/src/ipcpd/normal/pol-routing-ops.h b/src/ipcpd/normal/pol-routing-ops.h new file mode 100644 index 00000000..3a60ca6b --- /dev/null +++ b/src/ipcpd/normal/pol-routing-ops.h @@ -0,0 +1,38 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing policy ops + * + *    Dimitri Staessens <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * 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_POL_ROUTING_OPS_H +#define OUROBOROS_IPCPD_NORMAL_POL_ROUTING_OPS_H + +#include "pff.h" + +struct pol_routing_ops { +        int                (* init)(struct nbs * nbs); + +        void               (* fini)(void); + +        struct routing_i * (* routing_i_create)(struct pff * pff); + +        void               (* routing_i_destroy)(struct routing_i * instance); +}; + +#endif /* OUROBOROS_IPCPD_NORMAL_POL_ROUTING_OPS_H */ diff --git a/src/ipcpd/normal/fso.proto b/src/ipcpd/normal/pol/fso.proto index 32b281d6..32b281d6 100644 --- a/src/ipcpd/normal/fso.proto +++ b/src/ipcpd/normal/pol/fso.proto diff --git a/src/ipcpd/normal/graph.c b/src/ipcpd/normal/pol/graph.c index 78ed203d..78ed203d 100644 --- a/src/ipcpd/normal/graph.c +++ b/src/ipcpd/normal/pol/graph.c diff --git a/src/ipcpd/normal/graph.h b/src/ipcpd/normal/pol/graph.h index 44496bc3..44496bc3 100644 --- a/src/ipcpd/normal/graph.h +++ b/src/ipcpd/normal/pol/graph.h diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c new file mode 100644 index 00000000..3e0a63d6 --- /dev/null +++ b/src/ipcpd/normal/pol/link_state.c @@ -0,0 +1,360 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Link state routing policy + * + *    Dimitri Staessens <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * 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 "link-state-routing" + +#include <ouroboros/config.h> +#include <ouroboros/errno.h> +#include <ouroboros/list.h> +#include <ouroboros/logs.h> +#include <ouroboros/rib.h> +#include <ouroboros/rqueue.h> + +#include "ribmgr.h" +#include "ribconfig.h" +#include "graph.h" +#include "neighbors.h" +#include "ipcp.h" +#include "pff.h" + +#include <assert.h> +#include <stdlib.h> +#include <inttypes.h> +#include <string.h> +#include <pthread.h> + +#include "fso.pb-c.h" +typedef Fso fso_t; + +#define BUF_SIZE 256 +#define RECALC_TIME 4 + +struct routing_i { +        struct pff * pff; +        pthread_t    calculator; +}; + +struct { +        struct nbs *       nbs; +        struct nb_notifier nb_notifier; + +        struct graph *     graph; + +        ro_set_t *         set; +        rqueue_t *         queue; +        pthread_t          rib_listener; +} link_state; + +/* Take under neighbors lock */ +static int addr_to_fd(uint64_t addr) +{ +        struct list_head * p = NULL; + +        list_for_each(p, &link_state.nbs->list) { +                struct nb * e = list_entry(p, struct nb, next); +                if (e->conn.conn_info.addr == addr) +                        return e->conn.flow_info.fd; +        } + +        return -1; +} + +static void * calculate_pff(void * o) +{ +        struct routing_i *      instance; +        struct routing_table ** table; +        ssize_t                 n_table; +        int                     i; +        int                     fd; + +        instance = (struct routing_i *) o; + +        while (true) { +                table = NULL; +                n_table = graph_routing_table(link_state.graph, +                                              ipcpi.dt_addr, &table); +                if (n_table < 0) { +                        sleep(RECALC_TIME); +                        continue; +                } + +                pthread_mutex_lock(&link_state.nbs->list_lock); +                pff_lock(instance->pff); + +                pff_flush(instance->pff); + +                for (i = 0; i < n_table; i++) { +                        fd = addr_to_fd(table[i]->nhop); +                        if (fd == -1) +                                continue; + +                        pff_add(instance->pff, table[i]->dst, fd); +                } + +                pff_unlock(instance->pff); +                pthread_mutex_unlock(&link_state.nbs->list_lock); + +                freepp(struct routing_table, table, n_table); +                sleep(RECALC_TIME); +        } + +        return (void *) 0; +} + +static int link_state_neighbor_event(enum nb_event event, +                                     struct conn   conn) +{ +        char      path[RIB_MAX_PATH_LEN + 1]; +        char      fso_name[RIB_MAX_PATH_LEN + 1]; +        fso_t     fso = FSO__INIT; +        size_t    len; +        uint8_t * data; + +        /* Only announce the flow if our address is bigger */ +        if (ipcpi.dt_addr < conn.conn_info.addr) +                return 0; + +        path[0] = '\0'; +        sprintf(fso_name, "%" PRIu64 "-%" PRIu64, +                ipcpi.dt_addr, conn.conn_info.addr); +        rib_path_append(rib_path_append(path, ROUTING_NAME), fso_name); + +        switch (event) { +        case NEIGHBOR_ADDED: +                fso.s_addr = ipcpi.dt_addr; +                fso.d_addr = conn.conn_info.addr; + +                len = fso__get_packed_size(&fso); +                if (len == 0) +                        return -1; + +                data = malloc(len); +                if (data == NULL) +                        return -1; + +                fso__pack(&fso, data); + +                if (rib_add(ROUTING_PATH, fso_name)) { +                        log_err("Failed to add FSO."); +                        free(data); +                        return -1; +                } + +                if (rib_put(path, data, len)) { +                        log_err("Failed to put FSO in RIB."); +                        rib_del(path); +                        free(data); +                        return -1; +                } + +                log_dbg("Added %s to RIB.", path); + +                break; +        case NEIGHBOR_REMOVED: +                if (rib_del(path)) { +                        log_err("Failed to remove FSO."); +                        return -1; +                } + +                log_dbg("Removed %s from RIB.", path); + +                break; +        case NEIGHBOR_QOS_CHANGE: +                log_info("Not currently supported."); +                break; +        default: +                log_info("Unsupported event for routing."); +                break; +        } + +        return 0; +} + +static int read_fso(char *  path, +                    int32_t flag) +{ +        ssize_t   len; +        uint8_t   ro[BUF_SIZE]; +        fso_t *   fso; +        qosspec_t qs; + +        memset(&qs, 0, sizeof(qs)); + +        len = rib_read(path, ro, BUF_SIZE); +        if (len < 0) { +                log_err("Failed to read FSO."); +                return -1; +        } + +        fso = fso__unpack(NULL, len, ro); +        if (fso == NULL) { +                log_err("Failed to unpack."); +                return -1; +        } + +        if (flag & RO_MODIFY) { +                if (graph_update_edge(link_state.graph, +                                      fso->s_addr, fso->d_addr, qs)) { +                        fso__free_unpacked(fso, NULL); +                        return -1; +                } +        } else if (flag & RO_DELETE) { +                if (graph_del_edge(link_state.graph, fso->s_addr, fso->d_addr)) { +                        fso__free_unpacked(fso, NULL); +                        return -1; +                } +        } + +        fso__free_unpacked(fso, NULL); + +        return 0; +} + +static void * rib_listener(void * o) +{ +        int32_t flag; +        char    path[RIB_MAX_PATH_LEN + 1]; +        char ** children; +        ssize_t len; +        int     i; + +        (void) o; + +        if (ro_set_add(link_state.set, ROUTING_PATH, RO_MODIFY | RO_DELETE)) { +                log_err("Failed to add to RO set"); +                return (void * ) -1; +        } + +        len = rib_children(ROUTING_PATH, &children); +        if (len < 0) { +                log_err("Failed to retrieve children."); +                return (void *) -1; +        } + +        for (i = 0; i < len; i++) { +                if (read_fso(children[i], RO_CREATE)) { +                        log_err("Failed to parse FSO."); +                        continue; +                } +        } + +        while (rib_event_wait(link_state.set, link_state.queue, NULL) == 0) { +                path[0] = '\0'; +                flag = rqueue_next(link_state.queue, path); +                if (flag < 0) +                        continue; + +                if (read_fso(path, flag)) { +                        log_err("Failed to parse FSO."); +                        continue; +                } +        } + +        return (void *) 0; +} + +struct routing_i * link_state_routing_i_create(struct pff * pff) +{ +        struct routing_i * tmp; + +        assert(pff); + +        tmp = malloc(sizeof(*tmp)); +        if (tmp == NULL) +                return NULL; + +        tmp->pff = pff; + +        pthread_create(&tmp->calculator, NULL, calculate_pff, (void *) tmp); + +        return tmp; +} + +void link_state_routing_i_destroy(struct routing_i * instance) +{ +        assert(instance); + +        pthread_cancel(instance->calculator); + +        pthread_join(instance->calculator, NULL); + +        free(instance); +} + +int link_state_init(struct nbs * nbs) +{ +        link_state.graph = graph_create(); +        if (link_state.graph == NULL) +                return -1; + +        if (rib_add(RIB_ROOT, ROUTING_NAME)) { +                graph_destroy(link_state.graph); +                return -1; +        } + +        link_state.nbs = nbs; + +        link_state.nb_notifier.notify_call = link_state_neighbor_event; +        if (nbs_reg_notifier(link_state.nbs, &link_state.nb_notifier)) { +                graph_destroy(link_state.graph); +                rib_del(ROUTING_PATH); +                return -1; +        } + +        link_state.set = ro_set_create(); +        if (link_state.set == NULL) { +                nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier); +                graph_destroy(link_state.graph); +                rib_del(ROUTING_PATH); +                return -1; +        } + +        link_state.queue = rqueue_create(); +        if (link_state.queue == NULL) { +                ro_set_destroy(link_state.set); +                nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier); +                graph_destroy(link_state.graph); +                rib_del(ROUTING_PATH); +                return -1; +        } + +        pthread_create(&link_state.rib_listener, NULL, rib_listener, NULL); + +        return 0; +} + +void link_state_fini(void) +{ +        pthread_cancel(link_state.rib_listener); + +        pthread_join(link_state.rib_listener, NULL); + +        rqueue_destroy(link_state.queue); + +        ro_set_destroy(link_state.set); + +        graph_destroy(link_state.graph); + +        rib_del(ROUTING_PATH); + +        nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier); +} diff --git a/src/ipcpd/normal/pol/link_state.h b/src/ipcpd/normal/pol/link_state.h new file mode 100644 index 00000000..e78d0543 --- /dev/null +++ b/src/ipcpd/normal/pol/link_state.h @@ -0,0 +1,43 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Link state routing policy + * + *    Dimitri Staessens <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * 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_POL_LINK_STATE_H +#define OUROBOROS_IPCPD_NORMAL_POL_LINK_STATE_H + +#include "pol-routing-ops.h" + +int                link_state_init(struct nbs * nbs); + +void               link_state_fini(void); + +struct routing_i * link_state_routing_i_create(struct pff * pff); + +void               link_state_routing_i_destroy(struct routing_i * instance); + +struct pol_routing_ops link_state_ops = { +        .init              = link_state_init, +        .fini              = link_state_fini, +        .routing_i_create  = link_state_routing_i_create, +        .routing_i_destroy = link_state_routing_i_destroy +}; + +#endif /* OUROBOROS_IPCPD_NORMAL_POL_LINK_STATE_H */ diff --git a/src/ipcpd/normal/tests/CMakeLists.txt b/src/ipcpd/normal/pol/tests/CMakeLists.txt index 55ca425a..55ca425a 100644 --- a/src/ipcpd/normal/tests/CMakeLists.txt +++ b/src/ipcpd/normal/pol/tests/CMakeLists.txt diff --git a/src/ipcpd/normal/tests/graph_test.c b/src/ipcpd/normal/pol/tests/graph_test.c index 3d433e34..3d433e34 100644 --- a/src/ipcpd/normal/tests/graph_test.c +++ b/src/ipcpd/normal/pol/tests/graph_test.c diff --git a/src/ipcpd/normal/ribconfig.h b/src/ipcpd/normal/ribconfig.h index 2f5daf72..31c79fbe 100644 --- a/src/ipcpd/normal/ribconfig.h +++ b/src/ipcpd/normal/ribconfig.h @@ -26,14 +26,14 @@  /* RIB configuration for normal */  #define RIB_MAX_PATH_LEN 256 -#define DLR              "/" -#define BOOT_NAME        "boot" -#define MEMBERS_NAME     "members" -#define DIR_NAME         "directory" -#define ROUTING_NAME     "fsdb" -#define DIR_PATH         DLR DIR_NAME -#define BOOT_PATH        DLR BOOT_NAME -#define MEMBERS_PATH     DLR MEMBERS_NAME -#define ROUTING_PATH     DLR ROUTING_NAME +#define DLR          "/" +#define BOOT_NAME    "boot" +#define MEMBERS_NAME "members" +#define DIR_NAME     "directory" +#define ROUTING_NAME "fsdb" +#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/routing.c b/src/ipcpd/normal/routing.c index cc6cdca8..e1459c15 100644 --- a/src/ipcpd/normal/routing.c +++ b/src/ipcpd/normal/routing.c @@ -23,338 +23,41 @@  #define OUROBOROS_PREFIX "routing"  #include <ouroboros/config.h> -#include <ouroboros/errno.h> -#include <ouroboros/list.h>  #include <ouroboros/logs.h> -#include <ouroboros/rib.h> -#include <ouroboros/rqueue.h> -#include <ouroboros/utils.h>  #include "routing.h" -#include "ribmgr.h" -#include "ribconfig.h" -#include "ipcp.h" -#include "graph.h" -#include "neighbors.h" - -#include <assert.h> -#include <stdlib.h> -#include <inttypes.h> -#include <string.h> - -#include "fso.pb-c.h" -typedef Fso fso_t; - -#define BUF_SIZE 256 -#define RECALC_TIME 4 - -struct routing_i { -        struct pff * pff; -        pthread_t    calculator; -}; +#include "pol/link_state.h"  struct { -        struct nbs *       nbs; -        struct nb_notifier nb_notifier; - -        struct graph *     graph; - -        ro_set_t *         set; -        rqueue_t *         queue; -        pthread_t          rib_listener; +        struct pol_routing_ops * ops;  } routing; -/* Take under neighbors lock */ -static int addr_to_fd(uint64_t addr) -{ -        struct list_head * p = NULL; - -        list_for_each(p, &routing.nbs->list) { -                struct nb * e = list_entry(p, struct nb, next); -                if (e->conn.conn_info.addr == addr) -                        return e->conn.flow_info.fd; -        } - -        return -1; -} - -static void * calculate_pff(void * o) -{ -        struct routing_i *      instance; -        struct routing_table ** table; -        ssize_t                 n_table; -        int                     i; -        int                     fd; - -        instance = (struct routing_i *) o; - -        while (true) { -                table = NULL; -                n_table = graph_routing_table(routing.graph, -                                              ipcpi.dt_addr, &table); -                if (n_table < 0) { -                        sleep(RECALC_TIME); -                        continue; -                } - -                pthread_mutex_lock(&routing.nbs->list_lock); -                pff_lock(instance->pff); - -                pff_flush(instance->pff); - -                for (i = 0; i < n_table; i++) { -                        fd = addr_to_fd(table[i]->nhop); -                        if (fd == -1) -                                continue; - -                        pff_add(instance->pff, table[i]->dst, fd); -                } - -                pff_unlock(instance->pff); -                pthread_mutex_unlock(&routing.nbs->list_lock); - -                freepp(struct routing_table, table, n_table); -                sleep(RECALC_TIME); -        } - -        return (void *) 0; -} - -struct routing_i * routing_i_create(struct pff * pff) -{ -        struct routing_i * tmp; - -        assert(pff); - -        tmp = malloc(sizeof(*tmp)); -        if (tmp == NULL) -                return NULL; - -        tmp->pff = pff; - -        pthread_create(&tmp->calculator, NULL, calculate_pff, (void *) tmp); - -        return tmp; -} - -void routing_i_destroy(struct routing_i * instance) -{ -        assert(instance); - -        pthread_cancel(instance->calculator); - -        pthread_join(instance->calculator, NULL); - -        free(instance); -} - -static int routing_neighbor_event(enum nb_event event, -                                  struct conn   conn) +int routing_init(enum pol_routing pr, +                 struct nbs *     nbs)  { -        char      path[RIB_MAX_PATH_LEN + 1]; -        char      fso_name[RIB_MAX_PATH_LEN + 1]; -        fso_t     fso = FSO__INIT; -        size_t    len; -        uint8_t * data; - -        /* Only announce the flow if our address is bigger */ -        if (ipcpi.dt_addr < conn.conn_info.addr) -                return 0; - -        path[0] = '\0'; -        sprintf(fso_name, "%" PRIu64 "-%" PRIu64, -                ipcpi.dt_addr, conn.conn_info.addr); -        rib_path_append(rib_path_append(path, ROUTING_NAME), fso_name); - -        switch (event) { -        case NEIGHBOR_ADDED: -                fso.s_addr = ipcpi.dt_addr; -                fso.d_addr = conn.conn_info.addr; - -                len = fso__get_packed_size(&fso); -                if (len == 0) -                        return -1; - -                data = malloc(len); -                if (data == NULL) -                        return -1; - -                fso__pack(&fso, data); - -                if (rib_add(ROUTING_PATH, fso_name)) { -                        log_err("Failed to add FSO."); -                        free(data); -                        return -1; -                } - -                if (rib_put(path, data, len)) { -                        log_err("Failed to put FSO in RIB."); -                        rib_del(path); -                        free(data); -                        return -1; -                } - -                log_dbg("Added %s to RIB.", path); - -                break; -        case NEIGHBOR_REMOVED: -                if (rib_del(path)) { -                        log_err("Failed to remove FSO."); -                        return -1; -                } - -                log_dbg("Removed %s from RIB.", path); - -                break; -        case NEIGHBOR_QOS_CHANGE: -                log_info("Not currently supported."); +        switch (pr) { +        case LINK_STATE: +                routing.ops = &link_state_ops;                  break;          default: -                log_info("Unsupported event for routing."); -                break; -        } - -        return 0; -} - -static int read_fso(char *  path, -                    int32_t flag) -{ -        ssize_t   len; -        uint8_t   ro[BUF_SIZE]; -        fso_t *   fso; -        qosspec_t qs; - -        memset(&qs, 0, sizeof(qs)); - -        len = rib_read(path, ro, BUF_SIZE); -        if (len < 0) { -                log_err("Failed to read FSO."); -                return -1; -        } - -        fso = fso__unpack(NULL, len, ro); -        if (fso == NULL) { -                log_err("Failed to unpack."); +                log_err("Unknown routing type.");                  return -1;          } -        if (flag & RO_MODIFY) { -                if (graph_update_edge(routing.graph, -                                      fso->s_addr, fso->d_addr, qs)) { -                        fso__free_unpacked(fso, NULL); -                        return -1; -                } -        } else if (flag & RO_DELETE) { -                if (graph_del_edge(routing.graph, fso->s_addr, fso->d_addr)) { -                        fso__free_unpacked(fso, NULL); -                        return -1; -                } -        } - -        fso__free_unpacked(fso, NULL); - -        return 0; +        return routing.ops->init(nbs);  } -static void * rib_listener(void * o) +struct routing_i * routing_i_create(struct pff * pff)  { -        int32_t flag; -        char    path[RIB_MAX_PATH_LEN + 1]; -        char ** children; -        ssize_t len; -        int     i; - -        (void) o; - -        if (ro_set_add(routing.set, ROUTING_PATH, RO_MODIFY | RO_DELETE)) { -                log_err("Failed to add to RO set"); -                return (void * ) -1; -        } - -        len = rib_children(ROUTING_PATH, &children); -        if (len < 0) { -                log_err("Failed to retrieve children."); -                return (void *) -1; -        } - -        for (i = 0; i < len; i++) { -                if (read_fso(children[i], RO_CREATE)) { -                        log_err("Failed to parse FSO."); -                        continue; -                } -        } - -        while (rib_event_wait(routing.set, routing.queue, NULL) == 0) { -                path[0] = '\0'; -                flag = rqueue_next(routing.queue, path); -                if (flag < 0) -                        continue; - -                if (read_fso(path, flag)) { -                        log_err("Failed to parse FSO."); -                        continue; -                } -        } - -        return (void *) 0; +        return routing.ops->routing_i_create(pff);  } -int routing_init(struct nbs * nbs) +void routing_i_destroy(struct routing_i * instance)  { -        routing.graph = graph_create(); -        if (routing.graph == NULL) -                return -1; - -        if (rib_add(RIB_ROOT, ROUTING_NAME)) { -                graph_destroy(routing.graph); -                return -1; -        } - -        routing.nbs = nbs; - -        routing.nb_notifier.notify_call = routing_neighbor_event; -        if (nbs_reg_notifier(routing.nbs, &routing.nb_notifier)) { -                graph_destroy(routing.graph); -                rib_del(ROUTING_PATH); -                return -1; -        } - -        routing.set = ro_set_create(); -        if (routing.set == NULL) { -                nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); -                graph_destroy(routing.graph); -                rib_del(ROUTING_PATH); -                return -1; -        } - -        routing.queue = rqueue_create(); -        if (routing.queue == NULL) { -                ro_set_destroy(routing.set); -                nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); -                graph_destroy(routing.graph); -                rib_del(ROUTING_PATH); -                return -1; -        } - -        pthread_create(&routing.rib_listener, NULL, rib_listener, NULL); - -        return 0; +        return routing.ops->routing_i_destroy(instance);  }  void routing_fini(void)  { -        pthread_cancel(routing.rib_listener); - -        pthread_join(routing.rib_listener, NULL); - -        rqueue_destroy(routing.queue); - -        ro_set_destroy(routing.set); - -        graph_destroy(routing.graph); - -        rib_del(ROUTING_PATH); - -        nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); +        routing.ops->fini();  } diff --git a/src/ipcpd/normal/routing.h b/src/ipcpd/normal/routing.h index 0794ef28..7e47a425 100644 --- a/src/ipcpd/normal/routing.h +++ b/src/ipcpd/normal/routing.h @@ -23,6 +23,7 @@  #ifndef OUROBOROS_IPCPD_NORMAL_ROUTING_H  #define OUROBOROS_IPCPD_NORMAL_ROUTING_H +#include <ouroboros/ipcp.h>  #include <ouroboros/qos.h>  #include "pff.h" @@ -30,11 +31,8 @@  #include <stdint.h> -/* - * Routing will take a type in the future, - * to allow different policies. - */ -int                routing_init(struct nbs * nbs); +int                routing_init(enum pol_routing pr, +                                struct nbs *     nbs);  void               routing_fini(void); | 
