summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal/pol/flat.c
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@intec.ugent.be>2017-02-06 16:05:44 +0100
committerdimitri staessens <dimitri.staessens@intec.ugent.be>2017-02-06 20:04:34 +0100
commit373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7 (patch)
tree8711a4edbc2a6defaab63f0dcc2b0690252307b4 /src/ipcpd/normal/pol/flat.c
parent4b11f952c521315883f64571e1790389e8d20f64 (diff)
downloadouroboros-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/flat.c')
-rw-r--r--src/ipcpd/normal/pol/flat.c292
1 files changed, 88 insertions, 204 deletions
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;
}