From c48d9f5f8545c4af3e4a2a4a58999cf62b705486 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Tue, 6 Feb 2018 14:28:22 -0800 Subject: [PATCH] zebra, bgp: Support type-5 routes with asymmetric routing Asymmetric routing is an ideal choice when all VLANs are cfged on all leafs. It simplifies the routing configuration and eliminates potential need for advertising subnet routes. However, we need to reach the Internet or global destinations or to do subnet-based routing between PODs or DCs. This requires EVPN type-5 routes but those routes require L3 VNI configuration. This task is to support EVPN type-5 routes for prefix-based routing in conjunction with asymmetric routing within the POD/DC. It is done by providing an option to use the L3 VNI only for prefix routes, so that type-2 routes (host routes) will only use the L2 VNI. Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_evpn.c | 66 +++++++++++++++++++++++++++++-------- bgpd/bgp_evpn.h | 3 +- bgpd/bgp_evpn_private.h | 21 +++++++++--- bgpd/bgp_evpn_vty.c | 8 +++++ bgpd/bgp_zebra.c | 10 ++++-- bgpd/bgpd.h | 1 + zebra/zebra_vrf.c | 5 ++- zebra/zebra_vty.c | 28 +++++++++++----- zebra/zebra_vxlan.c | 40 ++++++++++++++++------ zebra/zebra_vxlan.h | 3 +- zebra/zebra_vxlan_private.h | 3 ++ 11 files changed, 147 insertions(+), 41 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c7d5f8d111..756449cf1b 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 a8dcbc112b..d8d92618f6 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 cc0ec82344..1dbc1f25f0 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 bd42ccdecf..e9e0c8df1b 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -3897,6 +3897,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 +3926,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 e0bd74a206..aaf3ba1252 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 c4ac4b0adb..afb7126ec5 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 b9b3048486..65fa7ecf80 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 93397afa79..c2a620c30d 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 c9cc556a44..20b9e94288 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 d9801a8b60..df9b07db60 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 8d34b3e2f1..e8de25cefd 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; -- 2.39.5