mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 02:06:12 +00:00
Merge pull request #10838 from ton31337/feature/bgpd_callbacks_for_start_end_configurations
bgpd: Add BGP configuration start/end markers
This commit is contained in:
commit
4037154240
@ -17599,11 +17599,67 @@ static const struct cmd_variable_handler bgp_var_peergroup[] = {
|
|||||||
{.tokenname = "PGNAME", .completions = bgp_ac_peergroup},
|
{.tokenname = "PGNAME", .completions = bgp_ac_peergroup},
|
||||||
{.completions = NULL} };
|
{.completions = NULL} };
|
||||||
|
|
||||||
|
DEFINE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp));
|
||||||
|
|
||||||
|
static struct thread *t_bgp_cfg;
|
||||||
|
|
||||||
|
bool bgp_config_inprocess(void)
|
||||||
|
{
|
||||||
|
return thread_is_scheduled(t_bgp_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bgp_config_finish(struct thread *t)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct bgp *bgp;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp))
|
||||||
|
hook_call(bgp_config_end, bgp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bgp_config_start(void)
|
||||||
|
{
|
||||||
|
#define BGP_PRE_CONFIG_MAX_WAIT_SECONDS 600
|
||||||
|
THREAD_OFF(t_bgp_cfg);
|
||||||
|
thread_add_timer(bm->master, bgp_config_finish, NULL,
|
||||||
|
BGP_PRE_CONFIG_MAX_WAIT_SECONDS, &t_bgp_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we receive a hook the configuration is read,
|
||||||
|
* we start a timer to make sure we postpone sending
|
||||||
|
* EoR before route-maps are processed.
|
||||||
|
* This is especially valid if using `bgp route-map delay-timer`.
|
||||||
|
*/
|
||||||
|
static void bgp_config_end(void)
|
||||||
|
{
|
||||||
|
#define BGP_POST_CONFIG_DELAY_SECONDS 1
|
||||||
|
uint32_t bgp_post_config_delay =
|
||||||
|
thread_is_scheduled(bm->t_rmap_update)
|
||||||
|
? thread_timer_remain_second(bm->t_rmap_update)
|
||||||
|
: BGP_POST_CONFIG_DELAY_SECONDS;
|
||||||
|
|
||||||
|
/* If BGP config processing thread isn't running, then
|
||||||
|
* we can return and rely it's properly handled.
|
||||||
|
*/
|
||||||
|
if (!bgp_config_inprocess())
|
||||||
|
return;
|
||||||
|
|
||||||
|
THREAD_OFF(t_bgp_cfg);
|
||||||
|
|
||||||
|
/* Start a new timer to make sure we don't send EoR
|
||||||
|
* before route-maps are processed.
|
||||||
|
*/
|
||||||
|
thread_add_timer(bm->master, bgp_config_finish, NULL,
|
||||||
|
bgp_post_config_delay, &t_bgp_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
void bgp_vty_init(void)
|
void bgp_vty_init(void)
|
||||||
{
|
{
|
||||||
cmd_variable_handler_register(bgp_var_neighbor);
|
cmd_variable_handler_register(bgp_var_neighbor);
|
||||||
cmd_variable_handler_register(bgp_var_peergroup);
|
cmd_variable_handler_register(bgp_var_peergroup);
|
||||||
|
|
||||||
|
cmd_init_config_callbacks(bgp_config_start, bgp_config_end);
|
||||||
|
|
||||||
/* Install bgp top node. */
|
/* Install bgp top node. */
|
||||||
install_node(&bgp_node);
|
install_node(&bgp_node);
|
||||||
install_node(&bgp_ipv4_unicast_node);
|
install_node(&bgp_ipv4_unicast_node);
|
||||||
|
@ -164,6 +164,7 @@ extern void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp);
|
|||||||
extern void bgp_config_write_listen(struct vty *vty, struct bgp *bgp);
|
extern void bgp_config_write_listen(struct vty *vty, struct bgp *bgp);
|
||||||
extern void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp);
|
extern void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp);
|
||||||
extern int bgp_vty_return(struct vty *vty, int ret);
|
extern int bgp_vty_return(struct vty *vty, int ret);
|
||||||
|
extern bool bgp_config_inprocess(void);
|
||||||
extern struct peer *peer_and_group_lookup_vty(struct vty *vty,
|
extern struct peer *peer_and_group_lookup_vty(struct vty *vty,
|
||||||
const char *peer_str);
|
const char *peer_str);
|
||||||
|
|
||||||
|
27
bgpd/bgpd.c
27
bgpd/bgpd.c
@ -1731,6 +1731,8 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
|
|||||||
peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
|
peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
|
||||||
? BGP_DEFAULT_IBGP_ROUTEADV
|
? BGP_DEFAULT_IBGP_ROUTEADV
|
||||||
: BGP_DEFAULT_EBGP_ROUTEADV;
|
: BGP_DEFAULT_EBGP_ROUTEADV;
|
||||||
|
if (bgp_config_inprocess())
|
||||||
|
peer->shut_during_cfg = true;
|
||||||
|
|
||||||
peer = peer_lock(peer); /* bgp peer list reference */
|
peer = peer_lock(peer); /* bgp peer list reference */
|
||||||
peer->group = group;
|
peer->group = group;
|
||||||
@ -7940,8 +7942,33 @@ void bgp_pthreads_finish(void)
|
|||||||
frr_pthread_stop_all();
|
frr_pthread_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int peer_unshut_after_cfg(struct bgp *bgp)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct peer *peer;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
|
||||||
|
if (!peer->shut_during_cfg)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bgp_debug_neighbor_events(peer))
|
||||||
|
zlog_debug("%s: released from config-pending hold",
|
||||||
|
peer->host);
|
||||||
|
|
||||||
|
peer->shut_during_cfg = false;
|
||||||
|
if (peer_active(peer) && peer->status != Established) {
|
||||||
|
if (peer->status != Idle)
|
||||||
|
BGP_EVENT_ADD(peer, BGP_Stop);
|
||||||
|
BGP_EVENT_ADD(peer, BGP_Start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void bgp_init(unsigned short instance)
|
void bgp_init(unsigned short instance)
|
||||||
{
|
{
|
||||||
|
hook_register(bgp_config_end, peer_unshut_after_cfg);
|
||||||
|
|
||||||
/* allocates some vital data structures used by peer commands in
|
/* allocates some vital data structures used by peer commands in
|
||||||
* vty_init */
|
* vty_init */
|
||||||
|
10
bgpd/bgpd.h
10
bgpd/bgpd.h
@ -771,6 +771,7 @@ DECLARE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp));
|
|||||||
DECLARE_HOOK(bgp_inst_config_write,
|
DECLARE_HOOK(bgp_inst_config_write,
|
||||||
(struct bgp *bgp, struct vty *vty),
|
(struct bgp *bgp, struct vty *vty),
|
||||||
(bgp, vty));
|
(bgp, vty));
|
||||||
|
DECLARE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp));
|
||||||
|
|
||||||
/* Thread callback information */
|
/* Thread callback information */
|
||||||
struct afi_safi_info {
|
struct afi_safi_info {
|
||||||
@ -1676,6 +1677,8 @@ struct peer {
|
|||||||
/* Long-lived Graceful Restart */
|
/* Long-lived Graceful Restart */
|
||||||
struct llgr_info llgr[AFI_MAX][SAFI_MAX];
|
struct llgr_info llgr[AFI_MAX][SAFI_MAX];
|
||||||
|
|
||||||
|
bool shut_during_cfg;
|
||||||
|
|
||||||
QOBJ_FIELDS;
|
QOBJ_FIELDS;
|
||||||
};
|
};
|
||||||
DECLARE_QOBJ_TYPE(peer);
|
DECLARE_QOBJ_TYPE(peer);
|
||||||
@ -1703,9 +1706,10 @@ DECLARE_QOBJ_TYPE(peer);
|
|||||||
|
|
||||||
/* Check if suppress start/restart of sessions to peer. */
|
/* Check if suppress start/restart of sessions to peer. */
|
||||||
#define BGP_PEER_START_SUPPRESSED(P) \
|
#define BGP_PEER_START_SUPPRESSED(P) \
|
||||||
(CHECK_FLAG((P)->flags, PEER_FLAG_SHUTDOWN) \
|
(CHECK_FLAG((P)->flags, PEER_FLAG_SHUTDOWN) || \
|
||||||
|| CHECK_FLAG((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW) \
|
CHECK_FLAG((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW) || \
|
||||||
|| CHECK_FLAG((P)->bgp->flags, BGP_FLAG_SHUTDOWN))
|
CHECK_FLAG((P)->bgp->flags, BGP_FLAG_SHUTDOWN) || \
|
||||||
|
(P)->shut_during_cfg)
|
||||||
|
|
||||||
#define PEER_ROUTE_ADV_DELAY(peer) \
|
#define PEER_ROUTE_ADV_DELAY(peer) \
|
||||||
(CHECK_FLAG(peer->thread_flags, PEER_THREAD_SUBGRP_ADV_DELAY))
|
(CHECK_FLAG(peer->thread_flags, PEER_THREAD_SUBGRP_ADV_DELAY))
|
||||||
|
Loading…
Reference in New Issue
Block a user