]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_mplsvpn.h
bgpd: fix the IGP metric for best path selection on VPN import
[mirror_frr.git] / bgpd / bgp_mplsvpn.h
index fcabb164354a758226dc700a715af98f75b25871..7b57e4c75d1064cedeb2bb5a2ffa32d69d2bed10 100644 (file)
@@ -25,6 +25,7 @@
 #include "bgpd/bgp_route.h"
 #include "bgpd/bgp_rd.h"
 #include "bgpd/bgp_zebra.h"
+#include "bgpd/bgp_vty.h"
 
 #define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
 #define MPLS_LABEL_IS_NULL(label)                                              \
@@ -32,9 +33,7 @@
         || (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL                           \
         || (label) == MPLS_LABEL_IMPLICIT_NULL)
 
-#define BGP_VPNVX_HELP_STR                                                     \
-       "Address Family\n"                                                     \
-       "Address Family\n"
+#define BGP_VPNVX_HELP_STR BGP_AF_STR BGP_AF_STR
 
 #define V4_HEADER                                                              \
        "   Network          Next Hop            Metric LocPrf Weight Path\n"
@@ -42,6 +41,8 @@
 #define V4_HEADER_OVERLAY                                                      \
        "   Network          Next Hop      EthTag    Overlay Index   RouterMac\n"
 
+#define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH 20
+
 extern void bgp_mplsvpn_init(void);
 extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
 extern uint32_t decode_label(mpls_label_t *);
@@ -70,8 +71,9 @@ extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
 extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
                                       afi_t afi);
 
-extern void vpn_leak_to_vrf_update(struct bgp *from_bgp,
-                                  struct bgp_path_info *path_vpn);
+extern bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
+                                  struct bgp_path_info *path_vpn,
+                                  struct prefix_rd *prd);
 
 extern void vpn_leak_to_vrf_withdraw(struct bgp *from_bgp,
                                     struct bgp_path_info *path_vpn);
@@ -79,9 +81,20 @@ extern void vpn_leak_to_vrf_withdraw(struct bgp *from_bgp,
 extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
 extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
 extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
+extern void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi);
+extern void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp);
 extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
+extern void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi);
+extern void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp);
 extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
 extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
+extern void delete_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
+extern void delete_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
+                                       afi_t afi);
+extern void delete_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
+extern void ensure_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
+                                       afi_t afi);
+extern void ensure_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
 extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
                          uint8_t size);
 extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
@@ -233,8 +246,14 @@ static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
        if (!bgp_vpn)
                return;
 
-       if (direction == BGP_VPN_POLICY_DIR_FROMVPN)
-               vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
+       if (direction == BGP_VPN_POLICY_DIR_FROMVPN) {
+               /* trigger a flush to re-sync with ADJ-RIB-in */
+               if (!CHECK_FLAG(bgp_vpn->af_flags[afi][SAFI_MPLS_VPN],
+                               BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL))
+                       bgp_clear_soft_in(bgp_vpn, afi, SAFI_MPLS_VPN);
+               else
+                       vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
+       }
        if (direction == BGP_VPN_POLICY_DIR_TOVPN) {
 
                if (bgp_vrf->vpn_policy[afi].tovpn_label !=
@@ -243,17 +262,33 @@ static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
                        vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
                }
 
-               if (!bgp_vrf->vpn_policy[afi].tovpn_sid)
+               if (bgp_vrf->vpn_policy[afi].tovpn_sid_index == 0 &&
+                   !CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
+                               BGP_VPN_POLICY_TOVPN_SID_AUTO) &&
+                   bgp_vrf->tovpn_sid_index == 0 &&
+                   !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
+                       delete_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
+
+               if (!bgp_vrf->vpn_policy[afi].tovpn_sid && !bgp_vrf->tovpn_sid)
                        ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
 
-               if (!bgp_vrf->vpn_policy[afi].tovpn_sid
-                   && bgp_vrf->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent)
+               if ((!bgp_vrf->vpn_policy[afi].tovpn_sid &&
+                    bgp_vrf->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent) ||
+                   (!bgp_vrf->tovpn_sid &&
+                    bgp_vrf->tovpn_zebra_vrf_sid_last_sent))
                        vpn_leak_zebra_vrf_sid_withdraw(bgp_vrf, afi);
 
-               if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
-                            bgp_vrf->vpn_policy[afi]
-                                    .tovpn_zebra_vrf_sid_last_sent)) {
-                       vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
+               if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
+                       if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
+                                    bgp_vrf->vpn_policy[afi]
+                                            .tovpn_zebra_vrf_sid_last_sent)) {
+                               vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
+                       }
+               } else if (bgp_vrf->tovpn_sid) {
+                       if (sid_diff(bgp_vrf->tovpn_sid,
+                                    bgp_vrf->tovpn_zebra_vrf_sid_last_sent)) {
+                               vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
+                       }
                }
 
                vpn_leak_from_vrf_update_all(bgp_vpn, bgp_vrf, afi);