aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/core/nexthops.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/core/nexthops.c')
-rw-r--r--hicn-light/src/hicn/core/nexthops.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/hicn-light/src/hicn/core/nexthops.c b/hicn-light/src/hicn/core/nexthops.c
new file mode 100644
index 000000000..1a6096777
--- /dev/null
+++ b/hicn-light/src/hicn/core/nexthops.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2021-2022 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file nexthops.c
+ * \brief Nexthops implementation
+ */
+
+#include <hicn/util/hash.h>
+
+#include "nexthops.h"
+
+int nexthops_disable(nexthops_t *nexthops, off_t offset) {
+ if (offset >= nexthops->num_elts) return -1;
+ nexthops->flags |= (1 << offset);
+ nexthops->cur_elts--;
+ return 0;
+}
+
+int nexthops_disable_all(nexthops_t *nexthops) {
+ nexthops->flags = ~0;
+ nexthops->cur_elts = 0;
+ return 0;
+}
+
+void nexthops_reset(nexthops_t *nexthops) {
+ nexthops->flags = 0;
+ nexthops->cur_elts = nexthops->num_elts;
+}
+
+off_t nexthops_add(nexthops_t *nexthops, nexthop_t nexthop) {
+ off_t id;
+ nexthops_enumerate(nexthops, i, n, {
+ if (n == nexthop) return i;
+ });
+ id = nexthops->num_elts++;
+ nexthops->elts[id] = nexthop;
+ nexthops_reset(nexthops);
+ return id;
+}
+
+off_t nexthops_remove(nexthops_t *nexthops, nexthop_t nexthop) {
+ nexthops_enumerate(nexthops, i, n, {
+ if (n == nexthop) {
+ nexthops->num_elts--;
+ nexthops->elts[i] = nexthops->elts[nexthops->num_elts];
+ nexthops->state[i] = nexthops->state[nexthops->num_elts];
+ nexthops_reset(nexthops);
+ return i;
+ }
+ });
+ return INVALID_NEXTHOP;
+}
+
+bool nexthops_contains(nexthops_t *nexthops, unsigned nexthop) {
+ nexthops_foreach(nexthops, n, {
+ if (n == nexthop) return true;
+ });
+ return false;
+}
+
+off_t nexthops_find(nexthops_t *nexthops, unsigned nexthop) {
+ nexthops_enumerate(nexthops, i, n, {
+ if (n == nexthop) return i;
+ });
+ return INVALID_NEXTHOP;
+}
+
+unsigned nexthops_get_one(nexthops_t *nexthops) {
+ nexthops_foreach(nexthops, n, { return n; });
+ return INVALID_NEXTHOP;
+}
+
+int nexthops_select(nexthops_t *nexthops, off_t i) {
+ if (i >= nexthops->num_elts) return -1;
+ nexthops->flags = ~0; /* all 1, could be limited to num_elts */
+ nexthops->flags &= ~(1 << (i));
+ nexthops->cur_elts = 1;
+ return 0;
+}
+
+#ifdef WITH_POLICY
+
+void nexthops_set_priority(nexthops_t *nexthops, nexthop_t nexthop,
+ int priority) {
+ nexthops_enumerate(nexthops, i, nh, {
+ if (nexthop == nh) nexthops_set_priority_by_id(nexthops, i, priority);
+ });
+}
+
+void nexthops_set_priority_by_id(nexthops_t *nexthops, off_t i, int priority) {
+ nexthops->state[i].priority = priority;
+}
+
+void nexthops_reset_priority(nexthops_t *nexthops, nexthop_t nexthop) {
+ nexthops_set_priority(nexthops, nexthop, DEFAULT_PRIORITY);
+}
+
+void nexthops_reset_priority_by_id(nexthops_t *nexthops, off_t i) {
+ nexthops_set_priority_by_id(nexthops, i, DEFAULT_PRIORITY);
+}
+
+void nexthops_reset_priorities(nexthops_t *nexthops) {
+ nexthops_enumerate(nexthops, i, nh, {
+ (void)nh;
+ nexthops_reset_priority(nexthops, i);
+ });
+}
+
+bool nexthops_equal(nexthops_t *a, nexthops_t *b) {
+ if (nexthops_get_len(a) != nexthops_get_len(b)) return false;
+ nexthops_foreach(a, n, {
+ if (!nexthops_contains(b, n)) return false;
+ });
+ return true;
+}
+
+void nexthops_copy(nexthops_t *src, nexthops_t *dst) {
+ for (unsigned i = 0; i < MAX_NEXTHOPS; i++) {
+ dst->elts[i] = src->elts[i];
+ dst->state[i] = src->state[i];
+ }
+ dst->num_elts = src->num_elts;
+ dst->flags = src->flags;
+ dst->cur_elts = src->cur_elts;
+}
+
+/* Adapted from Jenkins hash (commutative) */
+uint32_t nexthops_get_hash(nexthops_t *nexthops) {
+ uint32_t hash = 0;
+
+ nexthops_foreach(nexthops, nh, {
+ hash += nh;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ });
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ return hash;
+}
+
+#endif /* WITH_POLICY */