summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_adjacency.h1
-rw-r--r--isisd/isis_bfd.c47
-rw-r--r--isisd/isis_circuit.c6
-rw-r--r--isisd/isis_circuit.h3
4 files changed, 57 insertions, 0 deletions
diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h
index 3c3a211a5..2780d826f 100644
--- a/isisd/isis_adjacency.h
+++ b/isisd/isis_adjacency.h
@@ -139,5 +139,6 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
void isis_adj_build_neigh_list(struct list *adjdb, struct list *list);
void isis_adj_build_up_list(struct list *adjdb, struct list *list);
int isis_adj_usage2levels(enum isis_adj_usage usage);
+int isis_bfd_startup_timer(struct thread *thread);
#endif /* ISIS_ADJACENCY_H */
diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c
index f81dd6cf5..e74af4da2 100644
--- a/isisd/isis_bfd.c
+++ b/isisd/isis_bfd.c
@@ -329,6 +329,13 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj, int command)
if (!circuit->bfd_info)
goto out;
+ /* If IS-IS IPv6 is configured wait for IPv6 address to be programmed
+ * before starting up BFD
+ */
+ if ((circuit->ipv6_router && listcount(circuit->ipv6_link) == 0)
+ || adj->ipv6_address_count == 0)
+ return;
+
/*
* If IS-IS is enabled for both IPv4 and IPv6 on the circuit, prefer
* creating a BFD session over IPv6.
@@ -443,6 +450,44 @@ static int bfd_circuit_write_settings(struct isis_circuit *circuit,
}
#endif
+static int bfd_handle_adj_ip_enabled(struct isis_adjacency *adj, int family)
+{
+
+ if (family != AF_INET6)
+ return 0;
+
+ if (adj->bfd_session)
+ return 0;
+
+ if (adj->adj_state != ISIS_ADJ_UP)
+ return 0;
+
+ bfd_handle_adj_up(adj, ZEBRA_BFD_DEST_REGISTER);
+
+ return 0;
+}
+
+static int bfd_handle_circuit_add_addr(struct isis_circuit *circuit)
+{
+ struct isis_adjacency *adj;
+ struct listnode *node;
+
+ if (circuit->area == 0)
+ return 0;
+
+ for (ALL_LIST_ELEMENTS_RO(circuit->area->adjacency_list, node, adj)) {
+ if (adj->bfd_session)
+ continue;
+
+ if (adj->adj_state != ISIS_ADJ_UP)
+ continue;
+
+ bfd_handle_adj_up(adj, ZEBRA_BFD_DEST_REGISTER);
+ }
+
+ return 0;
+}
+
void isis_bfd_init(void)
{
bfd_gbl_init();
@@ -457,4 +502,6 @@ void isis_bfd_init(void)
hook_register(isis_circuit_config_write,
bfd_circuit_write_settings);
#endif
+ hook_register(isis_adj_ip_enabled_hook, bfd_handle_adj_ip_enabled);
+ hook_register(isis_circuit_add_addr_hook, bfd_handle_circuit_add_addr);
}
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index e3c70264f..72c17a4c7 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -248,6 +248,9 @@ struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp)
return circuit_lookup_by_ifp(ifp, isis->init_circ_list);
}
+DEFINE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit),
+ (circuit))
+
void isis_circuit_add_addr(struct isis_circuit *circuit,
struct connected *connected)
{
@@ -318,6 +321,9 @@ void isis_circuit_add_addr(struct isis_circuit *circuit,
connected->address, circuit->interface->name);
#endif /* EXTREME_DEBUG */
}
+
+ hook_call(isis_circuit_add_addr_hook, circuit);
+
return;
}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index b4b03bf6b..abb09f84e 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -221,4 +221,7 @@ DECLARE_HOOK(isis_circuit_config_write,
(circuit, vty))
#endif
+DECLARE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit),
+ (circuit))
+
#endif /* _ZEBRA_ISIS_CIRCUIT_H */