From 2c7e3030edb84abae14042f7a1a22b44255324be Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 20 Sep 2017 13:56:17 +0200 Subject: ipcpd: normal: Make PFF policy-based This turns the PDU Forwarding Function of the IPCP into a policy. For now only the simple PFF policy is available. --- src/ipcpd/normal/CMakeLists.txt | 1 + src/ipcpd/normal/addr_auth.c | 13 ++- src/ipcpd/normal/dt.c | 4 +- src/ipcpd/normal/dt.h | 1 + src/ipcpd/normal/enroll.c | 2 + src/ipcpd/normal/main.c | 1 + src/ipcpd/normal/pff.c | 154 +++++++++++--------------------- src/ipcpd/normal/pff.h | 39 ++++---- src/ipcpd/normal/pol-pff-ops.h | 63 +++++++++++++ src/ipcpd/normal/pol/flat.c | 7 ++ src/ipcpd/normal/pol/flat.h | 6 +- src/ipcpd/normal/pol/link_state.c | 2 +- src/ipcpd/normal/pol/simple_pff.c | 183 ++++++++++++++++++++++++++++++++++++++ src/ipcpd/normal/pol/simple_pff.h | 57 ++++++++++++ 14 files changed, 398 insertions(+), 135 deletions(-) create mode 100644 src/ipcpd/normal/pol-pff-ops.h create mode 100644 src/ipcpd/normal/pol/simple_pff.c create mode 100644 src/ipcpd/normal/pol/simple_pff.h (limited to 'src/ipcpd/normal') diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index e5fc33da..ebb413a8 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -44,6 +44,7 @@ set(SOURCE_FILES pol/flat.c pol/link_state.c pol/graph.c + pol/simple_pff.c ) add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index e4aacccd..c7c744c7 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -29,33 +29,30 @@ #include "pol/flat.h" #include -#include -struct addr_auth { - struct pol_addr_auth_ops * ops; -} addr_auth; +struct pol_addr_auth_ops * ops; int addr_auth_init(enum pol_addr_auth type, const void * info) { switch (type) { case FLAT_RANDOM: - addr_auth.ops = &flat_ops; + ops = &flat_ops; break; default: log_err("Unknown address authority type."); return -1; } - return addr_auth.ops->init(info); + return ops->init(info); } uint64_t addr_auth_address(void) { - return addr_auth.ops->address(); + return ops->address(); } int addr_auth_fini(void) { - return addr_auth.ops->fini(); + return ops->fini(); } diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c index 2db0e7e2..f99f7072 100644 --- a/src/ipcpd/normal/dt.c +++ b/src/ipcpd/normal/dt.c @@ -164,6 +164,7 @@ static void * dt_conn_handle(void * o) } int dt_init(enum pol_routing pr, + enum pol_pff pp, uint8_t addr_size, uint8_t fd_size, bool has_ttl) @@ -201,8 +202,9 @@ int dt_init(enum pol_routing pr, } for (i = 0; i < QOS_CUBE_MAX; ++i) { - dt.pff[i] = pff_create(); + dt.pff[i] = pff_create(pp); if (dt.pff[i] == NULL) { + log_err("Failed to create a PFF."); for (j = 0; j < i; ++j) pff_destroy(dt.pff[j]); goto fail_pff; diff --git a/src/ipcpd/normal/dt.h b/src/ipcpd/normal/dt.h index 09716153..ea029647 100644 --- a/src/ipcpd/normal/dt.h +++ b/src/ipcpd/normal/dt.h @@ -33,6 +33,7 @@ #define INVALID_ADDR 0 int dt_init(enum pol_routing pr, + enum pol_pff pp, uint8_t addr_size, uint8_t fd_size, bool has_ttl diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c index d14c62ac..d245d0bd 100644 --- a/src/ipcpd/normal/enroll.c +++ b/src/ipcpd/normal/enroll.c @@ -167,6 +167,8 @@ static ssize_t enroll_pack(uint8_t ** buf) config.addr_auth_type = enroll.conf.addr_auth_type; config.has_routing_type = true; config.routing_type = enroll.conf.routing_type; + config.has_pff_type = true; + config.pff_type = enroll.conf.pff_type; config.dif_info = &dif_info; dif_info.dif_name = (char *) enroll.conf.dif_info.dif_name; diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 6cfea4bc..8c16fd22 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -79,6 +79,7 @@ static int initialize_components(const struct ipcp_config * conf) log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr); if (dt_init(conf->routing_type, + conf->pff_type, conf->addr_size, conf->fd_size, conf->has_ttl)) { diff --git a/src/ipcpd/normal/pff.c b/src/ipcpd/normal/pff.c index d6c9ddee..27ff17f7 100644 --- a/src/ipcpd/normal/pff.c +++ b/src/ipcpd/normal/pff.c @@ -20,150 +20,98 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#define _POSIX_C_SOURCE 200112L - -#include "config.h" - -#define OUROBOROS_PREFIX "pff" - -#include -#include #include -#include -#include - #include "pff.h" +#include "pol-pff-ops.h" +#include "pol/simple_pff.h" struct pff { - struct htable * table; - pthread_rwlock_t lock; + struct pol_pff_ops * ops; + struct pff_i * pff_i; }; -struct pff * pff_create(void) +struct pff * pff_create(enum pol_pff pol) { - struct pff * tmp; + struct pff * pff; - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) + pff = malloc(sizeof(*pff)); + if (pff == NULL) return NULL; - if (pthread_rwlock_init(&tmp->lock, NULL)) { - free(tmp); - return NULL; + switch (pol) { + case SIMPLE_PFF: + pff->ops = &simple_pff_ops; + pff->pff_i = pff->ops->create(); + if (pff->pff_i == NULL) + goto err; + break; + default: + goto err; } - tmp->table = htable_create(PFT_SIZE, false); - if (tmp->table == NULL) { - pthread_rwlock_destroy(&tmp->lock); - free(tmp); - return NULL; - } - - return tmp; + return pff; + err: + free(pff); + return NULL; } -void pff_destroy(struct pff * instance) +void pff_destroy(struct pff * pff) { - assert(instance); - - htable_destroy(instance->table); + pff->ops->destroy(pff->pff_i); - pthread_rwlock_destroy(&instance->lock); - free(instance); + free(pff); } -void pff_lock(struct pff * instance) +void pff_lock(struct pff * pff) { - pthread_rwlock_wrlock(&instance->lock); + return pff->ops->lock(pff->pff_i); } -void pff_unlock(struct pff * instance) +void pff_unlock(struct pff * pff) { - pthread_rwlock_unlock(&instance->lock); + return pff->ops->unlock(pff->pff_i); } -int pff_add(struct pff * instance, +int pff_add(struct pff * pff, uint64_t addr, - int fd) + int * fd, + size_t len) { - int * val; - - assert(instance); - - val = malloc(sizeof(*val)); - if (val == NULL) - return -ENOMEM; - - *val = fd; - - if (htable_insert(instance->table, addr, val)) { - free(val); - return -1; - } - - return 0; + return pff->ops->add(pff->pff_i, addr, fd, len); } -int pff_update(struct pff * instance, +int pff_update(struct pff * pff, uint64_t addr, - int fd) + int * fd, + size_t len) { - int * val; - - assert(instance); - - val = malloc(sizeof(*val)); - if (val == NULL) - return -ENOMEM; - *val = fd; - - if (htable_delete(instance->table, addr)) { - free(val); - return -1; - } - - if (htable_insert(instance->table, addr, val)) { - free(val); - return -1; - } - - return 0; + return pff->ops->update(pff->pff_i, addr, fd, len); } -int pff_remove(struct pff * instance, - uint64_t addr) +int pff_del(struct pff * pff, + uint64_t addr) { - assert(instance); - - if (htable_delete(instance->table, addr)) - return -1; - - return 0; + return pff->ops->del(pff->pff_i, addr); } -void pff_flush(struct pff * instance) +void pff_flush(struct pff * pff) { - assert(instance); - - htable_flush(instance->table); + return pff->ops->flush(pff->pff_i); } -int pff_nhop(struct pff * instance, +int pff_nhop(struct pff * pff, uint64_t addr) { - int * j; - int fd = -1; - - assert(instance); - - pthread_rwlock_rdlock(&instance->lock); - - j = (int *) htable_lookup(instance->table, addr); - if (j != NULL) - fd = *j; + return pff->ops->nhop(pff->pff_i, addr); +} - pthread_rwlock_unlock(&instance->lock); +int pff_flow_state_change(struct pff * pff, + int fd, + bool up) +{ + if (pff->ops->flow_state_change != NULL) + return pff->ops->flow_state_change(pff->pff_i, fd, up); - return fd; + return 0; } diff --git a/src/ipcpd/normal/pff.h b/src/ipcpd/normal/pff.h index 0a33d884..f44cd0e9 100644 --- a/src/ipcpd/normal/pff.h +++ b/src/ipcpd/normal/pff.h @@ -23,36 +23,41 @@ #ifndef OUROBOROS_IPCPD_NORMAL_PFF_H #define OUROBOROS_IPCPD_NORMAL_PFF_H +#include + #include +#include +#include -/* - * PFF will take a type in the future, - * to allow different policies. - * Only 1 fd per next hop for now. - */ -struct pff * pff_create(void); +struct pff * pff_create(enum pol_pff pol); -void pff_destroy(struct pff * instance); +void pff_destroy(struct pff * pff); -void pff_lock(struct pff * instance); +void pff_lock(struct pff * pff); -void pff_unlock(struct pff * instance); +void pff_unlock(struct pff * pff); -int pff_add(struct pff * instance, +int pff_add(struct pff * pff, uint64_t addr, - int fd); + int * fd, + size_t len); -int pff_update(struct pff * instance, +int pff_update(struct pff * pff, uint64_t addr, - int fd); + int * fd, + size_t len); -int pff_remove(struct pff * instance, - uint64_t addr); +int pff_del(struct pff * pff, + uint64_t addr); -void pff_flush(struct pff * instance); +void pff_flush(struct pff * pff); /* Returns fd towards next hop */ -int pff_nhop(struct pff * instance, +int pff_nhop(struct pff * pff, uint64_t addr); +int pff_flow_state_change(struct pff * pff, + int fd, + bool up); + #endif /* OUROBOROS_IPCPD_NORMAL_PFF_H */ diff --git a/src/ipcpd/normal/pol-pff-ops.h b/src/ipcpd/normal/pol-pff-ops.h new file mode 100644 index 00000000..b8105f6f --- /dev/null +++ b/src/ipcpd/normal/pol-pff-ops.h @@ -0,0 +1,63 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Pff policy ops + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_POL_PFF_OPS_H +#define OUROBOROS_IPCPD_NORMAL_POL_PFF_OPS_H + +#include + +struct pff_i; + +struct pol_pff_ops { + struct pff_i * (* create)(void); + + void (* destroy)(struct pff_i * pff_i); + + void (* lock)(struct pff_i * pff_i); + + void (* unlock)(struct pff_i * pff_i); + + int (* add)(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len); + + int (* update)(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len); + + int (* del)(struct pff_i * pff_i, + uint64_t addr); + + void (* flush)(struct pff_i * pff_i); + + int (* nhop)(struct pff_i * pff_i, + uint64_t addr); + + /* Optional operation. */ + int (* flow_state_change)(struct pff_i * pff_i, + int fd, + bool up); +}; + +#endif /* OUROBOROS_IPCPD_NORMAL_POL_PFF_OPS_H */ diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index 0c4648c5..c52ebe38 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -30,6 +30,7 @@ #include #include "ipcp.h" +#include "flat.h" #include #include @@ -46,6 +47,12 @@ struct { #define INVALID_ADDRESS 0 +struct pol_addr_auth_ops flat_ops = { + .init = flat_init, + .fini = flat_fini, + .address = flat_address +}; + int flat_init(const void * info) { flat.addr_size = *((uint8_t *) info); diff --git a/src/ipcpd/normal/pol/flat.h b/src/ipcpd/normal/pol/flat.h index 57af591e..fdd06d68 100644 --- a/src/ipcpd/normal/pol/flat.h +++ b/src/ipcpd/normal/pol/flat.h @@ -31,10 +31,6 @@ int flat_fini(void); uint64_t flat_address(void); -struct pol_addr_auth_ops flat_ops = { - .init = flat_init, - .fini = flat_fini, - .address = flat_address -}; +struct pol_addr_auth_ops flat_ops; #endif /* OUROBOROS_IPCPD_NORMAL_FLAT_H */ diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c index 2823f28e..26370682 100644 --- a/src/ipcpd/normal/pol/link_state.c +++ b/src/ipcpd/normal/pol/link_state.c @@ -404,7 +404,7 @@ static void * calculate_pff(void * o) if (fd == -1) continue; - pff_add(instance->pff, table[i]->dst, fd); + pff_add(instance->pff, table[i]->dst, &fd, 1); } pff_unlock(instance->pff); diff --git a/src/ipcpd/normal/pol/simple_pff.c b/src/ipcpd/normal/pol/simple_pff.c new file mode 100644 index 00000000..28f7aa2e --- /dev/null +++ b/src/ipcpd/normal/pol/simple_pff.c @@ -0,0 +1,183 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Simple PDU Forwarding Function + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., http://www.fsf.org/about/contact/. + */ + +#define _POSIX_C_SOURCE 200112L + +#include "config.h" + +#include +#include + +#include +#include + +#include "simple_pff.h" + +struct pff_i { + struct htable * table; + pthread_rwlock_t lock; +}; + +struct pol_pff_ops simple_pff_ops = { + .create = simple_pff_create, + .destroy = simple_pff_destroy, + .lock = simple_pff_lock, + .unlock = simple_pff_unlock, + .add = simple_pff_add, + .update = simple_pff_update, + .del = simple_pff_del, + .flush = simple_pff_flush, + .nhop = simple_pff_nhop, + .flow_state_change = NULL +}; + +struct pff_i * simple_pff_create(void) +{ + struct pff_i * tmp; + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return NULL; + + if (pthread_rwlock_init(&tmp->lock, NULL)) { + free(tmp); + return NULL; + } + + tmp->table = htable_create(PFT_SIZE, false); + if (tmp->table == NULL) { + pthread_rwlock_destroy(&tmp->lock); + free(tmp); + return NULL; + } + + return tmp; +} + +void simple_pff_destroy(struct pff_i * pff_i) +{ + assert(pff_i); + + htable_destroy(pff_i->table); + + pthread_rwlock_destroy(&pff_i->lock); + free(pff_i); +} + +void simple_pff_lock(struct pff_i * pff_i) +{ + pthread_rwlock_wrlock(&pff_i->lock); +} + +void simple_pff_unlock(struct pff_i * pff_i) +{ + pthread_rwlock_unlock(&pff_i->lock); +} + +int simple_pff_add(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len) +{ + int * val; + + assert(pff_i); + assert(len > 0); + + val = malloc(sizeof(*val)); + if (val == NULL) + return -ENOMEM; + + *val = fd[0]; + + if (htable_insert(pff_i->table, addr, val)) { + free(val); + return -1; + } + + return 0; +} + +int simple_pff_update(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len) +{ + int * val; + + assert(pff_i); + assert(len > 0); + + val = malloc(sizeof(*val)); + if (val == NULL) + return -ENOMEM; + *val = fd[0]; + + if (htable_delete(pff_i->table, addr)) { + free(val); + return -1; + } + + if (htable_insert(pff_i->table, addr, val)) { + free(val); + return -1; + } + + return 0; +} + +int simple_pff_del(struct pff_i * pff_i, + uint64_t addr) +{ + assert(pff_i); + + if (htable_delete(pff_i->table, addr)) + return -1; + + return 0; +} + +void simple_pff_flush(struct pff_i * pff_i) +{ + assert(pff_i); + + htable_flush(pff_i->table); +} + +int simple_pff_nhop(struct pff_i * pff_i, + uint64_t addr) +{ + int * j; + int fd = -1; + + assert(pff_i); + + pthread_rwlock_rdlock(&pff_i->lock); + + j = (int *) htable_lookup(pff_i->table, addr); + if (j != NULL) + fd = *j; + + pthread_rwlock_unlock(&pff_i->lock); + + return fd; +} diff --git a/src/ipcpd/normal/pol/simple_pff.h b/src/ipcpd/normal/pol/simple_pff.h new file mode 100644 index 00000000..ef34dfee --- /dev/null +++ b/src/ipcpd/normal/pol/simple_pff.h @@ -0,0 +1,57 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Simple policy for PFF + * + * Dimitri Staessens + * Sander Vrijders + * + * 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., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_SIMPLE_PFF_H +#define OUROBOROS_IPCPD_NORMAL_SIMPLE_PFF_H + +#include "pol-pff-ops.h" + +struct pff_i * simple_pff_create(void); + +void simple_pff_destroy(struct pff_i * pff_i); + +void simple_pff_lock(struct pff_i * pff_i); + +void simple_pff_unlock(struct pff_i * pff_i); + +int simple_pff_add(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len); + +int simple_pff_update(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len); + +int simple_pff_del(struct pff_i * pff_i, + uint64_t addr); + +void simple_pff_flush(struct pff_i * pff_i); + +/* Returns fd towards next hop */ +int simple_pff_nhop(struct pff_i * pff_i, + uint64_t addr); + +struct pol_pff_ops simple_pff_ops; + +#endif /* OUROBOROS_IPCPD_NORMAL_SIMPLE_PFF_H */ -- cgit v1.2.3