mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 16:20:08 +00:00
bgpd: rework BFD integration
Remove old BFD API usage and replace it with the new one. Highlights: - More shared code: the daemon gets notified with callbacks instead of having to roll its own code to find the notified sessions. - Less code to integrate with BFD. - Remove hidden commands to configure single / multi hop. Use protocol data instead. BGP can determine if a peer is single/multi hop according to the following criteria: a. If the IP address is a link-local address (single hop) b. The network is shared with peer (single hop) c. BGP is configured for eBGP multi hop / TTL security (multi hop) - Respect the configuration hierarchy: a. Peer configuration take precendence over peer-group configuration. b. When peer group configuration is removed, reset peer BFD configurations to defaults (unless peer had specific configs). Example: neighbor foo peer-group neighbor foo bfd profile X neighbor 192.168.0.2 peer-group foo neighbor 192.168.0.2 bfd ! If peer-group is removed the profile configuration gets ! removed from peer 192.168.0.2, but BFD will still enabled ! because of the neighbor specific bfd configuration. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
50bd8995d4
commit
21bfce9827
1120
bgpd/bgp_bfd.c
1120
bgpd/bgp_bfd.c
File diff suppressed because it is too large
Load Diff
@ -23,22 +23,55 @@
|
||||
#ifndef _QUAGGA_BGP_BFD_H
|
||||
#define _QUAGGA_BGP_BFD_H
|
||||
|
||||
extern void bgp_bfd_init(void);
|
||||
#define PEER_IS_MULTIHOP(peer) \
|
||||
((((peer)->sort == BGP_PEER_IBGP) && !(peer)->shared_network) \
|
||||
|| is_ebgp_multihop_configured((peer)))
|
||||
|
||||
extern void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer);
|
||||
extern void bgp_bfd_init(struct thread_master *tm);
|
||||
|
||||
extern void bgp_bfd_register_peer(struct peer *peer);
|
||||
extern void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
|
||||
const char *addr);
|
||||
|
||||
extern void bgp_bfd_deregister_peer(struct peer *peer);
|
||||
|
||||
extern void bgp_bfd_reset_peer(struct peer *peer);
|
||||
|
||||
extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer,
|
||||
char *addr);
|
||||
|
||||
extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json,
|
||||
/**
|
||||
* Show BFD information helper.
|
||||
*
|
||||
* \param vty the VTY pointer.
|
||||
* \param peer the BGP configuration pointer.
|
||||
* \param use_json unused.
|
||||
* \param json_neigh JSON object when called as JSON command.
|
||||
*/
|
||||
extern void bgp_bfd_show_info(struct vty *vty, const struct peer *peer,
|
||||
json_object *json_neigh);
|
||||
|
||||
extern bool bgp_bfd_is_peer_multihop(struct peer *peer);
|
||||
/**
|
||||
* When called on a group it applies configuration to all peers in that group,
|
||||
* otherwise just applies the configuration to a single peer.
|
||||
*
|
||||
* This function should be called when configuration changes either on group
|
||||
* or peer.
|
||||
*
|
||||
* \param p the BGP peer pointer.
|
||||
* \param pg the BGP group to copy configuration from (it is usually
|
||||
* `p->group` exception when copying new group configuration
|
||||
* see `peer_group2peer_config_copy` function case).
|
||||
*/
|
||||
extern void bgp_peer_config_apply(struct peer *p, struct peer_group *pg);
|
||||
|
||||
/**
|
||||
* Allocates and configure BFD session for peer. If it is already configured,
|
||||
* then it does nothing.
|
||||
*/
|
||||
extern void bgp_peer_configure_bfd(struct peer *p, bool manual);
|
||||
|
||||
/**
|
||||
* Removes BFD configuration from either peer or peer group.
|
||||
*/
|
||||
extern void bgp_peer_remove_bfd_config(struct peer *p);
|
||||
|
||||
/**
|
||||
* Special function to handle the case of changing source address. This
|
||||
* happens when the peer/group is configured with `neigbor X update-source Y`.
|
||||
*/
|
||||
extern void bgp_peer_bfd_update_source(struct peer *p);
|
||||
|
||||
#endif /* _QUAGGA_BGP_BFD_H */
|
||||
|
@ -1215,8 +1215,9 @@ int bgp_stop(struct peer *peer)
|
||||
peer->nsf_af_count = 0;
|
||||
|
||||
/* deregister peer */
|
||||
if (peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE)
|
||||
bgp_bfd_deregister_peer(peer);
|
||||
if (peer->bfd_config
|
||||
&& peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE)
|
||||
bfd_sess_uninstall(peer->bfd_config->session);
|
||||
|
||||
if (peer_dynamic_neighbor(peer)
|
||||
&& !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
|
||||
@ -2122,7 +2123,10 @@ static int bgp_establish(struct peer *peer)
|
||||
hash_release(peer->bgp->peerhash, peer);
|
||||
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
|
||||
|
||||
bgp_bfd_reset_peer(peer);
|
||||
/* Start BFD peer if not already running. */
|
||||
if (peer->bfd_config)
|
||||
bgp_peer_bfd_update_source(peer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,9 @@ __attribute__((__noreturn__)) void sigint(void)
|
||||
assert(bm->terminating == false);
|
||||
bm->terminating = true; /* global flag that shutting down */
|
||||
|
||||
/* Disable BFD events to avoid wasting processing. */
|
||||
bfd_protocol_integration_set_shutdown(true);
|
||||
|
||||
bgp_terminate();
|
||||
|
||||
bgp_exit(0);
|
||||
|
@ -14411,7 +14411,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
|
||||
vty_out(vty, "\n");
|
||||
|
||||
/* BFD information. */
|
||||
bgp_bfd_show_info(vty, p, use_json, json_neigh);
|
||||
if (p->bfd_config)
|
||||
bgp_bfd_show_info(vty, p, json_neigh);
|
||||
|
||||
if (use_json) {
|
||||
if (p->conf_if) /* Configured interface name. */
|
||||
@ -16818,11 +16819,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
|
||||
peer->rtt_expected, peer->rtt_keepalive_conf);
|
||||
|
||||
/* bfd */
|
||||
if (peer->bfd_info) {
|
||||
if (!peer_group_active(peer) || !g_peer->bfd_info) {
|
||||
bgp_bfd_peer_config_write(vty, peer, addr);
|
||||
}
|
||||
}
|
||||
if (peer->bfd_config)
|
||||
bgp_bfd_peer_config_write(vty, peer, addr);
|
||||
|
||||
/* password */
|
||||
if (peergroup_flag_check(peer, PEER_FLAG_PASSWORD))
|
||||
|
19
bgpd/bgpd.c
19
bgpd/bgpd.c
@ -1161,7 +1161,9 @@ static void peer_free(struct peer *peer)
|
||||
|
||||
XFREE(MTYPE_PEER_CONF_IF, peer->conf_if);
|
||||
|
||||
bfd_info_free(&(peer->bfd_info));
|
||||
/* Remove BFD configuration. */
|
||||
if (peer->bfd_config)
|
||||
bgp_peer_remove_bfd_config(peer);
|
||||
|
||||
FOREACH_AFI_SAFI (afi, safi)
|
||||
bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE);
|
||||
@ -2394,7 +2396,9 @@ int peer_delete(struct peer *peer)
|
||||
|
||||
SET_FLAG(peer->flags, PEER_FLAG_DELETE);
|
||||
|
||||
bgp_bfd_deregister_peer(peer);
|
||||
/* Remove BFD settings. */
|
||||
if (peer->bfd_config)
|
||||
bgp_peer_remove_bfd_config(peer);
|
||||
|
||||
/* Delete peer route flap dampening configuration. This needs to happen
|
||||
* before removing the peer from peer groups.
|
||||
@ -2678,7 +2682,11 @@ static void peer_group2peer_config_copy(struct peer_group *group,
|
||||
/* Update GR flags for the peer. */
|
||||
bgp_peer_gr_flags_update(peer);
|
||||
|
||||
bgp_bfd_peer_group2peer_copy(conf, peer);
|
||||
/* Apply BFD settings from group to peer if it exists. */
|
||||
if (conf->bfd_config) {
|
||||
bgp_peer_configure_bfd(peer, false);
|
||||
bgp_peer_config_apply(peer, group);
|
||||
}
|
||||
}
|
||||
|
||||
/* Peer group's remote AS configuration. */
|
||||
@ -2768,7 +2776,8 @@ int peer_group_delete(struct peer_group *group)
|
||||
XFREE(MTYPE_PEER_GROUP_HOST, group->name);
|
||||
group->name = NULL;
|
||||
|
||||
bfd_info_free(&(group->conf->bfd_info));
|
||||
if (group->conf->bfd_config)
|
||||
bgp_peer_remove_bfd_config(group->conf);
|
||||
|
||||
group->conf->group = NULL;
|
||||
peer_delete(group->conf);
|
||||
@ -7700,7 +7709,7 @@ void bgp_init(unsigned short instance)
|
||||
bgp_clist = community_list_init();
|
||||
|
||||
/* BFD init */
|
||||
bgp_bfd_init();
|
||||
bgp_bfd_init(bm->master);
|
||||
|
||||
bgp_lp_vty_init();
|
||||
|
||||
|
27
bgpd/bgpd.h
27
bgpd/bgpd.h
@ -45,6 +45,8 @@
|
||||
#include "bgp_nexthop.h"
|
||||
#include "bgp_damp.h"
|
||||
|
||||
#include "lib/bfd.h"
|
||||
|
||||
#define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */
|
||||
#define BGP_PEER_MAX_HASH_SIZE 16384
|
||||
|
||||
@ -1558,8 +1560,29 @@ struct peer {
|
||||
#define PEER_RMAP_TYPE_EXPORT (1U << 7) /* neighbor route-map export */
|
||||
#define PEER_RMAP_TYPE_AGGREGATE (1U << 8) /* aggregate-address route-map */
|
||||
|
||||
/* peer specific BFD information */
|
||||
struct bfd_info *bfd_info;
|
||||
/** Peer overwrite configuration. */
|
||||
struct bfd_session_config {
|
||||
/**
|
||||
* Manual configuration bit.
|
||||
*
|
||||
* This flag only makes sense for real peers (and not groups),
|
||||
* it keeps track if the user explicitly configured BFD for a
|
||||
* peer.
|
||||
*/
|
||||
bool manual;
|
||||
/** Control Plane Independent. */
|
||||
bool cbit;
|
||||
/** Detection multiplier. */
|
||||
uint8_t detection_multiplier;
|
||||
/** Minimum required RX interval. */
|
||||
uint32_t min_rx;
|
||||
/** Minimum required TX interval. */
|
||||
uint32_t min_tx;
|
||||
/** Profile name. */
|
||||
char profile[BFD_PROFILE_NAME_LEN];
|
||||
/** Peer BFD session */
|
||||
struct bfd_session_params *session;
|
||||
} * bfd_config;
|
||||
|
||||
/* hostname and domainname advertised by host */
|
||||
char *hostname;
|
||||
|
Loading…
Reference in New Issue
Block a user