]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: advertise/withdraw type-5 routes upon user config
authormitesh <mitesh@cumulusnetworks.com>
Fri, 27 Oct 2017 21:15:45 +0000 (14:15 -0700)
committerMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Thu, 14 Dec 2017 18:57:07 +0000 (10:57 -0800)
CLI config for enabling/disabling type-5 routes

router bgp <as> vrf <vrf>
  address-family l2vpn evpn
    [no] advertise <ipv4|ipv6|both>

loop through all the routes in VRF instance and advertise/withdraw
all ip routes as type-5 routes in default instance.

Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_evpn_private.h
bgpd/bgp_evpn_vty.c
bgpd/bgp_route.h
bgpd/bgpd.h
lib/prefix.c

index e5d7d369c20d81ea264f3732c420bfbe30684e21..cef8735684615a517d0a633fa89a5748213212b5 100644 (file)
@@ -601,6 +601,52 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
        return zclient_send_message(zclient);
 }
 
+/*
+ * Build extended communities for EVPN prefix route.
+ */
+static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
+                                          struct attr *attr)
+{
+       struct ecommunity ecom_encap;
+       struct ecommunity ecom_rmac;
+       struct ecommunity_val eval;
+       struct ecommunity_val eval_rmac;
+       bgp_encap_types tnl_type;
+       struct listnode *node, *nnode;
+       struct ecommunity *ecom;
+       struct list *vrf_export_rtl = NULL;
+
+       /* Encap */
+       tnl_type = BGP_ENCAP_TYPE_VXLAN;
+       memset(&ecom_encap, 0, sizeof(ecom_encap));
+       encode_encap_extcomm(tnl_type, &eval);
+       ecom_encap.size = 1;
+       ecom_encap.val = (u_int8_t *)eval.val;
+
+       /* Add Encap */
+       attr->ecommunity = ecommunity_dup(&ecom_encap);
+
+       /* Add the export RTs for L3VNI/VRF */
+       vrf_export_rtl = bgp_vrf->vrf_export_rtl;
+       if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
+               for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, ecom))
+                       attr->ecommunity = ecommunity_merge(attr->ecommunity,
+                                                           ecom);
+       }
+
+       /* add the router mac extended community */
+       if (!is_zero_mac(&attr->rmac)) {
+               memset(&ecom_rmac, 0, sizeof(ecom_rmac));
+               encode_rmac_extcomm(&eval_rmac, &attr->rmac);
+               ecom_rmac.size = 1;
+               ecom_rmac.val = (uint8_t *)eval_rmac.val;
+               attr->ecommunity = ecommunity_merge(attr->ecommunity,
+                                                   &ecom_rmac);
+       }
+
+       attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
+}
+
 /*
  * Build extended communities for EVPN route. RT and ENCAP are
  * applicable to all routes.
@@ -907,6 +953,112 @@ static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
        return local_ri->attr->sticky;
 }
 
+static int update_evpn_type5_route_entry(struct bgp *bgp_def,
+                                        struct bgp *bgp_vrf, afi_t afi,
+                                        safi_t safi, struct bgp_node *rn,
+                                        struct attr *attr)
+{
+       struct attr *attr_new = NULL;
+       struct bgp_info *ri = NULL;
+       mpls_label_t label = MPLS_INVALID_LABEL;
+       struct bgp_info *local_ri = NULL;
+       struct bgp_info *tmp_ri = NULL;
+
+
+       /* locate the local route entry if any */
+       for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
+               if (tmp_ri->peer == bgp_def->peer_self
+                   && tmp_ri->type == ZEBRA_ROUTE_BGP
+                   && tmp_ri->sub_type == BGP_ROUTE_STATIC)
+                       local_ri = tmp_ri;
+       }
+
+       /* create a new route entry if one doesnt exist.
+          Otherwise see if route attr has changed */
+       if (!local_ri) {
+
+               /* Add (or update) attribute to hash. */
+               attr_new = bgp_attr_intern(attr);
+
+               /* create the route info from attribute */
+               ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
+                              bgp_def->peer_self, attr_new, rn);
+               SET_FLAG(ri->flags, BGP_INFO_VALID);
+
+               /* L3-VNI goes in the label2 field */
+               bgp_info_extra_get(ri);
+               vni2label(bgp_vrf->l3vni, &label);
+               memcpy(&ri->extra->label2, &label, BGP_LABEL_BYTES);
+
+               /* add the route entry to route node*/
+               bgp_info_add(rn, ri);
+       } else {
+
+               tmp_ri = local_ri;
+               if (!attrhash_cmp(tmp_ri->attr, attr)) {
+                       /* The attribute has changed. */
+                       /* Add (or update) attribute to hash. */
+                       attr_new = bgp_attr_intern(attr);
+                       bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
+
+                       /* Restore route, if needed. */
+                       if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
+                               bgp_info_restore(rn, tmp_ri);
+
+                       /* Unintern existing, set to new. */
+                       bgp_attr_unintern(&tmp_ri->attr);
+                       tmp_ri->attr = attr_new;
+                       tmp_ri->uptime = bgp_clock();
+               }
+       }
+       return 0;
+}
+
+/* update evpn type-5 route entry */
+static int update_evpn_type5_route(struct bgp *bgp_vrf,
+                                  struct prefix_evpn *evp)
+{
+       afi_t afi = AFI_L2VPN;
+       safi_t safi = SAFI_EVPN;
+       struct attr attr;
+       struct bgp_node *rn = NULL;
+       struct bgp *bgp_def = NULL;
+
+       bgp_def = bgp_get_default();
+       if (!bgp_def)
+               return -1;
+
+       /* build path attribute for this route */
+       memset(&attr, 0, sizeof(struct attr));
+       bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
+       attr.nexthop = bgp_vrf->originator_ip;
+       attr.mp_nexthop_global_in = bgp_vrf->originator_ip;
+       attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
+       memcpy(&attr.rmac, &bgp_vrf->rmac, sizeof(struct ethaddr));
+
+       /* Setup RT and encap extended community */
+       build_evpn_type5_route_extcomm(bgp_vrf, &attr);
+
+       /* get the route node in global table */
+       rn = bgp_afi_node_get(bgp_def->rib[afi][safi], afi, safi,
+                             (struct prefix *)evp,
+                             &bgp_vrf->vrf_prd);
+       assert(rn);
+
+       /* create or update the route entry within the route node */
+       update_evpn_type5_route_entry(bgp_def, bgp_vrf,
+                                     afi, safi,
+                                     rn, &attr);
+
+       /* schedule for processing and unlock node */
+       bgp_process(bgp_def, rn, afi, safi);
+       bgp_unlock_node(rn);
+
+       /* uninten temporary */
+       aspath_unintern(&attr.aspath);
+       return 0;
+}
+
 /*
  * Create or update EVPN route entry. This could be in the VNI route table
  * or the global route table.
@@ -1089,6 +1241,58 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
        return 0;
 }
 
+/* Delete EVPN type5 route entry from global table */
+static void delete_evpn_type5_route_entry(struct bgp *bgp_def,
+                                         struct bgp *bgp_vrf,
+                                         afi_t afi, safi_t safi,
+                                         struct bgp_node *rn,
+                                         struct bgp_info **ri)
+{
+       struct bgp_info *tmp_ri = NULL;
+
+       *ri = NULL;
+
+       /* find the matching route entry */
+       for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next)
+               if (tmp_ri->peer == bgp_def->peer_self
+                   && tmp_ri->type == ZEBRA_ROUTE_BGP
+                   && tmp_ri->sub_type == BGP_ROUTE_STATIC)
+                       break;
+
+       *ri = tmp_ri;
+
+       /* Mark route for delete. */
+       if (tmp_ri)
+               bgp_info_delete(rn, tmp_ri);
+}
+
+/* Delete EVPN type5 route */
+static int delete_evpn_type5_route(struct bgp *bgp_vrf,
+                                  struct prefix_evpn *evp)
+{
+       afi_t afi = AFI_L2VPN;
+       safi_t safi = SAFI_EVPN;
+       struct bgp_node *rn = NULL;
+       struct bgp_info *ri = NULL;
+       struct bgp *bgp_def = NULL; /* default bgp instance */
+
+       bgp_def = bgp_get_default();
+       if (!bgp_def)
+               return -1;
+
+       /* locate the global route entry for this type-5 prefix */
+       rn = bgp_afi_node_lookup(bgp_def->rib[afi][safi], afi, safi,
+                                (struct prefix *)evp, &bgp_vrf->vrf_prd);
+       if (!rn)
+               return 0;
+
+       delete_evpn_type5_route_entry(bgp_def, bgp_vrf, afi, safi, rn, &ri);
+       if (ri)
+               bgp_process(bgp_def, rn, afi, safi);
+       bgp_unlock_node(rn);
+       return 0;
+}
+
 /*
  * Delete EVPN route entry. This could be in the VNI route table
  * or the global route table.
@@ -2804,6 +3008,58 @@ static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf)
  * Public functions.
  */
 
+/* withdraw all type-5 routes for an address family */
+void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf,
+                                   afi_t afi)
+{
+       struct bgp_table *table = NULL;
+       struct bgp_node *rn = NULL;
+
+       table = bgp_vrf->rib[afi][SAFI_UNICAST];
+       for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+
+               int ret = 0;
+               struct prefix_evpn evp;
+               char buf[PREFIX_STRLEN];
+
+               build_type5_prefix_from_ip_prefix(&evp, &rn->p);
+               ret = delete_evpn_type5_route(bgp_vrf, &evp);
+               if (ret) {
+                       zlog_err(
+                                "%u failed to delete type-5 route for prefix %s in vrf %s",
+                                bgp_vrf->vrf_id,
+                                prefix2str(&rn->p, buf, sizeof(buf)),
+                                vrf_id_to_name(bgp_vrf->vrf_id));
+               }
+       }
+}
+
+/* advertise all type-5 routes for an address family */
+void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf,
+                                    afi_t afi)
+{
+       struct bgp_table *table = NULL;
+       struct bgp_node *rn = NULL;
+
+       table = bgp_vrf->rib[afi][SAFI_UNICAST];
+       for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+
+               int ret = 0;
+               struct prefix_evpn evp;
+               char buf[PREFIX_STRLEN];
+
+               build_type5_prefix_from_ip_prefix(&evp, &rn->p);
+               ret = update_evpn_type5_route(bgp_vrf, &evp);
+               if (ret) {
+                       zlog_err(
+                                "%u failed to create type-5 route for prefix %s in vrf %s",
+                                bgp_vrf->vrf_id,
+                                prefix2str(&rn->p, buf, sizeof(buf)),
+                                vrf_id_to_name(bgp_vrf->vrf_id));
+               }
+       }
+}
+
 void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni,
                                struct list *rtl)
 {
@@ -3128,6 +3384,13 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
                                 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
                                           PREFIX2STR_BUFFER));
                }
+       } else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
+               snprintf(buf, len, "[%d]:[0]:[%d]:[%s]",
+                        p->prefix.route_type,
+                        p->prefix.ip_prefix_length,
+                        IS_EVPN_PREFIX_IPADDR_V4(p) ?
+                               inet_ntoa(p->prefix.ip.ipaddr_v4) :
+                               inet6_ntoa(p->prefix.ip.ipaddr_v6));
        } else {
                /* For EVPN route types not supported yet. */
                snprintf(buf, len, "(unsupported route type %d)",
index e43fab9a7eb7bfe49bc28f716e7353f1b449ba58..488ebf686a8da2a4213cf8212b9b7de1fa0ed4c2 100644 (file)
@@ -25,6 +25,8 @@
 
 #define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
 
+extern void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi);
+extern void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi);
 extern void bgp_evpn_vrf_delete(struct bgp *);
 extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
 extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len);
index 26a026079412cbc96c039e68a6216be429e6edb2..1cf3f2215f1ecd7aa2aa4ee347d3adb2b7d037ea 100644 (file)
@@ -33,6 +33,7 @@
 /* EVPN prefix lengths. */
 #define EVPN_TYPE_2_ROUTE_PREFIXLEN      224
 #define EVPN_TYPE_3_ROUTE_PREFIXLEN      224
+#define EVPN_TYPE_5_ROUTE_PREFIXLEN      168
 
 /* EVPN route types. */
 typedef enum {
@@ -128,11 +129,14 @@ static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf,
 
 static inline int is_evpn_prefix_routes_adv_enabled(struct bgp *bgp_vrf)
 {
-       if (!bgp_vrf->l3vni ||
-           !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_EVPN_PREFIX_ROUTE))
+       if (!bgp_vrf->l3vni)
                return 0;
 
-       return 1;
+       if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN) ||
+           CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
+               return 1;
+
+       return 0;
 }
 
 static inline vni_t bgpevpn_get_l3vni(struct bgpevpn *vpn)
@@ -312,6 +316,31 @@ static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
                memcpy(&p->prefix.ip, ip, sizeof(*ip));
 }
 
+static inline void build_type5_prefix_from_ip_prefix(struct prefix_evpn *evp,
+                                                    struct prefix *ip_prefix)
+{
+       struct ipaddr ip;
+
+       memset(&ip, 0, sizeof(struct ipaddr));
+       if (ip_prefix->family == AF_INET) {
+               ip.ipa_type = IPADDR_V4;
+               memcpy(&ip.ipaddr_v4, &ip_prefix->u.prefix4,
+                      sizeof(struct in_addr));
+       } else {
+               ip.ipa_type = IPADDR_V6;
+               memcpy(&ip.ipaddr_v6, &ip_prefix->u.prefix6,
+                      sizeof(struct in6_addr));
+       }
+
+       memset(evp, 0, sizeof(struct prefix_evpn));
+       evp->family = AF_EVPN;
+       evp->prefixlen = EVPN_TYPE_5_ROUTE_PREFIXLEN;
+       evp->prefix.ip_prefix_length = ip_prefix->prefixlen;
+       evp->prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
+       evp->prefix.ip.ipa_type = ip.ipa_type;
+       memcpy(&evp->prefix.ip, &ip, sizeof(struct ipaddr));
+}
+
 static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
                                           struct in_addr originator_ip)
 {
index cb3c5eeb4d71a769496a6932e03a8055e9402a25..b2f4737b25c8146ccbbf46972884eaa85642da76 100644 (file)
@@ -1978,11 +1978,11 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
                        /* RD header and legend - once overall. */
                        if (rd_header && !json) {
                                vty_out(vty,
-                                       "EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:"
-                                       "[MAC]\n");
+                                       "EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC]\n");
                                vty_out(vty,
-                                       "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:"
-                                       "[OrigIP]\n\n");
+                                       "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
+                               vty_out(vty,
+                                       "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
                                rd_header = 0;
                        }
 
@@ -2440,6 +2440,105 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
        return CMD_SUCCESS;
 }
 
+DEFUN (bgp_evpn_advertise_type5,
+       bgp_evpn_advertise_type5_cmd,
+       "advertise <ipv4|ipv6|both>",
+       "Advertise prefix routes\n"
+       "advertise ipv4 prefix only\n"
+       "advertise ipv6 prefix only\n"
+       "advertise both ipv4/ipv6 prefix\n")
+{
+       struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
+       uint32_t type = 0;
+
+       if (strcmp(argv[1]->text, "ipv4")) {
+               type = BGP_VRF_ADVERTISE_IPV4_IN_EVPN;
+       } else if (strcmp(argv[1]->text, "ipv6")) {
+               type = BGP_VRF_ADVERTISE_IPV4_IN_EVPN;
+       } else if (strcmp(argv[1]->text, "both")) {
+               type = BGP_VRF_ADVERTISE_IPV4_IN_EVPN |
+                      BGP_VRF_ADVERTISE_IPV6_IN_EVPN;
+       } else {
+               vty_out(vty, "%%invalid command");
+               return CMD_WARNING;
+       }
+
+       if (CHECK_FLAG(type, BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
+
+               /* if we are already advertising ipv4 prefix as type-5
+                * nothing to do */
+               if (!CHECK_FLAG(bgp_vrf->vrf_flags,
+                               BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
+                       SET_FLAG(bgp_vrf->vrf_flags,
+                                BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
+                       bgp_evpn_advertise_type5_routes(bgp_vrf,
+                                                       AFI_IP);
+               }
+       } else {
+
+               /* if we are already advertising ipv6 prefix as type-5
+                * nothing to do */
+               if (!CHECK_FLAG(bgp_vrf->vrf_flags,
+                               BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) {
+                       SET_FLAG(bgp_vrf->vrf_flags,
+                                BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
+                       bgp_evpn_advertise_type5_routes(bgp_vrf,
+                                                       AFI_IP6);
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_evpn_advertise_type5,
+       no_bgp_evpn_advertise_type5_cmd,
+       "no advertise <ipv4|ipv6|both>",
+       NO_STR
+       "Advertise prefix routes\n"
+       "advertise ipv4 prefix only\n"
+       "advertise ipv6 prefix only\n"
+       "advertise both ipv4/ipv6 prefix\n")
+{
+       struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
+       uint32_t type = 0;
+
+       if (strcmp(argv[1]->text, "ipv4")) {
+               type = BGP_VRF_ADVERTISE_IPV4_IN_EVPN;
+       } else if (strcmp(argv[1]->text, "ipv6")) {
+               type = BGP_VRF_ADVERTISE_IPV4_IN_EVPN;
+       } else if (strcmp(argv[1]->text, "both")) {
+               type = BGP_VRF_ADVERTISE_IPV4_IN_EVPN |
+                      BGP_VRF_ADVERTISE_IPV6_IN_EVPN;
+       } else {
+               vty_out(vty, "%%invalid command");
+               return CMD_WARNING;
+       }
+
+       if (CHECK_FLAG(type, BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
+
+               /* if we are already advertising ipv4 prefix as type-5
+                * nothing to do */
+               if (CHECK_FLAG(bgp_vrf->vrf_flags,
+                              BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
+                       bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP);
+                       UNSET_FLAG(bgp_vrf->vrf_flags,
+                                  BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
+               }
+       } else {
+
+               /* if we are already advertising ipv6 prefix as type-5
+                * nothing to do */
+               if (CHECK_FLAG(bgp_vrf->vrf_flags,
+                              BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) {
+                       bgp_evpn_withdraw_type5_routes(bgp_vrf,
+                                                      AFI_IP6);
+                       UNSET_FLAG(bgp_vrf->vrf_flags,
+                                  BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
+               }
+       }
+       return CMD_SUCCESS;
+}
+
 /*
  * Display VNI information - for all or a specific VNI
  */
@@ -3955,6 +4054,8 @@ void bgp_ethernetvpn_init(void)
        install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
        install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_default_gw_cmd);
        install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
+       install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
+       install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
 
        /* "show bgp l2vpn evpn" commands. */
        install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
index 085de3fabb0eb64f6e275ff325e2206cc3b84ba7..ae4759aad0dbc848b6a3e05f9463d77cb972a38e 100644 (file)
@@ -73,9 +73,12 @@ struct bgp_info_extra {
        /* Nexthop reachability check.  */
        u_int32_t igpmetric;
 
-       /* MPLS label.  */
+       /* MPLS label - L2VNI  */
        mpls_label_t label;
 
+       /* MPLS label - L3-VNI */
+       mpls_label_t label2;
+
 #if ENABLE_BGP_VNC
        union {
 
index 449326ece514d22a97b98774446f60fa040ee3a1..bcf30adb3d5976dfc54e52438ed28c7d23995ab1 100644 (file)
@@ -424,10 +424,11 @@ struct bgp {
        /* vrf flags */
        uint32_t vrf_flags;
 #define BGP_VRF_AUTO                        (1 << 0)
-#define BGP_VRF_ADVERTISE_EVPN_PREFIX_ROUTE (1 << 1)
-#define BGP_VRF_IMPORT_RT_CFGD              (1 << 2)
-#define BGP_VRF_EXPORT_RT_CFGD              (1 << 3)
-#define BGP_VRF_RD_CFGD                     (1 << 4)
+#define BGP_VRF_ADVERTISE_IPV4_IN_EVPN      (1 << 1)
+#define BGP_VRF_ADVERTISE_IPV6_IN_EVPN      (1 << 2)
+#define BGP_VRF_IMPORT_RT_CFGD              (1 << 3)
+#define BGP_VRF_EXPORT_RT_CFGD              (1 << 4)
+#define BGP_VRF_RD_CFGD                     (1 << 5)
 
        /* unique ID for auto derivation of RD for this vrf */
        uint16_t vrf_rd_id;
index f1c25d24d964ad9da4a2fafaf85abecfe9de13e4..9f13cb8bb13b75b2a124fb326c64ea49bdcd37ea 100644 (file)
@@ -1043,10 +1043,11 @@ static const char *prefixevpn2str(const struct prefix *p, char *str, int size)
                family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)
                                 ? AF_INET
                                 : AF_INET6;
-               snprintf(str, size, "[%d]:[%u][%s]/%d",
+               snprintf(str, size, "[%d]:[%u][%s/%d]/%d",
                         p->u.prefix_evpn.route_type, p->u.prefix_evpn.eth_tag,
                         inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, buf,
                                   PREFIX2STR_BUFFER),
+                        p->u.prefix_evpn.ip_prefix_length,
                         p->prefixlen);
        } else {
                sprintf(str, "Unsupported EVPN route type %d",