diff options
author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2017-01-12 14:58:49 +0100 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2017-01-12 14:58:49 +0100 |
commit | 4e3c360377bc9b792c2fac83e9402d7531f79bbe (patch) | |
tree | e4409fb32ed7c391f48c3c2699997fc5b75137a1 | |
parent | 7cad036f812a87aafd7c0e8ed4cbea76fb4cb097 (diff) | |
parent | 15e9b779385c71d366776b83540e19e0735c4e66 (diff) | |
download | ouroboros-4e3c360377bc9b792c2fac83e9402d7531f79bbe.tar.gz ouroboros-4e3c360377bc9b792c2fac83e9402d7531f79bbe.zip |
Merged in sandervrijders/ouroboros/be-gam (pull request #345)
Be gam
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 <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * + * 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 <dimitri.staessens@intec.ugent.be> + * Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * 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 <dimitri.staessens@intec.ugent.be> + * Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * 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 <dimitri.staessens@intec.ugent.be> + * Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * 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 <dimitri.staessens@intec.ugent.be> + * Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * 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 <dimitri.staessens@intec.ugent.be> + * Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * 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 <sander.vrijders@intec.ugent.be> + * + * 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 <dimitri.staessens@intec.ugent.be> + * Sander Vrijders <sander.vrijders@intec.ugent.be> + * + * 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); } |