summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-04-26 20:31:39 +0200
committerdimitri staessens <[email protected]>2017-04-27 17:59:01 +0200
commitb398dbe5cfd12b928e00f9a22cd6826bbdfb18d7 (patch)
tree137c34f79897b5f371a65dd14208b77201d1e907
parent6d6a4a488d7b631f519b1cf462ffbb44d399e1ce (diff)
downloadouroboros-b398dbe5cfd12b928e00f9a22cd6826bbdfb18d7.tar.gz
ouroboros-b398dbe5cfd12b928e00f9a22cd6826bbdfb18d7.zip
ipcpd: Add capability reporting
The IPCP will now report the DIF name and the hash value to the IRMd as a dif_info struct. This can later be extended to add further capability reporting. Some bugfixes in normal. Fixes #24
-rw-r--r--include/ouroboros/ipcp.h8
-rw-r--r--src/ipcpd/ipcp.c12
-rw-r--r--src/ipcpd/ipcp.h3
-rw-r--r--src/ipcpd/normal/main.c29
-rw-r--r--src/irmd/ipcp.c26
-rw-r--r--src/irmd/ipcp.h7
-rw-r--r--src/irmd/main.c64
-rw-r--r--src/lib/ipcpd_messages.proto6
8 files changed, 102 insertions, 53 deletions
diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h
index b9c5b740..f418d640 100644
--- a/include/ouroboros/ipcp.h
+++ b/include/ouroboros/ipcp.h
@@ -86,4 +86,12 @@ struct ipcp_config {
char * if_name;
};
+#define DIF_NAME_SIZE 256
+
+/* capability report of a DIF */
+struct dif_info {
+ enum hash_algo algo;
+ char dif_name[DIF_NAME_SIZE];
+};
+
#endif /* OUROBOROS_IPCP_H */
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index d682309d..7f3ebc73 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -143,9 +143,10 @@ static void * ipcp_main_loop(void * o)
ipcp_config_msg_t * conf_msg;
struct ipcp_config conf;
+ struct dif_info info;
struct timeval ltv = {(SOCKET_TIMEOUT / 1000),
- (SOCKET_TIMEOUT % 1000) * 1000};
+ (SOCKET_TIMEOUT % 1000) * 1000};
ssize_t id = (ssize_t) o;
@@ -259,7 +260,14 @@ static void * ipcp_main_loop(void * o)
break;
}
- ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst_name);
+ ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst_name,
+ &info);
+
+ if (ret_msg.result == 0) {
+ ret_msg.has_dir_hash_algo = true;
+ ret_msg.dir_hash_algo = info.algo;
+ ret_msg.dif_name = info.dif_name;
+ }
break;
case IPCP_MSG_CODE__IPCP_REG:
ret_msg.has_result = true;
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index c78aa5a6..3f5e1bd6 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -43,7 +43,8 @@ enum ipcp_state {
struct ipcp_ops {
int (* ipcp_bootstrap)(const struct ipcp_config * conf);
- int (* ipcp_enroll)(const char * dst);
+ int (* ipcp_enroll)(const char * dst,
+ struct dif_info * info);
int (* ipcp_reg)(const uint8_t * hash);
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index ab8cf387..9228f36b 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -116,21 +116,21 @@ static int boot_components(void)
log_dbg("Starting ribmgr.");
- if (ribmgr_init()) {
- log_err("Failed to initialize RIB manager.");
+ if (dir_init()) {
+ log_err("Failed to initialize directory.");
goto fail_addr_auth;
}
- if (dir_init()) {
- log_err("Failed to initialize directory.");
- goto fail_ribmgr;
+ if (ribmgr_init()) {
+ log_err("Failed to initialize RIB manager.");
+ goto fail_dir;
}
log_dbg("Ribmgr started.");
if (frct_init()) {
log_err("Failed to initialize FRCT.");
- goto fail_dir;
+ goto fail_ribmgr;
}
if (fa_init()) {
@@ -180,10 +180,10 @@ static int boot_components(void)
fa_fini();
fail_frct:
frct_fini();
- fail_dir:
- dir_fini();
fail_ribmgr:
ribmgr_fini();
+ fail_dir:
+ dir_fini();
fail_addr_auth:
addr_auth_fini();
fail_name:
@@ -208,16 +208,17 @@ void shutdown_components(void)
frct_fini();
- dir_fini();
-
ribmgr_fini();
+ dir_fini();
+
addr_auth_fini();
free(ipcpi.dif_name);
}
-static int normal_ipcp_enroll(const char * dst)
+static int normal_ipcp_enroll(const char * dst,
+ struct dif_info * info)
{
if (rib_add(RIB_ROOT, MEMBERS_NAME)) {
log_err("Failed to create members.");
@@ -237,7 +238,11 @@ static int normal_ipcp_enroll(const char * dst)
log_dbg("Enrolled with " HASH_FMT, HASH_VAL(dst));
- return ipcpi.dir_hash_algo;
+ info->algo = ipcpi.dir_hash_algo;
+
+ strcpy(info->dif_name, ipcpi.dif_name);
+
+ return 0;
}
const struct ros {
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index 7a32dd88..182970b1 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -212,13 +212,13 @@ int ipcp_bootstrap(pid_t api,
return ret;
}
-/* return the hash algorithm */
-int ipcp_enroll(pid_t api,
- const char * dst)
+int ipcp_enroll(pid_t api,
+ const char * dst,
+ struct dif_info * info)
{
- ipcp_msg_t msg = IPCP_MSG__INIT;
+ ipcp_msg_t msg = IPCP_MSG__INIT;
ipcp_msg_t * recv_msg = NULL;
- int ret = -1;
+ int ret = -1;
if (dst == NULL)
return -EINVAL;
@@ -236,9 +236,23 @@ int ipcp_enroll(pid_t api,
}
ret = recv_msg->result;
+ if (ret != 0) {
+ ipcp_msg__free_unpacked(recv_msg, NULL);
+ return ret;
+ }
+
+ if (!recv_msg->has_dir_hash_algo || recv_msg->dif_name == NULL) {
+ ipcp_msg__free_unpacked(recv_msg, NULL);
+ return -EIPCP;
+ }
+
+ info->algo = recv_msg->dir_hash_algo;
+
+ strcpy(info->dif_name, recv_msg->dif_name);
+
ipcp_msg__free_unpacked(recv_msg, NULL);
- return ret;
+ return 0;
}
int ipcp_reg(pid_t api,
diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h
index 11adad7d..74175f97 100644
--- a/src/irmd/ipcp.h
+++ b/src/irmd/ipcp.h
@@ -34,10 +34,11 @@ pid_t ipcp_create(const char * name,
int ipcp_destroy(pid_t api);
-int ipcp_enroll(pid_t api,
- const char * dst);
+int ipcp_enroll(pid_t api,
+ const char * dst,
+ struct dif_info * info);
-int ipcp_bootstrap(pid_t api,
+int ipcp_bootstrap(pid_t api,
ipcp_config_msg_t * conf);
int ipcp_reg(pid_t api,
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 45a348ae..67c2ad60 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -56,7 +56,7 @@
#define IRMD_CLEANUP_TIMER ((IRMD_FLOW_TIMEOUT / 20) * MILLION) /* ns */
#define SHM_SAN_HOLDOFF 1000 /* ms */
-#define IPCP_HASH_LEN(e) (hash_len(e->dir_hash_algo))
+#define IPCP_HASH_LEN(e) hash_len(e->dir_hash_algo)
struct ipcp_entry {
struct list_head next;
@@ -226,27 +226,26 @@ static struct ipcp_entry * get_ipcp_entry_by_name(const char * name)
return NULL;
}
-/*
- * Check if the hash is reachable anywhere in a DIF.
- * FIXME: specify algorithm used
- */
static struct ipcp_entry * get_ipcp_by_dst_name(const char * name)
{
struct list_head * p = NULL;
uint8_t * hash;
list_for_each(p, &irmd.ipcps) {
- struct ipcp_entry * e =
- list_entry(p, struct ipcp_entry, next);
- if (e->dir_hash_algo < 0)
+ struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next);
+ if (e->dif_name == NULL)
continue;
+
+ log_dbg("IPCP %s found for name %s with hash enum %d.",
+ e->dif_name, name, e->dir_hash_algo);
+
hash = malloc(IPCP_HASH_LEN(e));
if (hash == NULL)
return NULL;
str_hash(e->dir_hash_algo, hash, name);
- if (ipcp_query(e->api, hash, hash_len(e->dir_hash_algo)) == 0) {
+ if (ipcp_query(e->api, hash, IPCP_HASH_LEN(e)) == 0) {
free(hash);
return e;
}
@@ -319,10 +318,10 @@ static pid_t create_ipcp(char * name,
list_add(&api->next, &irmd.spawned_apis);
- pthread_mutex_lock(&tmp->init_lock);
-
pthread_rwlock_unlock(&irmd.reg_lock);
+ pthread_mutex_lock(&tmp->init_lock);
+
while (tmp->init == false)
pthread_cond_wait(&tmp->init_cond, &tmp->init_lock);
@@ -401,7 +400,7 @@ static int destroy_ipcp(pid_t api)
return 0;
}
-static int bootstrap_ipcp(pid_t api,
+static int bootstrap_ipcp(pid_t api,
ipcp_config_msg_t * conf)
{
struct ipcp_entry * entry = NULL;
@@ -445,9 +444,10 @@ static int bootstrap_ipcp(pid_t api,
}
static int enroll_ipcp(pid_t api,
- char * dif_name)
+ char * dst_name)
{
struct ipcp_entry * entry = NULL;
+ struct dif_info info;
pthread_rwlock_wrlock(&irmd.reg_lock);
@@ -464,27 +464,35 @@ static int enroll_ipcp(pid_t api,
return -1;
}
- entry->dif_name = strdup(dif_name);
- if (entry->dif_name == NULL) {
- pthread_rwlock_unlock(&irmd.reg_lock);
- log_err("Failed to strdup.");
+ pthread_rwlock_unlock(&irmd.reg_lock);
+
+ if (ipcp_enroll(api, dst_name, &info) < 0) {
+ log_err("Could not enroll IPCP.");
return -1;
}
- pthread_rwlock_unlock(&irmd.reg_lock);
+ pthread_rwlock_wrlock(&irmd.reg_lock);
- entry->dir_hash_algo = ipcp_enroll(api, dif_name);
- if (entry->dir_hash_algo < 0) {
- pthread_rwlock_wrlock(&irmd.reg_lock);
- free(entry->dif_name);
- entry->dif_name = NULL;
+ entry = get_ipcp_entry_by_api(api);
+ if (entry == NULL) {
pthread_rwlock_unlock(&irmd.reg_lock);
- log_err("Could not enroll IPCP.");
+ log_err("No such IPCP.");
return -1;
}
+ entry->dif_name = strdup(info.dif_name);
+ if (entry->dif_name == NULL) {
+ pthread_rwlock_unlock(&irmd.reg_lock);
+ log_err("Failed to strdup dif_name.");
+ return -ENOMEM;
+ }
+
+ entry->dir_hash_algo = info.algo;
+
+ pthread_rwlock_unlock(&irmd.reg_lock);
+
log_info("Enrolled IPCP %d in DIF %s.",
- api, dif_name);
+ api, info.dif_name);
return 0;
}
@@ -769,6 +777,9 @@ static int name_reg(const char * name,
if (wildcard_match(difs[i], e->dif_name))
continue;
+ log_dbg("gonna register %s in dif %s.",
+ name, e->dif_name);
+
hash = malloc(IPCP_HASH_LEN(e));
if (hash == NULL)
break;
@@ -1101,10 +1112,9 @@ static int flow_alloc(pid_t api,
assert(irm_flow_get_state(f) == FLOW_ALLOC_PENDING);
hash = malloc(IPCP_HASH_LEN(ipcp));
- if (hash == NULL) {
+ if (hash == NULL)
/* sanitizer cleans this */
return -ENOMEM;
- }
str_hash(ipcp->dir_hash_algo, hash, dst);
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index bd71d3f3..9299afcd 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -46,6 +46,8 @@ message ipcp_msg {
optional uint32 qoscube = 6;
optional ipcp_config_msg conf = 7;
optional int32 api = 8;
- optional int32 response = 9;
- optional int32 result = 10;
+ optional int32 dir_hash_algo = 9;
+ optional string dif_name = 10;
+ optional int32 response = 11;
+ optional int32 result = 12;
};