summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <[email protected]>2018-02-19 23:46:34 +0100
committerSander Vrijders <[email protected]>2018-02-20 08:49:34 +0100
commite72fcd924b25b2b3b8a45c85d9c3d09388885249 (patch)
treee5ab66df04cedd1845dfa624a0ab97366c290325
parent91012d9af758a48c4c57fc940dfcc8a581fa46ac (diff)
downloadouroboros-e72fcd924b25b2b3b8a45c85d9c3d09388885249.tar.gz
ouroboros-e72fcd924b25b2b3b8a45c85d9c3d09388885249.zip
lib: Get RIB attributes from component
This revises the RIB so it gets the complete file attribute list from the component instead of setting some attributes in the library. This will allow setting read/write access later on in the component itself. The time of last change of lsdb entries in the file system is now set to the time of the last received Link State Update for that entry. Signed-off-by: Dimitri Staessens <[email protected]> Signed-off-by: Sander Vrijders <[email protected]>
-rw-r--r--include/ouroboros/rib.h5
-rw-r--r--src/ipcpd/normal/pol/link_state.c109
-rw-r--r--src/lib/rib.c70
3 files changed, 132 insertions, 52 deletions
diff --git a/include/ouroboros/rib.h b/include/ouroboros/rib.h
index fda36ead..5a3d66dc 100644
--- a/include/ouroboros/rib.h
+++ b/include/ouroboros/rib.h
@@ -25,6 +25,9 @@
#define RIB_PATH_LEN 128
+#include <sys/stat.h>
+#include <sys/types.h>
+
struct rib;
struct rib_ops {
@@ -32,6 +35,8 @@ struct rib_ops {
char * buf,
size_t len);
int (* readdir)(char *** entries);
+ int (* getattr)(const char * path,
+ struct stat * st);
};
int rib_init(const char * prefix);
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index 520e2952..179a3448 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -52,6 +52,7 @@
#define RECALC_TIME 4
#define LS_UPDATE_TIME 15
#define LS_TIMEO 60
+#define LS_ENTRY_SIZE 78
#define LSDB "lsdb"
#ifndef CLOCK_REALTIME_COARSE
@@ -131,51 +132,96 @@ static int str_adj(struct adjacency * adj,
size_t len)
{
char tmbuf[64];
+ char srcbuf[64];
+ char dstbuf[64];
struct tm * tm;
- if (len < 256)
+ if (len < LS_ENTRY_SIZE)
return -1;
tm = localtime(&adj->stamp);
- strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", tm);
+ strftime(tmbuf, sizeof(tmbuf), "%F %T", tm); /* 19 chars */
- sprintf(buf,
- "src: %" PRIu64 "\n"
- "dst: %" PRIu64 "\n"
- "upd: %s\n",
- adj->src,
- adj->dst,
- tmbuf);
+ sprintf(srcbuf, "%" PRIu64, adj->src);
+ sprintf(dstbuf, "%" PRIu64, adj->dst);
- return strlen(buf);
+ sprintf(buf, "src: %20s\ndst: %20s\nupd: %20s\n",
+ srcbuf, dstbuf, tmbuf);
+
+ return LS_ENTRY_SIZE;
}
-static int lsdb_read(const char * path,
- char * buf,
- size_t len)
+static struct adjacency * get_adj(const char * path)
{
struct list_head * p;
char entry[RIB_PATH_LEN + 1];
- pthread_rwlock_rdlock(&ls.db_lock);
-
- if (ls.db_len + ls.nbs_len == 0) {
- pthread_rwlock_unlock(&ls.db_lock);
- return -EPERM;
- }
+ assert(path);
list_for_each(p, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
sprintf(entry, "%" PRIu64 ".%" PRIu64, a->src, a->dst);
- if (strcmp(entry, path) == 0) {
- len = str_adj(a, buf, len);
- pthread_rwlock_unlock(&ls.db_lock);
- return len;
- }
+ if (strcmp(entry, path) == 0)
+ return a;
+ }
+
+ return NULL;
+}
+
+static int lsdb_getattr(const char * path,
+ struct stat * st)
+{
+ struct adjacency * adj;
+ struct timespec now;
+
+ clock_gettime(CLOCK_REALTIME_COARSE, &now);
+
+ pthread_rwlock_rdlock(&ls.db_lock);
+
+ adj = get_adj(path);
+ if (adj != NULL) {
+ st->st_mtime = adj->stamp;
+ st->st_size = LS_ENTRY_SIZE;
+ } else {
+ st->st_mtime = now.tv_sec;
+ st->st_size = 0;
}
+ st->st_mode = S_IFREG | 0755;
+ st->st_nlink = 1;
+ st->st_uid = getuid();
+ st->st_gid = getgid();
+
+ pthread_rwlock_unlock(&ls.db_lock);
+
+ return 0;
+}
+
+static int lsdb_read(const char * path,
+ char * buf,
+ size_t len)
+{
+ struct adjacency * a;
+ int size;
+
+ pthread_rwlock_rdlock(&ls.db_lock);
+
+ if (ls.db_len + ls.nbs_len == 0)
+ goto fail;
+
+ a = get_adj(path);
+ if (a == NULL)
+ goto fail;
+
+ size = str_adj(a, buf, len);
+ if (size < 0)
+ goto fail;
+
pthread_rwlock_unlock(&ls.db_lock);
+ return size;
+ fail:
+ pthread_rwlock_unlock(&ls.db_lock);
return -1;
}
@@ -204,8 +250,8 @@ static int lsdb_readdir(char *** buf)
sprintf(entry, "%s%" PRIu64, str, nb->addr);
(*buf)[idx] = malloc(strlen(entry) + 1);
if ((*buf)[idx] == NULL) {
- while (--idx >= 0)
- free(*buf[idx]);
+ while (idx-- > 0)
+ free((*buf)[idx]);
free(buf);
pthread_rwlock_unlock(&ls.db_lock);
return -ENOMEM;
@@ -241,7 +287,8 @@ static int lsdb_readdir(char *** buf)
static struct rib_ops r_ops = {
.read = lsdb_read,
- .readdir = lsdb_readdir
+ .readdir = lsdb_readdir,
+ .getattr = lsdb_getattr
};
static int lsdb_add_nb(uint64_t addr,
@@ -801,13 +848,17 @@ int link_state_init(enum pol_routing pr)
if (pthread_create(&ls.listener, NULL, ls_conn_handle, NULL))
goto fail_pthread_create_listener;
+ if (rib_reg(LSDB, &r_ops))
+ goto fail_rib_reg;
+
ls.db_len = 0;
ls.nbs_len = 0;
- rib_reg(LSDB, &r_ops);
-
return 0;
+ fail_rib_reg:
+ pthread_cancel(ls.listener);
+ pthread_join(ls.listener, NULL);
fail_pthread_create_listener:
pthread_cancel(ls.lsreader);
pthread_join(ls.lsreader, NULL);
diff --git a/src/lib/rib.c b/src/lib/rib.c
index 5bb8c1c3..947226a9 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -29,6 +29,7 @@
#include <ouroboros/rib.h>
#include <ouroboros/utils.h>
+#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
@@ -155,9 +156,11 @@ static int rib_readdir(const char * path,
ssize_t i;
struct reg_comp * c;
c = list_entry(p, struct reg_comp, next);
- if (strcmp(path + 1, c->path) == 0)
- if (c->ops->readdir == NULL)
- break;
+
+ if (strcmp(path + 1, c->path) != 0)
+ continue;
+
+ assert(c->ops->readdir != NULL);
len = c->ops->readdir(&dir_entries);
if (len < 0)
@@ -173,49 +176,70 @@ static int rib_readdir(const char * path,
return 0;
}
+static size_t __getattr(const char * path,
+ struct stat * st)
+{
+ struct list_head * p;
+ char comp[RIB_PATH_LEN + 1];
+ char * c;
+
+ strcpy(comp, path + 1);
+
+ c = strstr(comp, "/");
+
+ if (c != NULL)
+ *c = '\0';
+
+ pthread_rwlock_rdlock(&rib.lock);
+
+ list_for_each(p, &rib.reg_comps) {
+ struct reg_comp * r = list_entry(p, struct reg_comp, next);
+ if (strcmp(comp, r->path) == 0) {
+ size_t ret = r->ops->getattr(c + 1, st);
+ pthread_rwlock_unlock(&rib.lock);
+ return ret;
+ }
+ }
+
+ pthread_rwlock_unlock(&rib.lock);
+
+ return -1;
+}
+
static int rib_getattr(const char * path,
struct stat * st)
{
struct list_head * p;
struct timespec now;
- clock_gettime(CLOCK_REALTIME_COARSE, &now);
-
memset(st, 0, sizeof(*st));
- if (strcmp(path, RT) == 0) {
- st->st_mode = S_IFDIR | 0755;
- st->st_nlink = 2;
- st->st_uid = getuid();
- st->st_gid = getgid();
- st->st_mtime = now.tv_sec;
- return 0;
- }
+ if (strcmp(path, RT) == 0)
+ goto finish_dir;
pthread_rwlock_rdlock(&rib.lock);
list_for_each(p, &rib.reg_comps) {
struct reg_comp * rc = list_entry(p, struct reg_comp, next);
if (strcmp(path + 1, rc->path) == 0) {
- st->st_mode = S_IFDIR | 0755;
- st->st_nlink = 2;
- break;
+ pthread_rwlock_unlock(&rib.lock);
+ goto finish_dir;
}
}
pthread_rwlock_unlock(&rib.lock);
- if (st->st_mode == 0) {
- char buf[4096];
- st->st_nlink = 2;
- st->st_mode = S_IFREG | 0755;
- st->st_size = rib_read(path, buf, 4096, 0, NULL);
- }
+ assert(st->st_mode == 0);
+
+ return __getattr(path, st);
+ finish_dir:
+ clock_gettime(CLOCK_REALTIME_COARSE, &now);
+ st->st_mode = S_IFDIR | 0755;
+ st->st_nlink = 2;
st->st_uid = getuid();
st->st_gid = getgid();
st->st_mtime = now.tv_sec;
-
return 0;
}