diff options
author | Sander Vrijders <[email protected]> | 2017-02-23 14:31:31 +0100 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2017-03-03 11:20:40 +0100 |
commit | a409fd81dfc6d22f9a287f15394b86490dea5273 (patch) | |
tree | cec27d3c2064f0c0bcb564060d9d9012f819b22f /src/ipcpd/normal/neighbors.c | |
parent | 46c2f9d5363cdff2d99cf1b1c4a41c5bf97d2c03 (diff) | |
download | ouroboros-a409fd81dfc6d22f9a287f15394b86490dea5273.tar.gz ouroboros-a409fd81dfc6d22f9a287f15394b86490dea5273.zip |
ipcpd: normal: Refactor application entities and add neighbors struct
This refactors the different Application Entities of the normal
IPCP. They all listen to and use the connection manager to establish
new application connections.
This commit also adds a neighbors struct to the normal IPCP. It
contains neighbor structs that contain application
connection. Notifiers can be registered in case a neighbor changes
(added, removed, QoS changed).
The flow manager has an instance of this neighbors struct and listens
to these events to update its flow set. The routing component also
listens to these events so that it can update the FSDB if needed. The
flow manager now also creates the PFF instances and the routing
instances per QoS cube.
The RIB manager also uses this an instance of the neighbors struct and
listens to neighbor events as well.
Diffstat (limited to 'src/ipcpd/normal/neighbors.c')
-rw-r--r-- | src/ipcpd/normal/neighbors.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c new file mode 100644 index 00000000..40ef0d73 --- /dev/null +++ b/src/ipcpd/normal/neighbors.c @@ -0,0 +1,213 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + * Dimitri Staessens <[email protected]> + * Sander Vrijders <[email protected]> + * + * 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 "neighbors" + +#include <ouroboros/config.h> +#include <ouroboros/shared.h> +#include <ouroboros/ipcp-dev.h> +#include <ouroboros/errno.h> +#include <ouroboros/logs.h> + +#include "neighbors.h" + +#include <stdlib.h> +#include <assert.h> +#include <inttypes.h> + +static void notify_listeners(enum nb_event event, + struct nb * nb, + struct nbs * nbs) +{ + struct list_head * p = NULL; + + list_for_each(p, &nbs->notifiers) { + struct nb_notifier * e = + list_entry(p, struct nb_notifier, next); + if (e->notify_call(event, nb->conn)) + log_err("Listener reported an error."); + } +} + +struct nbs * nbs_create(void) +{ + struct nbs * nbs; + + nbs = malloc(sizeof(*nbs)); + if (nbs == NULL) + return NULL; + + list_head_init(&nbs->list); + list_head_init(&nbs->notifiers); + + if (pthread_mutex_init(&nbs->list_lock, NULL)) + return NULL; + + if (pthread_mutex_init(&nbs->notifiers_lock, NULL)) { + pthread_mutex_destroy(&nbs->list_lock); + return NULL; + } + + return nbs; +} + +void nbs_destroy(struct nbs * nbs) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each_safe(p, n, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + list_del(&e->next); + free(e); + } + + pthread_mutex_unlock(&nbs->list_lock); + + pthread_mutex_destroy(&nbs->list_lock); + pthread_mutex_destroy(&nbs->notifiers_lock); +} + +int nbs_add(struct nbs * nbs, + struct conn conn) +{ + struct nb * nb; + + assert(nbs); + + nb = malloc(sizeof(*nb)); + if (nb == NULL) + return -ENOMEM; + + nb->conn = conn; + + list_head_init(&nb->next); + + pthread_mutex_lock(&nbs->list_lock); + + list_add(&nb->next, &nbs->list); + + notify_listeners(NEIGHBOR_ADDED, nb, nbs); + + pthread_mutex_unlock(&nbs->list_lock); + + log_info("Added neighbor with address %" PRIu64 " to list.", + conn.conn_info.addr); + + return 0; +} + +int nbs_update_qos(struct nbs * nbs, + int fd, + qosspec_t qs) +{ + struct list_head * p = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each(p, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + if (e->conn.flow_info.fd == fd) { + e->conn.flow_info.qs = qs; + + notify_listeners(NEIGHBOR_QOS_CHANGE, e, nbs); + + pthread_mutex_unlock(&nbs->list_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->list_lock); + + return -1; +} + +int nbs_del(struct nbs * nbs, + int fd) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each_safe(p, n, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + if (e->conn.flow_info.fd == fd) { + notify_listeners(NEIGHBOR_REMOVED, e, nbs); + list_del(&e->next); + free(e); + pthread_mutex_unlock(&nbs->list_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->list_lock); + + return -1; +} + +int nbs_reg_notifier(struct nbs * nbs, + struct nb_notifier * notify) +{ + assert(nbs); + assert(notify); + + pthread_mutex_lock(&nbs->notifiers_lock); + + list_head_init(¬ify->next); + list_add(¬ify->next, &nbs->notifiers); + + pthread_mutex_unlock(&nbs->notifiers_lock); + + return 0; +} + +int nbs_unreg_notifier(struct nbs * nbs, + struct nb_notifier * notify) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + pthread_mutex_lock(&nbs->notifiers_lock); + + list_for_each_safe(p, n, &nbs->notifiers) { + struct nb_notifier * e = + list_entry(p, struct nb_notifier, next); + if (e == notify) { + list_del(&e->next); + pthread_mutex_unlock(&nbs->notifiers_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->notifiers_lock); + + return -1; +} |