summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2020-12-09 11:49:22 -0500
committerGitHub <noreply@github.com>2020-12-09 11:49:22 -0500
commit327c3aad2a08021ef2e4239bd0df123fa2845fbd (patch)
tree7b36f9accfb5ef9bb3cf4f184e66a3cbd87a5499
parente386d2b15419382d3cf00a6cd986fbdc723b48f5 (diff)
parentcb135cc94303d2581987645f124bd6d4cecd80a6 (diff)
Merge pull request #7686 from volta-networks/fix_ldpsync_igps_detect_client_close
isisd, ospfd: IGPs detect LDP down via zapi client close message
-rw-r--r--isisd/isis_ldp_sync.c40
-rw-r--r--isisd/isis_ldp_sync.h4
-rw-r--r--isisd/isis_zebra.c16
-rw-r--r--ospfd/ospf_ldp_sync.c29
-rw-r--r--ospfd/ospf_ldp_sync.h2
-rw-r--r--ospfd/ospf_zebra.c16
6 files changed, 105 insertions, 2 deletions
diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c
index 3b1faffe53..c9d29871ae 100644
--- a/isisd/isis_ldp_sync.c
+++ b/isisd/isis_ldp_sync.c
@@ -293,7 +293,7 @@ void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit)
ldp_sync_info = circuit->ldp_sync_info;
- /* LDP failed to send hello:
+ /* LDP client close detected:
* stop holddown timer
* set cost of interface to LSInfinity so traffic will use different
* interface until LDP restarts and has learned all labels from peer
@@ -522,6 +522,44 @@ void isis_ldp_sync_holddown_timer_add(struct isis_circuit *circuit)
}
/*
+ * LDP-SYNC handle client close routine
+ */
+void isis_ldp_sync_handle_client_close(struct zapi_client_close_info *info)
+{
+ struct isis_area *area;
+ struct listnode *node;
+ struct isis_circuit *circuit;
+ struct interface *ifp;
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+
+ /* if isis is not enabled or LDP-SYNC is not configured ignore */
+ if (!isis
+ || !CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ return;
+
+ /* Check if the LDP main client session closed */
+ if (info->proto != ZEBRA_ROUTE_LDP || info->session_id == 0)
+ return;
+
+ /* Handle the zebra notification that the LDP client session closed.
+ * set cost to LSInfinity
+ * send request to LDP for LDP-SYNC state for each interface
+ */
+ zlog_err("ldp_sync: LDP down");
+
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
+ circuit =
+ circuit_lookup_by_ifp(ifp, area->circuit_list);
+ if (circuit == NULL)
+ continue;
+ isis_ldp_sync_if_start(circuit, true);
+ }
+ }
+}
+
+/*
* LDP-SYNC hello timer routines
*/
static int isis_ldp_sync_hello_timer(struct thread *thread)
diff --git a/isisd/isis_ldp_sync.h b/isisd/isis_ldp_sync.h
index 61ac946078..1b6058c5c9 100644
--- a/isisd/isis_ldp_sync.h
+++ b/isisd/isis_ldp_sync.h
@@ -20,6 +20,8 @@
#ifndef _ZEBRA_ISIS_LDP_SYNC_H
#define _ZEBRA_ISIS_LDP_SYNC_H
+#include "zclient.h"
+
/* Macro to log debug message */
#define ils_debug(...) \
do { \
@@ -36,6 +38,8 @@ extern void isis_ldp_sync_if_start(struct isis_circuit *circuit,
extern void isis_ldp_sync_if_remove(struct isis_circuit *circuit, bool remove);
extern void isis_ldp_sync_if_complete(struct isis_circuit *circuit);
extern void isis_ldp_sync_holddown_timer_add(struct isis_circuit *circuit);
+extern void
+isis_ldp_sync_handle_client_close(struct zapi_client_close_info *info);
extern void isis_ldp_sync_hello_timer_add(void);
extern void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit);
extern int isis_ldp_sync_state_update(struct ldp_igp_sync_if_state state);
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 1b4b0c8f2f..d51a4db939 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -699,6 +699,20 @@ stream_failure:
return ret;
}
+static int isis_zebra_client_close_notify(ZAPI_CALLBACK_ARGS)
+{
+ int ret = 0;
+
+ struct zapi_client_close_info info;
+
+ if (zapi_client_close_notify_decode(zclient->ibuf, &info) < 0)
+ return -1;
+
+ isis_ldp_sync_handle_client_close(&info);
+
+ return ret;
+}
+
void isis_zebra_init(struct thread_master *master, int instance)
{
/* Initialize asynchronous zclient. */
@@ -727,6 +741,8 @@ void isis_zebra_init(struct thread_master *master, int instance)
zclient_sync->privs = &isisd_privs;
zclient->opaque_msg_handler = isis_opaque_msg_handler;
+
+ zclient->zebra_client_close_notify = isis_zebra_client_close_notify;
}
void isis_zebra_stop(void)
diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c
index 68792ebcc2..bca15304b1 100644
--- a/ospfd/ospf_ldp_sync.c
+++ b/ospfd/ospf_ldp_sync.c
@@ -253,6 +253,33 @@ void ospf_ldp_sync_if_complete(struct interface *ifp)
}
}
+void ospf_ldp_sync_handle_client_close(struct zapi_client_close_info *info)
+{
+ struct ospf *ospf;
+ struct vrf *vrf;
+ struct interface *ifp;
+
+ /* if ospf is not enabled or LDP-SYNC is not configured ignore */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL
+ || !CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ return;
+
+ /* Check if the LDP main client session closed */
+ if (info->proto != ZEBRA_ROUTE_LDP || info->session_id == 0)
+ return;
+
+ /* Handle the zebra notification that the LDP client session closed.
+ * set cost to LSInfinity
+ * send request to LDP for LDP-SYNC state for each interface
+ */
+ zlog_err("ldp_sync: LDP down");
+
+ vrf = vrf_lookup_by_id(ospf->vrf_id);
+ FOR_ALL_INTERFACES (vrf, ifp)
+ ospf_ldp_sync_if_start(ifp, true);
+}
+
void ospf_ldp_sync_ldp_fail(struct interface *ifp)
{
struct ospf_if_params *params;
@@ -264,7 +291,7 @@ void ospf_ldp_sync_ldp_fail(struct interface *ifp)
params = IF_DEF_PARAMS(ifp);
ldp_sync_info = params->ldp_sync_info;
- /* LDP failed to send hello:
+ /* LDP client close detected:
* stop holddown timer
* set cost of interface to LSInfinity so traffic will use different
* interface until LDP has learned all labels from peer
diff --git a/ospfd/ospf_ldp_sync.h b/ospfd/ospf_ldp_sync.h
index d4efa55311..418ca4e5b6 100644
--- a/ospfd/ospf_ldp_sync.h
+++ b/ospfd/ospf_ldp_sync.h
@@ -50,6 +50,8 @@ extern void ospf_ldp_sync_if_write_config(struct vty *vty,
extern int ospf_ldp_sync_state_update(struct ldp_igp_sync_if_state state);
extern int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce);
extern int ospf_ldp_sync_hello_update(struct ldp_igp_sync_hello hello);
+extern void
+ospf_ldp_sync_handle_client_close(struct zapi_client_close_info *info);
extern void ospf_ldp_sync_state_req_msg(struct interface *ifp);
extern void ospf_ldp_sync_init(void);
extern void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index e7dbdbd9af..93d4ee0ec7 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -1986,6 +1986,20 @@ stream_failure:
return ret;
}
+static int ospf_zebra_client_close_notify(ZAPI_CALLBACK_ARGS)
+{
+ int ret = 0;
+
+ struct zapi_client_close_info info;
+
+ if (zapi_client_close_notify_decode(zclient->ibuf, &info) < 0)
+ return -1;
+
+ ospf_ldp_sync_handle_client_close(&info);
+
+ return ret;
+}
+
void ospf_zebra_init(struct thread_master *master, unsigned short instance)
{
/* Allocate zebra structure. */
@@ -2021,6 +2035,8 @@ void ospf_zebra_init(struct thread_master *master, unsigned short instance)
prefix_list_delete_hook(ospf_prefix_list_update);
zclient->opaque_msg_handler = ospf_opaque_msg_handler;
+
+ zclient->zebra_client_close_notify = ospf_zebra_client_close_notify;
}
void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p)