mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-25 06:10:23 +00:00
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:
parent
49f0484113
commit
98efa5bc6b
@ -1924,7 +1924,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
|
|||||||
|
|
||||||
/* Mark route as self type-2 route */
|
/* Mark route as self type-2 route */
|
||||||
if (flags && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP))
|
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);
|
bgp_path_info_add(dest, tmp_pi);
|
||||||
} else {
|
} else {
|
||||||
tmp_pi = local_pi;
|
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;
|
attr.router_flag = 1;
|
||||||
}
|
}
|
||||||
memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t));
|
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));
|
vni2label(vpn->vni, &(attr.label));
|
||||||
/* Add L3 VNI RTs and RMAC for non IPv6 link-local if
|
/* Add L3 VNI RTs and RMAC for non IPv6 link-local if
|
||||||
* using L3 VNI for type-2 routes also.
|
* 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);
|
attr_new, dest);
|
||||||
SET_FLAG(pi->flags, BGP_PATH_VALID);
|
SET_FLAG(pi->flags, BGP_PATH_VALID);
|
||||||
bgp_path_info_extra_get(pi);
|
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_dest_lock_node((struct bgp_dest *)parent_pi->net);
|
||||||
if (parent_pi->extra) {
|
if (parent_pi->extra) {
|
||||||
memcpy(&pi->extra->label, &parent_pi->extra->label,
|
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. */
|
/* Check if route entry is already present. */
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
||||||
if (pi->extra
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
&& (struct bgp_path_info *)pi->extra->parent == parent_pi)
|
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
|
||||||
|
parent_pi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pi) {
|
if (!pi) {
|
||||||
@ -3031,8 +3038,9 @@ static int install_evpn_route_entry_in_vni_common(
|
|||||||
|
|
||||||
/* Check if route entry is already present. */
|
/* Check if route entry is already present. */
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
||||||
if (pi->extra
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
&& (struct bgp_path_info *)pi->extra->parent == parent_pi)
|
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
|
||||||
|
parent_pi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pi) {
|
if (!pi) {
|
||||||
@ -3127,8 +3135,9 @@ static int uninstall_evpn_route_entry_in_vni_common(
|
|||||||
|
|
||||||
/* Find matching route entry. */
|
/* Find matching route entry. */
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
||||||
if (pi->extra &&
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
(struct bgp_path_info *)pi->extra->parent == parent_pi)
|
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
|
||||||
|
parent_pi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pi)
|
if (!pi)
|
||||||
@ -3305,8 +3314,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
|
|||||||
|
|
||||||
/* Find matching route entry. */
|
/* Find matching route entry. */
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
||||||
if (pi->extra
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
&& (struct bgp_path_info *)pi->extra->parent == parent_pi)
|
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
|
||||||
|
parent_pi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pi) {
|
if (!pi) {
|
||||||
|
@ -51,15 +51,15 @@ get_route_parent_evpn(struct bgp_path_info *ri)
|
|||||||
struct bgp_path_info *parent_ri;
|
struct bgp_path_info *parent_ri;
|
||||||
|
|
||||||
/* If not imported (or doesn't have a parent), bail. */
|
/* If not imported (or doesn't have a parent), bail. */
|
||||||
if (ri->sub_type != BGP_ROUTE_IMPORTED ||
|
if (ri->sub_type != BGP_ROUTE_IMPORTED || !ri->extra ||
|
||||||
!ri->extra ||
|
!ri->extra->vrfleak || !ri->extra->vrfleak->parent)
|
||||||
!ri->extra->parent)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Determine parent recursively */
|
/* Determine parent recursively */
|
||||||
for (parent_ri = ri->extra->parent;
|
for (parent_ri = ri->extra->vrfleak->parent;
|
||||||
parent_ri->extra && parent_ri->extra->parent;
|
parent_ri->extra && parent_ri->extra->vrfleak &&
|
||||||
parent_ri = parent_ri->extra->parent)
|
parent_ri->extra->vrfleak->parent;
|
||||||
|
parent_ri = parent_ri->extra->vrfleak->parent)
|
||||||
;
|
;
|
||||||
|
|
||||||
return parent_ri;
|
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_table *table;
|
||||||
struct bgp_dest *dest;
|
struct bgp_dest *dest;
|
||||||
|
|
||||||
if (pi->sub_type != BGP_ROUTE_IMPORTED ||
|
if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra ||
|
||||||
!pi->extra ||
|
!pi->extra->vrfleak || !pi->extra->vrfleak->parent)
|
||||||
!pi->extra->parent)
|
|
||||||
return true;
|
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;
|
dest = parent_pi->net;
|
||||||
if (!dest)
|
if (!dest)
|
||||||
return true;
|
return true;
|
||||||
|
@ -185,8 +185,9 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
|
|||||||
|
|
||||||
/* Check if route entry is already present. */
|
/* Check if route entry is already present. */
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
||||||
if (pi->extra &&
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
(struct bgp_path_info *)pi->extra->parent == parent_pi)
|
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
|
||||||
|
parent_pi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pi) {
|
if (!pi) {
|
||||||
@ -198,7 +199,11 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
|
|||||||
parent_pi->peer, attr_new, dest);
|
parent_pi->peer, attr_new, dest);
|
||||||
SET_FLAG(pi->flags, BGP_PATH_VALID);
|
SET_FLAG(pi->flags, BGP_PATH_VALID);
|
||||||
bgp_path_info_extra_get(pi);
|
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_dest_lock_node((struct bgp_dest *)parent_pi->net);
|
||||||
bgp_path_info_add(dest, pi);
|
bgp_path_info_add(dest, pi);
|
||||||
} else {
|
} else {
|
||||||
@ -253,9 +258,9 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es,
|
|||||||
|
|
||||||
/* Find matching route entry. */
|
/* Find matching route entry. */
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
|
||||||
if (pi->extra
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
&& (struct bgp_path_info *)pi->extra->parent ==
|
(struct bgp_path_info *)pi->extra->vrfleak->parent ==
|
||||||
parent_pi)
|
parent_pi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pi) {
|
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);
|
e = bgp_path_info_extra_get(pi);
|
||||||
|
|
||||||
/* If mh_info doesn't exist allocate it */
|
/* If mh_info doesn't exist allocate it */
|
||||||
mh_info = e->mh_info;
|
mh_info = e->evpn->mh_info;
|
||||||
if (!mh_info)
|
if (!mh_info)
|
||||||
e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO,
|
e->evpn->mh_info = mh_info =
|
||||||
sizeof(struct bgp_path_mh_info));
|
XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO,
|
||||||
|
sizeof(struct bgp_path_mh_info));
|
||||||
|
|
||||||
/* If es_info doesn't exist allocate it */
|
/* If es_info doesn't exist allocate it */
|
||||||
es_info = mh_info->es_info;
|
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_evpn_es *es;
|
||||||
struct bgp *bgp_evpn;
|
struct bgp *bgp_evpn;
|
||||||
|
|
||||||
es_info = (pi->extra && pi->extra->mh_info)
|
es_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info)
|
||||||
? pi->extra->mh_info->es_info
|
? pi->extra->evpn->mh_info->es_info
|
||||||
: NULL;
|
: NULL;
|
||||||
/* if the esi is zero just unlink the path from the old es */
|
/* if the esi is zero just unlink the path from the old es */
|
||||||
if (!esi || !memcmp(esi, zero_esi, sizeof(*esi))) {
|
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;
|
*nhg_p = 0;
|
||||||
|
|
||||||
/* we don't support NHG for routes leaked from another VRF yet */
|
/* 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;
|
return false;
|
||||||
|
|
||||||
parent_pi = get_route_parent_evpn(pi);
|
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);
|
e = bgp_path_info_extra_get(pi);
|
||||||
|
|
||||||
/* If mh_info doesn't exist allocate it */
|
/* If mh_info doesn't exist allocate it */
|
||||||
mh_info = e->mh_info;
|
mh_info = e->evpn->mh_info;
|
||||||
if (!mh_info)
|
if (!mh_info)
|
||||||
e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO,
|
e->evpn->mh_info = mh_info =
|
||||||
sizeof(struct bgp_path_mh_info));
|
XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO,
|
||||||
|
sizeof(struct bgp_path_mh_info));
|
||||||
|
|
||||||
/* If nh_info doesn't exist allocate it */
|
/* If nh_info doesn't exist allocate it */
|
||||||
nh_info = mh_info->nh_info;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nh_info = (pi->extra && pi->extra->mh_info)
|
nh_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info)
|
||||||
? pi->extra->mh_info->nh_info
|
? pi->extra->evpn->mh_info->nh_info
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
/* if NHG is not being used for this path we don't need to manage the
|
/* 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;
|
struct bgp_path_evpn_nh_info *nh_info;
|
||||||
|
|
||||||
nh_info = (pi->extra && pi->extra->mh_info)
|
nh_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info)
|
||||||
? pi->extra->mh_info->nh_info
|
? pi->extra->evpn->mh_info->nh_info
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
if (!nh_info)
|
if (!nh_info)
|
||||||
|
@ -581,32 +581,32 @@ evpn_type2_prefix_vni_mac_copy(struct prefix_evpn *vni_p,
|
|||||||
static inline struct ethaddr *
|
static inline struct ethaddr *
|
||||||
evpn_type2_path_info_get_mac(const struct bgp_path_info *local_pi)
|
evpn_type2_path_info_get_mac(const struct bgp_path_info *local_pi)
|
||||||
{
|
{
|
||||||
assert(local_pi->extra);
|
assert(local_pi->extra && local_pi->extra->evpn);
|
||||||
return &local_pi->extra->vni_info.mac;
|
return &local_pi->extra->evpn->vni_info.mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get IP of path_info prefix */
|
/* Get IP of path_info prefix */
|
||||||
static inline struct ipaddr *
|
static inline struct ipaddr *
|
||||||
evpn_type2_path_info_get_ip(const struct bgp_path_info *local_pi)
|
evpn_type2_path_info_get_ip(const struct bgp_path_info *local_pi)
|
||||||
{
|
{
|
||||||
assert(local_pi->extra);
|
assert(local_pi->extra && local_pi->extra->evpn);
|
||||||
return &local_pi->extra->vni_info.ip;
|
return &local_pi->extra->evpn->vni_info.ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set MAC of path_info prefix */
|
/* Set MAC of path_info prefix */
|
||||||
static inline void evpn_type2_path_info_set_mac(struct bgp_path_info *local_pi,
|
static inline void evpn_type2_path_info_set_mac(struct bgp_path_info *local_pi,
|
||||||
const struct ethaddr mac)
|
const struct ethaddr mac)
|
||||||
{
|
{
|
||||||
assert(local_pi->extra);
|
assert(local_pi->extra && local_pi->extra->evpn);
|
||||||
local_pi->extra->vni_info.mac = mac;
|
local_pi->extra->evpn->vni_info.mac = mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set IP of path_info prefix */
|
/* Set IP of path_info prefix */
|
||||||
static inline void evpn_type2_path_info_set_ip(struct bgp_path_info *local_pi,
|
static inline void evpn_type2_path_info_set_ip(struct bgp_path_info *local_pi,
|
||||||
const struct ipaddr ip)
|
const struct ipaddr ip)
|
||||||
{
|
{
|
||||||
assert(local_pi->extra);
|
assert(local_pi->extra && local_pi->extra->evpn);
|
||||||
local_pi->extra->vni_info.ip = ip;
|
local_pi->extra->evpn->vni_info.ip = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the IP empty for the RT's dest? */
|
/* Is the IP empty for the RT's dest? */
|
||||||
|
@ -355,7 +355,8 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,
|
|||||||
bgp_path_info_extra_get(path);
|
bgp_path_info_extra_get(path);
|
||||||
bool list_began = false;
|
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 listnode *node;
|
||||||
struct bgp_pbr_match_entry *bpme;
|
struct bgp_pbr_match_entry *bpme;
|
||||||
struct bgp_pbr_match *bpm;
|
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();
|
list_bpm = list_new();
|
||||||
vty_out(vty, "\tinstalled in PBR");
|
vty_out(vty, "\tinstalled in PBR");
|
||||||
for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_pbr,
|
for (ALL_LIST_ELEMENTS_RO(extra->flowspec->bgp_fs_pbr, node,
|
||||||
node, bpme)) {
|
bpme)) {
|
||||||
bpm = bpme->backpointer;
|
bpm = bpme->backpointer;
|
||||||
if (listnode_lookup(list_bpm, bpm))
|
if (listnode_lookup(list_bpm, bpm))
|
||||||
continue;
|
continue;
|
||||||
@ -378,13 +379,14 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,
|
|||||||
}
|
}
|
||||||
list_delete(&list_bpm);
|
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 listnode *node;
|
||||||
struct bgp_pbr_rule *bpr;
|
struct bgp_pbr_rule *bpr;
|
||||||
|
|
||||||
if (!list_began)
|
if (!list_began)
|
||||||
vty_out(vty, "\tinstalled in PBR");
|
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)) {
|
node, bpr)) {
|
||||||
if (!bpr->action)
|
if (!bpr->action)
|
||||||
continue;
|
continue;
|
||||||
|
@ -37,6 +37,9 @@ DEFINE_MTYPE(BGPD, BGP_TABLE, "BGP table");
|
|||||||
DEFINE_MTYPE(BGPD, BGP_NODE, "BGP node");
|
DEFINE_MTYPE(BGPD, BGP_NODE, "BGP node");
|
||||||
DEFINE_MTYPE(BGPD, BGP_ROUTE, "BGP route");
|
DEFINE_MTYPE(BGPD, BGP_ROUTE, "BGP route");
|
||||||
DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA, "BGP ancillary route info");
|
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_CONN, "BGP connected");
|
||||||
DEFINE_MTYPE(BGPD, BGP_STATIC, "BGP static");
|
DEFINE_MTYPE(BGPD, BGP_STATIC, "BGP static");
|
||||||
DEFINE_MTYPE(BGPD, BGP_ADVERTISE_ATTR, "BGP adv attr");
|
DEFINE_MTYPE(BGPD, BGP_ADVERTISE_ATTR, "BGP adv attr");
|
||||||
|
@ -33,6 +33,9 @@ DECLARE_MTYPE(BGP_TABLE);
|
|||||||
DECLARE_MTYPE(BGP_NODE);
|
DECLARE_MTYPE(BGP_NODE);
|
||||||
DECLARE_MTYPE(BGP_ROUTE);
|
DECLARE_MTYPE(BGP_ROUTE);
|
||||||
DECLARE_MTYPE(BGP_ROUTE_EXTRA);
|
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_CONN);
|
||||||
DECLARE_MTYPE(BGP_STATIC);
|
DECLARE_MTYPE(BGP_STATIC);
|
||||||
DECLARE_MTYPE(BGP_ADVERTISE_ATTR);
|
DECLARE_MTYPE(BGP_ADVERTISE_ATTR);
|
||||||
|
@ -173,10 +173,11 @@ int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,
|
|||||||
* if they belong to same VRF
|
* if they belong to same VRF
|
||||||
*/
|
*/
|
||||||
if (!compare && bpi1->attr->nh_type != NEXTHOP_TYPE_BLACKHOLE) {
|
if (!compare && bpi1->attr->nh_type != NEXTHOP_TYPE_BLACKHOLE) {
|
||||||
if (bpi1->extra && bpi1->extra->bgp_orig && bpi2->extra
|
if (bpi1->extra && bpi1->extra->vrfleak &&
|
||||||
&& bpi2->extra->bgp_orig) {
|
bpi1->extra->vrfleak->bgp_orig && bpi2->extra &&
|
||||||
if (bpi1->extra->bgp_orig->vrf_id
|
bpi2->extra->vrfleak && bpi2->extra->vrfleak->bgp_orig) {
|
||||||
!= bpi2->extra->bgp_orig->vrf_id) {
|
if (bpi1->extra->vrfleak->bgp_orig->vrf_id !=
|
||||||
|
bpi2->extra->vrfleak->bgp_orig->vrf_id) {
|
||||||
compare = 1;
|
compare = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,41 +996,6 @@ static void setlabels(struct bgp_path_info *bpi,
|
|||||||
extra->num_labels = num_labels;
|
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,
|
static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
|
||||||
struct attr *new_attr, afi_t afi,
|
struct attr *new_attr, afi_t afi,
|
||||||
safi_t safi,
|
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);
|
bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi);
|
||||||
|
|
||||||
if (bpi->extra && bpi->extra->bgp_orig)
|
if (bpi->extra && bpi->extra->vrfleak && bpi->extra->vrfleak->bgp_orig)
|
||||||
bgp_nexthop = bpi->extra->bgp_orig;
|
bgp_nexthop = bpi->extra->vrfleak->bgp_orig;
|
||||||
else
|
else
|
||||||
bgp_nexthop = bgp_orig;
|
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 *bpi;
|
||||||
struct bgp_path_info *new;
|
struct bgp_path_info *new;
|
||||||
struct bgp_path_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
uint32_t num_sids = 0;
|
|
||||||
struct bgp_path_info *parent = source_bpi;
|
struct bgp_path_info *parent = source_bpi;
|
||||||
|
|
||||||
if (new_attr->srv6_l3vpn || new_attr->srv6_vpn)
|
|
||||||
num_sids = 1;
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
|
"%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
|
* match parent
|
||||||
*/
|
*/
|
||||||
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1200,34 +1162,6 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
|
|||||||
if (!labelssame)
|
if (!labelssame)
|
||||||
setlabels(bpi, label, num_labels);
|
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)
|
if (nexthop_self_flag)
|
||||||
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
|
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,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
|
||||||
to_bgp->peer_self, new_attr, bn);
|
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) {
|
if (source_bpi->peer) {
|
||||||
extra = bgp_path_info_extra_get(new);
|
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)
|
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))
|
if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
|
||||||
bgp_path_info_set_flag(bn, new, 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)
|
if (num_labels)
|
||||||
setlabels(new, label, 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(
|
bgp_dest_lock_node(
|
||||||
(struct bgp_dest *)parent->net);
|
(struct bgp_dest *)parent->net);
|
||||||
if (bgp_orig)
|
if (bgp_orig)
|
||||||
new->extra->bgp_orig = bgp_lock(bgp_orig);
|
new->extra->vrfleak->bgp_orig = bgp_lock(bgp_orig);
|
||||||
if (nexthop_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,
|
if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
|
||||||
source_bpi, new, bgp_orig, p, debug))
|
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.
|
/* Check the next-hop reachability.
|
||||||
* Get the bgp instance where the bgp_path_info originates.
|
* Get the bgp instance where the bgp_path_info originates.
|
||||||
*/
|
*/
|
||||||
if (pi->extra && pi->extra->bgp_orig)
|
if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig)
|
||||||
bgp_nexthop = pi->extra->bgp_orig;
|
bgp_nexthop = pi->extra->vrfleak->bgp_orig;
|
||||||
else
|
else
|
||||||
bgp_nexthop = from_bgp;
|
bgp_nexthop = from_bgp;
|
||||||
|
|
||||||
@ -1986,7 +1900,8 @@ void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, /* to */
|
|||||||
* match original bpi imported from
|
* match original bpi imported from
|
||||||
*/
|
*/
|
||||||
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2039,9 +1954,9 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,
|
|||||||
bpi->sub_type);
|
bpi->sub_type);
|
||||||
if (bpi->sub_type != BGP_ROUTE_IMPORTED)
|
if (bpi->sub_type != BGP_ROUTE_IMPORTED)
|
||||||
continue;
|
continue;
|
||||||
if (!bpi->extra)
|
if (!bpi->extra || !bpi->extra->vrfleak)
|
||||||
continue;
|
continue;
|
||||||
if ((struct bgp *)bpi->extra->bgp_orig ==
|
if ((struct bgp *)bpi->extra->vrfleak->bgp_orig ==
|
||||||
from_bgp) {
|
from_bgp) {
|
||||||
/* delete route */
|
/* delete route */
|
||||||
if (debug)
|
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_path_info_delete(bn, bpi);
|
||||||
bgp_process(to_bgp, bn, afi, safi);
|
bgp_process(to_bgp, bn, afi, safi);
|
||||||
bgp_mplsvpn_path_nh_label_unlink(
|
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);
|
struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi);
|
||||||
|
|
||||||
if (path_vpn->extra && path_vpn->extra->bgp_orig)
|
if (path_vpn->extra && path_vpn->extra->vrfleak &&
|
||||||
src_vrf = path_vpn->extra->bgp_orig;
|
path_vpn->extra->vrfleak->bgp_orig)
|
||||||
|
src_vrf = path_vpn->extra->vrfleak->bgp_orig;
|
||||||
else if (src_bgp)
|
else if (src_bgp)
|
||||||
src_vrf = src_bgp;
|
src_vrf = src_bgp;
|
||||||
else
|
else
|
||||||
@ -2429,9 +2345,8 @@ void vpn_leak_to_vrf_update(struct bgp *from_bgp,
|
|||||||
|
|
||||||
/* Loop over VRFs */
|
/* Loop over VRFs */
|
||||||
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
||||||
|
if (!path_vpn->extra || !path_vpn->extra->vrfleak ||
|
||||||
if (!path_vpn->extra
|
path_vpn->extra->vrfleak->bgp_orig != bgp) { /* no loop */
|
||||||
|| path_vpn->extra->bgp_orig != bgp) { /* no loop */
|
|
||||||
vpn_leak_to_vrf_update_onevrf(bgp, from_bgp, path_vpn,
|
vpn_leak_to_vrf_update_onevrf(bgp, from_bgp, path_vpn,
|
||||||
prd);
|
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;
|
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
|
||||||
bpi = bpi->next) {
|
bpi = bpi->next) {
|
||||||
if (bpi->extra
|
if (bpi->extra && bpi->extra->vrfleak &&
|
||||||
&& (struct bgp_path_info *)bpi->extra->parent
|
(struct bgp_path_info *)bpi->extra->vrfleak->parent ==
|
||||||
== path_vpn) {
|
path_vpn) {
|
||||||
break;
|
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;
|
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
|
||||||
bpi = bpi->next) {
|
bpi = bpi->next) {
|
||||||
if (bpi->extra && bpi->extra->bgp_orig != to_bgp &&
|
if (bpi->extra && bpi->extra->vrfleak &&
|
||||||
bpi->extra->parent &&
|
bpi->extra->vrfleak->bgp_orig != to_bgp &&
|
||||||
is_pi_family_vpn(bpi->extra->parent)) {
|
bpi->extra->vrfleak->parent &&
|
||||||
|
is_pi_family_vpn(bpi->extra->vrfleak->parent)) {
|
||||||
/* delete route */
|
/* delete route */
|
||||||
bgp_aggregate_decrement(to_bgp,
|
bgp_aggregate_decrement(to_bgp,
|
||||||
bgp_dest_get_prefix(bn),
|
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 (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
|
||||||
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
|
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
|
||||||
bpi = bpi->next) {
|
bpi = bpi->next) {
|
||||||
|
if (bpi->extra && bpi->extra->vrfleak &&
|
||||||
if (bpi->extra &&
|
bpi->extra->vrfleak->bgp_orig == to_bgp)
|
||||||
bpi->extra->bgp_orig == to_bgp)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (bpi->sub_type != BGP_ROUTE_NORMAL)
|
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;
|
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
|
||||||
bpi = bpi->next) {
|
bpi = bpi->next) {
|
||||||
|
if (bpi->extra && bpi->extra->vrfleak &&
|
||||||
if (bpi->extra &&
|
bpi->extra->vrfleak->bgp_orig == to_bgp)
|
||||||
bpi->extra->bgp_orig == to_bgp)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from,
|
vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from,
|
||||||
|
@ -298,12 +298,11 @@ static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi)
|
|||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_dest *dest;
|
struct bgp_dest *dest;
|
||||||
|
|
||||||
if (pi->sub_type != BGP_ROUTE_IMPORTED ||
|
if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra ||
|
||||||
!pi->extra ||
|
!pi->extra->vrfleak || !pi->extra->vrfleak->parent)
|
||||||
!pi->extra->parent)
|
|
||||||
return true;
|
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;
|
dest = parent_pi->net;
|
||||||
if (!dest)
|
if (!dest)
|
||||||
return true;
|
return true;
|
||||||
|
@ -56,10 +56,11 @@ static int bgp_isvalid_nexthop_for_ebgp(struct bgp_nexthop_cache *bnc,
|
|||||||
struct bgp_interface *iifp;
|
struct bgp_interface *iifp;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
|
|
||||||
if (!path->extra || !path->extra->peer_orig)
|
if (!path->extra || !path->extra->vrfleak ||
|
||||||
|
!path->extra->vrfleak->peer_orig)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
peer = path->extra->peer_orig;
|
peer = path->extra->vrfleak->peer_orig;
|
||||||
|
|
||||||
/* only connected ebgp peers are valid */
|
/* only connected ebgp peers are valid */
|
||||||
if (peer->sort != BGP_PEER_EBGP || peer->ttl != BGP_DEFAULT_TTL ||
|
if (peer->sort != BGP_PEER_EBGP || peer->ttl != BGP_DEFAULT_TTL ||
|
||||||
|
@ -1667,8 +1667,8 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa,
|
|||||||
/* unlink path to bpme */
|
/* unlink path to bpme */
|
||||||
path = (struct bgp_path_info *)bpr->path;
|
path = (struct bgp_path_info *)bpr->path;
|
||||||
extra = bgp_path_info_extra_get(path);
|
extra = bgp_path_info_extra_get(path);
|
||||||
if (extra->bgp_fs_iprule)
|
if (extra->flowspec && extra->flowspec->bgp_fs_iprule)
|
||||||
listnode_delete(extra->bgp_fs_iprule, bpr);
|
listnode_delete(extra->flowspec->bgp_fs_iprule, bpr);
|
||||||
bpr->path = NULL;
|
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 */
|
/* unlink path to bpme */
|
||||||
path = (struct bgp_path_info *)bpme->path;
|
path = (struct bgp_path_info *)bpme->path;
|
||||||
extra = bgp_path_info_extra_get(path);
|
extra = bgp_path_info_extra_get(path);
|
||||||
if (extra->bgp_fs_pbr)
|
if (extra->flowspec && extra->flowspec->bgp_fs_pbr)
|
||||||
listnode_delete(extra->bgp_fs_pbr, bpme);
|
listnode_delete(extra->flowspec->bgp_fs_pbr, bpme);
|
||||||
bpme->path = NULL;
|
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 =
|
struct bgp_path_info_extra *extra =
|
||||||
bgp_path_info_extra_get(path);
|
bgp_path_info_extra_get(path);
|
||||||
|
|
||||||
if (extra &&
|
if (extra && extra->flowspec &&
|
||||||
listnode_lookup_nocheck(extra->bgp_fs_iprule,
|
listnode_lookup_nocheck(extra->flowspec->bgp_fs_iprule,
|
||||||
bpr)) {
|
bpr)) {
|
||||||
if (BGP_DEBUG(pbr, PBR_ERROR))
|
if (BGP_DEBUG(pbr, PBR_ERROR))
|
||||||
zlog_err("%s: entry %p/%p already installed in bgp pbr iprule",
|
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 =
|
struct bgp_path_info_extra *extra =
|
||||||
bgp_path_info_extra_get(path);
|
bgp_path_info_extra_get(path);
|
||||||
|
|
||||||
if (extra &&
|
if (extra && extra->flowspec &&
|
||||||
listnode_lookup_nocheck(extra->bgp_fs_pbr, bpme)) {
|
listnode_lookup_nocheck(extra->flowspec->bgp_fs_pbr, bpme)) {
|
||||||
if (BGP_DEBUG(pbr, PBR_ERROR))
|
if (BGP_DEBUG(pbr, PBR_ERROR))
|
||||||
zlog_err(
|
zlog_err(
|
||||||
"%s: entry %p/%p already installed in bgp pbr",
|
"%s: entry %p/%p already installed in bgp pbr",
|
||||||
|
163
bgpd/bgp_route.c
163
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));
|
sizeof(struct bgp_path_info_extra));
|
||||||
new->label[0] = MPLS_INVALID_LABEL;
|
new->label[0] = MPLS_INVALID_LABEL;
|
||||||
new->num_labels = 0;
|
new->num_labels = 0;
|
||||||
new->bgp_fs_pbr = NULL;
|
new->flowspec = NULL;
|
||||||
new->bgp_fs_iprule = NULL;
|
|
||||||
return new;
|
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->safi);
|
||||||
|
|
||||||
e->damp_info = NULL;
|
e->damp_info = NULL;
|
||||||
if (e->parent) {
|
if (e->vrfleak && e->vrfleak->parent) {
|
||||||
struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
|
struct bgp_path_info *bpi =
|
||||||
|
(struct bgp_path_info *)e->vrfleak->parent;
|
||||||
|
|
||||||
if (bpi->net) {
|
if (bpi->net) {
|
||||||
/* FIXME: since multiple e may have the same e->parent
|
/* 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;
|
bpi->net = NULL;
|
||||||
bgp_path_info_unlock(bpi);
|
bgp_path_info_unlock(bpi);
|
||||||
}
|
}
|
||||||
bgp_path_info_unlock(e->parent);
|
bgp_path_info_unlock(e->vrfleak->parent);
|
||||||
e->parent = NULL;
|
e->vrfleak->parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->bgp_orig)
|
if (e->vrfleak && e->vrfleak->bgp_orig)
|
||||||
bgp_unlock(e->bgp_orig);
|
bgp_unlock(e->vrfleak->bgp_orig);
|
||||||
|
|
||||||
if (e->peer_orig)
|
if (e->vrfleak && e->vrfleak->peer_orig)
|
||||||
peer_unlock(e->peer_orig);
|
peer_unlock(e->vrfleak->peer_orig);
|
||||||
|
|
||||||
if (e->aggr_suppressors)
|
if (e->aggr_suppressors)
|
||||||
list_delete(&e->aggr_suppressors);
|
list_delete(&e->aggr_suppressors);
|
||||||
|
|
||||||
if (e->mh_info)
|
if (e->evpn && e->evpn->mh_info)
|
||||||
bgp_evpn_path_mh_info_free(e->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);
|
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)
|
if (!pi->extra)
|
||||||
pi->extra = bgp_path_info_extra_new();
|
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;
|
return pi->extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,8 +582,9 @@ struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
|
|||||||
return info;
|
return info;
|
||||||
|
|
||||||
for (bpi_ultimate = info;
|
for (bpi_ultimate = info;
|
||||||
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
bpi_ultimate->extra && bpi_ultimate->extra->vrfleak &&
|
||||||
bpi_ultimate = bpi_ultimate->extra->parent)
|
bpi_ultimate->extra->vrfleak->parent;
|
||||||
|
bpi_ultimate = bpi_ultimate->extra->vrfleak->parent)
|
||||||
;
|
;
|
||||||
|
|
||||||
return bpi_ultimate;
|
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]);
|
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
|
#ifdef ENABLE_BGP_VNC
|
||||||
if ((afi == AFI_IP || afi == AFI_IP6)
|
if ((afi == AFI_IP || afi == AFI_IP6)
|
||||||
&& (safi == SAFI_UNICAST)) {
|
&& (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;
|
struct bgp *bgp_nexthop = bgp;
|
||||||
|
|
||||||
if (pi->extra && pi->extra->bgp_orig)
|
if (pi->extra && pi->extra->vrfleak &&
|
||||||
bgp_nexthop = pi->extra->bgp_orig;
|
pi->extra->vrfleak->bgp_orig)
|
||||||
|
bgp_nexthop = pi->extra->vrfleak->bgp_orig;
|
||||||
|
|
||||||
nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
|
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]);
|
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. */
|
/* Nexthop reachability check. */
|
||||||
if (((afi == AFI_IP || afi == AFI_IP6) &&
|
if (((afi == AFI_IP || afi == AFI_IP6) &&
|
||||||
(safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST ||
|
(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,
|
* If vrf id of nexthop is different from that of prefix,
|
||||||
* set up printable string to append
|
* 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 = "";
|
const char *self = "";
|
||||||
|
|
||||||
if (nexthop_self)
|
if (nexthop_self)
|
||||||
self = "<";
|
self = "<";
|
||||||
|
|
||||||
nexthop_othervrf = true;
|
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),
|
snprintf(vrf_id_str, sizeof(vrf_id_str),
|
||||||
"@%s%s", VRFID_NONE_STR, self);
|
"@%s%s", VRFID_NONE_STR, self);
|
||||||
else
|
else
|
||||||
snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
|
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
|
if (path->extra->vrfleak->bgp_orig->inst_type !=
|
||||||
!= BGP_INSTANCE_TYPE_DEFAULT)
|
BGP_INSTANCE_TYPE_DEFAULT)
|
||||||
|
|
||||||
nexthop_vrfname = path->extra->bgp_orig->name;
|
nexthop_vrfname = path->extra->vrfleak->bgp_orig->name;
|
||||||
} else {
|
} else {
|
||||||
const char *self = "";
|
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");
|
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_path_info *parent_ri;
|
||||||
struct bgp_dest *dest, *pdest;
|
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;
|
dest = parent_ri->net;
|
||||||
if (dest && dest->pdest) {
|
if (dest && dest->pdest) {
|
||||||
pdest = 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
|
* Note when vrfid of nexthop is different from that of prefix
|
||||||
*/
|
*/
|
||||||
if (path->extra && path->extra->bgp_orig) {
|
if (path->extra && path->extra->vrfleak &&
|
||||||
vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
|
path->extra->vrfleak->bgp_orig) {
|
||||||
|
vrf_id_t nexthop_vrfid = path->extra->vrfleak->bgp_orig->vrf_id;
|
||||||
|
|
||||||
if (json_paths) {
|
if (json_paths) {
|
||||||
const char *vn;
|
const char *vn;
|
||||||
|
|
||||||
if (path->extra->bgp_orig->inst_type
|
if (path->extra->vrfleak->bgp_orig->inst_type ==
|
||||||
== BGP_INSTANCE_TYPE_DEFAULT)
|
BGP_INSTANCE_TYPE_DEFAULT)
|
||||||
vn = VRF_DEFAULT_NAME;
|
vn = VRF_DEFAULT_NAME;
|
||||||
else
|
else
|
||||||
vn = path->extra->bgp_orig->name;
|
vn = path->extra->vrfleak->bgp_orig->name;
|
||||||
|
|
||||||
json_object_string_add(json_path, "nhVrfName", vn);
|
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 */
|
/* 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)
|
if (json_paths)
|
||||||
json_object_string_addf(json_path, "remoteSid", "%pI6",
|
json_object_string_addf(json_path, "remoteSid", "%pI6",
|
||||||
&path->extra->sid[0].sid);
|
sid_tmp);
|
||||||
else
|
else
|
||||||
vty_out(vty, " Remote SID: %pI6\n",
|
vty_out(vty, " Remote SID: %pI6\n", sid_tmp);
|
||||||
&path->extra->sid[0].sid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Label Index */
|
/* Label Index */
|
||||||
|
104
bgpd/bgp_route.h
104
bgpd/bgp_route.h
@ -145,6 +145,54 @@ struct bgp_sid_info {
|
|||||||
uint8_t transposition_offset;
|
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,
|
/* Ancillary information to struct bgp_path_info,
|
||||||
* used for uncommonly used data (aggregation, MPLS, etc.)
|
* used for uncommonly used data (aggregation, MPLS, etc.)
|
||||||
* and lazily allocated to save memory.
|
* and lazily allocated to save memory.
|
||||||
@ -163,13 +211,8 @@ struct bgp_path_info_extra {
|
|||||||
mpls_label_t label[BGP_MAX_LABELS];
|
mpls_label_t label[BGP_MAX_LABELS];
|
||||||
uint32_t num_labels;
|
uint32_t num_labels;
|
||||||
|
|
||||||
/* af specific flags */
|
/*For EVPN*/
|
||||||
uint16_t af_flags;
|
struct bgp_path_info_extra_evpn *evpn;
|
||||||
#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;
|
|
||||||
|
|
||||||
#ifdef ENABLE_BGP_VNC
|
#ifdef ENABLE_BGP_VNC
|
||||||
union {
|
union {
|
||||||
@ -200,50 +243,11 @@ struct bgp_path_info_extra {
|
|||||||
} vnc;
|
} vnc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/* For flowspec*/
|
||||||
* For imported routes into a VNI (or VRF)
|
struct bgp_path_info_extra_fs *flowspec;
|
||||||
*/
|
|
||||||
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 vrf leaking*/
|
||||||
* Some tunnelish parameters follow. Maybe consolidate into an
|
struct bgp_path_info_extra_vrfleak *vrfleak;
|
||||||
* 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bgp_mplsvpn_label_nh {
|
struct bgp_mplsvpn_label_nh {
|
||||||
|
@ -1313,12 +1313,13 @@ route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,
|
|||||||
if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)
|
if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)
|
||||||
return RMAP_NOMATCH;
|
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;
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
if (strncmp(vrf_name, vrf_id_to_name(path->extra->bgp_orig->vrf_id),
|
if (strncmp(vrf_name,
|
||||||
VRF_NAMSIZ)
|
vrf_id_to_name(path->extra->vrfleak->bgp_orig->vrf_id),
|
||||||
== 0)
|
VRF_NAMSIZ) == 0)
|
||||||
return RMAP_MATCH;
|
return RMAP_MATCH;
|
||||||
|
|
||||||
return RMAP_NOMATCH;
|
return RMAP_NOMATCH;
|
||||||
|
@ -10959,6 +10959,29 @@ DEFUN (show_bgp_memory,
|
|||||||
memstrbuf, sizeof(memstrbuf),
|
memstrbuf, sizeof(memstrbuf),
|
||||||
count * sizeof(struct bgp_path_info_extra)));
|
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)))
|
if ((count = mtype_stats_alloc(MTYPE_BGP_STATIC)))
|
||||||
vty_out(vty, "%ld Static routes, using %s of memory\n", count,
|
vty_out(vty, "%ld Static routes, using %s of memory\n", count,
|
||||||
mtype_memstr(memstrbuf, sizeof(memstrbuf),
|
mtype_memstr(memstrbuf, sizeof(memstrbuf),
|
||||||
|
@ -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 local_info;
|
||||||
struct bgp_path_info *mpinfo_cp = &local_info;
|
struct bgp_path_info *mpinfo_cp = &local_info;
|
||||||
route_tag_t tag;
|
route_tag_t tag;
|
||||||
struct bgp_sid_info *sid_info;
|
|
||||||
mpls_label_t *labels;
|
mpls_label_t *labels;
|
||||||
uint32_t num_labels = 0;
|
uint32_t num_labels = 0;
|
||||||
mpls_label_t nh_label;
|
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)
|
* 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;
|
nh_othervrf = 1;
|
||||||
|
|
||||||
/* Make Zebra API structure. */
|
/* 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) {
|
&& info->sub_type == BGP_ROUTE_IMPORTED) {
|
||||||
|
|
||||||
/* Obtain peer from parent */
|
/* Obtain peer from parent */
|
||||||
if (info->extra && info->extra->parent)
|
if (info->extra && info->extra->vrfleak &&
|
||||||
peer = ((struct bgp_path_info *)(info->extra->parent))
|
info->extra->vrfleak->parent)
|
||||||
|
peer = ((struct bgp_path_info *)(info->extra->vrfleak
|
||||||
|
->parent))
|
||||||
->peer;
|
->peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1553,15 +1555,21 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
|||||||
|
|
||||||
api_nh->weight = nh_weight;
|
api_nh->weight = nh_weight;
|
||||||
|
|
||||||
if (mpinfo->extra && !is_evpn &&
|
if (((mpinfo->attr->srv6_l3vpn &&
|
||||||
bgp_is_valid_label(&labels[0]) &&
|
!sid_zero(&mpinfo->attr->srv6_l3vpn->sid)) ||
|
||||||
!sid_zero(&mpinfo->extra->sid[0].sid)) {
|
(mpinfo->attr->srv6_vpn &&
|
||||||
sid_info = &mpinfo->extra->sid[0];
|
!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));
|
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,
|
mpls_lse_decode(labels[0], &nh_label, &ttl,
|
||||||
&exp, &bos);
|
&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,
|
transpose_sid(&api_nh->seg6_segs, nh_label,
|
||||||
sid_info->transposition_offset,
|
mpinfo->attr->srv6_l3vpn
|
||||||
sid_info->transposition_len);
|
->transposition_offset,
|
||||||
|
mpinfo->attr->srv6_l3vpn
|
||||||
|
->transposition_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6);
|
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 */
|
/* link bgp_info to bgp_pbr */
|
||||||
path = (struct bgp_path_info *)bgp_pbr->path;
|
path = (struct bgp_path_info *)bgp_pbr->path;
|
||||||
extra = bgp_path_info_extra_get(path);
|
extra = bgp_path_info_extra_get(path);
|
||||||
listnode_add_force(&extra->bgp_fs_iprule,
|
if (!extra->flowspec) {
|
||||||
bgp_pbr);
|
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))
|
if (BGP_DEBUG(zebra, ZEBRA))
|
||||||
zlog_debug("%s: Received RULE_INSTALLED", __func__);
|
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 */
|
/* link bgp_path_info to bpme */
|
||||||
path = (struct bgp_path_info *)bgp_pbime->path;
|
path = (struct bgp_path_info *)bgp_pbime->path;
|
||||||
extra = bgp_path_info_extra_get(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;
|
break;
|
||||||
case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
|
case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
|
||||||
|
@ -10,9 +10,10 @@
|
|||||||
|
|
||||||
/* Macro to update bgp_original based on bpg_path_info */
|
/* Macro to update bgp_original based on bpg_path_info */
|
||||||
#define BGP_ORIGINAL_UPDATE(_bgp_orig, _mpinfo, _bgp) \
|
#define BGP_ORIGINAL_UPDATE(_bgp_orig, _mpinfo, _bgp) \
|
||||||
((_mpinfo->extra && _mpinfo->extra->bgp_orig \
|
((_mpinfo->extra && _mpinfo->extra->vrfleak && \
|
||||||
&& _mpinfo->sub_type == BGP_ROUTE_IMPORTED) \
|
_mpinfo->extra->vrfleak->bgp_orig && \
|
||||||
? (_bgp_orig = _mpinfo->extra->bgp_orig) \
|
_mpinfo->sub_type == BGP_ROUTE_IMPORTED) \
|
||||||
|
? (_bgp_orig = _mpinfo->extra->vrfleak->bgp_orig) \
|
||||||
: (_bgp_orig = _bgp))
|
: (_bgp_orig = _bgp))
|
||||||
|
|
||||||
/* Default weight for next hop, if doing weighted ECMP. */
|
/* Default weight for next hop, if doing weighted ECMP. */
|
||||||
|
@ -420,15 +420,20 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p,
|
|||||||
vty_out(vty, " label=%u",
|
vty_out(vty, " label=%u",
|
||||||
decode_label(&bpi->extra->label[0]));
|
decode_label(&bpi->extra->label[0]));
|
||||||
|
|
||||||
if (bpi->extra->num_sids) {
|
if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) {
|
||||||
vty_out(vty, " sid=%pI6", &bpi->extra->sid[0].sid);
|
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]",
|
vty_out(vty, " sid_structure=[%d,%d,%d,%d]",
|
||||||
bpi->extra->sid[0].loc_block_len,
|
bpi->attr->srv6_l3vpn->loc_block_len,
|
||||||
bpi->extra->sid[0].loc_node_len,
|
bpi->attr->srv6_l3vpn->loc_node_len,
|
||||||
bpi->extra->sid[0].func_len,
|
bpi->attr->srv6_l3vpn->func_len,
|
||||||
bpi->extra->sid[0].arg_len);
|
bpi->attr->srv6_l3vpn->arg_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user