diff options
Diffstat (limited to 'hicn-light/src/hicn/core/nexthops.c')
-rw-r--r-- | hicn-light/src/hicn/core/nexthops.c | 155 |
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 */ |