Skip to content

Commit

Permalink
bgpd: update route leak when vrf state changes
Browse files Browse the repository at this point in the history
Locally leaked routes remain active after the nexthop VRF interface goes
down.

Update route leaking when the loopback or a VRF interface state change is
received from zebra.

Signed-off-by: Louis Scalbert <[email protected]>
  • Loading branch information
louis-6wind committed Feb 14, 2024
1 parent c102add commit b45c5cd
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 1 deletion.
12 changes: 12 additions & 0 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2347,6 +2347,12 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
return BGP_ATTR_PARSE_WITHDRAW;
}
attr->nh_ifindex = peer->nexthop.ifp->ifindex;
if (if_is_operative(peer->nexthop.ifp))
SET_FLAG(attr->nh_flags,
BGP_ATTR_NH_IF_OPERSTATE);
else
UNSET_FLAG(attr->nh_flags,
BGP_ATTR_NH_IF_OPERSTATE);
}
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
Expand All @@ -2364,6 +2370,12 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
return BGP_ATTR_PARSE_WITHDRAW;
}
attr->nh_ifindex = peer->nexthop.ifp->ifindex;
if (if_is_operative(peer->nexthop.ifp))
SET_FLAG(attr->nh_flags,
BGP_ATTR_NH_IF_OPERSTATE);
else
UNSET_FLAG(attr->nh_flags,
BGP_ATTR_NH_IF_OPERSTATE);
}
if (attr->mp_nexthop_len
== BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ struct attr {
uint8_t nh_flags;

#define BGP_ATTR_NH_VALID 0x01
#define BGP_ATTR_NH_IF_OPERSTATE 0x02

/* Path origin attribute */
uint8_t origin;
Expand Down
12 changes: 11 additions & 1 deletion bgpd/bgp_mplsvpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2093,8 +2093,9 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
struct bgp_path_info *bpi;
int origin_local = 0;
struct bgp *src_vrf;
struct interface *ifp;
struct interface *ifp = NULL;
char rd_buf[RD_ADDRSTRLEN];

int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);

if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
Expand Down Expand Up @@ -2260,6 +2261,15 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
break;
}

if (!ifp && static_attr.nh_ifindex)
ifp = if_lookup_by_index(static_attr.nh_ifindex,
src_vrf->vrf_id);

if (ifp && if_is_operative(ifp))
SET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_IF_OPERSTATE);
else
UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_IF_OPERSTATE);

/*
* route map handling
*/
Expand Down
6 changes: 6 additions & 0 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -8569,6 +8569,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
afi_t afi;
route_map_result_t ret;
struct bgp_redist *red;
struct interface *ifp;

if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
bgp->peer_self == NULL)
Expand Down Expand Up @@ -8628,6 +8629,11 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
}
attr.nh_type = nhtype;
attr.nh_ifindex = ifindex;
ifp = if_lookup_by_index(ifindex, bgp->vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG(attr.nh_flags, BGP_ATTR_NH_IF_OPERSTATE);
else
UNSET_FLAG(attr.nh_flags, BGP_ATTR_NH_IF_OPERSTATE);

attr.med = metric;
attr.distance = distance;
Expand Down
16 changes: 16 additions & 0 deletions bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ static int bgp_ifp_up(struct interface *ifp)
hook_call(bgp_vrf_status_changed, bgp, ifp);
bgp_nht_ifp_up(ifp);

if (bgp_get_default() && if_is_loopback(ifp)) {
vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6);
vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP);
vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP6);
vpn_leak_postchange_all();
}

return 0;
}

Expand Down Expand Up @@ -282,6 +290,14 @@ static int bgp_ifp_down(struct interface *ifp)
hook_call(bgp_vrf_status_changed, bgp, ifp);
bgp_nht_ifp_down(ifp);

if (bgp_get_default() && if_is_loopback(ifp)) {
vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
vpn_leak_zebra_vrf_sid_withdraw(bgp, AFI_IP);
vpn_leak_zebra_vrf_sid_withdraw(bgp, AFI_IP6);
vpn_leak_postchange_all();
}

return 0;
}

Expand Down

0 comments on commit b45c5cd

Please sign in to comment.