summaryrefslogtreecommitdiffstats
path: root/lib/agg_table.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/agg_table.h')
-rw-r--r--lib/agg_table.h164
1 files changed, 164 insertions, 0 deletions
diff --git a/lib/agg_table.h b/lib/agg_table.h
new file mode 100644
index 0000000..af1e6b6
--- /dev/null
+++ b/lib/agg_table.h
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * agg_table - Aggregate Table Header
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ */
+#ifndef __AGG_TABLE_H__
+#define __AGG_TABLE_H__
+
+#include "prefix.h"
+#include "table.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct agg_table {
+ struct route_table *route_table;
+
+ void *info;
+};
+
+struct agg_node {
+ /*
+ * Caution these must be the very first fields
+ * @see agg_node_to_rnode
+ * @see agg_node_from_rnode
+ */
+ ROUTE_NODE_FIELDS
+
+ /* Aggregation. */
+ void *aggregate;
+};
+
+static inline struct route_node *agg_node_to_rnode(struct agg_node *node)
+{
+ return (struct route_node *)node;
+}
+
+static inline struct agg_node *agg_node_from_rnode(struct route_node *node)
+{
+ return (struct agg_node *)node;
+}
+
+static inline struct agg_node *agg_lock_node(struct agg_node *node)
+{
+ return (struct agg_node *)route_lock_node(agg_node_to_rnode(node));
+}
+
+static inline void agg_unlock_node(struct agg_node *node)
+{
+ route_unlock_node(agg_node_to_rnode(node));
+}
+
+static inline void agg_set_table_info(struct agg_table *atable, void *data)
+{
+ atable->info = data;
+}
+
+static inline void *agg_get_table_info(struct agg_table *atable)
+{
+ return atable->info;
+}
+
+static inline struct agg_node *agg_route_top(struct agg_table *table)
+{
+ return agg_node_from_rnode(route_top(table->route_table));
+}
+
+static inline struct agg_node *agg_route_next(struct agg_node *node)
+{
+ return agg_node_from_rnode(route_next(agg_node_to_rnode(node)));
+}
+
+static inline struct agg_node *agg_node_get(struct agg_table *table,
+ const struct prefix *p)
+{
+ return agg_node_from_rnode(route_node_get(table->route_table, p));
+}
+
+static inline struct agg_node *
+agg_node_lookup(const struct agg_table *const table, const struct prefix *p)
+{
+ return agg_node_from_rnode(route_node_lookup(table->route_table, p));
+}
+
+static inline struct agg_node *agg_route_next_until(struct agg_node *node,
+ struct agg_node *limit)
+{
+ struct route_node *rnode;
+
+ rnode = route_next_until(agg_node_to_rnode(node),
+ agg_node_to_rnode(limit));
+
+ return agg_node_from_rnode(rnode);
+}
+
+static inline struct agg_node *agg_node_match(struct agg_table *table,
+ const struct prefix *p)
+{
+ return agg_node_from_rnode(route_node_match(table->route_table, p));
+}
+
+static inline struct agg_node *agg_node_parent(struct agg_node *node)
+{
+ struct route_node *rn = agg_node_to_rnode(node);
+
+ return agg_node_from_rnode(rn->parent);
+}
+
+static inline struct agg_node *agg_node_left(struct agg_node *node)
+{
+ struct route_node *rn = agg_node_to_rnode(node);
+
+ return agg_node_from_rnode(rn->l_left);
+}
+
+static inline struct agg_node *agg_node_right(struct agg_node *node)
+{
+ struct route_node *rn = agg_node_to_rnode(node);
+
+ return agg_node_from_rnode(rn->l_right);
+}
+
+extern struct agg_table *agg_table_init(void);
+
+static inline void agg_table_finish(struct agg_table *atable)
+{
+ route_table_finish(atable->route_table);
+ atable->route_table = NULL;
+
+ XFREE(MTYPE_TMP, atable);
+}
+
+static inline struct agg_node *agg_route_table_top(struct agg_node *node)
+{
+ return (struct agg_node *)route_top(node->table);
+}
+
+static inline struct agg_table *agg_get_table(struct agg_node *node)
+{
+ return (struct agg_table *)route_table_get_info(node->table);
+}
+
+static inline const struct prefix *
+agg_node_get_prefix(const struct agg_node *node)
+{
+ return &node->p;
+}
+
+static inline unsigned int agg_node_get_lock_count(const struct agg_node *node)
+{
+ return node->lock;
+}
+
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+#pragma FRR printfrr_ext "%pRN" (struct agg_node *)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif