diff options
| -rw-r--r-- | bgpd/bgp_evpn.c | 32 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.h | 19 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_mh.c | 45 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_private.h | 16 | ||||
| -rw-r--r-- | bgpd/bgp_flowspec_vty.c | 12 | ||||
| -rw-r--r-- | bgpd/bgp_memory.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_memory.h | 3 | ||||
| -rw-r--r-- | bgpd/bgp_mpath.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 161 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.h | 7 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 5 | ||||
| -rw-r--r-- | bgpd/bgp_pbr.c | 16 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 163 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 104 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 23 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 55 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.h | 7 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi_vty.c | 21 |
19 files changed, 330 insertions, 380 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index a33f59cf5b..35f2438929 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1924,7 +1924,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, /* Mark route as self type-2 route */ if (flags && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP)) - tmp_pi->extra->af_flags = BGP_EVPN_MACIP_TYPE_SVI_IP; + tmp_pi->extra->evpn->af_flags = + BGP_EVPN_MACIP_TYPE_SVI_IP; bgp_path_info_add(dest, tmp_pi); } else { tmp_pi = local_pi; @@ -2390,7 +2391,8 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, attr.router_flag = 1; } memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t)); - bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, local_pi->extra->af_flags); + bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, + local_pi->extra->evpn->af_flags); vni2label(vpn->vni, &(attr.label)); /* Add L3 VNI RTs and RMAC for non IPv6 link-local if * using L3 VNI for type-2 routes also. @@ -2829,7 +2831,11 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, attr_new, dest); SET_FLAG(pi->flags, BGP_PATH_VALID); bgp_path_info_extra_get(pi); - pi->extra->parent = bgp_path_info_lock(parent_pi); + if (!pi->extra->vrfleak) + pi->extra->vrfleak = + XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, + sizeof(struct bgp_path_info_extra_vrfleak)); + pi->extra->vrfleak->parent = bgp_path_info_lock(parent_pi); bgp_dest_lock_node((struct bgp_dest *)parent_pi->net); if (parent_pi->extra) { memcpy(&pi->extra->label, &parent_pi->extra->label, @@ -2935,8 +2941,9 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, /* Check if route entry is already present. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (pi->extra - && (struct bgp_path_info *)pi->extra->parent == parent_pi) + if (pi->extra && pi->extra->vrfleak && + (struct bgp_path_info *)pi->extra->vrfleak->parent == + parent_pi) break; if (!pi) { @@ -3031,8 +3038,9 @@ static int install_evpn_route_entry_in_vni_common( /* Check if route entry is already present. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (pi->extra - && (struct bgp_path_info *)pi->extra->parent == parent_pi) + if (pi->extra && pi->extra->vrfleak && + (struct bgp_path_info *)pi->extra->vrfleak->parent == + parent_pi) break; if (!pi) { @@ -3127,8 +3135,9 @@ static int uninstall_evpn_route_entry_in_vni_common( /* Find matching route entry. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (pi->extra && - (struct bgp_path_info *)pi->extra->parent == parent_pi) + if (pi->extra && pi->extra->vrfleak && + (struct bgp_path_info *)pi->extra->vrfleak->parent == + parent_pi) break; if (!pi) @@ -3305,8 +3314,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, /* Find matching route entry. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (pi->extra - && (struct bgp_path_info *)pi->extra->parent == parent_pi) + if (pi->extra && pi->extra->vrfleak && + (struct bgp_path_info *)pi->extra->vrfleak->parent == + parent_pi) break; if (!pi) { diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 076248c9f7..55474464e5 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -51,15 +51,15 @@ get_route_parent_evpn(struct bgp_path_info *ri) struct bgp_path_info *parent_ri; /* If not imported (or doesn't have a parent), bail. */ - if (ri->sub_type != BGP_ROUTE_IMPORTED || - !ri->extra || - !ri->extra->parent) + if (ri->sub_type != BGP_ROUTE_IMPORTED || !ri->extra || + !ri->extra->vrfleak || !ri->extra->vrfleak->parent) return NULL; /* Determine parent recursively */ - for (parent_ri = ri->extra->parent; - parent_ri->extra && parent_ri->extra->parent; - parent_ri = parent_ri->extra->parent) + for (parent_ri = ri->extra->vrfleak->parent; + parent_ri->extra && parent_ri->extra->vrfleak && + parent_ri->extra->vrfleak->parent; + parent_ri = parent_ri->extra->vrfleak->parent) ; return parent_ri; @@ -103,12 +103,11 @@ static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi) struct bgp_table *table; struct bgp_dest *dest; - if (pi->sub_type != BGP_ROUTE_IMPORTED || - !pi->extra || - !pi->extra->parent) + if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra || + !pi->extra->vrfleak || !pi->extra->vrfleak->parent) return true; - parent_pi = (struct bgp_path_info *)pi->extra->parent; + parent_pi = (struct bgp_path_info *)pi->extra->vrfleak->parent; dest = parent_pi->net; if (!dest) return true; diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index efadda17b8..36bf752d48 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -185,8 +185,9 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, /* Check if route entry is already present. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (pi->extra && - (struct bgp_path_info *)pi->extra->parent == parent_pi) + if (pi->extra && pi->extra->vrfleak && + (struct bgp_path_info *)pi->extra->vrfleak->parent == + parent_pi) break; if (!pi) { @@ -198,7 +199,11 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, parent_pi->peer, attr_new, dest); SET_FLAG(pi->flags, BGP_PATH_VALID); bgp_path_info_extra_get(pi); - pi->extra->parent = bgp_path_info_lock(parent_pi); + if (!pi->extra->vrfleak) + pi->extra->vrfleak = + XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, + sizeof(struct bgp_path_info_extra_vrfleak)); + pi->extra->vrfleak->parent = bgp_path_info_lock(parent_pi); bgp_dest_lock_node((struct bgp_dest *)parent_pi->net); bgp_path_info_add(dest, pi); } else { @@ -253,9 +258,9 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, /* Find matching route entry. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (pi->extra - && (struct bgp_path_info *)pi->extra->parent == - parent_pi) + if (pi->extra && pi->extra->vrfleak && + (struct bgp_path_info *)pi->extra->vrfleak->parent == + parent_pi) break; if (!pi) { @@ -1548,10 +1553,11 @@ bgp_evpn_path_es_info_new(struct bgp_path_info *pi, vni_t vni) e = bgp_path_info_extra_get(pi); /* If mh_info doesn't exist allocate it */ - mh_info = e->mh_info; + mh_info = e->evpn->mh_info; if (!mh_info) - e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, - sizeof(struct bgp_path_mh_info)); + e->evpn->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 */ es_info = mh_info->es_info; @@ -1604,8 +1610,8 @@ void bgp_evpn_path_es_link(struct bgp_path_info *pi, vni_t vni, esi_t *esi) struct bgp_evpn_es *es; struct bgp *bgp_evpn; - es_info = (pi->extra && pi->extra->mh_info) - ? pi->extra->mh_info->es_info + es_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info) + ? pi->extra->evpn->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))) { @@ -3163,7 +3169,7 @@ bool bgp_evpn_path_es_use_nhg(struct bgp *bgp_vrf, struct bgp_path_info *pi, *nhg_p = 0; /* we don't support NHG for routes leaked from another VRF yet */ - if (pi->extra && pi->extra->bgp_orig) + if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) return false; parent_pi = get_route_parent_evpn(pi); @@ -4670,10 +4676,11 @@ bgp_evpn_path_nh_info_new(struct bgp_path_info *pi) e = bgp_path_info_extra_get(pi); /* If mh_info doesn't exist allocate it */ - mh_info = e->mh_info; + mh_info = e->evpn->mh_info; if (!mh_info) - e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, - sizeof(struct bgp_path_mh_info)); + e->evpn->mh_info = mh_info = + XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, + sizeof(struct bgp_path_mh_info)); /* If nh_info doesn't exist allocate it */ nh_info = mh_info->nh_info; @@ -4738,8 +4745,8 @@ static void bgp_evpn_path_nh_link(struct bgp *bgp_vrf, struct bgp_path_info *pi) return; } - nh_info = (pi->extra && pi->extra->mh_info) - ? pi->extra->mh_info->nh_info + nh_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info) + ? pi->extra->evpn->mh_info->nh_info : NULL; /* if NHG is not being used for this path we don't need to manage the @@ -4805,8 +4812,8 @@ void bgp_evpn_path_nh_del(struct bgp *bgp_vrf, struct bgp_path_info *pi) { struct bgp_path_evpn_nh_info *nh_info; - nh_info = (pi->extra && pi->extra->mh_info) - ? pi->extra->mh_info->nh_info + nh_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info) + ? pi->extra->evpn->mh_info->nh_info : NULL; if (!nh_info) diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 8cee048b69..f141ddd6ef 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -581,32 +581,32 @@ evpn_type2_prefix_vni_mac_copy(struct prefix_evpn *vni_p, static inline struct ethaddr * evpn_type2_path_info_get_mac(const struct bgp_path_info *local_pi) { - assert(local_pi->extra); - return &local_pi->extra->vni_info.mac; + assert(local_pi->extra && local_pi->extra->evpn); + return &local_pi->extra->evpn->vni_info.mac; } /* Get IP of path_info prefix */ static inline struct ipaddr * evpn_type2_path_info_get_ip(const struct bgp_path_info *local_pi) { - assert(local_pi->extra); - return &local_pi->extra->vni_info.ip; + assert(local_pi->extra && local_pi->extra->evpn); + return &local_pi->extra->evpn->vni_info.ip; } /* Set MAC of path_info prefix */ static inline void evpn_type2_path_info_set_mac(struct bgp_path_info *local_pi, const struct ethaddr mac) { - assert(local_pi->extra); - local_pi->extra->vni_info.mac = mac; + assert(local_pi->extra && local_pi->extra->evpn); + local_pi->extra->evpn->vni_info.mac = mac; } /* Set IP of path_info prefix */ static inline void evpn_type2_path_info_set_ip(struct bgp_path_info *local_pi, const struct ipaddr ip) { - assert(local_pi->extra); - local_pi->extra->vni_info.ip = ip; + assert(local_pi->extra && local_pi->extra->evpn); + local_pi->extra->evpn->vni_info.ip = ip; } /* Is the IP empty for the RT's dest? */ diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 7df1423e59..a295ec5a14 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -355,7 +355,8 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p, bgp_path_info_extra_get(path); bool list_began = false; - if (extra->bgp_fs_pbr && listcount(extra->bgp_fs_pbr)) { + if (extra->flowspec && extra->flowspec->bgp_fs_pbr && + listcount(extra->flowspec->bgp_fs_pbr)) { struct listnode *node; struct bgp_pbr_match_entry *bpme; struct bgp_pbr_match *bpm; @@ -363,8 +364,8 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p, list_bpm = list_new(); vty_out(vty, "\tinstalled in PBR"); - for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_pbr, - node, bpme)) { + for (ALL_LIST_ELEMENTS_RO(extra->flowspec->bgp_fs_pbr, node, + bpme)) { bpm = bpme->backpointer; if (listnode_lookup(list_bpm, bpm)) continue; @@ -378,13 +379,14 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p, } list_delete(&list_bpm); } - if (extra->bgp_fs_iprule && listcount(extra->bgp_fs_iprule)) { + if (extra->flowspec && extra->flowspec->bgp_fs_iprule && + listcount(extra->flowspec->bgp_fs_iprule)) { struct listnode *node; struct bgp_pbr_rule *bpr; if (!list_began) vty_out(vty, "\tinstalled in PBR"); - for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_iprule, + for (ALL_LIST_ELEMENTS_RO(extra->flowspec->bgp_fs_iprule, node, bpr)) { if (!bpr->action) continue; diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index d7b18de676..edaaef6021 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -37,6 +37,9 @@ DEFINE_MTYPE(BGPD, BGP_TABLE, "BGP table"); DEFINE_MTYPE(BGPD, BGP_NODE, "BGP node"); DEFINE_MTYPE(BGPD, BGP_ROUTE, "BGP route"); DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA, "BGP ancillary route info"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA_EVPN, "BGP extra info for EVPN"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA_FS, "BGP extra info for flowspec"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA_VRFLEAK, "BGP extra info for vrf leaking"); DEFINE_MTYPE(BGPD, BGP_CONN, "BGP connected"); DEFINE_MTYPE(BGPD, BGP_STATIC, "BGP static"); DEFINE_MTYPE(BGPD, BGP_ADVERTISE_ATTR, "BGP adv attr"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 7b00497714..1256eafd00 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -33,6 +33,9 @@ DECLARE_MTYPE(BGP_TABLE); DECLARE_MTYPE(BGP_NODE); DECLARE_MTYPE(BGP_ROUTE); DECLARE_MTYPE(BGP_ROUTE_EXTRA); +DECLARE_MTYPE(BGP_ROUTE_EXTRA_EVPN); +DECLARE_MTYPE(BGP_ROUTE_EXTRA_FS); +DECLARE_MTYPE(BGP_ROUTE_EXTRA_VRFLEAK); DECLARE_MTYPE(BGP_CONN); DECLARE_MTYPE(BGP_STATIC); DECLARE_MTYPE(BGP_ADVERTISE_ATTR); diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index e920d5753e..f2d1ee0bf3 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -173,10 +173,11 @@ int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1, * if they belong to same VRF */ if (!compare && bpi1->attr->nh_type != NEXTHOP_TYPE_BLACKHOLE) { - if (bpi1->extra && bpi1->extra->bgp_orig && bpi2->extra - && bpi2->extra->bgp_orig) { - if (bpi1->extra->bgp_orig->vrf_id - != bpi2->extra->bgp_orig->vrf_id) { + if (bpi1->extra && bpi1->extra->vrfleak && + bpi1->extra->vrfleak->bgp_orig && bpi2->extra && + bpi2->extra->vrfleak && bpi2->extra->vrfleak->bgp_orig) { + if (bpi1->extra->vrfleak->bgp_orig->vrf_id != + bpi2->extra->vrfleak->bgp_orig->vrf_id) { compare = 1; } } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index da599688ea..ad66720512 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -996,41 +996,6 @@ static void setlabels(struct bgp_path_info *bpi, extra->num_labels = num_labels; } -/* - * make encoded route SIDs match specified encoded sid set - */ -static void setsids(struct bgp_path_info *bpi, - struct in6_addr *sid, - uint32_t num_sids) -{ - uint32_t i; - struct bgp_path_info_extra *extra; - - if (num_sids) - assert(sid); - assert(num_sids <= BGP_MAX_SIDS); - - if (!num_sids) { - if (bpi->extra) - bpi->extra->num_sids = 0; - return; - } - - extra = bgp_path_info_extra_get(bpi); - for (i = 0; i < num_sids; i++) - memcpy(&extra->sid[i].sid, &sid[i], sizeof(struct in6_addr)); - extra->num_sids = num_sids; -} - -static void unsetsids(struct bgp_path_info *bpi) -{ - struct bgp_path_info_extra *extra; - - extra = bgp_path_info_extra_get(bpi); - extra->num_sids = 0; - memset(extra->sid, 0, sizeof(extra->sid)); -} - static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn, struct attr *new_attr, afi_t afi, safi_t safi, @@ -1045,8 +1010,8 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn, bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi); - if (bpi->extra && bpi->extra->bgp_orig) - bgp_nexthop = bpi->extra->bgp_orig; + if (bpi->extra && bpi->extra->vrfleak && bpi->extra->vrfleak->bgp_orig) + bgp_nexthop = bpi->extra->vrfleak->bgp_orig; else bgp_nexthop = bgp_orig; @@ -1098,12 +1063,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, struct bgp_path_info *bpi; struct bgp_path_info *new; struct bgp_path_info_extra *extra; - uint32_t num_sids = 0; struct bgp_path_info *parent = source_bpi; - if (new_attr->srv6_l3vpn || new_attr->srv6_vpn) - num_sids = 1; - if (debug) zlog_debug( "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d", @@ -1132,7 +1093,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, * match parent */ for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - if (bpi->extra && bpi->extra->parent == parent) + if (bpi->extra && bpi->extra->vrfleak && + bpi->extra->vrfleak->parent == parent) break; } @@ -1200,34 +1162,6 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, if (!labelssame) setlabels(bpi, label, num_labels); - /* - * rewrite sid - */ - if (num_sids) { - if (new_attr->srv6_l3vpn) { - setsids(bpi, &new_attr->srv6_l3vpn->sid, - num_sids); - - extra = bgp_path_info_extra_get(bpi); - - extra->sid[0].loc_block_len = - new_attr->srv6_l3vpn->loc_block_len; - extra->sid[0].loc_node_len = - new_attr->srv6_l3vpn->loc_node_len; - extra->sid[0].func_len = - new_attr->srv6_l3vpn->func_len; - extra->sid[0].arg_len = - new_attr->srv6_l3vpn->arg_len; - extra->sid[0].transposition_len = - new_attr->srv6_l3vpn->transposition_len; - extra->sid[0].transposition_offset = - new_attr->srv6_l3vpn - ->transposition_offset; - } else if (new_attr->srv6_vpn) - setsids(bpi, &new_attr->srv6_vpn->sid, - num_sids); - } else - unsetsids(bpi); if (nexthop_self_flag) bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF); @@ -1267,9 +1201,15 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0, to_bgp->peer_self, new_attr, bn); + bgp_path_info_extra_get(new); + if (!new->extra->vrfleak) + new->extra->vrfleak = + XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, + sizeof(struct bgp_path_info_extra_vrfleak)); + if (source_bpi->peer) { extra = bgp_path_info_extra_get(new); - extra->peer_orig = peer_lock(source_bpi->peer); + extra->vrfleak->peer_orig = peer_lock(source_bpi->peer); } if (nexthop_self_flag) @@ -1278,42 +1218,16 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN)) bgp_path_info_set_flag(bn, new, BGP_PATH_ACCEPT_OWN); - bgp_path_info_extra_get(new); - - /* - * rewrite sid - */ - if (num_sids) { - if (new_attr->srv6_l3vpn) { - setsids(new, &new_attr->srv6_l3vpn->sid, num_sids); - - extra = bgp_path_info_extra_get(new); - - extra->sid[0].loc_block_len = - new_attr->srv6_l3vpn->loc_block_len; - extra->sid[0].loc_node_len = - new_attr->srv6_l3vpn->loc_node_len; - extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len; - extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len; - extra->sid[0].transposition_len = - new_attr->srv6_l3vpn->transposition_len; - extra->sid[0].transposition_offset = - new_attr->srv6_l3vpn->transposition_offset; - } else if (new_attr->srv6_vpn) - setsids(new, &new_attr->srv6_vpn->sid, num_sids); - } else - unsetsids(new); - if (num_labels) setlabels(new, label, num_labels); - new->extra->parent = bgp_path_info_lock(parent); + new->extra->vrfleak->parent = bgp_path_info_lock(parent); bgp_dest_lock_node( (struct bgp_dest *)parent->net); if (bgp_orig) - new->extra->bgp_orig = bgp_lock(bgp_orig); + new->extra->vrfleak->bgp_orig = bgp_lock(bgp_orig); if (nexthop_orig) - new->extra->nexthop_orig = *nexthop_orig; + new->extra->vrfleak->nexthop_orig = *nexthop_orig; if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi, source_bpi, new, bgp_orig, p, debug)) @@ -1554,8 +1468,8 @@ vpn_leak_from_vrf_get_per_nexthop_label(afi_t afi, struct bgp_path_info *pi, /* Check the next-hop reachability. * Get the bgp instance where the bgp_path_info originates. */ - if (pi->extra && pi->extra->bgp_orig) - bgp_nexthop = pi->extra->bgp_orig; + if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) + bgp_nexthop = pi->extra->vrfleak->bgp_orig; else bgp_nexthop = from_bgp; @@ -1986,7 +1900,8 @@ void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, /* to */ * match original bpi imported from */ for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - if (bpi->extra && bpi->extra->parent == path_vrf) { + if (bpi->extra && bpi->extra->vrfleak && + bpi->extra->vrfleak->parent == path_vrf) { break; } } @@ -2039,9 +1954,9 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp, bpi->sub_type); if (bpi->sub_type != BGP_ROUTE_IMPORTED) continue; - if (!bpi->extra) + if (!bpi->extra || !bpi->extra->vrfleak) continue; - if ((struct bgp *)bpi->extra->bgp_orig == + if ((struct bgp *)bpi->extra->vrfleak->bgp_orig == from_bgp) { /* delete route */ if (debug) @@ -2055,7 +1970,7 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp, bgp_path_info_delete(bn, bpi); bgp_process(to_bgp, bn, afi, safi); bgp_mplsvpn_path_nh_label_unlink( - bpi->extra->parent); + bpi->extra->vrfleak->parent); } } } @@ -2162,8 +2077,9 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ */ struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi); - if (path_vpn->extra && path_vpn->extra->bgp_orig) - src_vrf = path_vpn->extra->bgp_orig; + if (path_vpn->extra && path_vpn->extra->vrfleak && + path_vpn->extra->vrfleak->bgp_orig) + src_vrf = path_vpn->extra->vrfleak->bgp_orig; else if (src_bgp) src_vrf = src_bgp; else @@ -2429,9 +2345,8 @@ void vpn_leak_to_vrf_update(struct bgp *from_bgp, /* Loop over VRFs */ for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) { - - if (!path_vpn->extra - || path_vpn->extra->bgp_orig != bgp) { /* no loop */ + if (!path_vpn->extra || !path_vpn->extra->vrfleak || + path_vpn->extra->vrfleak->bgp_orig != bgp) { /* no loop */ vpn_leak_to_vrf_update_onevrf(bgp, from_bgp, path_vpn, prd); } @@ -2504,9 +2419,9 @@ void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn) for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - if (bpi->extra - && (struct bgp_path_info *)bpi->extra->parent - == path_vpn) { + if (bpi->extra && bpi->extra->vrfleak && + (struct bgp_path_info *)bpi->extra->vrfleak->parent == + path_vpn) { break; } } @@ -2540,10 +2455,10 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi) for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - if (bpi->extra && bpi->extra->bgp_orig != to_bgp && - bpi->extra->parent && - is_pi_family_vpn(bpi->extra->parent)) { - + if (bpi->extra && bpi->extra->vrfleak && + bpi->extra->vrfleak->bgp_orig != to_bgp && + bpi->extra->vrfleak->parent && + is_pi_family_vpn(bpi->extra->vrfleak->parent)) { /* delete route */ bgp_aggregate_decrement(to_bgp, bgp_dest_get_prefix(bn), @@ -2580,9 +2495,8 @@ void vpn_leak_no_retain(struct bgp *to_bgp, struct bgp *vpn_from, afi_t afi) for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) { for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - - if (bpi->extra && - bpi->extra->bgp_orig == to_bgp) + if (bpi->extra && bpi->extra->vrfleak && + bpi->extra->vrfleak->bgp_orig == to_bgp) continue; if (bpi->sub_type != BGP_ROUTE_NORMAL) @@ -2627,9 +2541,8 @@ void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from, for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - - if (bpi->extra && - bpi->extra->bgp_orig == to_bgp) + if (bpi->extra && bpi->extra->vrfleak && + bpi->extra->vrfleak->bgp_orig == to_bgp) continue; vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from, diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index dcde42146c..62748a9e56 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -298,12 +298,11 @@ static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi) struct bgp_table *table; struct bgp_dest *dest; - if (pi->sub_type != BGP_ROUTE_IMPORTED || - !pi->extra || - !pi->extra->parent) + if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra || + !pi->extra->vrfleak || !pi->extra->vrfleak->parent) return true; - parent_pi = (struct bgp_path_info *)pi->extra->parent; + parent_pi = (struct bgp_path_info *)pi->extra->vrfleak->parent; dest = parent_pi->net; if (!dest) return true; diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 02cfd9c2af..bbc30365c7 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -56,10 +56,11 @@ static int bgp_isvalid_nexthop_for_ebgp(struct bgp_nexthop_cache *bnc, struct bgp_interface *iifp; struct peer *peer; - if (!path->extra || !path->extra->peer_orig) + if (!path->extra || !path->extra->vrfleak || + !path->extra->vrfleak->peer_orig) return false; - peer = path->extra->peer_orig; + peer = path->extra->vrfleak->peer_orig; /* only connected ebgp peers are valid */ if (peer->sort != BGP_PEER_EBGP || peer->ttl != BGP_DEFAULT_TTL || diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index bc9ecff7d9..43682de413 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -1667,8 +1667,8 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa, /* unlink path to bpme */ path = (struct bgp_path_info *)bpr->path; extra = bgp_path_info_extra_get(path); - if (extra->bgp_fs_iprule) - listnode_delete(extra->bgp_fs_iprule, bpr); + if (extra->flowspec && extra->flowspec->bgp_fs_iprule) + listnode_delete(extra->flowspec->bgp_fs_iprule, bpr); bpr->path = NULL; } } @@ -1696,8 +1696,8 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa, /* unlink path to bpme */ path = (struct bgp_path_info *)bpme->path; extra = bgp_path_info_extra_get(path); - if (extra->bgp_fs_pbr) - listnode_delete(extra->bgp_fs_pbr, bpme); + if (extra->flowspec && extra->flowspec->bgp_fs_pbr) + listnode_delete(extra->flowspec->bgp_fs_pbr, bpme); bpme->path = NULL; } } @@ -2342,8 +2342,8 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, struct bgp_path_info_extra *extra = bgp_path_info_extra_get(path); - if (extra && - listnode_lookup_nocheck(extra->bgp_fs_iprule, + if (extra && extra->flowspec && + listnode_lookup_nocheck(extra->flowspec->bgp_fs_iprule, bpr)) { if (BGP_DEBUG(pbr, PBR_ERROR)) zlog_err("%s: entry %p/%p already installed in bgp pbr iprule", @@ -2501,8 +2501,8 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, struct bgp_path_info_extra *extra = bgp_path_info_extra_get(path); - if (extra && - listnode_lookup_nocheck(extra->bgp_fs_pbr, bpme)) { + if (extra && extra->flowspec && + listnode_lookup_nocheck(extra->flowspec->bgp_fs_pbr, bpme)) { if (BGP_DEBUG(pbr, PBR_ERROR)) zlog_err( "%s: entry %p/%p already installed in bgp pbr", diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5f923c598f..839f6d3669 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -188,8 +188,7 @@ static struct bgp_path_info_extra *bgp_path_info_extra_new(void) sizeof(struct bgp_path_info_extra)); new->label[0] = MPLS_INVALID_LABEL; new->num_labels = 0; - new->bgp_fs_pbr = NULL; - new->bgp_fs_iprule = NULL; + new->flowspec = NULL; return new; } @@ -206,8 +205,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) e->damp_info->safi); e->damp_info = NULL; - if (e->parent) { - struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent; + if (e->vrfleak && e->vrfleak->parent) { + struct bgp_path_info *bpi = + (struct bgp_path_info *)e->vrfleak->parent; if (bpi->net) { /* FIXME: since multiple e may have the same e->parent @@ -227,26 +227,34 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) bpi->net = NULL; bgp_path_info_unlock(bpi); } - bgp_path_info_unlock(e->parent); - e->parent = NULL; + bgp_path_info_unlock(e->vrfleak->parent); + e->vrfleak->parent = NULL; } - if (e->bgp_orig) - bgp_unlock(e->bgp_orig); + if (e->vrfleak && e->vrfleak->bgp_orig) + bgp_unlock(e->vrfleak->bgp_orig); - if (e->peer_orig) - peer_unlock(e->peer_orig); + if (e->vrfleak && e->vrfleak->peer_orig) + peer_unlock(e->vrfleak->peer_orig); if (e->aggr_suppressors) list_delete(&e->aggr_suppressors); - if (e->mh_info) - bgp_evpn_path_mh_info_free(e->mh_info); + if (e->evpn && e->evpn->mh_info) + bgp_evpn_path_mh_info_free(e->evpn->mh_info); + + if ((*extra)->flowspec && (*extra)->flowspec->bgp_fs_iprule) + list_delete(&((*extra)->flowspec->bgp_fs_iprule)); + if ((*extra)->flowspec && (*extra)->flowspec->bgp_fs_pbr) + list_delete(&((*extra)->flowspec->bgp_fs_pbr)); + + if (e->evpn) + XFREE(MTYPE_BGP_ROUTE_EXTRA_EVPN, e->evpn); + if (e->flowspec) + XFREE(MTYPE_BGP_ROUTE_EXTRA_FS, e->flowspec); + if (e->vrfleak) + XFREE(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, e->vrfleak); - if ((*extra)->bgp_fs_iprule) - list_delete(&((*extra)->bgp_fs_iprule)); - if ((*extra)->bgp_fs_pbr) - list_delete(&((*extra)->bgp_fs_pbr)); XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); } @@ -257,6 +265,10 @@ struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi) { if (!pi->extra) pi->extra = bgp_path_info_extra_new(); + if (!pi->extra->evpn && pi->net && pi->net->p.family == AF_EVPN) + pi->extra->evpn = + XCALLOC(MTYPE_BGP_ROUTE_EXTRA_EVPN, + sizeof(struct bgp_path_info_extra_evpn)); return pi->extra; } @@ -570,8 +582,9 @@ struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info) return info; for (bpi_ultimate = info; - bpi_ultimate->extra && bpi_ultimate->extra->parent; - bpi_ultimate = bpi_ultimate->extra->parent) + bpi_ultimate->extra && bpi_ultimate->extra->vrfleak && + bpi_ultimate->extra->vrfleak->parent; + bpi_ultimate = bpi_ultimate->extra->vrfleak->parent) ; return bpi_ultimate; @@ -4674,49 +4687,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_set_valid_label(&extra->label[0]); } - /* Update SRv6 SID */ - if (attr->srv6_l3vpn) { - extra = bgp_path_info_extra_get(pi); - if (sid_diff(&extra->sid[0].sid, - &attr->srv6_l3vpn->sid)) { - sid_copy(&extra->sid[0].sid, - &attr->srv6_l3vpn->sid); - extra->num_sids = 1; - - extra->sid[0].loc_block_len = 0; - extra->sid[0].loc_node_len = 0; - extra->sid[0].func_len = 0; - extra->sid[0].arg_len = 0; - extra->sid[0].transposition_len = 0; - extra->sid[0].transposition_offset = 0; - - if (attr->srv6_l3vpn->loc_block_len != 0) { - extra->sid[0].loc_block_len = - attr->srv6_l3vpn->loc_block_len; - extra->sid[0].loc_node_len = - attr->srv6_l3vpn->loc_node_len; - extra->sid[0].func_len = - attr->srv6_l3vpn->func_len; - extra->sid[0].arg_len = - attr->srv6_l3vpn->arg_len; - extra->sid[0].transposition_len = - attr->srv6_l3vpn - ->transposition_len; - extra->sid[0].transposition_offset = - attr->srv6_l3vpn - ->transposition_offset; - } - } - } else if (attr->srv6_vpn) { - extra = bgp_path_info_extra_get(pi); - if (sid_diff(&extra->sid[0].sid, - &attr->srv6_vpn->sid)) { - sid_copy(&extra->sid[0].sid, - &attr->srv6_vpn->sid); - extra->num_sids = 1; - } - } - #ifdef ENABLE_BGP_VNC if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { @@ -4771,8 +4741,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct bgp *bgp_nexthop = bgp; - if (pi->extra && pi->extra->bgp_orig) - bgp_nexthop = pi->extra->bgp_orig; + if (pi->extra && pi->extra->vrfleak && + pi->extra->vrfleak->bgp_orig) + bgp_nexthop = pi->extra->vrfleak->bgp_orig; nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); @@ -4901,29 +4872,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_set_valid_label(&extra->label[0]); } - /* Update SRv6 SID */ - if (safi == SAFI_MPLS_VPN) { - extra = bgp_path_info_extra_get(new); - if (attr->srv6_l3vpn) { - sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid); - extra->num_sids = 1; - - extra->sid[0].loc_block_len = - attr->srv6_l3vpn->loc_block_len; - extra->sid[0].loc_node_len = - attr->srv6_l3vpn->loc_node_len; - extra->sid[0].func_len = attr->srv6_l3vpn->func_len; - extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len; - extra->sid[0].transposition_len = - attr->srv6_l3vpn->transposition_len; - extra->sid[0].transposition_offset = - attr->srv6_l3vpn->transposition_offset; - } else if (attr->srv6_vpn) { - sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid); - extra->num_sids = 1; - } - } - /* Nexthop reachability check. */ if (((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || @@ -9167,26 +9115,27 @@ void route_vty_out(struct vty *vty, const struct prefix *p, * If vrf id of nexthop is different from that of prefix, * set up printable string to append */ - if (path->extra && path->extra->bgp_orig) { + if (path->extra && path->extra->vrfleak && + path->extra->vrfleak->bgp_orig) { const char *self = ""; if (nexthop_self) self = "<"; nexthop_othervrf = true; - nexthop_vrfid = path->extra->bgp_orig->vrf_id; + nexthop_vrfid = path->extra->vrfleak->bgp_orig->vrf_id; - if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN) + if (path->extra->vrfleak->bgp_orig->vrf_id == VRF_UNKNOWN) snprintf(vrf_id_str, sizeof(vrf_id_str), "@%s%s", VRFID_NONE_STR, self); else snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s", - path->extra->bgp_orig->vrf_id, self); + path->extra->vrfleak->bgp_orig->vrf_id, self); - if (path->extra->bgp_orig->inst_type - != BGP_INSTANCE_TYPE_DEFAULT) + if (path->extra->vrfleak->bgp_orig->inst_type != + BGP_INSTANCE_TYPE_DEFAULT) - nexthop_vrfname = path->extra->bgp_orig->name; + nexthop_vrfname = path->extra->vrfleak->bgp_orig->name; } else { const char *self = ""; @@ -10301,11 +10250,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, "\n"); - if (path->extra && path->extra->parent && !json_paths) { + if (path->extra && path->extra->vrfleak && + path->extra->vrfleak->parent && !json_paths) { struct bgp_path_info *parent_ri; struct bgp_dest *dest, *pdest; - parent_ri = (struct bgp_path_info *)path->extra->parent; + parent_ri = + (struct bgp_path_info *)path->extra->vrfleak->parent; dest = parent_ri->net; if (dest && dest->pdest) { pdest = dest->pdest; @@ -10608,17 +10559,18 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, /* * Note when vrfid of nexthop is different from that of prefix */ - if (path->extra && path->extra->bgp_orig) { - vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id; + if (path->extra && path->extra->vrfleak && + path->extra->vrfleak->bgp_orig) { + vrf_id_t nexthop_vrfid = path->extra->vrfleak->bgp_orig->vrf_id; if (json_paths) { const char *vn; - if (path->extra->bgp_orig->inst_type - == BGP_INSTANCE_TYPE_DEFAULT) + if (path->extra->vrfleak->bgp_orig->inst_type == + BGP_INSTANCE_TYPE_DEFAULT) vn = VRF_DEFAULT_NAME; else - vn = path->extra->bgp_orig->name; + vn = path->extra->vrfleak->bgp_orig->name; json_object_string_add(json_path, "nhVrfName", vn); @@ -11013,13 +10965,16 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } /* Remote SID */ - if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) { + if ((path->attr->srv6_l3vpn || path->attr->srv6_vpn) && + safi != SAFI_EVPN) { + struct in6_addr *sid_tmp = + path->attr->srv6_l3vpn ? (&path->attr->srv6_l3vpn->sid) + : (&path->attr->srv6_vpn->sid); if (json_paths) json_object_string_addf(json_path, "remoteSid", "%pI6", - &path->extra->sid[0].sid); + sid_tmp); else - vty_out(vty, " Remote SID: %pI6\n", - &path->extra->sid[0].sid); + vty_out(vty, " Remote SID: %pI6\n", sid_tmp); } /* Label Index */ diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 265587c424..0a6f535b22 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -145,6 +145,54 @@ struct bgp_sid_info { uint8_t transposition_offset; }; +/* new structure for EVPN */ +struct bgp_path_info_extra_evpn { +#define BGP_EVPN_MACIP_TYPE_SVI_IP (1 << 0) + /* af specific flags */ + uint16_t af_flags; + union { + struct ethaddr mac; /* MAC set here for VNI IP table */ + struct ipaddr ip; /* IP set here for VNI MAC table */ + } vni_info; + /* Destination Ethernet Segment links for EVPN MH */ + struct bgp_path_mh_info *mh_info; +}; + +/* new structure for flowspec*/ +struct bgp_path_info_extra_fs { + /* presence of FS pbr firewall based entry */ + struct list *bgp_fs_pbr; + /* presence of FS pbr iprule based entry */ + struct list *bgp_fs_iprule; +}; + +/* new structure for vrfleak*/ +struct bgp_path_info_extra_vrfleak { + void *parent; /* parent from global table */ + /* + * Original bgp instance for imported routes. Needed for: + * 1. Find all routes from a specific vrf for deletion + * 2. vrf context of original nexthop + * + * Store pointer to bgp instance rather than bgp->vrf_id because + * bgp->vrf_id is not always valid (or may change?). + * + * Set to NULL if route is not imported from another bgp instance. + */ + struct bgp *bgp_orig; + /* + * Original bgp session to know if the session is a + * connected EBGP session or not + */ + struct peer *peer_orig; + /* + * Nexthop in context of original bgp instance. Needed + * for label resolution of core mpls routes exported to a vrf. + * Set nexthop_orig.family to 0 if not valid. + */ + struct prefix nexthop_orig; +}; + /* Ancillary information to struct bgp_path_info, * used for uncommonly used data (aggregation, MPLS, etc.) * and lazily allocated to save memory. @@ -163,13 +211,8 @@ struct bgp_path_info_extra { mpls_label_t label[BGP_MAX_LABELS]; uint32_t num_labels; - /* af specific flags */ - uint16_t af_flags; -#define BGP_EVPN_MACIP_TYPE_SVI_IP (1 << 0) - - /* SRv6 SID(s) for SRv6-VPN */ - struct bgp_sid_info sid[BGP_MAX_SIDS]; - uint32_t num_sids; + /*For EVPN*/ + struct bgp_path_info_extra_evpn *evpn; #ifdef ENABLE_BGP_VNC union { @@ -200,50 +243,11 @@ struct bgp_path_info_extra { } vnc; #endif - /* - * For imported routes into a VNI (or VRF) - */ - void *parent; /* parent from global table */ - union { - struct ethaddr mac; /* MAC set here for VNI IP table */ - struct ipaddr ip; /* IP set here for VNI MAC table */ - } vni_info; - - /* - * Some tunnelish parameters follow. Maybe consolidate into an - * internal tunnel structure? - */ - - /* - * Original bgp instance for imported routes. Needed for: - * 1. Find all routes from a specific vrf for deletion - * 2. vrf context of original nexthop - * - * Store pointer to bgp instance rather than bgp->vrf_id because - * bgp->vrf_id is not always valid (or may change?). - * - * Set to NULL if route is not imported from another bgp instance. - */ - struct bgp *bgp_orig; - - /* - * Original bgp session to know if the session is a - * connected EBGP session or not - */ - struct peer *peer_orig; + /* For flowspec*/ + struct bgp_path_info_extra_fs *flowspec; - /* - * Nexthop in context of original bgp instance. Needed - * for label resolution of core mpls routes exported to a vrf. - * Set nexthop_orig.family to 0 if not valid. - */ - struct prefix nexthop_orig; - /* presence of FS pbr firewall based entry */ - struct list *bgp_fs_pbr; - /* presence of FS pbr iprule based entry */ - struct list *bgp_fs_iprule; - /* Destination Ethernet Segment links for EVPN MH */ - struct bgp_path_mh_info *mh_info; + /* For vrf leaking*/ + struct bgp_path_info_extra_vrfleak *vrfleak; }; struct bgp_mplsvpn_label_nh { diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 0990567776..8fa0a4d4f3 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1313,12 +1313,13 @@ route_match_vrl_source_vrf(void *rule, const struct prefix *prefix, if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0) return RMAP_NOMATCH; - if (path->extra == NULL || path->extra->bgp_orig == NULL) + if (path->extra == NULL || path->extra->vrfleak == NULL || + path->extra->vrfleak->bgp_orig == NULL) return RMAP_NOMATCH; - if (strncmp(vrf_name, vrf_id_to_name(path->extra->bgp_orig->vrf_id), - VRF_NAMSIZ) - == 0) + if (strncmp(vrf_name, + vrf_id_to_name(path->extra->vrfleak->bgp_orig->vrf_id), + VRF_NAMSIZ) == 0) return RMAP_MATCH; return RMAP_NOMATCH; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4f773f21a5..f5bee8110e 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10959,6 +10959,29 @@ DEFUN (show_bgp_memory, memstrbuf, sizeof(memstrbuf), count * sizeof(struct bgp_path_info_extra))); + count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_EVPN); + if (count) + vty_out(vty, "%ld BGP extra info for EVPN, using %s of memory\n", + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct bgp_path_info_extra_evpn))); + + count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_FS); + if (count) + vty_out(vty, + "%ld BGP extra info for flowspec, using %s of memory\n", + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct bgp_path_info_extra_fs))); + + count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK); + if (count) + vty_out(vty, + "%ld BGP extra info for vrf leaking, using %s of memory\n", + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct bgp_path_info_extra_vrfleak))); + if ((count = mtype_stats_alloc(MTYPE_BGP_STATIC))) vty_out(vty, "%ld Static routes, using %s of memory\n", count, mtype_memstr(memstrbuf, sizeof(memstrbuf), diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index becd99167f..ac5aef6515 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1308,7 +1308,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, struct bgp_path_info local_info; struct bgp_path_info *mpinfo_cp = &local_info; route_tag_t tag; - struct bgp_sid_info *sid_info; mpls_label_t *labels; uint32_t num_labels = 0; mpls_label_t nh_label; @@ -1348,7 +1347,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, /* * vrf leaking support (will have only one nexthop) */ - if (info->extra && info->extra->bgp_orig) + if (info->extra && info->extra->vrfleak && + info->extra->vrfleak->bgp_orig) nh_othervrf = 1; /* Make Zebra API structure. */ @@ -1364,8 +1364,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, && info->sub_type == BGP_ROUTE_IMPORTED) { /* Obtain peer from parent */ - if (info->extra && info->extra->parent) - peer = ((struct bgp_path_info *)(info->extra->parent)) + if (info->extra && info->extra->vrfleak && + info->extra->vrfleak->parent) + peer = ((struct bgp_path_info *)(info->extra->vrfleak + ->parent)) ->peer; } @@ -1553,15 +1555,21 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, api_nh->weight = nh_weight; - if (mpinfo->extra && !is_evpn && - bgp_is_valid_label(&labels[0]) && - !sid_zero(&mpinfo->extra->sid[0].sid)) { - sid_info = &mpinfo->extra->sid[0]; - - memcpy(&api_nh->seg6_segs, &sid_info->sid, + if (((mpinfo->attr->srv6_l3vpn && + !sid_zero(&mpinfo->attr->srv6_l3vpn->sid)) || + (mpinfo->attr->srv6_vpn && + !sid_zero(&mpinfo->attr->srv6_vpn->sid))) && + !is_evpn && bgp_is_valid_label(&labels[0])) { + struct in6_addr *sid_tmp = + mpinfo->attr->srv6_l3vpn + ? (&mpinfo->attr->srv6_l3vpn->sid) + : (&mpinfo->attr->srv6_vpn->sid); + + memcpy(&api_nh->seg6_segs, sid_tmp, sizeof(api_nh->seg6_segs)); - if (sid_info->transposition_len != 0) { + if (mpinfo->attr->srv6_l3vpn && + mpinfo->attr->srv6_l3vpn->transposition_len != 0) { mpls_lse_decode(labels[0], &nh_label, &ttl, &exp, &bos); @@ -1573,8 +1581,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, } transpose_sid(&api_nh->seg6_segs, nh_label, - sid_info->transposition_offset, - sid_info->transposition_len); + mpinfo->attr->srv6_l3vpn + ->transposition_offset, + mpinfo->attr->srv6_l3vpn + ->transposition_len); } SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6); @@ -2436,8 +2446,14 @@ static int rule_notify_owner(ZAPI_CALLBACK_ARGS) /* link bgp_info to bgp_pbr */ path = (struct bgp_path_info *)bgp_pbr->path; extra = bgp_path_info_extra_get(path); - listnode_add_force(&extra->bgp_fs_iprule, - bgp_pbr); + if (!extra->flowspec) { + extra->flowspec = + XCALLOC(MTYPE_BGP_ROUTE_EXTRA_FS, + sizeof(struct bgp_path_info_extra_fs)); + extra->flowspec->bgp_fs_iprule = NULL; + extra->flowspec->bgp_fs_pbr = NULL; + } + listnode_add_force(&extra->flowspec->bgp_fs_iprule, bgp_pbr); } if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: Received RULE_INSTALLED", __func__); @@ -2539,7 +2555,14 @@ static int ipset_entry_notify_owner(ZAPI_CALLBACK_ARGS) /* link bgp_path_info to bpme */ path = (struct bgp_path_info *)bgp_pbime->path; extra = bgp_path_info_extra_get(path); - listnode_add_force(&extra->bgp_fs_pbr, bgp_pbime); + if (!extra->flowspec) { + extra->flowspec = + XCALLOC(MTYPE_BGP_ROUTE_EXTRA_FS, + sizeof(struct bgp_path_info_extra_fs)); + extra->flowspec->bgp_fs_iprule = NULL; + extra->flowspec->bgp_fs_pbr = NULL; + } + listnode_add_force(&extra->flowspec->bgp_fs_pbr, bgp_pbime); } break; case ZAPI_IPSET_ENTRY_FAIL_REMOVE: diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index a0f7819460..ed2d5e669d 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -10,9 +10,10 @@ /* Macro to update bgp_original based on bpg_path_info */ #define BGP_ORIGINAL_UPDATE(_bgp_orig, _mpinfo, _bgp) \ - ((_mpinfo->extra && _mpinfo->extra->bgp_orig \ - && _mpinfo->sub_type == BGP_ROUTE_IMPORTED) \ - ? (_bgp_orig = _mpinfo->extra->bgp_orig) \ + ((_mpinfo->extra && _mpinfo->extra->vrfleak && \ + _mpinfo->extra->vrfleak->bgp_orig && \ + _mpinfo->sub_type == BGP_ROUTE_IMPORTED) \ + ? (_bgp_orig = _mpinfo->extra->vrfleak->bgp_orig) \ : (_bgp_orig = _bgp)) /* Default weight for next hop, if doing weighted ECMP. */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 29698846c3..252b6d632a 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -420,15 +420,20 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p, vty_out(vty, " label=%u", decode_label(&bpi->extra->label[0])); - if (bpi->extra->num_sids) { - vty_out(vty, " sid=%pI6", &bpi->extra->sid[0].sid); - - if (bpi->extra->sid[0].loc_block_len != 0) { + if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) { + struct in6_addr *sid_tmp = + bpi->attr->srv6_l3vpn + ? (&bpi->attr->srv6_l3vpn->sid) + : (&bpi->attr->srv6_vpn->sid); + vty_out(vty, " sid=%pI6", sid_tmp); + + if (bpi->attr->srv6_l3vpn && + bpi->attr->srv6_l3vpn->loc_block_len != 0) { vty_out(vty, " sid_structure=[%d,%d,%d,%d]", - bpi->extra->sid[0].loc_block_len, - bpi->extra->sid[0].loc_node_len, - bpi->extra->sid[0].func_len, - bpi->extra->sid[0].arg_len); + bpi->attr->srv6_l3vpn->loc_block_len, + bpi->attr->srv6_l3vpn->loc_node_len, + bpi->attr->srv6_l3vpn->func_len, + bpi->attr->srv6_l3vpn->arg_len); } } } |
