summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal/pol
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/normal/pol')
-rw-r--r--src/ipcpd/normal/pol/complete.c103
-rw-r--r--src/ipcpd/normal/pol/complete.h6
-rw-r--r--src/ipcpd/normal/pol/flat.c292
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;
}