#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) \
|| (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"
#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 *);
enum bgp_show_type type, void *output_arg,
int tags, bool use_json);
-extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
+extern void vpn_leak_from_vrf_update(struct bgp *to_bgp, struct bgp *from_bgp,
struct bgp_path_info *path_vrf);
-extern void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
+extern void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, struct bgp *from_bgp,
struct bgp_path_info *path_vrf);
-extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
- struct bgp *bgp_vrf, afi_t afi);
+extern void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp,
+ struct bgp *from_bgp, afi_t afi);
-extern void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn,
- struct bgp *bgp_vrf, afi_t afi);
+extern void vpn_leak_from_vrf_update_all(struct bgp *to_bgp,
+ struct bgp *from_bgp, afi_t afi);
-extern void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, afi_t afi);
+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 *bgp_vrf, struct bgp *bgp_vpn,
+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 *bgp_vpn,
- 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 *bgp_vpn,
+extern void vpn_leak_to_vrf_withdraw(struct bgp *from_bgp,
struct bgp_path_info *path_vpn);
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,
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 !=
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);