summaryrefslogtreecommitdiffstats
path: root/isisd/isis_lfa.h
diff options
context:
space:
mode:
Diffstat (limited to 'isisd/isis_lfa.h')
-rw-r--r--isisd/isis_lfa.h172
1 files changed, 172 insertions, 0 deletions
diff --git a/isisd/isis_lfa.h b/isisd/isis_lfa.h
new file mode 100644
index 0000000..0ba1c1c
--- /dev/null
+++ b/isisd/isis_lfa.h
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 NetDEF, Inc.
+ * Renato Westphal
+ */
+
+#ifndef _FRR_ISIS_LFA_H
+#define _FRR_ISIS_LFA_H
+
+#include "lib/typesafe.h"
+#include "lib/zclient.h"
+#include "lib/memory.h"
+
+DECLARE_MTYPE(ISIS_NEXTHOP_LABELS);
+
+PREDECL_RBTREE_UNIQ(lfa_tiebreaker_tree);
+PREDECL_RBTREE_UNIQ(rlfa_tree);
+
+enum lfa_tiebreaker_type {
+ LFA_TIEBREAKER_DOWNSTREAM = 0,
+ LFA_TIEBREAKER_LOWEST_METRIC,
+ LFA_TIEBREAKER_NODE_PROTECTING,
+};
+
+struct lfa_tiebreaker {
+ struct lfa_tiebreaker_tree_item entry;
+ uint8_t index;
+ enum lfa_tiebreaker_type type;
+ struct isis_area *area;
+};
+int lfa_tiebreaker_cmp(const struct lfa_tiebreaker *a,
+ const struct lfa_tiebreaker *b);
+DECLARE_RBTREE_UNIQ(lfa_tiebreaker_tree, struct lfa_tiebreaker, entry,
+ lfa_tiebreaker_cmp);
+
+struct rlfa {
+ struct rlfa_tree_item entry;
+ struct prefix prefix;
+ struct isis_vertex *vertex;
+ struct in_addr pq_address;
+};
+int rlfa_cmp(const struct rlfa *a, const struct rlfa *b);
+DECLARE_RBTREE_UNIQ(rlfa_tree, struct rlfa, entry, rlfa_cmp);
+
+enum isis_tilfa_sid_type {
+ TILFA_SID_PREFIX = 1,
+ TILFA_SID_ADJ,
+};
+
+struct isis_tilfa_sid {
+ enum isis_tilfa_sid_type type;
+ union {
+ struct {
+ uint32_t value;
+ bool remote;
+ uint8_t remote_sysid[ISIS_SYS_ID_LEN];
+ } index;
+ mpls_label_t label;
+ } value;
+};
+
+enum spf_prefix_priority {
+ SPF_PREFIX_PRIO_CRITICAL = 0,
+ SPF_PREFIX_PRIO_HIGH,
+ SPF_PREFIX_PRIO_MEDIUM,
+ SPF_PREFIX_PRIO_LOW,
+ SPF_PREFIX_PRIO_MAX,
+};
+
+struct spf_prefix_priority_acl {
+ char *name;
+ struct access_list *list_v4;
+ struct access_list *list_v6;
+};
+
+RB_HEAD(isis_spf_nodes, isis_spf_node);
+RB_PROTOTYPE(isis_spf_nodes, isis_spf_node, entry, isis_spf_node_compare)
+struct isis_spf_node {
+ RB_ENTRY(isis_spf_node) entry;
+
+ /* Node's System ID. */
+ uint8_t sysid[ISIS_SYS_ID_LEN];
+
+ /* Local adjacencies over which this node is reachable. */
+ struct list *adjacencies;
+
+ /* Best metric of all adjacencies used to reach this node. */
+ uint32_t best_metric;
+
+ struct {
+ /* Node's forward SPT. */
+ struct isis_spftree *spftree;
+
+ /* Node's reverse SPT. */
+ struct isis_spftree *spftree_reverse;
+
+ /* Node's P-space. */
+ struct isis_spf_nodes p_space;
+ } lfa;
+};
+
+enum lfa_protection_type {
+ LFA_LINK_PROTECTION = 1,
+ LFA_NODE_PROTECTION,
+};
+
+struct lfa_protected_resource {
+ /* The protection type. */
+ enum lfa_protection_type type;
+
+ /* The protected adjacency (might be a pseudonode). */
+ uint8_t adjacency[ISIS_SYS_ID_LEN + 1];
+
+ /* List of nodes reachable over the protected interface. */
+ struct isis_spf_nodes nodes;
+};
+
+/* Forward declaration(s). */
+struct isis_vertex;
+
+/* Prototypes. */
+void isis_spf_node_list_init(struct isis_spf_nodes *nodes);
+void isis_spf_node_list_clear(struct isis_spf_nodes *nodes);
+struct isis_spf_node *isis_spf_node_new(struct isis_spf_nodes *nodes,
+ const uint8_t *sysid);
+struct isis_spf_node *isis_spf_node_find(const struct isis_spf_nodes *nodes,
+ const uint8_t *sysid);
+void isis_lfa_tiebreakers_init(struct isis_area *area, int level);
+void isis_lfa_tiebreakers_clear(struct isis_area *area, int level);
+struct lfa_tiebreaker *isis_lfa_tiebreaker_add(struct isis_area *area,
+ int level, uint8_t index,
+ enum lfa_tiebreaker_type type);
+void isis_lfa_tiebreaker_delete(struct isis_area *area, int level,
+ struct lfa_tiebreaker *tie_b);
+void isis_lfa_excluded_ifaces_init(struct isis_circuit *circuit, int level);
+void isis_lfa_excluded_ifaces_clear(struct isis_circuit *circuit, int level);
+void isis_lfa_excluded_iface_add(struct isis_circuit *circuit, int level,
+ const char *ifname);
+void isis_lfa_excluded_iface_delete(struct isis_circuit *circuit, int level,
+ const char *ifname);
+bool isis_lfa_excluded_iface_check(struct isis_circuit *circuit, int level,
+ const char *ifname);
+bool isis_lfa_excise_adj_check(const struct isis_spftree *spftree,
+ const uint8_t *id);
+bool isis_lfa_excise_node_check(const struct isis_spftree *spftree,
+ const uint8_t *id);
+struct isis_spftree *isis_spf_reverse_run(const struct isis_spftree *spftree);
+int isis_spf_run_neighbors(struct isis_spftree *spftree);
+int isis_rlfa_activate(struct isis_spftree *spftree, struct rlfa *rlfa,
+ struct zapi_rlfa_response *response);
+void isis_rlfa_deactivate(struct isis_spftree *spftree, struct rlfa *rlfa);
+void isis_rlfa_list_init(struct isis_spftree *spftree);
+void isis_rlfa_list_clear(struct isis_spftree *spftree);
+void isis_rlfa_process_ldp_response(struct zapi_rlfa_response *response);
+void isis_ldp_rlfa_handle_client_close(struct zapi_client_close_info *info);
+void isis_rlfa_check(struct isis_spftree *spftree, struct isis_vertex *vertex);
+struct isis_spftree *isis_rlfa_compute(struct isis_area *area,
+ struct isis_spftree *spftree,
+ struct isis_spftree *spftree_reverse,
+ uint32_t max_metric,
+ struct lfa_protected_resource *resource);
+void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
+ struct isis_spftree *spftree,
+ struct lfa_protected_resource *resource);
+void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree);
+int isis_tilfa_check(struct isis_spftree *spftree, struct isis_vertex *vertex);
+struct isis_spftree *
+isis_tilfa_compute(struct isis_area *area, struct isis_spftree *spftree,
+ struct isis_spftree *spftree_reverse,
+ struct lfa_protected_resource *protected_resource);
+
+#endif /* _FRR_ISIS_LFA_H */