From 71d08ecc9d2a43997fe92193c3bd1d1203fa6954 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Fri, 22 Sep 2023 17:19:09 -0700 Subject: [PATCH 1/2] bgpd: aggr summary-only suppressed export to evpn When exporting bgp vrf instance unicast route into EVPN as type-5, check for suppressed ones and do not export them. Ticket:#3534718 Testing Done: Config: router bgp 660000 vrf vrf1 bgp router-id 144.1.1.2 no bgp network import-check neighbor 144.1.1.1 remote-as external ! address-family ipv4 unicast aggregate-address 50.1.0.0/16 summary-only redistribute connected exit-address-family ! address-family l2vpn evpn advertise ipv4 unicast exit-address-family exit v4 suppressed route: (5 suppressed routes not exported to evpn) tor1# vtysh -c "show bgp vrf vrf1 ipv4 unicast" | grep "50.1" *> 50.1.0.0/16 0.0.0.0(bordertor-11) s> 50.1.1.212/32 6.0.0.30(leaf-11)< s> 50.1.1.222/32 6.0.0.31(leaf-11)< s> 50.1.110.0/24 0.0.0.0(bordertor-11) s> 50.1.210.214/32 6.0.0.30(leaf-11)< s> 50.1.220.224/32 6.0.0.31(leaf-11)< tor1# vtysh -c "show bgp l2vpn evpn route" | grep -A3 "*> \[5\].*\[50.1" *> [5]:[0]:[16]:[50.1.0.0] RD 144.1.1.2:7 6.0.0.1 (bordertor-11) 0 32768 ? ET:8 RT:4640:104001 Rmac:00:02:00:00:00:04 Signed-off-by: Chirag Shah --- bgpd/bgp_evpn.c | 33 +++++++++++++++++++++++++++++++++ bgpd/bgp_evpn.h | 26 +------------------------- bgpd/bgp_route.c | 2 +- bgpd/bgp_route.h | 1 + 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index faafab850501..f141fcee6a08 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -311,6 +311,39 @@ static int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn) return 0; } +/* Flag if the route is injectable into EVPN. + * This would be following category: + * Non-imported route, + * Non-EVPN imported route, + * Non Aggregate suppressed route. + */ +bool is_route_injectable_into_evpn(struct bgp_path_info *pi) +{ + struct bgp_path_info *parent_pi; + struct bgp_table *table; + struct bgp_dest *dest; + + /* do not import aggr suppressed routes */ + if (bgp_path_suppressed(pi)) + return false; + + if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra || + !pi->extra->vrfleak || !pi->extra->vrfleak->parent) + return true; + + parent_pi = (struct bgp_path_info *)pi->extra->vrfleak->parent; + dest = parent_pi->net; + if (!dest) + return true; + table = bgp_dest_table(dest); + if (table && + table->afi == AFI_L2VPN && + table->safi == SAFI_EVPN) + return false; + + return true; +} + /* * Compare Route Targets. */ diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 55474464e593..840389758723 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -94,31 +94,6 @@ static inline bool is_pi_family_evpn(struct bgp_path_info *pi) return is_pi_family_matching(pi, AFI_L2VPN, SAFI_EVPN); } -/* Flag if the route is injectable into EVPN. This would be either a - * non-imported route or a non-EVPN imported route. - */ -static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi) -{ - struct bgp_path_info *parent_pi; - struct bgp_table *table; - struct bgp_dest *dest; - - if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra || - !pi->extra->vrfleak || !pi->extra->vrfleak->parent) - return true; - - parent_pi = (struct bgp_path_info *)pi->extra->vrfleak->parent; - dest = parent_pi->net; - if (!dest) - return true; - table = bgp_dest_table(dest); - if (table && - table->afi == AFI_L2VPN && - table->safi == SAFI_EVPN) - return false; - return true; -} - static inline bool evpn_resolve_overlay_index(void) { struct bgp *bgp = NULL; @@ -206,5 +181,6 @@ extern mpls_label_t *bgp_evpn_path_info_labels_get_l3vni(mpls_label_t *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); +extern bool is_route_injectable_into_evpn(struct bgp_path_info *pi); #endif /* _QUAGGA_BGP_EVPN_H */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 193d9fe4f918..9283055d9de0 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -120,7 +120,7 @@ DEFINE_HOOK(bgp_process, (bgp, afi, safi, bn, peer, withdraw)); /** Test if path is suppressed. */ -static bool bgp_path_suppressed(struct bgp_path_info *pi) +bool bgp_path_suppressed(struct bgp_path_info *pi) { if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL) return false; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3057a4259abe..ad0cc9eabca3 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -914,6 +914,7 @@ extern void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, extern void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr); const char * bgp_path_selection_reason2str(enum bgp_path_selection_reason reason); +extern bool bgp_path_suppressed(struct bgp_path_info *pi); extern bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi); extern const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest, safi_t safi); From ac30911160c6dd5556dd42133760a0c60b897569 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 7 Sep 2023 15:51:32 -0700 Subject: [PATCH 2/2] bgpd: lttng tp add evpn route events Ticket:#3597393 Testing Done: 2023-09-08T22:53:03.532 frr_bgp:evpn_withdraw_type5 {'vrf_id': 42, 'ip': '53.1.1.0'} 2023-09-08T22:53:06.207 frr_bgp:evpn_advertise_type5 {'vrf_id': 42, 'ip': '53.1.1.0', 'rmac': '00:02:00:00:00:38', 'vtep': '27.0.0.15'} 2023-09-08T21:51:15.637 frr_bgp:evpn_mh_local_ead_es_evi_route_upd {'esi': '03:44:38:39:ff:ff:01:00:00:03', 'vni': 1000, 'route_type': 1, 'vtep': '27.0.0.15'} 2023-09-08T20:45:17.059 frr_bgp:evpn_mh_local_ead_es_evi_route_del {'esi': '03:44:38:39:ff:ff:01:00:00:01', 'vni': 0, 'route_type': 4, 'vtep': '27.0.0.15'} 2023-09-08T21:51:18.363 frr_bgp:evpn_mh_es_evi_vtep_add {'esi': '03:44:38:39:ff:ff:01:00:00:02', 'vni': 1000, 'vtep': '27.0.0.16', 'ead_es': 1} 2023-09-08T20:43:50.206 frr_bgp:evpn_mh_es_evi_vtep_del {'esi': '03:44:38:39:ff:ff:01:00:00:01', 'vni': 1002, 'vtep': '27.0.0.16', 'ead_es': 0} Signed-off-by: Chirag Shah --- bgpd/bgp_evpn.c | 5 +++ bgpd/bgp_evpn_mh.c | 14 +++++++ bgpd/bgp_trace.h | 86 +++++++++++++++++++++++++++++++++++++++++ tools/frr_babeltrace.py | 70 +++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index f141fcee6a08..49f24ee7be44 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1671,6 +1671,9 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, vrf_id_to_name(bgp_vrf->vrf_id), evp, &attr.rmac, &attr.nexthop); + frrtrace(4, frr_bgp, evpn_advertise_type5, bgp_vrf->vrf_id, evp, + &attr.rmac, attr.nexthop); + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; if (src_afi == AFI_IP6 && @@ -2313,6 +2316,8 @@ static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) if (!dest) return 0; + frrtrace(2, frr_bgp, evpn_withdraw_type5, bgp_vrf->vrf_id, evp); + delete_evpn_route_entry(bgp_evpn, afi, safi, dest, &pi); if (pi) bgp_process(bgp_evpn, dest, afi, safi); diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index ffb1b17ec7f7..a71231090509 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -441,6 +441,10 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, ? "esr" : (vpn ? "ead-evi" : "ead-es"), &attr->mp_nexthop_global_in); + + frrtrace(4, frr_bgp, evpn_mh_local_ead_es_evi_route_upd, + &es->esi, (vpn ? vpn->vni : 0), evp->prefix.route_type, + attr->mp_nexthop_global_in); } /* Return back the route entry. */ @@ -491,6 +495,8 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es, : (vpn ? "ead-evi" : "ead-es"), &es->originator_ip); + frrtrace(4, frr_bgp, evpn_mh_local_ead_es_evi_route_del, &es->esi, + (vpn ? vpn->vni : 0), p->prefix.route_type, es->originator_ip); /* Next, locate route node in the global EVPN routing table. * Note that this table is a 2-level tree (RD-level + Prefix-level) */ @@ -3460,6 +3466,10 @@ static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp, evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip, ead_es ? "ead_es" : "ead_evi"); + frrtrace(4, frr_bgp, evpn_mh_es_evi_vtep_add, + &evi_vtep->es_evi->es->esi, evi_vtep->es_evi->vpn->vni, + evi_vtep->vtep_ip, ead_es); + if (ead_es) SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_ES); else @@ -3484,6 +3494,10 @@ static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp, evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip, ead_es ? "ead_es" : "ead_evi"); + frrtrace(4, frr_bgp, evpn_mh_es_evi_vtep_del, + &evi_vtep->es_evi->es->esi, evi_vtep->es_evi->vpn->vni, + evi_vtep->vtep_ip, ead_es); + if (ead_es) UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_ES); else diff --git a/bgpd/bgp_trace.h b/bgpd/bgp_trace.h index 8274802a7338..5a80a53f61c1 100644 --- a/bgpd/bgp_trace.h +++ b/bgpd/bgp_trace.h @@ -435,6 +435,64 @@ TRACEPOINT_EVENT( ) TRACEPOINT_LOGLEVEL(frr_bgp, evpn_mh_local_es_evi_del_zrecv, TRACE_INFO) +TRACEPOINT_EVENT( + frr_bgp, + evpn_mh_es_evi_vtep_add, + TP_ARGS(esi_t *, esi, vni_t, vni, struct in_addr, vtep, + uint8_t, ead_es), + TP_FIELDS( + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + ctf_integer(vni_t, vni, vni) + ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) + ctf_integer(uint8_t, ead_es, ead_es) + ) +) +TRACEPOINT_LOGLEVEL(frr_bgp, evpn_mh_es_evi_vtep_add, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + evpn_mh_es_evi_vtep_del, + TP_ARGS(esi_t *, esi, vni_t, vni, struct in_addr, vtep, + uint8_t, ead_es), + TP_FIELDS( + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + ctf_integer(vni_t, vni, vni) + ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) + ctf_integer(uint8_t, ead_es, ead_es) + ) +) +TRACEPOINT_LOGLEVEL(frr_bgp, evpn_mh_es_evi_vtep_del, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + evpn_mh_local_ead_es_evi_route_upd, + TP_ARGS(esi_t *, esi, vni_t, vni, + uint8_t, route_type, + struct in_addr, vtep), + TP_FIELDS( + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + ctf_integer(vni_t, vni, vni) + ctf_integer(uint8_t, route_type, route_type) + ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) + ) +) +TRACEPOINT_LOGLEVEL(frr_bgp, evpn_mh_local_ead_es_evi_route_upd, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + evpn_mh_local_ead_es_evi_route_del, + TP_ARGS(esi_t *, esi, vni_t, vni, + uint8_t, route_type, + struct in_addr, vtep), + TP_FIELDS( + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + ctf_integer(vni_t, vni, vni) + ctf_integer(uint8_t, route_type, route_type) + ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) + ) +) +TRACEPOINT_LOGLEVEL(frr_bgp, evpn_mh_local_ead_es_evi_route_del, TRACE_INFO) + TRACEPOINT_EVENT( frr_bgp, evpn_local_vni_add_zrecv, @@ -495,6 +553,34 @@ TRACEPOINT_EVENT( ) TRACEPOINT_LOGLEVEL(frr_bgp, evpn_local_macip_del_zrecv, TRACE_INFO) +TRACEPOINT_EVENT( + frr_bgp, + evpn_advertise_type5, + TP_ARGS(vrf_id_t, vrf, const struct prefix_evpn *, pfx, + struct ethaddr *, rmac, struct in_addr, vtep), + TP_FIELDS( + ctf_integer(int, vrf_id, vrf) + ctf_array(unsigned char, ip, &pfx->prefix.prefix_addr.ip, + sizeof(struct ipaddr)) + ctf_array(unsigned char, rmac, rmac, + sizeof(struct ethaddr)) + ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) + ) +) +TRACEPOINT_LOGLEVEL(frr_bgp, evpn_advertise_type5, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + evpn_withdraw_type5, + TP_ARGS(vrf_id_t, vrf, const struct prefix_evpn *, pfx), + TP_FIELDS( + ctf_integer(int, vrf_id, vrf) + ctf_array(unsigned char, ip, &pfx->prefix.prefix_addr.ip, + sizeof(struct ipaddr)) + ) +) +TRACEPOINT_LOGLEVEL(frr_bgp, evpn_withdraw_type5, TRACE_INFO) + TRACEPOINT_EVENT( frr_bgp, evpn_local_l3vni_add_zrecv, diff --git a/tools/frr_babeltrace.py b/tools/frr_babeltrace.py index 4d974ad356f8..9832568b3736 100755 --- a/tools/frr_babeltrace.py +++ b/tools/frr_babeltrace.py @@ -157,6 +157,46 @@ def parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv(event): parse_event(event, field_parsers) +def parse_frr_bgp_evpn_mh_es_evi_vtep_add(event): + """ + bgp evpn remote ead evi remote vtep add; raw format - + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + """ + field_parsers = {"esi": print_esi, + "vtep": print_net_ipv4_addr} + + parse_event(event, field_parsers) + +def parse_frr_bgp_evpn_mh_es_evi_vtep_del(event): + """ + bgp evpn remote ead evi remote vtep del; raw format - + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + """ + field_parsers = {"esi": print_esi, + "vtep": print_net_ipv4_addr} + + parse_event(event, field_parsers) + +def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_upd(event): + """ + bgp evpn local ead evi vtep; raw format - + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + """ + field_parsers = {"esi": print_esi, + "vtep": print_net_ipv4_addr} + + parse_event(event, field_parsers) + +def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_del(event): + """ + bgp evpn local ead evi vtep del; raw format - + ctf_array(unsigned char, esi, esi, sizeof(esi_t)) + """ + field_parsers = {"esi": print_esi, + "vtep": print_net_ipv4_addr} + + parse_event(event, field_parsers) + def parse_frr_bgp_evpn_local_vni_add_zrecv(event): """ bgp evpn local-vni parser; raw format - @@ -205,6 +245,24 @@ def parse_frr_bgp_evpn_local_macip_del_zrecv(event): parse_event(event, field_parsers) +def parse_frr_bgp_evpn_advertise_type5(event): + """ + local originated type-5 route + """ + field_parsers = {"ip": print_ip_addr, + "rmac": print_mac, + "vtep": print_net_ipv4_addr} + + parse_event(event, field_parsers) + +def parse_frr_bgp_evpn_withdraw_type5(event): + """ + local originated type-5 route withdraw + """ + field_parsers = {"ip": print_ip_addr} + + parse_event(event, field_parsers) + ############################ evpn parsers - end *############################# def main(): @@ -225,6 +283,14 @@ def main(): parse_frr_bgp_evpn_mh_local_es_evi_add_zrecv, "frr_bgp:evpn_mh_local_es_evi_del_zrecv": parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv, + "frr_bgp:evpn_mh_es_evi_vtep_add": + parse_frr_bgp_evpn_mh_es_evi_vtep_add, + "frr_bgp:evpn_mh_es_evi_vtep_del": + parse_frr_bgp_evpn_mh_es_evi_vtep_del, + "frr_bgp:evpn_mh_local_ead_es_evi_route_upd": + parse_frr_bgp_evpn_mh_local_ead_es_evi_route_upd, + "frr_bgp:evpn_mh_local_ead_es_evi_route_del": + parse_frr_bgp_evpn_mh_local_ead_es_evi_route_del, "frr_bgp:evpn_local_vni_add_zrecv": parse_frr_bgp_evpn_local_vni_add_zrecv, "frr_bgp:evpn_local_l3vni_add_zrecv": @@ -233,6 +299,10 @@ def main(): parse_frr_bgp_evpn_local_macip_add_zrecv, "frr_bgp:evpn_local_macip_del_zrecv": parse_frr_bgp_evpn_local_macip_del_zrecv, + "frr_bgp:evpn_advertise_type5": + parse_frr_bgp_evpn_advertise_type5, + "frr_bgp:evpn_withdraw_type5": + parse_frr_bgp_evpn_withdraw_type5, } # get the trace path from the first command line argument