diff options
| author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-08-01 11:17:42 +0200 | 
|---|---|---|
| committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-08-01 11:17:42 +0200 | 
| commit | 84293e0e57ee2a3d779a575717fbc54f8e94e178 (patch) | |
| tree | e0825f5586c2870839f15e0c8f4b390463145cd0 /src/ipcpd/normal | |
| parent | 434c782c99496b491684f4ab0058d9491c250774 (diff) | |
| parent | cf719963be2e42026012e152ae49f4c764dd9b4f (diff) | |
| download | ouroboros-84293e0e57ee2a3d779a575717fbc54f8e94e178.tar.gz ouroboros-84293e0e57ee2a3d779a575717fbc54f8e94e178.zip | |
Merged in sandervrijders/ouroboros/be-enrolment (pull request #182)
Be enrolment
Diffstat (limited to 'src/ipcpd/normal')
| -rw-r--r-- | src/ipcpd/normal/dt_const.h | 3 | ||||
| -rw-r--r-- | src/ipcpd/normal/fmgr.c | 84 | ||||
| -rw-r--r-- | src/ipcpd/normal/fmgr.h | 3 | ||||
| -rw-r--r-- | src/ipcpd/normal/frct.c | 20 | ||||
| -rw-r--r-- | src/ipcpd/normal/frct.h | 2 | ||||
| -rw-r--r-- | src/ipcpd/normal/main.c | 68 | ||||
| -rw-r--r-- | src/ipcpd/normal/ribmgr.c | 293 | ||||
| -rw-r--r-- | src/ipcpd/normal/ribmgr.h | 7 | 
8 files changed, 421 insertions, 59 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..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; @@ -48,7 +51,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 +68,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,10 +80,21 @@ static void * fmgr_listen(void * o)          int fd;          char * ae_name; -        while (true) { +        /* 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 (_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;                  } @@ -89,37 +103,46 @@ static void * fmgr_listen(void * o)                          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;                  }                  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_add_flow(fd)) { +                                LOG_ERR("Failed to hand fd to RIB."); +                                flow_dealloc(fd); +                                pthread_rwlock_rdlock(&_ipcp->state_lock); +                                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); +                                pthread_rwlock_rdlock(&_ipcp->state_lock); +                                continue; +                        }                  }                  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; @@ -127,16 +150,15 @@ 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,20 +170,21 @@ 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)                          free(e->ae_name); -                flow_dealloc(e->fd); +                if (ribmgr_remove_flow(e->fd)) +                    LOG_ERR("Failed to remove management flow.");          } -        free(instance); +        free(fmgr);          return 0;  } @@ -185,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; @@ -233,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 22f8a9fc..ba465540 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -22,24 +22,36 @@  #define OUROBOROS_PREFIX "flow-rtx-control" +#include <stdlib.h> +  #include <ouroboros/logs.h>  #include "frct.h"  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..57fb72df 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> @@ -58,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; @@ -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 */ +        } + +        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; +        } + +        /* FIXME: Wait until state changed to ENROLLED */ + +        return 0;  }  static int normal_ipcp_bootstrap(struct dif_config * conf)  { -        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 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; + +        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..8bb320c0 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -22,41 +22,324 @@  #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" +#include "ipcp.h" + +#define ENROLLMENT "enrollment" + +extern struct ipcp * _ipcp; + +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); +        INIT_LIST_HEAD(&rib->cdap_reqs); + +        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->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); + +        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_fmgr_msg() +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_add_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_rdlock(&_ipcp->state_lock); +        pthread_rwlock_wrlock(&rib->flows_lock); +        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); +                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); +        } +        pthread_rwlock_unlock(&_ipcp->state_lock); + +        list_add(&flow->next, &rib->flows); +        pthread_rwlock_unlock(&rib->flows_lock); + +        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 || +            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; +} 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 | 
