summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c32
-rw-r--r--bgpd/bgp_evpn.h19
-rw-r--r--bgpd/bgp_evpn_mh.c45
-rw-r--r--bgpd/bgp_evpn_private.h16
-rw-r--r--bgpd/bgp_flowspec_vty.c12
-rw-r--r--bgpd/bgp_memory.c3
-rw-r--r--bgpd/bgp_memory.h3
-rw-r--r--bgpd/bgp_mpath.c9
-rw-r--r--bgpd/bgp_mplsvpn.c161
-rw-r--r--bgpd/bgp_mplsvpn.h7
-rw-r--r--bgpd/bgp_nht.c5
-rw-r--r--bgpd/bgp_pbr.c16
-rw-r--r--bgpd/bgp_route.c163
-rw-r--r--bgpd/bgp_route.h104
-rw-r--r--bgpd/bgp_routemap.c9
-rw-r--r--bgpd/bgp_vty.c23
-rw-r--r--bgpd/bgp_zebra.c55
-rw-r--r--bgpd/bgp_zebra.h7
-rw-r--r--bgpd/rfapi/rfapi_vty.c21
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);
}
}
}