mirror_frr/bgpd/bgp_nht.h
Philippe Guibert 6e2d58854d bgpd: fix do re-send post-policy bgp update when not valid
When a BGP listener configured with BMP receives the first BGP
IPv6 update from a connected BGP IPv6 peer, the BMP collector
receives a withdraw post-policy message.

> {"peer_type": "route distinguisher instance", "policy": "post-policy",
> "ipv6": true, "peer_ip": "192:167::3", "peer_distinguisher": "444:1",
> "peer_asn": 65501, "peer_bgp_id": "192.168.1.3", "timestamp":
> "2024-10-29 11:44:47.111962", "bmp_log_type": "withdraw", "afi": 2,
> "safi": 1, "ip_prefix": "2001::1125/128", "seq": 22}
> {"peer_type": "route distinguisher instance", "policy": "pre-policy",
> "ipv6": true, "peer_ip": "192:167::3", "peer_distinguisher": "444:1",
> "peer_asn": 65501, "peer_bgp_id": "192.168.1.3", "timestamp":
> "2024-10-29 11:44:47.111963", "bmp_log_type": "update", "origin":
> "IGP", "as_path": "", "afi": 2, "safi": 1, "nxhp_ip": "192:167::3",
> "nxhp_link-local": "fe80::7063:d8ff:fedb:9e11", "ip_prefix": "2001::1125/128", "seq": 23}

Actually, the BGP update is not valid, and BMP considers it as a
withdraw message. The BGP upate is not valid, because the nexthop
reachability is unknown at the time of reception, and no other
BMP message is sent.

Fix this by re-sending a BMP post update message when nexthop
tracking becomes successfull. Generalise the re-sending of
messages when nexthop tracking changes.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2024-12-30 15:13:37 +01:00

92 lines
3.1 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/* BGP Nexthop tracking
* Copyright (C) 2013 Cumulus Networks, Inc.
*/
#ifndef _BGP_NHT_H
#define _BGP_NHT_H
/**
* bgp_nexthop_update() - process a nexthop update message from Zebra.
*/
extern void bgp_nexthop_update(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr);
/**
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
* object. If not found, create a new object and register with ZEBRA for
* nexthop notification.
* ARGUMENTS:
* bgp_route - BGP instance of route
* bgp_nexthop - BGP instance of nexthop
* a - afi: AFI_IP or AF_IP6
* safi - safi: to check which table nhs are being imported to
* p - path for which the nexthop object is being looked up
* peer - The BGP peer associated with this NHT
* connected - True if NH MUST be a connected route
*/
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
struct bgp *bgp_nexthop, afi_t a,
safi_t safi, struct bgp_path_info *p,
struct peer *peer, int connected,
const struct prefix *orig_prefix);
/**
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
* ARGUMENTS:
* p - path structure.
*/
extern void bgp_unlink_nexthop(struct bgp_path_info *p);
void bgp_unlink_nexthop_by_peer(struct peer *peer);
void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to);
/**
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
* nexthop entry. If no paths reference the nexthop, it will be unregistered
* and freed.
* ARGUMENTS:
* afi - afi: AFI_IP or AF_IP6
* peer - Ptr to peer
*/
extern void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer);
/*
* Cleanup nexthop registration and status information for BGP nexthops
* pertaining to this VRF. This is invoked upon VRF deletion.
*/
extern void bgp_cleanup_nexthops(struct bgp *bgp);
/*
* Add or remove the tracking of the bgp_path_info that
* uses this nexthop
*/
extern void path_nh_map(struct bgp_path_info *path,
struct bgp_nexthop_cache *bnc, bool make);
/*
* When we actually have the connection to
* the zebra daemon, we need to reregister
* any nexthops we may have sitting around
*/
extern void bgp_nht_register_nexthops(struct bgp *bgp);
/*
* When we have the the PEER_FLAG_CAPABILITY_ENHE flag
* set on a peer *after* it has been brought up we need
* to notice and setup the interface based RA,
* this code can walk the registered nexthops and
* register the important ones with zebra for RA.
*/
extern void bgp_nht_reg_enhe_cap_intfs(struct peer *peer);
extern void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer);
extern void evaluate_paths(struct bgp_nexthop_cache *bnc);
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 */