summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_bmp.c22
-rw-r--r--bgpd/bgp_nht.c6
-rw-r--r--bgpd/bgp_nht.h5
-rw-r--r--bgpd/bgp_trace.h18
4 files changed, 51 insertions, 0 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 4065d86795..0d3f196f96 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -28,6 +28,7 @@
#include "bgpd/bgp_table.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_errors.h"
@@ -1708,6 +1709,26 @@ static int bmp_process(struct bgp *bgp, afi_t afi, safi_t safi,
return 0;
}
+static int bmp_nht_path_valid(struct bgp *bgp, struct bgp_path_info *path, bool valid)
+{
+ struct bgp_dest *dest = path->net;
+ struct bgp_table *table;
+
+ if (frrtrace_enabled(frr_bgp, bmp_nht_path_valid)) {
+ char pfxprint[PREFIX2STR_BUFFER];
+
+ prefix2str(&dest->rn->p, pfxprint, sizeof(pfxprint));
+ frrtrace(4, frr_bgp, bmp_nht_path_valid, bgp, pfxprint, path, valid);
+ }
+ if (bgp->peer_self == path->peer)
+ /* self declared networks or redistributed networks are not relevant for bmp */
+ return 0;
+
+ table = bgp_dest_table(dest);
+
+ return bmp_process(bgp, table->afi, table->safi, dest, path->peer, !valid);
+}
+
static void bmp_stat_put_u32(struct stream *s, size_t *cnt, uint16_t type,
uint32_t value)
{
@@ -3195,6 +3216,7 @@ static int bgp_bmp_module_init(void)
hook_register(peer_status_changed, bmp_peer_status_changed);
hook_register(peer_backward_transition, bmp_peer_backward);
hook_register(bgp_process, bmp_process);
+ hook_register(bgp_nht_path_update, bmp_nht_path_valid);
hook_register(bgp_inst_config_write, bmp_config_write);
hook_register(bgp_inst_delete, bmp_bgp_del);
hook_register(frr_late_init, bgp_bmp_init);
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index ed83757ea3..164e2300c0 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -41,6 +41,9 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc);
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
static void bgp_nht_ifp_initial(struct event *thread);
+DEFINE_HOOK(bgp_nht_path_update, (struct bgp *bgp, struct bgp_path_info *pi, bool valid),
+ (bgp, pi, valid));
+
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
{
return (bgp_zebra_num_connects() == 0
@@ -1449,6 +1452,9 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
}
}
+ if (path_valid != bnc_is_valid_nexthop)
+ hook_call(bgp_nht_path_update, bgp_path, path, bnc_is_valid_nexthop);
+
bgp_process(bgp_path, dest, path, afi, safi);
}
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index e7c6fdc281..345089ac5a 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -83,4 +83,9 @@ extern void bgp_nht_ifp_up(struct interface *ifp);
extern void bgp_nht_ifp_down(struct interface *ifp);
extern void bgp_nht_interface_events(struct peer *peer);
+
+/* called when a path becomes valid or invalid, because of nexthop tracking */
+DECLARE_HOOK(bgp_nht_path_update, (struct bgp *bgp, struct bgp_path_info *pi, bool valid),
+ (bgp, pi, valid));
+
#endif /* _BGP_NHT_H */
diff --git a/bgpd/bgp_trace.h b/bgpd/bgp_trace.h
index a77a25e435..43bc7a5a17 100644
--- a/bgpd/bgp_trace.h
+++ b/bgpd/bgp_trace.h
@@ -211,6 +211,24 @@ TRACEPOINT_EVENT(
TRACEPOINT_LOGLEVEL(frr_bgp, bmp_process, TRACE_DEBUG)
/*
+ * BMP is hooked for a nexthop tracking event
+ */
+TRACEPOINT_EVENT(
+ frr_bgp,
+ bmp_nht_path_valid,
+ TP_ARGS(struct bgp *, bgp, char *, pfx, struct bgp_path_info *,
+ path, bool, valid),
+ TP_FIELDS(
+ ctf_string(bgp, bgp->name_pretty)
+ ctf_string(prefix, pfx)
+ ctf_string(path, PEER_HOSTNAME(path->peer))
+ ctf_integer(bool, valid, valid)
+ )
+)
+
+TRACEPOINT_LOGLEVEL(frr_bgp, bmp_nht_path_valid, TRACE_DEBUG)
+
+/*
* bgp_dest_lock/bgp_dest_unlock
*/
TRACEPOINT_EVENT(