3 SA issues fixed.
struct ecommunity_val eval;
struct ecommunity *ecomadd;
+ if (bgp->advertise_autort_rfc8365)
+ vni |= EVPN_AUTORT_VXLAN;
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
ecomadd = ecommunity_new();
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.
*/
struct ecommunity *ecom, *ecom_auto;
struct ecommunity_val eval;
+ if (bgp->advertise_autort_rfc8365)
+ vni |= EVPN_AUTORT_VXLAN;
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
ecom_auto = ecommunity_new();
}
}
+/*
+ * 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.
*/
#include "bgpd.h"
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
+#define EVPN_AUTORT_VXLAN 0x10000000
static inline int is_evpn_enabled(void)
{
struct ecommunity *ecomdel);
extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
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_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
int withdraw);
bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
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 */
static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
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,
bgp_evpn_default_originate_cmd,
"default-originate <ipv4 | ipv6>",
if (bgp->advertise_all_vni)
vty_out(vty, " advertise-all-vni\n");
+ if (bgp->advertise_autort_rfc8365)
+ vty_out(vty, " autort rfc8365-compatible\n");
+
if (bgp->advertise_gw_macip)
vty_out(vty, " advertise-default-gw\n");
#if defined(HAVE_CUMULUS)
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, &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, &no_bgp_evpn_advertise_default_gw_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
? true
: false;
bool nexthop_othervrf = false;
- vrf_id_t nexthop_vrfid;
+ vrf_id_t nexthop_vrfid = VRF_DEFAULT;
const char *nexthop_vrfname = "Default";
if (json_paths)
/* EVPN enable - advertise local VNIs and their MACs etc. */
int advertise_all_vni;
+ /* EVPN - use RFC 8365 to auto-derive RT */
+ int advertise_autort_rfc8365;
+
/* Hash table of Import RTs to EVIs */
struct hash *import_rt_hash;
pbr_nht_install_nexthop_group(pnhgc, nhgc->nhg);
}
-/*
- * Since we are writing into the name field which is PBR_MAP_NAMELEN
- * size, we are expecting this to field to be at max 100 bytes.
- * Newer compilers understand that the %s portion may be up to
- * 100 bytes( because of the size of the string. The %u portion
- * is expected to be 10 bytes. So in `theory` there are situations
- * where we might truncate. The reality this is never going to
- * happen( who is going to create a nexthop group name that is
- * over say 30 characters? ). As such we are expecting the
- * calling function to subtract 10 from the size_t l before
- * we pass it in to get around this new gcc fun.
- */
char *pbr_nht_nexthop_make_name(char *name, size_t l,
uint32_t seqno, char *buffer)
{
struct pbr_nexthop_cache lookup;
memset(&find, 0, sizeof(find));
- pbr_nht_nexthop_make_name(pbrms->parent->name, PBR_MAP_NAMELEN - 10,
+ pbr_nht_nexthop_make_name(pbrms->parent->name, PBR_NHC_NAMELEN,
pbrms->seqno, find.name);
if (!pbrms->internal_nhg_name)
pbrms->internal_nhg_name = XSTRDUP(MTYPE_TMP, find.name);
#include "pbr_map.h"
+#define PBR_NHC_NAMELEN PBR_MAP_NAMELEN + 10
+
struct pbr_nexthop_group_cache {
- char name[PBR_MAP_NAMELEN];
+ char name[PBR_NHC_NAMELEN];
uint32_t table_id;
if (pbrms->nhg)
nh = nexthop_exists(pbrms->nhg, &nhop);
else {
- char buf[PBR_MAP_NAMELEN];
+ char buf[PBR_NHC_NAMELEN];
if (no) {
vty_out(vty, "No nexthops to delete");
pbrms->internal_nhg_name =
XSTRDUP(MTYPE_TMP,
pbr_nht_nexthop_make_name(pbrms->parent->name,
- PBR_MAP_NAMELEN - 10,
+ PBR_NHC_NAMELEN,
pbrms->seqno,
buf));
nh = NULL;