diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c7d5f8d1118c..756449cf1b87 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -666,10 +666,11 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom)) attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom); - /* Add the export RTs for L3VNI - currently only supported for IPV4 host - * routes + /* + * only attach l3-vni export rts for ipv4 address family and if we are + * advertising both the labels in type-2 routes */ - if (afi == AFI_IP) { + if (afi == AFI_IP && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn); if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) { for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, @@ -690,7 +691,12 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, ecommunity_merge(attr->ecommunity, &ecom_sticky); } - if (afi == AFI_IP && !is_zero_mac(&attr->rmac)) { + /* + * only attach l3-vni rmac for ipv4 address family and if we are + * advertising both the labels in type-2 routes + */ + if (afi == AFI_IP && !is_zero_mac(&attr->rmac) && + CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { memset(&ecom_rmac, 0, sizeof(ecom_rmac)); encode_rmac_extcomm(&eval_rmac, &attr->rmac); ecom_rmac.size = 1; @@ -1189,8 +1195,13 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, /* The VNI goes into the 'label' field of the route */ vni2label(vpn->vni, &label[0]); - /* Type-2 routes may carry a second VNI - the L3-VNI */ - if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { + + /* Type-2 routes may carry a second VNI - the L3-VNI. + * Only attach second label if we are advertising two labels for + * type-2 routes. + */ + if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && + CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { vni_t l3vni; l3vni = bgpevpn_get_l3vni(vpn); @@ -1209,6 +1220,24 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, && !CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED)) route_change = 0; else { + /* + * The attributes have changed, type-2 routes needs to + * be advertised with right labels. + */ + vni2label(vpn->vni, &label[0]); + if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && + CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { + vni_t l3vni; + + l3vni = bgpevpn_get_l3vni(vpn); + if (l3vni) { + vni2label(l3vni, &label[1]); + num_labels++; + } + } + memcpy(&tmp_ri->extra->label, label, sizeof(label)); + tmp_ri->extra->num_labels = num_labels; + /* The attribute has changed. */ /* Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(attr); @@ -4214,7 +4243,8 @@ static void link_l2vni_hash_to_l3vni(struct hash_backet *backet, int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, - struct in_addr originator_ip) + struct in_addr originator_ip, + int filter) { struct bgp *bgp_vrf = NULL; /* bgp VRF instance */ struct bgp *bgp_def = NULL; /* default bgp instance */ @@ -4266,6 +4296,10 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, /* set the originator ip */ bgp_vrf->originator_ip = originator_ip; + /* set the right filter - are we using l3vni only for prefix routes? */ + if (filter) + SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY); + /* auto derive RD/RT */ if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) evpn_auto_rt_import_add_for_vrf(bgp_vrf); @@ -4279,9 +4313,12 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, link_l2vni_hash_to_l3vni, bgp_vrf); - /* updates all corresponding local mac-ip routes */ - for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) - update_routes_for_vni(bgp_def, vpn); + /* Only update all corresponding type-2 routes if we are advertising two + * labels along with type-2 routes + */ + if (!filter) + for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) + update_routes_for_vni(bgp_def, vpn); /* advertise type-5 routes if needed */ update_advertise_vrf_routes(bgp_vrf); @@ -4340,9 +4377,12 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, } /* update all corresponding local mac-ip routes */ - for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) - update_routes_for_vni(bgp_def, vpn); - + if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) { + for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) { + UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); + update_routes_for_vni(bgp_def, vpn); + } + } /* Delete the instance if it was autocreated */ if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO)) diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index a8dcbc112b1c..d8d92618f6da 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -91,7 +91,8 @@ extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, u_char flags); extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id, struct ethaddr *rmac, - struct in_addr originator_ip); + struct in_addr originator_ip, + int filter); extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id); extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni); extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index cc0ec82344b3..1dbc1f25f00d 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -61,6 +61,8 @@ struct bgpevpn { #define VNI_FLAG_RD_CFGD 0x4 /* RD is user configured. */ #define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */ #define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */ +#define VNI_FLAG_USE_TWO_LABELS 0x20 /* Attach both L2-VNI and L3-VNI if + needed for this VPN */ /* Flag to indicate if we are advertising the g/w mac ip for this VNI*/ u_int8_t advertise_gw_macip; @@ -179,9 +181,13 @@ 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 || !bgp_vrf->l2vnis) + if (!bgp_vrf) return; - listnode_delete(bgp_vrf->l2vnis, vpn); + + UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); + + if (bgp_vrf->l2vnis) + listnode_delete(bgp_vrf->l2vnis, vpn); } static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn) @@ -189,9 +195,16 @@ static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn) struct bgp *bgp_vrf = NULL; bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); - if (!bgp_vrf || !bgp_vrf->l2vnis) + if (!bgp_vrf) return; - 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 bd42ccdecfdd..c02f3b61351d 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -436,6 +436,10 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) inet_ntoa(vpn->originator_ip)); json_object_string_add(json, "advertiseGatewayMacip", vpn->advertise_gw_macip ? "Yes" : "No"); + json_object_int_add(json, "numAdvLabels", + CHECK_FLAG(vpn->flags, + VNI_FLAG_USE_TWO_LABELS) ? + BGP_MAX_LABELS : BGP_MAX_LABELS - 1); } else { vty_out(vty, "VNI: %d", vpn->vni); if (is_vni_live(vpn)) @@ -451,6 +455,9 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) inet_ntoa(vpn->originator_ip)); vty_out(vty, " Advertise-gw-macip : %s\n", vpn->advertise_gw_macip ? "Yes" : "No"); + vty_out(vty, " Number of advertised labels %d\n", + CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) ? + BGP_MAX_LABELS : BGP_MAX_LABELS - 1); } if (!json) @@ -3897,6 +3904,10 @@ DEFUN (show_bgp_vrf_l3vni_info, vty_out(vty, " L3-VNI: %u\n", bgp->l3vni); vty_out(vty, " Rmac: %s\n", prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); + vty_out(vty, " VNI Filter: %s\n", + CHECK_FLAG(bgp->vrf_flags, + BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY) ? + "prefix-routes-only" : "none"); vty_out(vty, " L2-VNI List:\n"); vty_out(vty, " "); for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn)) @@ -3922,6 +3933,10 @@ DEFUN (show_bgp_vrf_l3vni_info, json_object_string_add(json, "rmac", prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); + json_object_string_add(json, "vniFilter", + CHECK_FLAG(bgp->vrf_flags, + BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY) + ? "prefix-routes-only" : "none"); /* list of l2vnis */ for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn)) json_object_array_add(json_vnis, diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index e0bd74a20699..aaf3ba125209 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1731,6 +1731,7 @@ static void bgp_zebra_connected(struct zclient *zclient) static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { + int filter = 0; char buf[ETHER_ADDR_STRLEN]; vni_t l3vni = 0; struct ethaddr rmac; @@ -1744,17 +1745,20 @@ static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient, if (cmd == ZEBRA_L3VNI_ADD) { stream_get(&rmac, s, sizeof(struct ethaddr)); originator_ip.s_addr = stream_get_ipv4(s); + stream_get(&filter, s, sizeof(int)); } if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s", + zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s filter %s", (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del", vrf_id_to_name(vrf_id), l3vni, - prefix_mac2str(&rmac, buf, sizeof(buf))); + prefix_mac2str(&rmac, buf, sizeof(buf)), + filter ? "prefix-routes-only" : "none"); if (cmd == ZEBRA_L3VNI_ADD) - bgp_evpn_local_l3vni_add(l3vni, vrf_id, &rmac, originator_ip); + bgp_evpn_local_l3vni_add(l3vni, vrf_id, &rmac, originator_ip, + filter); else bgp_evpn_local_l3vni_del(l3vni, vrf_id); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c4ac4b0adb05..afb7126ec570 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -435,6 +435,7 @@ struct bgp { #define BGP_VRF_IMPORT_RT_CFGD (1 << 3) #define BGP_VRF_EXPORT_RT_CFGD (1 << 4) #define BGP_VRF_RD_CFGD (1 << 5) +#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 6) /* unique ID for auto derivation of RD for this vrf */ uint16_t vrf_rd_id; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index b9b3048486f7..65fa7ecf805c 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -598,7 +598,10 @@ static int vrf_config_write(struct vty *vty) if (vrf_is_user_cfged(vrf)) { vty_out(vty, "vrf %s\n", zvrf_name(zvrf)); if (zvrf->l3vni) - vty_out(vty, " vni %u\n", zvrf->l3vni); + vty_out(vty, " vni %u%s\n", + zvrf->l3vni, + is_l3vni_for_prefix_routes_only(zvrf->l3vni) ? + " prefix-routes-only" :""); vty_out(vty, "!\n"); } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 93397afa79e8..c2a620c30dd9 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2338,20 +2338,26 @@ DEFUN (show_vrf, DEFUN (default_vrf_vni_mapping, default_vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE, + "vni " CMD_VNI_RANGE "[prefix-routes-only]", "VNI corresponding to the DEFAULT VRF\n" - "VNI-ID\n") + "VNI-ID\n" + "Prefix routes only \n") { int ret = 0; char err[ERR_STR_SZ]; struct zebra_vrf *zvrf = NULL; vni_t vni = strtoul(argv[1]->arg, NULL, 10); + int filter = 0; zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) return CMD_WARNING; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 1); + if (argc == 3) + filter = 1; + + ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, + filter, 1); if (ret != 0) { vty_out(vty, "%s\n", err); return CMD_WARNING; @@ -2376,7 +2382,7 @@ DEFUN (no_default_vrf_vni_mapping, if (!zvrf) return CMD_WARNING; - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0); + ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0); if (ret != 0) { vty_out(vty, "%s\n", err); return CMD_WARNING; @@ -2387,11 +2393,13 @@ DEFUN (no_default_vrf_vni_mapping, DEFUN (vrf_vni_mapping, vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE, + "vni " CMD_VNI_RANGE "[prefix-routes-only]", "VNI corresponding to tenant VRF\n" - "VNI-ID\n") + "VNI-ID\n" + "prefix-routes-only\n") { int ret = 0; + int filter = 0; ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); vni_t vni = strtoul(argv[1]->arg, NULL, 10); @@ -2400,9 +2408,13 @@ DEFUN (vrf_vni_mapping, assert(vrf); assert(zvrf); + if (argc == 3) + filter = 1; + /* Mark as having FRR configuration */ vrf_set_user_cfged(vrf); - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 1); + ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, + filter, 1); if (ret != 0) { vty_out(vty, "%s\n", err); return CMD_WARNING; @@ -2427,7 +2439,7 @@ DEFUN (no_vrf_vni_mapping, assert(vrf); assert(zvrf); - ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0); + ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0); if (ret != 0) { vty_out(vty, "%s\n", err); return CMD_WARNING; diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index c9cc556a4478..20b9e9428879 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -928,6 +928,9 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx) zl3vni_svi_if_name(zl3vni)); vty_out(vty, " State: %s\n", zl3vni_state2str(zl3vni)); + vty_out(vty, " VNI Filter: %s\n", + CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? + "prefix-routes-only" : "none"); vty_out(vty, " Router MAC: %s\n", zl3vni_rmac2str(zl3vni, buf, sizeof(buf))); vty_out(vty, " L2 VNIs: "); @@ -951,6 +954,10 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx) json_object_string_add(json, "routerMac", zl3vni_rmac2str(zl3vni, buf, sizeof(buf))); + json_object_string_add(json, "vniFilter", + CHECK_FLAG(zl3vni->filter, + PREFIX_ROUTES_ONLY) ? + "prefix-routes-only" : "none"); for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni)) { json_object_array_add(json_vni_list, json_object_new_int(zvni->vni)); @@ -3613,15 +3620,19 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni) stream_putl(s, zl3vni->vni); stream_put(s, &rmac, sizeof(struct ethaddr)); stream_put_in_addr(s, &zl3vni->local_vtep_ip); + stream_put(s, &zl3vni->filter, sizeof(int)); /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s to %s", + zlog_debug( + "Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s filter %s to %s", zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)), prefix_mac2str(&rmac, buf, sizeof(buf)), inet_ntoa(zl3vni->local_vtep_ip), + CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? + "prefix-routes-only" : "none", zebra_route_string(client->proto)); client->l3vniadd_cnt++; @@ -3666,10 +3677,6 @@ static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni) if (!zl3vni) return; - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("L3-VNI %u is UP - send add to BGP", - zl3vni->vni); - /* send l3vni add to BGP */ zl3vni_send_add_to_client(zl3vni); } @@ -3679,10 +3686,6 @@ static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni) if (!zl3vni) return; - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("L3-VNI %u is Down - Send del to BGP", - zl3vni->vni); - /* send l3-vni del to BGP*/ zl3vni_send_del_to_client(zl3vni); } @@ -3835,6 +3838,17 @@ static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni, /* Public functions */ +int is_l3vni_for_prefix_routes_only(vni_t vni) +{ + zebra_l3vni_t *zl3vni = NULL; + + zl3vni = zl3vni_lookup(vni); + if (!zl3vni) + return 0; + + return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0; +} + /* handle evpn route in vrf table */ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac, @@ -6432,7 +6446,7 @@ int zebra_vxlan_if_add(struct interface *ifp) int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, char *err, int err_str_sz, - int add) + int filter, int add) { zebra_l3vni_t *zl3vni = NULL; struct zebra_vrf *zvrf_default = NULL; @@ -6477,6 +6491,12 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, /* associate the vrf with vni */ zvrf->l3vni = vni; + /* set the filter in l3vni to denote if we are using l3vni only + * for prefix routes + */ + if (filter) + SET_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY); + /* associate with vxlan-intf; * we need to associate with the vxlan-intf first */ diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index d9801a8b6059..df9b07db60f9 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -52,6 +52,7 @@ is_evpn_enabled() #define VNI_STR_LEN 32 +extern int is_l3vni_for_prefix_routes_only(vni_t vni); extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id); extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf); extern int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf); @@ -154,7 +155,7 @@ extern int zebra_vxlan_advertise_all_vni(struct zserv *client, struct zebra_vrf *zvrf); extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, char *err, - int err_str_sz, int add); + int err_str_sz, int filter, int add); extern void zebra_vxlan_init_tables(struct zebra_vrf *zvrf); extern void zebra_vxlan_close_tables(struct zebra_vrf *); extern void zebra_vxlan_cleanup_tables(struct zebra_vrf *); diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index 8d34b3e2f12b..e8de25cefd72 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -101,6 +101,9 @@ struct zebra_l3vni_t_ { /* vrf_id */ vrf_id_t vrf_id; + uint32_t filter; +#define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */ + /* Local IP */ struct in_addr local_vtep_ip;