Skip to content

Commit

Permalink
bgpd: fix label lost when vrf loopback comes back
Browse files Browse the repository at this point in the history
VRF-label association drops when the VRF loopback goes down, however, it
does not return once the interface is enabled again.

Logs show that when VRF loopback goes down, a label drop message is sent
to zebra and immediately resent label installation to zebra:
2024/07/16 13:26:29 BGP: [RVJ1J-J2T22] ifp down r1-cust1 vrf id 7
2024/07/16 13:26:29 BGP: [WA2QY-06STJ] vpn_leak_zebra_vrf_label_withdraw: deleting label for vrf VRF r1-cust1 (id=7)
2024/07/16 13:26:30 BGP: [S82AC-6YAC8] vpn_leak_zebra_vrf_label_update: vrf VRF r1-cust1: afi IPv4: setting label 80 for vrf id 7

Since the interface is down, the netlink message is not send to kernel.
Once the interface comes back, zebra ignore the installation assuming
the label is already seen.

To fix this, add a check for the interface status before attempting to
reinstall the label.

Signed-off-by: Loïc Sang <[email protected]>
  • Loading branch information
Loïc Sang committed Jul 16, 2024
1 parent cc3519f commit cc31751
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
10 changes: 8 additions & 2 deletions bgpd/bgp_mplsvpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,16 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
*
* Sending this vrf-label association is qualified by a) whether vrf->vpn
* exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
* are set) and b) whether vpn-policy label is set.
* are set), b) whether vpn-policy label is set and c) the vrf loopback
* interface is up.
*
* If any of these conditions do not hold, then we send MPLS_LABEL_NONE
* for this vrf, which zebra interprets to mean "delete this vrf-label
* association."
*/
void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
{
const char *debugmsg = NULL;
mpls_label_t label = MPLS_LABEL_NONE;
int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);

Expand All @@ -300,11 +302,15 @@ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
return;
}

if (vpn_leak_to_vpn_active(bgp, afi, NULL, false)) {
if (vpn_leak_to_vpn_active(bgp, afi, &debugmsg, false)) {
label = bgp->vpn_policy[afi].tovpn_label;
}

if (debug) {
if (debugmsg)
zlog_debug("%s: vrf %s: afi %s: label %u not updated, %s",
__func__, bgp->name_pretty, afi2str(afi),
bgp->vpn_policy[afi].tovpn_label, debugmsg);
zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
__func__, bgp->name_pretty, afi2str(afi), label,
bgp->vrf_id);
Expand Down
15 changes: 15 additions & 0 deletions bgpd/bgp_mplsvpn.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
const char **pmsg,
bool ignore_export_rt_list)
{
struct interface *ifp;

if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
&& bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {

Expand All @@ -124,6 +126,19 @@ static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
return 0;
}

ifp = if_get_vrf_loopback(bgp_vrf->vrf_id);
/* should not happen */
if (!ifp) {
if (pmsg)
*pmsg = "loopback interface not defined";
return 0;
}
if (!if_is_up(ifp)) {
if (pmsg)
*pmsg = "loopback interface is down";
return 0;
}

/* Is vrf configured to export to vpn? */
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
Expand Down

0 comments on commit cc31751

Please sign in to comment.