forked from Mirror/frr

When exporting a VPN SRv6 route, the path may not be considered valid if the nexthop is not valid. This is the case when the 'nexthop vpn export' command is used. The below example illustrates that the VPN path to 2001:1::/64 is not selected, as the expected nexthop to find in vrf10 is the one configured: > # show running-config > router bgp 1 vrf vrf10 > address-family ipv6 unicast > nexthop vpn export 2001::1 > # show bgp ipv6 vpn > [..] > Route Distinguisher: 1:10 > 2001:1::/64 2001::1@4 0 0 65001 i > UN=2001::1 EC{99:99} label=16 sid=2001:db8:1:1:: sid_structure=[40,24,16,0] type=bgp, subtype=5 The analysis indicates that the 2001::1 nexthop is considered. > 2025/03/20 21:47:53.751853 BGP: [RD1WY-YE9EC] leak_update: entry: leak-to=VRF default, p=2001:1::/64, type=10, sub_type=0 > 2025/03/20 21:47:53.751855 BGP: [VWNP2-DNMFV] Found existing bnc 2001::1/128(0)(VRF vrf10) flags 0x82 ifindex 0 #paths 2 peer 0x0, resolved prefix UNK prefix > 2025/03/20 21:47:53.751856 BGP: [VWC2R-4REXZ] leak_update_nexthop_valid: 2001:1::/64 nexthop is not valid (in VRF vrf10) > 2025/03/20 21:47:53.751857 BGP: [HX87B-ZXWX9] leak_update: ->VRF default: 2001:1::/64: Found route, no change Actually, to check the nexthop validity, only the source path in the VRF has the correct nexthop. Fix this by reusing the source path information instead of the current one. > 2025/03/20 22:43:51.703521 BGP: [RD1WY-YE9EC] leak_update: entry: leak-to=VRF default, p=2001:1::/64, type=10, sub_type=0 > 2025/03/20 22:43:51.703523 BGP: [VWNP2-DNMFV] Found existing bnc fe80::b812:37ff:fe13:d441/128(0)(VRF vrf10) flags 0x87 ifindex 0 #paths 2 peer 0x0, resolved prefix fe80::/64 > 2025/03/20 22:43:51.703525 BGP: [VWC2R-4REXZ] leak_update_nexthop_valid: 2001:1::/64 nexthop is valid (in VRF vrf10) > 2025/03/20 22:43:51.703526 BGP: [HX87B-ZXWX9] leak_update: ->VRF default: 2001:1::/64: Found route, no change Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
91 lines
3.1 KiB
C
91 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,
|
|
struct bgp_path_info *source_pi);
|
|
|
|
/**
|
|
* 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 */
|