mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +00:00
bgpd: add an option for RT auto-derivation to use RFC 8635.
RFC 8635 explains how RT auto-derivation should be done in section 5.1.2.1 [1]. In addition to encoding the VNI in the lowest bytes, a 3-bit field is used to encode a namespace. For VXLAN, we have to put 1 in this field. This is needed for proper interoperability with RT auto-derivation in JunOS. Since this would break existing setup, an additional option, "autort rfc8365-compatible" is used. [1]: https://tools.ietf.org/html/rfc8365#section-5.1.2.1 Signed-off-by: Vincent Bernat <vincent@bernat.im>
This commit is contained in:
parent
0c842c46c7
commit
bf1061d876
@ -453,6 +453,8 @@ static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl)
|
|||||||
struct ecommunity_val eval;
|
struct ecommunity_val eval;
|
||||||
struct ecommunity *ecomadd;
|
struct ecommunity *ecomadd;
|
||||||
|
|
||||||
|
if (bgp->advertise_autort_rfc8365)
|
||||||
|
vni |= EVPN_AUTORT_VXLAN;
|
||||||
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
|
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
|
||||||
|
|
||||||
ecomadd = ecommunity_new();
|
ecomadd = ecommunity_new();
|
||||||
@ -3224,6 +3226,41 @@ static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf)
|
|||||||
update_routes_for_vni(bgp_def, vpn);
|
update_routes_for_vni(bgp_def, vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle autort change for a given VNI.
|
||||||
|
*/
|
||||||
|
static void update_autort_vni(struct hash_backet *backet, struct bgp *bgp)
|
||||||
|
{
|
||||||
|
struct bgpevpn *vpn = backet->data;
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct ecommunity *ecom;
|
||||||
|
|
||||||
|
if (!vpn) {
|
||||||
|
zlog_warn("%s: VNI hash entry for VNI not found", __PRETTY_FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_import_rt_configured(vpn)) {
|
||||||
|
if (is_vni_live(vpn))
|
||||||
|
bgp_evpn_uninstall_routes(bgp, vpn);
|
||||||
|
bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
|
||||||
|
for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom))
|
||||||
|
ecommunity_free(&ecom);
|
||||||
|
list_delete_all_node(vpn->import_rtl);
|
||||||
|
bgp_evpn_derive_auto_rt_import(bgp, vpn);
|
||||||
|
if (is_vni_live(vpn))
|
||||||
|
bgp_evpn_install_routes(bgp, vpn);
|
||||||
|
}
|
||||||
|
if (!is_export_rt_configured(vpn)) {
|
||||||
|
for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
|
||||||
|
ecommunity_free(&ecom);
|
||||||
|
list_delete_all_node(vpn->export_rtl);
|
||||||
|
bgp_evpn_derive_auto_rt_export(bgp, vpn);
|
||||||
|
if (is_vni_live(vpn))
|
||||||
|
bgp_evpn_handle_export_rt_change(bgp, vpn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Public functions.
|
* Public functions.
|
||||||
*/
|
*/
|
||||||
@ -3335,6 +3372,8 @@ void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl)
|
|||||||
struct ecommunity *ecom, *ecom_auto;
|
struct ecommunity *ecom, *ecom_auto;
|
||||||
struct ecommunity_val eval;
|
struct ecommunity_val eval;
|
||||||
|
|
||||||
|
if (bgp->advertise_autort_rfc8365)
|
||||||
|
vni |= EVPN_AUTORT_VXLAN;
|
||||||
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
|
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
|
||||||
|
|
||||||
ecom_auto = ecommunity_new();
|
ecom_auto = ecommunity_new();
|
||||||
@ -3494,6 +3533,17 @@ void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle change to auto-RT algorithm - update and advertise local routes.
|
||||||
|
*/
|
||||||
|
void bgp_evpn_handle_autort_change(struct bgp *bgp)
|
||||||
|
{
|
||||||
|
hash_iterate(bgp->vnihash,
|
||||||
|
(void (*)(struct hash_backet *,
|
||||||
|
void*))update_autort_vni,
|
||||||
|
bgp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle change to export RT - update and advertise local routes.
|
* Handle change to export RT - update and advertise local routes.
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "bgpd.h"
|
#include "bgpd.h"
|
||||||
|
|
||||||
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
|
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
|
||||||
|
#define EVPN_AUTORT_VXLAN 0x10000000
|
||||||
|
|
||||||
static inline int is_evpn_enabled(void)
|
static inline int is_evpn_enabled(void)
|
||||||
{
|
{
|
||||||
|
@ -385,6 +385,7 @@ extern void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
|
|||||||
struct ecommunity *ecomdel);
|
struct ecommunity *ecomdel);
|
||||||
extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
|
extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
|
||||||
struct bgpevpn *vpn);
|
struct bgpevpn *vpn);
|
||||||
|
extern void bgp_evpn_handle_autort_change(struct bgp *bgp);
|
||||||
extern void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw);
|
extern void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw);
|
||||||
extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
|
extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
|
||||||
int withdraw);
|
int withdraw);
|
||||||
|
@ -2502,6 +2502,24 @@ static void evpn_unset_advertise_all_vni(struct bgp *bgp)
|
|||||||
bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
|
bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
|
||||||
bgp_evpn_cleanup_on_disable(bgp);
|
bgp_evpn_cleanup_on_disable(bgp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EVPN - use RFC8365 to auto-derive RT
|
||||||
|
*/
|
||||||
|
static void evpn_set_advertise_autort_rfc8365(struct bgp *bgp)
|
||||||
|
{
|
||||||
|
bgp->advertise_autort_rfc8365 = 1;
|
||||||
|
bgp_evpn_handle_autort_change(bgp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EVPN - don't use RFC8365 to auto-derive RT
|
||||||
|
*/
|
||||||
|
static void evpn_unset_advertise_autort_rfc8365(struct bgp *bgp)
|
||||||
|
{
|
||||||
|
bgp->advertise_autort_rfc8365 = 0;
|
||||||
|
bgp_evpn_handle_autort_change(bgp);
|
||||||
|
}
|
||||||
#endif /* HAVE_CUMULUS */
|
#endif /* HAVE_CUMULUS */
|
||||||
|
|
||||||
static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
|
static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
|
||||||
@ -2655,6 +2673,35 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_evpn_advertise_autort_rfc8365,
|
||||||
|
bgp_evpn_advertise_autort_rfc8365_cmd,
|
||||||
|
"autort rfc8365-compatible",
|
||||||
|
"Auto-derivation of RT\n"
|
||||||
|
"Auto-derivation of RT using RFC8365\n")
|
||||||
|
{
|
||||||
|
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||||
|
|
||||||
|
if (!bgp)
|
||||||
|
return CMD_WARNING;
|
||||||
|
evpn_set_advertise_autort_rfc8365(bgp);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_bgp_evpn_advertise_autort_rfc8365,
|
||||||
|
no_bgp_evpn_advertise_autort_rfc8365_cmd,
|
||||||
|
"no autort rfc8365-compatible",
|
||||||
|
NO_STR
|
||||||
|
"Auto-derivation of RT\n"
|
||||||
|
"Auto-derivation of RT using RFC8365\n")
|
||||||
|
{
|
||||||
|
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||||
|
|
||||||
|
if (!bgp)
|
||||||
|
return CMD_WARNING;
|
||||||
|
evpn_unset_advertise_autort_rfc8365(bgp);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (bgp_evpn_default_originate,
|
DEFUN (bgp_evpn_default_originate,
|
||||||
bgp_evpn_default_originate_cmd,
|
bgp_evpn_default_originate_cmd,
|
||||||
"default-originate <ipv4 | ipv6>",
|
"default-originate <ipv4 | ipv6>",
|
||||||
@ -4378,6 +4425,9 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
if (bgp->advertise_all_vni)
|
if (bgp->advertise_all_vni)
|
||||||
vty_out(vty, " advertise-all-vni\n");
|
vty_out(vty, " advertise-all-vni\n");
|
||||||
|
|
||||||
|
if (bgp->advertise_autort_rfc8365)
|
||||||
|
vty_out(vty, " autort rfc8365-compatible\n");
|
||||||
|
|
||||||
if (bgp->advertise_gw_macip)
|
if (bgp->advertise_gw_macip)
|
||||||
vty_out(vty, " advertise-default-gw\n");
|
vty_out(vty, " advertise-default-gw\n");
|
||||||
|
|
||||||
@ -4455,6 +4505,8 @@ void bgp_ethernetvpn_init(void)
|
|||||||
#if defined(HAVE_CUMULUS)
|
#if defined(HAVE_CUMULUS)
|
||||||
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_all_vni_cmd);
|
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_all_vni_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
|
||||||
|
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_autort_rfc8365_cmd);
|
||||||
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_autort_rfc8365_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_default_gw_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, &no_bgp_evpn_advertise_default_gw_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
|
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
|
||||||
|
@ -423,6 +423,9 @@ struct bgp {
|
|||||||
/* EVPN enable - advertise local VNIs and their MACs etc. */
|
/* EVPN enable - advertise local VNIs and their MACs etc. */
|
||||||
int advertise_all_vni;
|
int advertise_all_vni;
|
||||||
|
|
||||||
|
/* EVPN - use RFC 8365 to auto-derive RT */
|
||||||
|
int advertise_autort_rfc8365;
|
||||||
|
|
||||||
/* Hash table of Import RTs to EVIs */
|
/* Hash table of Import RTs to EVIs */
|
||||||
struct hash *import_rt_hash;
|
struct hash *import_rt_hash;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user