diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index e21a08c268..a8ee14c72e 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1283,8 +1283,14 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0; attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0; - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL); - bgpevpn_get_rmac(vpn, &attr.rmac); + + /* PMSI is only needed for type-3 routes */ + if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL); + + /* router mac is only needed for type-2 and type-5 routes */ + if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) + bgpevpn_get_rmac(vpn, &attr.rmac); vni2label(vpn->vni, &(attr.label)); /* Set up RT and ENCAP extended community. */ diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 1dbc1f25f0..5d59ed5ae6 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -64,6 +64,8 @@ struct bgpevpn { #define VNI_FLAG_USE_TWO_LABELS 0x20 /* Attach both L2-VNI and L3-VNI if needed for this VPN */ + struct bgp *bgp_vrf; /* back pointer to the vrf instance */ + /* Flag to indicate if we are advertising the g/w mac ip for this VNI*/ u_int8_t advertise_gw_macip; @@ -134,77 +136,66 @@ static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf, static inline vni_t bgpevpn_get_l3vni(struct bgpevpn *vpn) { - struct bgp *bgp_vrf = NULL; - - bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); - if (!bgp_vrf) - return 0; - - return bgp_vrf->l3vni; + return vpn->bgp_vrf ? vpn->bgp_vrf->l3vni : 0; } static inline void bgpevpn_get_rmac(struct bgpevpn *vpn, struct ethaddr *rmac) { - struct bgp *bgp_vrf = NULL; - memset(rmac, 0, sizeof(struct ethaddr)); - bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); - if (!bgp_vrf) + if (!vpn->bgp_vrf) return; - memcpy(rmac, &bgp_vrf->rmac, sizeof(struct ethaddr)); + memcpy(rmac, &vpn->bgp_vrf->rmac, sizeof(struct ethaddr)); } static inline struct list *bgpevpn_get_vrf_export_rtl(struct bgpevpn *vpn) { - struct bgp *bgp_vrf = NULL; - - bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); - if (!bgp_vrf) + if (!vpn->bgp_vrf) return NULL; - return bgp_vrf->vrf_export_rtl; + return vpn->bgp_vrf->vrf_export_rtl; } static inline struct list *bgpevpn_get_vrf_import_rtl(struct bgpevpn *vpn) { - struct bgp *bgp_vrf = NULL; - - bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); - if (!bgp_vrf) + if (!vpn->bgp_vrf) return NULL; - return bgp_vrf->vrf_import_rtl; + return vpn->bgp_vrf->vrf_import_rtl; } static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn) { - struct bgp *bgp_vrf = NULL; - - bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); - if (!bgp_vrf) + /* bail if vpn is not associated to bgp_vrf */ + if (!vpn->bgp_vrf) return; - + UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); - - if (bgp_vrf->l2vnis) - listnode_delete(bgp_vrf->l2vnis, vpn); + listnode_delete(vpn->bgp_vrf->l2vnis, vpn); + + /* remove the backpointer to the vrf instance */ + vpn->bgp_vrf = NULL; } static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn) { struct bgp *bgp_vrf = NULL; + /* bail if vpn is already associated to vrf */ + if (vpn->bgp_vrf) + return; + bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); if (!bgp_vrf) return; + /* associate the vpn to the bgp_vrf instance */ + vpn->bgp_vrf = bgp_vrf; + listnode_add_sort(bgp_vrf->l2vnis, vpn); + /* check if we are advertising two labels for this vpn */ if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); - - if (bgp_vrf->l2vnis) - listnode_add_sort(bgp_vrf->l2vnis, vpn); } static inline int is_vni_configured(struct bgpevpn *vpn) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 58c72bf36f..f519bb463b 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -491,53 +491,6 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) json_object_object_add(json, "exportRts", json_export_rtl); } -static void evpn_show_vrf_routes(struct vty *vty, - struct bgp *bgp_vrf) -{ - struct bgp *bgp_def = NULL; - struct bgp_node *rn; - struct bgp_info *ri; - int header = 1; - u_int32_t prefix_cnt, path_cnt; - struct bgp_table *table; - - prefix_cnt = path_cnt = 0; - bgp_def = bgp_get_default(); - if (!bgp_def) - return; - - table = (struct bgp_table *)bgp_vrf->rib[AFI_L2VPN][SAFI_EVPN]; - for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { - char prefix_str[BUFSIZ]; - - bgp_evpn_route2str((struct prefix_evpn *)&rn->p, prefix_str, - sizeof(prefix_str)); - - if (rn->info) { - /* Overall header/legend displayed once. */ - if (header) { - bgp_evpn_show_route_header(vty, bgp_def, NULL); - header = 0; - } - prefix_cnt++; - } - - /* For EVPN, the prefix is displayed for each path (to fit in - * with code that already exists). - */ - for (ri = rn->info; ri; ri = ri->next) { - route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN, NULL); - path_cnt++; - } - } - - if (prefix_cnt == 0) - vty_out(vty, "No EVPN prefixes exist for this VRF"); - else - vty_out(vty, "\nDisplayed %u prefixes (%u paths)", - prefix_cnt, path_cnt); -} - static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type, struct vty *vty, struct in_addr vtep_ip, json_object *json) @@ -2967,16 +2920,23 @@ DEFUN(show_bgp_l2vpn_evpn_vni, */ DEFUN(show_bgp_l2vpn_evpn_summary, show_bgp_l2vpn_evpn_summary_cmd, - "show bgp l2vpn evpn summary [json]", + "show bgp [vrf VRFNAME] l2vpn evpn summary [json]", SHOW_STR BGP_STR + "bgp vrf\n" + "vrf name\n" L2VPN_HELP_STR EVPN_HELP_STR "Summary of BGP neighbor status\n" JSON_STR) { + int idx_vrf = 0; u_char uj = use_json(argc, argv); - return bgp_show_summary_vty(vty, NULL, AFI_L2VPN, SAFI_EVPN, uj); + char *vrf = NULL; + + if (argv_find(argv, argc, "vrf", &idx_vrf)) + vrf = argv[++idx_vrf]->arg; + return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN, uj); } /* @@ -3183,33 +3143,6 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip, return CMD_SUCCESS; } -/* - * Display per-VRF EVPN routing table. - */ -DEFUN(show_bgp_l2vpn_evpn_route_vrf, show_bgp_l2vpn_evpn_route_vrf_cmd, - "show bgp l2vpn evpn route vrf VRFNAME", - SHOW_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "EVPN route information\n" - "VRF\n" - "VRF Name\n") -{ - int vrf_idx = 6; - char *vrf_name = NULL; - struct bgp *bgp_vrf = NULL; - - vrf_name = argv[vrf_idx]->arg; - bgp_vrf = bgp_lookup_by_name(vrf_name); - if (!bgp_vrf) - return CMD_WARNING; - - evpn_show_vrf_routes(vty, bgp_vrf); - - return CMD_SUCCESS; -} - /* * Display per-VNI EVPN routing table. */ @@ -4377,6 +4310,8 @@ DEFUN (no_bgp_evpn_vni_rt_without_val, void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi) { + char buf1[RD_ADDRSTRLEN]; + if (bgp->vnihash) hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *, @@ -4394,6 +4329,42 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi, if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) vty_out(vty, " advertise ipv6 unicast\n"); + + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD)) + vty_out(vty, " rd %s\n", + prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1))); + + /* import route-target */ + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) { + char *ecom_str; + struct listnode *node, *nnode; + struct ecommunity *ecom; + + for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode, + ecom)) { + ecom_str = ecommunity_ecom2str( + ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, " route-target import %s\n", + ecom_str); + XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); + } + } + + /* export route-target */ + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) { + char *ecom_str; + struct listnode *node, *nnode; + struct ecommunity *ecom; + + for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode, + ecom)) { + ecom_str = ecommunity_ecom2str( + ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, " route-target export %s\n", + ecom_str); + XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); + } + } } void bgp_ethernetvpn_init(void) @@ -4431,7 +4402,6 @@ void bgp_ethernetvpn_init(void) install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_rd_cmd); install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_rd_macip_cmd); install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_cmd); - install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vrf_cmd); install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_multicast_cmd); install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_macip_cmd); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index c7140b2f1f..15cc5673ac 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7278,8 +7278,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, safi = SAFI_MAX; } afi++; - if (!afi_wildcard - || afi == AFI_L2VPN) /* special case, not handled yet */ + if (!afi_wildcard) afi = AFI_MAX; } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 63eff81145..c06339aad9 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7400,38 +7400,6 @@ int bgp_config_write(struct vty *vty) if (bgp_option_check(BGP_OPT_CONFIG_CISCO)) vty_out(vty, " no auto-summary\n"); - /* import route-target */ - if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) { - char *ecom_str; - struct listnode *node, *nnode; - struct ecommunity *ecom; - - for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode, - ecom)) { - ecom_str = ecommunity_ecom2str( - ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out(vty, " route-target import %s\n", - ecom_str); - XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); - } - } - - /* export route-target */ - if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) { - char *ecom_str; - struct listnode *node, *nnode; - struct ecommunity *ecom; - - for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode, - ecom)) { - ecom_str = ecommunity_ecom2str( - ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out(vty, " route-target export %s\n", - ecom_str); - XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); - } - } - /* IPv4 unicast configuration. */ bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);