diff options
Diffstat (limited to 'src/ipcpd/normal/pol')
| -rw-r--r-- | src/ipcpd/normal/pol/complete.c | 103 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/complete.h | 6 | ||||
| -rw-r--r-- | src/ipcpd/normal/pol/flat.c | 292 | 
3 files changed, 141 insertions, 260 deletions
| diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c index 89e1b91f..f85fd749 100644 --- a/src/ipcpd/normal/pol/complete.c +++ b/src/ipcpd/normal/pol/complete.c @@ -26,16 +26,14 @@  #include <ouroboros/logs.h>  #include <ouroboros/list.h>  #include <ouroboros/qos.h> +#include <ouroboros/rib.h> -#include "pathname.h" -#include "ro.h"  #include "ipcp.h"  #include "gam.h"  #include <string.h>  #include <stdlib.h> - -#define RO_DIR "neighbors" +#include <assert.h>  struct neighbor {          struct list_head next; @@ -56,73 +54,39 @@ static void * allocator(void * o)          qosspec_t         qs;          ssize_t           len;          char **           children; -        int               i; -        char *            ro_name; +        ssize_t           i;          struct complete * complete = (struct complete *) o; +        assert(complete); +        assert(complete->gam); +          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; +        /* 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); -                } +                free(children[i]);          } -        pathname_destroy(ro_name); +        if (len > 0) +                free(children);          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; +        assert(gam);          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; @@ -131,14 +95,34 @@ void * complete_create(struct gam * gam)                  return NULL;          } +        return (void *) complete; +} + +int complete_start(void * o) +{ +        struct complete * complete = (struct complete *) o; + +        assert(complete); +        assert(complete->gam); +          if (pthread_create(&complete->allocator, NULL,                             allocator, (void *) complete)) { -                free(complete);                  pthread_mutex_destroy(&complete->neighbors_lock); -                return NULL; +                free(complete); +                return -1;          } -        return (void *) complete; +        /* FIXME: Handle flooding of the flow allocator before detaching.*/ +        pthread_join(complete->allocator, NULL); + +        return 0; +} + +int complete_stop(void * o) +{ +        (void) o; + +        return 0;  }  void complete_destroy(void * o) @@ -147,15 +131,16 @@ void complete_destroy(void * o)          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);          } + +        pthread_mutex_destroy(&complete->neighbors_lock); + +        free(complete);  }  int complete_accept_new_flow(void * o) @@ -175,6 +160,8 @@ int complete_accept_flow(void *                    o,          (void) qs; +        assert(complete); +          pthread_mutex_lock(&complete->neighbors_lock);          list_for_each(pos, &complete->neighbors) { @@ -183,6 +170,10 @@ int complete_accept_flow(void *                    o,                          pthread_mutex_unlock(&complete->neighbors_lock);                          return -1;                  } + +                assert(complete); +                assert(&complete->neighbors_lock); +                assert(pos->nxt);          }          n = malloc(sizeof(*n)); diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h index 8fcc87ba..3f08c2e5 100644 --- a/src/ipcpd/normal/pol/complete.h +++ b/src/ipcpd/normal/pol/complete.h @@ -30,6 +30,10 @@ void * complete_create(struct gam * instance);  void   complete_destroy(void * o); +int    complete_start(void * o); + +int    complete_stop(void * o); +  int    complete_accept_new_flow(void * o);  int    complete_accept_flow(void *                    o, @@ -39,6 +43,8 @@ int    complete_accept_flow(void *                    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  }; diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index abcb1ad4..31fcd4e8 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -3,7 +3,8 @@   *   * Policy for flat addresses in a distributed way   * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + *    Dimitri Staessens <dimitri.staessens@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 @@ -25,11 +26,9 @@  #include <ouroboros/logs.h>  #include <ouroboros/errno.h>  #include <ouroboros/time_utils.h> +#include <ouroboros/rib.h> -#include "shm_pci.h" -#include "ribmgr.h" -#include "ro.h" -#include "pathname.h" +#include "ipcp.h"  #include <time.h>  #include <stdlib.h> @@ -37,235 +36,120 @@  #include <string.h>  #include <assert.h> -#define POL_RO_ROOT "flat_addr" +#define NAME_LEN 8 +#define REC_DIF_SIZE 10000 -#define TIMEOUT  100 /* ms */ -#define STR_SIZE 100 - -#define FLAT_ADDR_REQ   0 -#define FLAT_ADDR_REPLY 1 - -struct flat_addr_msg { -        uint8_t  code; -        uint64_t addr; -}; - -struct { -        int      sid; -        uint64_t addr; -        bool     addr_in_use; - -        pthread_cond_t  cond; -        pthread_mutex_t lock; -} flat; - -static char * addr_name(void) +/* convert 32 bit addr to a hex string */ +static void addr_name(char *   name, +                      uint32_t addr)  { -        char * name; -        /* uint64_t as a string has 25 chars */ -        char   addr_name[30]; - -        sprintf(addr_name, "%lu", (unsigned long) flat.addr); - -        name = pathname_create(POL_RO_ROOT); -        if (name == NULL) -                return NULL; - -        name = pathname_append(name, addr_name); -        return name; +        sprintf(name, "%8x", (uint32_t) (addr));  } -static void ro_created(const char * name, -                       uint8_t *    data, -                       size_t       len) +#define freepp(type, ptr, len)                          \ +        do {                                            \ +                if (len == 0)                           \ +                        break;                          \ +                while (len > 0)                         \ +                        free(((type **) ptr)[--len]);   \ +                free(ptr);                              \ +        } while (0); + +static int addr_taken(char *  name, +                      char ** members, +                      size_t  len)  { -        struct flat_addr_msg * msg; - -        assert(name); -        assert(data); -        assert(len >= sizeof(*msg)); - -        msg = (struct flat_addr_msg *) data; -        if (msg->code == FLAT_ADDR_REQ && msg->addr == flat.addr) { -                msg->code = FLAT_ADDR_REPLY; -                ro_write(name, data, len); +        size_t i; +        char path[RIB_MAX_PATH_LEN + 1]; + +        size_t reset; +        strcpy(path, "/" MEMBERS_NAME); + +        reset = strlen(path); + +        for (i = 0; i < len; ++i) { +                ssize_t j; +                ssize_t c; +                char ** addrs; +                rib_path_append(path, members[i]); +                c = rib_children(path, &addrs); +                for (j = 0; j < c; ++j) +                        if (strcmp(addrs[j], name) == 0) { +                                freepp(char, addrs, c); +                                return 1; +                        } +                freepp(char, addrs, c); +                path[reset] = '\0';          } -} -static void ro_updated(const char * name, -                       uint8_t *    data, -                       size_t       len) -{ -        struct flat_addr_msg * msg; -        char * ro_name; - -        assert(name); -        assert(data); -        assert(len >= sizeof(*msg)); -        (void) len; - -        ro_name = addr_name(); -        if (ro_name == NULL) { -                free(data); -                return; -        } - -        msg = (struct flat_addr_msg *) data; -        if (msg->code == FLAT_ADDR_REPLY && -            strcmp(name, ro_name) == 0) { -                pthread_mutex_lock(&flat.lock); -                flat.addr_in_use = true; -                pthread_cond_broadcast(&flat.cond); -                pthread_mutex_unlock(&flat.lock); -        } - -        free(data); -        free(ro_name); +        return 0;  } -static struct ro_sub_ops flat_sub_ops = { -        .ro_created = ro_created, -        .ro_updated = ro_updated, -        .ro_deleted = NULL -}; +#define INVALID_ADDRESS 0 -int flat_init(void) +uint64_t flat_address(void)  { -        struct ro_attr     rattr; -        pthread_condattr_t cattr; -        struct timespec    t; -        char *             name; +        struct timespec t; -        clock_gettime(CLOCK_REALTIME, &t); +        char path[RIB_MAX_PATH_LEN]; +        char name[NAME_LEN + 1]; +        uint32_t addr; +        uint8_t addr_size; -        srand(t.tv_nsec); -        flat.addr_in_use = false; +        char ** members; +        ssize_t n_members; -        ro_attr_init(&rattr); -        pthread_mutex_init(&flat.lock, NULL); -        pthread_condattr_init(&cattr); -#ifndef __APPLE__ -        pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); -#endif -        pthread_cond_init(&flat.cond, &cattr); +        strcpy(path, "/" MEMBERS_NAME); -        flat.sid = ro_subscribe(POL_RO_ROOT, &flat_sub_ops); -        if (flat.sid < 0) { -                LOG_ERR("Could not subscribe to RIB."); -                pthread_cond_destroy(&flat.cond); -                pthread_mutex_destroy(&flat.lock); -                return -1; +        if (!rib_has(path)) { +                LOG_ERR("Could not read members from RIB."); +                return INVALID_ADDRESS;          } -        name = pathname_create(POL_RO_ROOT); -        if (name == NULL) { -                pthread_cond_destroy(&flat.cond); -                pthread_mutex_destroy(&flat.lock); -                ro_unsubscribe(flat.sid); -                return -1; +        if (rib_read("/" BOOT_NAME "/dt/const/addr_size", +                     &addr_size, sizeof(addr_size)) != sizeof(addr_size)) { +                LOG_ERR("Failed to read address size."); +                return INVALID_ADDRESS;          } -        if (!ro_exists(name)) { -                rattr.enrol_sync = true; -                if (ro_create(name, &rattr, NULL, 0)) { -                        LOG_ERR("Could not create RO."); -                        pathname_destroy(name); -                        pthread_cond_destroy(&flat.cond); -                        pthread_mutex_destroy(&flat.lock); -                        ro_unsubscribe(flat.sid); -                        return -1; -                } +        if (addr_size != 4) { +                LOG_ERR("Flat address policy mandates 4 byte addresses."); +                return INVALID_ADDRESS;          } -        pathname_destroy(name); - -        return 0; -} - -int flat_fini(void) -{ -        pthread_cond_destroy(&flat.cond); -        pthread_mutex_destroy(&flat.lock); -        ro_unsubscribe(flat.sid); -        return 0; -} -uint64_t flat_address(void) -{ -        int                    ret = 0; -        uint64_t               max_addr; -        struct dt_const *      dtc; -        struct timespec        timeout = {(TIMEOUT / 1000), -                                          (TIMEOUT % 1000) * MILLION}; -        struct timespec        abstime; -        struct ro_attr         attr; -        struct flat_addr_msg * msg; -        uint8_t *              buf; -        char *                 ro_name; +        n_members = rib_children(path, &members); +        if (n_members > REC_DIF_SIZE) +                LOG_WARN("DIF exceeding recommended size for flat addresses."); -        dtc = ribmgr_dt_const(); -        if (dtc == NULL) -                return INVALID_ADDR; +        rib_path_append(path, ipcpi.name); -        if (dtc->addr_size == 8) { -                LOG_ERR("Policy cannot be used with 64 bit addresses."); -                return INVALID_ADDR; +        if (!rib_has(path)) { +                LOG_ERR("This ipcp is not a member."); +                freepp(char, members, n_members); +                return INVALID_ADDRESS;          } -        while (ret != -ETIMEDOUT) { -                clock_gettime(PTHREAD_COND_CLOCK, &abstime); -                ts_add(&abstime, &timeout, &abstime); - -                max_addr = (1 << (8 * dtc->addr_size)) - 1; -                flat.addr = (rand() % (max_addr - 1)) + 1; - -                ro_attr_init(&attr); -                attr.recv_set = ALL_MEMBERS; -                attr.expiry.tv_sec = TIMEOUT / 1000; -                attr.expiry.tv_nsec = (TIMEOUT % 1000) * MILLION; - -                buf = malloc(sizeof(*msg)); -                if (buf == NULL) -                        return INVALID_ADDR; - -                msg = (struct flat_addr_msg *) buf; -                msg->code = FLAT_ADDR_REQ; -                msg->addr = flat.addr; - -                ro_name = addr_name(); -                if (ro_name == NULL) { -                        free(buf); -                        return INVALID_ADDR; -                } - -                pthread_mutex_lock(&flat.lock); - -                if (ro_exists(ro_name)) { -                        pthread_mutex_unlock(&flat.lock); -                        free(ro_name); -                        free(buf); -                        continue; -                } +        clock_gettime(CLOCK_REALTIME, &t); +        srand(t.tv_nsec); +        assert(n_members > 0); -                if (ro_create(ro_name, &attr, buf, sizeof(*msg))) { -                        pthread_mutex_unlock(&flat.lock); -                        free(ro_name); -                        free(buf); -                        return INVALID_ADDR; -                } +        do { +                addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF; +                addr_name(name, addr); +        } while (addr_taken(name, members, n_members)); -                free(ro_name); +        freepp(char, members, n_members); -                while (flat.addr_in_use == false) { -                        ret = -pthread_cond_timedwait(&flat.cond, -                                                      &flat.lock, -                                                      &abstime); -                        if (ret == -ETIMEDOUT) -                                break; -                } +        if (rib_add(path, name)) { +                LOG_ERR("Failed to add address to RIB."); +                return INVALID_ADDRESS; +        } -                pthread_mutex_unlock(&flat.lock); +        if (rib_write(path, &addr, sizeof(addr))) { +                LOG_ERR("Failed to write address in RIB."); +                return INVALID_ADDRESS;          } -        return flat.addr; +        return addr;  } | 
