summaryrefslogtreecommitdiff
path: root/src/ipcpd/unicast/pff/simple.c
diff options
context:
space:
mode:
authorDimitri Staessens <[email protected]>2021-12-04 15:35:36 +0100
committerSander Vrijders <[email protected]>2021-12-06 17:52:08 +0100
commit11d2ecc140486949c8d81e984137263ca48d5799 (patch)
tree3b9a61015cb86e75fa7284fb1f3e66d7b326025e /src/ipcpd/unicast/pff/simple.c
parentb8ffe155228dd05f8097422349e8e6525288bbdb (diff)
downloadouroboros-11d2ecc140486949c8d81e984137263ca48d5799.tar.gz
ouroboros-11d2ecc140486949c8d81e984137263ca48d5799.zip
ipcpd: Restructure policy code
The policies were all in a single folder pol/, and have been moved to a folder per component/mechanism to keep things a bit more orderly. Signed-off-by: Dimitri Staessens <[email protected]> Signed-off-by: Sander Vrijders <[email protected]>
Diffstat (limited to 'src/ipcpd/unicast/pff/simple.c')
-rw-r--r--src/ipcpd/unicast/pff/simple.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/ipcpd/unicast/pff/simple.c b/src/ipcpd/unicast/pff/simple.c
new file mode 100644
index 00000000..a007bcec
--- /dev/null
+++ b/src/ipcpd/unicast/pff/simple.c
@@ -0,0 +1,190 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2021
+ *
+ * Simple PDU Forwarding Function
+ *
+ * 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., http://www.fsf.org/about/contact/.
+ */
+
+#define _POSIX_C_SOURCE 200112L
+
+#include "config.h"
+
+#include <ouroboros/errno.h>
+
+#include "pft.h"
+#include "simple.h"
+
+#include <assert.h>
+#include <pthread.h>
+
+struct pff_i {
+ struct pft * pft;
+ pthread_rwlock_t lock;
+};
+
+struct 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->pft = pft_create(PFT_SIZE, false);
+ if (tmp->pft == NULL) {
+ pthread_rwlock_destroy(&tmp->lock);
+ free(tmp);
+ return NULL;
+ }
+
+ return tmp;
+}
+
+void simple_pff_destroy(struct pff_i * pff_i)
+{
+ assert(pff_i);
+
+ pft_destroy(pff_i->pft);
+
+ 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 * fds;
+
+ assert(pff_i);
+ assert(fd);
+ assert(len > 0);
+
+ (void) len;
+
+ fds = malloc(sizeof(*fds));
+ if (fds == NULL)
+ return -ENOMEM;
+
+ *fds = *fd;
+
+ if (pft_insert(pff_i->pft, addr, fds, 1)) {
+ free(fds);
+ return -1;
+ }
+
+ return 0;
+}
+
+int simple_pff_update(struct pff_i * pff_i,
+ uint64_t addr,
+ int * fd,
+ size_t len)
+{
+ int * fds;
+
+ assert(pff_i);
+ assert(fd);
+ assert(len > 0);
+
+ (void) len;
+
+ fds = malloc(sizeof(*fds));
+ if (fds == NULL)
+ return -ENOMEM;
+
+ *fds = *fd;
+
+ if (pft_delete(pff_i->pft, addr)) {
+ free(fds);
+ return -1;
+ }
+
+ if (pft_insert(pff_i->pft, addr, fds, 1)) {
+ free(fds);
+ return -1;
+ }
+
+ return 0;
+}
+
+int simple_pff_del(struct pff_i * pff_i,
+ uint64_t addr)
+{
+ assert(pff_i);
+
+ if (pft_delete(pff_i->pft, addr))
+ return -1;
+
+ return 0;
+}
+
+void simple_pff_flush(struct pff_i * pff_i)
+{
+ assert(pff_i);
+
+ pft_flush(pff_i->pft);
+}
+
+int simple_pff_nhop(struct pff_i * pff_i,
+ uint64_t addr)
+{
+ int * fds;
+ size_t len;
+ int fd = -1;
+
+ assert(pff_i);
+
+ pthread_rwlock_rdlock(&pff_i->lock);
+
+ if (pft_lookup(pff_i->pft, addr, &fds, &len) == 0)
+ fd = *fds;
+
+ pthread_rwlock_unlock(&pff_i->lock);
+
+ return fd;
+}