]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: update route leak when vrf state changes
authorLouis Scalbert <louis.scalbert@6wind.com>
Tue, 26 Apr 2022 14:57:45 +0000 (16:57 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Wed, 14 Feb 2024 15:39:51 +0000 (16:39 +0100)
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>
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_mplsvpn.c
bgpd/bgp_route.c
bgpd/bgp_zebra.c

index edfbc6c8352b5b9a5e79b27c200aaf01bad956a2..0dec8ea4e4c915de0cb802f52e8050178a0652f6 100644 (file)
@@ -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) {
index d78f04c6dd8cc242b361eed3e08ca680f0587c1b..4b6270408e4e1879511bb9bdaa35ce0cea184696 100644 (file)
@@ -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;
index cd5cf5be548668aa2f1f3a535a5e4cedbff25043..91bc3b1a888e79c235cadfaada9bc118b3ac9c72 100644 (file)
@@ -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
         */
index f0c5de074d66240692a5f58bbab6eabd37ba7be5..b6a000b13810fa167d3aee93df248ec48c5aa9ff 100644 (file)
@@ -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;
index 1172514e52615dcf3a0846a408b8ae990d93e9de..54b792af29d9e172349bc680dfba8a67d922d09c 100644 (file)
@@ -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;
 }