diff options
author | dimitri staessens <[email protected]> | 2017-02-06 16:05:44 +0100 |
---|---|---|
committer | dimitri staessens <[email protected]> | 2017-02-06 20:04:34 +0100 |
commit | 373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7 (patch) | |
tree | 8711a4edbc2a6defaab63f0dcc2b0690252307b4 /src/ipcpd/normal/pol | |
parent | 4b11f952c521315883f64571e1790389e8d20f64 (diff) | |
download | ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.tar.gz ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.zip |
ipcpd, lib: Revise normal IPCP
This PR updates the normal IPCP to use the new RIB. The old ribmgr is
removed and replaced by a stub that needs to be implemented. All
components (dir, fmgr, frct) were adapted to the new RIB API. A lot
of functionality was moved outside of the ribmgr, such as the
addr_auth, which is now a component of the IPCP. The address is also
stored to the ipcpi struct. The irm tool has an option to set the gam
policy of the rib manager.
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 <[email protected]> + * Sander Vrijders <[email protected]> + * Dimitri Staessens <[email protected]> * * 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; } |