summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/cacep.h6
-rw-r--r--include/ouroboros/ipcp.h16
-rw-r--r--include/ouroboros/irm.h13
-rw-r--r--src/ipcpd/ipcp.c30
-rw-r--r--src/ipcpd/ipcp.h6
-rw-r--r--src/ipcpd/local/main.c4
-rw-r--r--src/ipcpd/normal/CMakeLists.txt6
-rw-r--r--src/ipcpd/normal/addr_auth.c5
-rw-r--r--src/ipcpd/normal/addr_auth.h3
-rw-r--r--src/ipcpd/normal/ae.h24
-rw-r--r--src/ipcpd/normal/connmgr.c373
-rw-r--r--src/ipcpd/normal/connmgr.h28
-rw-r--r--src/ipcpd/normal/dir.c92
-rw-r--r--src/ipcpd/normal/dir.h4
-rw-r--r--src/ipcpd/normal/dt.c85
-rw-r--r--src/ipcpd/normal/dt.h9
-rw-r--r--src/ipcpd/normal/dt_pci.c18
-rw-r--r--src/ipcpd/normal/dt_pci.h6
-rw-r--r--src/ipcpd/normal/enroll.c457
-rw-r--r--src/ipcpd/normal/enroll.h22
-rw-r--r--src/ipcpd/normal/enroll.proto (renamed from src/ipcpd/normal/pol-gam-ops.h)25
-rw-r--r--src/ipcpd/normal/flow_alloc.proto18
-rw-r--r--src/ipcpd/normal/gam.c83
-rw-r--r--src/ipcpd/normal/gam.h37
-rw-r--r--src/ipcpd/normal/main.c388
-rw-r--r--src/ipcpd/normal/neighbors.c2
-rw-r--r--src/ipcpd/normal/neighbors.h12
-rw-r--r--src/ipcpd/normal/pol-addr-auth-ops.h2
-rw-r--r--src/ipcpd/normal/pol/complete.c180
-rw-r--r--src/ipcpd/normal/pol/complete.h41
-rw-r--r--src/ipcpd/normal/pol/flat.c106
-rw-r--r--src/ipcpd/normal/pol/flat.h4
-rw-r--r--src/ipcpd/normal/pol/link_state.c52
-rw-r--r--src/ipcpd/normal/ribconfig.h4
-rw-r--r--src/ipcpd/normal/ribmgr.c116
-rw-r--r--src/ipcpd/normal/ribmgr.h4
-rw-r--r--src/ipcpd/normal/routing.c15
-rw-r--r--src/ipcpd/normal/sdu_sched.c6
-rw-r--r--src/ipcpd/shim-eth-llc/main.c2
-rw-r--r--src/ipcpd/shim-udp/main.c4
-rw-r--r--src/irmd/ipcp.c61
-rw-r--r--src/irmd/ipcp.h8
-rw-r--r--src/irmd/main.c82
-rw-r--r--src/lib/dev.c3
-rw-r--r--src/lib/ipcp_config.proto10
-rw-r--r--src/lib/ipcpd_messages.proto7
-rw-r--r--src/lib/irm.c70
-rw-r--r--src/lib/irmd_messages.proto31
-rw-r--r--src/lib/rib.c3
-rw-r--r--src/tools/irm/CMakeLists.txt2
-rw-r--r--src/tools/irm/irm_ipcp.c18
-rw-r--r--src/tools/irm/irm_ipcp_bootstrap.c25
-rw-r--r--src/tools/irm/irm_ipcp_connect.c94
-rw-r--r--src/tools/irm/irm_ipcp_disconnect.c94
-rw-r--r--src/tools/irm/irm_ops.h6
55 files changed, 1468 insertions, 1354 deletions
diff --git a/include/ouroboros/cacep.h b/include/ouroboros/cacep.h
index d2b0de9a..4b557b46 100644
--- a/include/ouroboros/cacep.h
+++ b/include/ouroboros/cacep.h
@@ -29,9 +29,11 @@
#include <stdint.h>
#include <sys/types.h>
+#define CACEP_BUF_STRLEN 64
+
struct conn_info {
- char ae_name[64];
- char protocol[64];
+ char ae_name[CACEP_BUF_STRLEN + 1];
+ char protocol[CACEP_BUF_STRLEN + 1];
uint32_t pref_version;
enum proto_concrete_syntax pref_syntax;
struct proto_field fixed_conc_syntax[PROTO_MAX_FIELDS];
diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h
index 11095ba6..2d785fbb 100644
--- a/include/ouroboros/ipcp.h
+++ b/include/ouroboros/ipcp.h
@@ -27,15 +27,17 @@
#include <unistd.h>
#include <stdbool.h>
+#define DIF_NAME_SIZE 256
+
/*
* NOTE: the IRMd uses this order to select an IPCP
- * for flow allocation
+ * for flow allocation.
*/
enum ipcp_type {
IPCP_LOCAL = 0,
+ IPCP_NORMAL,
IPCP_SHIM_ETH_LLC,
- IPCP_SHIM_UDP,
- IPCP_NORMAL
+ IPCP_SHIM_UDP
};
/* Normal IPCP policies */
@@ -43,10 +45,6 @@ enum pol_addr_auth {
FLAT_RANDOM = 0
};
-enum pol_gam {
- COMPLETE = 0
-};
-
enum pol_routing {
LINK_STATE = 0
};
@@ -58,8 +56,6 @@ enum pol_dir_hash {
DIR_HASH_SHA3_512
};
-#define DIF_NAME_SIZE 256
-
/* Info reported back to the IRMd about the DIF on enrollment */
struct dif_info {
char dif_name[DIF_NAME_SIZE];
@@ -78,8 +74,6 @@ struct ipcp_config {
bool has_ttl;
enum pol_addr_auth addr_auth_type;
- enum pol_gam dt_gam_type;
- enum pol_gam rm_gam_type;
enum pol_routing routing_type;
/* Shim UDP */
diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h
index 5ad8f754..dc723fc0 100644
--- a/include/ouroboros/irm.h
+++ b/include/ouroboros/irm.h
@@ -28,8 +28,11 @@
#include <sys/types.h>
-/* Name binding options */
+/* Normal IPCP components. */
+#define DT_AE "Data Transfer"
+#define MGMT_AE "Management"
+/* Name binding options. */
#define BIND_AP_AUTO 0x01
#define BIND_AP_UNIQUE 0x02
@@ -50,6 +53,14 @@ int irm_enroll_ipcp(pid_t api,
int irm_bootstrap_ipcp(pid_t api,
const struct ipcp_config * conf);
+int irm_connect_ipcp(pid_t api,
+ const char * component,
+ const char * dst);
+
+int irm_disconnect_ipcp(pid_t api,
+ const char * component,
+ const char * dst);
+
int irm_bind_ap(const char * ap,
const char * name,
uint16_t opts,
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index ff45407b..41ea4784 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -227,8 +227,6 @@ static void * mainloop(void * o)
conf.fd_size = conf_msg->fd_size;
conf.has_ttl = conf_msg->has_ttl;
conf.addr_auth_type = conf_msg->addr_auth_type;
- conf.dt_gam_type = conf_msg->dt_gam_type;
- conf.rm_gam_type = conf_msg->rm_gam_type;
conf.routing_type = conf_msg->routing_type;
switch(conf_msg->dif_info->dir_hash_algo) {
@@ -303,6 +301,32 @@ static void * mainloop(void * o)
dif_info.dif_name = info.dif_name;
}
break;
+ case IPCP_MSG_CODE__IPCP_CONNECT:
+ ret_msg.has_result = true;
+
+ if (ipcpi.ops->ipcp_connect == NULL) {
+ log_err("Connect unsupported.");
+ ret_msg.result = -ENOTSUP;
+ break;
+ }
+
+ ret_msg.result =
+ ipcpi.ops->ipcp_connect(msg->dst_name,
+ msg->comp_name);
+ break;
+ case IPCP_MSG_CODE__IPCP_DISCONNECT:
+ ret_msg.has_result = true;
+
+ if (ipcpi.ops->ipcp_disconnect == NULL) {
+ log_err("Disconnect unsupported.");
+ ret_msg.result = -ENOTSUP;
+ break;
+ }
+
+ ret_msg.result =
+ ipcpi.ops->ipcp_disconnect(msg->dst_name,
+ msg->comp_name);
+ break;
case IPCP_MSG_CODE__IPCP_REG:
ret_msg.has_result = true;
@@ -437,6 +461,8 @@ static void * mainloop(void * o)
ipcpi.ops->ipcp_flow_dealloc(fd);
break;
default:
+ ret_msg.has_result = true;
+ ret_msg.result = -1;
log_err("Don't know that message code");
break;
}
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index cd18d198..1b2a0334 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -45,6 +45,12 @@ struct ipcp_ops {
int (* ipcp_enroll)(const char * dst,
struct dif_info * info);
+ int (* ipcp_connect)(const char * dst,
+ const char * component);
+
+ int (* ipcp_disconnect)(const char * dst,
+ const char * component);
+
int (* ipcp_reg)(const uint8_t * hash);
int (* ipcp_unreg)(const uint8_t * hash);
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 37d23fc3..c6f88d78 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -323,7 +323,9 @@ static int ipcp_local_flow_dealloc(int fd)
static struct ipcp_ops local_ops = {
.ipcp_bootstrap = ipcp_local_bootstrap,
- .ipcp_enroll = NULL, /* shim */
+ .ipcp_enroll = NULL,
+ .ipcp_connect = NULL,
+ .ipcp_disconnect = NULL,
.ipcp_reg = ipcp_local_reg,
.ipcp_unreg = ipcp_local_unreg,
.ipcp_query = ipcp_local_query,
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt
index 7a40e94c..aebc6c35 100644
--- a/src/ipcpd/normal/CMakeLists.txt
+++ b/src/ipcpd/normal/CMakeLists.txt
@@ -15,6 +15,8 @@ include_directories(${CMAKE_BINARY_DIR}/include)
set(IPCP_NORMAL_TARGET ipcpd-normal CACHE INTERNAL "")
protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto)
+protobuf_generate_c(ENROLL_PROTO_SRCS ENROLL_PROTO_HDRS enroll.proto
+ ${CMAKE_SOURCE_DIR}/src/lib/ipcp_config.proto)
protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto)
# Add GPB sources of policies last
@@ -34,7 +36,6 @@ set(SOURCE_FILES
dt_pci.c
enroll.c
fa.c
- gam.c
main.c
neighbors.c
pff.c
@@ -42,14 +43,13 @@ set(SOURCE_FILES
routing.c
sdu_sched.c
# Add policies last
- pol/complete.c
pol/flat.c
pol/link_state.c
pol/graph.c
)
add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES}
- ${FLOW_ALLOC_SRCS} ${FSO_SRCS} ${KAD_PROTO_SRCS})
+ ${FLOW_ALLOC_SRCS} ${FSO_SRCS} ${KAD_PROTO_SRCS} ${ENROLL_PROTO_SRCS})
target_link_libraries(ipcpd-normal LINK_PUBLIC ouroboros)
include(AddCompileFlags)
diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c
index e327e2fa..e4aacccd 100644
--- a/src/ipcpd/normal/addr_auth.c
+++ b/src/ipcpd/normal/addr_auth.c
@@ -35,7 +35,8 @@ struct addr_auth {
struct pol_addr_auth_ops * ops;
} addr_auth;
-int addr_auth_init(enum pol_addr_auth type)
+int addr_auth_init(enum pol_addr_auth type,
+ const void * info)
{
switch (type) {
case FLAT_RANDOM:
@@ -46,7 +47,7 @@ int addr_auth_init(enum pol_addr_auth type)
return -1;
}
- return addr_auth.ops->init();
+ return addr_auth.ops->init(info);
}
uint64_t addr_auth_address(void)
diff --git a/src/ipcpd/normal/addr_auth.h b/src/ipcpd/normal/addr_auth.h
index 5a6dec05..14754660 100644
--- a/src/ipcpd/normal/addr_auth.h
+++ b/src/ipcpd/normal/addr_auth.h
@@ -27,7 +27,8 @@
#include <stdint.h>
-int addr_auth_init(enum pol_addr_auth type);
+int addr_auth_init(enum pol_addr_auth type,
+ const void * info);
int addr_auth_fini(void);
diff --git a/src/ipcpd/normal/ae.h b/src/ipcpd/normal/ae.h
index 6285ba6a..3d3bdc27 100644
--- a/src/ipcpd/normal/ae.h
+++ b/src/ipcpd/normal/ae.h
@@ -23,8 +23,26 @@
#ifndef OUROBOROS_IPCPD_NORMAL_AE_H
#define OUROBOROS_IPCPD_NORMAL_AE_H
-#define MGMT_AE "Management"
-#define DT_AE "Data transfer"
-#define ENROLL_AE "Enrollment"
+#include <ouroboros/cacep.h>
+
+#include "dt.h"
+
+#define DST_MAX_STRLEN 64
+
+enum ae_id {
+ AEID_DT = 0,
+ AEID_ENROLL,
+ AEID_MGMT,
+ AEID_MAX
+};
+
+struct conn {
+ struct conn_info conn_info;
+ struct {
+ char dst[DST_MAX_STRLEN + 1];
+ int fd;
+ qosspec_t qs;
+ } flow_info;
+};
#endif /* OUROBOROS_IPCPD_NORMAL_AE_H */
diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c
index a83d71c3..fa43b97a 100644
--- a/src/ipcpd/normal/connmgr.c
+++ b/src/ipcpd/normal/connmgr.c
@@ -22,7 +22,7 @@
#define _POSIX_C_SOURCE 200112L
-#define OUROBOROS_PREFIX "normal-ipcp"
+#define OUROBOROS_PREFIX "Connection manager"
#include <ouroboros/dev.h>
#include <ouroboros/cacep.h>
@@ -42,92 +42,69 @@
#include <stdlib.h>
#include <assert.h>
-struct ae_conn {
+enum connmgr_state {
+ CONNMGR_NULL = 0,
+ CONNMGR_INIT,
+ CONNMGR_RUNNING
+};
+
+struct conn_el {
struct list_head next;
struct conn conn;
};
struct ae {
- struct list_head next;
+ struct nbs * nbs;
struct conn_info info;
- struct list_head conn_list;
- pthread_cond_t conn_cond;
- pthread_mutex_t conn_lock;
+ struct list_head conns;
+ struct list_head pending;
+
+ pthread_cond_t cond;
+ pthread_mutex_t lock;
};
struct {
- pthread_t acceptor;
+ struct ae aes[AEID_MAX];
+ enum connmgr_state state;
- struct list_head aes;
- pthread_rwlock_t aes_lock;
+ pthread_t acceptor;
} connmgr;
-
-static int get_info_by_name(const char * name,
- struct conn_info * info)
+static int get_id_by_name(const char * name)
{
- struct list_head * p;
+ enum ae_id i;
- pthread_rwlock_rdlock(&connmgr.aes_lock);
-
- list_for_each(p, &connmgr.aes) {
- struct ae * ae = list_entry(p, struct ae, next);
- if (strcmp(ae->info.ae_name, name) == 0) {
- memcpy(info, &ae->info, sizeof(*info));
- pthread_rwlock_unlock(&connmgr.aes_lock);
- return 0;
- }
- }
-
- pthread_rwlock_unlock(&connmgr.aes_lock);
+ for (i = 0; i < AEID_MAX; ++i)
+ if (strcmp(name, connmgr.aes[i].info.ae_name) == 0)
+ return i;
return -1;
}
-static int add_ae_conn(const char * name,
+static int add_ae_conn(enum ae_id id,
int fd,
qosspec_t qs,
struct conn_info * rcv_info)
{
- struct ae_conn * ae_conn;
- struct list_head * p;
- struct ae * ae = NULL;
+ struct conn_el * el;
- ae_conn = malloc(sizeof(*ae_conn));
- if (ae_conn == NULL) {
+ el = malloc(sizeof(*el));
+ if (el == NULL) {
log_err("Not enough memory.");
return -1;
}
- ae_conn->conn.conn_info = *rcv_info;
- ae_conn->conn.flow_info.fd = fd;
- ae_conn->conn.flow_info.qs = qs;
+ el->conn.conn_info = *rcv_info;
+ el->conn.flow_info.fd = fd;
+ el->conn.flow_info.qs = qs;
- list_head_init(&ae_conn->next);
+ pthread_mutex_lock(&connmgr.aes[id].lock);
- pthread_rwlock_wrlock(&connmgr.aes_lock);
+ list_add(&el->next, &connmgr.aes[id].pending);
+ pthread_cond_signal(&connmgr.aes[id].cond);
- list_for_each(p, &connmgr.aes) {
- ae = list_entry(p, struct ae, next);
- if (strcmp(ae->info.ae_name, name) == 0)
- break;
- }
-
- /* Check if entry was removed during allocation. */
- if (ae == NULL || strcmp(ae->info.ae_name, name) != 0) {
- pthread_rwlock_unlock(&connmgr.aes_lock);
- return -1;
- }
-
- pthread_mutex_lock(&ae->conn_lock);
-
- list_add(&ae_conn->next, &ae->conn_list);
- pthread_cond_signal(&ae->conn_cond);
-
- pthread_mutex_unlock(&ae->conn_lock);
-
- pthread_rwlock_unlock(&connmgr.aes_lock);
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
return 0;
}
@@ -136,7 +113,6 @@ static void * flow_acceptor(void * o)
{
int fd;
qosspec_t qs;
- struct conn_info snd_info;
struct conn_info rcv_info;
struct conn_info fail_info;
@@ -145,10 +121,7 @@ static void * flow_acceptor(void * o)
memset(&fail_info, 0, sizeof(fail_info));
while (true) {
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_info("Shutting down flow acceptor.");
- return 0;
- }
+ int id;
fd = flow_accept(&qs, NULL);
if (fd < 0) {
@@ -158,26 +131,30 @@ static void * flow_acceptor(void * o)
}
if (cacep_rcv(fd, &rcv_info)) {
- log_err("Error establishing application connection.");
+ log_dbg("Error establishing application connection.");
flow_dealloc(fd);
continue;
}
- if (get_info_by_name(rcv_info.ae_name, &snd_info)) {
- log_err("Failed to get info for %s.", rcv_info.ae_name);
+ id = get_id_by_name(rcv_info.ae_name);
+ if (id < 0) {
+ log_dbg("Connection request for unknown AE %s.",
+ rcv_info.ae_name);
cacep_snd(fd, &fail_info);
flow_dealloc(fd);
continue;
}
- if (cacep_snd(fd, &snd_info)) {
- log_err("Failed to respond to request.");
+ assert(id < AEID_MAX);
+
+ if (cacep_snd(fd, &connmgr.aes[id].info)) {
+ log_dbg("Failed to respond to request.");
flow_dealloc(fd);
continue;
}
- if (add_ae_conn(rcv_info.ae_name, fd, qs, &rcv_info)) {
- log_err("Failed to add new connection.");
+ if (add_ae_conn(id, fd, qs, &rcv_info)) {
+ log_dbg("Failed to add new connection.");
flow_dealloc(fd);
continue;
}
@@ -188,130 +165,192 @@ static void * flow_acceptor(void * o)
int connmgr_init(void)
{
- if (pthread_rwlock_init(&connmgr.aes_lock, NULL))
- return -1;
-
- list_head_init(&connmgr.aes);
+ connmgr.state = CONNMGR_INIT;
return 0;
}
+void connmgr_fini(void)
+{
+ int i;
+
+ if (connmgr.state == CONNMGR_RUNNING)
+ pthread_join(connmgr.acceptor, NULL);
+
+ for (i = 0; i < AEID_MAX; ++i)
+ connmgr_ae_fini(i);
+}
+
int connmgr_start(void)
{
if (pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL))
return -1;
+ connmgr.state = CONNMGR_RUNNING;
+
return 0;
}
void connmgr_stop(void)
{
- pthread_cancel(connmgr.acceptor);
+ if (connmgr.state == CONNMGR_RUNNING)
+ pthread_cancel(connmgr.acceptor);
}
-static void destroy_ae(struct ae * ae)
+int connmgr_ae_init(enum ae_id id,
+ const struct conn_info * info,
+ struct nbs * nbs)
{
- struct list_head * p;
- struct list_head * h;
+ struct ae * ae;
- pthread_mutex_lock(&ae->conn_lock);
+ assert(id >= 0 && id < AEID_MAX);
- list_for_each_safe(p, h, &ae->conn_list) {
- struct ae_conn * e = list_entry(p, struct ae_conn, next);
- list_del(&e->next);
- free(e);
+ ae = connmgr.aes + id;
+
+ if (pthread_mutex_init(&ae->lock, NULL))
+ return -1;
+
+ if (pthread_cond_init(&ae->cond, NULL)) {
+ pthread_mutex_destroy(&ae->lock);
+ return -1;
}
- pthread_mutex_unlock(&ae->conn_lock);
+ list_head_init(&ae->conns);
+ list_head_init(&ae->pending);
+
+ memcpy(&connmgr.aes[id].info, info, sizeof(connmgr.aes[id].info));
- pthread_cond_destroy(&ae->conn_cond);
- pthread_mutex_destroy(&ae->conn_lock);
+ connmgr.aes[id].nbs = nbs;
- free(ae);
+ return 0;
}
-void connmgr_fini(void)
+void connmgr_ae_fini(enum ae_id id)
{
struct list_head * p;
struct list_head * h;
+ struct ae * ae;
+
+ assert(id >= 0 && id < AEID_MAX);
- pthread_join(connmgr.acceptor, NULL);
+ if (strlen(connmgr.aes[id].info.ae_name) == 0)
+ return;
- pthread_rwlock_wrlock(&connmgr.aes_lock);
+ ae = connmgr.aes + id;
- list_for_each_safe(p, h, &connmgr.aes) {
- struct ae * e = list_entry(p, struct ae, next);
+ pthread_mutex_lock(&ae->lock);
+
+ list_for_each_safe(p, h, &ae->conns) {
+ struct conn_el * e = list_entry(p, struct conn_el, next);
+ list_del(&e->next);
+ free(e);
+ }
+
+ list_for_each_safe(p, h, &ae->pending) {
+ struct conn_el * e = list_entry(p, struct conn_el, next);
list_del(&e->next);
- destroy_ae(e);
+ free(e);
}
- pthread_rwlock_unlock(&connmgr.aes_lock);
+ pthread_mutex_unlock(&ae->lock);
- pthread_rwlock_destroy(&connmgr.aes_lock);
+ pthread_cond_destroy(&ae->cond);
+ pthread_mutex_destroy(&ae->lock);
+
+ memset(&connmgr.aes[id].info, 0, sizeof(connmgr.aes[id].info));
+
+ connmgr.aes[id].nbs = NULL;
}
-struct ae * connmgr_ae_create(struct conn_info info)
+int connmgr_ipcp_connect(const char * dst,
+ const char * component)
{
- struct ae * ae;
+ struct conn_el * ce;
+ int id;
- ae = malloc(sizeof(*ae));
- if (ae == NULL)
- goto fail_malloc;
+ assert(dst);
+ assert(component);
- list_head_init(&ae->next);
- list_head_init(&ae->conn_list);
-
- ae->info = info;
+ ce = malloc(sizeof(*ce));
+ if (ce == NULL) {
+ log_dbg("Out of memory.");
+ return -1;
+ }
- if (pthread_mutex_init(&ae->conn_lock, NULL))
- goto fail_mutex_init;
+ id = get_id_by_name(component);
+ if (id < 0) {
+ log_dbg("No such component: %s", component);
+ free(ce);
+ return -1;
+ }
- if (pthread_cond_init(&ae->conn_cond, NULL))
- goto fail_cond_init;
+ /* FIXME: get the correct qos for the component. */
+ if (connmgr_alloc(id, dst, NULL, &ce->conn)) {
+ free(ce);
+ return -1;
+ }
- pthread_rwlock_wrlock(&connmgr.aes_lock);
+ if (strlen(dst) > DST_MAX_STRLEN) {
+ log_warn("Truncating dst length for connection.");
+ memcpy(ce->conn.flow_info.dst, dst, DST_MAX_STRLEN);
+ ce->conn.flow_info.dst[DST_MAX_STRLEN] = '\0';
+ } else {
+ strcpy(ce->conn.flow_info.dst, dst);
+ }
- list_add(&ae->next, &connmgr.aes);
+ pthread_mutex_lock(&connmgr.aes[id].lock);
- pthread_rwlock_unlock(&connmgr.aes_lock);
+ list_add(&ce->next, &connmgr.aes[id].conns);
- return ae;
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
- fail_cond_init:
- pthread_mutex_destroy(&ae->conn_lock);
- fail_mutex_init:
- free(ae);
- fail_malloc:
- return NULL;
+ return 0;
}
-void connmgr_ae_destroy(struct ae * ae)
+int connmgr_ipcp_disconnect(const char * dst,
+ const char * component)
{
- assert(ae);
+ struct list_head * p;
+ struct list_head * h;
+ int id;
- pthread_rwlock_wrlock(&connmgr.aes_lock);
+ assert(dst);
+ assert(component);
- list_del(&ae->next);
+ id = get_id_by_name(component);
+ if (id < 0)
+ return -1;
- pthread_rwlock_unlock(&connmgr.aes_lock);
+ pthread_mutex_lock(&connmgr.aes[id].lock);
+
+ list_for_each_safe(p,h, &connmgr.aes[id].conns) {
+ struct conn_el * el = list_entry(p, struct conn_el, next);
+ if (strcmp(el->conn.flow_info.dst, dst) == 0) {
+ int ret;
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
+ list_del(&el->next);
+ ret = connmgr_dealloc(id, &el->conn);
+ free(el);
+ return ret;
+ }
+ }
+
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
- destroy_ae(ae);
+ return 0;
}
-int connmgr_alloc(struct ae * ae,
- const char * dst_name,
+int connmgr_alloc(enum ae_id id,
+ const char * dst,
qosspec_t * qs,
struct conn * conn)
{
- assert(ae);
- assert(dst_name);
- assert(conn);
-
- memset(&conn->conn_info, 0, sizeof(conn->conn_info));
+ assert(id >= 0 && id < AEID_MAX);
+ assert(dst);
- conn->flow_info.fd = flow_alloc(dst_name, qs, NULL);
+ conn->flow_info.fd = flow_alloc(dst, qs, NULL);
if (conn->flow_info.fd < 0) {
- log_err("Failed to allocate flow to %s.", dst_name);
+ log_dbg("Failed to allocate flow to %s.", dst);
return -1;
}
@@ -320,58 +359,90 @@ int connmgr_alloc(struct ae * ae,
else
memset(&conn->flow_info.qs, 0, sizeof(conn->flow_info.qs));
- if (cacep_snd(conn->flow_info.fd, &ae->info)) {
- log_err("Failed to create application connection.");
+ log_dbg("Sending cacep info for protocol %s to fd %d.",
+ connmgr.aes[id].info.protocol, conn->flow_info.fd);
+
+ if (cacep_snd(conn->flow_info.fd, &connmgr.aes[id].info)) {
+ log_dbg("Failed to create application connection.");
flow_dealloc(conn->flow_info.fd);
return -1;
}
if (cacep_rcv(conn->flow_info.fd, &conn->conn_info)) {
- log_err("Failed to connect to application.");
+ log_dbg("Failed to connect to application.");
flow_dealloc(conn->flow_info.fd);
return -1;
}
- if (strcmp(ae->info.protocol, conn->conn_info.protocol) ||
- ae->info.pref_version != conn->conn_info.pref_version ||
- ae->info.pref_syntax != conn->conn_info.pref_syntax) {
+ if (strcmp(connmgr.aes[id].info.protocol, conn->conn_info.protocol)) {
+ log_dbg("Unknown protocol (requested %s, got %s).",
+ connmgr.aes[id].info.protocol,
+ conn->conn_info.protocol);
flow_dealloc(conn->flow_info.fd);
return -1;
}
+ if (connmgr.aes[id].info.pref_version != conn->conn_info.pref_version) {
+ log_dbg("Unknown protocol version.");
+ flow_dealloc(conn->flow_info.fd);
+ return -1;
+ }
+
+ if (connmgr.aes[id].info.pref_syntax != conn->conn_info.pref_syntax) {
+ log_dbg("Unknown protocol syntax.");
+ flow_dealloc(conn->flow_info.fd);
+ return -1;
+ }
+
+ if (connmgr.aes[id].nbs != NULL)
+ nbs_add(connmgr.aes[id].nbs, *conn);
+
return 0;
}
-int connmgr_wait(struct ae * ae,
+int connmgr_dealloc(enum ae_id id,
+ struct conn * conn)
+{
+ if (connmgr.aes[id].nbs != NULL)
+ nbs_del(connmgr.aes[id].nbs, conn->flow_info.fd);
+
+ return flow_dealloc(conn->flow_info.fd);
+}
+
+
+int connmgr_wait(enum ae_id id,
struct conn * conn)
{
- struct ae_conn * ae_conn;
+ struct conn_el * el;
+ struct ae * ae;
- assert(ae);
+ assert(id >= 0 && id < AEID_MAX);
assert(conn);
- pthread_mutex_lock(&ae->conn_lock);
+ ae = connmgr.aes + id;
+
+ pthread_mutex_lock(&ae->lock);
pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,
- (void *) &ae->conn_lock);
+ (void *) &ae->lock);
- while (list_is_empty(&ae->conn_list))
- pthread_cond_wait(&ae->conn_cond, &ae->conn_lock);
+ while (list_is_empty(&ae->pending))
+ pthread_cond_wait(&ae->cond, &ae->lock);
pthread_cleanup_pop(false);
- ae_conn = list_first_entry((&ae->conn_list), struct ae_conn, next);
- if (ae_conn == NULL) {
- pthread_mutex_unlock(&ae->conn_lock);
+ el = list_first_entry((&ae->pending), struct conn_el, next);
+ if (el == NULL) {
+ pthread_mutex_unlock(&ae->lock);
return -1;
}
- *conn = ae_conn->conn;
+ *conn = el->conn;
- list_del(&ae_conn->next);
- free(ae_conn);
+ list_del(&el->next);
+ free(el);
- pthread_mutex_unlock(&ae->conn_lock);
+ pthread_mutex_unlock(&ae->lock);
return 0;
}
diff --git a/src/ipcpd/normal/connmgr.h b/src/ipcpd/normal/connmgr.h
index 40d74348..379877e6 100644
--- a/src/ipcpd/normal/connmgr.h
+++ b/src/ipcpd/normal/connmgr.h
@@ -26,13 +26,8 @@
#include <ouroboros/cacep.h>
#include <ouroboros/qos.h>
-struct conn {
- struct conn_info conn_info;
- struct flow_info {
- int fd;
- qosspec_t qs;
- } flow_info;
-};
+#include "ae.h"
+#include "neighbors.h"
int connmgr_init(void);
@@ -42,16 +37,27 @@ int connmgr_start(void);
void connmgr_stop(void);
-struct ae * connmgr_ae_create(struct conn_info info);
+int connmgr_ae_init(enum ae_id id,
+ const struct conn_info * info,
+ struct nbs * nbs);
-void connmgr_ae_destroy(struct ae * ae);
+void connmgr_ae_fini(enum ae_id id);
-int connmgr_alloc(struct ae * ae,
+int connmgr_ipcp_connect(const char * dst,
+ const char * component);
+
+int connmgr_ipcp_disconnect(const char * dst,
+ const char * component);
+
+int connmgr_alloc(enum ae_id id,
const char * dst,
qosspec_t * qs,
struct conn * conn);
-int connmgr_wait(struct ae * ae,
+int connmgr_dealloc(enum ae_id id,
+ struct conn * conn);
+
+int connmgr_wait(enum ae_id id,
struct conn * conn);
#endif /* OUROBOROS_IPCPD_NORMAL_CONNMGR_H */
diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c
index feae7013..2e2c113a 100644
--- a/src/ipcpd/normal/dir.c
+++ b/src/ipcpd/normal/dir.c
@@ -46,80 +46,21 @@
struct dht * dht;
-static uint64_t find_peer_addr(void)
+int dir_init(void)
{
- ssize_t i;
- char ** members;
- ssize_t n_members;
- size_t reset;
- char path[RIB_MAX_PATH_LEN + 1];
-
- strcpy(path, MEMBERS_PATH);
-
- reset = strlen(path);
-
- n_members = rib_children(path, &members);
- if (n_members == 1) {
- freepp(ssize_t, members, n_members);
- return 0;
- }
-
- for (i = 0; i < n_members; ++i) {
- uint64_t addr;
- rib_path_append(path, members[i]);
- if (rib_read(path, &addr, sizeof(addr)) != sizeof(addr)) {
- log_err("Failed to read address from RIB.");
- freepp(ssize_t, members, n_members);
- return ipcpi.dt_addr;
- }
-
- if (addr != ipcpi.dt_addr) {
- freepp(ssize_t, members, n_members);
- return addr;
- }
-
- path[reset] = '\0';
- }
-
- freepp(ssize_t, members, n_members);
-
- return 0;
-}
-
-int dir_init()
-{
- uint64_t addr;
-
dht = dht_create(ipcpi.dt_addr);
if (dht == NULL)
return -ENOMEM;
- addr = find_peer_addr();
- if (addr == ipcpi.dt_addr) {
- log_err("Failed to get peer address.");
- dht_destroy(dht);
- return -EPERM;
- }
-
- if (addr != 0) {
- size_t retr = 0;
- log_dbg("Enrolling directory with peer %" PRIu64 ".", addr);
- /* NOTE: we could try other members if dht_enroll times out. */
- while (dht_enroll(dht, addr)) {
- if (retr++ == ENROL_RETR) {
- dht_destroy(dht);
- return -EPERM;
- }
-
- log_dbg("Directory enrollment failed, retrying...");
- sleep(ENROL_INTV);
- }
-
- log_dbg("Directory enrolled.");
+ return 0;
+}
- return 0;
- }
+void dir_fini(void)
+{
+ dht_destroy(dht);
+}
+int dir_bootstrap(void) {
log_dbg("Bootstrapping directory.");
/* TODO: get parameters for bootstrap from IRM tool. */
@@ -133,9 +74,20 @@ int dir_init()
return 0;
}
-void dir_fini(void)
-{
- dht_destroy(dht);
+int dir_enroll(uint64_t addr) {
+ size_t retr = 0;
+ log_dbg("Enrolling directory with peer %" PRIu64 ".", addr);
+ while (dht_enroll(dht, addr)) {
+ if (retr++ == ENROL_RETR)
+ return -EPERM;
+
+ log_dbg("Directory enrollment failed, retrying...");
+ sleep(ENROL_INTV);
+ }
+
+ log_dbg("Directory enrolled.");
+
+ return 0;
}
int dir_reg(const uint8_t * hash)
diff --git a/src/ipcpd/normal/dir.h b/src/ipcpd/normal/dir.h
index 5f3f738e..13571b68 100644
--- a/src/ipcpd/normal/dir.h
+++ b/src/ipcpd/normal/dir.h
@@ -27,6 +27,10 @@ int dir_init(void);
void dir_fini(void);
+int dir_bootstrap(void);
+
+int dir_enroll(uint64_t peer);
+
int dir_reg(const uint8_t * hash);
int dir_unreg(const uint8_t * hash);
diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c
index f4ab2440..282f6bee 100644
--- a/src/ipcpd/normal/dt.c
+++ b/src/ipcpd/normal/dt.c
@@ -38,7 +38,6 @@
#include "dt_pci.h"
#include "pff.h"
#include "neighbors.h"
-#include "gam.h"
#include "routing.h"
#include "sdu_sched.h"
#include "ae.h"
@@ -67,11 +66,11 @@ struct {
struct ae_info aes[AP_RES_FDS];
pthread_rwlock_t lock;
- struct gam * gam;
struct nbs * nbs;
- struct ae * ae;
struct nb_notifier nb_notifier;
+
+ pthread_t listener;
} dt;
static int dt_neighbor_event(enum nb_event event,
@@ -149,36 +148,48 @@ static int sdu_handler(int fd,
return 0;
}
-int dt_init(void)
+static void * dt_conn_handle(void * o)
{
- int i;
- int j;
- struct conn_info info;
- enum pol_routing pr;
+ struct conn conn;
- if (rib_read(BOOT_PATH "/dt/routing/type", &pr, sizeof(pr))
- != sizeof(pr)) {
- log_err("Failed to read policy for routing.");
- return -1;
- }
+ (void) o;
- if (dt_pci_init()) {
- log_err("Failed to init shm dt_pci.");
- return -1;
+ while (true) {
+ if (connmgr_wait(AEID_DT, &conn)) {
+ log_err("Failed to get next DT connection.");
+ continue;
+ }
+
+ log_dbg("Got new connection.");
+
+ /* NOTE: connection acceptance policy could be here. */
+
+ nbs_add(dt.nbs, conn);
}
+ return 0;
+}
+
+int dt_init(enum pol_routing pr,
+ uint8_t addr_size,
+ uint8_t fd_size,
+ bool has_ttl)
+{
+ int i;
+ int j;
+ struct conn_info info;
+
memset(&info, 0, sizeof(info));
strcpy(info.ae_name, DT_AE);
strcpy(info.protocol, DT_PROTO);
info.pref_version = 1;
- info.pref_syntax = PROTO_FIXED;
- info.addr = ipcpi.dt_addr;
+ info.pref_syntax = PROTO_FIXED;
+ info.addr = ipcpi.dt_addr;
- dt.ae = connmgr_ae_create(info);
- if (dt.ae == NULL) {
- log_err("Failed to create AE struct.");
- goto fail_connmgr;
+ if (dt_pci_init(addr_size, fd_size, has_ttl)) {
+ log_err("Failed to init shm dt_pci.");
+ goto fail_pci_init;
}
dt.nbs = nbs_create();
@@ -193,6 +204,11 @@ int dt_init(void)
goto fail_nbs_notifier;
}
+ if (connmgr_ae_init(AEID_DT, &info, dt.nbs)) {
+ log_err("Failed to register with connmgr.");
+ goto fail_connmgr_ae_init;
+ }
+
if (routing_init(pr, dt.nbs)) {
log_err("Failed to init routing.");
goto fail_routing;
@@ -233,6 +249,8 @@ int dt_init(void)
for (j = 0; j < QOS_CUBE_MAX; ++j)
routing_i_destroy(dt.routing[j]);
fail_routing_i:
+ connmgr_ae_fini(AEID_DT);
+ fail_connmgr_ae_init:
for (i = 0; i < QOS_CUBE_MAX; ++i)
pff_destroy(dt.pff[i]);
fail_pff:
@@ -242,9 +260,9 @@ int dt_init(void)
fail_nbs_notifier:
nbs_destroy(dt.nbs);
fail_nbs:
- connmgr_ae_destroy(dt.ae);
- fail_connmgr:
dt_pci_fini();
+ fail_pci_init:
+ connmgr_ae_fini(AEID_DT);
return -1;
}
@@ -268,28 +286,19 @@ void dt_fini(void)
nbs_destroy(dt.nbs);
- connmgr_ae_destroy(dt.ae);
+ connmgr_ae_fini(AEID_DT);
}
int dt_start(void)
{
- enum pol_gam pg;
-
- if (rib_read(BOOT_PATH "/dt/gam/type", &pg, sizeof(pg))
- != sizeof(pg)) {
- log_err("Failed to read policy for ribmgr gam.");
- return -1;
- }
-
dt.sdu_sched = sdu_sched_create(sdu_handler);
if (dt.sdu_sched == NULL) {
log_err("Failed to create N-1 SDU scheduler.");
return -1;
}
- dt.gam = gam_create(pg, dt.nbs, dt.ae);
- if (dt.gam == NULL) {
- log_err("Failed to init dt graph adjacency manager.");
+ if (pthread_create(&dt.listener, NULL, dt_conn_handle, NULL)) {
+ log_err("Failed to create listener thread.");
sdu_sched_destroy(dt.sdu_sched);
return -1;
}
@@ -299,8 +308,8 @@ int dt_start(void)
void dt_stop(void)
{
- gam_destroy(dt.gam);
-
+ pthread_cancel(dt.listener);
+ pthread_join(dt.listener, NULL);
sdu_sched_destroy(dt.sdu_sched);
}
diff --git a/src/ipcpd/normal/dt.h b/src/ipcpd/normal/dt.h
index 99918ea5..09716153 100644
--- a/src/ipcpd/normal/dt.h
+++ b/src/ipcpd/normal/dt.h
@@ -23,13 +23,20 @@
#ifndef OUROBOROS_IPCPD_NORMAL_DT_H
#define OUROBOROS_IPCPD_NORMAL_DT_H
+#include <ouroboros/ipcp.h>
#include <ouroboros/shm_rdrbuff.h>
#include "dt_pci.h"
+#define DT_AE "Data Transfer"
+#define DT_PROTO "dtp"
#define INVALID_ADDR 0
-int dt_init(void);
+int dt_init(enum pol_routing pr,
+ uint8_t addr_size,
+ uint8_t fd_size,
+ bool has_ttl
+);
void dt_fini(void);
diff --git a/src/ipcpd/normal/dt_pci.c b/src/ipcpd/normal/dt_pci.c
index 9e6dfa89..5704a09a 100644
--- a/src/ipcpd/normal/dt_pci.c
+++ b/src/ipcpd/normal/dt_pci.c
@@ -44,19 +44,13 @@ struct {
size_t fd_o;
} dt_pci_info;
-int dt_pci_init()
+int dt_pci_init(uint8_t addr_size,
+ uint8_t fd_size,
+ bool has_ttl)
{
- /* read dt constants from the RIB */
- if (rib_read(BOOT_PATH "/dt/const/addr_size",
- &dt_pci_info.addr_size,
- sizeof(dt_pci_info.addr_size)) < 0 ||
- rib_read(BOOT_PATH "/dt/const/fd_size",
- &dt_pci_info.fd_size,
- sizeof(dt_pci_info.fd_size)) < 0 ||
- rib_read(BOOT_PATH "/dt/const/has_ttl",
- &dt_pci_info.has_ttl,
- sizeof(dt_pci_info.has_ttl)) < 0)
- return -1;
+ dt_pci_info.addr_size = addr_size;
+ dt_pci_info.fd_size = fd_size;
+ dt_pci_info.has_ttl = has_ttl;
dt_pci_info.qc_o = dt_pci_info.addr_size;
dt_pci_info.ttl_o = dt_pci_info.qc_o + QOS_LEN;
diff --git a/src/ipcpd/normal/dt_pci.h b/src/ipcpd/normal/dt_pci.h
index 5f14527c..efb4d0c0 100644
--- a/src/ipcpd/normal/dt_pci.h
+++ b/src/ipcpd/normal/dt_pci.h
@@ -30,8 +30,6 @@
#include <stdint.h>
#include <stdbool.h>
-#define DT_PROTO "dt"
-
/* Abstract syntax */
enum dtp_fields {
DTP_DST = 0, /* DST ADDRESS */
@@ -54,7 +52,9 @@ struct dt_pci {
uint32_t fd;
};
-int dt_pci_init(void);
+int dt_pci_init(uint8_t addr_size,
+ uint8_t fd_size,
+ bool has_ttl);
void dt_pci_fini(void);
diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c
index a33239a0..7f93ed3a 100644
--- a/src/ipcpd/normal/enroll.c
+++ b/src/ipcpd/normal/enroll.c
@@ -22,19 +22,19 @@
#define _POSIX_C_SOURCE 199309L
-#define OUROBOROS_PREFIX "enrollment"
+#define OUROBOROS_PREFIX "Enrollment"
#include <ouroboros/endian.h>
#include <ouroboros/errno.h>
-#include <ouroboros/cdap.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/dev.h>
#include <ouroboros/logs.h>
#include <ouroboros/rib.h>
#include <ouroboros/errno.h>
-#include "ae.h"
#include "connmgr.h"
+#include "enroll.h"
+#include "ipcp.h"
#include "ribconfig.h"
#include <assert.h>
@@ -42,302 +42,337 @@
#include <string.h>
#include <pthread.h>
-/* Symbolic, will return current time */
-#define TIME_NAME "localtime"
-#define TIME_PATH DLR TIME_NAME
+#include "enroll.pb-c.h"
+typedef EnrollMsg enroll_msg_t;
+typedef IpcpConfigMsg ipcp_config_msg_t;
+typedef DifInfoMsg dif_info_msg_t;
+
+#define ENROLL_AE "Enrollment"
+#define ENROLL_PROTO "OEP" /* Ouroboros enrollment protocol */
#define ENROLL_WARN_TIME_OFFSET 20
+#define ENROLL_BUF_LEN 1024
+
+enum enroll_state {
+ ENROLL_NULL = 0,
+ ENROLL_INIT,
+ ENROLL_RUNNING
+};
struct {
- struct ae * ae;
- struct cdap * cdap;
- pthread_t listener;
+ struct ipcp_config conf;
+ enum enroll_state state;
+ pthread_t listener;
} enroll;
-static void * enroll_handle(void * o)
+static int send_rcv_enroll_msg(int fd)
{
- struct cdap * cdap;
- struct conn conn;
- cdap_key_t key;
- enum cdap_opcode oc;
- char * name;
- uint8_t * buf;
- uint8_t * data;
- ssize_t len;
- uint32_t flags;
+ enroll_msg_t req = ENROLL_MSG__INIT;
+ enroll_msg_t * reply;
+ uint8_t buf[ENROLL_BUF_LEN];
+ ssize_t len;
+ ssize_t delta_t;
+ struct timespec t0;
+ struct timespec rtt;
- bool boot_r = false;
- bool members_r = false;
+ req.code = ENROLL_CODE__ENROLL_REQ;
- char * boot_ro = BOOT_PATH;
- char * members_ro = MEMBERS_PATH;
+ len = enroll_msg__get_packed_size(&req);
+ if (len < 0) {
+ log_dbg("Failed pack request message.");
+ return -1;
+ }
- cdap = (struct cdap *) o;
+ enroll_msg__pack(&req, buf);
- assert(cdap);
+ clock_gettime(CLOCK_REALTIME, &t0);
- while (true) {
- if (connmgr_wait(enroll.ae, &conn)) {
- log_err("Failed to get next connection.");
- continue;
- }
+ if (flow_write(fd, buf, len)) {
+ log_dbg("Failed to send request message.");
+ return -1;
+ }
- if (cdap_add_flow(cdap, conn.flow_info.fd)) {
- log_warn("Failed to add flow to CDAP.");
- flow_dealloc(conn.flow_info.fd);
- continue;
- }
+ len = flow_read(fd, buf, ENROLL_BUF_LEN);
+ if (len < 0) {
+ log_dbg("No enrollment reply received.");
+ return -1;
+ }
- while (!(boot_r && members_r)) {
- key = cdap_request_wait(cdap, &oc, &name, &data,
- (size_t *) &len , &flags);
- assert(key >= 0);
- assert(name);
-
- if (data != NULL) {
- free(data);
- log_warn("Received data with enroll request.");
- }
-
- if (oc != CDAP_READ) {
- log_warn("Invalid request.");
- cdap_reply_send(cdap, key, -1, NULL, 0);
- free(name);
- continue;
- }
-
- if (strcmp(name, boot_ro) == 0) {
- boot_r = true;
- } else if (strcmp(name, members_ro) == 0) {
- members_r = true;
- } else if (strcmp(name, TIME_PATH) == 0) {
- struct timespec t;
- uint64_t buf[2];
- clock_gettime(CLOCK_REALTIME, &t);
- buf[0] = hton64(t.tv_sec);
- buf[1] = hton64(t.tv_nsec);
- cdap_reply_send(cdap, key, 0, buf, sizeof(buf));
- free(name);
- continue;
- } else {
- log_warn("Illegal read: %s.", name);
- cdap_reply_send(cdap, key, -1, NULL, 0);
- free(name);
- continue;
- }
-
- len = rib_pack(name, &buf, PACK_HASH_ROOT);
- if (len < 0) {
- log_err("Failed to pack %s.", name);
- cdap_reply_send(cdap, key, -1, NULL, 0);
- free(name);
- continue;
- }
-
- log_dbg("Packed %s (%zu bytes).", name, len);
-
- free(name);
-
- if (cdap_reply_send(cdap, key, 0, buf, len)) {
- log_err("Failed to send CDAP reply.");
- free(buf);
- continue;
- }
-
- free(buf);
- }
+ log_dbg("Received enrollment info (%zd bytes).", len);
- log_dbg("Sent boot info to new member.");
+ reply = enroll_msg__unpack(NULL, len, buf);
+ if (reply == NULL) {
+ log_dbg("No enrollment response.");
+ return -1;
+ }
- cdap_del_flow(cdap, conn.flow_info.fd);
- flow_dealloc(conn.flow_info.fd);
+ if (reply->code != ENROLL_CODE__ENROLL_BOOT) {
+ log_dbg("Failed to unpack enrollment response.");
+ enroll_msg__free_unpacked(reply, NULL);
+ return -1;
+ }
- boot_r = members_r = false;
+ if (!(reply->has_t_sec && reply->has_t_nsec)) {
+ log_dbg("No time in response message.");
+ enroll_msg__free_unpacked(reply, NULL);
+ return -1;
}
+ clock_gettime(CLOCK_REALTIME, &rtt);
+
+ delta_t = ts_diff_ms(&t0, &rtt);
+
+ rtt.tv_sec = reply->t_sec;
+ rtt.tv_nsec = reply->t_nsec;
+
+ if (labs(ts_diff_ms(&t0, &rtt)) - delta_t > ENROLL_WARN_TIME_OFFSET)
+ log_warn("Clock offset above threshold.");
+
+ strcpy(enroll.conf.dif_info.dif_name, reply->conf->dif_info->dif_name);
+ enroll.conf.type = reply->conf->ipcp_type;
+ enroll.conf.addr_size = reply->conf->addr_size;
+ enroll.conf.fd_size = reply->conf->fd_size;
+ enroll.conf.has_ttl = reply->conf->has_ttl;
+ enroll.conf.addr_auth_type = reply->conf->addr_auth_type;
+ enroll.conf.routing_type = reply->conf->routing_type;
+ enroll.conf.dif_info.dir_hash_algo
+ = reply->conf->dif_info->dir_hash_algo;
+
+ enroll_msg__free_unpacked(reply, NULL);
+
return 0;
}
-int enroll_boot(const char * dst)
+static ssize_t enroll_pack(uint8_t ** buf)
{
- struct cdap * cdap;
- cdap_key_t * key;
- uint8_t * data;
- size_t len;
- struct conn conn;
+ enroll_msg_t msg = ENROLL_MSG__INIT;
+ ipcp_config_msg_t config = IPCP_CONFIG_MSG__INIT;
+ dif_info_msg_t dif_info = DIF_INFO_MSG__INIT;
+ struct timespec now;
+ ssize_t len;
+
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ msg.code = ENROLL_CODE__ENROLL_BOOT;
+ msg.has_t_sec = true;
+ msg.t_sec = now.tv_sec;
+ msg.has_t_nsec = true;
+ msg.t_nsec = now.tv_nsec;
+ msg.conf = &config;
+
+ config.ipcp_type = enroll.conf.type;
+ config.has_addr_size = true;
+ config.addr_size = enroll.conf.addr_size;
+ config.has_fd_size = true;
+ config.fd_size = enroll.conf.fd_size;
+ config.has_has_ttl = true;
+ config.has_ttl = enroll.conf.has_ttl;
+ config.has_addr_auth_type = true;
+ config.addr_auth_type = enroll.conf.addr_auth_type;
+ config.has_routing_type = true;
+ config.routing_type = enroll.conf.routing_type;
+ config.dif_info = &dif_info;
+
+ dif_info.dif_name = (char *) enroll.conf.dif_info.dif_name;
+ dif_info.dir_hash_algo = enroll.conf.dif_info.dir_hash_algo;
+
+ len = enroll_msg__get_packed_size(&msg);
+
+ *buf = malloc(len);
+ if (*buf == NULL)
+ return -1;
- struct timespec t0;
- struct timespec rtt;
+ enroll_msg__pack(&msg, *buf);
- ssize_t delta_t;
+ return len;
+}
- char * boot_ro = BOOT_PATH;
- char * members_ro = MEMBERS_PATH;
+static void * enroll_handle(void * o)
+{
+ struct conn conn;
+ uint8_t buf[ENROLL_BUF_LEN];
+ uint8_t * reply;
+ ssize_t len;
+ enroll_msg_t * msg;
- cdap = cdap_create();
- if (cdap == NULL) {
- log_err("Failed to instantiate CDAP.");
- return -1;
- }
+ (void) o;
- if (connmgr_alloc(enroll.ae, dst, NULL, &conn)) {
- log_err("Failed to get connection.");
- cdap_destroy(cdap);
- return -1;
- }
+ while (true) {
+ if (connmgr_wait(AEID_ENROLL, &conn)) {
+ log_err("Failed to get next connection.");
+ continue;
+ }
- if (cdap_add_flow(cdap, conn.flow_info.fd)) {
- log_warn("Failed to add flow to CDAP.");
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
- return -1;
- }
+ len = flow_read(conn.flow_info.fd, buf, ENROLL_BUF_LEN);
+ if (len < 0) {
+ log_err("Failed to read from flow.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ continue;
+ }
- log_dbg("Getting boot information from %s.", dst);
+ msg = enroll_msg__unpack(NULL, len, buf);
+ if (msg == NULL) {
+ log_err("Failed to unpack message.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ continue;
+ }
- clock_gettime(CLOCK_REALTIME, &t0);
+ if (msg->code != ENROLL_CODE__ENROLL_REQ) {
+ log_err("Wrong message type.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ enroll_msg__free_unpacked(msg, NULL);
+ continue;
+ }
- key = cdap_request_send(cdap, CDAP_READ, TIME_PATH, NULL, 0, 0);
- if (key == NULL || key[0] == INVALID_CDAP_KEY) {
- log_err("Failed to send CDAP request.");
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
- return -1;
- }
+ log_dbg("Enrolling a new neighbor.");
- if (cdap_reply_wait(cdap, key[0], &data, &len)) {
- log_err("Failed to get CDAP reply.");
- free(key);
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
- return -1;
- }
+ enroll_msg__free_unpacked(msg, NULL);
- free(key);
+ len = enroll_pack(&reply);
+ if (reply == NULL) {
+ log_err("Failed to pack enrollment message.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ continue;
+ }
- clock_gettime(CLOCK_REALTIME, &rtt);
+ log_dbg("Sending enrollment info (%zd bytes).", len);
- delta_t = ts_diff_ms(&t0, &rtt);
+ if (flow_write(conn.flow_info.fd, reply, len)) {
+ log_err("Failed respond to enrollment request.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ free(reply);
+ continue;
+ }
- assert(len == 2 * sizeof (uint64_t));
+ free(reply);
- rtt.tv_sec = ntoh64(((uint64_t *) data)[0]);
- rtt.tv_nsec = ntoh64(((uint64_t *) data)[1]);
+ len = flow_read(conn.flow_info.fd, buf, ENROLL_BUF_LEN);
+ if (len < 0) {
+ log_err("Failed to read from flow.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ continue;
+ }
- if (labs(ts_diff_ms(&t0, &rtt)) - delta_t > ENROLL_WARN_TIME_OFFSET)
- log_warn("Clock offset above threshold.");
+ msg = enroll_msg__unpack(NULL, len, buf);
+ if (msg == NULL) {
+ log_err("Failed to unpack message.");
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ continue;
+ }
- free(data);
+ if (msg->code != ENROLL_CODE__ENROLL_DONE || !msg->has_result) {
+ log_err("Wrong message type.");
+ enroll_msg__free_unpacked(msg, NULL);
+ connmgr_dealloc(AEID_ENROLL, &conn);
+ continue;
+ }
- key = cdap_request_send(cdap, CDAP_READ, boot_ro, NULL, 0, 0);
- if (key == NULL || key[0] == INVALID_CDAP_KEY) {
- log_err("Failed to send CDAP request.");
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
- return -1;
- }
+ if (msg->result == 0)
+ log_dbg("Neighbor enrollment successful.");
+ else
+ log_dbg("Neigbor reported failed enrollment.");
- if (cdap_reply_wait(cdap, key[0], &data, &len)) {
- log_err("Failed to get CDAP reply.");
- free(key);
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
- return -1;
+ connmgr_dealloc(AEID_ENROLL, &conn);
}
- free(key);
+ return 0;
+}
- log_dbg("Packed information received (%zu bytes).", len);
+int enroll_boot(struct conn * conn,
+ const char * dst)
+{
+ log_dbg("Getting boot information from %s.", dst);
- if (rib_unpack(data, len, UNPACK_CREATE)) {
- log_warn("Error unpacking RIB data.");
- rib_del(boot_ro);
- free(data);
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
+ if (send_rcv_enroll_msg(conn->flow_info.fd)) {
+ log_err("Failed to enroll.");
return -1;
}
- log_dbg("Packed information inserted into RIB.");
+ return 0;
+}
- key = cdap_request_send(cdap, CDAP_READ, members_ro, NULL, 0, 0);
- if (key == NULL || key[0] == INVALID_CDAP_KEY) {
- log_err("Failed to send CDAP request.");
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
- return -1;
- }
+int enroll_done(struct conn * conn,
+ int result)
+{
+ enroll_msg_t msg = ENROLL_MSG__INIT;
+ uint8_t buf[ENROLL_BUF_LEN];
+ ssize_t len;
- if (cdap_reply_wait(cdap, key[0], &data, &len)) {
- log_err("Failed to get CDAP reply.");
- free(key);
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
+ msg.code = ENROLL_CODE__ENROLL_DONE;
+ msg.has_result = true;
+ msg.result = result;
+
+ len = enroll_msg__get_packed_size(&msg);
+ if (len < 0) {
+ log_dbg("Failed pack request message.");
return -1;
}
- free(key);
-
- log_dbg("Packed information received (%zu bytes).", len);
+ enroll_msg__pack(&msg, buf);
- if (rib_unpack(data, len, UNPACK_CREATE)) {
- log_warn("Error unpacking RIB data.");
- rib_del(boot_ro);
- free(data);
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
+ if (flow_write(conn->flow_info.fd, buf, len)) {
+ log_dbg("Failed to send acknowledgment.");
return -1;
}
- log_dbg("Packed information inserted into RIB.");
+ return 0;
+}
+
+void enroll_bootstrap(const struct ipcp_config * conf)
+{
+ assert(conf);
- cdap_destroy(cdap);
- flow_dealloc(conn.flow_info.fd);
+ memcpy(&enroll.conf, conf, sizeof(enroll.conf));
+}
- return 0;
+struct ipcp_config * enroll_get_conf(void)
+{
+ return &enroll.conf;
}
int enroll_init(void)
{
struct conn_info info;
- enroll.cdap = cdap_create();
- if (enroll.cdap == NULL) {
- log_err("Failed to instantiate CDAP.");
- return -1;
- }
-
memset(&info, 0, sizeof(info));
strcpy(info.ae_name, ENROLL_AE);
- strcpy(info.protocol, CDAP_PROTO);
+ strcpy(info.protocol, ENROLL_PROTO);
info.pref_version = 1;
info.pref_syntax = PROTO_GPB;
+ info.addr = 0;
- enroll.ae = connmgr_ae_create(info);
- if (enroll.ae == NULL) {
- cdap_destroy(enroll.cdap);
+ if (connmgr_ae_init(AEID_ENROLL, &info, NULL)) {
+ log_err("Failed to register with connmgr.");
return -1;
}
+ enroll.state = ENROLL_INIT;
+
return 0;
}
void enroll_fini(void)
{
- pthread_join(enroll.listener, NULL);
- cdap_destroy(enroll.cdap);
- connmgr_ae_destroy(enroll.ae);
+ if (enroll.state == ENROLL_RUNNING)
+ pthread_join(enroll.listener, NULL);
+
+ connmgr_ae_fini(AEID_ENROLL);
}
int enroll_start(void)
{
- if (pthread_create(&enroll.listener, NULL, enroll_handle, enroll.cdap))
+ if (pthread_create(&enroll.listener, NULL, enroll_handle, NULL))
return -1;
+ enroll.state = ENROLL_RUNNING;
+
return 0;
}
void enroll_stop(void)
{
- pthread_cancel(enroll.listener);
+ if (enroll.state == ENROLL_RUNNING)
+ pthread_cancel(enroll.listener);
+
+ enroll.state = ENROLL_INIT;
}
diff --git a/src/ipcpd/normal/enroll.h b/src/ipcpd/normal/enroll.h
index 9b50f6bb..3b277e44 100644
--- a/src/ipcpd/normal/enroll.h
+++ b/src/ipcpd/normal/enroll.h
@@ -23,14 +23,26 @@
#ifndef OUROBOROS_IPCPD_NORMAL_ENROLL_H
#define OUROBOROS_IPCPD_NORMAL_ENROLL_H
-int enroll_init(void);
+#include <ouroboros/ipcp.h>
-void enroll_fini(void);
+#include "ae.h"
-int enroll_start(void);
+int enroll_init(void);
-void enroll_stop(void);
+void enroll_fini(void);
-int enroll_boot(const char * dst);
+int enroll_start(void);
+
+void enroll_stop(void);
+
+void enroll_bootstrap(const struct ipcp_config * conf);
+
+int enroll_boot(struct conn * conn,
+ const char * dst);
+
+int enroll_done(struct conn * conn,
+ int result);
+
+struct ipcp_config * enroll_get_conf(void);
#endif /* OUROBOROS_IPCPD_NORMAL_ENROLL_H */
diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/enroll.proto
index e63752c0..2347fb8f 100644
--- a/src/ipcpd/normal/pol-gam-ops.h
+++ b/src/ipcpd/normal/enroll.proto
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * Graph adjacency manager policy ops
+ * Enrollment message
*
* Dimitri Staessens <[email protected]>
* Sander Vrijders <[email protected]>
@@ -20,17 +20,20 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H
-#define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H
+syntax = "proto2";
-#include <ouroboros/cacep.h>
-#include <ouroboros/qos.h>
+import "ipcp_config.proto";
-struct pol_gam_ops {
- void * (* create)(struct nbs * nbs,
- struct ae * ae);
-
- void (* destroy)(void * o);
+enum enroll_code {
+ ENROLL_REQ = 1;
+ ENROLL_BOOT = 2;
+ ENROLL_DONE = 4;
};
-#endif /* OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H */
+message enroll_msg {
+ required enroll_code code = 1;
+ optional ipcp_config_msg conf = 2;
+ optional int64 t_sec = 3;
+ optional uint32 t_nsec = 4;
+ optional int32 result = 5;
+}; \ No newline at end of file
diff --git a/src/ipcpd/normal/flow_alloc.proto b/src/ipcpd/normal/flow_alloc.proto
index 717a1a81..eb078674 100644
--- a/src/ipcpd/normal/flow_alloc.proto
+++ b/src/ipcpd/normal/flow_alloc.proto
@@ -23,16 +23,16 @@
syntax = "proto2";
enum flow_alloc_code {
- FLOW_REQ = 1;
- FLOW_REPLY = 2;
+ FLOW_REQ = 1;
+ FLOW_REPLY = 2;
};
message flow_alloc_msg {
- required flow_alloc_code code = 1;
- optional bytes hash = 2;
- optional uint32 qc = 3;
- optional sint32 response = 4;
- optional uint32 r_fd = 5;
- optional uint32 s_fd = 6;
- optional uint64 s_addr = 7;
+ required flow_alloc_code code = 1;
+ optional bytes hash = 2;
+ optional uint32 qc = 3;
+ optional sint32 response = 4;
+ optional uint32 r_fd = 5;
+ optional uint32 s_fd = 6;
+ optional uint64 s_addr = 7;
};
diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c
deleted file mode 100644
index 3b4cc5de..00000000
--- a/src/ipcpd/normal/gam.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Data transfer graph adjacency manager
- *
- * Dimitri Staessens <[email protected]>
- * Sander Vrijders <[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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define _POSIX_C_SOURCE 200112L
-
-#define OUROBOROS_PREFIX "dt-gam"
-
-#include <ouroboros/cdap.h>
-#include <ouroboros/dev.h>
-#include <ouroboros/logs.h>
-#include <ouroboros/list.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/rib.h>
-
-#include "ipcp.h"
-#include "gam.h"
-#include "pol-gam-ops.h"
-#include "pol/complete.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-
-struct gam {
- struct pol_gam_ops * ops;
- void * ops_o;
-};
-
-struct gam * gam_create(enum pol_gam gam_type,
- struct nbs * nbs,
- struct ae * ae)
-{
- struct gam * gam;
-
- gam = malloc(sizeof(*gam));
- if (gam == NULL)
- return NULL;
-
- switch (gam_type) {
- case COMPLETE:
- gam->ops = &complete_ops;
- break;
- default:
- log_err("Unknown gam policy: %d.", gam_type);
- return NULL;
- }
-
- gam->ops_o = gam->ops->create(nbs, ae);
- if (gam->ops_o == NULL) {
- free(gam);
- return NULL;
- }
-
- return gam;
-}
-
-void gam_destroy(struct gam * gam)
-{
- assert(gam);
-
- gam->ops->destroy(gam->ops_o);
- free(gam);
-}
diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h
deleted file mode 100644
index 3dd01a75..00000000
--- a/src/ipcpd/normal/gam.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Data transfer graph adjacency manager
- *
- * Dimitri Staessens <[email protected]>
- * Sander Vrijders <[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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_IPCPD_NORMAL_GAM_H
-#define OUROBOROS_IPCPD_NORMAL_GAM_H
-
-#include <ouroboros/ipcp.h>
-#include <ouroboros/cacep.h>
-
-#include "neighbors.h"
-
-struct gam * gam_create(enum pol_gam gam_type,
- struct nbs * nbs,
- struct ae * ae);
-
-void gam_destroy(struct gam * gam);
-
-#endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index 53762415..0a41f883 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -54,50 +54,25 @@
#define THIS_TYPE IPCP_NORMAL
-static int boot_components(void)
+static int initialize_components(const struct ipcp_config * conf)
{
- char buf[256];
- ssize_t len;
- enum pol_addr_auth pa;
- char path[RIB_MAX_PATH_LEN + 1];
-
- len = rib_read(BOOT_PATH "/general/dif_name", buf, 256);
- if (len < 0) {
- log_err("Failed to read DIF name: %zd.", len);
- return -1;
+ if (rib_init()) {
+ log_err("Failed to initialize RIB.");
+ goto fail_rib_init;
}
- ipcpi.dif_name = strdup(buf);
+ ipcpi.dif_name = strdup(conf->dif_info.dif_name);
if (ipcpi.dif_name == NULL) {
log_err("Failed to set DIF name.");
- return -1;
+ goto fail_dif_name;
}
- len = rib_read(BOOT_PATH "/general/dir_hash_algo",
- &ipcpi.dir_hash_algo, sizeof(ipcpi.dir_hash_algo));
- if (len < 0) {
- log_err("Failed to read hash length: %zd.", len);
- goto fail_addr_auth;
- }
-
- ipcpi.dir_hash_algo = ntoh32(ipcpi.dir_hash_algo);
+ ipcpi.dir_hash_algo = conf->dif_info.dir_hash_algo;
assert(ipcp_dir_hash_len() != 0);
- if (rib_add(MEMBERS_PATH, ipcpi.name)) {
- log_err("Failed to add name to " MEMBERS_PATH);
- goto fail_addr_auth;
- }
-
- log_dbg("Starting components.");
-
- if (rib_read(BOOT_PATH "/dt/addr_auth/type", &pa, sizeof(pa))
- != sizeof(pa)) {
- log_err("Failed to read policy for address authority.");
- goto fail_addr_auth;
- }
-
- if (addr_auth_init(pa)) {
+ if (addr_auth_init(conf->addr_auth_type,
+ &conf->addr_size)) {
log_err("Failed to init address authority.");
goto fail_addr_auth;
}
@@ -105,40 +80,84 @@ static int boot_components(void)
ipcpi.dt_addr = addr_auth_address();
if (ipcpi.dt_addr == 0) {
log_err("Failed to get a valid address.");
- goto fail_dir;
- }
-
- path[0] = '\0';
- rib_path_append(rib_path_append(path, MEMBERS_NAME), ipcpi.name);
- if (rib_write(path, &ipcpi.dt_addr, sizeof(&ipcpi.dt_addr))) {
- log_err("Failed to write address to member object.");
- goto fail_dir;
+ goto fail_addr_auth;
}
log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr);
- log_dbg("Starting ribmgr.");
-
if (ribmgr_init()) {
log_err("Failed to initialize RIB manager.");
goto fail_ribmgr;
}
- log_dbg("Ribmgr started.");
-
- if (dt_init()) {
- log_err("Failed to initialize data transfer ae.");
+ if (dt_init(conf->routing_type,
+ conf->addr_size,
+ conf->fd_size,
+ conf->has_ttl)) {
+ log_err("Failed to initialize data transfer component.");
goto fail_dt;
}
if (fa_init()) {
- log_err("Failed to initialize flow allocator ae.");
+ log_err("Failed to initialize flow allocator component.");
goto fail_fa;
}
- if (dt_start()) {
- log_err("Failed to start data transfer ae.");
- goto fail_dt_start;
+ if (dir_init()) {
+ log_err("Failed to initialize directory.");
+ goto fail_dir;
+ }
+
+ ipcp_set_state(IPCP_INIT);
+
+ return 0;
+
+ fail_dir:
+ fa_fini();
+ fail_fa:
+ dt_fini();
+ fail_dt:
+ ribmgr_fini();
+ fail_ribmgr:
+ addr_auth_fini();
+ fail_addr_auth:
+ free(ipcpi.dif_name);
+ fail_dif_name:
+ rib_fini();
+ fail_rib_init:
+ return -1;
+}
+
+static void finalize_components(void)
+{
+ dir_fini();
+
+ fa_fini();
+
+ dt_fini();
+
+ ribmgr_fini();
+
+ addr_auth_fini();
+
+ free(ipcpi.dif_name);
+
+ enroll_fini();
+
+ connmgr_fini();
+
+ rib_fini();
+}
+
+static int start_components(void)
+{
+ assert(ipcp_get_state() == IPCP_INIT);
+
+ ipcp_set_state(IPCP_OPERATIONAL);
+
+ if (ribmgr_start()) {
+ log_err("Failed to start RIB manager.");
+ goto fail_ribmgr_start;
}
if (fa_start()) {
@@ -146,20 +165,12 @@ static int boot_components(void)
goto fail_fa_start;
}
- if (dir_init()) {
- log_err("Failed to initialize directory.");
- goto fail_dir;
- }
-
if (enroll_start()) {
- log_err("Failed to start enroll.");
+ log_err("Failed to start enrollment.");
goto fail_enroll_start;
}
- ipcp_set_state(IPCP_OPERATIONAL);
-
if (connmgr_start()) {
- ipcp_set_state(IPCP_INIT);
log_err("Failed to start AP connection manager.");
goto fail_connmgr_start;
}
@@ -169,184 +180,163 @@ static int boot_components(void)
fail_connmgr_start:
enroll_stop();
fail_enroll_start:
- dir_fini();
- fail_dir:
fa_stop();
fail_fa_start:
- dt_stop();
- fail_dt_start:
- fa_fini();
- fail_fa:
- dt_fini();
- fail_dt:
- ribmgr_fini();
- fail_ribmgr:
- addr_auth_fini();
- fail_addr_auth:
- free(ipcpi.dif_name);
-
+ ribmgr_stop();
+ fail_ribmgr_start:
+ ipcp_set_state(IPCP_INIT);
return -1;
}
-void shutdown_components(void)
+static void stop_components(void)
{
+ assert(ipcp_get_state() == IPCP_OPERATIONAL ||
+ ipcp_get_state() == IPCP_SHUTDOWN);
+
connmgr_stop();
enroll_stop();
- dir_fini();
-
fa_stop();
- dt_stop();
+ ribmgr_stop();
- fa_fini();
+ ipcp_set_state(IPCP_INIT);
+}
- dt_fini();
+static int bootstrap_components(void)
+{
+ if (dir_bootstrap()) {
+ log_err("Failed to bootstrap directory.");
+ dt_stop();
+ return -1;
+ }
- ribmgr_fini();
+ return 0;
+}
- addr_auth_fini();
+static int enroll_components(uint64_t peer)
+{
+ if (dir_enroll(peer)) {
+ log_err("Failed to enroll directory.");
+ return -1;
+ }
- free(ipcpi.dif_name);
+ return 0;
}
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.");
- return -1;
+ struct conn er_conn;
+ struct conn dt_conn;
+
+ if (connmgr_alloc(AEID_ENROLL, dst, NULL, &er_conn)) {
+ log_err("Failed to get connection.");
+ goto fail_er_flow;
}
- /* Get boot state from peer */
- if (enroll_boot(dst)) {
- log_err("Failed to boot IPCP components.");
- return -1;
+ /* Get boot state from peer. */
+ if (enroll_boot(&er_conn, dst)) {
+ log_err("Failed to get boot information.");
+ goto fail_enroll_boot;
}
- if (boot_components()) {
- log_err("Failed to boot IPCP components.");
- return -1;
+ if (initialize_components(enroll_get_conf())) {
+ log_err("Failed to initialize IPCP components.");
+ goto fail_enroll_boot;
+ }
+
+ if (dt_start()) {
+ log_err("Failed to initialize IPCP components.");
+ goto fail_dt_start;
+ }
+
+ if (connmgr_alloc(AEID_DT, dst, NULL, &dt_conn)) {
+ log_err("Failed to create a data transfer flow.");
+ goto fail_dt_flow;
+ }
+
+ if (start_components()) {
+ log_err("Failed to start components.");
+ goto fail_start_comp;
+ }
+
+ if (enroll_components(dt_conn.conn_info.addr)) {
+ enroll_done(&er_conn, -1);
+ log_err("Failed to enroll components.");
+ goto fail_enroll_comp;
}
+ if (enroll_done(&er_conn, 0))
+ log_warn("Failed to confirm enrollment with peer.");
+
+ if (connmgr_dealloc(AEID_DT, &dt_conn))
+ log_warn("Failed to deallocate data transfer flow.");
+
+ if (connmgr_dealloc(AEID_ENROLL, &er_conn))
+ log_warn("Failed to deallocate enrollment flow.");
+
log_dbg("Enrolled with %s.", dst);
info->dir_hash_algo = ipcpi.dir_hash_algo;
strcpy(info->dif_name, ipcpi.dif_name);
return 0;
-}
-
-const struct ros {
- char * parent;
- char * child;
-} ros[] = {
- /* BOOT INFO */
- {RIB_ROOT, BOOT_NAME},
- /* OTHER RIB STRUCTURES */
- {RIB_ROOT, MEMBERS_NAME},
-
- /* GENERAL IPCP INFO */
- {BOOT_PATH, "general"},
-
- {BOOT_PATH "/general", "dif_name"},
- {BOOT_PATH "/general", "dir_hash_algo"},
-
- /* DT COMPONENT */
- {BOOT_PATH, "dt"},
-
- {BOOT_PATH "/dt", "gam"},
- {BOOT_PATH "/dt/gam", "type"},
- {BOOT_PATH "/dt/gam", "cacep"},
- {BOOT_PATH "/dt", "const"},
- {BOOT_PATH "/dt/const", "addr_size"},
- {BOOT_PATH "/dt/const", "fd_size"},
- {BOOT_PATH "/dt/const", "has_ttl"},
- {BOOT_PATH "/dt", "addr_auth"},
- {BOOT_PATH "/dt/addr_auth", "type"},
- {BOOT_PATH "/dt", "routing"},
- {BOOT_PATH "/dt/routing", "type"},
-
- /* RIB MGR COMPONENT */
- {BOOT_PATH, "rm"},
- {BOOT_PATH "/rm","gam"},
- {BOOT_PATH "/rm/gam", "type"},
- {BOOT_PATH "/rm/gam", "cacep"},
-
- {NULL, NULL}
-};
-int normal_rib_init(void)
-{
- struct ros * r;
-
- for (r = (struct ros *) ros; r->parent; ++r) {
- if (rib_add(r->parent, r->child)) {
- log_err("Failed to create %s/%s",
- r->parent, r->child);
- return -1;
- }
- }
-
- return 0;
+ fail_enroll_comp:
+ stop_components();
+ fail_start_comp:
+ connmgr_dealloc(AEID_DT, &dt_conn);
+ fail_dt_flow:
+ dt_stop();
+ fail_dt_start:
+ finalize_components();
+ fail_enroll_boot:
+ connmgr_dealloc(AEID_ENROLL, &er_conn);
+ fail_er_flow:
+ return -1;
}
static int normal_ipcp_bootstrap(const struct ipcp_config * conf)
{
- uint32_t hash_algo;
-
assert(conf);
assert(conf->type == THIS_TYPE);
- hash_algo = hton32((uint32_t) conf->dif_info.dir_hash_algo);
+ enroll_bootstrap(conf);
- assert(ntoh32(hash_algo) != 0);
-
- if (normal_rib_init()) {
- log_err("Failed to write initial structure to the RIB.");
- return -1;
+ if (initialize_components(conf)) {
+ log_err("Failed to init IPCP components.");
+ goto fail_init;
}
- if (rib_write(BOOT_PATH "/general/dif_name",
- conf->dif_info.dif_name,
- strlen(conf->dif_info.dif_name) + 1) ||
- rib_write(BOOT_PATH "/general/dir_hash_algo",
- &hash_algo,
- sizeof(hash_algo)) ||
- rib_write(BOOT_PATH "/dt/const/addr_size",
- &conf->addr_size,
- sizeof(conf->addr_size)) ||
- rib_write(BOOT_PATH "/dt/const/fd_size",
- &conf->fd_size,
- sizeof(conf->fd_size)) ||
- rib_write(BOOT_PATH "/dt/const/has_ttl",
- &conf->has_ttl,
- sizeof(conf->has_ttl)) ||
- rib_write(BOOT_PATH "/dt/gam/type",
- &conf->dt_gam_type,
- sizeof(conf->dt_gam_type)) ||
- rib_write(BOOT_PATH "/rm/gam/type",
- &conf->rm_gam_type,
- sizeof(conf->rm_gam_type)) ||
- rib_write(BOOT_PATH "/dt/addr_auth/type",
- &conf->addr_auth_type,
- sizeof(conf->addr_auth_type)) ||
- rib_write(BOOT_PATH "/dt/routing/type",
- &conf->routing_type,
- sizeof(conf->routing_type))) {
- log_err("Failed to write boot info to RIB.");
- return -1;
+ if (dt_start()) {
+ log_err("Failed to initialize IPCP components.");
+ goto fail_dt_start;
+ };
+
+ if (start_components()) {
+ log_err("Failed to init IPCP components.");
+ goto fail_start;
}
- if (boot_components()) {
- log_err("Failed to boot IPCP components.");
- return -1;
+ if (bootstrap_components()) {
+ log_err("Failed to bootstrap IPCP components.");
+ goto fail_bootstrap;
}
log_dbg("Bootstrapped in DIF %s.", conf->dif_info.dif_name);
return 0;
+
+ fail_bootstrap:
+ stop_components();
+ fail_start:
+ dt_stop();
+ fail_dt_start:
+ finalize_components();
+ fail_init:
+ return -1;
}
static int normal_ipcp_query(const uint8_t * dst)
@@ -357,6 +347,8 @@ static int normal_ipcp_query(const uint8_t * dst)
static struct ipcp_ops normal_ops = {
.ipcp_bootstrap = normal_ipcp_bootstrap,
.ipcp_enroll = normal_ipcp_enroll,
+ .ipcp_connect = connmgr_ipcp_connect,
+ .ipcp_disconnect = connmgr_ipcp_disconnect,
.ipcp_reg = dir_reg,
.ipcp_unreg = dir_unreg,
.ipcp_query = normal_ipcp_query,
@@ -378,18 +370,14 @@ int main(int argc,
goto fail_bind_api;
}
- if (rib_init()) {
- log_err("Failed to initialize RIB.");
- goto fail_rib_init;
- }
-
+ /* These components must be init at creation. */
if (connmgr_init()) {
log_err("Failed to initialize connection manager.");
goto fail_connmgr_init;
}
if (enroll_init()) {
- log_err("Failed to initialize enroll component.");
+ log_err("Failed to initialize enrollment component.");
goto fail_enroll_init;
}
@@ -406,14 +394,10 @@ int main(int argc,
ipcp_shutdown();
- if (ipcp_get_state() == IPCP_SHUTDOWN)
- shutdown_components();
-
- enroll_fini();
-
- connmgr_fini();
-
- rib_fini();
+ if (ipcp_get_state() == IPCP_SHUTDOWN) {
+ dt_stop();
+ stop_components();
+ }
irm_unbind_api(getpid(), ipcpi.name);
@@ -428,8 +412,6 @@ int main(int argc,
fail_enroll_init:
connmgr_fini();
fail_connmgr_init:
- rib_fini();
- fail_rib_init:
irm_unbind_api(getpid(), ipcpi.name);
fail_bind_api:
ipcp_fini();
diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c
index 5da0f0df..c32e9aa2 100644
--- a/src/ipcpd/normal/neighbors.c
+++ b/src/ipcpd/normal/neighbors.c
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * Data transfer neighbors
+ * Neighbors
*
* Dimitri Staessens <[email protected]>
* Sander Vrijders <[email protected]>
diff --git a/src/ipcpd/normal/neighbors.h b/src/ipcpd/normal/neighbors.h
index 7047d027..9c5a6e50 100644
--- a/src/ipcpd/normal/neighbors.h
+++ b/src/ipcpd/normal/neighbors.h
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2017
*
- * Data transfer neighbors
+ * Neighbors
*
* Dimitri Staessens <[email protected]>
* Sander Vrijders <[email protected]>
@@ -29,7 +29,7 @@
#include <ouroboros/fqueue.h>
#include <ouroboros/cacep.h>
-#include "connmgr.h"
+#include "ae.h"
enum nb_event {
NEIGHBOR_ADDED,
@@ -40,14 +40,14 @@ enum nb_event {
typedef int (* nb_notify_t)(enum nb_event event,
struct conn conn);
-struct nb_notifier {
+struct nb {
struct list_head next;
- nb_notify_t notify_call;
+ struct conn conn;
};
-struct nb {
+struct nb_notifier {
struct list_head next;
- struct conn conn;
+ nb_notify_t notify_call;
};
struct nbs {
diff --git a/src/ipcpd/normal/pol-addr-auth-ops.h b/src/ipcpd/normal/pol-addr-auth-ops.h
index a3b39298..5d90c64f 100644
--- a/src/ipcpd/normal/pol-addr-auth-ops.h
+++ b/src/ipcpd/normal/pol-addr-auth-ops.h
@@ -24,7 +24,7 @@
#define OUROBOROS_IPCPD_NORMAL_POL_ADDR_AUTH_OPS_H
struct pol_addr_auth_ops {
- int (* init)(void);
+ int (* init)(const void * info);
int (* fini)(void);
diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c
deleted file mode 100644
index 6c6e7372..00000000
--- a/src/ipcpd/normal/pol/complete.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Sets up a complete graph
- *
- * Dimitri Staessens <[email protected]>
- * Sander Vrijders <[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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define _POSIX_C_SOURCE 200112L
-
-#define OUROBOROS_PREFIX "complete"
-
-#include <ouroboros/qoscube.h>
-#include <ouroboros/rib.h>
-#include <ouroboros/dev.h>
-#include <ouroboros/logs.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/cacep.h>
-
-#include "neighbors.h"
-#include "ribconfig.h"
-#include "ipcp.h"
-#include "ae.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define COMPLETE_REFRESH 1000 /* ms */
-
-struct complete {
- struct nbs * nbs;
- struct ae * ae;
- pthread_t allocator;
- pthread_t listener;
-};
-
-static void * listener(void * o)
-{
- struct complete * complete;
- struct conn conn;
-
- complete = (struct complete *) o;
-
- while (true) {
- if (connmgr_wait(complete->ae, &conn)) {
- log_err("Error while getting next connection.");
- continue;
- }
-
- if (nbs_add(complete->nbs, conn)) {
- log_err("Failed to add neighbor.");
- continue;
- }
- }
-
- return (void *) 0;
-}
-
-static void path_reset(char * path)
-{
- path[strlen(MEMBERS_PATH)] = '\0';
-}
-
-static void * allocator(void * o)
-{
- qosspec_t qs;
- ssize_t len;
- char ** children;
- ssize_t i;
- struct complete * complete;
- struct conn conn;
- uint64_t addr;
- char path[RIB_MAX_PATH_LEN];
- struct timespec to = {(COMPLETE_REFRESH / 1000),
- (COMPLETE_REFRESH % 1000) * 1000000};
-
- strcpy(path, MEMBERS_PATH);
-
- complete = (struct complete *) o;
-
- qosspec_init(&qs);
-
- while (true) {
- len = rib_children(MEMBERS_PATH, &children);
- for (i = 0; i < len; ++i) {
- if (strcmp(children[i], ipcpi.name) != 0) {
- path_reset(path);
- rib_path_append(path, children[i]);
- if (rib_read(path, &addr,
- sizeof(addr)) !=
- sizeof(addr)) {
- log_err("Failed to read address.");
- free(children[i]);
- continue;
- }
-
- if (nbs_has(complete->nbs, addr)) {
- free(children[i]);
- continue;
- }
-
- if (connmgr_alloc(complete->ae, children[i],
- &qs, &conn)) {
- log_warn("Failed conn to neighbor.");
- free(children[i]);
- continue;
- }
-
- if (nbs_add(complete->nbs, conn)) {
- log_err("Failed to add neighbor.");
- free(children[i]);
- continue;
- }
- }
-
- free(children[i]);
- }
-
- if (len > 0)
- free(children);
-
- nanosleep(&to, NULL);
- }
-
- return (void *) 0;
-}
-
-void * complete_create(struct nbs * nbs,
- struct ae * ae)
-{
- struct complete * complete;
-
- complete = malloc(sizeof(*complete));
- if (complete == NULL)
- return NULL;
-
- complete->nbs = nbs;
- complete->ae = ae;
-
- if (pthread_create(&complete->allocator, NULL,
- allocator, (void *) complete))
- return NULL;
-
- if (pthread_create(&complete->listener, NULL,
- listener, (void *) complete))
- return NULL;
-
- return complete;
-}
-
-void complete_destroy(void * ops_o)
-{
- struct complete * complete;
-
- assert(ops_o);
-
- complete = (struct complete *) ops_o;
-
- pthread_cancel(complete->allocator);
- pthread_cancel(complete->listener);
- pthread_join(complete->allocator, NULL);
- pthread_join(complete->listener, NULL);
-
- free(complete);
-}
diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h
deleted file mode 100644
index 54c4a9ef..00000000
--- a/src/ipcpd/normal/pol/complete.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Sets up a complete graph
- *
- * Dimitri Staessens <[email protected]>
- * Sander Vrijders <[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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H
-#define OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H
-
-#include <ouroboros/ipcp.h>
-#include <ouroboros/qos.h>
-
-#include "pol-gam-ops.h"
-
-void * complete_create(struct nbs * nbs,
- struct ae * ae);
-
-void complete_destroy(void * ops_o);
-
-struct pol_gam_ops complete_ops = {
- .create = complete_create,
- .destroy = complete_destroy
-};
-
-#endif /* OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H */
diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c
index 1fece07f..7a5a785e 100644
--- a/src/ipcpd/normal/pol/flat.c
+++ b/src/ipcpd/normal/pol/flat.c
@@ -42,47 +42,21 @@
#define NAME_LEN 8
#define REC_DIF_SIZE 10000
-/* convert 32 bit addr to a hex string */
-static void addr_name(char * name,
- uint32_t addr)
-{
- sprintf(name, "%8x", (uint32_t) (addr));
-}
-
-static int addr_taken(char * name,
- char ** members,
- size_t len)
-{
- size_t i;
- char path[RIB_MAX_PATH_LEN + 1];
-
- size_t reset;
- strcpy(path, MEMBERS_PATH);
-
- 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';
- }
-
- return 0;
-}
+struct {
+ uint8_t addr_size;
+} flat;
#define INVALID_ADDRESS 0
-int flat_init(void)
+int flat_init(const void * info)
{
+ flat.addr_size = *((uint8_t *) info);
+
+ if (flat.addr_size != 4) {
+ log_err("Flat address policy mandates 4 byte addresses.");
+ return -1;
+ }
+
return 0;
}
@@ -94,66 +68,12 @@ int flat_fini(void)
uint64_t flat_address(void)
{
struct timespec t;
-
- char path[RIB_MAX_PATH_LEN];
- char name[NAME_LEN + 1];
- uint32_t addr;
- uint8_t addr_size;
-
- char ** members;
- ssize_t n_members;
-
- strcpy(path, MEMBERS_PATH);
-
- if (!rib_has(path)) {
- log_err("Could not read members from RIB.");
- return INVALID_ADDRESS;
- }
-
- 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 (addr_size != 4) {
- log_err("Flat address policy mandates 4 byte addresses.");
- return INVALID_ADDRESS;
- }
-
- n_members = rib_children(path, &members);
- if (n_members > REC_DIF_SIZE)
- log_warn("DIF exceeding recommended size for flat addresses.");
-
- rib_path_append(path, ipcpi.name);
-
- if (!rib_has(path)) {
- log_err("This ipcp is not a member.");
- freepp(char, members, n_members);
- return INVALID_ADDRESS;
- }
+ uint32_t addr;
clock_gettime(CLOCK_REALTIME, &t);
srand(t.tv_nsec);
- assert(n_members > 0);
-
- do {
- addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF;
- addr_name(name, addr);
- } while (addr_taken(name, members, n_members));
-
- freepp(char, members, n_members);
-
- if (rib_add(path, name)) {
- log_err("Failed to add address to RIB.");
- return INVALID_ADDRESS;
- }
-
- if (rib_write(path, &addr, sizeof(addr))) {
- log_err("Failed to write address in RIB.");
- return INVALID_ADDRESS;
- }
+ addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF;
return addr;
}
diff --git a/src/ipcpd/normal/pol/flat.h b/src/ipcpd/normal/pol/flat.h
index af49d283..57af591e 100644
--- a/src/ipcpd/normal/pol/flat.h
+++ b/src/ipcpd/normal/pol/flat.h
@@ -25,8 +25,10 @@
#include "pol-addr-auth-ops.h"
-int flat_init(void);
+int flat_init(const void * info);
+
int flat_fini(void);
+
uint64_t flat_address(void);
struct pol_addr_auth_ops flat_ops = {
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index 9dfed5c0..512ced7f 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -130,10 +130,6 @@ static int link_state_neighbor_event(enum nb_event event,
size_t len;
uint8_t * data;
- /* Only announce the flow if our address is bigger */
- if (ipcpi.dt_addr < conn.conn_info.addr)
- return 0;
-
path[0] = '\0';
sprintf(fso_name, "%" PRIu64 "-%" PRIu64,
ipcpi.dt_addr, conn.conn_info.addr);
@@ -305,42 +301,42 @@ int link_state_init(struct nbs * nbs)
{
link_state.graph = graph_create();
if (link_state.graph == NULL)
- return -1;
+ goto fail_graph;
- if (rib_add(RIB_ROOT, ROUTING_NAME)) {
- graph_destroy(link_state.graph);
- return -1;
- }
+ if (rib_add(RIB_ROOT, ROUTING_NAME))
+ goto fail_rib_add;
link_state.nbs = nbs;
link_state.nb_notifier.notify_call = link_state_neighbor_event;
- if (nbs_reg_notifier(link_state.nbs, &link_state.nb_notifier)) {
- graph_destroy(link_state.graph);
- rib_del(ROUTING_PATH);
- return -1;
- }
+ if (nbs_reg_notifier(link_state.nbs, &link_state.nb_notifier))
+ goto fail_nbs_reg_notifier;
link_state.set = ro_set_create();
- if (link_state.set == NULL) {
- nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier);
- graph_destroy(link_state.graph);
- rib_del(ROUTING_PATH);
- return -1;
- }
+ if (link_state.set == NULL)
+ goto fail_ro_set_create;
link_state.queue = rqueue_create();
- if (link_state.queue == NULL) {
- ro_set_destroy(link_state.set);
- nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier);
- graph_destroy(link_state.graph);
- rib_del(ROUTING_PATH);
- return -1;
- }
+ if (link_state.queue == NULL)
+ goto fail_rqueue_create;
- pthread_create(&link_state.rib_listener, NULL, rib_listener, NULL);
+ if (pthread_create(&link_state.rib_listener, NULL, rib_listener, NULL))
+ goto fail_listener_create;
return 0;
+
+ fail_listener_create:
+ ro_set_destroy(link_state.set);
+ fail_rqueue_create:
+ ro_set_destroy(link_state.set);
+ fail_ro_set_create:
+ nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier);
+ fail_nbs_reg_notifier:
+ rib_del(ROUTING_PATH);
+ fail_rib_add:
+ graph_destroy(link_state.graph);
+ fail_graph:
+ return -1;
}
void link_state_fini(void)
diff --git a/src/ipcpd/normal/ribconfig.h b/src/ipcpd/normal/ribconfig.h
index 3a9b6ecb..f6d10133 100644
--- a/src/ipcpd/normal/ribconfig.h
+++ b/src/ipcpd/normal/ribconfig.h
@@ -27,11 +27,7 @@
#define RIB_MAX_PATH_LEN 256
#define DLR "/"
-#define BOOT_NAME "boot"
-#define MEMBERS_NAME "members"
#define ROUTING_NAME "fsdb"
-#define BOOT_PATH DLR BOOT_NAME
-#define MEMBERS_PATH DLR MEMBERS_NAME
#define ROUTING_PATH DLR ROUTING_NAME
#endif /* OUROBOROS_IPCPD_NORMAL_RIB_CONFIG_H */
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
index ab2aa430..a5e7d6ce 100644
--- a/src/ipcpd/normal/ribmgr.c
+++ b/src/ipcpd/normal/ribmgr.c
@@ -35,10 +35,11 @@
#include <ouroboros/rib.h>
#include "ae.h"
-#include "gam.h"
+#include "connmgr.h"
+#include "ipcp.h"
+#include "neighbors.h"
#include "ribconfig.h"
#include "ribmgr.h"
-#include "ipcp.h"
#include <stdlib.h>
#include <pthread.h>
@@ -46,10 +47,12 @@
#include <errno.h>
#include <assert.h>
+#define MGMT_AE "Management"
#define RIB_SYNC_TIMEOUT 1
enum ribmgr_state {
RIBMGR_NULL = 0,
+ RIBMGR_INIT,
RIBMGR_OPERATIONAL,
RIBMGR_SHUTDOWN
};
@@ -60,7 +63,6 @@ struct {
pthread_t reader;
pthread_t sync;
- struct gam * gam;
struct nbs * nbs;
struct ae * ae;
@@ -300,9 +302,8 @@ static void * sync_rib(void *o)
rib_path_append(path, children[--ch]);
free(children[ch]);
- /* Only sync fsdb and members */
- if (strcmp(path, MEMBERS_PATH) == 0
- || strcmp(path, ROUTING_PATH) == 0)
+ /* Sync fsdb */
+ if (strcmp(path, ROUTING_PATH) == 0)
ribmgr_sync(path);
}
@@ -314,7 +315,6 @@ static void * sync_rib(void *o)
int ribmgr_init(void)
{
- enum pol_gam pg;
struct conn_info info;
memset(&info, 0, sizeof(info));
@@ -323,82 +323,90 @@ int ribmgr_init(void)
strcpy(info.protocol, CDAP_PROTO);
info.pref_version = 1;
info.pref_syntax = PROTO_GPB;
- /* NOTE: Use the same name as the DT AE of this IPCP */
- info.addr = ipcpi.dt_addr;
+ info.addr = 0;
ribmgr.nbs = nbs_create();
if (ribmgr.nbs == NULL) {
log_err("Failed to create neighbors.");
- return -1;
- }
-
- ribmgr.ae = connmgr_ae_create(info);
- if (ribmgr.ae == NULL) {
- log_err("Failed to create AE struct.");
- nbs_destroy(ribmgr.nbs);
- return -1;
+ goto fail_nbs_create;
}
- if (rib_read(BOOT_PATH "/rm/gam/type", &pg, sizeof(pg))
- != sizeof(pg)) {
- log_err("Failed to read policy for ribmgr gam.");
- connmgr_ae_destroy(ribmgr.ae);
- nbs_destroy(ribmgr.nbs);
- return -1;
- }
+ if (connmgr_ae_init(AEID_MGMT, &info, ribmgr.nbs)) {
+ log_err("Failed to register with connmgr.");
+ goto fail_connmgr_ae_init;
+ };
ribmgr.cdap = cdap_create();
if (ribmgr.cdap == NULL) {
log_err("Failed to create CDAP instance.");
- connmgr_ae_destroy(ribmgr.ae);
- nbs_destroy(ribmgr.nbs);
- return -1;
+ goto fail_cdap_create;
}
ribmgr.nb_notifier.notify_call = ribmgr_neighbor_event;
if (nbs_reg_notifier(ribmgr.nbs, &ribmgr.nb_notifier)) {
log_err("Failed to register notifier.");
- cdap_destroy(ribmgr.cdap);
- connmgr_ae_destroy(ribmgr.ae);
- nbs_destroy(ribmgr.nbs);
- return -1;
+ goto fail_nbs_reg_notifier;
}
- ribmgr.gam = gam_create(pg, ribmgr.nbs, ribmgr.ae);
- if (ribmgr.gam == NULL) {
- log_err("Failed to create gam.");
- nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier);
- cdap_destroy(ribmgr.cdap);
- connmgr_ae_destroy(ribmgr.ae);
- nbs_destroy(ribmgr.nbs);
- return -1;
+ if (pthread_rwlock_init(&ribmgr.state_lock, NULL)) {
+ log_err("Failed to init rwlock.");
+ goto fail_rwlock_init;
}
- pthread_rwlock_init(&ribmgr.state_lock, NULL);
-
- ribmgr.state = RIBMGR_OPERATIONAL;
-
- pthread_create(&ribmgr.sync, NULL, sync_rib, NULL);
-
- pthread_create(&ribmgr.reader, NULL, reader, NULL);
+ ribmgr.state = RIBMGR_INIT;
return 0;
+
+ fail_rwlock_init:
+ nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier);
+ fail_nbs_reg_notifier:
+ cdap_destroy(ribmgr.cdap);
+ fail_cdap_create:
+ connmgr_ae_fini(AEID_MGMT);
+ fail_connmgr_ae_init:
+ nbs_destroy(ribmgr.nbs);
+ fail_nbs_create:
+ return -1;
}
void ribmgr_fini(void)
{
- ribmgr_set_state(RIBMGR_SHUTDOWN);
-
- pthread_cancel(ribmgr.reader);
-
- pthread_join(ribmgr.reader, NULL);
- pthread_join(ribmgr.sync, NULL);
+ if (ribmgr_get_state() == RIBMGR_SHUTDOWN) {
+ pthread_join(ribmgr.reader, NULL);
+ pthread_join(ribmgr.sync, NULL);
+ }
nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier);
cdap_destroy(ribmgr.cdap);
- gam_destroy(ribmgr.gam);
- connmgr_ae_destroy(ribmgr.ae);
nbs_destroy(ribmgr.nbs);
+
+ connmgr_ae_fini(AEID_MGMT);
+}
+
+int ribmgr_start(void)
+{
+ ribmgr_set_state(RIBMGR_OPERATIONAL);
+
+ if (pthread_create(&ribmgr.sync, NULL, sync_rib, NULL)) {
+ ribmgr_set_state(RIBMGR_NULL);
+ return -1;
+ }
+
+ if (pthread_create(&ribmgr.reader, NULL, reader, NULL)) {
+ ribmgr_set_state(RIBMGR_SHUTDOWN);
+ pthread_cancel(ribmgr.reader);
+ return -1;
+ }
+
+ return 0;
+}
+
+void ribmgr_stop(void)
+{
+ if (ribmgr_get_state() == RIBMGR_OPERATIONAL) {
+ ribmgr_set_state(RIBMGR_SHUTDOWN);
+ pthread_cancel(ribmgr.reader);
+ }
}
int ribmgr_disseminate(char * path,
diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h
index 7411aedd..20f87548 100644
--- a/src/ipcpd/normal/ribmgr.h
+++ b/src/ipcpd/normal/ribmgr.h
@@ -42,6 +42,10 @@ int ribmgr_init(void);
void ribmgr_fini(void);
+int ribmgr_start(void);
+
+void ribmgr_stop(void);
+
int ribmgr_disseminate(char * path,
enum diss_target target,
enum diss_freq freq,
diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c
index c00ec67c..04e6fd76 100644
--- a/src/ipcpd/normal/routing.c
+++ b/src/ipcpd/normal/routing.c
@@ -29,36 +29,35 @@
#include "routing.h"
#include "pol/link_state.h"
-struct {
- struct pol_routing_ops * ops;
-} routing;
+
+struct pol_routing_ops * r_ops;
int routing_init(enum pol_routing pr,
struct nbs * nbs)
{
switch (pr) {
case LINK_STATE:
- routing.ops = &link_state_ops;
+ r_ops = &link_state_ops;
break;
default:
log_err("Unknown routing type.");
return -1;
}
- return routing.ops->init(nbs);
+ return r_ops->init(nbs);
}
struct routing_i * routing_i_create(struct pff * pff)
{
- return routing.ops->routing_i_create(pff);
+ return r_ops->routing_i_create(pff);
}
void routing_i_destroy(struct routing_i * instance)
{
- return routing.ops->routing_i_destroy(instance);
+ return r_ops->routing_i_destroy(instance);
}
void routing_fini(void)
{
- routing.ops->fini();
+ r_ops->fini();
}
diff --git a/src/ipcpd/normal/sdu_sched.c b/src/ipcpd/normal/sdu_sched.c
index f3550d5c..10b0f02f 100644
--- a/src/ipcpd/normal/sdu_sched.c
+++ b/src/ipcpd/normal/sdu_sched.c
@@ -117,6 +117,8 @@ struct sdu_sched * sdu_sched_create(next_sdu_t callback)
if (sdu_sched == NULL)
goto fail_malloc;
+ assert(callback);
+
sdu_sched->callback = callback;
for (i = 0; i < QOS_CUBE_MAX; ++i) {
@@ -170,6 +172,8 @@ void sdu_sched_add(struct sdu_sched * sdu_sched,
{
qoscube_t qc;
+ assert(sdu_sched);
+
ipcp_flow_get_qoscube(fd, &qc);
flow_set_add(sdu_sched->set[qc], fd);
}
@@ -179,6 +183,8 @@ void sdu_sched_del(struct sdu_sched * sdu_sched,
{
qoscube_t qc;
+ assert(sdu_sched);
+
ipcp_flow_get_qoscube(fd, &qc);
flow_set_del(sdu_sched->set[qc], fd);
}
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c
index bcf5abe2..3d186d7a 100644
--- a/src/ipcpd/shim-eth-llc/main.c
+++ b/src/ipcpd/shim-eth-llc/main.c
@@ -1216,6 +1216,8 @@ static int eth_llc_ipcp_flow_dealloc(int fd)
static struct ipcp_ops eth_llc_ops = {
.ipcp_bootstrap = eth_llc_ipcp_bootstrap,
.ipcp_enroll = NULL,
+ .ipcp_connect = NULL,
+ .ipcp_disconnect = NULL,
.ipcp_reg = eth_llc_ipcp_reg,
.ipcp_unreg = eth_llc_ipcp_unreg,
.ipcp_query = eth_llc_ipcp_query,
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 55fe19a6..0bf57741 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -1092,7 +1092,9 @@ static int ipcp_udp_flow_dealloc(int fd)
static struct ipcp_ops udp_ops = {
.ipcp_bootstrap = ipcp_udp_bootstrap,
- .ipcp_enroll = NULL, /* shim */
+ .ipcp_enroll = NULL,
+ .ipcp_connect = NULL,
+ .ipcp_disconnect = NULL,
.ipcp_reg = ipcp_udp_reg,
.ipcp_unreg = ipcp_udp_unreg,
.ipcp_query = ipcp_udp_query,
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index e1689b91..ed1ad924 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -281,6 +281,67 @@ int ipcp_enroll(pid_t api,
return 0;
}
+int ipcp_connect(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ ipcp_msg_t msg = IPCP_MSG__INIT;
+ ipcp_msg_t * recv_msg = NULL;
+ int ret = -1;
+
+ msg.code = IPCP_MSG_CODE__IPCP_CONNECT;
+ msg.dst_name = (char *) dst;
+ msg.comp_name = (char *) component;
+ msg.has_api = true;
+ msg.api = api;
+
+ recv_msg = send_recv_ipcp_msg(api, &msg);
+ if (recv_msg == NULL) {
+ log_dbg("bad msg");
+ return -EIPCP;
+ }
+
+ if (recv_msg->has_result == false) {
+ ipcp_msg__free_unpacked(recv_msg, NULL);
+ log_dbg("no result.");
+ return -EIPCP;
+ }
+
+ ret = recv_msg->result;
+ ipcp_msg__free_unpacked(recv_msg, NULL);
+
+ return ret;
+}
+
+int ipcp_disconnect(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ ipcp_msg_t msg = IPCP_MSG__INIT;
+ ipcp_msg_t * recv_msg = NULL;
+ int ret = -1;
+
+ msg.code = IPCP_MSG_CODE__IPCP_DISCONNECT;
+ msg.dst_name = (char *) dst;
+ msg.comp_name = (char *) component;
+ msg.has_api = true;
+ msg.api = api;
+
+ recv_msg = send_recv_ipcp_msg(api, &msg);
+ if (recv_msg == NULL)
+ return -EIPCP;
+
+ if (recv_msg->has_result == false) {
+ ipcp_msg__free_unpacked(recv_msg, NULL);
+ return -EIPCP;
+ }
+
+ ret = recv_msg->result;
+ ipcp_msg__free_unpacked(recv_msg, NULL);
+
+ return ret;
+}
+
int ipcp_reg(pid_t api,
const uint8_t * hash,
size_t len)
diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h
index 67d0476f..9c861cde 100644
--- a/src/irmd/ipcp.h
+++ b/src/irmd/ipcp.h
@@ -42,6 +42,14 @@ int ipcp_bootstrap(pid_t api,
ipcp_config_msg_t * conf,
struct dif_info * info);
+int ipcp_connect(pid_t api,
+ const char * dst,
+ const char * component);
+
+int ipcp_disconnect(pid_t api,
+ const char * dst,
+ const char * component);
+
int ipcp_reg(pid_t api,
const uint8_t * hash,
size_t len);
diff --git a/src/irmd/main.c b/src/irmd/main.c
index e72153ae..cc15e092 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -555,6 +555,76 @@ static int enroll_ipcp(pid_t api,
return 0;
}
+static int connect_ipcp(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ struct ipcp_entry * entry = NULL;
+
+ pthread_rwlock_rdlock(&irmd.reg_lock);
+
+ entry = get_ipcp_entry_by_api(api);
+ if (entry == NULL) {
+ pthread_rwlock_unlock(&irmd.reg_lock);
+ log_err("No such IPCP.");
+ return -EIPCP;
+ }
+
+ if (entry->type != IPCP_NORMAL) {
+ pthread_rwlock_unlock(&irmd.reg_lock);
+ log_err("Cannot establish connections for this IPCP type.");
+ return -EIPCP;
+ }
+
+ pthread_rwlock_unlock(&irmd.reg_lock);
+
+ log_dbg("Connecting %s to %s.", component, dst);
+
+ if (ipcp_connect(api, dst, component)) {
+ log_err("Could not connect IPCP.");
+ return -EPERM;
+ }
+
+ log_info("Established %s connection between IPCP %d and %s.",
+ component, api, dst);
+
+ return 0;
+}
+
+static int disconnect_ipcp(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ struct ipcp_entry * entry = NULL;
+
+ pthread_rwlock_rdlock(&irmd.reg_lock);
+
+ entry = get_ipcp_entry_by_api(api);
+ if (entry == NULL) {
+ pthread_rwlock_unlock(&irmd.reg_lock);
+ log_err("No such IPCP.");
+ return -EIPCP;
+ }
+
+ if (entry->type != IPCP_NORMAL) {
+ pthread_rwlock_unlock(&irmd.reg_lock);
+ log_err("Cannot tear down connections for this IPCP type.");
+ return -EIPCP;
+ }
+
+ pthread_rwlock_unlock(&irmd.reg_lock);
+
+ if (ipcp_disconnect(api, dst, component)) {
+ log_err("Could not disconnect IPCP.");
+ return -EPERM;
+ }
+
+ log_info("%s connection between IPCP %d and %s torn down.",
+ component, api, dst);
+
+ return 0;
+}
+
static int bind_ap(char * ap,
char * name,
uint16_t flags,
@@ -1876,6 +1946,18 @@ void * mainloop(void * o)
ret_msg.result = enroll_ipcp(msg->api,
msg->dif_name[0]);
break;
+ case IRM_MSG_CODE__IRM_CONNECT_IPCP:
+ ret_msg.has_result = true;
+ ret_msg.result = connect_ipcp(msg->api,
+ msg->dst_name,
+ msg->comp_name);
+ break;
+ case IRM_MSG_CODE__IRM_DISCONNECT_IPCP:
+ ret_msg.has_result = true;
+ ret_msg.result = disconnect_ipcp(msg->api,
+ msg->dst_name,
+ msg->comp_name);
+ break;
case IRM_MSG_CODE__IRM_BIND_AP:
ret_msg.has_result = true;
ret_msg.result = bind_ap(msg->ap_name,
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 9b41e5d4..cfcfdf81 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -857,8 +857,7 @@ int flow_dealloc(int fd)
if (!recv_msg->has_result) {
irm_msg__free_unpacked(recv_msg, NULL);
- assert(false);
- return -1;
+ return -EIRMD;
}
irm_msg__free_unpacked(recv_msg, NULL);
diff --git a/src/lib/ipcp_config.proto b/src/lib/ipcp_config.proto
index f0d5f6eb..4ede5060 100644
--- a/src/lib/ipcp_config.proto
+++ b/src/lib/ipcp_config.proto
@@ -35,12 +35,10 @@ message ipcp_config_msg {
optional uint32 fd_size = 4;
optional bool has_ttl = 5;
optional uint32 addr_auth_type = 6;
- optional uint32 dt_gam_type = 7;
- optional uint32 rm_gam_type = 8;
- optional uint32 routing_type = 9;
+ optional uint32 routing_type = 7;
// Config for shim UDP
- optional uint32 ip_addr = 10;
- optional uint32 dns_addr = 11;
+ optional uint32 ip_addr = 8;
+ optional uint32 dns_addr = 9;
// Config for the shim Ethernet LLC
- optional string if_name = 12;
+ optional string if_name = 10;
}
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index 2e6c0497..691b76ad 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -33,7 +33,9 @@ enum ipcp_msg_code {
IPCP_FLOW_ALLOC = 6;
IPCP_FLOW_ALLOC_RESP = 7;
IPCP_FLOW_DEALLOC = 8;
- IPCP_REPLY = 9;
+ IPCP_CONNECT = 9;
+ IPCP_DISCONNECT = 10;
+ IPCP_REPLY = 11;
};
message ipcp_msg {
@@ -47,5 +49,6 @@ message ipcp_msg {
optional int32 api = 8;
optional dif_info_msg dif_info = 9;
optional int32 response = 10;
- optional int32 result = 11;
+ optional string comp_name = 11;
+ optional int32 result = 12;
};
diff --git a/src/lib/irm.c b/src/lib/irm.c
index 4232cec1..ce17bf18 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -121,10 +121,6 @@ int irm_bootstrap_ipcp(pid_t api,
config.has_ttl = conf->has_ttl;
config.has_addr_auth_type = true;
config.addr_auth_type = conf->addr_auth_type;
- config.has_dt_gam_type = true;
- config.dt_gam_type = conf->dt_gam_type;
- config.has_rm_gam_type = true;
- config.rm_gam_type = conf->rm_gam_type;
config.has_routing_type = true;
config.routing_type = conf->routing_type;
dif_info.dir_hash_algo = conf->dif_info.dir_hash_algo;
@@ -150,7 +146,65 @@ int irm_bootstrap_ipcp(pid_t api,
if (recv_msg->has_result == false) {
irm_msg__free_unpacked(recv_msg, NULL);
- return -1;
+ return -EIRMD;
+ }
+
+ ret = recv_msg->result;
+ irm_msg__free_unpacked(recv_msg, NULL);
+
+ return ret;
+}
+
+int irm_connect_ipcp(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ int ret;
+
+ msg.code = IRM_MSG_CODE__IRM_CONNECT_IPCP;
+ msg.dst_name = (char *) dst;
+ msg.comp_name = (char *) component;
+ msg.has_api = true;
+ msg.api = api;
+
+ recv_msg = send_recv_irm_msg(&msg);
+ if (recv_msg == NULL)
+ return -EIRMD;
+
+ if (recv_msg->has_result == false) {
+ irm_msg__free_unpacked(recv_msg, NULL);
+ return -EIRMD;
+ }
+
+ ret = recv_msg->result;
+ irm_msg__free_unpacked(recv_msg, NULL);
+
+ return ret;
+}
+
+int irm_disconnect_ipcp(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ int ret;
+
+ msg.code = IRM_MSG_CODE__IRM_DISCONNECT_IPCP;
+ msg.dst_name = (char *) dst;
+ msg.comp_name = (char *) component;
+ msg.has_api = true;
+ msg.api = api;
+
+ recv_msg = send_recv_irm_msg(&msg);
+ if (recv_msg == NULL)
+ return -EIRMD;
+
+ if (recv_msg->has_result == false) {
+ irm_msg__free_unpacked(recv_msg, NULL);
+ return -EIRMD;
}
ret = recv_msg->result;
@@ -162,15 +216,15 @@ int irm_bootstrap_ipcp(pid_t api,
ssize_t irm_list_ipcps(const char * name,
pid_t ** apis)
{
- irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t msg = IRM_MSG__INIT;
irm_msg_t * recv_msg = NULL;
- size_t nr = 0;
+ size_t nr = 0;
size_t i;
if (apis == NULL)
return -EINVAL;
- msg.code = IRM_MSG_CODE__IRM_LIST_IPCPS;
+ msg.code = IRM_MSG_CODE__IRM_LIST_IPCPS;
msg.dst_name = (char *) name;
recv_msg = send_recv_irm_msg(&msg);
diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto
index 117752c8..723f6fb3 100644
--- a/src/lib/irmd_messages.proto
+++ b/src/lib/irmd_messages.proto
@@ -31,19 +31,21 @@ enum irm_msg_code {
IRM_LIST_IPCPS = 4;
IRM_BOOTSTRAP_IPCP = 5;
IRM_ENROLL_IPCP = 6;
- IRM_BIND_AP = 7;
- IRM_UNBIND_AP = 8;
- IRM_API_ANNOUNCE = 9;
- IRM_BIND_API = 10;
- IRM_UNBIND_API = 11;
- IRM_REG = 12;
- IRM_UNREG = 13;
- IRM_FLOW_ALLOC = 14;
- IRM_FLOW_ACCEPT = 15;
- IRM_FLOW_DEALLOC = 16;
- IPCP_FLOW_REQ_ARR = 17;
- IPCP_FLOW_ALLOC_REPLY = 18;
- IRM_REPLY = 19;
+ IRM_CONNECT_IPCP = 7;
+ IRM_DISCONNECT_IPCP = 8;
+ IRM_BIND_AP = 9;
+ IRM_UNBIND_AP = 10;
+ IRM_API_ANNOUNCE = 11;
+ IRM_BIND_API = 12;
+ IRM_UNBIND_API = 13;
+ IRM_REG = 14;
+ IRM_UNREG = 15;
+ IRM_FLOW_ALLOC = 16;
+ IRM_FLOW_ACCEPT = 17;
+ IRM_FLOW_DEALLOC = 18;
+ IPCP_FLOW_REQ_ARR = 19;
+ IPCP_FLOW_ALLOC_REPLY = 20;
+ IRM_REPLY = 21;
};
message irm_msg {
@@ -63,5 +65,6 @@ message irm_msg {
repeated sint32 apis = 14;
optional uint32 timeo_sec = 15;
optional uint32 timeo_nsec = 16;
- optional sint32 result = 17;
+ optional string comp_name = 17;
+ optional sint32 result = 18;
};
diff --git a/src/lib/rib.c b/src/lib/rib.c
index 104dc0cc..bbe996e7 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -373,7 +373,8 @@ static void destroy_rnode(struct rnode * node)
branch_hash(node->parent);
}
- rnode_throw_event(node, RO_DELETE);
+ if (node->parent != NULL)
+ rnode_throw_event(node->parent, RO_DELETE);
list_for_each_safe(p, h, &node->subs) {
struct rn_sub * s = list_entry(p, struct rn_sub, next);
diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt
index 300ad982..895bc746 100644
--- a/src/tools/irm/CMakeLists.txt
+++ b/src/tools/irm/CMakeLists.txt
@@ -14,6 +14,8 @@ set(SOURCE_FILES
irm_ipcp_destroy.c
irm_ipcp_bootstrap.c
irm_ipcp_enroll.c
+ irm_ipcp_connect.c
+ irm_ipcp_disconnect.c
irm_unbind_ap.c
irm_unbind_api.c
irm_unbind_ipcp.c
diff --git a/src/tools/irm/irm_ipcp.c b/src/tools/irm/irm_ipcp.c
index 2850ac89..2f7b01c9 100644
--- a/src/tools/irm/irm_ipcp.c
+++ b/src/tools/irm/irm_ipcp.c
@@ -45,17 +45,19 @@ static const struct cmd {
const char * cmd;
int (* func)(int argc, char ** argv);
} cmds[] = {
- { "create", do_create_ipcp },
- { "destroy", do_destroy_ipcp },
- { "bootstrap", do_bootstrap_ipcp },
- { "enroll", do_enroll_ipcp },
- { "help", do_help },
- { NULL, NULL }
+ { "create", do_create_ipcp },
+ { "destroy", do_destroy_ipcp },
+ { "bootstrap", do_bootstrap_ipcp },
+ { "enroll", do_enroll_ipcp },
+ { "connect", do_connect_ipcp },
+ { "disconnect", do_disconnect_ipcp },
+ { "help", do_help },
+ { NULL, NULL }
};
static int do_cmd(const char * argv0,
- int argc,
- char ** argv)
+ int argc,
+ char ** argv)
{
const struct cmd * c;
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c
index 264fbfd5..a4a4d326 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -48,13 +48,9 @@
#define DEFAULT_FD_SIZE 2
#define DEFAULT_DDNS 0
#define DEFAULT_ADDR_AUTH FLAT_RANDOM
-#define DEFAULT_DT_GAM COMPLETE
-#define DEFAULT_RM_GAM COMPLETE
#define DEFAULT_ROUTING LINK_STATE
#define DEFAULT_HASH_ALGO DIR_HASH_SHA3_256
#define ADDR_AUTH_FLAT "flat"
-#define DT_GAM_COMPLETE "complete"
-#define RM_GAM_COMPLETE "complete"
#define ROUTING_LINK_STATE "link_state"
static void usage(void)
@@ -71,10 +67,6 @@ static void usage(void)
" [fd <fd size> (default: %d)]\n"
" [ttl (add time to live value in the PCI)]\n"
" [addr_auth <address policy> (default: %s)]\n"
- " [dt_gam <data transfer graph adjacency manager>"
- " (default: %s)]\n"
- " [rm_gam <rib manager graph adjacency manager>"
- " (default: %s)]\n"
" [routing <routing policy> (default: %s)]\n"
" [hash [ALGORITHM] (default: %s)]\n"
"where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
@@ -86,8 +78,7 @@ static void usage(void)
"if TYPE == " SHIM_ETH_LLC "\n"
" if_name <interface name>\n",
DEFAULT_ADDR_SIZE, DEFAULT_FD_SIZE,
- ADDR_AUTH_FLAT, DT_GAM_COMPLETE, RM_GAM_COMPLETE,
- ROUTING_LINK_STATE, SHA3_256);
+ ADDR_AUTH_FLAT, ROUTING_LINK_STATE, SHA3_256);
}
int do_bootstrap_ipcp(int argc, char ** argv)
@@ -99,8 +90,6 @@ int do_bootstrap_ipcp(int argc, char ** argv)
uint8_t fd_size = DEFAULT_FD_SIZE;
bool has_ttl = false;
enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH;
- enum pol_gam dt_gam_type = DEFAULT_DT_GAM;
- enum pol_gam rm_gam_type = DEFAULT_RM_GAM;
enum pol_routing routing_type = DEFAULT_ROUTING;
enum pol_dir_hash hash_algo = DEFAULT_HASH_ALGO;
uint32_t ip_addr = 0;
@@ -151,16 +140,6 @@ int do_bootstrap_ipcp(int argc, char ** argv)
addr_auth_type = FLAT_RANDOM;
else
goto unknown_param;
- } else if (matches(*argv, "dt_gam") == 0) {
- if (strcmp(DT_GAM_COMPLETE, *(argv + 1)) == 0)
- dt_gam_type = COMPLETE;
- else
- goto unknown_param;
- } else if (matches(*argv, "rm_gam") == 0) {
- if (strcmp(RM_GAM_COMPLETE, *(argv + 1)) == 0)
- rm_gam_type = COMPLETE;
- else
- goto unknown_param;
} else if (matches(*argv, "routing") == 0) {
if (strcmp(ROUTING_LINK_STATE, *(argv + 1)) == 0)
routing_type = LINK_STATE;
@@ -188,8 +167,6 @@ int do_bootstrap_ipcp(int argc, char ** argv)
conf.fd_size = fd_size;
conf.has_ttl = has_ttl;
conf.addr_auth_type = addr_auth_type;
- conf.dt_gam_type = dt_gam_type;
- conf.rm_gam_type = rm_gam_type;
conf.routing_type = routing_type;
conf.dif_info.dir_hash_algo = hash_algo;
} else if (strcmp(ipcp_type, SHIM_UDP) == 0) {
diff --git a/src/tools/irm/irm_ipcp_connect.c b/src/tools/irm/irm_ipcp_connect.c
new file mode 100644
index 00000000..168c8d17
--- /dev/null
+++ b/src/tools/irm/irm_ipcp_connect.c
@@ -0,0 +1,94 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Connect components of normal IPC Processes
+ *
+ * Dimitri Staessens <[email protected]>
+ * Sander Vrijders <[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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#include <ouroboros/irm.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DT "dt"
+#define MGMT "mgmt"
+
+static void usage(void)
+{
+ printf("Usage: irm ipcp connect\n"
+ " name <ipcp name>\n"
+ " comp <COMPONENT>\n"
+ " dst <name of destination IPCP>\n"
+ "where COMPONENT = {" DT " " MGMT "},\n\n");
+}
+
+int do_connect_ipcp(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ char * dst_name = NULL;
+ char * comp_name = NULL;
+ pid_t * apis = NULL;
+ ssize_t len = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "name") == 0) {
+ name = *(argv + 1);
+ } else if (matches(*argv, "dst") == 0) {
+ dst_name = *(argv + 1);
+ } else if (matches(*argv, "comp") == 0) {
+ comp_name = *(argv + 1);
+ } else {
+ printf("\"%s\" is unknown, try \"irm "
+ "ipcpi connect\".\n", *argv);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (name == NULL || dst_name == NULL || comp_name == NULL) {
+ usage();
+ return -1;
+ }
+
+ len = irm_list_ipcps(name, &apis);
+ if (len != 1)
+ return -1;
+
+ if (!strcmp(comp_name, DT))
+ comp_name = DT_AE;
+
+ if (!strcmp(comp_name , MGMT))
+ comp_name = MGMT_AE;
+
+ if (irm_connect_ipcp(apis[0], dst_name, comp_name)) {
+ free(apis);
+ return -1;
+ }
+
+ if (apis != NULL)
+ free(apis);
+
+ return 0;
+}
diff --git a/src/tools/irm/irm_ipcp_disconnect.c b/src/tools/irm/irm_ipcp_disconnect.c
new file mode 100644
index 00000000..8f83f3e8
--- /dev/null
+++ b/src/tools/irm/irm_ipcp_disconnect.c
@@ -0,0 +1,94 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Connect components of normal IPC Processes
+ *
+ * Dimitri Staessens <[email protected]>
+ * Sander Vrijders <[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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#include <ouroboros/irm.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DT "dt"
+#define MGMT "mgmt"
+
+static void usage(void)
+{
+ printf("Usage: irm ipcp disconnect\n"
+ " name <ipcp name>\n"
+ " comp <COMPONENT>\n"
+ " dst <name of destination IPCP>\n"
+ "where COMPONENT = {" DT " " MGMT "},\n\n");
+}
+
+int do_disconnect_ipcp(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ char * dst_name = NULL;
+ char * comp_name = NULL;
+ pid_t * apis = NULL;
+ ssize_t len = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "name") == 0) {
+ name = *(argv + 1);
+ } else if (matches(*argv, "dst") == 0) {
+ dst_name = *(argv + 1);
+ } else if (matches(*argv, "comp") == 0) {
+ comp_name = *(argv + 1);
+ } else {
+ printf("\"%s\" is unknown, try \"irm "
+ "ipcpi connect\".\n", *argv);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (name == NULL || dst_name == NULL || comp_name == NULL) {
+ usage();
+ return -1;
+ }
+
+ len = irm_list_ipcps(name, &apis);
+ if (len != 1)
+ return -1;
+
+ if (!strcmp(comp_name, DT))
+ comp_name = DT_AE;
+
+ if (!strcmp(comp_name , MGMT))
+ comp_name = MGMT_AE;
+
+ if (irm_disconnect_ipcp(apis[0], dst_name, comp_name)) {
+ free(apis);
+ return -1;
+ }
+
+ if (apis != NULL)
+ free(apis);
+
+ return 0;
+}
diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h
index 749ea13d..a2bc40b4 100644
--- a/src/tools/irm/irm_ops.h
+++ b/src/tools/irm/irm_ops.h
@@ -35,6 +35,12 @@ int do_bootstrap_ipcp(int argc,
int do_enroll_ipcp(int argc,
char ** argv);
+int do_connect_ipcp(int argc,
+ char ** argv);
+
+int do_disconnect_ipcp(int argc,
+ char ** argv);
+
int bind_cmd(int argc,
char ** argv);