From b46ba7bb7405c3b5a85f4203f816e623a5edb2d7 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sat, 15 Feb 2020 21:39:24 +0100 Subject: ipcpd: Rename hashtable to pft This makes the hashtable more tailored to a packet forwarding table (PFT). In the end not much of a change was needed, but now it's clear the pft maps a destination address to a list of (outgoing) fds. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/unicast/CMakeLists.txt | 2 +- src/ipcpd/unicast/pol/alternate_pff.c | 93 ++++++----- src/ipcpd/unicast/pol/hashtable.c | 222 --------------------------- src/ipcpd/unicast/pol/hashtable.h | 55 ------- src/ipcpd/unicast/pol/pft.c | 222 +++++++++++++++++++++++++++ src/ipcpd/unicast/pol/pft.h | 55 +++++++ src/ipcpd/unicast/pol/simple_pff.c | 49 +++--- src/ipcpd/unicast/pol/tests/CMakeLists.txt | 2 +- src/ipcpd/unicast/pol/tests/hashtable_test.c | 129 ---------------- src/ipcpd/unicast/pol/tests/pft_test.c | 126 +++++++++++++++ 10 files changed, 475 insertions(+), 480 deletions(-) delete mode 100644 src/ipcpd/unicast/pol/hashtable.c delete mode 100644 src/ipcpd/unicast/pol/hashtable.h create mode 100644 src/ipcpd/unicast/pol/pft.c create mode 100644 src/ipcpd/unicast/pol/pft.h delete mode 100644 src/ipcpd/unicast/pol/tests/hashtable_test.c create mode 100644 src/ipcpd/unicast/pol/tests/pft_test.c diff --git a/src/ipcpd/unicast/CMakeLists.txt b/src/ipcpd/unicast/CMakeLists.txt index 192b6592..d6ec4a93 100644 --- a/src/ipcpd/unicast/CMakeLists.txt +++ b/src/ipcpd/unicast/CMakeLists.txt @@ -44,7 +44,7 @@ set(SOURCE_FILES routing.c psched.c # Add policies last - pol/hashtable.c + pol/pft.c pol/alternate_pff.c pol/flat.c pol/link_state.c diff --git a/src/ipcpd/unicast/pol/alternate_pff.c b/src/ipcpd/unicast/pol/alternate_pff.c index 36d8d513..80c93f0e 100644 --- a/src/ipcpd/unicast/pol/alternate_pff.c +++ b/src/ipcpd/unicast/pol/alternate_pff.c @@ -31,7 +31,7 @@ #include #include -#include "hashtable.h" +#include "pft.h" #include "alternate_pff.h" struct nhop { @@ -45,7 +45,7 @@ struct addr { }; struct pff_i { - struct htable * table; + struct pft * pft; struct list_head addrs; @@ -86,11 +86,11 @@ static int add_addr(struct pff_i * pff_i, static void del_addr(struct pff_i * pff_i, uint64_t addr) { - struct list_head * pos = NULL; - struct list_head * n = NULL; + struct list_head * p; + struct list_head * h; - list_for_each_safe(pos, n, &(pff_i->addrs)) { - struct addr * e = list_entry(pos, struct addr, next); + list_for_each_safe(p, h, &(pff_i->addrs)) { + struct addr * e = list_entry(p, struct addr, next); if (e->addr == addr) { list_del(&e->next); free(e); @@ -101,11 +101,11 @@ static void del_addr(struct pff_i * pff_i, static void del_addrs(struct pff_i * pff_i) { - struct list_head * pos = NULL; - struct list_head * n = NULL; + struct list_head * p; + struct list_head * h; - list_for_each_safe(pos, n, &(pff_i->addrs)) { - struct addr * e = list_entry(pos, struct addr, next); + list_for_each_safe(p, h, &(pff_i->addrs)) { + struct addr * e = list_entry(p, struct addr, next); list_del(&e->next); free(e); } @@ -113,11 +113,11 @@ static void del_addrs(struct pff_i * pff_i) static void del_nhops_down(struct pff_i * pff_i) { - struct list_head * pos = NULL; - struct list_head * n = NULL; + struct list_head * p; + struct list_head * h; - list_for_each_safe(pos, n, &(pff_i->nhops_down)) { - struct nhop * e = list_entry(pos, struct nhop, next); + list_for_each_safe(p, h, &(pff_i->nhops_down)) { + struct nhop * e = list_entry(p, struct nhop, next); list_del(&e->next); free(e); } @@ -126,11 +126,11 @@ static void del_nhops_down(struct pff_i * pff_i) static int del_nhop_down(struct pff_i * pff_i, int fd) { - struct list_head * pos = NULL; - struct list_head * n = NULL; + struct list_head * p; + struct list_head * h; - list_for_each_safe(pos, n, &(pff_i->nhops_down)) { - struct nhop * e = list_entry(pos, struct nhop, next); + list_for_each_safe(p, h, &(pff_i->nhops_down)) { + struct nhop * e = list_entry(p, struct nhop, next); if (e->fd == fd) { list_del(&e->next); free(e); @@ -171,31 +171,31 @@ static bool nhops_down_has(struct pff_i * pff_i, return false; } -static int add_to_htable(struct pff_i * pff_i, - uint64_t addr, - int * fd, - size_t len) +static int add_to_pft(struct pff_i * pff_i, + uint64_t addr, + int * fd, + size_t len) { - int * val; + int * fds; assert(pff_i); assert(len > 0); - val = malloc(sizeof(*val) * (len + 1)); - if (val == NULL) + fds = malloc(sizeof(*fds) * (len + 1)); + if (fds == NULL) goto fail_malloc; - memcpy(val, fd, len * sizeof(*val)); + memcpy(fds, fd, len * sizeof(*fds)); /* Put primary hop again at the end */ - val[len] = val[0]; + fds[len] = fds[0]; - if (htable_insert(pff_i->table, addr, val, len)) + if (pft_insert(pff_i->pft, addr, fds, len)) goto fail_insert; return 0; fail_insert: - free(val); + free(fds); fail_malloc: return -1; } @@ -211,16 +211,16 @@ struct pff_i * alternate_pff_create(void) if (pthread_rwlock_init(&tmp->lock, NULL)) goto fail_lock; - tmp->table = htable_create(PFT_SIZE, false); - if (tmp->table == NULL) - goto fail_table; + tmp->pft = pft_create(PFT_SIZE, false); + if (tmp->pft == NULL) + goto fail_pft; list_head_init(&tmp->nhops_down); list_head_init(&tmp->addrs); return tmp; - fail_table: + fail_pft: pthread_rwlock_destroy(&tmp->lock); fail_lock: free(tmp); @@ -232,7 +232,7 @@ void alternate_pff_destroy(struct pff_i * pff_i) { assert(pff_i); - htable_destroy(pff_i->table); + pft_destroy(pff_i->pft); del_nhops_down(pff_i); del_addrs(pff_i); pthread_rwlock_destroy(&pff_i->lock); @@ -257,11 +257,11 @@ int alternate_pff_add(struct pff_i * pff_i, assert(pff_i); assert(len > 0); - if (add_to_htable(pff_i, addr, fd, len)) + if (add_to_pft(pff_i, addr, fd, len)) return -1; if (add_addr(pff_i, addr)) { - htable_delete(pff_i->table, addr); + pft_delete(pff_i->pft, addr); return -1; } @@ -276,10 +276,10 @@ int alternate_pff_update(struct pff_i * pff_i, assert(pff_i); assert(len > 0); - if (htable_delete(pff_i->table, addr)) + if (pft_delete(pff_i->pft, addr)) return -1; - if (add_to_htable(pff_i, addr, fd, len)) + if (add_to_pft(pff_i, addr, fd, len)) return -1; return 0; @@ -292,7 +292,7 @@ int alternate_pff_del(struct pff_i * pff_i, del_addr(pff_i, addr); - if (htable_delete(pff_i->table, addr)) + if (pft_delete(pff_i->pft, addr)) return -1; return 0; @@ -302,7 +302,7 @@ void alternate_pff_flush(struct pff_i * pff_i) { assert(pff_i); - htable_flush(pff_i->table); + pft_flush(pff_i->pft); del_nhops_down(pff_i); @@ -312,20 +312,20 @@ void alternate_pff_flush(struct pff_i * pff_i) int alternate_pff_nhop(struct pff_i * pff_i, uint64_t addr) { - int fd = -1; + int fd; size_t len; - void * el; + int * fds; assert(pff_i); pthread_rwlock_rdlock(&pff_i->lock); - if (htable_lookup(pff_i->table, addr, &el, &len)) { + if (pft_lookup(pff_i->pft, addr, &fds, &len)) { pthread_rwlock_unlock(&pff_i->lock); return -1; } - fd = *((int *) el); + fd = *fds; pthread_rwlock_unlock(&pff_i->lock); @@ -338,7 +338,6 @@ int alternate_flow_state_change(struct pff_i * pff_i, { struct list_head * pos = NULL; size_t len; - void * el; int * fds; size_t i; int tmp; @@ -361,13 +360,11 @@ int alternate_flow_state_change(struct pff_i * pff_i, list_for_each(pos, &pff_i->addrs) { struct addr * e = list_entry(pos, struct addr, next); - if (htable_lookup(pff_i->table, e->addr, &el, &len)) { + if (pft_lookup(pff_i->pft, e->addr, &fds, &len)) { pthread_rwlock_unlock(&pff_i->lock); return -1; } - fds = (int *) el; - if (up) { /* It is using an alternate */ if (fds[len] == fd && fds[0] != fd) { diff --git a/src/ipcpd/unicast/pol/hashtable.c b/src/ipcpd/unicast/pol/hashtable.c deleted file mode 100644 index 596219f3..00000000 --- a/src/ipcpd/unicast/pol/hashtable.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2020 - * - * Hash table with integer keys with separate chaining on collisions - * - * 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/. - */ - -#if defined(__linux__) || defined(__CYGWIN__) -#define _DEFAULT_SOURCE -#endif - -#include -#include -#include - -#include "hashtable.h" - -#include -#include - -struct htable_entry { - struct list_head next; - uint64_t key; - void * val; - size_t len; -}; - -struct htable { - struct list_head * buckets; - bool hash_key; - uint64_t buckets_size; -}; - -struct htable * htable_create(uint64_t buckets, - bool hash_key) -{ - struct htable * tmp; - unsigned int i; - - if (buckets == 0) - return NULL; - - buckets--; - buckets |= buckets >> 1; - buckets |= buckets >> 2; - buckets |= buckets >> 4; - buckets |= buckets >> 8; - buckets |= buckets >> 16; - buckets |= buckets >> 32; - buckets++; - - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) - return NULL; - - tmp->hash_key = hash_key; - tmp->buckets_size = buckets; - - tmp->buckets = malloc(buckets * sizeof(*tmp->buckets)); - if (tmp->buckets == NULL) { - free(tmp); - return NULL; - } - - for (i = 0; i < buckets; i++) - list_head_init(&(tmp->buckets[i])); - - return tmp; -} - -void htable_destroy(struct htable * table) -{ - assert(table); - assert(table->buckets); - - htable_flush(table); - free(table->buckets); - free(table); -} - -void htable_flush(struct htable * table) -{ - unsigned int i; - struct list_head * pos = NULL; - struct list_head * n = NULL; - struct htable_entry * entry; - - assert(table); - - for (i = 0; i < table->buckets_size; i++) { - list_for_each_safe(pos, n, &(table->buckets[i])) { - entry = list_entry(pos, struct htable_entry, next); - list_del(&entry->next); - free(entry->val); - free(entry); - } - } -} - -static uint64_t hash(uint64_t key) -{ - void * res; - uint64_t ret; - uint8_t keys[4]; - - memcpy(keys, &key, 4); - - mem_hash(HASH_MD5, &res, keys, 4); - - ret = (* (uint64_t *) res); - - free(res); - - return ret; -} - -static uint64_t calc_key(struct htable * table, - uint64_t key) -{ - if (table->hash_key) - key = hash(key); - - return (key & (table->buckets_size - 1)); -} - -int htable_insert(struct htable * table, - uint64_t key, - void * val, - size_t len) -{ - struct htable_entry * entry; - uint64_t lookup_key; - struct list_head * pos = NULL; - - assert(table); - - lookup_key = calc_key(table, key); - - list_for_each(pos, &(table->buckets[lookup_key])) { - entry = list_entry(pos, struct htable_entry, next); - if (entry->key == key) - return -1; - } - - entry = malloc(sizeof(*entry)); - if (entry == NULL) - return -ENOMEM; - - entry->key = key; - entry->val = val; - entry->len = len; - list_head_init(&entry->next); - - list_add(&entry->next, &(table->buckets[lookup_key])); - - return 0; -} - -int htable_lookup(struct htable * table, - uint64_t key, - void ** val, - size_t * len) -{ - struct htable_entry * entry; - struct list_head * pos = NULL; - uint64_t lookup_key; - - assert(table); - - lookup_key = calc_key(table, key); - - list_for_each(pos, &(table->buckets[lookup_key])) { - entry = list_entry(pos, struct htable_entry, next); - if (entry->key == key) { - *val = entry->val; - *len = entry->len; - return 0; - } - } - - return -1; -} - -int htable_delete(struct htable * table, - uint64_t key) -{ - struct htable_entry * entry; - uint64_t lookup_key; - struct list_head * pos = NULL; - struct list_head * n = NULL; - - assert(table); - - lookup_key = calc_key(table, key); - - list_for_each_safe(pos, n, &(table->buckets[lookup_key])) { - entry = list_entry(pos, struct htable_entry, next); - if (entry->key == key) { - list_del(&entry->next); - free(entry->val); - free(entry); - return 0; - } - } - - return -1; -} diff --git a/src/ipcpd/unicast/pol/hashtable.h b/src/ipcpd/unicast/pol/hashtable.h deleted file mode 100644 index b6a36180..00000000 --- a/src/ipcpd/unicast/pol/hashtable.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2020 - * -* Hash table with integer keys with separate chaining on collisions - * - * 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_HASHTABLE_H -#define OUROBOROS_HASHTABLE_H - -#include -#include -#include - -struct htable; - -/* Buckets is rounded up to the nearest power of 2 */ -struct htable * htable_create(uint64_t buckets, - bool hash_key); - -void htable_destroy(struct htable * table); - -void htable_flush(struct htable * table); - -/* Passes ownership of the block of memory */ -int htable_insert(struct htable * table, - uint64_t key, - void * val, - size_t len); - -/* The block of memory returned is no copy */ -int htable_lookup(struct htable * table, - uint64_t key, - void ** val, - size_t * len); - -int htable_delete(struct htable * table, - uint64_t key); - -#endif /* OUROBOROS_HASHTABLE_H */ diff --git a/src/ipcpd/unicast/pol/pft.c b/src/ipcpd/unicast/pol/pft.c new file mode 100644 index 00000000..924efbe1 --- /dev/null +++ b/src/ipcpd/unicast/pol/pft.c @@ -0,0 +1,222 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2020 + * + * Packet forwarding table (PFT) with chaining on collisions + * + * 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/. + */ + +#if defined(__linux__) || defined(__CYGWIN__) +#define _DEFAULT_SOURCE +#endif + +#include +#include +#include + +#include "pft.h" + +#include +#include + +/* store output fds for dst addr */ +struct pft_entry { + struct list_head next; + uint64_t dst; + int * fds; + size_t len; +}; + +struct pft { + struct list_head * buckets; + bool hash_key; + uint64_t buckets_size; +}; + +struct pft * pft_create(uint64_t buckets, + bool hash_key) +{ + struct pft * tmp; + unsigned int i; + + if (buckets == 0) + return NULL; + + buckets--; + buckets |= buckets >> 1; + buckets |= buckets >> 2; + buckets |= buckets >> 4; + buckets |= buckets >> 8; + buckets |= buckets >> 16; + buckets |= buckets >> 32; + buckets++; + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return NULL; + + tmp->hash_key = hash_key; + tmp->buckets_size = buckets; + + tmp->buckets = malloc(buckets * sizeof(*tmp->buckets)); + if (tmp->buckets == NULL) { + free(tmp); + return NULL; + } + + for (i = 0; i < buckets; i++) + list_head_init(&(tmp->buckets[i])); + + return tmp; +} + +void pft_destroy(struct pft * pft) +{ + assert(pft); + assert(pft->buckets); + + pft_flush(pft); + free(pft->buckets); + free(pft); +} + +void pft_flush(struct pft * pft) +{ + unsigned int i; + struct list_head * p; + struct list_head * h; + struct pft_entry * entry; + + assert(pft); + + for (i = 0; i < pft->buckets_size; i++) { + list_for_each_safe(p, h, &(pft->buckets[i])) { + entry = list_entry(p, struct pft_entry, next); + list_del(&entry->next); + free(entry->fds); + free(entry); + } + } +} + +static uint64_t hash(uint64_t key) +{ + void * res; + uint64_t ret; + uint8_t keys[4]; + + memcpy(keys, &key, 4); + + mem_hash(HASH_MD5, &res, keys, 4); + + ret = (* (uint64_t *) res); + + free(res); + + return ret; +} + +static uint64_t calc_key(struct pft * pft, + uint64_t dst) +{ + if (pft->hash_key) + dst = hash(dst); + + return (dst & (pft->buckets_size - 1)); +} + +int pft_insert(struct pft * pft, + uint64_t dst, + int * fds, + size_t len) +{ + struct pft_entry * entry; + uint64_t lookup_key; + struct list_head * p; + + assert(pft); + + lookup_key = calc_key(pft, dst); + + list_for_each(p, &(pft->buckets[lookup_key])) { + entry = list_entry(p, struct pft_entry, next); + if (entry->dst == dst) + return -EPERM; + } + + entry = malloc(sizeof(*entry)); + if (entry == NULL) + return -ENOMEM; + + entry->dst = dst; + entry->fds = fds; + entry->len = len; + + list_add(&entry->next, &(pft->buckets[lookup_key])); + + return 0; +} + +int pft_lookup(struct pft * pft, + uint64_t dst, + int ** fds, + size_t * len) +{ + struct pft_entry * entry; + struct list_head * p; + uint64_t lookup_key; + + assert(pft); + + lookup_key = calc_key(pft, dst); + + list_for_each(p, &(pft->buckets[lookup_key])) { + entry = list_entry(p, struct pft_entry, next); + if (entry->dst == dst) { + *fds = entry->fds; + *len = entry->len; + return 0; + } + } + + return -1; +} + +int pft_delete(struct pft * pft, + uint64_t dst) +{ + struct pft_entry * entry; + uint64_t lookup_key; + struct list_head * p; + struct list_head * h; + + assert(pft); + + lookup_key = calc_key(pft, dst); + + list_for_each_safe(p, h, &(pft->buckets[lookup_key])) { + entry = list_entry(p, struct pft_entry, next); + if (entry->dst == dst) { + list_del(&entry->next); + free(entry->fds); + free(entry); + return 0; + } + } + + return -1; +} diff --git a/src/ipcpd/unicast/pol/pft.h b/src/ipcpd/unicast/pol/pft.h new file mode 100644 index 00000000..aed4dba8 --- /dev/null +++ b/src/ipcpd/unicast/pol/pft.h @@ -0,0 +1,55 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2020 + * + * Packet forwarding table (PFT) with chaining on collisions + * + * 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_PFT_H +#define OUROBOROS_PFT_H + +#include +#include +#include + +struct pft; + +/* Buckets is rounded up to the nearest power of 2 */ +struct pft * pft_create(uint64_t buckets, + bool hash_key); + +void pft_destroy(struct pft * table); + +void pft_flush(struct pft * table); + +/* Passes ownership of the block of memory */ +int pft_insert(struct pft * pft, + uint64_t dst, + int * fds, + size_t len); + +/* The block of memory returned is no copy */ +int pft_lookup(struct pft * pft, + uint64_t dst, + int ** fds, + size_t * len); + +int pft_delete(struct pft * pft, + uint64_t dst); + +#endif /* OUROBOROS_PFT_H */ diff --git a/src/ipcpd/unicast/pol/simple_pff.c b/src/ipcpd/unicast/pol/simple_pff.c index 3d294d90..c5780703 100644 --- a/src/ipcpd/unicast/pol/simple_pff.c +++ b/src/ipcpd/unicast/pol/simple_pff.c @@ -29,11 +29,11 @@ #include #include -#include "hashtable.h" +#include "pft.h" #include "simple_pff.h" struct pff_i { - struct htable * table; + struct pft * pft; pthread_rwlock_t lock; }; @@ -63,8 +63,8 @@ struct pff_i * simple_pff_create(void) return NULL; } - tmp->table = htable_create(PFT_SIZE, false); - if (tmp->table == NULL) { + tmp->pft = pft_create(PFT_SIZE, false); + if (tmp->pft == NULL) { pthread_rwlock_destroy(&tmp->lock); free(tmp); return NULL; @@ -77,7 +77,7 @@ void simple_pff_destroy(struct pff_i * pff_i) { assert(pff_i); - htable_destroy(pff_i->table); + pft_destroy(pff_i->pft); pthread_rwlock_destroy(&pff_i->lock); free(pff_i); @@ -98,21 +98,21 @@ int simple_pff_add(struct pff_i * pff_i, int * fd, size_t len) { - int * val; + int * fds; assert(pff_i); assert(len > 0); (void) len; - val = malloc(sizeof(*val)); - if (val == NULL) + fds = malloc(sizeof(*fds)); + if (fds == NULL) return -ENOMEM; - *val = fd[0]; + *fds = *fd; - if (htable_insert(pff_i->table, addr, val, 1)) { - free(val); + if (pft_insert(pff_i->pft, addr, fds, 1)) { + free(fds); return -1; } @@ -124,25 +124,26 @@ int simple_pff_update(struct pff_i * pff_i, int * fd, size_t len) { - int * val; + int * fds; assert(pff_i); assert(len > 0); (void) len; - val = malloc(sizeof(*val)); - if (val == NULL) + fds = malloc(sizeof(*fds)); + if (fds == NULL) return -ENOMEM; - *val = fd[0]; - if (htable_delete(pff_i->table, addr)) { - free(val); + *fds = *fd; + + if (pft_delete(pff_i->pft, addr)) { + free(fds); return -1; } - if (htable_insert(pff_i->table, addr, val, 1)) { - free(val); + if (pft_insert(pff_i->pft, addr, fds, 1)) { + free(fds); return -1; } @@ -154,7 +155,7 @@ int simple_pff_del(struct pff_i * pff_i, { assert(pff_i); - if (htable_delete(pff_i->table, addr)) + if (pft_delete(pff_i->pft, addr)) return -1; return 0; @@ -164,13 +165,13 @@ void simple_pff_flush(struct pff_i * pff_i) { assert(pff_i); - htable_flush(pff_i->table); + pft_flush(pff_i->pft); } int simple_pff_nhop(struct pff_i * pff_i, uint64_t addr) { - void * j; + int * fds; size_t len; int fd = -1; @@ -178,8 +179,8 @@ int simple_pff_nhop(struct pff_i * pff_i, pthread_rwlock_rdlock(&pff_i->lock); - if (!htable_lookup(pff_i->table, addr, &j, &len)) - fd = *((int *) j); + if (pft_lookup(pff_i->pft, addr, &fds, &len) == 0) + fd = *fds; pthread_rwlock_unlock(&pff_i->lock); diff --git a/src/ipcpd/unicast/pol/tests/CMakeLists.txt b/src/ipcpd/unicast/pol/tests/CMakeLists.txt index 86c2d948..34d80e8d 100644 --- a/src/ipcpd/unicast/pol/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/pol/tests/CMakeLists.txt @@ -18,7 +18,7 @@ get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here graph_test.c - hashtable_test.c + pft_test.c ) add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) diff --git a/src/ipcpd/unicast/pol/tests/hashtable_test.c b/src/ipcpd/unicast/pol/tests/hashtable_test.c deleted file mode 100644 index f84fee63..00000000 --- a/src/ipcpd/unicast/pol/tests/hashtable_test.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2020 - * - * Test of the hash table - * - * 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/. - */ - -#include "hashtable.c" - -#include - -#define HASHTABLE_SIZE 256 -#define INT_TEST 4 - -int hashtable_test(int argc, char ** argv) -{ - struct htable * table; - int i; - int * j; - void * el; - size_t len; - - (void) argc; - (void) argv; - - table = htable_create(HASHTABLE_SIZE, true); - if (table == NULL) { - printf("Failed to create.\n"); - return -1; - } - - htable_destroy(table); - - table = htable_create(HASHTABLE_SIZE, false); - if (table == NULL) { - printf("Failed to create.\n"); - return -1; - } - - for (i = 0; i < HASHTABLE_SIZE + INT_TEST + 2; i++) { - j = malloc(sizeof(*j)); - if (j == NULL) { - printf("Failed to malloc.\n"); - htable_destroy(table); - return -1; - } - *j = i; - - if (htable_insert(table, i, (void *) j, 1)) { - printf("Failed to insert.\n"); - htable_destroy(table); - free(j); - return -1; - } - } - - if (htable_lookup(table, INT_TEST, &el, &len)) { - printf("Failed to lookup.\n"); - htable_destroy(table); - return -1; - } - - j = (int *) el; - if (*j != INT_TEST) { - printf("Lookup returned wrong value (%d != %d).\n", - INT_TEST, *j); - htable_destroy(table); - return -1; - } - - if (htable_lookup(table, HASHTABLE_SIZE + INT_TEST, &el, &len)) { - printf("Failed to lookup.\n"); - htable_destroy(table); - return -1; - } - - j = (int *) el; - if (*j != HASHTABLE_SIZE + INT_TEST) { - printf("Lookup returned wrong value (%d != %d).\n", - INT_TEST, *j); - htable_destroy(table); - return -1; - } - - if (htable_delete(table, INT_TEST)) { - printf("Failed to delete.\n"); - htable_destroy(table); - return -1; - } - - if (htable_lookup(table, INT_TEST, &el, &len) == 0) { - printf("Failed to delete properly.\n"); - htable_destroy(table); - return -1; - } - - if (htable_lookup(table, HASHTABLE_SIZE + INT_TEST, &el, &len)) { - printf("Failed to lookup after deletion.\n"); - htable_destroy(table); - return -1; - } - - j = (int *) el; - if (*j != HASHTABLE_SIZE + INT_TEST) { - printf("Lookup returned wrong value (%d != %d).\n", - INT_TEST, *j); - htable_destroy(table); - return -1; - } - - htable_destroy(table); - - return 0; -} diff --git a/src/ipcpd/unicast/pol/tests/pft_test.c b/src/ipcpd/unicast/pol/tests/pft_test.c new file mode 100644 index 00000000..4e23898b --- /dev/null +++ b/src/ipcpd/unicast/pol/tests/pft_test.c @@ -0,0 +1,126 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2020 + * + * Test of the hash table + * + * 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/. + */ + +#include "pft.c" + +#include + +#define TBL_SIZE 256 +#define INT_TEST 4 + +int pft_test(int argc, + char ** argv) +{ + struct pft * pft; + int i; + int * j; + size_t len; + + (void) argc; + (void) argv; + + pft = pft_create(TBL_SIZE, true); + if (pft == NULL) { + printf("Failed to create.\n"); + return -1; + } + + pft_destroy(pft); + + pft = pft_create(TBL_SIZE, false); + if (pft == NULL) { + printf("Failed to create.\n"); + return -1; + } + + for (i = 0; i < TBL_SIZE + INT_TEST + 2; i++) { + j = malloc(sizeof(*j)); + if (j == NULL) { + printf("Failed to malloc.\n"); + pft_destroy(pft); + return -1; + } + *j = i; + + if (pft_insert(pft, i, j, 1)) { + printf("Failed to insert.\n"); + pft_destroy(pft); + free(j); + return -1; + } + } + + if (pft_lookup(pft, INT_TEST, &j, &len)) { + printf("Failed to lookup.\n"); + pft_destroy(pft); + return -1; + } + + if (*j != INT_TEST) { + printf("Lookup returned wrong value (%d != %d).\n", + INT_TEST, *j); + pft_destroy(pft); + return -1; + } + + if (pft_lookup(pft, TBL_SIZE + INT_TEST, &j, &len)) { + printf("Failed to lookup.\n"); + pft_destroy(pft); + return -1; + } + + if (*j != TBL_SIZE + INT_TEST) { + printf("Lookup returned wrong value (%d != %d).\n", + INT_TEST, *j); + pft_destroy(pft); + return -1; + } + + if (pft_delete(pft, INT_TEST)) { + printf("Failed to delete.\n"); + pft_destroy(pft); + return -1; + } + + if (pft_lookup(pft, INT_TEST, &j, &len) == 0) { + printf("Failed to delete properly.\n"); + pft_destroy(pft); + return -1; + } + + if (pft_lookup(pft, TBL_SIZE + INT_TEST, &j, &len)) { + printf("Failed to lookup after deletion.\n"); + pft_destroy(pft); + return -1; + } + + if (*j != TBL_SIZE + INT_TEST) { + printf("Lookup returned wrong value (%d != %d).\n", + INT_TEST, *j); + pft_destroy(pft); + return -1; + } + + pft_destroy(pft); + + return 0; +} -- cgit v1.2.3