summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/cacep.h47
-rw-r--r--include/ouroboros/irm.h4
-rw-r--r--include/ouroboros/irm_config.h32
-rw-r--r--include/ouroboros/wrap/CMakeLists.txt3
-rw-r--r--include/ouroboros/wrap/ouroboros.i2
-rw-r--r--src/ipcpd/ipcp.c17
-rw-r--r--src/ipcpd/ipcp.h3
-rw-r--r--src/ipcpd/local/main.c8
-rw-r--r--src/ipcpd/normal/CMakeLists.txt2
-rw-r--r--src/ipcpd/normal/fmgr.c197
-rw-r--r--src/ipcpd/normal/fmgr.h10
-rw-r--r--src/ipcpd/normal/gam.c285
-rw-r--r--src/ipcpd/normal/gam.h46
-rw-r--r--src/ipcpd/normal/main.c27
-rw-r--r--src/ipcpd/normal/pol-gam-ops.h40
-rw-r--r--src/ipcpd/normal/pol/complete.c208
-rw-r--r--src/ipcpd/normal/pol/complete.h46
-rw-r--r--src/ipcpd/normal/ribmgr.c19
-rw-r--r--src/ipcpd/normal/ribmgr.h2
-rw-r--r--src/ipcpd/normal/static_info.proto19
-rw-r--r--src/ipcpd/shim-eth-llc/main.c8
-rw-r--r--src/ipcpd/shim-udp/main.c8
-rw-r--r--src/irmd/ipcp.c12
-rw-r--r--src/irmd/ipcp.h6
-rw-r--r--src/irmd/main.c2
-rw-r--r--src/lib/CMakeLists.txt11
-rw-r--r--src/lib/cacep.c170
-rw-r--r--src/lib/cacep.proto29
-rw-r--r--src/lib/dif_config.proto7
-rw-r--r--src/lib/irm.c2
-rw-r--r--src/tools/irm/irm_ipcp_bootstrap.c15
-rw-r--r--src/tools/irm/irm_ipcp_create.c3
-rw-r--r--src/tools/irm/irm_ipcp_enroll.c1
33 files changed, 1117 insertions, 174 deletions
diff --git a/include/ouroboros/cacep.h b/include/ouroboros/cacep.h
new file mode 100644
index 00000000..ae615e6e
--- /dev/null
+++ b/include/ouroboros/cacep.h
@@ -0,0 +1,47 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * The Common Application Connection Establishment Phase
+ *
+ * Sander Vrijders <[email protected]>
+ * Dimitri Staessens <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef OUROBOROS_CACEP_H
+#define OUROBOROS_CACEP_H
+
+#include <stdint.h>
+#include <unistd.h>
+
+struct cacep;
+
+struct cacep_info {
+ char * name;
+ uint64_t addr;
+};
+
+struct cacep * cacep_create(int fd,
+ const char * name,
+ uint64_t address);
+
+int cacep_destroy(struct cacep * instance);
+
+struct cacep_info * cacep_auth(struct cacep * instance);
+
+struct cacep_info * cacep_auth_wait(struct cacep * instance);
+
+#endif /* OUROBOROS_CACEP_H */
diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h
index b281d4c5..79e3e7c9 100644
--- a/include/ouroboros/irm.h
+++ b/include/ouroboros/irm.h
@@ -50,10 +50,10 @@ int irm_bind_ap(char * ap,
int irm_unbind_ap(char * ap,
char * name);
-int irm_bind_api(pid_t api,
+int irm_bind_api(pid_t api,
char * name);
-int irm_unbind_api(pid_t api,
+int irm_unbind_api(pid_t api,
char * name);
int irm_reg(char * name,
diff --git a/include/ouroboros/irm_config.h b/include/ouroboros/irm_config.h
index ac94e9c8..c4a81c23 100644
--- a/include/ouroboros/irm_config.h
+++ b/include/ouroboros/irm_config.h
@@ -43,36 +43,40 @@ enum pol_addr_auth {
FLAT_RANDOM = 0
};
+enum pol_gam {
+ COMPLETE = 0
+};
+
struct dif_config {
- char * dif_name;
+ char * dif_name;
enum ipcp_type type;
union {
/* Normal DIF */
struct {
- uint8_t addr_size;
- uint8_t cep_id_size;
- uint8_t pdu_length_size;
- uint8_t qos_id_size;
- uint8_t seqno_size;
+ uint8_t addr_size;
+ uint8_t cep_id_size;
+ uint8_t pdu_length_size;
+ uint8_t qos_id_size;
+ uint8_t seqno_size;
- /* DUP constants */
- bool has_ttl;
- bool has_chk;
+ bool has_ttl;
+ bool has_chk;
- uint32_t min_pdu_size;
- uint32_t max_pdu_size;
+ uint32_t min_pdu_size;
+ uint32_t max_pdu_size;
enum pol_addr_auth addr_auth_type;
+ enum pol_gam dt_gam_type;
};
/* Shim UDP */
struct {
- uint32_t ip_addr;
- uint32_t dns_addr;
+ uint32_t ip_addr;
+ uint32_t dns_addr;
};
/* Shim Ethernet LLC */
struct {
- char * if_name;
+ char * if_name;
};
};
};
diff --git a/include/ouroboros/wrap/CMakeLists.txt b/include/ouroboros/wrap/CMakeLists.txt
index 16c86611..7753ca02 100644
--- a/include/ouroboros/wrap/CMakeLists.txt
+++ b/include/ouroboros/wrap/CMakeLists.txt
@@ -16,6 +16,9 @@ else ()
else ()
include_directories(${PYTHON_INCLUDE_PATH})
+ # Python assumes C99 since Python 3.6
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
+
swig_add_module(ouroboros python ouroboros.i)
swig_link_libraries(ouroboros ${PYTHON_LIBRARIES} ouroboros)
diff --git a/include/ouroboros/wrap/ouroboros.i b/include/ouroboros/wrap/ouroboros.i
index 23d05f7b..b156eb36 100644
--- a/include/ouroboros/wrap/ouroboros.i
+++ b/include/ouroboros/wrap/ouroboros.i
@@ -22,6 +22,7 @@
%module ouroboros
%{
+#include "ouroboros/cacep.h"
#include "ouroboros/cdap.h"
#include "ouroboros/dev.h"
#include "ouroboros/errno.h"
@@ -35,6 +36,7 @@
typedef int pid_t;
+#include "ouroboros/cacep.h"
%include "ouroboros/cdap.h"
%include "ouroboros/dev.h"
%include "ouroboros/errno.h"
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index 2e4c3fca..a94e268d 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -128,6 +128,7 @@ static void * ipcp_main_loop(void * o)
conf.min_pdu_size = conf_msg->min_pdu_size;
conf.max_pdu_size = conf_msg->max_pdu_size;
conf.addr_auth_type = conf_msg->addr_auth_type;
+ conf.dt_gam_type = conf_msg->dt_gam_type;
}
if (conf_msg->ipcp_type == IPCP_SHIM_UDP) {
conf.ip_addr = conf_msg->ip_addr;
@@ -440,22 +441,26 @@ int ipcp_parse_arg(int argc, char * argv[])
if (atoi(argv[1]) == 0)
return -1;
- if (argv[2] == NULL)
+ ipcpi.irmd_api = atoi(argv[1]);
+
+ /* argument 2: IPCP name */
+ ipcpi.name = argv[2];
+
+ /* argument 3: logfile name (if any) */
+ if (argv[3] == NULL)
return 0;
len += strlen(INSTALL_PREFIX);
len += strlen(LOG_DIR);
- len += strlen(argv[2]);
+ len += strlen(argv[3]);
log_file = malloc(len + 1);
- if (log_file == NULL) {
- LOG_ERR("Failed to malloc");
+ if (log_file == NULL)
return -1;
- }
strcpy(log_file, INSTALL_PREFIX);
strcat(log_file, LOG_DIR);
- strcat(log_file, argv[2]);
+ strcat(log_file, argv[3]);
log_file[len] = '\0';
if (set_logfile(log_file))
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index ae5a56da..a75186ba 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -38,6 +38,9 @@ enum ipcp_state {
};
struct ipcp {
+ int irmd_api;
+ char * name;
+
struct ipcp_data * data;
struct ipcp_ops * ops;
int irmd_fd;
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 58949aea..5117f59d 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -41,9 +41,6 @@
#define EVENT_WAIT_TIMEOUT 100 /* us */
#define THIS_TYPE IPCP_LOCAL
-/* global for trapping signal */
-int irmd_api;
-
struct {
int in_out[IRMD_MAX_FLOWS];
flow_set_t * flows;
@@ -127,7 +124,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
case SIGTERM:
case SIGHUP:
case SIGQUIT:
- if (info->si_pid == irmd_api) {
+ if (info->si_pid == ipcpi.irmd_api) {
pthread_rwlock_wrlock(&ipcpi.state_lock);
if (ipcp_get_state() == IPCP_INIT)
@@ -349,9 +346,6 @@ int main(int argc, char * argv[])
exit(EXIT_FAILURE);
}
- /* store the process id of the irmd */
- irmd_api = atoi(argv[1]);
-
/* init sig_act */
memset(&sig_act, 0, sizeof(sig_act));
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt
index bdcb78ae..157baa9e 100644
--- a/src/ipcpd/normal/CMakeLists.txt
+++ b/src/ipcpd/normal/CMakeLists.txt
@@ -29,12 +29,14 @@ set(SOURCE_FILES
dir.c
fmgr.c
frct.c
+ gam.c
main.c
pathname.c
pff.c
ribmgr.c
shm_pci.c
# Add policies last
+ pol/complete.c
pol/flat.c
)
diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c
index a419e9f5..6fe6fb60 100644
--- a/src/ipcpd/normal/fmgr.c
+++ b/src/ipcpd/normal/fmgr.c
@@ -28,6 +28,7 @@
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/errno.h>
+#include <ouroboros/cacep.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -42,15 +43,24 @@
#include "dir.h"
#include "pathname.h"
#include "ro.h"
+#include "gam.h"
#include "flow_alloc.pb-c.h"
typedef FlowAllocMsg flow_alloc_msg_t;
#define FD_UPDATE_TIMEOUT 100000 /* nanoseconds */
+struct nm1_flow {
+ struct list_head next;
+ int fd;
+ qosspec_t qs;
+ struct cacep_info * info;
+};
+
struct {
flow_set_t * nm1_set[QOS_CUBE_MAX];
fqueue_t * nm1_fqs[QOS_CUBE_MAX];
+ struct list_head nm1_flows;
pthread_rwlock_t nm1_flows_lock;
flow_set_t * np1_set[QOS_CUBE_MAX];
@@ -60,21 +70,23 @@ struct {
cep_id_t np1_fd_to_cep_id[AP_MAX_FLOWS];
int np1_cep_id_to_fd[IPCPD_MAX_CONNS];
- pthread_t nm1_sdu_reader;
pthread_t np1_sdu_reader;
+ pthread_t nm1_sdu_reader;
+ pthread_t nm1_flow_wait;
/* FIXME: Replace with PFF */
int fd;
+
+ struct gam * gam;
} fmgr;
static void * fmgr_np1_sdu_reader(void * o)
{
struct shm_du_buff * sdb;
- struct timespec timeout = {0, FD_UPDATE_TIMEOUT};
- int fd;
-
- int i = 0;
- int ret;
+ struct timespec timeout = {0, FD_UPDATE_TIMEOUT};
+ int fd;
+ int i = 0;
+ int ret;
(void) o;
@@ -118,12 +130,12 @@ static void * fmgr_np1_sdu_reader(void * o)
void * fmgr_nm1_sdu_reader(void * o)
{
- struct timespec timeout = {0, FD_UPDATE_TIMEOUT};
+ struct timespec timeout = {0, FD_UPDATE_TIMEOUT};
struct shm_du_buff * sdb;
- struct pci * pci;
- int fd;
- int i = 0;
- int ret;
+ struct pci * pci;
+ int fd;
+ int i = 0;
+ int ret;
(void) o;
@@ -202,6 +214,49 @@ void * fmgr_nm1_sdu_reader(void * o)
return (void *) 0;
}
+static void * fmgr_nm1_flow_wait(void * o)
+{
+ qoscube_t cube;
+ struct cacep_info * info;
+ int fd;
+ qosspec_t qs;
+ struct nm1_flow * flow;
+
+ (void) o;
+
+ while (true) {
+ if (gam_flow_wait(fmgr.gam, &fd, &info, &qs)) {
+ LOG_ERR("Failed to get next flow descriptor.");
+ continue;
+ }
+
+ ipcp_flow_get_qoscube(fd, &cube);
+ flow_set_add(fmgr.nm1_set[cube], fd);
+
+ /* FIXME: Temporary, until we have a PFF */
+ fmgr.fd = fd;
+
+ pthread_rwlock_wrlock(&fmgr.nm1_flows_lock);
+ flow = malloc(sizeof(*flow));
+ if (flow == NULL) {
+ free(info);
+ pthread_rwlock_unlock(&fmgr.nm1_flows_lock);
+ continue;
+ }
+
+ flow->info = info;
+ flow->fd = fd;
+ flow->qs = qs;
+
+ list_head_init(&flow->next);
+ list_add(&flow->next, &fmgr.nm1_flows);
+
+ pthread_rwlock_unlock(&fmgr.nm1_flows_lock);
+ }
+
+ return (void *) 0;
+}
+
static void fmgr_destroy_flows(void)
{
int i;
@@ -224,9 +279,6 @@ int fmgr_init()
for (i = 0; i < IPCPD_MAX_CONNS; ++i)
fmgr.np1_cep_id_to_fd[i] = -1;
- pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL);
- pthread_rwlock_init(&fmgr.np1_flows_lock, NULL);
-
for (i = 0; i < QOS_CUBE_MAX; ++i) {
fmgr.np1_set[i] = flow_set_create();
if (fmgr.np1_set[i] == NULL) {
@@ -253,29 +305,55 @@ int fmgr_init()
}
}
+ fmgr.gam = gam_create(ribmgr_dt_gam(), DT_AE);
+ if (fmgr.gam == NULL) {
+ LOG_ERR("Failed to create graph adjacency manager.");
+ fmgr_destroy_flows();
+ return -1;
+ }
+
+ list_head_init(&fmgr.nm1_flows);
+
+ pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL);
+ pthread_rwlock_init(&fmgr.np1_flows_lock, NULL);
+
pthread_create(&fmgr.np1_sdu_reader, NULL, fmgr_np1_sdu_reader, NULL);
pthread_create(&fmgr.nm1_sdu_reader, NULL, fmgr_nm1_sdu_reader, NULL);
+ pthread_create(&fmgr.nm1_flow_wait, NULL, fmgr_nm1_flow_wait, NULL);
return 0;
}
int fmgr_fini()
{
- int i;
- int j;
+ struct list_head * pos = NULL;
+ struct list_head * n = NULL;
+ qoscube_t cube;
pthread_cancel(fmgr.np1_sdu_reader);
pthread_cancel(fmgr.nm1_sdu_reader);
+ pthread_cancel(fmgr.nm1_flow_wait);
pthread_join(fmgr.np1_sdu_reader, NULL);
pthread_join(fmgr.nm1_sdu_reader, NULL);
+ pthread_join(fmgr.nm1_flow_wait, NULL);
- for (i = 0; i < AP_MAX_FLOWS; ++i)
- for (j = 0; j < QOS_CUBE_MAX; ++j)
- if (flow_set_has(fmgr.nm1_set[j], i)) {
- flow_dealloc(i);
- flow_set_del(fmgr.nm1_set[j], i);
- }
+ gam_destroy(fmgr.gam);
+
+ pthread_rwlock_wrlock(&fmgr.nm1_flows_lock);
+
+ list_for_each_safe(pos, n, &fmgr.nm1_flows) {
+ struct nm1_flow * flow =
+ list_entry(pos, struct nm1_flow, next);
+ list_del(&flow->next);
+ flow_dealloc(flow->fd);
+ ipcp_flow_get_qoscube(flow->fd, &cube);
+ flow_set_del(fmgr.nm1_set[cube], flow->fd);
+ free(flow->info);
+ free(flow);
+ }
+
+ pthread_rwlock_unlock(&fmgr.nm1_flows_lock);
pthread_rwlock_destroy(&fmgr.nm1_flows_lock);
pthread_rwlock_destroy(&fmgr.np1_flows_lock);
@@ -290,12 +368,12 @@ int fmgr_np1_alloc(int fd,
char * src_ae_name,
qoscube_t cube)
{
- cep_id_t cep_id;
- buffer_t buf;
+ cep_id_t cep_id;
+ buffer_t buf;
flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT;
- char * path;
- uint8_t * ro_data;
- uint64_t addr;
+ char * path;
+ uint8_t * ro_data;
+ uint64_t addr;
path = pathname_create(RO_DIR);
if (path == NULL)
@@ -359,9 +437,9 @@ int fmgr_np1_alloc(int fd,
static int np1_flow_dealloc(int fd)
{
flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT;
- buffer_t buf;
- int ret;
- qoscube_t cube;
+ buffer_t buf;
+ int ret;
+ qoscube_t cube;
ipcp_flow_get_qoscube(fd, &cube);
flow_set_del(fmgr.np1_set[cube], fd);
@@ -388,10 +466,11 @@ static int np1_flow_dealloc(int fd)
return ret;
}
-int fmgr_np1_alloc_resp(int fd, int response)
+int fmgr_np1_alloc_resp(int fd,
+ int response)
{
flow_alloc_msg_t msg = FLOW_ALLOC_MSG__INIT;
- buffer_t buf;
+ buffer_t buf;
msg.code = FLOW_ALLOC_CODE__FLOW_REPLY;
msg.response = response;
@@ -443,7 +522,8 @@ int fmgr_np1_dealloc(int fd)
return ret;
}
-int fmgr_np1_post_buf(cep_id_t cep_id, buffer_t * buf)
+int fmgr_np1_post_buf(cep_id_t cep_id,
+ buffer_t * buf)
{
int ret = 0;
int fd;
@@ -512,7 +592,8 @@ int fmgr_np1_post_buf(cep_id_t cep_id, buffer_t * buf)
return ret;
}
-int fmgr_np1_post_sdu(cep_id_t cep_id, struct shm_du_buff * sdb)
+int fmgr_np1_post_sdu(cep_id_t cep_id,
+ struct shm_du_buff * sdb)
{
int fd;
@@ -530,52 +611,21 @@ int fmgr_np1_post_sdu(cep_id_t cep_id, struct shm_du_buff * sdb)
return 0;
}
-/* FIXME: do this in a topologymanager instance */
-int fmgr_nm1_add_flow(int fd)
+int fmgr_nm1_flow_arr(int fd,
+ qosspec_t qs)
{
- qoscube_t qos;
+ assert(fmgr.gam);
- if (flow_alloc_resp(fd, 0) < 0) {
- LOG_ERR("Could not respond to new flow.");
+ if (gam_flow_arr(fmgr.gam, fd, qs)) {
+ LOG_ERR("Failed to hand to graph adjacency manager.");
return -1;
}
- ipcp_flow_get_qoscube(fd, &qos);
- flow_set_add(fmgr.nm1_set[qos], fd);
-
- /* FIXME: Temporary, until we have a PFF */
- fmgr.fd = fd;
-
- return 0;
-}
-
-int fmgr_nm1_dt_flow(char * dst_name, qoscube_t qos)
-{
- int fd;
- int result;
-
- /* FIXME: Map qos cube on correct QoS. */
- fd = flow_alloc(dst_name, DT_AE, NULL);
- if (fd < 0) {
- LOG_ERR("Failed to allocate flow to %s.", dst_name);
- return -1;
- }
-
- result = flow_alloc_res(fd);
- if (result < 0) {
- LOG_ERR("Allocate flow to %s result %d.", dst_name, result);
- return -1;
- }
-
- flow_set_add(fmgr.nm1_set[qos], fd);
-
- /* FIXME: Temporary, until we have a PFF */
- fmgr.fd = fd;
-
return 0;
}
-int fmgr_nm1_write_sdu(struct pci * pci, struct shm_du_buff * sdb)
+int fmgr_nm1_write_sdu(struct pci * pci,
+ struct shm_du_buff * sdb)
{
if (pci == NULL || sdb == NULL)
return -1;
@@ -595,7 +645,8 @@ int fmgr_nm1_write_sdu(struct pci * pci, struct shm_du_buff * sdb)
return 0;
}
-int fmgr_nm1_write_buf(struct pci * pci, buffer_t * buf)
+int fmgr_nm1_write_buf(struct pci * pci,
+ buffer_t * buf)
{
buffer_t * buffer;
diff --git a/src/ipcpd/normal/fmgr.h b/src/ipcpd/normal/fmgr.h
index 85731081..ae5c8ea8 100644
--- a/src/ipcpd/normal/fmgr.h
+++ b/src/ipcpd/normal/fmgr.h
@@ -23,6 +23,7 @@
#define OUROBOROS_IPCPD_NORMAL_FMGR_H
#include <ouroboros/shared.h>
+#include <ouroboros/qos.h>
#include "ae.h"
#include "frct.h"
@@ -47,15 +48,14 @@ int fmgr_np1_post_buf(cep_id_t id,
int fmgr_np1_post_sdu(cep_id_t id,
struct shm_du_buff * sdb);
-int fmgr_nm1_add_flow(int fd);
-
-int fmgr_nm1_dt_flow(char * dst_name,
- qoscube_t qos);
-
int fmgr_nm1_write_sdu(struct pci * pci,
struct shm_du_buff * sdb);
int fmgr_nm1_write_buf(struct pci * pci,
buffer_t * buf);
+int fmgr_nm1_flow_arr(int fd,
+ qosspec_t qs);
+
+
#endif /* OUROBOROS_IPCPD_NORMAL_FMGR_H */
diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c
new file mode 100644
index 00000000..0e626115
--- /dev/null
+++ b/src/ipcpd/normal/gam.c
@@ -0,0 +1,285 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager for IPC Process components
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define OUROBOROS_PREFIX "graph-adjacency-manager"
+
+#include <ouroboros/config.h>
+#include <ouroboros/dev.h>
+#include <ouroboros/logs.h>
+#include <ouroboros/list.h>
+#include <ouroboros/errno.h>
+
+#include "ribmgr.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 ga {
+ struct list_head next;
+
+ qosspec_t qs;
+ int fd;
+ struct cacep_info * info;
+};
+
+struct gam {
+ struct list_head gas;
+ pthread_mutex_t gas_lock;
+ pthread_cond_t gas_cond;
+
+ char * ae_name;
+
+ struct pol_gam_ops * ops;
+ void * ops_o;
+};
+
+struct gam * gam_create(enum pol_gam gam_type,
+ const char * ae_name)
+{
+ struct gam * tmp;
+
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL)
+ return NULL;
+
+ switch (gam_type) {
+ case COMPLETE:
+ tmp->ops = &complete_ops;
+ break;
+ default:
+ free(tmp);
+ return NULL;
+ }
+
+ list_head_init(&tmp->gas);
+
+ tmp->ae_name = strdup(ae_name);
+ if (tmp->ae_name == NULL) {
+ free(tmp);
+ return NULL;
+ }
+
+ if (pthread_mutex_init(&tmp->gas_lock, NULL)) {
+ free(tmp->ae_name);
+ free(tmp);
+ return NULL;
+ }
+
+ if (pthread_cond_init(&tmp->gas_cond, NULL)) {
+ pthread_mutex_destroy(&tmp->gas_lock);
+ free(tmp->ae_name);
+ free(tmp);
+ return NULL;
+ }
+
+ tmp->ops_o = tmp->ops->create(tmp);
+ if (tmp->ops_o == NULL) {
+ pthread_cond_destroy(&tmp->gas_cond);
+ pthread_mutex_destroy(&tmp->gas_lock);
+ free(tmp->ae_name);
+ free(tmp);
+ return NULL;
+ }
+
+ return tmp;
+}
+
+void gam_destroy(struct gam * instance)
+{
+ struct list_head * p = NULL;
+ struct list_head * n = NULL;
+
+ assert(instance);
+
+ instance->ops->destroy(instance->ops_o);
+
+ pthread_mutex_destroy(&instance->gas_lock);
+ pthread_cond_destroy(&instance->gas_cond);
+
+ list_for_each_safe(p, n, &instance->gas) {
+ struct ga * e = list_entry(p, struct ga, next);
+ list_del(&e->next);
+ free(e->info);
+ free(e);
+ }
+
+ free(instance->ae_name);
+ free(instance);
+}
+
+static int add_ga(struct gam * instance,
+ int fd,
+ qosspec_t qs,
+ struct cacep_info * info)
+{
+ struct ga * ga;
+
+ ga = malloc(sizeof(*ga));
+ if (ga == NULL)
+ return -ENOMEM;
+
+ ga->fd = fd;
+ ga->info = info;
+ ga->qs = qs;
+
+ list_head_init(&ga->next);
+
+ pthread_mutex_lock(&instance->gas_lock);
+ list_add(&ga->next, &instance->gas);
+ pthread_cond_signal(&instance->gas_cond);
+ pthread_mutex_unlock(&instance->gas_lock);
+
+ return 0;
+}
+
+int gam_flow_arr(struct gam * instance,
+ int fd,
+ qosspec_t qs)
+{
+ struct cacep * cacep;
+ struct cacep_info * info;
+
+ if (flow_alloc_resp(fd, instance->ops->accept_new_flow(instance->ops_o))
+ < 0) {
+ LOG_ERR("Could not respond to new flow.");
+ return -1;
+ }
+
+ cacep = cacep_create(fd, ipcpi.name, ribmgr_address());
+ if (cacep == NULL) {
+ LOG_ERR("Failed to create CACEP instance.");
+ return -1;
+ }
+
+ info = cacep_auth_wait(cacep);
+ if (info == NULL) {
+ LOG_ERR("Other side failed to authenticate.");
+ cacep_destroy(cacep);
+ return -1;
+ }
+
+ cacep_destroy(cacep);
+
+ if (instance->ops->accept_flow(instance->ops_o, qs, info)) {
+ flow_dealloc(fd);
+ free(info);
+ return 0;
+ }
+
+ if (add_ga(instance, fd, qs, info)) {
+ LOG_ERR("Failed to add ga to graph adjacency manager list.");
+ free(info);
+ return -1;
+ }
+
+ return 0;
+}
+
+int gam_flow_alloc(struct gam * instance,
+ char * dst_name,
+ qosspec_t qs)
+{
+ struct cacep * cacep;
+ struct cacep_info * info;
+ int fd;
+
+ fd = flow_alloc(dst_name, instance->ae_name, NULL);
+ if (fd < 0) {
+ LOG_ERR("Failed to allocate flow to %s.", dst_name);
+ return -1;
+ }
+
+ if (flow_alloc_res(fd)) {
+ LOG_ERR("Flow allocation to %s failed.", dst_name);
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ cacep = cacep_create(fd, ipcpi.name, ribmgr_address());
+ if (cacep == NULL) {
+ LOG_ERR("Failed to create CACEP instance.");
+ return -1;
+ }
+
+ info = cacep_auth(cacep);
+ if (info == NULL) {
+ LOG_ERR("Failed to authenticate.");
+ cacep_destroy(cacep);
+ return -1;
+ }
+
+ cacep_destroy(cacep);
+
+ if (instance->ops->accept_flow(instance->ops_o, qs, info)) {
+ flow_dealloc(fd);
+ free(info);
+ return 0;
+ }
+
+ if (add_ga(instance, fd, qs, info)) {
+ LOG_ERR("Failed to add GA to graph adjacency manager list.");
+ free(info);
+ return -1;
+ }
+
+ return 0;
+}
+
+int gam_flow_wait(struct gam * instance,
+ int * fd,
+ struct cacep_info ** info,
+ qosspec_t * qs)
+{
+ struct ga * ga;
+
+ assert(fd);
+ assert(info);
+ assert(qs);
+
+ pthread_mutex_lock(&instance->gas_lock);
+
+ while (list_is_empty(&instance->gas))
+ pthread_cond_wait(&instance->gas_cond, &instance->gas_lock);
+
+ ga = list_first_entry((&instance->gas), struct ga, next);
+ if (ga == NULL) {
+ pthread_mutex_unlock(&instance->gas_lock);
+ return -1;
+ }
+
+ *fd = ga->fd;
+ *info = ga->info;
+ *qs = ga->qs;
+
+ list_del(&ga->next);
+ free(ga);
+
+ pthread_mutex_unlock(&instance->gas_lock);
+
+ return 0;
+}
diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h
new file mode 100644
index 00000000..e858114c
--- /dev/null
+++ b/src/ipcpd/normal/gam.h
@@ -0,0 +1,46 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager for IPC Process components
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef OUROBOROS_IPCPD_NORMAL_GAM_H
+#define OUROBOROS_IPCPD_NORMAL_GAM_H
+
+#include <ouroboros/cacep.h>
+
+struct gam * gam_create(enum pol_gam gam_type,
+ const char * ae_name);
+
+void gam_destroy(struct gam * instance);
+
+int gam_flow_arr(struct gam * instance,
+ int fd,
+ qosspec_t qs);
+
+int gam_flow_alloc(struct gam * instance,
+ char * dst_name,
+ qosspec_t qs);
+
+int gam_flow_wait(struct gam * instance,
+ int * fd,
+ struct cacep_info ** info,
+ qosspec_t * qs);
+
+#endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index 8db754aa..85f56ab0 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -26,6 +26,7 @@
#include <ouroboros/dev.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/time_utils.h>
+#include <ouroboros/irm.h>
#include "fmgr.h"
#include "ribmgr.h"
@@ -47,7 +48,9 @@ int irmd_api;
pthread_t acceptor;
-void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
+void ipcp_sig_handler(int sig,
+ siginfo_t * info,
+ void * c)
{
(void) c;
@@ -55,7 +58,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- if (info->si_pid == irmd_api) {
+ if (info->si_pid == ipcpi.irmd_api) {
pthread_rwlock_wrlock(&ipcpi.state_lock);
if (ipcp_get_state() == IPCP_INIT)
@@ -101,7 +104,7 @@ static void * flow_acceptor(void * o)
if (strcmp(ae_name, MGMT_AE) == 0) {
ribmgr_add_nm1_flow(fd);
} else if (strcmp(ae_name, DT_AE) == 0) {
- fmgr_nm1_add_flow(fd);
+ fmgr_nm1_flow_arr(fd, qs);
} else {
LOG_DBG("Flow allocation request for unknown AE %s.",
ae_name);
@@ -195,12 +198,6 @@ static int normal_ipcp_enroll(char * dst_name)
pthread_rwlock_unlock(&ipcpi.state_lock);
- /* FIXME: Remove once we obtain neighbors during enrollment */
- if (fmgr_nm1_dt_flow(dst_name, QOS_CUBE_BE)) {
- LOG_ERR("Failed to establish data transfer flow.");
- return -1;
- }
-
LOG_DBG("Enrolled with %s.", dst_name);
return 0;
@@ -296,10 +293,11 @@ static struct ipcp_ops normal_ops = {
.ipcp_flow_dealloc = fmgr_np1_dealloc
};
-int main(int argc, char * argv[])
+int main(int argc,
+ char * argv[])
{
struct sigaction sig_act;
- sigset_t sigset;
+ sigset_t sigset;
if (ap_init(argv[0])) {
LOG_ERR("Failed to init AP");
@@ -317,8 +315,11 @@ int main(int argc, char * argv[])
exit(EXIT_FAILURE);
}
- /* store the process id of the irmd */
- irmd_api = atoi(argv[1]);
+ if (irm_bind_api(getpid(), ipcpi.name)) {
+ LOG_ERR("Failed to bind AP name.");
+ close_logfile();
+ exit(EXIT_FAILURE);
+ }
/* init sig_act */
memset(&sig_act, 0, sizeof(sig_act));
diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h
new file mode 100644
index 00000000..eeece8d9
--- /dev/null
+++ b/src/ipcpd/normal/pol-gam-ops.h
@@ -0,0 +1,40 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager policy ops
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H
+#define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H
+
+#include <ouroboros/cacep.h>
+
+struct pol_gam_ops {
+ void * (* create)(struct gam * instance);
+
+ void (* destroy)(void * o);
+
+ int (* accept_new_flow)(void * o);
+
+ int (* accept_flow)(void * o,
+ qosspec_t qs,
+ const struct cacep_info * info);
+};
+
+#endif /* OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H */
diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c
new file mode 100644
index 00000000..89e1b91f
--- /dev/null
+++ b/src/ipcpd/normal/pol/complete.c
@@ -0,0 +1,208 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager for IPC Process components
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define OUROBOROS_PREFIX "complete-graph-adjacency-manager"
+
+#include <ouroboros/config.h>
+#include <ouroboros/logs.h>
+#include <ouroboros/list.h>
+#include <ouroboros/qos.h>
+
+#include "pathname.h"
+#include "ro.h"
+#include "ipcp.h"
+#include "gam.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define RO_DIR "neighbors"
+
+struct neighbor {
+ struct list_head next;
+ char * neighbor;
+};
+
+struct complete {
+ struct list_head neighbors;
+ pthread_mutex_t neighbors_lock;
+
+ pthread_t allocator;
+
+ struct gam * gam;
+};
+
+static void * allocator(void * o)
+{
+ qosspec_t qs;
+ ssize_t len;
+ char ** children;
+ int i;
+ char * ro_name;
+ struct complete * complete = (struct complete *) o;
+
+ qs.delay = 0;
+ qs.jitter = 0;
+
+ ro_name = pathname_create(RO_DIR);
+ if (ro_name == NULL)
+ return (void *) -1;
+
+ len = ro_children(ro_name, &children);
+ if (len > 0) {
+ for (i = 0; i < len; i++) {
+ if (strcmp(children[i], ipcpi.name) == 0)
+ continue;
+ gam_flow_alloc(complete->gam, children[i], qs);
+ }
+ }
+
+ pathname_destroy(ro_name);
+
+ return (void *) 0;
+}
+
+void * complete_create(struct gam * gam)
+{
+ struct ro_attr attr;
+ char * ro_name;
+ struct complete * complete;
+
+ ro_attr_init(&attr);
+ attr.enrol_sync = true;
+ attr.recv_set = ALL_MEMBERS;
+
+ complete = malloc(sizeof(*complete));
+ if (complete == NULL)
+ return NULL;
+
+ ro_name = pathname_create(RO_DIR);
+ if (ro_name == NULL) {
+ free(complete);
+ return NULL;
+ }
+
+ if (!ro_exists(RO_DIR)) {
+ if (ro_create(ro_name, &attr, NULL, 0)) {
+ free(complete);
+ pathname_destroy(ro_name);
+ return NULL;
+ }
+ }
+
+ ro_name = pathname_append(ro_name, ipcpi.name);
+ if (ro_name == NULL) {
+ free(complete);
+ pathname_destroy(ro_name);
+ return NULL;
+ }
+
+ if (ro_create(ro_name, &attr, NULL, 0)) {
+ free(complete);
+ pathname_destroy(ro_name);
+ return NULL;
+ }
+ pathname_destroy(ro_name);
+
+ list_head_init(&complete->neighbors);
+ complete->gam = gam;
+
+ if (pthread_mutex_init(&complete->neighbors_lock, NULL)) {
+ free(complete);
+ return NULL;
+ }
+
+ if (pthread_create(&complete->allocator, NULL,
+ allocator, (void *) complete)) {
+ free(complete);
+ pthread_mutex_destroy(&complete->neighbors_lock);
+ return NULL;
+ }
+
+ return (void *) complete;
+}
+
+void complete_destroy(void * o)
+{
+ struct list_head * p = NULL;
+ struct list_head * n = NULL;
+ struct complete * complete = (struct complete *) o;
+
+ pthread_cancel(complete->allocator);
+ pthread_join(complete->allocator, NULL);
+
+ list_for_each_safe(p, n, &complete->neighbors) {
+ struct neighbor * e = list_entry(p, struct neighbor, next);
+ list_del(&e->next);
+ free(e->neighbor);
+ free(e);
+ }
+}
+
+int complete_accept_new_flow(void * o)
+{
+ (void) o;
+
+ return 0;
+}
+
+int complete_accept_flow(void * o,
+ qosspec_t qs,
+ const struct cacep_info * info)
+{
+ struct list_head * pos = NULL;
+ struct neighbor * n;
+ struct complete * complete = (struct complete *) o;
+
+ (void) qs;
+
+ pthread_mutex_lock(&complete->neighbors_lock);
+
+ list_for_each(pos, &complete->neighbors) {
+ struct neighbor * e = list_entry(pos, struct neighbor, next);
+ if (strcmp(e->neighbor, info->name) == 0) {
+ pthread_mutex_unlock(&complete->neighbors_lock);
+ return -1;
+ }
+ }
+
+ n = malloc(sizeof(*n));
+ if (n == NULL) {
+ pthread_mutex_unlock(&complete->neighbors_lock);
+ return -1;
+ }
+
+ list_head_init(&n->next);
+
+ n->neighbor = strdup(info->name);
+ if (n->neighbor == NULL) {
+ pthread_mutex_unlock(&complete->neighbors_lock);
+ free(n);
+ return -1;
+ }
+
+ list_add(&n->next, &complete->neighbors);
+
+ pthread_mutex_unlock(&complete->neighbors_lock);
+
+ return 0;
+}
diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h
new file mode 100644
index 00000000..8fcc87ba
--- /dev/null
+++ b/src/ipcpd/normal/pol/complete.h
@@ -0,0 +1,46 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager for IPC Process components
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H
+#define OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H
+
+#include "gam.h"
+#include "pol-gam-ops.h"
+
+void * complete_create(struct gam * instance);
+
+void complete_destroy(void * o);
+
+int complete_accept_new_flow(void * o);
+
+int complete_accept_flow(void * o,
+ qosspec_t qs,
+ const struct cacep_info * info);
+
+struct pol_gam_ops complete_ops = {
+ .create = complete_create,
+ .destroy = complete_destroy,
+ .accept_new_flow = complete_accept_new_flow,
+ .accept_flow = complete_accept_flow
+};
+
+#endif /* OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H */
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
index 6356d48c..993fe62a 100644
--- a/src/ipcpd/normal/ribmgr.c
+++ b/src/ipcpd/normal/ribmgr.c
@@ -139,6 +139,8 @@ struct {
struct addr_auth * addr_auth;
enum pol_addr_auth addr_auth_type;
+ enum pol_gam dt_gam_type;
+
enum ribmgr_state state;
pthread_cond_t state_cond;
pthread_mutex_t state_lock;
@@ -168,6 +170,7 @@ void ribmgr_ro_created(const char * name,
rib.dtc.min_pdu_size = stat_msg->min_pdu_size;
rib.dtc.max_pdu_size = stat_msg->max_pdu_size;
rib.addr_auth_type = stat_msg->addr_auth_type;
+ rib.dt_gam_type = stat_msg->dt_gam_type;
static_info_msg__free_unpacked(stat_msg, NULL);
}
@@ -1262,6 +1265,7 @@ int ribmgr_bootstrap(struct dif_config * conf)
stat_info.min_pdu_size = rib.dtc.min_pdu_size = conf->min_pdu_size;
stat_info.max_pdu_size = rib.dtc.max_pdu_size = conf->max_pdu_size;
stat_info.addr_auth_type = rib.addr_auth_type = conf->addr_auth_type;
+ stat_info.dt_gam_type = rib.dt_gam_type = conf->dt_gam_type;
len = static_info_msg__get_packed_size(&stat_info);
if (len == 0) {
@@ -1354,16 +1358,21 @@ int ribmgr_start_policies(void)
return 0;
}
-struct dt_const * ribmgr_dt_const()
+struct dt_const * ribmgr_dt_const(void)
{
return &(rib.dtc);
}
-uint64_t ribmgr_address()
+uint64_t ribmgr_address(void)
{
return rib.address;
}
+enum pol_gam ribmgr_dt_gam(void)
+{
+ return rib.dt_gam_type;
+}
+
static int send_neighbors_ro(char * name, ro_msg_t * msg, enum cdap_opcode code)
{
struct list_head * p = NULL;
@@ -1577,8 +1586,8 @@ ssize_t ro_children(const char * name, char *** children)
}
child = node->child;
- **children = malloc(len);
- if (**children == NULL) {
+ *children = malloc(len);
+ if (*children == NULL) {
pthread_mutex_unlock(&rib.ro_lock);
return -1;
}
@@ -1590,7 +1599,7 @@ ssize_t ro_children(const char * name, char *** children)
free((*children)[i]);
i--;
}
- free(**children);
+ free(*children);
pthread_mutex_unlock(&rib.ro_lock);
return -1;
}
diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h
index ddc98e6e..22212de9 100644
--- a/src/ipcpd/normal/ribmgr.h
+++ b/src/ipcpd/normal/ribmgr.h
@@ -45,4 +45,6 @@ struct dt_const * ribmgr_dt_const(void);
uint64_t ribmgr_address(void);
+enum pol_gam ribmgr_dt_gam(void);
+
#endif /* OUROBOROS_IPCPD_NORMAL_RIBMGR_H */
diff --git a/src/ipcpd/normal/static_info.proto b/src/ipcpd/normal/static_info.proto
index 18f02e36..bb6f8c4e 100644
--- a/src/ipcpd/normal/static_info.proto
+++ b/src/ipcpd/normal/static_info.proto
@@ -23,13 +23,14 @@
syntax = "proto2";
message static_info_msg {
- required uint32 addr_size = 1;
- required uint32 cep_id_size = 2;
- required uint32 pdu_length_size = 3;
- required uint32 seqno_size = 4;
- required bool has_ttl = 5;
- required bool has_chk = 6;
- required uint32 min_pdu_size = 7;
- required uint32 max_pdu_size = 8;
- required uint32 addr_auth_type = 9;
+ required uint32 addr_size = 1;
+ required uint32 cep_id_size = 2;
+ required uint32 pdu_length_size = 3;
+ required uint32 seqno_size = 4;
+ required bool has_ttl = 5;
+ required bool has_chk = 6;
+ required uint32 min_pdu_size = 7;
+ required uint32 max_pdu_size = 8;
+ required uint32 addr_auth_type = 9;
+ required uint32 dt_gam_type = 10;
} \ No newline at end of file
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c
index 0ff8007b..da496b07 100644
--- a/src/ipcpd/shim-eth-llc/main.c
+++ b/src/ipcpd/shim-eth-llc/main.c
@@ -77,9 +77,6 @@ typedef ShimEthLlcMsg shim_eth_llc_msg_t;
#define EVENT_WAIT_TIMEOUT 100 /* us */
#define NAME_QUERY_TIMEOUT 100000000 /* ns */
-/* global for trapping signal */
-int irmd_api;
-
struct eth_llc_frame {
uint8_t dst_hwaddr[MAC_SIZE];
uint8_t src_hwaddr[MAC_SIZE];
@@ -675,7 +672,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- if (info->si_pid == irmd_api) {
+ if (info->si_pid == ipcpi.irmd_api) {
pthread_rwlock_wrlock(&ipcpi.state_lock);
if (ipcp_get_state() == IPCP_INIT)
@@ -1123,9 +1120,6 @@ int main(int argc, char * argv[])
exit(EXIT_FAILURE);
}
- /* store the process id of the irmd */
- irmd_api = atoi(argv[1]);
-
/* init sig_act */
memset(&sig_act, 0, sizeof(sig_act));
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 8c0c0aac..99aac40e 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -60,9 +60,6 @@ typedef ShimUdpMsg shim_udp_msg_t;
#define UDP_MAX_PORTS 0xFFFF
-/* global for trapping signal */
-int irmd_api;
-
struct uf {
int udp;
int skfd;
@@ -529,7 +526,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- if (info->si_pid == irmd_api) {
+ if (info->si_pid == ipcpi.irmd_api) {
pthread_rwlock_wrlock(&ipcpi.state_lock);
if (ipcp_get_state() == IPCP_INIT)
@@ -1191,9 +1188,6 @@ int main(int argc, char * argv[])
exit(EXIT_FAILURE);
}
- /* store the process id of the irmd */
- irmd_api = atoi(argv[1]);
-
/* init sig_act */
memset(&sig_act, 0, sizeof(sig_act));
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index cad4dd88..f16587e1 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -100,7 +100,7 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t api, ipcp_msg_t * msg)
return recv_msg;
}
-pid_t ipcp_create(enum ipcp_type ipcp_type)
+pid_t ipcp_create(char * name, enum ipcp_type ipcp_type)
{
pid_t api = -1;
char irmd_api[10];
@@ -109,7 +109,7 @@ pid_t ipcp_create(enum ipcp_type ipcp_type)
char * full_name = NULL;
char * exec_name = NULL;
char * log_file = NULL;
- char * argv[4];
+ char * argv[5];
sprintf(irmd_api, "%u", getpid());
@@ -119,9 +119,8 @@ pid_t ipcp_create(enum ipcp_type ipcp_type)
return api;
}
- if (api != 0) {
+ if (api != 0)
return api;
- }
if (ipcp_type == IPCP_NORMAL)
exec_name = IPCP_NORMAL_EXEC;
@@ -162,8 +161,9 @@ pid_t ipcp_create(enum ipcp_type ipcp_type)
/* log_file to be placed at the end */
argv[0] = full_name;
argv[1] = irmd_api;
- argv[2] = log_file;
- argv[3] = NULL;
+ argv[2] = name;
+ argv[3] = log_file;
+ argv[4] = NULL;
execv(argv[0], &argv[0]);
diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h
index 429e0d5d..658aa2ea 100644
--- a/src/irmd/ipcp.h
+++ b/src/irmd/ipcp.h
@@ -28,8 +28,8 @@
#ifndef OUROBOROS_IPCP_H
#define OUROBOROS_IPCP_H
-/* Returns the process id */
-pid_t ipcp_create(enum ipcp_type ipcp_type);
+pid_t ipcp_create(char * name,
+ enum ipcp_type ipcp_type);
int ipcp_destroy(pid_t api);
@@ -45,7 +45,7 @@ int ipcp_name_reg(pid_t api,
int ipcp_name_unreg(pid_t api,
char * name);
-int ipcp_name_query(pid_t api,
+int ipcp_name_query(pid_t api,
char * name);
int ipcp_flow_alloc(pid_t api,
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 9dc08cbe..435ee116 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -245,7 +245,7 @@ static pid_t create_ipcp(char * name, enum ipcp_type ipcp_type)
pthread_rwlock_wrlock(&irmd->reg_lock);
- api->pid = ipcp_create(ipcp_type);
+ api->pid = ipcp_create(name, ipcp_type);
if (api->pid == -1) {
pthread_rwlock_unlock(&irmd->reg_lock);
pthread_rwlock_unlock(&irmd->state_lock);
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index cdd8abb1..688cf6f5 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -8,8 +8,8 @@ protobuf_generate_c(IRM_PROTO_SRCS IRM_PROTO_HDRS irmd_messages.proto)
protobuf_generate_c(IPCP_PROTO_SRCS IPCP_PROTO_HDRS ipcpd_messages.proto)
protobuf_generate_c(DIF_CONFIG_PROTO_SRCS DIF_CONFIG_PROTO_HDRS
dif_config.proto)
-protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS
- cdap.proto)
+protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS cdap.proto)
+protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)
if(NOT APPLE)
find_library(LIBRT_LIBRARIES rt)
@@ -28,6 +28,7 @@ endif()
set(SOURCE_FILES
# Add source files here
bitmap.c
+ cacep.c
cdap.c
cdap_req.c
dev.c
@@ -46,9 +47,9 @@ set(SOURCE_FILES
utils.c
)
-add_library(ouroboros SHARED ${SOURCE_FILES}
- ${IRM_PROTO_SRCS} ${IPCP_PROTO_SRCS}
- ${DIF_CONFIG_PROTO_SRCS} ${CDAP_PROTO_SRCS})
+add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS}
+ ${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS}
+ ${CDAP_PROTO_SRCS} ${CACEP_PROTO_SRCS})
target_link_libraries(ouroboros ${LIBRT_LIBRARIES}
${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY})
diff --git a/src/lib/cacep.c b/src/lib/cacep.c
new file mode 100644
index 00000000..22c6137f
--- /dev/null
+++ b/src/lib/cacep.c
@@ -0,0 +1,170 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * The Common Application Connection Establishment Phase
+ *
+ * Sander Vrijders <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <ouroboros/config.h>
+#include <ouroboros/cacep.h>
+#include <ouroboros/dev.h>
+#include <ouroboros/errno.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cacep.pb-c.h"
+typedef Cacep cacep_t;
+
+#define BUF_SIZE 2048
+
+struct cacep {
+ int fd;
+ char * name;
+ uint64_t address;
+};
+
+struct cacep * cacep_create(int fd,
+ const char * name,
+ uint64_t address)
+{
+ struct cacep * tmp;
+
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL)
+ return NULL;
+
+ tmp->fd = fd;
+ tmp->address = address;
+ tmp->name = strdup(name);
+ if (tmp->name == NULL) {
+ free(tmp);
+ return NULL;
+ }
+
+ return tmp;
+}
+
+int cacep_destroy(struct cacep * instance)
+{
+ if (instance == NULL)
+ return 0;
+
+ free(instance);
+
+ return 0;
+}
+
+static struct cacep_info * read_msg(struct cacep * instance)
+{
+ struct cacep_info * tmp;
+ uint8_t buf[BUF_SIZE];
+ cacep_t * msg;
+ ssize_t len;
+
+ len = flow_read(instance->fd, buf, BUF_SIZE);
+ if (len < 0)
+ return NULL;
+
+ msg = cacep__unpack(NULL, len, buf);
+ if (msg == NULL)
+ return NULL;
+
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ cacep__free_unpacked(msg, NULL);
+ return NULL;
+ }
+
+ tmp->addr = msg->address;
+ tmp->name = strdup(msg->name);
+ if (tmp->name == NULL) {
+ free(tmp);
+ cacep__free_unpacked(msg, NULL);
+ return NULL;
+ }
+
+ cacep__free_unpacked(msg, NULL);
+
+ return tmp;
+}
+
+static int send_msg(struct cacep * instance)
+{
+ cacep_t msg = CACEP__INIT;
+ int ret = 0;
+ uint8_t * data = NULL;
+ size_t len = 0;
+
+ msg.name = instance->name;
+ msg.address = instance->address;
+
+ len = cacep__get_packed_size(&msg);
+ if (len == 0)
+ return -1;
+
+ data = malloc(len);
+ if (data == NULL)
+ return -ENOMEM;
+
+ cacep__pack(&msg, data);
+
+ if (flow_write(instance->fd, data, len) < 0)
+ ret = -1;
+
+ free(data);
+
+ return ret;
+}
+
+struct cacep_info * cacep_auth(struct cacep * instance)
+{
+ struct cacep_info * tmp;
+
+ if (instance == NULL)
+ return NULL;
+
+ if (send_msg(instance))
+ return NULL;
+
+ tmp = read_msg(instance);
+ if (tmp == NULL)
+ return NULL;
+
+ return tmp;
+}
+
+struct cacep_info * cacep_auth_wait(struct cacep * instance)
+{
+ struct cacep_info * tmp;
+
+ if (instance == NULL)
+ return NULL;
+
+ tmp = read_msg(instance);
+ if (tmp == NULL)
+ return NULL;
+
+ if (send_msg(instance)) {
+ free(tmp->name);
+ free(tmp);
+ return NULL;
+ }
+
+ return tmp;
+}
diff --git a/src/lib/cacep.proto b/src/lib/cacep.proto
new file mode 100644
index 00000000..603b095d
--- /dev/null
+++ b/src/lib/cacep.proto
@@ -0,0 +1,29 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * CACEP message
+ *
+ * Dimitri Staessens <[email protected]>
+ * Sander Vrijders <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+syntax = "proto2";
+
+message cacep {
+ required string name = 1;
+ required uint64 address = 2;
+}
diff --git a/src/lib/dif_config.proto b/src/lib/dif_config.proto
index 8a1d329e..f1f8747b 100644
--- a/src/lib/dif_config.proto
+++ b/src/lib/dif_config.proto
@@ -37,9 +37,10 @@ message dif_config_msg {
optional uint32 min_pdu_size = 10;
optional uint32 max_pdu_size = 11;
optional uint32 addr_auth_type = 12;
+ optional uint32 dt_gam_type = 13;
// Config for shim UDP
- optional uint32 ip_addr = 13;
- optional uint32 dns_addr = 14;
+ optional uint32 ip_addr = 14;
+ optional uint32 dns_addr = 15;
// Config for the shim Ethernet LLC
- optional string if_name = 15;
+ optional string if_name = 16;
} \ No newline at end of file
diff --git a/src/lib/irm.c b/src/lib/irm.c
index 635c8f9b..ade38b6f 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -120,6 +120,7 @@ int irm_bootstrap_ipcp(pid_t api,
config.has_min_pdu_size = true;
config.has_max_pdu_size = true;
config.has_addr_auth_type = true;
+ config.has_dt_gam_type = true;
config.addr_size = conf->addr_size;
config.cep_id_size = conf->cep_id_size;
@@ -131,6 +132,7 @@ int irm_bootstrap_ipcp(pid_t api,
config.min_pdu_size = conf->min_pdu_size;
config.max_pdu_size = conf->max_pdu_size;
config.addr_auth_type = conf->addr_auth_type;
+ config.dt_gam_type = conf->dt_gam_type;
break;
case IPCP_SHIM_UDP:
config.has_ip_addr = true;
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c
index 8fd2fb73..4c7f2168 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -45,8 +45,10 @@
#define DEFAULT_MAX_PDU_SIZE 9000
#define DEFAULT_DDNS 0
#define DEFAULT_ADDR_AUTH FLAT_RANDOM
+#define DEFAULT_DT_GAM COMPLETE
-#define ADDR_AUTH_FLAT "flat"
+#define ADDR_AUTH_FLAT "flat"
+#define DT_GAM_COMPLETE "complete"
static void usage(void)
{
@@ -67,6 +69,8 @@ static void usage(void)
" [min_pdu <minimum PDU size> (default: %d)]\n"
" [max_pdu <maximum PDU size> (default: %d)]\n"
" [addr_auth <address policy> (default: %s)]\n"
+ " [dt_gam <data transfer graph adjacency manager>"
+ "(default: %s)]\n"
"if TYPE == " SHIM_UDP "\n"
" ip <IP address in dotted notation>\n"
" [dns <DDNS IP address in dotted notation>"
@@ -76,7 +80,7 @@ static void usage(void)
DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE,
DEFAULT_PDU_LEN_SIZE, DEFAULT_SEQ_NO_SIZE,
DEFAULT_MIN_PDU_SIZE, DEFAULT_MAX_PDU_SIZE,
- ADDR_AUTH_FLAT, DEFAULT_DDNS);
+ ADDR_AUTH_FLAT, DT_GAM_COMPLETE, DEFAULT_DDNS);
}
int do_bootstrap_ipcp(int argc, char ** argv)
@@ -93,6 +97,7 @@ int do_bootstrap_ipcp(int argc, char ** argv)
uint32_t min_pdu_size = DEFAULT_MIN_PDU_SIZE;
uint32_t max_pdu_size = DEFAULT_MAX_PDU_SIZE;
enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH;
+ enum pol_gam dt_gam_type = DEFAULT_DT_GAM;
uint32_t ip_addr = 0;
uint32_t dns_addr = DEFAULT_DDNS;
char * ipcp_type = NULL;
@@ -144,6 +149,9 @@ int do_bootstrap_ipcp(int argc, char ** argv)
} else if (matches(*argv, "addr_auth") == 0) {
if (strcmp(ADDR_AUTH_FLAT, *(argv + 1)) == 0)
addr_auth_type = FLAT_RANDOM;
+ } else if (matches(*argv, "dt_gam") == 0) {
+ if (strcmp(DT_GAM_COMPLETE, *(argv + 1)) == 0)
+ dt_gam_type = COMPLETE;
} else {
printf("\"%s\" is unknown, try \"irm "
"ipcp bootstrap\".\n", *argv);
@@ -172,6 +180,7 @@ int do_bootstrap_ipcp(int argc, char ** argv)
conf.min_pdu_size = min_pdu_size;
conf.max_pdu_size = max_pdu_size;
conf.addr_auth_type = addr_auth_type;
+ conf.dt_gam_type = dt_gam_type;
} else if (strcmp(ipcp_type, SHIM_UDP) == 0) {
conf.type = IPCP_SHIM_UDP;
if (ip_addr == 0) {
@@ -199,8 +208,6 @@ int do_bootstrap_ipcp(int argc, char ** argv)
api = irm_create_ipcp(name, conf.type);
if (api == 0)
return -1;
- if (conf.type == IPCP_NORMAL)
- irm_bind_api(api, name);
len = irm_list_ipcps(name, &apis);
}
diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c
index 9f636f34..e8ed1186 100644
--- a/src/tools/irm/irm_ipcp_create.c
+++ b/src/tools/irm/irm_ipcp_create.c
@@ -85,8 +85,5 @@ int do_create_ipcp(int argc, char ** argv)
if (api == 0)
return -1;
- if (type == IPCP_NORMAL)
- irm_bind_api(api, ipcp_name);
-
return 0;
}
diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c
index f7807f42..3731fa81 100644
--- a/src/tools/irm/irm_ipcp_enroll.c
+++ b/src/tools/irm/irm_ipcp_enroll.c
@@ -68,7 +68,6 @@ int do_enroll_ipcp(int argc, char ** argv)
api = irm_create_ipcp(name, IPCP_NORMAL);
if (api == 0)
return -1;
- irm_bind_api(api, name);
len = irm_list_ipcps(name, &apis);
}