diff options
| author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2017-01-11 18:59:11 +0100 | 
|---|---|---|
| committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2017-01-12 13:40:38 +0100 | 
| commit | 15e9b779385c71d366776b83540e19e0735c4e66 (patch) | |
| tree | 5f4fe39683c0676c243f287840f2775a867c9142 /src/ipcpd | |
| parent | a991831b5373eba38d6f756d254f151b22790238 (diff) | |
| download | ouroboros-15e9b779385c71d366776b83540e19e0735c4e66.tar.gz ouroboros-15e9b779385c71d366776b83540e19e0735c4e66.zip | |
ipcpd: normal: Create policies for GAM
This allows the selection of a policy for the graph adjacency
manager. Currently we only support constructing a complete graph.
Diffstat (limited to 'src/ipcpd')
| -rw-r--r-- | src/ipcpd/ipcp.c | 1 | ||||
| -rw-r--r-- | src/ipcpd/normal/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/ipcpd/normal/fmgr.c | 4 | ||||
| -rw-r--r-- | src/ipcpd/normal/gam.c | 136 | ||||
| -rw-r--r-- | src/ipcpd/normal/gam.h | 8 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol-gam-ops.h | 40 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/complete.c | 208 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/complete.h | 46 | ||||
| -rw-r--r-- | src/ipcpd/normal/ribmgr.c | 13 | ||||
| -rw-r--r-- | src/ipcpd/normal/ribmgr.h | 2 | ||||
| -rw-r--r-- | src/ipcpd/normal/static_info.proto | 19 | 
11 files changed, 367 insertions, 111 deletions
| diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 96f00dc0..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; diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 43059c3e..157baa9e 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCE_FILES    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 33ac83c9..6fe6fb60 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -305,7 +305,7 @@ int fmgr_init()                  }          } -        fmgr.gam = gam_create(DT_AE); +        fmgr.gam = gam_create(ribmgr_dt_gam(), DT_AE);          if (fmgr.gam == NULL) {                  LOG_ERR("Failed to create graph adjacency manager.");                  fmgr_destroy_flows(); @@ -617,7 +617,7 @@ int fmgr_nm1_flow_arr(int       fd,          assert(fmgr.gam);          if (gam_flow_arr(fmgr.gam, fd, qs)) { -                LOG_ERR("Failed to hand to connectivy manager."); +                LOG_ERR("Failed to hand to graph adjacency manager.");                  return -1;          } diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c index 34db87e3..0e626115 100644 --- a/src/ipcpd/normal/gam.c +++ b/src/ipcpd/normal/gam.c @@ -3,7 +3,7 @@   *   * Graph adjacency manager for IPC Process components   * - *    Dimitri Staeesens <dimitri.staessens@intec.ugent.be> + *    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 @@ -25,23 +25,20 @@  #include <ouroboros/config.h>  #include <ouroboros/dev.h>  #include <ouroboros/logs.h> -#include <ouroboros/cacep.h>  #include <ouroboros/list.h>  #include <ouroboros/errno.h>  #include "ribmgr.h"  #include "ipcp.h" -#include "ro.h" -#include "pathname.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> -#define RO_DIR "neighbors" -  struct ga {          struct list_head    next; @@ -51,59 +48,34 @@ struct ga {  };  struct gam { -        struct list_head gas; -        pthread_mutex_t  gas_lock; -        pthread_cond_t   gas_cond; - -        char *           ae_name; +        struct list_head     gas; +        pthread_mutex_t      gas_lock; +        pthread_cond_t       gas_cond; -        /* FIXME: Keep a list of known members */ +        char *               ae_name; -        pthread_t        allocator; +        struct pol_gam_ops * ops; +        void *               ops_o;  }; -static void * allocator(void * o) +struct gam * gam_create(enum pol_gam gam_type, +                        const char * ae_name)  { -        qosspec_t    qs; -        ssize_t      len; -        char **      children; -        struct gam * instance; -        int          i; -        char *       ro_name; - -        instance = (struct gam *) 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(instance, children[i], qs); -                } -        } - -        pathname_destroy(ro_name); - -        return (void *) 0; -} - -struct gam * gam_create(char * ae_name) -{ -        struct gam *   tmp; -        struct ro_attr attr; -        char *         ro_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); @@ -125,47 +97,8 @@ struct gam * gam_create(char * ae_name)                  return NULL;          } -        ro_attr_init(&attr); -        attr.enrol_sync = true; -        attr.recv_set = ALL_MEMBERS; - -        ro_name = pathname_create(RO_DIR); -        if (ro_name == NULL) { -                pthread_mutex_destroy(&tmp->gas_lock); -                free(tmp->ae_name); -                free(tmp); -                return NULL; -        } - -        if (!ro_exists(RO_DIR)) { -                if (ro_create(ro_name, &attr, NULL, 0)) { -                        pathname_destroy(ro_name); -                        pthread_mutex_destroy(&tmp->gas_lock); -                        free(tmp->ae_name); -                        free(tmp); -                        return NULL; -                } -        } - -        ro_name = pathname_append(ro_name, ipcpi.name); -        if (ro_name == NULL) { -                pathname_destroy(ro_name); -                pthread_mutex_destroy(&tmp->gas_lock); -                free(tmp->ae_name); -                free(tmp); -                return NULL; -        } - -        if (ro_create(ro_name, &attr, NULL, 0)) { -                pathname_destroy(ro_name); -                pthread_mutex_destroy(&tmp->gas_lock); -                free(tmp->ae_name); -                free(tmp); -                return NULL; -        } -        pathname_destroy(ro_name); - -        if (pthread_create(&tmp->allocator, NULL, allocator, (void *) tmp)) { +        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); @@ -183,8 +116,7 @@ void gam_destroy(struct gam * instance)          assert(instance); -        pthread_cancel(instance->allocator); -        pthread_join(instance->allocator, NULL); +        instance->ops->destroy(instance->ops_o);          pthread_mutex_destroy(&instance->gas_lock);          pthread_cond_destroy(&instance->gas_cond); @@ -232,7 +164,8 @@ int gam_flow_arr(struct gam * instance,          struct cacep *      cacep;          struct cacep_info * info; -        if (flow_alloc_resp(fd, 0) < 0) { +        if (flow_alloc_resp(fd, instance->ops->accept_new_flow(instance->ops_o)) +            < 0) {                  LOG_ERR("Could not respond to new flow.");                  return -1;          } @@ -249,8 +182,15 @@ int gam_flow_arr(struct gam * instance,                  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); @@ -292,10 +232,17 @@ int gam_flow_alloc(struct gam * instance,                  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."); +                LOG_ERR("Failed to add GA to graph adjacency manager list.");                  free(info);                  return -1;          } @@ -322,7 +269,6 @@ int gam_flow_wait(struct gam *         instance,          ga = list_first_entry((&instance->gas), struct ga, next);          if (ga == NULL) {                  pthread_mutex_unlock(&instance->gas_lock); -                LOG_ERR("Ga was NULL.");                  return -1;          } diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h index 309cb46d..e858114c 100644 --- a/src/ipcpd/normal/gam.h +++ b/src/ipcpd/normal/gam.h @@ -23,8 +23,10 @@  #ifndef OUROBOROS_IPCPD_NORMAL_GAM_H  #define OUROBOROS_IPCPD_NORMAL_GAM_H -/* FIXME: Will take a policy */ -struct gam * gam_create(char * ae_name); +#include <ouroboros/cacep.h> + +struct gam * gam_create(enum pol_gam gam_type, +                        const char * ae_name);  void         gam_destroy(struct gam * instance); @@ -41,4 +43,4 @@ int          gam_flow_wait(struct gam *         instance,                             struct cacep_info ** info,                             qosspec_t *          qs); -#endif +#endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */ 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 c780bf50..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; 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 | 
