bgpd: bgp_path_info_extra memory optimization

Even if some of the attributes in bgp_path_info_extra are
not used, their memory is still allocated every time. It
cause a waste of memory.
This commit code deletes all unnecessary attributes and
changes the optional attributes to pointer storage. Memory
will only be allocated when they are actually used. After
optimization, extra info related memory is reduced by about
half(~400B -> ~200B).

Signed-off-by: Valerian_He <1826906282@qq.com>
This commit is contained in:
Valerian_He 2023-08-08 10:47:29 +00:00
parent 49f0484113
commit 98efa5bc6b
19 changed files with 328 additions and 378 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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,8 +258,8 @@ 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 ==
if (pi->extra && pi->extra->vrfleak &&
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
parent_pi)
break;
@ -1548,9 +1553,10 @@ 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,
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 */
@ -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,9 +4676,10 @@ 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,
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 */
@ -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)

View File

@ -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? */

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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;

View File

@ -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 ||

View File

@ -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",

View File

@ -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 */

View File

@ -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;
/* For flowspec*/
struct bgp_path_info_extra_fs *flowspec;
/*
* 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;
/*
* 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 {

View File

@ -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;

View File

@ -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),

View File

@ -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];
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_info->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:

View File

@ -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. */

View File

@ -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->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->extra->sid[0].loc_block_len != 0) {
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);
}
}
}