mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 20:59:36 +00:00
Merge pull request #7686 from volta-networks/fix_ldpsync_igps_detect_client_close
isisd, ospfd: IGPs detect LDP down via zapi client close message
This commit is contained in:
commit
327c3aad2a
@ -293,7 +293,7 @@ void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit)
|
|||||||
|
|
||||||
ldp_sync_info = circuit->ldp_sync_info;
|
ldp_sync_info = circuit->ldp_sync_info;
|
||||||
|
|
||||||
/* LDP failed to send hello:
|
/* LDP client close detected:
|
||||||
* stop holddown timer
|
* stop holddown timer
|
||||||
* set cost of interface to LSInfinity so traffic will use different
|
* set cost of interface to LSInfinity so traffic will use different
|
||||||
* interface until LDP restarts and has learned all labels from peer
|
* interface until LDP restarts and has learned all labels from peer
|
||||||
@ -521,6 +521,44 @@ void isis_ldp_sync_holddown_timer_add(struct isis_circuit *circuit)
|
|||||||
&ldp_sync_info->t_holddown);
|
&ldp_sync_info->t_holddown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* LDP-SYNC hello timer routines
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#ifndef _ZEBRA_ISIS_LDP_SYNC_H
|
#ifndef _ZEBRA_ISIS_LDP_SYNC_H
|
||||||
#define _ZEBRA_ISIS_LDP_SYNC_H
|
#define _ZEBRA_ISIS_LDP_SYNC_H
|
||||||
|
|
||||||
|
#include "zclient.h"
|
||||||
|
|
||||||
/* Macro to log debug message */
|
/* Macro to log debug message */
|
||||||
#define ils_debug(...) \
|
#define ils_debug(...) \
|
||||||
do { \
|
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_remove(struct isis_circuit *circuit, bool remove);
|
||||||
extern void isis_ldp_sync_if_complete(struct isis_circuit *circuit);
|
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_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_hello_timer_add(void);
|
||||||
extern void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit);
|
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);
|
extern int isis_ldp_sync_state_update(struct ldp_igp_sync_if_state state);
|
||||||
|
@ -699,6 +699,20 @@ stream_failure:
|
|||||||
return ret;
|
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)
|
void isis_zebra_init(struct thread_master *master, int instance)
|
||||||
{
|
{
|
||||||
/* Initialize asynchronous zclient. */
|
/* Initialize asynchronous zclient. */
|
||||||
@ -727,6 +741,8 @@ void isis_zebra_init(struct thread_master *master, int instance)
|
|||||||
zclient_sync->privs = &isisd_privs;
|
zclient_sync->privs = &isisd_privs;
|
||||||
|
|
||||||
zclient->opaque_msg_handler = isis_opaque_msg_handler;
|
zclient->opaque_msg_handler = isis_opaque_msg_handler;
|
||||||
|
|
||||||
|
zclient->zebra_client_close_notify = isis_zebra_client_close_notify;
|
||||||
}
|
}
|
||||||
|
|
||||||
void isis_zebra_stop(void)
|
void isis_zebra_stop(void)
|
||||||
|
@ -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)
|
void ospf_ldp_sync_ldp_fail(struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct ospf_if_params *params;
|
struct ospf_if_params *params;
|
||||||
@ -264,7 +291,7 @@ void ospf_ldp_sync_ldp_fail(struct interface *ifp)
|
|||||||
params = IF_DEF_PARAMS(ifp);
|
params = IF_DEF_PARAMS(ifp);
|
||||||
ldp_sync_info = params->ldp_sync_info;
|
ldp_sync_info = params->ldp_sync_info;
|
||||||
|
|
||||||
/* LDP failed to send hello:
|
/* LDP client close detected:
|
||||||
* stop holddown timer
|
* stop holddown timer
|
||||||
* set cost of interface to LSInfinity so traffic will use different
|
* set cost of interface to LSInfinity so traffic will use different
|
||||||
* interface until LDP has learned all labels from peer
|
* interface until LDP has learned all labels from peer
|
||||||
|
@ -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_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_announce_update(struct ldp_igp_sync_announce announce);
|
||||||
extern int ospf_ldp_sync_hello_update(struct ldp_igp_sync_hello hello);
|
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_state_req_msg(struct interface *ifp);
|
||||||
extern void ospf_ldp_sync_init(void);
|
extern void ospf_ldp_sync_init(void);
|
||||||
extern void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove);
|
extern void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove);
|
||||||
|
@ -1986,6 +1986,20 @@ stream_failure:
|
|||||||
return ret;
|
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)
|
void ospf_zebra_init(struct thread_master *master, unsigned short instance)
|
||||||
{
|
{
|
||||||
/* Allocate zebra structure. */
|
/* 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);
|
prefix_list_delete_hook(ospf_prefix_list_update);
|
||||||
|
|
||||||
zclient->opaque_msg_handler = ospf_opaque_msg_handler;
|
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)
|
void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p)
|
||||||
|
Loading…
Reference in New Issue
Block a user