summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_table.h
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_table.h')
-rw-r--r--bgpd/bgp_table.h417
1 files changed, 417 insertions, 0 deletions
diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h
new file mode 100644
index 0000000..5b4c3be
--- /dev/null
+++ b/bgpd/bgp_table.h
@@ -0,0 +1,417 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* BGP routing table
+ * Copyright (C) 1998, 2001 Kunihiro Ishiguro
+ */
+
+#ifndef _QUAGGA_BGP_TABLE_H
+#define _QUAGGA_BGP_TABLE_H
+
+#include "mpls.h"
+#include "table.h"
+#include "queue.h"
+#include "linklist.h"
+#include "bgpd.h"
+#include "bgp_advertise.h"
+
+struct bgp_table {
+ /* table belongs to this instance */
+ struct bgp *bgp;
+
+ /* afi/safi of this table */
+ afi_t afi;
+ safi_t safi;
+
+ int lock;
+
+ /* soft_reconfig_table in progress */
+ bool soft_reconfig_init;
+ struct event *soft_reconfig_thread;
+
+ /* list of peers on which soft_reconfig_table has to run */
+ struct list *soft_reconfig_peers;
+
+ struct route_table *route_table;
+ uint64_t version;
+};
+
+enum bgp_path_selection_reason {
+ bgp_path_selection_none,
+ bgp_path_selection_first,
+ bgp_path_selection_evpn_sticky_mac,
+ bgp_path_selection_evpn_seq,
+ bgp_path_selection_evpn_local_path,
+ bgp_path_selection_evpn_non_proxy,
+ bgp_path_selection_evpn_lower_ip,
+ bgp_path_selection_weight,
+ bgp_path_selection_local_pref,
+ bgp_path_selection_accept_own,
+ bgp_path_selection_local_route,
+ bgp_path_selection_aigp,
+ bgp_path_selection_confed_as_path,
+ bgp_path_selection_as_path,
+ bgp_path_selection_origin,
+ bgp_path_selection_med,
+ bgp_path_selection_peer,
+ bgp_path_selection_confed,
+ bgp_path_selection_igp_metric,
+ bgp_path_selection_older,
+ bgp_path_selection_router_id,
+ bgp_path_selection_cluster_length,
+ bgp_path_selection_stale,
+ bgp_path_selection_local_configured,
+ bgp_path_selection_neighbor_ip,
+ bgp_path_selection_default,
+};
+
+struct bgp_dest {
+ struct route_node *rn;
+
+ void *info;
+
+ struct bgp_adj_out_rb adj_out;
+
+ struct bgp_adj_in *adj_in;
+
+ struct bgp_dest *pdest;
+
+ STAILQ_ENTRY(bgp_dest) pq;
+
+ uint64_t version;
+
+ mpls_label_t local_label;
+
+ uint16_t flags;
+#define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
+#define BGP_NODE_USER_CLEAR (1 << 1)
+#define BGP_NODE_LABEL_CHANGED (1 << 2)
+#define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3)
+#define BGP_NODE_SELECT_DEFER (1 << 4)
+#define BGP_NODE_FIB_INSTALL_PENDING (1 << 5)
+#define BGP_NODE_FIB_INSTALLED (1 << 6)
+#define BGP_NODE_LABEL_REQUESTED (1 << 7)
+#define BGP_NODE_SOFT_RECONFIG (1 << 8)
+#define BGP_NODE_PROCESS_CLEAR (1 << 9)
+
+ struct bgp_addpath_node_data tx_addpath;
+
+ enum bgp_path_selection_reason reason;
+};
+
+extern void bgp_delete_listnode(struct bgp_dest *dest);
+/*
+ * bgp_table_iter_t
+ *
+ * Structure that holds state for iterating over a bgp table.
+ */
+typedef struct bgp_table_iter_t_ {
+ struct bgp_table *table;
+ route_table_iter_t rt_iter;
+} bgp_table_iter_t;
+
+extern struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t, safi_t);
+extern void bgp_table_lock(struct bgp_table *);
+extern void bgp_table_unlock(struct bgp_table *);
+extern void bgp_table_finish(struct bgp_table **);
+extern struct bgp_dest *bgp_dest_unlock_node(struct bgp_dest *dest);
+extern struct bgp_dest *bgp_dest_lock_node(struct bgp_dest *dest);
+extern const char *bgp_dest_get_prefix_str(struct bgp_dest *dest);
+
+
+/*
+ * bgp_dest_from_rnode
+ *
+ * Returns the bgp_dest structure corresponding to a route_node.
+ */
+static inline struct bgp_dest *bgp_dest_from_rnode(struct route_node *rnode)
+{
+ return (rnode && rnode->info) ? (struct bgp_dest *)rnode->info : NULL;
+}
+
+/*
+ * bgp_dest_to_rnode
+ *
+ * Returns the route_node structure corresponding to a bgp_dest.
+ */
+static inline struct route_node *bgp_dest_to_rnode(const struct bgp_dest *dest)
+{
+ return dest ? dest->rn : NULL;
+}
+
+/*
+ * bgp_dest_table
+ *
+ * Returns the bgp_table that the given dest is in.
+ */
+static inline struct bgp_table *bgp_dest_table(struct bgp_dest *dest)
+{
+ return route_table_get_info(bgp_dest_to_rnode(dest)->table);
+}
+
+/*
+ * bgp_dest_parent_nolock
+ *
+ * Gets the parent dest of the given node without locking it.
+ */
+static inline struct bgp_dest *bgp_dest_parent_nolock(struct bgp_dest *dest)
+{
+ struct route_node *rn = bgp_dest_to_rnode(dest)->parent;
+
+ while (rn && !rn->info)
+ rn = rn->parent;
+
+ return bgp_dest_from_rnode(rn);
+}
+
+/*
+ * bgp_table_top_nolock
+ *
+ * Gets the top dest in the table without locking it.
+ *
+ * @see bgp_table_top
+ */
+static inline struct bgp_dest *
+bgp_table_top_nolock(const struct bgp_table *const table)
+{
+ struct route_node *top;
+ struct route_node *rn = top = table->route_table->top;
+
+ while (rn && !rn->info) {
+ if (rn == top)
+ route_lock_node(rn);
+ rn = route_next(rn);
+ }
+ if (rn && rn != top)
+ route_unlock_node(rn);
+ return rn ? rn->info : NULL;
+}
+
+/*
+ * bgp_table_top
+ */
+static inline struct bgp_dest *
+bgp_table_top(const struct bgp_table *const table)
+{
+ struct route_node *rn = route_top(table->route_table);
+
+ while (rn && !rn->info)
+ rn = route_next(rn);
+ return rn ? rn->info : NULL;
+}
+
+/*
+ * bgp_route_next
+ */
+static inline struct bgp_dest *bgp_route_next(struct bgp_dest *dest)
+{
+ struct route_node *rn = route_next(bgp_dest_to_rnode(dest));
+
+ while (rn && !rn->info)
+ rn = route_next(rn);
+ return bgp_dest_from_rnode(rn);
+}
+
+/*
+ * bgp_route_next_until
+ */
+static inline struct bgp_dest *bgp_route_next_until(struct bgp_dest *dest,
+ struct bgp_dest *limit)
+{
+ struct route_node *rnode;
+
+ rnode = route_next_until(bgp_dest_to_rnode(dest),
+ bgp_dest_to_rnode(limit));
+
+ while (rnode && !rnode->info)
+ rnode = route_next_until(rnode, bgp_dest_to_rnode(limit));
+
+ return bgp_dest_from_rnode(rnode);
+}
+
+/*
+ * bgp_node_get
+ */
+static inline struct bgp_dest *bgp_node_get(struct bgp_table *const table,
+ const struct prefix *p)
+{
+ struct route_node *rn = route_node_get(table->route_table, p);
+
+ if (!rn->info) {
+ struct bgp_dest *dest = XCALLOC(MTYPE_BGP_NODE,
+ sizeof(struct bgp_dest));
+
+ RB_INIT(bgp_adj_out_rb, &dest->adj_out);
+ rn->info = dest;
+ dest->rn = rn;
+ }
+ return rn->info;
+}
+
+/*
+ * bgp_node_lookup
+ */
+static inline struct bgp_dest *
+bgp_node_lookup(const struct bgp_table *const table, const struct prefix *p)
+{
+ struct route_node *rn = route_node_lookup(table->route_table, p);
+
+ return bgp_dest_from_rnode(rn);
+}
+
+/*
+ * bgp_node_match
+ */
+static inline struct bgp_dest *bgp_node_match(const struct bgp_table *table,
+ const struct prefix *p)
+{
+ struct route_node *rn = route_node_match(table->route_table, p);
+
+ return bgp_dest_from_rnode(rn);
+}
+
+static inline unsigned long bgp_table_count(const struct bgp_table *const table)
+{
+ return route_table_count(table->route_table);
+}
+
+/*
+ * bgp_table_get_next
+ */
+static inline struct bgp_dest *bgp_table_get_next(const struct bgp_table *table,
+ const struct prefix *p)
+{
+ struct route_node *rn = route_table_get_next(table->route_table, p);
+
+ while (rn && !rn->info)
+ rn = route_next(rn);
+ return bgp_dest_from_rnode(rn);
+}
+
+/* This would benefit from a real atomic operation...
+ * until then. */
+static inline uint64_t bgp_table_next_version(struct bgp_table *table)
+{
+ return ++table->version;
+}
+
+static inline uint64_t bgp_table_version(struct bgp_table *table)
+{
+ return table->version;
+}
+
+/* Find the subtree of the prefix p
+ *
+ * This will return the first node that belongs the the subtree of p. Including
+ * p itself, if it is in the tree.
+ *
+ * If the subtree is not present in the table, NULL is returned.
+ */
+struct bgp_dest *bgp_table_subtree_lookup(const struct bgp_table *table,
+ const struct prefix *p);
+
+static inline struct bgp_aggregate *
+bgp_dest_get_bgp_aggregate_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void
+bgp_dest_set_bgp_aggregate_info(struct bgp_dest *dest,
+ struct bgp_aggregate *aggregate)
+{
+ dest->info = aggregate;
+}
+
+static inline struct bgp_distance *
+bgp_dest_get_bgp_distance_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void bgp_dest_set_bgp_distance_info(struct bgp_dest *dest,
+ struct bgp_distance *distance)
+{
+ dest->info = distance;
+}
+
+static inline struct bgp_static *
+bgp_dest_get_bgp_static_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void bgp_dest_set_bgp_static_info(struct bgp_dest *dest,
+ struct bgp_static *bgp_static)
+{
+ dest->info = bgp_static;
+}
+
+static inline struct bgp_connected_ref *
+bgp_dest_get_bgp_connected_ref_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void
+bgp_dest_set_bgp_connected_ref_info(struct bgp_dest *dest,
+ struct bgp_connected_ref *bc)
+{
+ dest->info = bc;
+}
+
+static inline struct bgp_nexthop_cache *
+bgp_dest_get_bgp_nexthop_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void bgp_dest_set_bgp_nexthop_info(struct bgp_dest *dest,
+ struct bgp_nexthop_cache *bnc)
+{
+ dest->info = bnc;
+}
+
+static inline struct bgp_path_info *
+bgp_dest_get_bgp_path_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void bgp_dest_set_bgp_path_info(struct bgp_dest *dest,
+ struct bgp_path_info *bi)
+{
+ dest->info = bi;
+}
+
+static inline struct bgp_table *
+bgp_dest_get_bgp_table_info(struct bgp_dest *dest)
+{
+ return dest ? dest->info : NULL;
+}
+
+static inline void bgp_dest_set_bgp_table_info(struct bgp_dest *dest,
+ struct bgp_table *table)
+{
+ dest->info = table;
+}
+
+static inline bool bgp_dest_has_bgp_path_info_data(struct bgp_dest *dest)
+{
+ return dest ? !!dest->info : false;
+}
+
+static inline const struct prefix *bgp_dest_get_prefix(const struct bgp_dest *dest)
+{
+ return dest ? &dest->rn->p : NULL;
+}
+
+static inline unsigned int bgp_dest_get_lock_count(const struct bgp_dest *dest)
+{
+ return dest ? dest->rn->lock : 0;
+}
+
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+#pragma FRR printfrr_ext "%pRN" (struct bgp_node *)
+#pragma FRR printfrr_ext "%pBD" (struct bgp_dest *)
+#endif
+
+#endif /* _QUAGGA_BGP_TABLE_H */