diff options
Diffstat (limited to 'src')
28 files changed, 1045 insertions, 158 deletions
| diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 2e4c3fca..a94e268d 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -128,6 +128,7 @@ static void * ipcp_main_loop(void * o)                                  conf.min_pdu_size = conf_msg->min_pdu_size;                                  conf.max_pdu_size = conf_msg->max_pdu_size;                                  conf.addr_auth_type = conf_msg->addr_auth_type; +                                conf.dt_gam_type = conf_msg->dt_gam_type;                          }                          if (conf_msg->ipcp_type == IPCP_SHIM_UDP) {                                  conf.ip_addr  = conf_msg->ip_addr; @@ -440,22 +441,26 @@ int ipcp_parse_arg(int argc, char * argv[])          if (atoi(argv[1]) == 0)                  return -1; -        if (argv[2] == NULL) +        ipcpi.irmd_api = atoi(argv[1]); + +        /* argument 2: IPCP name */ +        ipcpi.name = argv[2]; + +        /* argument 3: logfile name (if any) */ +        if (argv[3] == NULL)                  return 0;          len += strlen(INSTALL_PREFIX);          len += strlen(LOG_DIR); -        len += strlen(argv[2]); +        len += strlen(argv[3]);          log_file = malloc(len + 1); -        if (log_file == NULL) { -                LOG_ERR("Failed to malloc"); +        if (log_file == NULL)                  return -1; -        }          strcpy(log_file, INSTALL_PREFIX);          strcat(log_file, LOG_DIR); -        strcat(log_file, argv[2]); +        strcat(log_file, argv[3]);          log_file[len] = '\0';          if (set_logfile(log_file)) diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index ae5a56da..a75186ba 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -38,6 +38,9 @@ enum ipcp_state {  };  struct ipcp { +        int                irmd_api; +        char *             name; +          struct ipcp_data * data;          struct ipcp_ops *  ops;          int                irmd_fd; diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 58949aea..5117f59d 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -41,9 +41,6 @@  #define EVENT_WAIT_TIMEOUT 100 /* us */  #define THIS_TYPE IPCP_LOCAL -/* global for trapping signal */ -int irmd_api; -  struct {          int                   in_out[IRMD_MAX_FLOWS];          flow_set_t *          flows; @@ -127,7 +124,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)          case SIGTERM:          case SIGHUP:          case SIGQUIT: -                if (info->si_pid == irmd_api) { +                if (info->si_pid == ipcpi.irmd_api) {                          pthread_rwlock_wrlock(&ipcpi.state_lock);                          if (ipcp_get_state() == IPCP_INIT) @@ -349,9 +346,6 @@ int main(int argc, char * argv[])                  exit(EXIT_FAILURE);          } -        /* store the process id of the irmd */ -        irmd_api = atoi(argv[1]); -          /* init sig_act */          memset(&sig_act, 0, sizeof(sig_act)); diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index bdcb78ae..157baa9e 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -29,12 +29,14 @@ set(SOURCE_FILES    dir.c    fmgr.c    frct.c +  gam.c    main.c    pathname.c    pff.c    ribmgr.c    shm_pci.c    # Add policies last +  pol/complete.c    pol/flat.c    ) diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index a419e9f5..6fe6fb60 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -28,6 +28,7 @@  #include <ouroboros/ipcp-dev.h>  #include <ouroboros/fqueue.h>  #include <ouroboros/errno.h> +#include <ouroboros/cacep.h>  #include <stdlib.h>  #include <stdbool.h> @@ -42,15 +43,24 @@  #include "dir.h"  #include "pathname.h"  #include "ro.h" +#include "gam.h"  #include "flow_alloc.pb-c.h"  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]; @@ -60,21 +70,23 @@ struct {          cep_id_t           np1_fd_to_cep_id[AP_MAX_FLOWS];          int                np1_cep_id_to_fd[IPCPD_MAX_CONNS]; -        pthread_t          nm1_sdu_reader;          pthread_t          np1_sdu_reader; +        pthread_t          nm1_sdu_reader; +        pthread_t          nm1_flow_wait;          /* FIXME: Replace with PFF */          int fd; + +        struct gam *       gam;  } fmgr;  static void * fmgr_np1_sdu_reader(void * o)  {          struct shm_du_buff * sdb; -        struct timespec timeout = {0, FD_UPDATE_TIMEOUT}; -        int fd; - -        int i = 0; -        int ret; +        struct timespec      timeout = {0, FD_UPDATE_TIMEOUT}; +        int                  fd; +        int                  i = 0; +        int                  ret;          (void) o; @@ -118,12 +130,12 @@ static void * fmgr_np1_sdu_reader(void * o)  void * fmgr_nm1_sdu_reader(void * o)  { -        struct timespec timeout = {0, FD_UPDATE_TIMEOUT}; +        struct timespec      timeout = {0, FD_UPDATE_TIMEOUT};          struct shm_du_buff * sdb; -        struct pci * pci; -        int fd; -        int i = 0; -        int ret; +        struct pci *         pci; +        int                  fd; +        int                  i = 0; +        int                  ret;          (void) o; @@ -202,6 +214,49 @@ 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; @@ -224,9 +279,6 @@ int fmgr_init()          for (i = 0; i < IPCPD_MAX_CONNS; ++i)                  fmgr.np1_cep_id_to_fd[i] = -1; -        pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL); -        pthread_rwlock_init(&fmgr.np1_flows_lock, NULL); -          for (i = 0; i < QOS_CUBE_MAX; ++i) {                  fmgr.np1_set[i] = flow_set_create();                  if (fmgr.np1_set[i] == NULL) { @@ -253,29 +305,55 @@ int fmgr_init()                  }          } +        fmgr.gam = gam_create(ribmgr_dt_gam(), DT_AE); +        if (fmgr.gam == NULL) { +                LOG_ERR("Failed to create graph adjacency manager."); +                fmgr_destroy_flows(); +                return -1; +        } + +        list_head_init(&fmgr.nm1_flows); + +        pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL); +        pthread_rwlock_init(&fmgr.np1_flows_lock, NULL); +          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;  }  int fmgr_fini()  { -        int i; -        int j; +        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); -        for (i = 0; i < AP_MAX_FLOWS; ++i) -                for (j = 0; j < QOS_CUBE_MAX; ++j) -                        if (flow_set_has(fmgr.nm1_set[j], i)) { -                                flow_dealloc(i); -                                flow_set_del(fmgr.nm1_set[j], i); -                        } +        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); +                free(flow); +        } + +        pthread_rwlock_unlock(&fmgr.nm1_flows_lock);          pthread_rwlock_destroy(&fmgr.nm1_flows_lock);          pthread_rwlock_destroy(&fmgr.np1_flows_lock); @@ -290,12 +368,12 @@ int fmgr_np1_alloc(int       fd,                     char *    src_ae_name,                     qoscube_t cube)  { -        cep_id_t cep_id; -        buffer_t buf; +        cep_id_t         cep_id; +        buffer_t         buf;          flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; -        char * path; -        uint8_t * ro_data; -        uint64_t addr; +        char *           path; +        uint8_t *        ro_data; +        uint64_t         addr;          path = pathname_create(RO_DIR);          if (path == NULL) @@ -359,9 +437,9 @@ int fmgr_np1_alloc(int       fd,  static int np1_flow_dealloc(int fd)  {          flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; -        buffer_t buf; -        int ret; -        qoscube_t cube; +        buffer_t         buf; +        int              ret; +        qoscube_t        cube;          ipcp_flow_get_qoscube(fd, &cube);          flow_set_del(fmgr.np1_set[cube], fd); @@ -388,10 +466,11 @@ static int np1_flow_dealloc(int fd)          return ret;  } -int fmgr_np1_alloc_resp(int fd, int response) +int fmgr_np1_alloc_resp(int fd, +                        int response)  {          flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT; -        buffer_t buf; +        buffer_t         buf;          msg.code = FLOW_ALLOC_CODE__FLOW_REPLY;          msg.response = response; @@ -443,7 +522,8 @@ int fmgr_np1_dealloc(int fd)          return ret;  } -int fmgr_np1_post_buf(cep_id_t cep_id, buffer_t * buf) +int fmgr_np1_post_buf(cep_id_t   cep_id, +                      buffer_t * buf)  {          int ret = 0;          int fd; @@ -512,7 +592,8 @@ int fmgr_np1_post_buf(cep_id_t cep_id, buffer_t * buf)          return ret;  } -int fmgr_np1_post_sdu(cep_id_t cep_id, struct shm_du_buff * sdb) +int fmgr_np1_post_sdu(cep_id_t             cep_id, +                      struct shm_du_buff * sdb)  {          int fd; @@ -530,52 +611,21 @@ int fmgr_np1_post_sdu(cep_id_t cep_id, struct shm_du_buff * sdb)          return 0;  } -/* FIXME: do this in a topologymanager instance */ -int fmgr_nm1_add_flow(int fd) +int fmgr_nm1_flow_arr(int       fd, +                      qosspec_t qs)  { -        qoscube_t qos; +        assert(fmgr.gam); -        if (flow_alloc_resp(fd, 0) < 0) { -                LOG_ERR("Could not respond to new flow."); +        if (gam_flow_arr(fmgr.gam, fd, qs)) { +                LOG_ERR("Failed to hand to graph adjacency manager.");                  return -1;          } -        ipcp_flow_get_qoscube(fd, &qos); -        flow_set_add(fmgr.nm1_set[qos], fd); - -        /* FIXME: Temporary, until we have a PFF */ -        fmgr.fd = fd; - -        return 0; -} - -int fmgr_nm1_dt_flow(char * dst_name, qoscube_t qos) -{ -        int fd; -        int result; - -        /* FIXME: Map qos cube on correct QoS. */ -        fd = flow_alloc(dst_name, DT_AE, NULL); -        if (fd < 0) { -                LOG_ERR("Failed to allocate flow to %s.", dst_name); -                return -1; -        } - -        result = flow_alloc_res(fd); -        if (result < 0) { -                LOG_ERR("Allocate flow to %s result %d.", dst_name, result); -                return -1; -        } - -        flow_set_add(fmgr.nm1_set[qos], fd); - -        /* FIXME: Temporary, until we have a PFF */ -        fmgr.fd = fd; -          return 0;  } -int fmgr_nm1_write_sdu(struct pci * pci, struct shm_du_buff * sdb) +int fmgr_nm1_write_sdu(struct pci *         pci, +                       struct shm_du_buff * sdb)  {          if (pci == NULL || sdb == NULL)                  return -1; @@ -595,7 +645,8 @@ int fmgr_nm1_write_sdu(struct pci * pci, struct shm_du_buff * sdb)          return 0;  } -int fmgr_nm1_write_buf(struct pci * pci, buffer_t * buf) +int fmgr_nm1_write_buf(struct pci * pci, +                       buffer_t *   buf)  {          buffer_t * buffer; diff --git a/src/ipcpd/normal/fmgr.h b/src/ipcpd/normal/fmgr.h index 85731081..ae5c8ea8 100644 --- a/src/ipcpd/normal/fmgr.h +++ b/src/ipcpd/normal/fmgr.h @@ -23,6 +23,7 @@  #define OUROBOROS_IPCPD_NORMAL_FMGR_H  #include <ouroboros/shared.h> +#include <ouroboros/qos.h>  #include "ae.h"  #include "frct.h" @@ -47,15 +48,14 @@ int fmgr_np1_post_buf(cep_id_t   id,  int fmgr_np1_post_sdu(cep_id_t             id,                        struct shm_du_buff * sdb); -int fmgr_nm1_add_flow(int fd); - -int fmgr_nm1_dt_flow(char *    dst_name, -                     qoscube_t qos); -  int fmgr_nm1_write_sdu(struct pci *         pci,                         struct shm_du_buff * sdb);  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/gam.c b/src/ipcpd/normal/gam.c new file mode 100644 index 00000000..0e626115 --- /dev/null +++ b/src/ipcpd/normal/gam.c @@ -0,0 +1,285 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph adjacency manager for IPC Process components + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.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-adjacency-manager" + +#include <ouroboros/config.h> +#include <ouroboros/dev.h> +#include <ouroboros/logs.h> +#include <ouroboros/list.h> +#include <ouroboros/errno.h> + +#include "ribmgr.h" +#include "ipcp.h" +#include "gam.h" +#include "pol-gam-ops.h" +#include "pol/complete.h" + +#include <assert.h> +#include <stdlib.h> +#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 gam * tmp; + +        tmp = malloc(sizeof(*tmp)); +        if (tmp == NULL) +                return NULL; + +        switch (gam_type) { +        case COMPLETE: +                tmp->ops = &complete_ops; +                break; +        default: +                free(tmp); +                return NULL; +        } + +        list_head_init(&tmp->gas); + +        tmp->ae_name = strdup(ae_name); +        if (tmp->ae_name == NULL) { +                free(tmp); +                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; +        } + +        return tmp; +} + +void gam_destroy(struct gam * instance) +{ +        struct list_head * p = NULL; +        struct list_head * n = NULL; + +        assert(instance); + +        instance->ops->destroy(instance->ops_o); + +        pthread_mutex_destroy(&instance->gas_lock); +        pthread_cond_destroy(&instance->gas_cond); + +        list_for_each_safe(p, n, &instance->gas) { +                struct ga * e = list_entry(p, struct ga, next); +                list_del(&e->next); +                free(e->info); +                free(e); +        } + +        free(instance->ae_name); +        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); + +        return 0; +} + +int gam_flow_arr(struct gam * instance, +                 int          fd, +                 qosspec_t    qs) +{ +        struct cacep *      cacep; +        struct cacep_info * 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 = cacep_create(fd, ipcpi.name, ribmgr_address()); +        if (cacep == NULL) { +                LOG_ERR("Failed to create CACEP instance."); +                return -1; +        } + +        info = cacep_auth_wait(cacep); +        if (info == NULL) { +                LOG_ERR("Other side failed to authenticate."); +                cacep_destroy(cacep); +                return -1; +        } + +        cacep_destroy(cacep); + +        if (instance->ops->accept_flow(instance->ops_o, qs, info)) { +                flow_dealloc(fd); +                free(info); +                return 0; +        } + +        if (add_ga(instance, fd, qs, info)) { +                LOG_ERR("Failed to add ga to graph adjacency manager list."); +                free(info); +                return -1; +        } + +        return 0; +} + +int gam_flow_alloc(struct gam * instance, +                   char *       dst_name, +                   qosspec_t    qs) +{ +        struct cacep *      cacep; +        struct cacep_info * info; +        int                 fd; + +        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 = cacep_create(fd, ipcpi.name, ribmgr_address()); +        if (cacep == NULL) { +                LOG_ERR("Failed to create CACEP instance."); +                return -1; +        } + +        info = cacep_auth(cacep); +        if (info == NULL) { +                LOG_ERR("Failed to authenticate."); +                cacep_destroy(cacep); +                return -1; +        } + +        cacep_destroy(cacep); + +        if (instance->ops->accept_flow(instance->ops_o, qs, info)) { +                flow_dealloc(fd); +                free(info); +                return 0; +        } + +        if (add_ga(instance, fd, qs, info)) { +                LOG_ERR("Failed to add GA to graph adjacency manager list."); +                free(info); +                return -1; +        } + +        return 0; +} + +int gam_flow_wait(struct gam *         instance, +                  int *                fd, +                  struct cacep_info ** info, +                  qosspec_t *          qs) +{ +        struct ga * ga; + +        assert(fd); +        assert(info); +        assert(qs); + +        pthread_mutex_lock(&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_mutex_unlock(&instance->gas_lock); + +        return 0; +} diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h new file mode 100644 index 00000000..e858114c --- /dev/null +++ b/src/ipcpd/normal/gam.h @@ -0,0 +1,46 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph adjacency manager for IPC Process components + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.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_GAM_H +#define OUROBOROS_IPCPD_NORMAL_GAM_H + +#include <ouroboros/cacep.h> + +struct gam * gam_create(enum pol_gam gam_type, +                        const char * ae_name); + +void         gam_destroy(struct gam * instance); + +int          gam_flow_arr(struct gam * instance, +                          int          fd, +                          qosspec_t    qs); + +int          gam_flow_alloc(struct gam * instance, +                            char *       dst_name, +                            qosspec_t    qs); + +int          gam_flow_wait(struct gam *         instance, +                           int *                fd, +                           struct cacep_info ** info, +                           qosspec_t *          qs); + +#endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 8db754aa..85f56ab0 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -26,6 +26,7 @@  #include <ouroboros/dev.h>  #include <ouroboros/ipcp-dev.h>  #include <ouroboros/time_utils.h> +#include <ouroboros/irm.h>  #include "fmgr.h"  #include "ribmgr.h" @@ -47,7 +48,9 @@ int irmd_api;  pthread_t acceptor; -void ipcp_sig_handler(int sig, siginfo_t * info, void * c) +void ipcp_sig_handler(int         sig, +                      siginfo_t * info, +                      void *      c)  {          (void) c; @@ -55,7 +58,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)          case SIGINT:          case SIGTERM:          case SIGHUP: -                if (info->si_pid == irmd_api) { +                if (info->si_pid == ipcpi.irmd_api) {                          pthread_rwlock_wrlock(&ipcpi.state_lock);                          if (ipcp_get_state() == IPCP_INIT) @@ -101,7 +104,7 @@ static void * flow_acceptor(void * o)                  if (strcmp(ae_name, MGMT_AE) == 0) {                          ribmgr_add_nm1_flow(fd);                  } else if (strcmp(ae_name, DT_AE) == 0) { -                        fmgr_nm1_add_flow(fd); +                        fmgr_nm1_flow_arr(fd, qs);                  } else {                          LOG_DBG("Flow allocation request for unknown AE %s.",                                  ae_name); @@ -195,12 +198,6 @@ static int normal_ipcp_enroll(char * dst_name)          pthread_rwlock_unlock(&ipcpi.state_lock); -        /* FIXME: Remove once we obtain neighbors during enrollment */ -        if (fmgr_nm1_dt_flow(dst_name, QOS_CUBE_BE)) { -                LOG_ERR("Failed to establish data transfer flow."); -                return -1; -        } -          LOG_DBG("Enrolled with %s.", dst_name);          return 0; @@ -296,10 +293,11 @@ static struct ipcp_ops normal_ops = {          .ipcp_flow_dealloc    = fmgr_np1_dealloc  }; -int main(int argc, char * argv[]) +int main(int    argc, +         char * argv[])  {          struct sigaction sig_act; -        sigset_t sigset; +        sigset_t         sigset;          if (ap_init(argv[0])) {                  LOG_ERR("Failed to init AP"); @@ -317,8 +315,11 @@ int main(int argc, char * argv[])                  exit(EXIT_FAILURE);          } -        /* store the process id of the irmd */ -        irmd_api = atoi(argv[1]); +        if (irm_bind_api(getpid(), ipcpi.name)) { +                LOG_ERR("Failed to bind AP name."); +                close_logfile(); +                exit(EXIT_FAILURE); +        }          /* init sig_act */          memset(&sig_act, 0, sizeof(sig_act)); diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h new file mode 100644 index 00000000..eeece8d9 --- /dev/null +++ b/src/ipcpd/normal/pol-gam-ops.h @@ -0,0 +1,40 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph adjacency manager policy ops + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H +#define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H + +#include <ouroboros/cacep.h> + +struct pol_gam_ops { +        void * (* create)(struct gam * instance); + +        void   (* destroy)(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 new file mode 100644 index 00000000..89e1b91f --- /dev/null +++ b/src/ipcpd/normal/pol/complete.c @@ -0,0 +1,208 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph adjacency manager for IPC Process components + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.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 "complete-graph-adjacency-manager" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/list.h> +#include <ouroboros/qos.h> + +#include "pathname.h" +#include "ro.h" +#include "ipcp.h" +#include "gam.h" + +#include <string.h> +#include <stdlib.h> + +#define RO_DIR "neighbors" + +struct neighbor { +        struct list_head next; +        char *           neighbor; +}; + +struct complete { +        struct list_head neighbors; +        pthread_mutex_t  neighbors_lock; + +        pthread_t        allocator; + +        struct gam *     gam; +}; + +static void * allocator(void * o) +{ +        qosspec_t         qs; +        ssize_t           len; +        char **           children; +        int               i; +        char *            ro_name; +        struct complete * complete = (struct complete *) o; + +        qs.delay = 0; +        qs.jitter = 0; + +        ro_name = pathname_create(RO_DIR); +        if (ro_name == NULL) +                return (void *) -1; + +        len = ro_children(ro_name, &children); +        if (len > 0) { +                for (i = 0; i < len; i++) { +                        if (strcmp(children[i], ipcpi.name) == 0) +                                continue; +                        gam_flow_alloc(complete->gam, children[i], qs); +                } +        } + +        pathname_destroy(ro_name); + +        return (void *) 0; +} + +void * complete_create(struct gam * gam) +{ +        struct ro_attr    attr; +        char *            ro_name; +        struct complete * complete; + +        ro_attr_init(&attr); +        attr.enrol_sync = true; +        attr.recv_set = ALL_MEMBERS; + +        complete = malloc(sizeof(*complete)); +        if (complete == NULL) +                return NULL; + +        ro_name = pathname_create(RO_DIR); +        if (ro_name == NULL) { +                free(complete); +                return NULL; +        } + +        if (!ro_exists(RO_DIR)) { +                if (ro_create(ro_name, &attr, NULL, 0)) { +                        free(complete); +                        pathname_destroy(ro_name); +                        return NULL; +                } +        } + +        ro_name = pathname_append(ro_name, ipcpi.name); +        if (ro_name == NULL) { +                free(complete); +                pathname_destroy(ro_name); +                return NULL; +        } + +        if (ro_create(ro_name, &attr, NULL, 0)) { +                free(complete); +                pathname_destroy(ro_name); +                return NULL; +        } +        pathname_destroy(ro_name); + +        list_head_init(&complete->neighbors); +        complete->gam = gam; + +        if (pthread_mutex_init(&complete->neighbors_lock, NULL)) { +                free(complete); +                return NULL; +        } + +        if (pthread_create(&complete->allocator, NULL, +                           allocator, (void *) complete)) { +                free(complete); +                pthread_mutex_destroy(&complete->neighbors_lock); +                return NULL; +        } + +        return (void *) complete; +} + +void complete_destroy(void * o) +{ +        struct list_head * p = NULL; +        struct list_head * n = NULL; +        struct complete * complete = (struct complete *) o; + +        pthread_cancel(complete->allocator); +        pthread_join(complete->allocator, NULL); + +        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); +        } +} + +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; + +        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; +                } +        } + +        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 new file mode 100644 index 00000000..8fcc87ba --- /dev/null +++ b/src/ipcpd/normal/pol/complete.h @@ -0,0 +1,46 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph adjacency manager for IPC Process components + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_POL_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); + +int    complete_accept_new_flow(void * o); + +int    complete_accept_flow(void *                    o, +                            qosspec_t                 qs, +                            const struct cacep_info * info); + +struct pol_gam_ops complete_ops = { +        .create          = complete_create, +        .destroy         = complete_destroy, +        .accept_new_flow = complete_accept_new_flow, +        .accept_flow     = complete_accept_flow +}; + +#endif /* OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H */ diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 6356d48c..993fe62a 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -139,6 +139,8 @@ struct {          struct addr_auth *  addr_auth;          enum pol_addr_auth  addr_auth_type; +        enum pol_gam        dt_gam_type; +          enum ribmgr_state   state;          pthread_cond_t      state_cond;          pthread_mutex_t     state_lock; @@ -168,6 +170,7 @@ void ribmgr_ro_created(const char * name,                  rib.dtc.min_pdu_size = stat_msg->min_pdu_size;                  rib.dtc.max_pdu_size = stat_msg->max_pdu_size;                  rib.addr_auth_type = stat_msg->addr_auth_type; +                rib.dt_gam_type = stat_msg->dt_gam_type;                  static_info_msg__free_unpacked(stat_msg, NULL);          } @@ -1262,6 +1265,7 @@ int ribmgr_bootstrap(struct dif_config * conf)          stat_info.min_pdu_size = rib.dtc.min_pdu_size = conf->min_pdu_size;          stat_info.max_pdu_size = rib.dtc.max_pdu_size = conf->max_pdu_size;          stat_info.addr_auth_type = rib.addr_auth_type = conf->addr_auth_type; +        stat_info.dt_gam_type = rib.dt_gam_type = conf->dt_gam_type;          len = static_info_msg__get_packed_size(&stat_info);          if (len == 0) { @@ -1354,16 +1358,21 @@ int ribmgr_start_policies(void)          return 0;  } -struct dt_const * ribmgr_dt_const() +struct dt_const * ribmgr_dt_const(void)  {          return &(rib.dtc);  } -uint64_t ribmgr_address() +uint64_t ribmgr_address(void)  {          return rib.address;  } +enum pol_gam ribmgr_dt_gam(void) +{ +        return rib.dt_gam_type; +} +  static int send_neighbors_ro(char * name, ro_msg_t * msg, enum cdap_opcode code)  {          struct list_head * p = NULL; @@ -1577,8 +1586,8 @@ ssize_t ro_children(const char * name, char *** children)          }          child = node->child; -        **children = malloc(len); -        if (**children == NULL) { +        *children = malloc(len); +        if (*children == NULL) {                  pthread_mutex_unlock(&rib.ro_lock);                  return -1;          } @@ -1590,7 +1599,7 @@ ssize_t ro_children(const char * name, char *** children)                                  free((*children)[i]);                                  i--;                          } -                        free(**children); +                        free(*children);                          pthread_mutex_unlock(&rib.ro_lock);                          return -1;                  } diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index ddc98e6e..22212de9 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -45,4 +45,6 @@ struct dt_const * ribmgr_dt_const(void);  uint64_t          ribmgr_address(void); +enum pol_gam      ribmgr_dt_gam(void); +  #endif /* OUROBOROS_IPCPD_NORMAL_RIBMGR_H */ diff --git a/src/ipcpd/normal/static_info.proto b/src/ipcpd/normal/static_info.proto index 18f02e36..bb6f8c4e 100644 --- a/src/ipcpd/normal/static_info.proto +++ b/src/ipcpd/normal/static_info.proto @@ -23,13 +23,14 @@  syntax = "proto2";  message static_info_msg { -        required uint32 addr_size       = 1; -        required uint32 cep_id_size     = 2; -        required uint32 pdu_length_size = 3; -        required uint32 seqno_size      = 4; -        required bool   has_ttl         = 5; -        required bool   has_chk         = 6; -        required uint32 min_pdu_size    = 7; -        required uint32 max_pdu_size    = 8; -        required uint32 addr_auth_type  = 9; +        required uint32 addr_size       =  1; +        required uint32 cep_id_size     =  2; +        required uint32 pdu_length_size =  3; +        required uint32 seqno_size      =  4; +        required bool   has_ttl         =  5; +        required bool   has_chk         =  6; +        required uint32 min_pdu_size    =  7; +        required uint32 max_pdu_size    =  8; +        required uint32 addr_auth_type  =  9; +        required uint32 dt_gam_type     = 10;  }
\ No newline at end of file diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index 0ff8007b..da496b07 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -77,9 +77,6 @@ typedef ShimEthLlcMsg shim_eth_llc_msg_t;  #define EVENT_WAIT_TIMEOUT 100 /* us */  #define NAME_QUERY_TIMEOUT 100000000 /* ns */ -/* global for trapping signal */ -int irmd_api; -  struct eth_llc_frame {          uint8_t dst_hwaddr[MAC_SIZE];          uint8_t src_hwaddr[MAC_SIZE]; @@ -675,7 +672,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)          case SIGINT:          case SIGTERM:          case SIGHUP: -                if (info->si_pid == irmd_api) { +                if (info->si_pid == ipcpi.irmd_api) {                          pthread_rwlock_wrlock(&ipcpi.state_lock);                          if (ipcp_get_state() == IPCP_INIT) @@ -1123,9 +1120,6 @@ int main(int argc, char * argv[])                  exit(EXIT_FAILURE);          } -        /* store the process id of the irmd */ -        irmd_api = atoi(argv[1]); -          /* init sig_act */          memset(&sig_act, 0, sizeof(sig_act)); diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 8c0c0aac..99aac40e 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -60,9 +60,6 @@ typedef ShimUdpMsg shim_udp_msg_t;  #define UDP_MAX_PORTS 0xFFFF -/* global for trapping signal */ -int irmd_api; -  struct uf {          int                udp;          int                skfd; @@ -529,7 +526,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)          case SIGINT:          case SIGTERM:          case SIGHUP: -                if (info->si_pid == irmd_api) { +                if (info->si_pid == ipcpi.irmd_api) {                          pthread_rwlock_wrlock(&ipcpi.state_lock);                          if (ipcp_get_state() == IPCP_INIT) @@ -1191,9 +1188,6 @@ int main(int argc, char * argv[])                  exit(EXIT_FAILURE);          } -        /* store the process id of the irmd */ -        irmd_api = atoi(argv[1]); -          /* init sig_act */          memset(&sig_act, 0, sizeof(sig_act)); diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index cad4dd88..f16587e1 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -100,7 +100,7 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t api, ipcp_msg_t * msg)         return recv_msg;  } -pid_t ipcp_create(enum ipcp_type ipcp_type) +pid_t ipcp_create(char * name, enum ipcp_type ipcp_type)  {          pid_t api = -1;          char irmd_api[10]; @@ -109,7 +109,7 @@ pid_t ipcp_create(enum ipcp_type ipcp_type)          char * full_name = NULL;          char * exec_name = NULL;          char * log_file = NULL; -        char * argv[4]; +        char * argv[5];          sprintf(irmd_api, "%u", getpid()); @@ -119,9 +119,8 @@ pid_t ipcp_create(enum ipcp_type ipcp_type)                  return api;          } -        if (api != 0) { +        if (api != 0)                  return api; -        }          if (ipcp_type == IPCP_NORMAL)                  exec_name = IPCP_NORMAL_EXEC; @@ -162,8 +161,9 @@ pid_t ipcp_create(enum ipcp_type ipcp_type)          /* log_file to be placed at the end */          argv[0] = full_name;          argv[1] = irmd_api; -        argv[2] = log_file; -        argv[3] = NULL; +        argv[2] = name; +        argv[3] = log_file; +        argv[4] = NULL;          execv(argv[0], &argv[0]); diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h index 429e0d5d..658aa2ea 100644 --- a/src/irmd/ipcp.h +++ b/src/irmd/ipcp.h @@ -28,8 +28,8 @@  #ifndef OUROBOROS_IPCP_H  #define OUROBOROS_IPCP_H -/* Returns the process id */ -pid_t ipcp_create(enum ipcp_type ipcp_type); +pid_t ipcp_create(char *         name, +                  enum ipcp_type ipcp_type);  int   ipcp_destroy(pid_t api); @@ -45,7 +45,7 @@ int   ipcp_name_reg(pid_t  api,  int   ipcp_name_unreg(pid_t  api,                        char * name); -int   ipcp_name_query(pid_t api, +int   ipcp_name_query(pid_t  api,                        char * name);  int   ipcp_flow_alloc(pid_t     api, diff --git a/src/irmd/main.c b/src/irmd/main.c index 9dc08cbe..435ee116 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -245,7 +245,7 @@ static pid_t create_ipcp(char * name, enum ipcp_type ipcp_type)          pthread_rwlock_wrlock(&irmd->reg_lock); -        api->pid = ipcp_create(ipcp_type); +        api->pid = ipcp_create(name, ipcp_type);          if (api->pid == -1) {                  pthread_rwlock_unlock(&irmd->reg_lock);                  pthread_rwlock_unlock(&irmd->state_lock); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index cdd8abb1..688cf6f5 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -8,8 +8,8 @@ protobuf_generate_c(IRM_PROTO_SRCS IRM_PROTO_HDRS irmd_messages.proto)  protobuf_generate_c(IPCP_PROTO_SRCS IPCP_PROTO_HDRS ipcpd_messages.proto)  protobuf_generate_c(DIF_CONFIG_PROTO_SRCS DIF_CONFIG_PROTO_HDRS    dif_config.proto) -protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS -  cdap.proto) +protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS cdap.proto) +protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)  if(NOT APPLE)    find_library(LIBRT_LIBRARIES rt) @@ -28,6 +28,7 @@ endif()  set(SOURCE_FILES    # Add source files here    bitmap.c +  cacep.c    cdap.c    cdap_req.c    dev.c @@ -46,9 +47,9 @@ set(SOURCE_FILES    utils.c    ) -add_library(ouroboros SHARED ${SOURCE_FILES} -  ${IRM_PROTO_SRCS} ${IPCP_PROTO_SRCS} -  ${DIF_CONFIG_PROTO_SRCS} ${CDAP_PROTO_SRCS}) +add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS} +  ${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} +  ${CDAP_PROTO_SRCS} ${CACEP_PROTO_SRCS})  target_link_libraries(ouroboros ${LIBRT_LIBRARIES}    ${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY}) diff --git a/src/lib/cacep.c b/src/lib/cacep.c new file mode 100644 index 00000000..22c6137f --- /dev/null +++ b/src/lib/cacep.c @@ -0,0 +1,170 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * The Common Application Connection Establishment Phase + * + *    Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <ouroboros/config.h> +#include <ouroboros/cacep.h> +#include <ouroboros/dev.h> +#include <ouroboros/errno.h> + +#include <stdlib.h> +#include <string.h> + +#include "cacep.pb-c.h" +typedef Cacep cacep_t; + +#define BUF_SIZE 2048 + +struct cacep { +        int      fd; +        char *   name; +        uint64_t address; +}; + +struct cacep * cacep_create(int          fd, +                            const char * name, +                            uint64_t     address) +{ +        struct cacep * tmp; + +        tmp = malloc(sizeof(*tmp)); +        if (tmp == NULL) +                return NULL; + +        tmp->fd = fd; +        tmp->address = address; +        tmp->name = strdup(name); +        if (tmp->name == NULL) { +                free(tmp); +                return NULL; +        } + +        return tmp; +} + +int cacep_destroy(struct cacep * instance) +{ +        if (instance == NULL) +                return 0; + +        free(instance); + +        return 0; +} + +static struct cacep_info * read_msg(struct cacep * instance) +{ +        struct cacep_info * tmp; +        uint8_t             buf[BUF_SIZE]; +        cacep_t *           msg; +        ssize_t             len; + +        len = flow_read(instance->fd, buf, BUF_SIZE); +        if (len < 0) +                return NULL; + +        msg = cacep__unpack(NULL, len, buf); +        if (msg == NULL) +                return NULL; + +        tmp = malloc(sizeof(*tmp)); +        if (tmp == NULL) { +                cacep__free_unpacked(msg, NULL); +                return NULL; +        } + +        tmp->addr = msg->address; +        tmp->name = strdup(msg->name); +        if (tmp->name == NULL) { +                free(tmp); +                cacep__free_unpacked(msg, NULL); +                return NULL; +        } + +        cacep__free_unpacked(msg, NULL); + +        return tmp; +} + +static int send_msg(struct cacep * instance) +{ +        cacep_t   msg = CACEP__INIT; +        int       ret = 0; +        uint8_t * data = NULL; +        size_t    len = 0; + +        msg.name = instance->name; +        msg.address = instance->address; + +        len = cacep__get_packed_size(&msg); +        if (len == 0) +                return -1; + +        data = malloc(len); +        if (data == NULL) +                return -ENOMEM; + +        cacep__pack(&msg, data); + +        if (flow_write(instance->fd, data, len) < 0) +                ret = -1; + +        free(data); + +        return ret; +} + +struct cacep_info * cacep_auth(struct cacep * instance) +{ +        struct cacep_info * tmp; + +        if (instance == NULL) +                return NULL; + +        if (send_msg(instance)) +                return NULL; + +        tmp = read_msg(instance); +        if (tmp == NULL) +                return NULL; + +        return tmp; +} + +struct cacep_info * cacep_auth_wait(struct cacep * instance) +{ +        struct cacep_info * tmp; + +        if (instance == NULL) +                return NULL; + +        tmp = read_msg(instance); +        if (tmp == NULL) +                return NULL; + +        if (send_msg(instance)) { +                free(tmp->name); +                free(tmp); +                return NULL; +        } + +        return tmp; +} diff --git a/src/lib/cacep.proto b/src/lib/cacep.proto new file mode 100644 index 00000000..603b095d --- /dev/null +++ b/src/lib/cacep.proto @@ -0,0 +1,29 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * CACEP message + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +syntax = "proto2"; + +message cacep { +        required string name    = 1; +        required uint64 address = 2; +} diff --git a/src/lib/dif_config.proto b/src/lib/dif_config.proto index 8a1d329e..f1f8747b 100644 --- a/src/lib/dif_config.proto +++ b/src/lib/dif_config.proto @@ -37,9 +37,10 @@ message dif_config_msg {          optional uint32 min_pdu_size    = 10;          optional uint32 max_pdu_size    = 11;          optional uint32 addr_auth_type  = 12; +        optional uint32 dt_gam_type     = 13;          // Config for shim UDP -        optional uint32 ip_addr         = 13; -        optional uint32 dns_addr        = 14; +        optional uint32 ip_addr         = 14; +        optional uint32 dns_addr        = 15;          // Config for the shim Ethernet LLC -        optional string if_name         = 15; +        optional string if_name         = 16;  }
\ No newline at end of file diff --git a/src/lib/irm.c b/src/lib/irm.c index 635c8f9b..ade38b6f 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -120,6 +120,7 @@ int irm_bootstrap_ipcp(pid_t               api,                  config.has_min_pdu_size = true;                  config.has_max_pdu_size = true;                  config.has_addr_auth_type = true; +                config.has_dt_gam_type = true;                  config.addr_size = conf->addr_size;                  config.cep_id_size = conf->cep_id_size; @@ -131,6 +132,7 @@ int irm_bootstrap_ipcp(pid_t               api,                  config.min_pdu_size = conf->min_pdu_size;                  config.max_pdu_size = conf->max_pdu_size;                  config.addr_auth_type = conf->addr_auth_type; +                config.dt_gam_type = conf->dt_gam_type;                  break;          case IPCP_SHIM_UDP:                  config.has_ip_addr = true; diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 8fd2fb73..4c7f2168 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -45,8 +45,10 @@  #define DEFAULT_MAX_PDU_SIZE 9000  #define DEFAULT_DDNS 0  #define DEFAULT_ADDR_AUTH FLAT_RANDOM +#define DEFAULT_DT_GAM COMPLETE -#define ADDR_AUTH_FLAT "flat" +#define ADDR_AUTH_FLAT  "flat" +#define DT_GAM_COMPLETE "complete"  static void usage(void)  { @@ -67,6 +69,8 @@ static void usage(void)                 "                [min_pdu <minimum PDU size> (default: %d)]\n"                 "                [max_pdu <maximum PDU size> (default: %d)]\n"                 "                [addr_auth <address policy> (default: %s)]\n" +               "                [dt_gam <data transfer graph adjacency manager>" +               "(default: %s)]\n"                 "if TYPE == " SHIM_UDP "\n"                 "                ip <IP address in dotted notation>\n"                 "                [dns <DDNS IP address in dotted notation>" @@ -76,7 +80,7 @@ static void usage(void)                 DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE,                 DEFAULT_PDU_LEN_SIZE, DEFAULT_SEQ_NO_SIZE,                 DEFAULT_MIN_PDU_SIZE, DEFAULT_MAX_PDU_SIZE, -               ADDR_AUTH_FLAT, DEFAULT_DDNS); +               ADDR_AUTH_FLAT, DT_GAM_COMPLETE, DEFAULT_DDNS);  }  int do_bootstrap_ipcp(int argc, char ** argv) @@ -93,6 +97,7 @@ int do_bootstrap_ipcp(int argc, char ** argv)          uint32_t min_pdu_size = DEFAULT_MIN_PDU_SIZE;          uint32_t max_pdu_size = DEFAULT_MAX_PDU_SIZE;          enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH; +        enum pol_gam dt_gam_type = DEFAULT_DT_GAM;          uint32_t ip_addr = 0;          uint32_t dns_addr = DEFAULT_DDNS;          char * ipcp_type = NULL; @@ -144,6 +149,9 @@ int do_bootstrap_ipcp(int argc, char ** argv)                  } else if (matches(*argv, "addr_auth") == 0) {                          if (strcmp(ADDR_AUTH_FLAT, *(argv + 1)) == 0)                                  addr_auth_type = FLAT_RANDOM; +                } else if (matches(*argv, "dt_gam") == 0) { +                        if (strcmp(DT_GAM_COMPLETE, *(argv + 1)) == 0) +                                dt_gam_type = COMPLETE;                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcp bootstrap\".\n", *argv); @@ -172,6 +180,7 @@ int do_bootstrap_ipcp(int argc, char ** argv)                  conf.min_pdu_size = min_pdu_size;                  conf.max_pdu_size = max_pdu_size;                  conf.addr_auth_type = addr_auth_type; +                conf.dt_gam_type = dt_gam_type;          } else if (strcmp(ipcp_type, SHIM_UDP) == 0) {                  conf.type = IPCP_SHIM_UDP;                  if (ip_addr == 0) { @@ -199,8 +208,6 @@ int do_bootstrap_ipcp(int argc, char ** argv)                  api = irm_create_ipcp(name, conf.type);                  if (api == 0)                          return -1; -                if (conf.type == IPCP_NORMAL) -                        irm_bind_api(api, name);                  len = irm_list_ipcps(name, &apis);          } diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c index 9f636f34..e8ed1186 100644 --- a/src/tools/irm/irm_ipcp_create.c +++ b/src/tools/irm/irm_ipcp_create.c @@ -85,8 +85,5 @@ int do_create_ipcp(int argc, char ** argv)          if (api == 0)                  return -1; -        if (type == IPCP_NORMAL) -                irm_bind_api(api, ipcp_name); -          return 0;  } diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c index f7807f42..3731fa81 100644 --- a/src/tools/irm/irm_ipcp_enroll.c +++ b/src/tools/irm/irm_ipcp_enroll.c @@ -68,7 +68,6 @@ int do_enroll_ipcp(int argc, char ** argv)                  api = irm_create_ipcp(name, IPCP_NORMAL);                  if (api == 0)                          return -1; -                irm_bind_api(api, name);                  len = irm_list_ipcps(name, &apis);          } | 
