diff options
Diffstat (limited to 'src/ipcpd')
58 files changed, 2174 insertions, 1180 deletions
| 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/ipcp.c b/src/ipcpd/ipcp.c index 19b3a721..8646121a 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -3,7 +3,8 @@   *   * IPC process main loop   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -191,7 +192,6 @@ static void * ipcp_main_loop(void * o)                          ret_msg.result =                                  ipcpi.ops->ipcp_flow_alloc(fd,                                                             msg->dst_name, -                                                           msg->src_ae_name,                                                             msg->qoscube);                          break;                  case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index de7d72b0..a64ab65c 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -3,7 +3,8 @@   *   * IPC process structure   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -50,7 +51,6 @@ struct ipcp_ops {          int   (* ipcp_flow_alloc)(int       fd,                                    char *    dst_ap_name, -                                  char *    src_ae_name,                                    qoscube_t qos);          int   (* ipcp_flow_alloc_resp)(int fd, @@ -66,7 +66,7 @@ struct ipcp {          enum ipcp_type     type;          char *             dif_name; -        uint64_t           address; +        uint64_t           dt_addr;          struct ipcp_ops *  ops;          int                irmd_fd; 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/local/main.c b/src/ipcpd/local/main.c index 8d770c94..f025afa2 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -3,7 +3,8 @@   *   * Local IPC process   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -220,7 +221,6 @@ static int ipcp_local_name_query(char * name)  static int ipcp_local_flow_alloc(int       fd,                                   char *    dst_name, -                                 char *    src_ae_name,                                   qoscube_t cube)  {          int out_fd = -1; @@ -228,7 +228,6 @@ static int ipcp_local_flow_alloc(int       fd,          log_dbg("Allocating flow to %s on fd %d.", dst_name, fd);          assert(dst_name); -        assert(src_ae_name);          pthread_rwlock_rdlock(&ipcpi.state_lock); @@ -240,7 +239,7 @@ static int ipcp_local_flow_alloc(int       fd,          pthread_rwlock_wrlock(&local_data.lock); -        out_fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name, cube); +        out_fd = ipcp_flow_req_arr(getpid(), dst_name, cube);          local_data.in_out[fd]  = out_fd;          local_data.in_out[out_fd] = fd; diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 7e10cc0d..06292c50 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -15,32 +15,36 @@ 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    addr_auth.c -  cdap_flow.c +  connmgr.c    dir.c    enroll.c    fmgr.c    frct.c    gam.c +  graph.c    main.c +  neighbors.c    pff.c    ribmgr.c +  routing.c    shm_pci.c    # Add policies last    pol/complete.c    pol/flat.c    ) -add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} -  ${FLOW_ALLOC_SRCS}) -target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros) +add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} +  ${FLOW_ALLOC_SRCS} ${FSO_SRCS}) +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/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index 8469e95e..5b3c6170 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -3,8 +3,8 @@   *   * Address authority   * - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/addr_auth.h b/src/ipcpd/normal/addr_auth.h index b389fa90..fbe7d790 100644 --- a/src/ipcpd/normal/addr_auth.h +++ b/src/ipcpd/normal/addr_auth.h @@ -3,8 +3,8 @@   *   * Address authority   * - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/ae.h b/src/ipcpd/normal/ae.h index 882625dd..aafef625 100644 --- a/src/ipcpd/normal/ae.h +++ b/src/ipcpd/normal/ae.h @@ -3,8 +3,8 @@   *   * Application Entities for the normal IPC process   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/cdap_flow.c b/src/ipcpd/normal/cdap_flow.c deleted file mode 100644 index a94627c2..00000000 --- a/src/ipcpd/normal/cdap_flow.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Normal IPC Process - Authenticated CDAP Flow Allocator - * - *    Sander Vrijders   <sander.vrijders@ugent.be> - *    Dimitri Staessens <dimitri.staessens@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 "cdap-flow" - -#include <ouroboros/config.h> -#include <ouroboros/dev.h> -#include <ouroboros/logs.h> - -#include "cdap_flow.h" - -#include <stdlib.h> -#include <assert.h> - -static void cdap_flow_destroy(struct cdap_flow * flow) -{ -        assert(flow); - -        if (flow->ci != NULL) -                cdap_destroy(flow->ci); -        if (flow->info != NULL) { -                cacep_info_fini(flow->info); -                free(flow->info); -        } - -        free(flow); -} - -struct cdap_flow * cdap_flow_arr(int                       fd, -                                 int                       resp, -                                 enum pol_cacep            pc, -                                 const struct cacep_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; -        } - -        flow->fd = fd; -        flow->ci = NULL; - -        flow->info = cacep_auth_wait(fd, pc, info); -        if (flow->info == NULL) { -                log_err("Other side failed to authenticate."); -                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, -                                   const char *              ae_name, -                                   qosspec_t *               qs, -                                   enum pol_cacep            pc, -                                   const struct cacep_info * info) -{ -        struct cdap_flow *  flow; -        int                 fd; - -        log_dbg("Allocating flow to %s.", dst_name); - -        if (dst_name == NULL || ae_name == NULL) { -                log_err("Not enough info to establish flow."); -                return NULL; -        } - -        fd = flow_alloc(dst_name, ae_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; -        } - -        flow->fd = fd; -        flow->ci = NULL; - -        flow->info = cacep_auth(fd, pc, info); -        if (flow->info == NULL) { -                log_err("Failed to authenticate."); -                cdap_flow_dealloc(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 c5ca2ab4..00000000 --- a/src/ipcpd/normal/cdap_flow.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Normal IPC Process - Authenticated CDAP Flow Allocator - * - *    Sander Vrijders   <sander.vrijders@ugent.be> - *    Dimitri Staessens <dimitri.staessens@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_CDAP_FLOW_H -#define OUROBOROS_IPCPD_NORMAL_CDAP_FLOW_H - -#include <ouroboros/cacep.h> -#include <ouroboros/cdap.h> -#include <ouroboros/qos.h> - -struct cdap_flow { -        int                 fd; -        struct cdap *       ci; -        struct cacep_info * info; -}; - -struct cdap_flow * cdap_flow_arr(int                       fd, -                                 int                       resp, -                                 enum pol_cacep            pc, -                                 const struct cacep_info * info); - -struct cdap_flow * cdap_flow_alloc(const char *              dst_name, -                                   const char *              ae_name, -                                   qosspec_t *               qs, -                                   enum pol_cacep            pc, -                                   const struct cacep_info * info); - -void               cdap_flow_dealloc(struct cdap_flow * flow); - -#endif /* OUROBOROS_IPCPD_NORMAL_CDAP_FLOW_H */ diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c new file mode 100644 index 00000000..b97d2b23 --- /dev/null +++ b/src/ipcpd/normal/connmgr.c @@ -0,0 +1,358 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Handles AE connections + * + *    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 "normal-ipcp" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/dev.h> +#include <ouroboros/cacep.h> +#include <ouroboros/cdap.h> +#include <ouroboros/errno.h> + +#include "ae.h" +#include "connmgr.h" +#include "enroll.h" +#include "fmgr.h" +#include "frct.h" +#include "ipcp.h" +#include "ribmgr.h" + +#include <pthread.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +struct ae_conn { +        struct list_head next; +        struct conn      conn; +}; + +struct ae { +        struct list_head next; +        struct conn_info info; + +        struct list_head conn_list; +        pthread_cond_t   conn_cond; +        pthread_mutex_t  conn_lock; +}; + +struct { +        pthread_t        acceptor; + +        struct list_head aes; +        pthread_mutex_t  aes_lock; +} connmgr; + +static int add_ae_conn(struct ae *        ae, +                       int                fd, +                       qosspec_t          qs, +                       struct conn_info * rcv_info) +{ +        struct ae_conn * ae_conn = NULL; + +        ae_conn = malloc(sizeof(*ae_conn)); +        if (ae_conn == NULL) { +                log_err("Not enough memory."); +                return -1; +        } + +        ae_conn->conn.conn_info = *rcv_info; +        ae_conn->conn.flow_info.fd = fd; +        ae_conn->conn.flow_info.qs = qs; + +        list_head_init(&ae_conn->next); + +        pthread_mutex_lock(&ae->conn_lock); +        list_add(&ae_conn->next, &ae->conn_list); +        pthread_cond_signal(&ae->conn_cond); +        pthread_mutex_unlock(&ae->conn_lock); + +        return 0; +} + +static struct ae * find_ae_by_name(char * name) +{ +        struct list_head * p = NULL; + +        list_for_each(p, &connmgr.aes) { +                struct ae * ae = list_entry(p, struct ae, next); +                if (strcmp(ae->info.ae_name, name) == 0) +                        return ae; +        } + +        return NULL; +} + +static void * flow_acceptor(void * o) +{ +        int               fd; +        qosspec_t         qs; +        struct conn_info  rcv_info; +        struct conn_info  fail_info; +        struct ae *       ae = NULL; + +        (void) o; + +        memset(&fail_info, 0, sizeof(fail_info)); + +        while (true) { +                pthread_rwlock_rdlock(&ipcpi.state_lock); + +                if (ipcp_get_state() != IPCP_OPERATIONAL) { +                        pthread_rwlock_unlock(&ipcpi.state_lock); +                        log_info("Shutting down flow acceptor."); +                        return 0; +                } + +                pthread_rwlock_unlock(&ipcpi.state_lock); + +                fd = flow_accept(&qs); +                if (fd < 0) { +                        if (fd != -EIRMD) +                                log_warn("Flow accept failed: %d", fd); +                        continue; +                } + +                if (flow_alloc_resp(fd, 0)) { +                        log_err("Failed to respond to flow alloc request."); +                        continue; +                } + +                if (cacep_rcv(fd, &rcv_info)) { +                        log_err("Error establishing application connection."); +                        flow_dealloc(fd); +                        continue; +                } + +                pthread_mutex_lock(&connmgr.aes_lock); +                ae = find_ae_by_name(rcv_info.ae_name); +                pthread_mutex_unlock(&connmgr.aes_lock); + +                if (ae != NULL) { +                        if (cacep_snd(fd, &ae->info)) { +                                log_err("Failed to respond to req."); +                                flow_dealloc(fd); +                                continue; +                        } + +                        if (add_ae_conn(ae, fd, qs, &rcv_info)) { +                                log_err("Failed to add ae conn."); +                                flow_dealloc(fd); +                                continue; +                        } +                } else { +                        cacep_snd(fd, &fail_info); +                        flow_dealloc(fd); +                } +        } + +        return (void *) 0; +} + +int connmgr_init(void) +{ +        list_head_init(&connmgr.aes); + +        if (pthread_mutex_init(&connmgr.aes_lock, NULL)) +                return -1; + +        return 0; +} + +int connmgr_start(void) +{ +        pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL); + +        return 0; +} + +void connmgr_stop(void) +{ +        pthread_cancel(connmgr.acceptor); +        pthread_join(connmgr.acceptor, NULL); +} + +static void destroy_ae(struct ae * ae) +{ +        struct list_head * p = NULL; +        struct list_head * h = NULL; + +        pthread_mutex_lock(&ae->conn_lock); + +        list_for_each_safe(p, h, &ae->conn_list) { +                struct ae_conn * e = list_entry(p, struct ae_conn, next); +                list_del(&e->next); +                free(e); +        } + +        pthread_mutex_unlock(&ae->conn_lock); + +        pthread_cond_destroy(&ae->conn_cond); +        pthread_mutex_destroy(&ae->conn_lock); + +        free(ae); +} + +void connmgr_fini(void) +{ +        struct list_head * p = NULL; +        struct list_head * n = NULL; + +        pthread_mutex_lock(&connmgr.aes_lock); + +        list_for_each_safe(p, n, &connmgr.aes) { +                struct ae * e = list_entry(p, struct ae, next); +                list_del(&e->next); +                destroy_ae(e); +        } + +        pthread_mutex_unlock(&connmgr.aes_lock); + +        pthread_mutex_destroy(&connmgr.aes_lock); +} + +struct ae * connmgr_ae_create(struct conn_info info) +{ +        struct ae * ae; + +        ae = malloc(sizeof(*ae)); +        if (ae == NULL) +                return NULL; + +        list_head_init(&ae->next); +        list_head_init(&ae->conn_list); + +        ae->info = info; + +        if (pthread_mutex_init(&ae->conn_lock, NULL)) { +                free(ae); +                return NULL; +        } + +        if (pthread_cond_init(&ae->conn_cond, NULL)) { +                pthread_mutex_destroy(&ae->conn_lock); +                free(ae); +                return NULL; +        } + +        pthread_mutex_lock(&connmgr.aes_lock); +        list_add(&ae->next, &connmgr.aes); +        pthread_mutex_unlock(&connmgr.aes_lock); + +        return ae; +} + +void connmgr_ae_destroy(struct ae * ae) +{ +        assert(ae); + +        pthread_mutex_lock(&connmgr.aes_lock); + +        list_del(&ae->next); + +        destroy_ae(ae); + +        pthread_mutex_unlock(&connmgr.aes_lock); +} + +int connmgr_alloc(struct ae *   ae, +                  char *        dst_name, +                  qosspec_t *   qs, +                  struct conn * conn) +{ +        assert(ae); +        assert(dst_name); +        assert(conn); + +        memset(&conn->conn_info, 0, sizeof(conn->conn_info)); + +        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; +        } + +        if (qs != NULL) +                conn->flow_info.qs = *qs; +        else +                memset(&conn->flow_info.qs, 0, sizeof(conn->flow_info.qs)); + +        if (flow_alloc_res(conn->flow_info.fd)) { +                log_err("Flow allocation to %s failed.", dst_name); +                flow_dealloc(conn->flow_info.fd); +                return -1; +        } + +        if (cacep_snd(conn->flow_info.fd, &ae->info)) { +                log_err("Failed to create application connection."); +                flow_dealloc(conn->flow_info.fd); +                return -1; +        } + +        if (cacep_rcv(conn->flow_info.fd, &conn->conn_info)) { +                log_err("Failed to connect to application."); +                flow_dealloc(conn->flow_info.fd); +                return -1; +        } + +        if (strcmp(ae->info.protocol, conn->conn_info.protocol) || +            ae->info.pref_version != conn->conn_info.pref_version || +            ae->info.pref_syntax != conn->conn_info.pref_syntax) { +                flow_dealloc(conn->flow_info.fd); +                return -1; +        } + +        return 0; +} + +int connmgr_wait(struct ae *   ae, +                 struct conn * conn) +{ +        struct ae_conn * ae_conn; + +        assert(ae); +        assert(conn); + +        pthread_mutex_lock(&ae->conn_lock); + +        pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, +                             (void *) &ae->conn_lock); + +        while (list_is_empty(&ae->conn_list)) +                pthread_cond_wait(&ae->conn_cond, &ae->conn_lock); + +        ae_conn = list_first_entry((&ae->conn_list), struct ae_conn, next); +        if (ae_conn == NULL) { +                pthread_mutex_unlock(&ae->conn_lock); +                return -1; +        } + +        *conn = ae_conn->conn; + +        list_del(&ae_conn->next); +        free(ae_conn); + +        pthread_cleanup_pop(true); + +        return 0; +} diff --git a/src/ipcpd/normal/connmgr.h b/src/ipcpd/normal/connmgr.h new file mode 100644 index 00000000..c0356f6d --- /dev/null +++ b/src/ipcpd/normal/connmgr.h @@ -0,0 +1,57 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Handles the different AP connections + * + *    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_CONNMGR_H +#define OUROBOROS_IPCPD_NORMAL_CONNMGR_H + +#include <ouroboros/cacep.h> +#include <ouroboros/qos.h> + +struct conn { +        struct conn_info conn_info; +        struct flow_info { +                int              fd; +                qosspec_t        qs; +        } flow_info; +}; + +int         connmgr_init(void); + +void        connmgr_fini(void); + +int         connmgr_start(void); + +void        connmgr_stop(void); + +struct ae * connmgr_ae_create(struct conn_info info); + +void        connmgr_ae_destroy(struct ae * ae); + +int         connmgr_alloc(struct ae *   ae, +                          char *        dst_name, +                          qosspec_t *   qs, +                          struct conn * conn); + +int         connmgr_wait(struct ae *   ae, +                         struct conn * conn); + +#endif /* OUROBOROS_IPCPD_NORMAL_CONNMGR_H */ diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c index 55d6e3f6..ae9793c6 100644 --- a/src/ipcpd/normal/dir.c +++ b/src/ipcpd/normal/dir.c @@ -3,8 +3,8 @@   *   * DIF directory   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/dir.h b/src/ipcpd/normal/dir.h index 925fc823..04e722f3 100644 --- a/src/ipcpd/normal/dir.h +++ b/src/ipcpd/normal/dir.h @@ -3,7 +3,8 @@   *   * DIF directory   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/dt_const.h b/src/ipcpd/normal/dt_const.h index c94e9395..327f51b8 100644 --- a/src/ipcpd/normal/dt_const.h +++ b/src/ipcpd/normal/dt_const.h @@ -3,8 +3,8 @@   *   * Data Transfer Constants for the IPCP   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c index ce6768fb..7e15be11 100644 --- a/src/ipcpd/normal/enroll.c +++ b/src/ipcpd/normal/enroll.c @@ -3,7 +3,8 @@   *   * Enrollment Task   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -22,6 +23,8 @@  #include <ouroboros/config.h>  #include <ouroboros/endian.h> +#include <ouroboros/errno.h> +#include <ouroboros/cdap.h>  #include <ouroboros/time_utils.h>  #include <ouroboros/dev.h>  #include <ouroboros/logs.h> @@ -29,29 +32,35 @@  #include <ouroboros/errno.h>  #include "ae.h" -#include "cdap_flow.h" +#include "connmgr.h"  #include "ribconfig.h"  #include <assert.h>  #include <stdlib.h>  #include <string.h> +#include <pthread.h>  /* 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 cacep_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,105 +70,105 @@ int enroll_handle(int fd)          char * members_ro = MEMBERS_PATH;          char * dif_ro     = DIF_PATH; -        cacep_info_init(&info); - -        info.proto.protocol = strdup(CDAP_PROTO); -        if (info.proto.protocol == NULL) { -                cacep_info_fini(&info); -                return -ENOMEM; -        } +        (void) o; -        info.proto.pref_version = 1; -        info.proto.pref_syntax  = PROTO_GPB; - -        flow = cdap_flow_arr(fd, 0, ANONYMOUS_AUTH, &info); -        if (flow == NULL) { -                log_err("Failed to auth enrollment request."); -                cacep_info_fini(&info); -                flow_dealloc(fd); -                return -1; -        } - -        cacep_info_fini(&info); - -        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."); +        while (true) { +                cdap = cdap_create(); +                if (cdap == NULL) { +                        log_err("Failed to instantiate CDAP."); +                        continue;                  } -                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; +                if (connmgr_wait(enroll.ae, &conn)) { +                        log_err("Failed to get next connection."); +                        cdap_destroy(cdap); +                        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); +                if (cdap_add_flow(cdap, conn.flow_info.fd)) { +                        log_warn("Failed to add flow to CDAP."); +                        cdap_destroy(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); +                                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); +                                continue; +                        } else { +                                log_warn("Illegal read: %s.", name); +                                cdap_reply_send(cdap, key, -1, NULL, 0); +                                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); +                                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."); +                                free(buf); +                                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 cacep_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; @@ -170,49 +179,52 @@ int enroll_boot(char * dst_name)          char * members_ro = MEMBERS_PATH;          char * dif_ro     = DIF_PATH; -        cacep_info_init(&info); - -        info.proto.protocol = strdup(CDAP_PROTO); -        if (info.proto.protocol == NULL) { -                cacep_info_fini(&info); -                return -ENOMEM; +        cdap = cdap_create(); +        if (cdap == NULL) { +                log_err("Failed to instantiate CDAP."); +                return -1;          } -        info.proto.pref_version = 1; -        info.proto.pref_syntax  = PROTO_GPB; - -        flow = cdap_flow_alloc(dst_name, ENROLL_AE, NULL, ANONYMOUS_AUTH, -                               &info); -        if (flow == NULL) { -                log_err("Failed to allocate flow for enrollment request."); -                cacep_info_fini(&info); +        if (connmgr_alloc(enroll.ae, dst_name, NULL, &conn)) { +                log_err("Failed to get connection."); +                cdap_destroy(cdap);                  return -1;          } -        cacep_info_fini(&info); +        if (cdap_add_flow(cdap, conn.flow_info.fd)) { +                log_warn("Failed to add flow to CDAP."); +                cdap_destroy(cdap); +                flow_dealloc(conn.flow_info.fd); +                return -1; +        }          log_dbg("Getting boot information from %s.", dst_name);          clock_gettime(CLOCK_REALTIME, &t0); -        key = cdap_request_send(flow->ci, CDAP_READ, TIME_PATH, NULL, 0, 0); -        if (key < 0) { +        key = cdap_request_send(cdap, CDAP_READ, TIME_PATH, NULL, 0, 0); +        if (key == NULL) {                  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[0], &data, &len)) {                  log_err("Failed to get CDAP reply."); -                cdap_flow_dealloc(flow); +                free(key); +                cdap_destroy(cdap); +                flow_dealloc(conn.flow_info.fd);                  return -1;          } +        free(key); +          clock_gettime(CLOCK_REALTIME, &rtt);          delta_t = ts_diff_ms(&t0, &rtt); -        assert (len == 2 * sizeof (uint64_t)); +        assert(len == 2 * sizeof (uint64_t));          rtt.tv_sec  = ntoh64(((uint64_t *) data)[0]);          rtt.tv_nsec = ntoh64(((uint64_t *) data)[1]); @@ -222,82 +234,138 @@ int enroll_boot(char * dst_name)          free(data); -        key = cdap_request_send(flow->ci, CDAP_READ, boot_ro, NULL, 0, 0); -        if (key < 0) { +        key = cdap_request_send(cdap, CDAP_READ, boot_ro, NULL, 0, 0); +        if (key == NULL) {                  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[0], &data, &len)) {                  log_err("Failed to get CDAP reply."); -                cdap_flow_dealloc(flow); +                free(key); +                cdap_destroy(cdap); +                flow_dealloc(conn.flow_info.fd);                  return -1;          } +        free(key); +          log_dbg("Packed information received (%zu bytes).", len);          if (rib_unpack(data, len, UNPACK_CREATE)) {                  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); -        if (key < 0) { +        key = cdap_request_send(cdap, CDAP_READ, members_ro, NULL, 0, 0); +        if (key == NULL) {                  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[0], &data, &len)) {                  log_err("Failed to get CDAP reply."); -                cdap_flow_dealloc(flow); +                free(key); +                cdap_destroy(cdap); +                flow_dealloc(conn.flow_info.fd);                  return -1;          } +        free(key); +          log_dbg("Packed information received (%zu bytes).", len);          if (rib_unpack(data, len, UNPACK_CREATE)) {                  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); -        if (key < 0) { +        key = cdap_request_send(cdap, CDAP_READ, dif_ro, NULL, 0, 0); +        if (key == NULL) {                  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[0], &data, &len)) {                  log_err("Failed to get CDAP reply."); -                cdap_flow_dealloc(flow); +                free(key); +                cdap_destroy(cdap); +                flow_dealloc(conn.flow_info.fd);                  return -1;          } +        free(key); +          log_dbg("Packed information received (%zu bytes).", len);          if (rib_unpack(data, len, UNPACK_CREATE)) {                  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..05f950ba 100644 --- a/src/ipcpd/normal/enroll.h +++ b/src/ipcpd/normal/enroll.h @@ -3,7 +3,8 @@   *   * Enrollment Task   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -22,8 +23,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/flow_alloc.proto b/src/ipcpd/normal/flow_alloc.proto index 16e8be2c..3b08f047 100644 --- a/src/ipcpd/normal/flow_alloc.proto +++ b/src/ipcpd/normal/flow_alloc.proto @@ -31,7 +31,6 @@ enum flow_alloc_code {  message flow_alloc_msg {          required flow_alloc_code code  = 1;          optional string dst_name       = 2; -        optional string src_ae_name    = 3; -        optional uint32 qoscube        = 4; -        optional sint32 response       = 5; +        optional uint32 qoscube        = 3; +        optional sint32 response       = 4;  }; diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index c2b53abf..184baf82 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -3,7 +3,8 @@   *   * Flow manager of the IPC Process   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -31,12 +32,16 @@  #include <ouroboros/cacep.h>  #include <ouroboros/rib.h> +#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 <stdlib.h>  #include <stdbool.h> @@ -48,19 +53,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 cacep_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 +62,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_i * 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; @@ -162,7 +183,7 @@ void * fmgr_nm1_sdu_reader(void * o)                          shm_pci_des(sdb, &pci); -                        if (pci.dst_addr != ipcpi.address) { +                        if (pci.dst_addr != ipcpi.dt_addr) {                                  log_dbg("PDU needs to be forwarded.");                                  if (pci.ttl == 0) { @@ -171,12 +192,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 +221,6 @@ void * fmgr_nm1_sdu_reader(void * o)          return (void *) 0;  } -static void * fmgr_nm1_flow_wait(void * o) -{ -        qoscube_t           cube; -        struct cacep_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,13 +233,29 @@ static void fmgr_destroy_flows(void)          }  } -int fmgr_init(void) +static void fmgr_destroy_routing(void)  { -        enum pol_cacep     pc; -        enum pol_gam       pg; +        int i; + +        for (i = 0; i < QOS_CUBE_MAX; ++i) +                routing_i_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; @@ -289,78 +291,135 @@ 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;          } -        if (rib_read(BOOT_PATH "/dt/gam/cacep", &pc, sizeof(pc)) -            != sizeof(pc)) { -                log_err("Failed to read CACEP policy for ribmgr gam."); +        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;          } -        /* FIXME: Implement cacep policies */ -        (void) pc; +        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; +        } -        fmgr.gam = gam_create(pg, DT_AE); -        if (fmgr.gam == NULL) { -                log_err("Failed to create graph adjacency manager."); +        if (routing_init(fmgr.nbs)) { +                log_err("Failed to init routing."); +                nbs_destroy(fmgr.nbs); +                fmgr_destroy_flows(); +                connmgr_ae_destroy(fmgr.ae); +                return -1; +        } + +        fmgr.nb_notifier.notify_call = fmgr_neighbor_event; +        if (nbs_reg_notifier(fmgr.nbs, &fmgr.nb_notifier)) { +                log_err("Failed to register notifier."); +                routing_fini(); +                nbs_destroy(fmgr.nbs); +                fmgr_destroy_flows(); +                connmgr_ae_destroy(fmgr.ae); +                return -1; +        } + +        if (pthread_rwlock_init(&fmgr.np1_flows_lock, NULL)) { +                gam_destroy(fmgr.gam); +                nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); +                routing_fini(); +                nbs_destroy(fmgr.nbs);                  fmgr_destroy_flows(); +                connmgr_ae_destroy(fmgr.ae);                  return -1;          } -        list_head_init(&fmgr.nm1_flows); +        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); +                        routing_fini(); +                        nbs_destroy(fmgr.nbs); +                        fmgr_destroy_flows(); +                        connmgr_ae_destroy(fmgr.ae); +                        return -1; +                } + +                fmgr.routing[i] = routing_i_create(fmgr.pff[i]); +                if (fmgr.routing[i] == NULL) { +                        for (j = 0; j < i; ++j) +                                routing_i_destroy(fmgr.routing[j]); +                        fmgr_destroy_pff(); +                        pthread_rwlock_destroy(&fmgr.np1_flows_lock); +                        nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); +                        routing_fini(); +                        nbs_destroy(fmgr.nbs); +                        fmgr_destroy_flows(); +                        connmgr_ae_destroy(fmgr.ae); +                        return -1; +                } +        } -        pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL); -        pthread_rwlock_init(&fmgr.np1_flows_lock, NULL); +        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); +                routing_fini(); +                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); + +        nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier);          gam_destroy(fmgr.gam); -        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->name); -                free(flow->info); -                free(flow); -        } +        fmgr_destroy_routing(); -        pthread_rwlock_unlock(&fmgr.nm1_flows_lock); +        fmgr_destroy_pff(); -        pthread_rwlock_destroy(&fmgr.nm1_flows_lock); -        pthread_rwlock_destroy(&fmgr.np1_flows_lock); +        routing_fini();          fmgr_destroy_flows(); + +        connmgr_ae_destroy(fmgr.ae); + +        nbs_destroy(fmgr.nbs);  }  int fmgr_np1_alloc(int       fd,                     char *    dst_ap_name, -                   char *    src_ae_name,                     qoscube_t cube)  {          cep_id_t         cep_id; @@ -406,7 +465,6 @@ int fmgr_np1_alloc(int       fd,          msg.code = FLOW_ALLOC_CODE__FLOW_REQ;          msg.dst_name = dst_ap_name; -        msg.src_ae_name = src_ae_name;          msg.has_qoscube = true;          msg.qoscube = cube; @@ -546,7 +604,6 @@ int fmgr_np1_post_buf(cep_id_t   cep_id,          case FLOW_ALLOC_CODE__FLOW_REQ:                  fd = ipcp_flow_req_arr(getpid(),                                         msg->dst_name, -                                       msg->src_ae_name,                                         msg->qoscube);                  if (fd < 0) {                          flow_alloc_msg__free_unpacked(msg, NULL); @@ -615,24 +672,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."); @@ -640,8 +693,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;          } @@ -653,9 +706,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) { @@ -664,7 +725,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 3c61f55a..f5076eab 100644 --- a/src/ipcpd/normal/fmgr.h +++ b/src/ipcpd/normal/fmgr.h @@ -3,7 +3,8 @@   *   * Flow manager of the IPC Process   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -34,7 +35,6 @@ void fmgr_fini(void);  int  fmgr_np1_alloc(int       fd,                      char *    dst_ap_name, -                    char *    src_ae_name,                      qoscube_t qos);  int  fmgr_np1_alloc_resp(int fd, @@ -54,8 +54,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 915feaf8..62cbf9f7 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -3,7 +3,8 @@   *   * The Flow and Retransmission control component   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -198,12 +199,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 +268,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; @@ -285,7 +286,7 @@ cep_id_t frct_i_create(uint64_t   address,          pci.pdu_type = PDU_TYPE_MGMT;          pci.dst_addr = address; -        pci.src_addr = ipcpi.address; +        pci.src_addr = ipcpi.dt_addr;          pci.dst_cep_id = 0;          pci.src_cep_id = id;          pci.seqno = 0; @@ -304,7 +305,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) @@ -330,7 +331,7 @@ int frct_i_accept(cep_id_t   id,          pci.pdu_type = PDU_TYPE_MGMT;          pci.dst_addr = instance->r_address; -        pci.src_addr = ipcpi.address; +        pci.src_addr = ipcpi.dt_addr;          pci.dst_cep_id = instance->r_cep_id;          pci.src_cep_id = instance->cep_id;          pci.seqno = 0; @@ -347,7 +348,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); @@ -367,7 +368,7 @@ int frct_i_destroy(cep_id_t   id,          pci.pdu_type = PDU_TYPE_MGMT;          pci.dst_addr = instance->r_address; -        pci.src_addr = ipcpi.address; +        pci.src_addr = ipcpi.dt_addr;          pci.dst_cep_id = instance->r_cep_id;          pci.src_cep_id = instance->cep_id;          pci.seqno = 0; @@ -390,7 +391,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) @@ -413,7 +414,7 @@ int frct_i_write_sdu(cep_id_t             id,          pci.pdu_type = PDU_TYPE_DTP;          pci.dst_addr = instance->r_address; -        pci.src_addr = ipcpi.address; +        pci.src_addr = ipcpi.dt_addr;          pci.dst_cep_id = instance->r_cep_id;          pci.src_cep_id = instance->cep_id;          pci.seqno = (instance->seqno)++; diff --git a/src/ipcpd/normal/frct.h b/src/ipcpd/normal/frct.h index 462b8cc3..a1dcb151 100644 --- a/src/ipcpd/normal/frct.h +++ b/src/ipcpd/normal/frct.h @@ -3,7 +3,8 @@   *   * The Flow and Retransmission control component   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -27,6 +28,8 @@  #include "shm_pci.h" +#define FRCT_PROTO "FRCT" +  struct frct_i;  int         frct_init(void); diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/normal/fso.proto index 6a42ec5c..32b281d6 100644 --- a/src/ipcpd/ipcp-ops.h +++ b/src/ipcpd/normal/fso.proto @@ -1,7 +1,7 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * IPC process ops + * Flow State Object message   *   *    Dimitri Staessens <dimitri.staessens@intec.ugent.be>   *    Sander Vrijders   <sander.vrijders@intec.ugent.be> @@ -20,32 +20,10 @@   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ -#ifndef IPCPD_IPCP_OPS_H -#define IPCPD_IPCP_OPS_H +syntax = "proto2"; -#include <ouroboros/irm_config.h> -#include <ouroboros/shared.h> - -struct ipcp_ops { -        int   (* ipcp_bootstrap)(struct dif_config * conf); - -        int   (* ipcp_enroll)(char * dif_name); - -        int   (* ipcp_name_reg)(char * name); - -        int   (* ipcp_name_unreg)(char * name); - -        int   (* ipcp_name_query)(char * name); - -        int   (* ipcp_flow_alloc)(int       fd, -                                  char *    dst_ap_name, -                                  char *    src_ae_name, -                                  qoscube_t qos); - -        int   (* ipcp_flow_alloc_resp)(int fd, -                                       int response); - -        int   (* ipcp_flow_dealloc)(int fd); +message fso { +        required uint64 s_addr = 1; +        required uint64 d_addr = 2; +        /* Add QoS parameters of link here */  }; - -#endif /* IPCPD_IPCP_OPS_H */ diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c index 791cf34e..643d83b0 100644 --- a/src/ipcpd/normal/gam.c +++ b/src/ipcpd/normal/gam.c @@ -1,10 +1,10 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Graph adjacency manager for IPC Process components + *  Data transfer graph adjacency manager   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 @@ -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 <ouroboros/config.h>  #include <ouroboros/cdap.h> @@ -40,295 +40,43 @@  #include <pthread.h>  #include <string.h> -struct ga { -        struct list_head    next; - -        qosspec_t           qs; -        int                 fd; -        struct cacep_info * info; -}; -  struct gam { -        struct list_head     gas; -        pthread_mutex_t      gas_lock; -        pthread_cond_t       gas_cond; - -        char *               ae_name; -          struct pol_gam_ops * ops;          void *               ops_o;  };  struct gam * gam_create(enum pol_gam gam_type, -                        const char * ae_name) +                        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); - -        tmp->ae_name = strdup(ae_name); -        if (tmp->ae_name == NULL) { -                free(tmp); +        gam->ops_o = gam->ops->create(nbs, ae); +        if (gam->ops_o == NULL) { +                free(gam);                  return NULL;          } -        if (pthread_mutex_init(&tmp->gas_lock, NULL)) { -                free(tmp->ae_name); -                free(tmp); -                return NULL; -        } - -        if (pthread_cond_init(&tmp->gas_cond, NULL)) { -                pthread_mutex_destroy(&tmp->gas_lock); -                free(tmp->ae_name); -                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->ae_name); -                free(tmp); -                return NULL; -        } - -        if (tmp->ops->start(tmp->ops_o)) { -                pthread_cond_destroy(&tmp->gas_cond); -                pthread_mutex_destroy(&tmp->gas_lock); -                free(tmp->ae_name); -                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->name); -                free(e->info); -                free(e); -        } - -        pthread_mutex_unlock(&instance->gas_lock); - -        pthread_mutex_destroy(&instance->gas_lock); -        pthread_cond_destroy(&instance->gas_cond); - -        free(instance->ae_name); -        instance->ops->destroy(instance->ops_o); -        free(instance); -} - -static int add_ga(struct gam *        instance, -                  int                 fd, -                  qosspec_t           qs, -                  struct cacep_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 %s flow to %s.", instance->ae_name, info->name); - -        return 0; -} - -int gam_flow_arr(struct gam * instance, -                 int          fd, -                 qosspec_t    qs) -{ -        struct cacep_info * rcv_info; -        struct cacep_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; -        } - -        cacep_info_init(&snd_info); -        snd_info.proto.protocol = strdup(CDAP_PROTO); -        if (snd_info.proto.protocol == NULL) { -                cacep_info_fini(&snd_info); -                return -ENOMEM; -        } - -        snd_info.proto.pref_version = 1; -        snd_info.proto.pref_syntax = PROTO_GPB; -        snd_info.addr = ipcpi.address; -        snd_info.name = strdup(ipcpi.name); -        if (snd_info.name == NULL) { -                cacep_info_fini(&snd_info); -                return -ENOMEM; -        } - -        rcv_info = cacep_auth_wait(fd, SIMPLE_AUTH, &snd_info); -        if (rcv_info == NULL) { -                log_err("Other side failed to authenticate."); -                cacep_info_fini(&snd_info); -                return -1; -        } - -        cacep_info_fini(&snd_info); - -        if (instance->ops->accept_flow(instance->ops_o, qs, rcv_info)) { -                flow_dealloc(fd); -                cacep_info_fini(rcv_info); -                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); -                cacep_info_fini(rcv_info); -                free(rcv_info); -                return -1; -        } - -        return 0; -} - -int gam_flow_alloc(struct gam * instance, -                   char *       dst_name, -                   qosspec_t    qs) -{ -        struct cacep_info * rcv_info; -        struct cacep_info   snd_info; -        int                 fd; - -        log_dbg("Allocating flow to %s.", dst_name); - -        fd = flow_alloc(dst_name, instance->ae_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; -        } - -        cacep_info_init(&snd_info); -        snd_info.proto.protocol = strdup(CDAP_PROTO); -        if (snd_info.proto.protocol == NULL) { -                cacep_info_fini(&snd_info); -                return -ENOMEM; -        } - -        snd_info.proto.pref_version = 1; -        snd_info.proto.pref_syntax = PROTO_GPB; -        snd_info.addr = ipcpi.address; -        snd_info.name = strdup(ipcpi.name); -        if (snd_info.name == NULL) { -                cacep_info_fini(&snd_info); -                return -ENOMEM; -        } - -        rcv_info = cacep_auth(fd, SIMPLE_AUTH, &snd_info); -        if (rcv_info == NULL) { -                log_err("Other side failed to authenticate."); -                cacep_info_fini(&snd_info); -                return -1; -        } - -        cacep_info_fini(&snd_info); - -        if (instance->ops->accept_flow(instance->ops_o, qs, rcv_info)) { -                flow_dealloc(fd); -                cacep_info_fini(rcv_info); -                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); -                cacep_info_fini(rcv_info); -                free(rcv_info); -                return -1; -        } - -        return 0; +        return gam;  } -int gam_flow_wait(struct gam *         instance, -                  int *                fd, -                  struct cacep_info ** info, -                  qosspec_t *          qs) +void gam_destroy(struct gam * gam)  { -        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 50f83df9..4ae0b1b3 100644 --- a/src/ipcpd/normal/gam.h +++ b/src/ipcpd/normal/gam.h @@ -1,10 +1,10 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Graph adjacency manager for IPC Process components + * Data transfer graph adjacency manager   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 @@ -26,22 +26,12 @@  #include <ouroboros/cacep.h>  #include <ouroboros/irm_config.h> -struct gam * gam_create(enum pol_gam gam_type, -                        const char * ae_name); - -void         gam_destroy(struct gam * instance); +#include "neighbors.h" -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); +struct gam * gam_create(enum pol_gam gam_type, +                        struct nbs * nbs, +                        struct ae *  ae); -int          gam_flow_wait(struct gam *         instance, -                           int *                fd, -                           struct cacep_info ** info, -                           qosspec_t *          qs); +void         gam_destroy(struct gam * gam);  #endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */ 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 <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 "graph" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> +#include <ouroboros/list.h> + +#include "graph.h" + +#include <assert.h> +#include <pthread.h> +#include <stdlib.h> + +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 <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_GRAPH_H +#define OUROBOROS_IPCPD_NORMAL_GRAPH_H + +#include <ouroboros/list.h> +#include <ouroboros/qos.h> + +#include <inttypes.h> + +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/main.c b/src/ipcpd/normal/main.c index 522daa3b..398d6ee3 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -3,8 +3,8 @@   *   * Normal IPC Process   * - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -24,7 +24,6 @@  #include <ouroboros/config.h>  #include <ouroboros/logs.h> -#include <ouroboros/dev.h>  #include <ouroboros/ipcp-dev.h>  #include <ouroboros/time_utils.h>  #include <ouroboros/irm.h> @@ -33,11 +32,10 @@  #include <ouroboros/errno.h>  #include "addr_auth.h" -#include "ae.h" +#include "connmgr.h"  #include "dir.h"  #include "enroll.h"  #include "fmgr.h" -#include "frct.h"  #include "ipcp.h"  #include "ribconfig.h"  #include "ribmgr.h" @@ -45,16 +43,11 @@  #include <stdbool.h>  #include <signal.h>  #include <stdlib.h> -#include <pthread.h>  #include <string.h>  #include <assert.h>  #include <inttypes.h> -#define THIS_TYPE    IPCP_NORMAL - -struct { -        pthread_t acceptor; -} normal; +#define THIS_TYPE IPCP_NORMAL  void ipcp_sig_handler(int         sig,                        siginfo_t * info, @@ -82,54 +75,6 @@ void ipcp_sig_handler(int         sig,          }  } -static void * flow_acceptor(void * o) -{ -        int       fd; -        char *    ae_name; -        qosspec_t qs; - -        (void) o; - -        while (true) { -                pthread_rwlock_rdlock(&ipcpi.state_lock); - -                if (ipcp_get_state() != IPCP_OPERATIONAL) { -                        pthread_rwlock_unlock(&ipcpi.state_lock); -                        log_info("Shutting down flow acceptor."); -                        return 0; -                } - -                pthread_rwlock_unlock(&ipcpi.state_lock); - -                fd = flow_accept(&ae_name, &qs); -                if (fd < 0) { -                        if (fd != -EIRMD) -                                log_warn("Flow accept failed: %d", fd); -                        continue; -                } - -                log_dbg("New flow allocation request for AE %s.", ae_name); - -                if (strcmp(ae_name, ENROLL_AE) == 0) { -                        enroll_handle(fd); -                } else if (strcmp(ae_name, MGMT_AE) == 0) { -                        ribmgr_flow_arr(fd, qs); -                } else if (strcmp(ae_name, DT_AE) == 0) { -                        fmgr_nm1_flow_arr(fd, qs); -                } else { -                        log_dbg("Flow allocation request for unknown AE %s.", -                                ae_name); -                        if (flow_alloc_resp(fd, -1)) -                                log_warn("Failed to reply to flow allocation."); -                        flow_dealloc(fd); -                } - -                free(ae_name); -        } - -        return (void *) 0; -} -  /*   * Boots the IPCP off information in the rib.   * Common function after bootstrap or enroll. @@ -154,7 +99,7 @@ static int boot_components(void)          }          if (rib_add(MEMBERS_PATH, ipcpi.name)) { -                log_warn("Failed to add name to " MEMBERS_PATH); +                log_err("Failed to add name to " MEMBERS_PATH);                  return -1;          } @@ -163,6 +108,7 @@ static int boot_components(void)          if (rib_read(BOOT_PATH "/addr_auth/type", &pa, sizeof(pa))              != sizeof(pa)) {                  log_err("Failed to read policy for address authority."); +                connmgr_fini();                  return -1;          } @@ -171,14 +117,14 @@ static int boot_components(void)                  return -1;          } -        ipcpi.address = addr_auth_address(); -        if (ipcpi.address == 0) { +        ipcpi.dt_addr = addr_auth_address(); +        if (ipcpi.dt_addr == 0) {                  log_err("Failed to get a valid address.");                  addr_auth_fini();                  return -1;          } -        log_dbg("IPCP got address %" PRIu64 ".", ipcpi.address); +        log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr);          log_dbg("Starting ribmgr."); @@ -214,15 +160,26 @@ static int boot_components(void)                  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 (pthread_create(&normal.acceptor, NULL, flow_acceptor, NULL)) { +        if (connmgr_start()) {                  ipcp_set_state(IPCP_INIT); +                enroll_stop(); +                frct_fini();                  fmgr_fini();                  dir_fini();                  ribmgr_fini();                  addr_auth_fini(); -                log_err("Failed to create acceptor thread."); +                log_err("Failed to start AP connection manager.");                  return -1;          } @@ -231,8 +188,9 @@ static int boot_components(void)  void shutdown_components(void)  { -        pthread_cancel(normal.acceptor); -        pthread_join(normal.acceptor, NULL); +        connmgr_stop(); + +        enroll_stop();          frct_fini(); @@ -337,11 +295,6 @@ int normal_rib_init(void)  static int normal_ipcp_bootstrap(struct dif_config * conf)  { -        /* FIXME: get CACEP policies from conf */ -        enum pol_cacep pol = SIMPLE_AUTH; - -        (void) pol; -          assert(conf);          assert(conf->type == THIS_TYPE); @@ -389,12 +342,6 @@ static int normal_ipcp_bootstrap(struct dif_config * conf)              rib_write(BOOT_PATH "/rm/gam/type",                        &conf->rm_gam_type,                        sizeof(conf->rm_gam_type)) || -            rib_write(BOOT_PATH "/rm/gam/cacep", -                      &pol, -                      sizeof(pol)) || -            rib_write(BOOT_PATH "/dt/gam/cacep", -                      &pol, -                      sizeof(pol)) ||              rib_write(BOOT_PATH "/addr_auth/type",                        &conf->addr_auth_type,                        sizeof(conf->addr_auth_type))) { @@ -422,9 +369,9 @@ static struct ipcp_ops normal_ops = {          .ipcp_name_reg        = dir_name_reg,          .ipcp_name_unreg      = dir_name_unreg,          .ipcp_name_query      = dir_name_query, -        .ipcp_flow_alloc      = NULL, /* fmgr_np1_alloc, */ -        .ipcp_flow_alloc_resp = NULL, /* fmgr_np1_alloc_resp, */ -        .ipcp_flow_dealloc    = NULL, /* fmgr_np1_dealloc */ +        .ipcp_flow_alloc      = fmgr_np1_alloc, +        .ipcp_flow_alloc_resp = fmgr_np1_alloc_resp, +        .ipcp_flow_dealloc    = fmgr_np1_dealloc  };  int main(int    argc, @@ -471,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(); @@ -488,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(); @@ -501,6 +472,10 @@ int main(int    argc,          rib_fini(); +        enroll_fini(); + +        connmgr_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..1c399145 --- /dev/null +++ b/src/ipcpd/normal/neighbors.c @@ -0,0 +1,213 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + *    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 "neighbors" + +#include <ouroboros/config.h> +#include <ouroboros/shared.h> +#include <ouroboros/ipcp-dev.h> +#include <ouroboros/errno.h> +#include <ouroboros/logs.h> + +#include "neighbors.h" + +#include <stdlib.h> +#include <assert.h> +#include <inttypes.h> + +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..8714a9aa --- /dev/null +++ b/src/ipcpd/normal/neighbors.h @@ -0,0 +1,81 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + *    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_NEIGHBORS_H +#define OUROBOROS_IPCPD_NORMAL_NEIGHBORS_H + +#include <ouroboros/irm_config.h> +#include <ouroboros/list.h> +#include <ouroboros/qos.h> +#include <ouroboros/fqueue.h> +#include <ouroboros/cacep.h> + +#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..8cab7936 100644 --- a/src/ipcpd/normal/pff.c +++ b/src/ipcpd/normal/pff.c @@ -3,7 +3,8 @@   *   * PDU Forwarding Function   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -55,15 +56,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..667c341e 100644 --- a/src/ipcpd/normal/pff.h +++ b/src/ipcpd/normal/pff.h @@ -3,8 +3,8 @@   *   * PDU Forwarding Function   * - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -25,8 +25,6 @@  #include <stdint.h> -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-addr-auth-ops.h b/src/ipcpd/normal/pol-addr-auth-ops.h index 25952636..f0f473ef 100644 --- a/src/ipcpd/normal/pol-addr-auth-ops.h +++ b/src/ipcpd/normal/pol-addr-auth-ops.h @@ -3,8 +3,8 @@   *   * Address authority policy ops   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h index 0721136c..cfe9cbc3 100644 --- a/src/ipcpd/normal/pol-gam-ops.h +++ b/src/ipcpd/normal/pol-gam-ops.h @@ -3,8 +3,8 @@   *   * Graph adjacency manager policy ops   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 @@ -24,21 +24,13 @@  #define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H  #include <ouroboros/cacep.h> +#include <ouroboros/qos.h>  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 cacep_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 5faa1ae8..1f3f6031 100644 --- a/src/ipcpd/normal/pol/complete.c +++ b/src/ipcpd/normal/pol/complete.c @@ -1,10 +1,10 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Graph adjacency manager for IPC Process components + * Sets up a complete graph   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 @@ -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 <ouroboros/config.h> -#include <ouroboros/logs.h> -#include <ouroboros/list.h> -#include <ouroboros/qos.h> +#include <ouroboros/shared.h>  #include <ouroboros/rib.h> +#include <ouroboros/dev.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> +#include <ouroboros/cacep.h> -#include "ipcp.h" -#include "gam.h" +#include "neighbors.h" +#include "frct.h"  #include "ribconfig.h" +#include "ipcp.h" +#include "ae.h"  #include <string.h>  #include <stdlib.h>  #include <assert.h> -struct neighbor { -        struct list_head next; -        char *           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,19 +75,37 @@ 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; +        /* FIXME: implement QoS specs */ +        qs.cube = QOS_CUBE_BE; +          /* 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,123 +115,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->neighbor); -                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 cacep_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); -                if (strcmp(e->neighbor, info->name) == 0) { -                        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 = strdup(info->name); -        if (n->neighbor == NULL) { -                pthread_mutex_unlock(&complete->neighbors_lock); -                free(n); -                return -1; -        } - -        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 3f08c2e5..46a535c2 100644 --- a/src/ipcpd/normal/pol/complete.h +++ b/src/ipcpd/normal/pol/complete.h @@ -1,10 +1,10 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Graph adjacency manager for IPC Process components + * Sets up a complete graph   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 @@ -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 <ouroboros/irm_config.h> +#include <ouroboros/qos.h> -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 cacep_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/pol/flat.c b/src/ipcpd/normal/pol/flat.c index aa0f6c7c..e709da7c 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -3,8 +3,8 @@   *   * Policy for flat addresses in a distributed way   * - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/pol/flat.h b/src/ipcpd/normal/pol/flat.h index 85fe9281..d45a89cd 100644 --- a/src/ipcpd/normal/pol/flat.h +++ b/src/ipcpd/normal/pol/flat.h @@ -3,7 +3,8 @@   *   * Policy for flat addresses in a distributed way   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 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 f254bd50..ec465c6b 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -3,8 +3,8 @@   *   * RIB manager of the IPC Process   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 @@ -45,35 +45,70 @@  #include <assert.h>  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_cacep pc; -        enum pol_gam   pg; +        enum pol_gam     pg; +        struct conn_info info; -        if (rib_read(BOOT_PATH "/rm/gam/type", &pg, sizeof(pg)) -            != sizeof(pg)) { -                log_err("Failed to read policy for ribmgr gam."); +        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;          } -        if (rib_read(BOOT_PATH "/rm/gam/cacep", &pc, sizeof(pc)) -            != sizeof(pc)) { -                log_err("Failed to read CACEP policy for ribmgr gam."); +        ribmgr.ae = connmgr_ae_create(info); +        if (ribmgr.ae == NULL) { +                log_err("Failed to create AE struct."); +                nbs_destroy(ribmgr.nbs);                  return -1;          } -        /* FIXME: Implement cacep policies */ -        (void) pc; +        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, MGMT_AE); +        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;          } @@ -81,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;          } @@ -89,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;          } @@ -97,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..8922688a 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -3,7 +3,8 @@   *   * RIB manager of the IPC Process   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -41,9 +42,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..745d1812 --- /dev/null +++ b/src/ipcpd/normal/routing.c @@ -0,0 +1,298 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing component of the IPCP + * + *    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 "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 "routing.h" +#include "ribmgr.h" +#include "ribconfig.h" +#include "ipcp.h" +#include "graph.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 + +struct routing_table_entry { +        struct list_head next; +        uint64_t         dst; +        uint64_t         nhop; +}; + +struct routing_i { +        struct pff * pff; +}; + +struct { +        struct nbs *       nbs; +        struct nb_notifier nb_notifier; + +        struct graph *     graph; + +        ro_set_t *         set; +        rqueue_t *         queue; +        pthread_t          rib_listener; +} routing; + +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; + +        return tmp; +} + +void routing_i_destroy(struct routing_i * instance) +{ +        assert(instance); + +        free(instance); +} + +static int routing_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; + +        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: +                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; +                } + +                break; +        case NEIGHBOR_REMOVED: +                if (rib_del(path)) { +                        log_err("Failed to remove FSO."); +                        return -1; +                } + +                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; + +        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) +{ +        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; + +        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; +} + +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); +} diff --git a/src/ipcpd/normal/routing.h b/src/ipcpd/normal/routing.h new file mode 100644 index 00000000..0794ef28 --- /dev/null +++ b/src/ipcpd/normal/routing.h @@ -0,0 +1,45 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing component of the IPCP + * + *    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_ROUTING_H +#define OUROBOROS_IPCPD_NORMAL_ROUTING_H + +#include <ouroboros/qos.h> + +#include "pff.h" +#include "neighbors.h" + +#include <stdint.h> + +/* + * Routing will take a type in the future, + * to allow different policies. + */ +int                routing_init(struct nbs * nbs); + +void               routing_fini(void); + +struct routing_i * routing_i_create(struct pff * pff); + +void               routing_i_destroy(struct routing_i * instance); + +#endif /* OUROBOROS_IPCPD_NORMAL_ROUTING_H */ diff --git a/src/ipcpd/normal/shm_pci.c b/src/ipcpd/normal/shm_pci.c index 0807a24f..1170adff 100644 --- a/src/ipcpd/normal/shm_pci.c +++ b/src/ipcpd/normal/shm_pci.c @@ -3,8 +3,8 @@   *   * Protocol Control Information in Shared Memory Map   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/normal/shm_pci.h b/src/ipcpd/normal/shm_pci.h index 17ce5cdd..0c54c883 100644 --- a/src/ipcpd/normal/shm_pci.h +++ b/src/ipcpd/normal/shm_pci.h @@ -3,8 +3,8 @@   *   * Protocol Control Information in Shared Memory Map   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index bec2486c..eb4ec33f 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -3,8 +3,8 @@   *   * IPC process utilities   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h index 28087901..ac670b43 100644 --- a/src/ipcpd/shim-data.h +++ b/src/ipcpd/shim-data.h @@ -3,8 +3,8 @@   *   * Utitilies for building IPC processes   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> - *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    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 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-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index cd913de4..8015d64a 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -3,7 +3,8 @@   *   * Shim IPC process over Ethernet with LLC   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    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 @@ -334,7 +335,6 @@ static int eth_llc_ipcp_send_mgmt_frame(shim_eth_llc_msg_t * msg,  static int eth_llc_ipcp_sap_alloc(uint8_t * dst_addr,                                    uint8_t   ssap,                                    char *    dst_name, -                                  char *    src_ae_name,                                    qoscube_t cube)  {          shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT; @@ -343,7 +343,6 @@ static int eth_llc_ipcp_sap_alloc(uint8_t * dst_addr,          msg.has_ssap    = true;          msg.ssap        = ssap;          msg.dst_name    = dst_name; -        msg.src_ae_name = src_ae_name;          msg.has_qoscube = true;          msg.qoscube     = cube; @@ -371,7 +370,6 @@ static int eth_llc_ipcp_sap_alloc_resp(uint8_t * dst_addr,  static int eth_llc_ipcp_sap_req(uint8_t   r_sap,                                  uint8_t * r_addr,                                  char *    dst_name, -                                char *    src_ae_name,                                  qoscube_t cube)  {          int fd; @@ -380,7 +378,7 @@ static int eth_llc_ipcp_sap_req(uint8_t   r_sap,          pthread_rwlock_wrlock(ð_llc_data.flows_lock);          /* reply to IRM */ -        fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name, cube); +        fd = ipcp_flow_req_arr(getpid(), dst_name, cube);          if (fd < 0) {                  pthread_rwlock_unlock(ð_llc_data.flows_lock);                  pthread_rwlock_unlock(&ipcpi.state_lock); @@ -491,7 +489,6 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf,                          eth_llc_ipcp_sap_req(msg->ssap,                                               r_addr,                                               msg->dst_name, -                                             msg->src_ae_name,                                               msg->qoscube);                  }                  break; @@ -989,7 +986,6 @@ static int eth_llc_ipcp_name_query(char * name)  static int eth_llc_ipcp_flow_alloc(int       fd,                                     char *    dst_name, -                                   char *    src_ae_name,                                     qoscube_t cube)  {          uint8_t ssap = 0; @@ -998,7 +994,7 @@ static int eth_llc_ipcp_flow_alloc(int       fd,          log_dbg("Allocating flow to %s.", dst_name); -        if (dst_name == NULL || src_ae_name == NULL) +        if (dst_name == NULL)                  return -1;          if (cube != QOS_CUBE_BE && cube != QOS_CUBE_FRC) { @@ -1038,11 +1034,7 @@ static int eth_llc_ipcp_flow_alloc(int       fd,          memcpy(r_addr, &addr, MAC_SIZE); -        if (eth_llc_ipcp_sap_alloc(r_addr, -                                   ssap, -                                   dst_name, -                                   src_ae_name, -                                   cube) < 0) { +        if (eth_llc_ipcp_sap_alloc(r_addr, ssap, dst_name, cube) < 0) {                  pthread_rwlock_rdlock(&ipcpi.state_lock);                  pthread_rwlock_wrlock(ð_llc_data.flows_lock);                  bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap); diff --git a/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto b/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto index cedb0fd4..2d66428c 100644 --- a/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto +++ b/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto @@ -32,9 +32,8 @@ enum shim_eth_llc_msg_code {  message shim_eth_llc_msg {          required shim_eth_llc_msg_code code  = 1;          optional string dst_name             = 2; -        optional string src_ae_name          = 3; -        optional uint32 ssap                 = 4; -        optional uint32 dsap                 = 5; -        optional uint32 qoscube              = 6; -        optional sint32 response             = 7; +        optional uint32 ssap                 = 3; +        optional uint32 dsap                 = 4; +        optional uint32 qoscube              = 5; +        optional sint32 response             = 6;  }; 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/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 4d6fdc3b..3bbce79d 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -3,7 +3,8 @@   *   * Shim IPC process over UDP   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -197,7 +198,6 @@ static int send_shim_udp_msg(shim_udp_msg_t * msg,  static int ipcp_udp_port_alloc(uint32_t  dst_ip_addr,                                 uint16_t  src_udp_port,                                 char *    dst_name, -                               char *    src_ae_name,                                 qoscube_t cube)  {          shim_udp_msg_t msg = SHIM_UDP_MSG__INIT; @@ -205,7 +205,6 @@ static int ipcp_udp_port_alloc(uint32_t  dst_ip_addr,          msg.code         = SHIM_UDP_MSG_CODE__FLOW_REQ;          msg.src_udp_port = src_udp_port;          msg.dst_name     = dst_name; -        msg.src_ae_name  = src_ae_name;          msg.has_qoscube  = true;          msg.qoscube      = cube; @@ -231,7 +230,6 @@ static int ipcp_udp_port_alloc_resp(uint32_t dst_ip_addr,  static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,                               char *               dst_name, -                             char *               src_ae_name,                               qoscube_t            cube)  {          int skfd; @@ -275,7 +273,7 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,          pthread_rwlock_wrlock(&udp_data.flows_lock);          /* reply to IRM */ -        fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name, cube); +        fd = ipcp_flow_req_arr(getpid(), dst_name, cube);          if (fd < 0) {                  pthread_rwlock_unlock(&udp_data.flows_lock);                  pthread_rwlock_unlock(&ipcpi.state_lock); @@ -397,7 +395,6 @@ static void * ipcp_udp_listener(void * o)                          c_saddr.sin_port = msg->src_udp_port;                          ipcp_udp_port_req(&c_saddr,                                            msg->dst_name, -                                          msg->src_ae_name,                                            msg->qoscube);                          break;                  case SHIM_UDP_MSG_CODE__FLOW_REPLY: @@ -957,7 +954,6 @@ static int ipcp_udp_name_query(char * name)  static int ipcp_udp_flow_alloc(int       fd,                                 char *    dst_name, -                               char *    src_ae_name,                                 qoscube_t cube)  {          struct sockaddr_in r_saddr; /* server address */ @@ -969,10 +965,8 @@ static int ipcp_udp_flow_alloc(int       fd,          log_dbg("Allocating flow to %s.", dst_name);          assert(dst_name); -        assert(src_ae_name); -        if (strlen(dst_name) > 255 -            || strlen(src_ae_name) > 255) { +        if (strlen(dst_name) > 255) {                  log_err("Name too long for this shim.");                  return -1;          } @@ -1043,7 +1037,6 @@ static int ipcp_udp_flow_alloc(int       fd,          if (ipcp_udp_port_alloc(ip_addr,                                  f_saddr.sin_port,                                  dst_name, -                                src_ae_name,                                  cube) < 0) {                  pthread_rwlock_rdlock(&ipcpi.state_lock);                  pthread_rwlock_wrlock(&udp_data.flows_lock); diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c index d4a5d8ed..d7bd0bb7 100644 --- a/src/ipcpd/shim-udp/tests/shim_udp_test.c +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -3,7 +3,8 @@   *   * Test of the Shim UDP IPCP Daemon   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 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/ipcpd/tests/timerwheel_test.c b/src/ipcpd/tests/timerwheel_test.c index 23de403a..cf5b0333 100644 --- a/src/ipcpd/tests/timerwheel_test.c +++ b/src/ipcpd/tests/timerwheel_test.c @@ -3,7 +3,8 @@   *   * Test of the timer wheel   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 diff --git a/src/ipcpd/timerwheel.c b/src/ipcpd/timerwheel.c index ef79bc14..d309bbf9 100644 --- a/src/ipcpd/timerwheel.c +++ b/src/ipcpd/timerwheel.c @@ -3,7 +3,8 @@   *   * Timerwheel   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 diff --git a/src/ipcpd/timerwheel.h b/src/ipcpd/timerwheel.h index 8ef9437c..aa71c73d 100644 --- a/src/ipcpd/timerwheel.h +++ b/src/ipcpd/timerwheel.h @@ -3,7 +3,8 @@   *   * Ring buffer for incoming SDUs   * - *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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 @@ -31,8 +32,8 @@ void                timerwheel_destroy(struct timerwheel * tw);  int                 timerwheel_add(struct timerwheel * tw,                                     void (* func)(void *), -                                   void *       arg, -                                   size_t       arg_len, -                                   unsigned int delay); /* ms */ +                                   void *              arg, +                                   size_t              arg_len, +                                   unsigned int        delay); /* ms */  #endif /* OUROBOROS_IPCPD_TIMERWHEEL_H */ | 
