static void bgp_evpn_l3nhg_update_on_vtep_chg(struct bgp_evpn_es *es);
static struct bgp_evpn_es *bgp_evpn_es_new(struct bgp *bgp, const esi_t *esi);
static void bgp_evpn_es_free(struct bgp_evpn_es *es, const char *caller);
+static void bgp_evpn_path_es_unlink(struct bgp_path_es_info *es_info);
esi_t zero_esi_buf, *zero_esi = &zero_esi_buf;
static int bgp_evpn_run_consistency_checks(struct thread *t);
* b. ES-VRF add/del - this may result in the host route being migrated to
* L3NHG or vice versa (flat multipath list).
****************************************************************************/
-void bgp_evpn_path_es_info_free(struct bgp_path_es_info *es_info)
+static void bgp_evpn_path_es_info_free(struct bgp_path_es_info *es_info)
{
bgp_evpn_path_es_unlink(es_info);
XFREE(MTYPE_BGP_EVPN_PATH_ES_INFO, es_info);
}
+void bgp_evpn_path_mh_info_free(struct bgp_path_mh_info *mh_info)
+{
+ if (mh_info->es_info)
+ bgp_evpn_path_es_info_free(mh_info->es_info);
+ XFREE(MTYPE_BGP_EVPN_PATH_MH_INFO, mh_info);
+}
+
static struct bgp_path_es_info *
bgp_evpn_path_es_info_new(struct bgp_path_info *pi, vni_t vni)
{
struct bgp_path_info_extra *e;
+ struct bgp_path_mh_info *mh_info;
+ struct bgp_path_es_info *es_info;
e = bgp_path_info_extra_get(pi);
+ /* If mh_info doesn't exist allocate it */
+ mh_info = e->mh_info;
+ if (!mh_info)
+ e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO,
+ sizeof(struct bgp_path_mh_info));
+
/* If es_info doesn't exist allocate it */
- if (!e->es_info) {
- e->es_info = XCALLOC(MTYPE_BGP_EVPN_PATH_ES_INFO,
- sizeof(struct bgp_path_es_info));
- e->es_info->pi = pi;
- e->es_info->vni = vni;
+ es_info = mh_info->es_info;
+ if (!es_info) {
+ mh_info->es_info = es_info =
+ XCALLOC(MTYPE_BGP_EVPN_PATH_ES_INFO,
+ sizeof(struct bgp_path_es_info));
+ es_info->vni = vni;
+ es_info->pi = pi;
}
- return e->es_info;
+ return es_info;
}
-void bgp_evpn_path_es_unlink(struct bgp_path_es_info *es_info)
+static void bgp_evpn_path_es_unlink(struct bgp_path_es_info *es_info)
{
struct bgp_evpn_es *es = es_info->es;
struct bgp_path_info *pi;
struct bgp *bgp_evpn;
struct prefix_evpn *evp;
- es_info = pi->extra ? pi->extra->es_info : NULL;
+ es_info = (pi->extra && pi->extra->mh_info)
+ ? pi->extra->mh_info->es_info
+ : NULL;
/* if the esi is zero just unlink the path from the old es */
if (!esi || !memcmp(esi, zero_esi, sizeof(*esi))) {
if (es_info)
extern void bgp_evpn_es_vrf_deref(struct bgp_evpn_es_evi *es_evi);
extern void bgp_evpn_es_vrf_ref(struct bgp_evpn_es_evi *es_evi,
struct bgp *bgp_vrf);
-extern void bgp_evpn_path_es_info_free(struct bgp_path_es_info *es_info);
-extern void bgp_evpn_path_es_unlink(struct bgp_path_es_info *es_info);
+extern void bgp_evpn_path_mh_info_free(struct bgp_path_mh_info *mh_info);
extern void bgp_evpn_path_es_link(struct bgp_path_info *pi, vni_t vni,
esi_t *esi);
extern bool bgp_evpn_path_es_use_nhg(struct bgp *bgp_vrf,
DEFINE_MTYPE(BGPD, BGP_EVPN, "BGP EVPN Information");
DEFINE_MTYPE(BGPD, BGP_EVPN_MH_INFO, "BGP EVPN MH Information");
DEFINE_MTYPE(BGPD, BGP_EVPN_ES_VTEP, "BGP EVPN ES VTEP");
+DEFINE_MTYPE(BGPD, BGP_EVPN_PATH_MH_INFO, "BGP EVPN PATH MH Information");
DEFINE_MTYPE(BGPD, BGP_EVPN_PATH_ES_INFO, "BGP EVPN PATH ES Information");
DEFINE_MTYPE(BGPD, BGP_EVPN_ES_EVI_VTEP, "BGP EVPN ES-EVI VTEP");
DEFINE_MTYPE(BGPD, BGP_EVPN_ES, "BGP EVPN ESI Information");
DECLARE_MTYPE(BGP_EVPN_ES_VRF);
DECLARE_MTYPE(BGP_EVPN_ES_VTEP);
DECLARE_MTYPE(BGP_EVPN_PATH_ES_INFO);
+DECLARE_MTYPE(BGP_EVPN_PATH_MH_INFO);
DECLARE_MTYPE(BGP_EVPN_ES_EVI_VTEP);
DECLARE_MTYPE(BGP_EVPN);
if (e->aggr_suppressors)
list_delete(&e->aggr_suppressors);
- if (e->es_info)
- bgp_evpn_path_es_info_free(e->es_info);
+ if (e->mh_info)
+ bgp_evpn_path_mh_info_free(e->mh_info);
if ((*extra)->bgp_fs_iprule)
list_delete(&((*extra)->bgp_fs_iprule));
if (safi == SAFI_EVPN) {
struct bgp_path_es_info *path_es_info = NULL;
- if (path->extra)
- path_es_info = path->extra->es_info;
-
if (bgp_evpn_is_esi_valid(&attr->esi)) {
/* XXX - add these params to the json out */
vty_out(vty, "%*s", 20, " ");
vty_out(vty, "ESI:%s",
esi_to_str(&attr->esi, esi_buf,
sizeof(esi_buf)));
+
+ if (path->extra && path->extra->mh_info)
+ path_es_info =
+ path->extra->mh_info->es_info;
+
if (path_es_info && path_es_info->es)
vty_out(vty, " VNI: %u",
path_es_info->vni);
#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE1_SIZE -15
#define BGP_NLRI_PARSE_ERROR -32
-/* MAC-IP/type-2 path_info in the VNI routing table is linked to the
+/* 1. local MAC-IP/type-2 paths in the VNI routing table are linked to the
+ * destination ES
+ * 2. remote MAC-IP paths in the global routing table are linked to the
* destination ES
*/
struct bgp_path_es_info {
struct listnode es_listnode;
};
+/* IP paths imported into the VRF from an EVPN route source
+ * are linked to the nexthop/VTEP IP
+ */
+struct bgp_path_mh_vrf_info {
+ /* back pointer to the route */
+ struct bgp_path_info *pi;
+ /* memory used for linking the path to the nexthop */
+ struct listnode nh_listnode;
+};
+
+struct bgp_path_mh_info {
+ struct bgp_path_es_info *es_info;
+ struct bgp_path_mh_vrf_info *vrf_info;
+};
+
/* Ancillary information to struct bgp_path_info,
* used for uncommonly used data (aggregation, MPLS, etc.)
* and lazily allocated to save memory.
/* presence of FS pbr iprule based entry */
struct list *bgp_fs_iprule;
/* Destination Ethernet Segment links for EVPN MH */
- struct bgp_path_es_info *es_info;
+ struct bgp_path_mh_info *mh_info;
};
struct bgp_path_info {