From 742341e1443d8162e44020101bf93d22b11ce549 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Thu, 8 Apr 2021 19:20:53 -0400 Subject: [PATCH] bgpd: add mpath label stack helper functions for dvni Add some bgp_path_info helper functions for getting the correct l3vni label, getting the vni from the label stack, and determinging if the mpath is D-VNI based. Signed-off-by: Stephen Worley --- bgpd/bgp_evpn.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ bgpd/bgp_evpn.h | 5 ++++ bgpd/bgp_zebra.c | 10 +++----- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index d8acbcd19a..5fdf021104 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -55,6 +55,7 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_nht.h" #include "bgpd/bgp_trace.h" +#include "bgpd/bgp_mpath.h" /* * Definitions and external declarations. @@ -7178,3 +7179,66 @@ void bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket, bgp_evpn_remote_ip_hash_destroy(vpn); } + +/* + * Helper function for getting the correct label index for l3vni. + * + * Returns the label with the l3vni of the path's label stack. + * + * L3vni is always last label. Type5 will only + * have one label, Type2 will have two. + * + */ +mpls_label_t *bgp_evpn_path_info_labels_get_l3vni(mpls_label_t *labels, + uint32_t num_labels) +{ + if (!labels) + return NULL; + + if (!num_labels) + return NULL; + + return &labels[num_labels - 1]; +} + +/* + * Returns the l3vni of the path converted from the label stack. + */ +vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi) +{ + if (!pi->extra) + return 0; + + return label2vni(bgp_evpn_path_info_labels_get_l3vni( + pi->extra->label, pi->extra->num_labels)); +} + +/* + * Returns true if the l3vni of any of this path doesn't match vrf's l3vni. + */ +static bool bgp_evpn_path_is_dvni(const struct bgp *bgp_vrf, + const struct bgp_path_info *pi) +{ + vni_t vni = 0; + + vni = bgp_evpn_path_info_get_l3vni(pi); + + if ((vni > 0) && (vni != bgp_vrf->l3vni)) + return true; + + return false; +} + +/* + * Returns true if the l3vni of any of the mpath's doesn't match vrf's l3vni. + */ +bool bgp_evpn_mpath_has_dvni(const struct bgp *bgp_vrf, + struct bgp_path_info *mpinfo) +{ + for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) { + if (bgp_evpn_path_is_dvni(bgp_vrf, mpinfo)) + return true; + } + + return false; +} diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 3c980eb1da..4f95b71b1d 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -208,5 +208,10 @@ bgp_evpn_handle_resolve_overlay_index_set(struct hash_bucket *bucket, extern void bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket, void *arg); +extern mpls_label_t *bgp_evpn_path_info_labels_get_l3vni(mpls_label_t *labels, + uint32_t num_labels); +extern vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi); +extern bool bgp_evpn_mpath_has_dvni(const struct bgp *bgp_vrf, + struct bgp_path_info *mpinfo); #endif /* _QUAGGA_BGP_EVPN_H */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index fc2df44ac6..c1b27688dd 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1523,14 +1523,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; if (is_evpn) { - /* - * L3VNI is always last label. Type5 will only - * have one label, Type2 will have two. - */ - nh_label = labels[num_labels - 1]; + nh_label = *bgp_evpn_path_info_labels_get_l3vni( + labels, num_labels); nh_label_type = ZEBRA_LSP_EVPN; - - } else if (bgp_is_valid_label(&labels[0])) { + } else { mpls_lse_decode(labels[0], &nh_label, &ttl, &exp, &bos); } -- 2.39.5