diff options
Diffstat (limited to 'src/ipcpd/normal')
-rw-r--r-- | src/ipcpd/normal/dt_const.h | 3 | ||||
-rw-r--r-- | src/ipcpd/normal/fmgr.c | 52 | ||||
-rw-r--r-- | src/ipcpd/normal/frct.c | 21 | ||||
-rw-r--r-- | src/ipcpd/normal/frct.h | 2 | ||||
-rw-r--r-- | src/ipcpd/normal/main.c | 62 | ||||
-rw-r--r-- | src/ipcpd/normal/ribmgr.c | 265 |
6 files changed, 369 insertions, 36 deletions
diff --git a/src/ipcpd/normal/dt_const.h b/src/ipcpd/normal/dt_const.h index 65cde5f7..b33f16c5 100644 --- a/src/ipcpd/normal/dt_const.h +++ b/src/ipcpd/normal/dt_const.h @@ -31,9 +31,10 @@ struct dt_const { uint8_t cep_id_size; uint8_t pdu_length_size; uint8_t seqno_size; - uint8_t qos_id_size; uint8_t ttl_size; uint8_t chk_size; + uint32_t min_pdu_size; + uint32_t max_pdu_size; }; #endif /* IPCP_DT_CONST_H */ diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 9521805f..4b3c49e6 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -48,7 +48,7 @@ struct fmgr { struct list_head n_1_flows; pthread_mutex_t n_1_flows_lock; -} * instance = NULL; +} * fmgr = NULL; static int add_n_1_fd(int fd, char * ae_name) @@ -65,9 +65,9 @@ static int add_n_1_fd(int fd, tmp->fd = fd; tmp->ae_name = ae_name; - pthread_mutex_lock(&instance->n_1_flows_lock); - list_add(&tmp->next, &instance->n_1_flows); - pthread_mutex_unlock(&instance->n_1_flows_lock); + pthread_mutex_lock(&fmgr->n_1_flows_lock); + list_add(&tmp->next, &fmgr->n_1_flows); + pthread_mutex_unlock(&fmgr->n_1_flows_lock); return 0; } @@ -77,6 +77,8 @@ static void * fmgr_listen(void * o) int fd; char * ae_name; + /* FIXME: Only start to listen once we are enrolled */ + while (true) { fd = flow_accept(&ae_name); if (fd < 0) { @@ -84,6 +86,8 @@ static void * fmgr_listen(void * o) continue; } + LOG_DBG("New flow alloc request for AE %s", ae_name); + if (!(strcmp(ae_name, MGMT_AE) == 0 || strcmp(ae_name, DT_AE) == 0)) { if (flow_alloc_resp(fd, -1)) @@ -101,18 +105,20 @@ static void * fmgr_listen(void * o) LOG_DBG("Accepted new flow allocation request for AE %s.", ae_name); - if (strcmp(ae_name, MGMT_AE) == 0 && - ribmgr_mgmt_flow(fd)) { - LOG_ERR("Failed to hand file descriptor to RIB."); - flow_dealloc(fd); - continue; + if (strcmp(ae_name, MGMT_AE) == 0) { + if (ribmgr_mgmt_flow(fd)) { + LOG_ERR("Failed to hand fd to RIB."); + flow_dealloc(fd); + continue; + } } - if (strcmp(ae_name, DT_AE) == 0 && - frct_dt_flow(fd)) { - LOG_ERR("Failed to hand file descriptor to FRCT."); - flow_dealloc(fd); - continue; + if (strcmp(ae_name, DT_AE) == 0) { + if (frct_dt_flow(fd)) { + LOG_ERR("Failed to hand fd to FRCT."); + flow_dealloc(fd); + continue; + } } if (add_n_1_fd(fd, ae_name)) { @@ -127,16 +133,16 @@ static void * fmgr_listen(void * o) int fmgr_init() { - instance = malloc(sizeof(*instance)); - if (instance == NULL) { + fmgr = malloc(sizeof(*fmgr)); + if (fmgr == NULL) { return -1; } - INIT_LIST_HEAD(&instance->n_1_flows); + INIT_LIST_HEAD(&fmgr->n_1_flows); - pthread_mutex_init(&instance->n_1_flows_lock, NULL); + pthread_mutex_init(&fmgr->n_1_flows_lock, NULL); - pthread_create(&instance->listen_thread, + pthread_create(&fmgr->listen_thread, NULL, fmgr_listen, NULL); @@ -148,12 +154,12 @@ int fmgr_fini() { struct list_head * pos = NULL; - pthread_cancel(instance->listen_thread); + pthread_cancel(fmgr->listen_thread); - pthread_join(instance->listen_thread, + pthread_join(fmgr->listen_thread, NULL); - list_for_each(pos, &instance->n_1_flows) { + list_for_each(pos, &fmgr->n_1_flows) { struct n_1_flow * e = list_entry(pos, struct n_1_flow, next); if (e->ae_name != NULL) @@ -161,7 +167,7 @@ int fmgr_fini() flow_dealloc(e->fd); } - free(instance); + free(fmgr); return 0; } diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c index 22f8a9fc..49006276 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -22,6 +22,8 @@ #define OUROBOROS_PREFIX "flow-rtx-control" +#include <stdlib.h> + #include <ouroboros/logs.h> #include "frct.h" @@ -30,16 +32,29 @@ struct frct_i { }; -int frct_init(struct dt_const * dt_const) +struct frct { + struct dt_const * dtc; + +} * frct = NULL; + +int frct_init(struct dt_const * dtc) { - LOG_MISSING; + if (dtc == NULL) + return -1; + + frct = malloc(sizeof(*frct)); + if (frct == NULL) { + return -1; + } + + frct->dtc = dtc; return 0; } int frct_fini() { - LOG_MISSING; + free(frct); return 0; } diff --git a/src/ipcpd/normal/frct.h b/src/ipcpd/normal/frct.h index 07fd2c65..515bed3f 100644 --- a/src/ipcpd/normal/frct.h +++ b/src/ipcpd/normal/frct.h @@ -29,7 +29,7 @@ struct frct_i; -int frct_init(struct dt_const * dt_const); +int frct_init(struct dt_const * dtc); int frct_fini(); struct frct_i * frct_i_create(int port_id, diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 2d97f435..54ebd674 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -1,3 +1,25 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Normal IPC Process + * + * 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 "normal-ipcp" #include <ouroboros/config.h> @@ -108,16 +130,48 @@ static int normal_ipcp_name_unreg(char * name) static int normal_ipcp_enroll(char * dif_name) { - LOG_MISSING; + pthread_rwlock_rdlock(&_ipcp->state_lock); - return -1; + if (_ipcp->state != IPCP_INIT) { + pthread_rwlock_unlock(&_ipcp->state_lock); + LOG_DBGF("Won't enroll an IPCP that is not in INIT."); + return -1; /* -ENOTINIT */ + } + + if (fmgr_mgmt_flow(dif_name)) { + pthread_rwlock_unlock(&_ipcp->state_lock); + LOG_ERR("Failed to establish management flow."); + return -1; + } + + _ipcp->state = IPCP_ENROLLED; + + pthread_rwlock_unlock(&_ipcp->state_lock); + + return 0; } static int normal_ipcp_bootstrap(struct dif_config * conf) { - LOG_MISSING; + pthread_rwlock_rdlock(&_ipcp->state_lock); + + if (_ipcp->state != IPCP_INIT) { + pthread_rwlock_unlock(&_ipcp->state_lock); + LOG_DBGF("Won't bootstrap an IPCP that is not in INIT."); + return -1; /* -ENOTINIT */ + } + + if (ribmgr_bootstrap(conf)) { + pthread_rwlock_unlock(&_ipcp->state_lock); + LOG_ERR("Failed to bootstrap RIB manager."); + return -1; + } + + _ipcp->state = IPCP_ENROLLED; - return -1; + pthread_rwlock_unlock(&_ipcp->state_lock); + + return 0; } static struct ipcp_ops normal_ops = { diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 98ed38c6..4d29b098 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -22,38 +22,295 @@ #define OUROBOROS_PREFIX "rib-manager" +#include <ouroboros/config.h> #include <ouroboros/logs.h> +#include <ouroboros/cdap.h> +#include <ouroboros/list.h> + +#include <stdlib.h> +#include <pthread.h> +#include <string.h> #include "ribmgr.h" +#include "dt_const.h" +#include "frct.h" + +#define ENROLLMENT "enrollment" + +enum cdap_opcode { + READ = 0, + WRITE, + START, + STOP, + CREATE, + DELETE +}; + +struct cdap_request { + enum cdap_opcode code; + char * name; + int invoke_id; + struct cdap * instance; + + struct list_head next; +}; + +struct mgmt_flow { + struct cdap * instance; + int fd; + struct list_head next; +}; + +struct rib { + struct dt_const dtc; + + struct list_head flows; + pthread_rwlock_t flows_lock; + + struct list_head cdap_reqs; + pthread_mutex_t cdap_reqs_lock; +} * rib = NULL; + +/* Call while holding cdap_reqs_lock */ +int cdap_request_add(struct cdap * instance, + enum cdap_opcode code, + char * name, + int invoke_id) +{ + struct cdap_request * req; + + req = malloc(sizeof(*req)); + if (req == NULL) + return -1; + + req->code = code; + req->invoke_id = invoke_id; + req->instance = instance; + + req->name = strdup(name); + if (req->name == NULL) { + free(req); + return -1; + } + + INIT_LIST_HEAD(&req->next); + + list_add(&req->next, &rib->cdap_reqs); + + return 0; +} int ribmgr_init() { - LOG_MISSING; + rib = malloc(sizeof(*rib)); + if (rib == NULL) { + return -1; + } + + INIT_LIST_HEAD(&rib->flows); + + if (pthread_rwlock_init(&rib->flows_lock, NULL)) { + LOG_ERR("Failed to initialize rwlock."); + free(rib); + return -1; + } + + if (pthread_mutex_init(&rib->cdap_reqs_lock, NULL)) { + LOG_ERR("Failed to initialize mutex."); + free(rib); + return -1; + } return 0; } int ribmgr_fini() { - LOG_MISSING; + struct list_head * pos = NULL; + struct list_head * n = NULL; + + pthread_mutex_lock(&rib->cdap_reqs_lock); + list_for_each_safe(pos, n, &rib->cdap_reqs) { + struct cdap_request * req = + list_entry(pos, struct cdap_request, next); + + free(req->name); + list_del(&req->next); + free(req); + } + pthread_mutex_unlock(&rib->cdap_reqs_lock); + + pthread_rwlock_wrlock(&rib->flows_lock); + list_for_each_safe(pos, n, &rib->cdap_reqs) { + struct mgmt_flow * flow = + list_entry(pos, struct mgmt_flow, next); + if (cdap_destroy(flow->instance)) + LOG_ERR("Failed to destroy CDAP instance."); + } + pthread_rwlock_unlock(&rib->flows_lock); + + free(rib); return 0; } -int ribmgr_mgmt_flow(int fd) +int ribmgr_cdap_reply(struct cdap * instance, + int invoke_id, + int result, + buffer_t * val, + size_t len) { LOG_MISSING; + /* FIXME: Check all cdap_reqs here to see if we expect a reply */ + return -1; } -int ribmgr_bootstrap(struct dif_config * conf) +int ribmgr_cdap_read(struct cdap * instance, + char * name) +{ + LOG_MISSING; + + return -1; +} + +int ribmgr_cdap_write(struct cdap * instance, + char * name, + buffer_t * val, + size_t len, + uint32_t flags) +{ + LOG_MISSING; + + return -1; +} + +int ribmgr_cdap_create(struct cdap * instance, + char * name, + buffer_t val) { LOG_MISSING; return -1; } +int ribmgr_cdap_delete(struct cdap * instance, + char * name, + buffer_t val) +{ + LOG_MISSING; + + return -1; +} + +int ribmgr_cdap_start(struct cdap * instance, + char * name) +{ + LOG_MISSING; + + /* FIXME: Handle enrollment request here */ + + return -1; +} + +int ribmgr_cdap_stop(struct cdap * instance, + char * name) +{ + LOG_MISSING; + + return -1; +} + +static struct cdap_ops ribmgr_ops = { + .cdap_reply = ribmgr_cdap_reply, + .cdap_read = ribmgr_cdap_read, + .cdap_write = ribmgr_cdap_write, + .cdap_create = ribmgr_cdap_create, + .cdap_delete = ribmgr_cdap_delete, + .cdap_start = ribmgr_cdap_start, + .cdap_stop = ribmgr_cdap_stop +}; + +int ribmgr_mgmt_flow(int fd) +{ + struct cdap * instance = NULL; + struct mgmt_flow * flow; + int iid = 0; + + flow = malloc(sizeof(*flow)); + if (flow == NULL) + return -1; + + instance = cdap_create(&ribmgr_ops, fd); + if (instance == NULL) { + LOG_ERR("Failed to create CDAP instance"); + free(flow); + return -1; + } + + INIT_LIST_HEAD(&flow->next); + flow->instance = instance; + flow->fd = fd; + + pthread_rwlock_wrlock(&rib->flows_lock); + if (list_empty(&rib->flows)) { + pthread_mutex_lock(&rib->cdap_reqs_lock); + iid = cdap_send_start(instance, + ENROLLMENT); + if (iid < 0) { + pthread_mutex_unlock(&rib->cdap_reqs_lock); + pthread_rwlock_unlock(&rib->flows_lock); + LOG_ERR("Failed to start enrollment."); + cdap_destroy(instance); + free(flow); + return -1; + } + + if (cdap_request_add(instance, START, ENROLLMENT, iid)) { + pthread_mutex_unlock(&rib->cdap_reqs_lock); + pthread_rwlock_unlock(&rib->flows_lock); + LOG_ERR("Failed to add CDAP request to list."); + cdap_destroy(instance); + free(flow); + return -1; + } + pthread_mutex_unlock(&rib->cdap_reqs_lock); + } + + list_add(&flow->next, &rib->flows); + pthread_rwlock_unlock(&rib->flows_lock); + + return 0; +} + +int ribmgr_bootstrap(struct dif_config * conf) +{ + if (conf == NULL || + conf->type != IPCP_NORMAL) { + LOG_ERR("Bad DIF configuration."); + return -1; + } + + rib->dtc.addr_size = conf->addr_size; + rib->dtc.cep_id_size = conf->cep_id_size; + rib->dtc.pdu_length_size = conf->pdu_length_size; + rib->dtc.seqno_size = conf->seqno_size; + rib->dtc.ttl_size = conf->ttl_size; + rib->dtc.chk_size = conf->chk_size; + rib->dtc.min_pdu_size = conf->min_pdu_size; + rib->dtc.max_pdu_size = conf->max_pdu_size; + + if (frct_init(&rib->dtc)) { + LOG_ERR("Failed to initialize FRCT."); + return -1; + } + + LOG_DBG("Bootstrapped RIB Manager."); + + return 0; +} + int ribmgr_fmgr_msg() { LOG_MISSING; |