diff options
author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-07-27 16:46:23 +0200 |
---|---|---|
committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-07-27 16:46:23 +0200 |
commit | 0c0508619959b5ac98b31b4389fcfadf5ee26d9b (patch) | |
tree | 08b53089bd819a215412041282776fb225b31395 /src/ipcpd/normal/ribmgr.c | |
parent | bee74baa8fa8ffa71dbb659496bc88df3e8ce6a5 (diff) | |
download | ouroboros-0c0508619959b5ac98b31b4389fcfadf5ee26d9b.tar.gz ouroboros-0c0508619959b5ac98b31b4389fcfadf5ee26d9b.zip |
ipcpd: normal: Provide initial steps for enrollment
This provides the normal IPCP with bootstrapping and the initial steps
for enrollment. Next step is actually reacting to an enrollment
request and sending the data transfer constants.
Diffstat (limited to 'src/ipcpd/normal/ribmgr.c')
-rw-r--r-- | src/ipcpd/normal/ribmgr.c | 265 |
1 files changed, 261 insertions, 4 deletions
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; |