From 0c0508619959b5ac98b31b4389fcfadf5ee26d9b Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 27 Jul 2016 16:46:23 +0200 Subject: 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. --- src/ipcpd/local/main.c | 1 - src/ipcpd/normal/dt_const.h | 3 +- src/ipcpd/normal/fmgr.c | 52 +++++---- src/ipcpd/normal/frct.c | 21 +++- src/ipcpd/normal/frct.h | 2 +- src/ipcpd/normal/main.c | 62 ++++++++++- src/ipcpd/normal/ribmgr.c | 265 +++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 369 insertions(+), 37 deletions(-) (limited to 'src/ipcpd') diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index fcf5f879..4b9dcbbc 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include 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 + #include #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 + * + * 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 @@ -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 #include +#include +#include + +#include +#include +#include #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; -- cgit v1.2.3 From cf719963be2e42026012e152ae49f4c764dd9b4f Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Thu, 28 Jul 2016 17:23:42 +0200 Subject: ipcpd: normal: Allow initiating enrollment This will add more functionality for enrolling two normal IPCPs with each other. Some bugs were fixed in CDAP. Now on enrolling, an IPCP will send a START message to the other IPCP. Next step is syncing the RIBs. --- src/ipcpd/ipcp.h | 1 + src/ipcpd/normal/fmgr.c | 42 ++++++++++++++++++++++++--------------- src/ipcpd/normal/fmgr.h | 3 --- src/ipcpd/normal/frct.c | 5 +---- src/ipcpd/normal/main.c | 12 ++++++------ src/ipcpd/normal/ribmgr.c | 50 +++++++++++++++++++++++++++++++++++------------ src/ipcpd/normal/ribmgr.h | 7 +++---- src/lib/cdap.c | 4 ++++ src/lib/shm_ap_rbuff.c | 2 +- 9 files changed, 80 insertions(+), 46 deletions(-) (limited to 'src/ipcpd') diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index bbf1d1f7..630f7922 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -33,6 +33,7 @@ enum ipcp_state { IPCP_INIT = 0, + IPCP_PENDING_ENROLL, IPCP_ENROLLED, IPCP_DISCONNECTED, IPCP_SHUTDOWN diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 4b3c49e6..a539b289 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -35,6 +35,9 @@ #include "fmgr.h" #include "ribmgr.h" #include "frct.h" +#include "ipcp.h" + +extern struct ipcp * _ipcp; struct n_1_flow { int fd; @@ -77,28 +80,37 @@ static void * fmgr_listen(void * o) int fd; char * ae_name; - /* FIXME: Only start to listen once we are enrolled */ + /* FIXME: Avoid busy wait and react to pthread_cond_t */ + pthread_rwlock_rdlock(&_ipcp->state_lock); + while (_ipcp->state != IPCP_ENROLLED || + _ipcp->state != IPCP_SHUTDOWN) { + pthread_rwlock_unlock(&_ipcp->state_lock); + sched_yield(); + pthread_rwlock_rdlock(&_ipcp->state_lock); + } - while (true) { + while (_ipcp->state != IPCP_SHUTDOWN) { + pthread_rwlock_unlock(&_ipcp->state_lock); fd = flow_accept(&ae_name); if (fd < 0) { LOG_ERR("Failed to accept flow."); + pthread_rwlock_rdlock(&_ipcp->state_lock); 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)) LOG_ERR("Failed to reply to flow allocation."); flow_dealloc(fd); + pthread_rwlock_rdlock(&_ipcp->state_lock); continue; } if (flow_alloc_resp(fd, 0)) { LOG_ERR("Failed to reply to flow allocation."); flow_dealloc(fd); + pthread_rwlock_rdlock(&_ipcp->state_lock); continue; } @@ -106,9 +118,10 @@ static void * fmgr_listen(void * o) ae_name); if (strcmp(ae_name, MGMT_AE) == 0) { - if (ribmgr_mgmt_flow(fd)) { + if (ribmgr_add_flow(fd)) { LOG_ERR("Failed to hand fd to RIB."); flow_dealloc(fd); + pthread_rwlock_rdlock(&_ipcp->state_lock); continue; } } @@ -117,6 +130,7 @@ static void * fmgr_listen(void * o) if (frct_dt_flow(fd)) { LOG_ERR("Failed to hand fd to FRCT."); flow_dealloc(fd); + pthread_rwlock_rdlock(&_ipcp->state_lock); continue; } } @@ -124,8 +138,11 @@ static void * fmgr_listen(void * o) if (add_n_1_fd(fd, ae_name)) { LOG_ERR("Failed to add file descriptor to list."); flow_dealloc(fd); + pthread_rwlock_rdlock(&_ipcp->state_lock); continue; } + + pthread_rwlock_rdlock(&_ipcp->state_lock); } return (void *) 0; @@ -134,9 +151,8 @@ static void * fmgr_listen(void * o) int fmgr_init() { fmgr = malloc(sizeof(*fmgr)); - if (fmgr == NULL) { + if (fmgr == NULL) return -1; - } INIT_LIST_HEAD(&fmgr->n_1_flows); @@ -164,7 +180,8 @@ int fmgr_fini() list_entry(pos, struct n_1_flow, next); if (e->ae_name != NULL) free(e->ae_name); - flow_dealloc(e->fd); + if (ribmgr_remove_flow(e->fd)) + LOG_ERR("Failed to remove management flow."); } free(fmgr); @@ -191,7 +208,7 @@ int fmgr_mgmt_flow(char * dst_name) return -1; } - if (ribmgr_mgmt_flow(fd)) { + if (ribmgr_add_flow(fd)) { LOG_ERR("Failed to hand file descriptor to RIB manager"); flow_dealloc(fd); return -1; @@ -239,10 +256,3 @@ int fmgr_flow_dealloc(int port_id) return -1; } - -int fmgr_flow_msg() -{ - LOG_MISSING; - - return -1; -} diff --git a/src/ipcpd/normal/fmgr.h b/src/ipcpd/normal/fmgr.h index 867cbff6..dc88bbdf 100644 --- a/src/ipcpd/normal/fmgr.h +++ b/src/ipcpd/normal/fmgr.h @@ -52,7 +52,4 @@ int fmgr_flow_alloc_resp(pid_t n_api, int fmgr_flow_dealloc(int port_id); -/* RIB Manager calls this (param will be of type fmgr_msg_t) */ -int fmgr_flow_msg(); - #endif diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c index 49006276..ba465540 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -29,12 +29,10 @@ #include "frct.h" struct frct_i { - }; struct frct { struct dt_const * dtc; - } * frct = NULL; int frct_init(struct dt_const * dtc) @@ -43,9 +41,8 @@ int frct_init(struct dt_const * dtc) return -1; frct = malloc(sizeof(*frct)); - if (frct == NULL) { + if (frct == NULL) return -1; - } frct->dtc = dtc; diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 54ebd674..57fb72df 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -80,14 +80,14 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c) pthread_cancel(normal_data(_ipcp)->mainloop); + if (fmgr_fini()) + LOG_ERR("Failed to finalize flow manager."); + if (ribmgr_fini()) LOG_ERR("Failed to finalize RIB manager."); if (frct_fini()) LOG_ERR("Failed to finalize FRCT."); - - if (fmgr_fini()) - LOG_ERR("Failed to finalize flow manager."); } default: return; @@ -138,15 +138,15 @@ static int normal_ipcp_enroll(char * dif_name) return -1; /* -ENOTINIT */ } + pthread_rwlock_unlock(&_ipcp->state_lock); + 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); + /* FIXME: Wait until state changed to ENROLLED */ return 0; } diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 4d29b098..8bb320c0 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -34,9 +34,12 @@ #include "ribmgr.h" #include "dt_const.h" #include "frct.h" +#include "ipcp.h" #define ENROLLMENT "enrollment" +extern struct ipcp * _ipcp; + enum cdap_opcode { READ = 0, WRITE, @@ -103,11 +106,11 @@ int cdap_request_add(struct cdap * instance, int ribmgr_init() { rib = malloc(sizeof(*rib)); - if (rib == NULL) { + if (rib == NULL) return -1; - } INIT_LIST_HEAD(&rib->flows); + INIT_LIST_HEAD(&rib->cdap_reqs); if (pthread_rwlock_init(&rib->flows_lock, NULL)) { LOG_ERR("Failed to initialize rwlock."); @@ -141,11 +144,13 @@ int ribmgr_fini() pthread_mutex_unlock(&rib->cdap_reqs_lock); pthread_rwlock_wrlock(&rib->flows_lock); - list_for_each_safe(pos, n, &rib->cdap_reqs) { + list_for_each_safe(pos, n, &rib->flows) { struct mgmt_flow * flow = list_entry(pos, struct mgmt_flow, next); if (cdap_destroy(flow->instance)) LOG_ERR("Failed to destroy CDAP instance."); + list_del(&flow->next); + free(flow); } pthread_rwlock_unlock(&rib->flows_lock); @@ -232,7 +237,7 @@ static struct cdap_ops ribmgr_ops = { .cdap_stop = ribmgr_cdap_stop }; -int ribmgr_mgmt_flow(int fd) +int ribmgr_add_flow(int fd) { struct cdap * instance = NULL; struct mgmt_flow * flow; @@ -253,8 +258,14 @@ int ribmgr_mgmt_flow(int fd) flow->instance = instance; flow->fd = fd; + pthread_rwlock_rdlock(&_ipcp->state_lock); pthread_rwlock_wrlock(&rib->flows_lock); - if (list_empty(&rib->flows)) { + if (list_empty(&rib->flows) && + (_ipcp->state == IPCP_INIT || + _ipcp->state == IPCP_DISCONNECTED)) { + _ipcp->state = IPCP_PENDING_ENROLL; + pthread_rwlock_unlock(&_ipcp->state_lock); + pthread_mutex_lock(&rib->cdap_reqs_lock); iid = cdap_send_start(instance, ENROLLMENT); @@ -277,6 +288,7 @@ int ribmgr_mgmt_flow(int fd) } pthread_mutex_unlock(&rib->cdap_reqs_lock); } + pthread_rwlock_unlock(&_ipcp->state_lock); list_add(&flow->next, &rib->flows); pthread_rwlock_unlock(&rib->flows_lock); @@ -284,6 +296,27 @@ int ribmgr_mgmt_flow(int fd) return 0; } +int ribmgr_remove_flow(int fd) +{ + struct list_head * pos, * n = NULL; + + pthread_rwlock_wrlock(&rib->flows_lock); + list_for_each_safe(pos, n, &rib->flows) { + struct mgmt_flow * flow = + list_entry(pos, struct mgmt_flow, next); + if (flow->fd == fd) { + if (cdap_destroy(flow->instance)) + LOG_ERR("Failed to destroy CDAP instance."); + list_del(&flow->next); + free(flow); + return 0; + } + } + pthread_rwlock_unlock(&rib->flows_lock); + + return -1; +} + int ribmgr_bootstrap(struct dif_config * conf) { if (conf == NULL || @@ -310,10 +343,3 @@ int ribmgr_bootstrap(struct dif_config * conf) return 0; } - -int ribmgr_fmgr_msg() -{ - LOG_MISSING; - - return -1; -} diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index 335189f9..e85c65be 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -28,10 +28,9 @@ int ribmgr_init(); int ribmgr_fini(); -int ribmgr_mgmt_flow(int fd); -int ribmgr_bootstrap(struct dif_config * conf); +int ribmgr_add_flow(int fd); +int ribmgr_remove_flow(int fd); -/* Called by Flow Manager (param of type fmgr_msg_t) */ -int ribmgr_fmgr_msg(); +int ribmgr_bootstrap(struct dif_config * conf); #endif diff --git a/src/lib/cdap.c b/src/lib/cdap.c index 441f7e44..4599fd8b 100644 --- a/src/lib/cdap.c +++ b/src/lib/cdap.c @@ -212,6 +212,7 @@ struct cdap * cdap_create(struct cdap_ops * ops, } instance->ops = ops; + instance->fd = fd; instance->ids = bmp_create(IDS_SIZE, 0); if (instance->ids == NULL) { @@ -234,6 +235,9 @@ int cdap_destroy(struct cdap * instance) pthread_cancel(instance->reader); + if (flow_dealloc(instance->fd)) + return -1; + pthread_mutex_lock(&instance->ids_lock); bmp_destroy(instance->ids); diff --git a/src/lib/shm_ap_rbuff.c b/src/lib/shm_ap_rbuff.c index 618c4c19..86570d98 100644 --- a/src/lib/shm_ap_rbuff.c +++ b/src/lib/shm_ap_rbuff.c @@ -296,7 +296,7 @@ struct rb_entry * shm_ap_rbuff_read(struct shm_ap_rbuff * rb) while (tail_el_ptr->port_id < 0) *rb->ptr_tail = (*rb->ptr_tail + 1) & (SHM_RBUFF_SIZE -1); - while(shm_rbuff_empty(rb)) + while (shm_rbuff_empty(rb)) if (pthread_cond_wait(rb->work, rb->shm_mutex) == EOWNERDEAD) { LOG_DBGF("Recovering dead mutex."); -- cgit v1.2.3