summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2022-04-26 16:57:45 +0200
committerLouis Scalbert <louis.scalbert@6wind.com>2024-02-14 16:39:51 +0100
commitb45c5cd959ecf859aa11673ab83d169b76988ba2 (patch)
tree896ad07922337b8c4edafeb0999104de6fd870a4
parenttests: use check_ping in bgp_vrf_route_leak_basic (diff)
downloadfrr-b45c5cd959ecf859aa11673ab83d169b76988ba2.tar.xz
frr-b45c5cd959ecf859aa11673ab83d169b76988ba2.zip
bgpd: update route leak when vrf state changes
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 <louis.scalbert@6wind.com>
-rw-r--r--bgpd/bgp_attr.c12
-rw-r--r--bgpd/bgp_attr.h1
-rw-r--r--bgpd/bgp_mplsvpn.c12
-rw-r--r--bgpd/bgp_route.c6
-rw-r--r--bgpd/bgp_zebra.c16
5 files changed, 46 insertions, 1 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index edfbc6c83..0dec8ea4e 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -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:
@@ -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) {
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index d78f04c6d..4b6270408 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -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;
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index cd5cf5be5..91bc3b1a8 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -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)) {
@@ -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
*/
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f0c5de074..b6a000b13 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -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)
@@ -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;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 1172514e5..54b792af2 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -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;
}
@@ -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;
}