mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 12:16:46 +00:00
Merge pull request #3032 from donaldsharp/bgp_info
`struct bgp_info` to `struct bgp_path_info`
This commit is contained in:
commit
b3c8d34291
@ -104,8 +104,8 @@ bgp_route.[hc]:
|
|||||||
looking for data in hash table, and putting there if missing, refcnt
|
looking for data in hash table, and putting there if missing, refcnt
|
||||||
using pointer to existing data
|
using pointer to existing data
|
||||||
many validity checks
|
many validity checks
|
||||||
get new struct bgp_info (10 words/40 bytes)
|
get new struct bgp_path_info
|
||||||
call bgp_info_add with rn and bgp_info
|
call bgp_path_info_add with rn and bgp_path_info
|
||||||
call bgp_process
|
call bgp_process
|
||||||
|
|
||||||
bgp_routemap.c
|
bgp_routemap.c
|
||||||
@ -149,7 +149,7 @@ bgpd.c
|
|||||||
Question: How much memory does quagga's bgpd use as a function of
|
Question: How much memory does quagga's bgpd use as a function of
|
||||||
state received from peers?
|
state received from peers?
|
||||||
|
|
||||||
It seems that a struct bgp_info is kept for each prefix. The "struct
|
It seems that a struct bgp_path_info is kept for each prefix. The "struct
|
||||||
attr *" is interned, and variables within that are interned. So, 40
|
attr *" is interned, and variables within that are interned. So, 40
|
||||||
bytes are kept per received prefix, plus interned shared values. This
|
bytes are kept per received prefix, plus interned shared values. This
|
||||||
could be 36 if 'int suppress' where changed to a u_char and moved to
|
could be 36 if 'int suppress' where changed to a u_char and moved to
|
||||||
|
@ -90,9 +90,9 @@ struct bgp_advertise *bgp_advertise_new(void)
|
|||||||
|
|
||||||
void bgp_advertise_free(struct bgp_advertise *adv)
|
void bgp_advertise_free(struct bgp_advertise *adv)
|
||||||
{
|
{
|
||||||
if (adv->binfo)
|
if (adv->pathi)
|
||||||
bgp_info_unlock(
|
/* bgp_advertise bgp_path_info reference */
|
||||||
adv->binfo); /* bgp_advertise bgp_info reference */
|
bgp_path_info_unlock(adv->pathi);
|
||||||
XFREE(MTYPE_BGP_ADVERTISE, adv);
|
XFREE(MTYPE_BGP_ADVERTISE, adv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ struct bgp_advertise {
|
|||||||
struct bgp_advertise_attr *baa;
|
struct bgp_advertise_attr *baa;
|
||||||
|
|
||||||
/* BGP info. */
|
/* BGP info. */
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *pathi;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BGP adjacency out. */
|
/* BGP adjacency out. */
|
||||||
@ -113,7 +113,7 @@ struct bgp_synchronize {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* BGP adjacency linked list. */
|
/* BGP adjacency linked list. */
|
||||||
#define BGP_INFO_ADD(N, A, TYPE) \
|
#define BGP_PATH_INFO_ADD(N, A, TYPE) \
|
||||||
do { \
|
do { \
|
||||||
(A)->prev = NULL; \
|
(A)->prev = NULL; \
|
||||||
(A)->next = (N)->TYPE; \
|
(A)->next = (N)->TYPE; \
|
||||||
@ -122,7 +122,7 @@ struct bgp_synchronize {
|
|||||||
(N)->TYPE = (A); \
|
(N)->TYPE = (A); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BGP_INFO_DEL(N, A, TYPE) \
|
#define BGP_PATH_INFO_DEL(N, A, TYPE) \
|
||||||
do { \
|
do { \
|
||||||
if ((A)->next) \
|
if ((A)->next) \
|
||||||
(A)->next->prev = (A)->prev; \
|
(A)->next->prev = (A)->prev; \
|
||||||
@ -132,10 +132,10 @@ struct bgp_synchronize {
|
|||||||
(N)->TYPE = (A)->next; \
|
(N)->TYPE = (A)->next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BGP_ADJ_IN_ADD(N,A) BGP_INFO_ADD(N,A,adj_in)
|
#define BGP_ADJ_IN_ADD(N, A) BGP_PATH_INFO_ADD(N, A, adj_in)
|
||||||
#define BGP_ADJ_IN_DEL(N,A) BGP_INFO_DEL(N,A,adj_in)
|
#define BGP_ADJ_IN_DEL(N, A) BGP_PATH_INFO_DEL(N, A, adj_in)
|
||||||
#define BGP_ADJ_OUT_ADD(N,A) BGP_INFO_ADD(N,A,adj_out)
|
#define BGP_ADJ_OUT_ADD(N, A) BGP_PATH_INFO_ADD(N, A, adj_out)
|
||||||
#define BGP_ADJ_OUT_DEL(N,A) BGP_INFO_DEL(N,A,adj_out)
|
#define BGP_ADJ_OUT_DEL(N, A) BGP_PATH_INFO_DEL(N, A, adj_out)
|
||||||
|
|
||||||
#define BGP_ADV_FIFO_ADD(F, N) \
|
#define BGP_ADV_FIFO_ADD(F, N) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -42,8 +42,8 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg;
|
|||||||
|
|
||||||
/* Utility macro to add and delete BGP dampening information to no
|
/* Utility macro to add and delete BGP dampening information to no
|
||||||
used list. */
|
used list. */
|
||||||
#define BGP_DAMP_LIST_ADD(N,A) BGP_INFO_ADD(N,A,no_reuse_list)
|
#define BGP_DAMP_LIST_ADD(N, A) BGP_PATH_INFO_ADD(N, A, no_reuse_list)
|
||||||
#define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
|
#define BGP_DAMP_LIST_DEL(N, A) BGP_PATH_INFO_DEL(N, A, no_reuse_list)
|
||||||
|
|
||||||
/* Calculate reuse list index by penalty value. */
|
/* Calculate reuse list index by penalty value. */
|
||||||
static int bgp_reuse_index(int penalty)
|
static int bgp_reuse_index(int penalty)
|
||||||
@ -128,7 +128,7 @@ static int bgp_reuse_timer(struct thread *t)
|
|||||||
|
|
||||||
/* 3. if ( the saved list head pointer is non-empty ) */
|
/* 3. if ( the saved list head pointer is non-empty ) */
|
||||||
for (; bdi; bdi = next) {
|
for (; bdi; bdi = next) {
|
||||||
struct bgp *bgp = bdi->binfo->peer->bgp;
|
struct bgp *bgp = bdi->path->peer->bgp;
|
||||||
|
|
||||||
next = bdi->next;
|
next = bdi->next;
|
||||||
|
|
||||||
@ -145,15 +145,15 @@ static int bgp_reuse_timer(struct thread *t)
|
|||||||
/* if (figure-of-merit < reuse). */
|
/* if (figure-of-merit < reuse). */
|
||||||
if (bdi->penalty < damp->reuse_limit) {
|
if (bdi->penalty < damp->reuse_limit) {
|
||||||
/* Reuse the route. */
|
/* Reuse the route. */
|
||||||
bgp_info_unset_flag(bdi->rn, bdi->binfo,
|
bgp_path_info_unset_flag(bdi->rn, bdi->path,
|
||||||
BGP_INFO_DAMPED);
|
BGP_PATH_DAMPED);
|
||||||
bdi->suppress_time = 0;
|
bdi->suppress_time = 0;
|
||||||
|
|
||||||
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
|
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
|
||||||
bgp_info_unset_flag(bdi->rn, bdi->binfo,
|
bgp_path_info_unset_flag(bdi->rn, bdi->path,
|
||||||
BGP_INFO_HISTORY);
|
BGP_PATH_HISTORY);
|
||||||
bgp_aggregate_increment(bgp, &bdi->rn->p,
|
bgp_aggregate_increment(bgp, &bdi->rn->p,
|
||||||
bdi->binfo, bdi->afi,
|
bdi->path, bdi->afi,
|
||||||
bdi->safi);
|
bdi->safi);
|
||||||
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
|
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
|
||||||
}
|
}
|
||||||
@ -172,8 +172,8 @@ static int bgp_reuse_timer(struct thread *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
|
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
|
||||||
int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
|
||||||
safi_t safi, int attr_change)
|
afi_t afi, safi_t safi, int attr_change)
|
||||||
{
|
{
|
||||||
time_t t_now;
|
time_t t_now;
|
||||||
struct bgp_damp_info *bdi = NULL;
|
struct bgp_damp_info *bdi = NULL;
|
||||||
@ -182,8 +182,8 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
t_now = bgp_clock();
|
t_now = bgp_clock();
|
||||||
|
|
||||||
/* Processing Unreachable Messages. */
|
/* Processing Unreachable Messages. */
|
||||||
if (binfo->extra)
|
if (path->extra)
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
if (bdi == NULL) {
|
if (bdi == NULL) {
|
||||||
/* If there is no previous stability history. */
|
/* If there is no previous stability history. */
|
||||||
@ -195,7 +195,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
|
|
||||||
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
|
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
|
||||||
sizeof(struct bgp_damp_info));
|
sizeof(struct bgp_damp_info));
|
||||||
bdi->binfo = binfo;
|
bdi->path = path;
|
||||||
bdi->rn = rn;
|
bdi->rn = rn;
|
||||||
bdi->penalty =
|
bdi->penalty =
|
||||||
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
|
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
|
||||||
@ -205,7 +205,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
bdi->index = -1;
|
bdi->index = -1;
|
||||||
bdi->afi = afi;
|
bdi->afi = afi;
|
||||||
bdi->safi = safi;
|
bdi->safi = safi;
|
||||||
(bgp_info_extra_get(binfo))->damp_info = bdi;
|
(bgp_path_info_extra_get(path))->damp_info = bdi;
|
||||||
BGP_DAMP_LIST_ADD(damp, bdi);
|
BGP_DAMP_LIST_ADD(damp, bdi);
|
||||||
} else {
|
} else {
|
||||||
last_penalty = bdi->penalty;
|
last_penalty = bdi->penalty;
|
||||||
@ -222,16 +222,16 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
bdi->flap++;
|
bdi->flap++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((rn == bdi->rn) && (binfo == bdi->binfo));
|
assert((rn == bdi->rn) && (path == bdi->path));
|
||||||
|
|
||||||
bdi->lastrecord = BGP_RECORD_WITHDRAW;
|
bdi->lastrecord = BGP_RECORD_WITHDRAW;
|
||||||
bdi->t_updated = t_now;
|
bdi->t_updated = t_now;
|
||||||
|
|
||||||
/* Make this route as historical status. */
|
/* Make this route as historical status. */
|
||||||
bgp_info_set_flag(rn, binfo, BGP_INFO_HISTORY);
|
bgp_path_info_set_flag(rn, path, BGP_PATH_HISTORY);
|
||||||
|
|
||||||
/* Remove the route from a reuse list if it is on one. */
|
/* Remove the route from a reuse list if it is on one. */
|
||||||
if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)) {
|
if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) {
|
||||||
/* If decay rate isn't equal to 0, reinsert brn. */
|
/* If decay rate isn't equal to 0, reinsert brn. */
|
||||||
if (bdi->penalty != last_penalty && bdi->index >= 0) {
|
if (bdi->penalty != last_penalty && bdi->index >= 0) {
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
@ -243,7 +243,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
/* If not suppressed before, do annonunce this withdraw and
|
/* If not suppressed before, do annonunce this withdraw and
|
||||||
insert into reuse_list. */
|
insert into reuse_list. */
|
||||||
if (bdi->penalty >= damp->suppress_value) {
|
if (bdi->penalty >= damp->suppress_value) {
|
||||||
bgp_info_set_flag(rn, binfo, BGP_INFO_DAMPED);
|
bgp_path_info_set_flag(rn, path, BGP_PATH_DAMPED);
|
||||||
bdi->suppress_time = t_now;
|
bdi->suppress_time = t_now;
|
||||||
BGP_DAMP_LIST_DEL(damp, bdi);
|
BGP_DAMP_LIST_DEL(damp, bdi);
|
||||||
bgp_reuse_list_add(bdi);
|
bgp_reuse_list_add(bdi);
|
||||||
@ -252,28 +252,28 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
return BGP_DAMP_USED;
|
return BGP_DAMP_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn, afi_t afi,
|
||||||
safi_t safi)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
time_t t_now;
|
time_t t_now;
|
||||||
struct bgp_damp_info *bdi;
|
struct bgp_damp_info *bdi;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!binfo->extra || !((bdi = binfo->extra->damp_info)))
|
if (!path->extra || !((bdi = path->extra->damp_info)))
|
||||||
return BGP_DAMP_USED;
|
return BGP_DAMP_USED;
|
||||||
|
|
||||||
t_now = bgp_clock();
|
t_now = bgp_clock();
|
||||||
bgp_info_unset_flag(rn, binfo, BGP_INFO_HISTORY);
|
bgp_path_info_unset_flag(rn, path, BGP_PATH_HISTORY);
|
||||||
|
|
||||||
bdi->lastrecord = BGP_RECORD_UPDATE;
|
bdi->lastrecord = BGP_RECORD_UPDATE;
|
||||||
bdi->penalty = bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty);
|
bdi->penalty = bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty);
|
||||||
|
|
||||||
if (!CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
|
if (!CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
|
||||||
&& (bdi->penalty < damp->suppress_value))
|
&& (bdi->penalty < damp->suppress_value))
|
||||||
status = BGP_DAMP_USED;
|
status = BGP_DAMP_USED;
|
||||||
else if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
|
else if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
|
||||||
&& (bdi->penalty < damp->reuse_limit)) {
|
&& (bdi->penalty < damp->reuse_limit)) {
|
||||||
bgp_info_unset_flag(rn, binfo, BGP_INFO_DAMPED);
|
bgp_path_info_unset_flag(rn, path, BGP_PATH_DAMPED);
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
BGP_DAMP_LIST_ADD(damp, bdi);
|
BGP_DAMP_LIST_ADD(damp, bdi);
|
||||||
bdi->suppress_time = 0;
|
bdi->suppress_time = 0;
|
||||||
@ -290,28 +290,29 @@ int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove dampening information and history route. */
|
/* Remove dampening information and history route. */
|
||||||
int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
|
int bgp_damp_scan(struct bgp_path_info *path, afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
time_t t_now, t_diff;
|
time_t t_now, t_diff;
|
||||||
struct bgp_damp_info *bdi;
|
struct bgp_damp_info *bdi;
|
||||||
|
|
||||||
assert(binfo->extra && binfo->extra->damp_info);
|
assert(path->extra && path->extra->damp_info);
|
||||||
|
|
||||||
t_now = bgp_clock();
|
t_now = bgp_clock();
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
|
||||||
t_diff = t_now - bdi->suppress_time;
|
t_diff = t_now - bdi->suppress_time;
|
||||||
|
|
||||||
if (t_diff >= damp->max_suppress_time) {
|
if (t_diff >= damp->max_suppress_time) {
|
||||||
bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_DAMPED);
|
bgp_path_info_unset_flag(bdi->rn, path,
|
||||||
|
BGP_PATH_DAMPED);
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
BGP_DAMP_LIST_ADD(damp, bdi);
|
BGP_DAMP_LIST_ADD(damp, bdi);
|
||||||
bdi->penalty = damp->reuse_limit;
|
bdi->penalty = damp->reuse_limit;
|
||||||
bdi->suppress_time = 0;
|
bdi->suppress_time = 0;
|
||||||
bdi->t_updated = t_now;
|
bdi->t_updated = t_now;
|
||||||
|
|
||||||
/* Need to announce UPDATE once this binfo is usable
|
/* Need to announce UPDATE once this path is usable
|
||||||
* again. */
|
* again. */
|
||||||
if (bdi->lastrecord == BGP_RECORD_UPDATE)
|
if (bdi->lastrecord == BGP_RECORD_UPDATE)
|
||||||
return 1;
|
return 1;
|
||||||
@ -323,7 +324,7 @@ int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
|
|||||||
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
|
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
|
||||||
|
|
||||||
if (bdi->penalty <= damp->reuse_limit / 2.0) {
|
if (bdi->penalty <= damp->reuse_limit / 2.0) {
|
||||||
/* release the bdi, bdi->binfo. */
|
/* release the bdi, bdi->path. */
|
||||||
bgp_damp_info_free(bdi, 1);
|
bgp_damp_info_free(bdi, 1);
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
@ -334,23 +335,24 @@ int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
|
|||||||
|
|
||||||
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
|
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
|
||||||
{
|
{
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
|
|
||||||
if (!bdi)
|
if (!bdi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
binfo = bdi->binfo;
|
path = bdi->path;
|
||||||
binfo->extra->damp_info = NULL;
|
path->extra->damp_info = NULL;
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
else
|
else
|
||||||
BGP_DAMP_LIST_DEL(damp, bdi);
|
BGP_DAMP_LIST_DEL(damp, bdi);
|
||||||
|
|
||||||
bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_HISTORY | BGP_INFO_DAMPED);
|
bgp_path_info_unset_flag(bdi->rn, path,
|
||||||
|
BGP_PATH_HISTORY | BGP_PATH_DAMPED);
|
||||||
|
|
||||||
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
|
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
|
||||||
bgp_info_delete(bdi->rn, binfo);
|
bgp_path_info_delete(bdi->rn, path);
|
||||||
|
|
||||||
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
|
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
|
||||||
}
|
}
|
||||||
@ -588,7 +590,7 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
|
||||||
json_object *json_path)
|
json_object *json_path)
|
||||||
{
|
{
|
||||||
struct bgp_damp_info *bdi;
|
struct bgp_damp_info *bdi;
|
||||||
@ -596,11 +598,11 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
char timebuf[BGP_UPTIME_LEN];
|
char timebuf[BGP_UPTIME_LEN];
|
||||||
int penalty;
|
int penalty;
|
||||||
|
|
||||||
if (!binfo->extra)
|
if (!path->extra)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* BGP dampening information. */
|
/* BGP dampening information. */
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
/* If dampening is not enabled or there is no dampening information,
|
/* If dampening is not enabled or there is no dampening information,
|
||||||
return immediately. */
|
return immediately. */
|
||||||
@ -618,8 +620,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1,
|
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
|
||||||
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
|
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
|
||||||
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
|
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
|
||||||
json_path);
|
json_path);
|
||||||
} else {
|
} else {
|
||||||
@ -629,8 +631,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
|
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
|
||||||
json_path));
|
json_path));
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
|
||||||
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
|
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
|
||||||
vty_out(vty, ", reuse in %s",
|
vty_out(vty, ", reuse in %s",
|
||||||
bgp_get_reuse_time(penalty, timebuf,
|
bgp_get_reuse_time(penalty, timebuf,
|
||||||
BGP_UPTIME_LEN, 0,
|
BGP_UPTIME_LEN, 0,
|
||||||
@ -640,7 +642,7 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
|
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
|
||||||
char *timebuf, size_t len, bool use_json,
|
char *timebuf, size_t len, bool use_json,
|
||||||
json_object *json)
|
json_object *json)
|
||||||
{
|
{
|
||||||
@ -648,11 +650,11 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
time_t t_now, t_diff;
|
time_t t_now, t_diff;
|
||||||
int penalty;
|
int penalty;
|
||||||
|
|
||||||
if (!binfo->extra)
|
if (!path->extra)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* BGP dampening information. */
|
/* BGP dampening information. */
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
/* If dampening is not enabled or there is no dampening information,
|
/* If dampening is not enabled or there is no dampening information,
|
||||||
return immediately. */
|
return immediately. */
|
||||||
|
@ -43,8 +43,8 @@ struct bgp_damp_info {
|
|||||||
/* Time of route start to be suppressed. */
|
/* Time of route start to be suppressed. */
|
||||||
time_t suppress_time;
|
time_t suppress_time;
|
||||||
|
|
||||||
/* Back reference to bgp_info. */
|
/* Back reference to bgp_path_info. */
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
|
|
||||||
/* Back reference to bgp_node. */
|
/* Back reference to bgp_node. */
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
@ -130,18 +130,19 @@ struct bgp_damp_config {
|
|||||||
extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int,
|
extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int,
|
||||||
unsigned int, time_t);
|
unsigned int, time_t);
|
||||||
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
|
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
|
||||||
extern int bgp_damp_withdraw(struct bgp_info *, struct bgp_node *, afi_t,
|
extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
|
||||||
safi_t, int);
|
afi_t afi, safi_t safi, int attr_change);
|
||||||
extern int bgp_damp_update(struct bgp_info *, struct bgp_node *, afi_t, safi_t);
|
extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn,
|
||||||
extern int bgp_damp_scan(struct bgp_info *, afi_t, safi_t);
|
afi_t afi, safi_t saff);
|
||||||
extern void bgp_damp_info_free(struct bgp_damp_info *, int);
|
extern int bgp_damp_scan(struct bgp_path_info *path, afi_t afi, safi_t safi);
|
||||||
|
extern void bgp_damp_info_free(struct bgp_damp_info *path, int withdraw);
|
||||||
extern void bgp_damp_info_clean(void);
|
extern void bgp_damp_info_clean(void);
|
||||||
extern int bgp_damp_decay(time_t, int);
|
extern int bgp_damp_decay(time_t, int);
|
||||||
extern void bgp_config_write_damp(struct vty *);
|
extern void bgp_config_write_damp(struct vty *);
|
||||||
extern void bgp_damp_info_vty(struct vty *, struct bgp_info *,
|
extern void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
|
||||||
json_object *json_path);
|
json_object *json_path);
|
||||||
extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
|
extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
char *timebuf, size_t len,
|
char *timebuf, size_t len,
|
||||||
bool use_json, json_object *json);
|
bool use_json, json_object *json);
|
||||||
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
|
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
|
||||||
|
@ -299,9 +299,9 @@ static void bgp_dump_routes_index_table(struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
static struct bgp_path_info *
|
||||||
struct bgp_info *info,
|
bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
||||||
unsigned int seq)
|
struct bgp_path_info *path, unsigned int seq)
|
||||||
{
|
{
|
||||||
struct stream *obuf;
|
struct stream *obuf;
|
||||||
size_t sizep;
|
size_t sizep;
|
||||||
@ -349,18 +349,18 @@ static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
|||||||
stream_putw(obuf, 0);
|
stream_putw(obuf, 0);
|
||||||
|
|
||||||
endp = stream_get_endp(obuf);
|
endp = stream_get_endp(obuf);
|
||||||
for (; info; info = info->next) {
|
for (; path; path = path->next) {
|
||||||
size_t cur_endp;
|
size_t cur_endp;
|
||||||
|
|
||||||
/* Peer index */
|
/* Peer index */
|
||||||
stream_putw(obuf, info->peer->table_dump_index);
|
stream_putw(obuf, path->peer->table_dump_index);
|
||||||
|
|
||||||
/* Originated */
|
/* Originated */
|
||||||
stream_putl(obuf, time(NULL) - (bgp_clock() - info->uptime));
|
stream_putl(obuf, time(NULL) - (bgp_clock() - path->uptime));
|
||||||
|
|
||||||
/* Dump attribute. */
|
/* Dump attribute. */
|
||||||
/* Skip prefix & AFI/SAFI for MP_NLRI */
|
/* Skip prefix & AFI/SAFI for MP_NLRI */
|
||||||
bgp_dump_routes_attr(obuf, info->attr, &rn->p);
|
bgp_dump_routes_attr(obuf, path->attr, &rn->p);
|
||||||
|
|
||||||
cur_endp = stream_get_endp(obuf);
|
cur_endp = stream_get_endp(obuf);
|
||||||
if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
|
if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
|
||||||
@ -379,7 +379,7 @@ static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
|||||||
bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
|
bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
|
||||||
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_routes.fp);
|
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_routes.fp);
|
||||||
|
|
||||||
return info;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
|||||||
static unsigned int bgp_dump_routes_func(int afi, int first_run,
|
static unsigned int bgp_dump_routes_func(int afi, int first_run,
|
||||||
unsigned int seq)
|
unsigned int seq)
|
||||||
{
|
{
|
||||||
struct bgp_info *info;
|
struct bgp_path_info *path;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
@ -410,9 +410,9 @@ static unsigned int bgp_dump_routes_func(int afi, int first_run,
|
|||||||
table = bgp->rib[afi][SAFI_UNICAST];
|
table = bgp->rib[afi][SAFI_UNICAST];
|
||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
info = rn->info;
|
path = rn->info;
|
||||||
while (info) {
|
while (path) {
|
||||||
info = bgp_dump_route_node_record(afi, rn, info, seq);
|
path = bgp_dump_route_node_record(afi, rn, path, seq);
|
||||||
seq++;
|
seq++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
825
bgpd/bgp_evpn.c
825
bgpd/bgp_evpn.c
File diff suppressed because it is too large
Load Diff
@ -76,9 +76,9 @@ static inline int advertise_type5_routes(struct bgp *bgp_vrf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Flag if the route's parent is a EVPN route. */
|
/* Flag if the route's parent is a EVPN route. */
|
||||||
static inline int is_route_parent_evpn(struct bgp_info *ri)
|
static inline int is_route_parent_evpn(struct bgp_path_info *ri)
|
||||||
{
|
{
|
||||||
struct bgp_info *parent_ri;
|
struct bgp_path_info *parent_ri;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ static inline int is_route_parent_evpn(struct bgp_info *ri)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* See if the parent is of family L2VPN/EVPN */
|
/* See if the parent is of family L2VPN/EVPN */
|
||||||
parent_ri = (struct bgp_info *)ri->extra->parent;
|
parent_ri = (struct bgp_path_info *)ri->extra->parent;
|
||||||
rn = parent_ri->net;
|
rn = parent_ri->net;
|
||||||
if (!rn)
|
if (!rn)
|
||||||
return 0;
|
return 0;
|
||||||
@ -124,9 +124,9 @@ extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
|
|||||||
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
|
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
|
||||||
struct bgp_nlri *packet, int withdraw);
|
struct bgp_nlri *packet, int withdraw);
|
||||||
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct prefix *p, struct bgp_info *ri);
|
struct prefix *p, struct bgp_path_info *ri);
|
||||||
extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct prefix *p, struct bgp_info *ri);
|
struct prefix *p, struct bgp_path_info *ri);
|
||||||
extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
|
extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
|
||||||
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
||||||
struct ethaddr *mac, struct ipaddr *ip);
|
struct ethaddr *mac, struct ipaddr *ip);
|
||||||
|
@ -536,7 +536,7 @@ static void show_esi_routes(struct bgp *bgp,
|
|||||||
{
|
{
|
||||||
int header = 1;
|
int header = 1;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint32_t prefix_cnt, path_cnt;
|
uint32_t prefix_cnt, path_cnt;
|
||||||
uint64_t tbl_ver;
|
uint64_t tbl_ver;
|
||||||
|
|
||||||
@ -573,13 +573,13 @@ static void show_esi_routes(struct bgp *bgp,
|
|||||||
/* For EVPN, the prefix is displayed for each path (to fit in
|
/* For EVPN, the prefix is displayed for each path (to fit in
|
||||||
* with code that already exists).
|
* with code that already exists).
|
||||||
*/
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN, json_path);
|
route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN, json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_object_array_add(json_paths, json_path);
|
json_object_array_add(json_paths, json_path);
|
||||||
@ -616,7 +616,7 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
|
|||||||
json_object *json)
|
json_object *json)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
uint64_t tbl_ver;
|
uint64_t tbl_ver;
|
||||||
@ -660,18 +660,18 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
|
|||||||
/* For EVPN, the prefix is displayed for each path (to fit in
|
/* For EVPN, the prefix is displayed for each path (to fit in
|
||||||
* with code that already exists).
|
* with code that already exists).
|
||||||
*/
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (vtep_ip.s_addr
|
if (vtep_ip.s_addr
|
||||||
&& !IPV4_ADDR_SAME(&(vtep_ip),
|
&& !IPV4_ADDR_SAME(&(vtep_ip),
|
||||||
&(ri->attr->nexthop)))
|
&(pi->attr->nexthop)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN, json_path);
|
route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN, json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_object_array_add(json_paths, json_path);
|
json_object_array_add(json_paths, json_path);
|
||||||
@ -990,7 +990,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_node *rm;
|
struct bgp_node *rm;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
int rd_header;
|
int rd_header;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
|
|
||||||
@ -1046,14 +1046,14 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
tbl_ver = table->version;
|
tbl_ver = table->version;
|
||||||
|
|
||||||
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm))
|
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm))
|
||||||
for (ri = rm->info; ri; ri = ri->next) {
|
for (pi = rm->info; pi; pi = pi->next) {
|
||||||
total_count++;
|
total_count++;
|
||||||
if (type == bgp_show_type_neighbor) {
|
if (type == bgp_show_type_neighbor) {
|
||||||
union sockunion *su = output_arg;
|
union sockunion *su = output_arg;
|
||||||
|
|
||||||
if (ri->peer->su_remote == NULL
|
if (pi->peer->su_remote == NULL
|
||||||
|| !sockunion_same(
|
|| !sockunion_same(
|
||||||
ri->peer->su_remote, su))
|
pi->peer->su_remote, su))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (header == 0) {
|
if (header == 0) {
|
||||||
@ -1162,14 +1162,14 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
else
|
else
|
||||||
json_array = NULL;
|
json_array = NULL;
|
||||||
if (option == SHOW_DISPLAY_TAGS)
|
if (option == SHOW_DISPLAY_TAGS)
|
||||||
route_vty_out_tag(vty, &rm->p, ri, 0,
|
route_vty_out_tag(vty, &rm->p, pi, 0,
|
||||||
SAFI_EVPN,
|
SAFI_EVPN,
|
||||||
json_array);
|
json_array);
|
||||||
else if (option == SHOW_DISPLAY_OVERLAY)
|
else if (option == SHOW_DISPLAY_OVERLAY)
|
||||||
route_vty_out_overlay(vty, &rm->p, ri,
|
route_vty_out_overlay(vty, &rm->p, pi,
|
||||||
0, json_array);
|
0, json_array);
|
||||||
else
|
else
|
||||||
route_vty_out(vty, &rm->p, ri, 0,
|
route_vty_out(vty, &rm->p, pi, 0,
|
||||||
SAFI_EVPN, json_array);
|
SAFI_EVPN, json_array);
|
||||||
output_count++;
|
output_count++;
|
||||||
}
|
}
|
||||||
@ -2017,7 +2017,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
|
|||||||
struct bgpevpn *vpn;
|
struct bgpevpn *vpn;
|
||||||
struct prefix_evpn p;
|
struct prefix_evpn p;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint32_t path_cnt = 0;
|
uint32_t path_cnt = 0;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -2049,13 +2049,13 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
|
|||||||
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2086,7 +2086,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
struct bgpevpn *vpn;
|
struct bgpevpn *vpn;
|
||||||
struct prefix_evpn p;
|
struct prefix_evpn p;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint32_t path_cnt = 0;
|
uint32_t path_cnt = 0;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -2119,13 +2119,13 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2196,7 +2196,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
{
|
{
|
||||||
struct prefix_evpn p;
|
struct prefix_evpn p;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
uint32_t path_cnt = 0;
|
uint32_t path_cnt = 0;
|
||||||
@ -2226,13 +2226,13 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
json_paths = json_object_new_array();
|
json_paths = json_object_new_array();
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2262,7 +2262,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
|
|||||||
struct bgp_node *rd_rn;
|
struct bgp_node *rd_rn;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
int rd_header = 1;
|
int rd_header = 1;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -2330,13 +2330,13 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
|
|||||||
json_paths = json_object_new_array();
|
json_paths = json_object_new_array();
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2383,7 +2383,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
|||||||
struct bgp_node *rd_rn;
|
struct bgp_node *rd_rn;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
int rd_header;
|
int rd_header;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -2467,7 +2467,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
|||||||
* fit in
|
* fit in
|
||||||
* with code that already exists).
|
* with code that already exists).
|
||||||
*/
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
path_cnt++;
|
path_cnt++;
|
||||||
add_prefix_to_json = 1;
|
add_prefix_to_json = 1;
|
||||||
@ -2476,7 +2476,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
|||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN,
|
route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
|
@ -44,8 +44,8 @@ extern void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
|
|||||||
json_object *json_path);
|
json_object *json_path);
|
||||||
|
|
||||||
extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path, int display,
|
||||||
int display, json_object *json_paths);
|
json_object *json_paths);
|
||||||
extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
|
extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
|
||||||
afi_t afi, safi_t safi);
|
afi_t afi, safi_t safi);
|
||||||
|
|
||||||
|
@ -253,8 +253,8 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path, int display,
|
||||||
int display, json_object *json_paths)
|
json_object *json_paths)
|
||||||
{
|
{
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
char return_string[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
|
char return_string[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
|
||||||
@ -274,9 +274,9 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
else
|
else
|
||||||
json_nlri_path = json_paths;
|
json_nlri_path = json_paths;
|
||||||
}
|
}
|
||||||
if (display == NLRI_STRING_FORMAT_LARGE && binfo)
|
if (display == NLRI_STRING_FORMAT_LARGE && path)
|
||||||
vty_out(vty, "BGP flowspec entry: (flags 0x%x)\n",
|
vty_out(vty, "BGP flowspec entry: (flags 0x%x)\n",
|
||||||
binfo->flags);
|
path->flags);
|
||||||
bgp_fs_nlri_get_string((unsigned char *)
|
bgp_fs_nlri_get_string((unsigned char *)
|
||||||
p->u.prefix_flowspec.ptr,
|
p->u.prefix_flowspec.ptr,
|
||||||
p->u.prefix_flowspec.prefixlen,
|
p->u.prefix_flowspec.prefixlen,
|
||||||
@ -292,11 +292,11 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
else if (json_paths && display == NLRI_STRING_FORMAT_JSON)
|
else if (json_paths && display == NLRI_STRING_FORMAT_JSON)
|
||||||
json_object_array_add(json_paths, json_nlri_path);
|
json_object_array_add(json_paths, json_nlri_path);
|
||||||
}
|
}
|
||||||
if (!binfo)
|
if (!path)
|
||||||
return;
|
return;
|
||||||
if (binfo->attr && binfo->attr->ecommunity) {
|
if (path->attr && path->attr->ecommunity) {
|
||||||
/* Print attribute */
|
/* Print attribute */
|
||||||
attr = binfo->attr;
|
attr = path->attr;
|
||||||
s = ecommunity_ecom2str(attr->ecommunity,
|
s = ecommunity_ecom2str(attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
if (!s)
|
if (!s)
|
||||||
@ -318,7 +318,7 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
vty_out(vty, "\tNH %-16s\n", inet_ntoa(attr->nexthop));
|
vty_out(vty, "\tNH %-16s\n", inet_ntoa(attr->nexthop));
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
peer_uptime(binfo->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
|
peer_uptime(path->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
|
||||||
if (display == NLRI_STRING_FORMAT_LARGE) {
|
if (display == NLRI_STRING_FORMAT_LARGE) {
|
||||||
vty_out(vty, "\treceived for %8s\n", timebuf);
|
vty_out(vty, "\treceived for %8s\n", timebuf);
|
||||||
} else if (json_paths) {
|
} else if (json_paths) {
|
||||||
@ -329,7 +329,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
json_object_array_add(json_paths, json_time_path);
|
json_object_array_add(json_paths, json_time_path);
|
||||||
}
|
}
|
||||||
if (display == NLRI_STRING_FORMAT_LARGE) {
|
if (display == NLRI_STRING_FORMAT_LARGE) {
|
||||||
struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
|
struct bgp_path_info_extra *extra =
|
||||||
|
bgp_path_info_extra_get(path);
|
||||||
|
|
||||||
if (extra->bgp_fs_pbr) {
|
if (extra->bgp_fs_pbr) {
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
@ -368,7 +369,7 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
void *output_arg, bool use_json, int is_last,
|
void *output_arg, bool use_json, int is_last,
|
||||||
unsigned long *output_cum, unsigned long *total_cum)
|
unsigned long *output_cum, unsigned long *total_cum)
|
||||||
{
|
{
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
unsigned long total_count = 0;
|
unsigned long total_count = 0;
|
||||||
json_object *json_paths = NULL;
|
json_object *json_paths = NULL;
|
||||||
@ -384,12 +385,10 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
json_paths = json_object_new_array();
|
json_paths = json_object_new_array();
|
||||||
display = NLRI_STRING_FORMAT_JSON;
|
display = NLRI_STRING_FORMAT_JSON;
|
||||||
}
|
}
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
total_count++;
|
total_count++;
|
||||||
route_vty_out_flowspec(vty, &rn->p,
|
route_vty_out_flowspec(vty, &rn->p, pi, display,
|
||||||
ri, display,
|
|
||||||
json_paths);
|
json_paths);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
vty_out(vty, "%s\n",
|
vty_out(vty, "%s\n",
|
||||||
|
@ -94,18 +94,18 @@ int bgp_parse_fec_update(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
|
mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *to, afi_t afi, safi_t safi)
|
struct peer *to, afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
struct peer *from;
|
struct peer *from;
|
||||||
mpls_label_t remote_label;
|
mpls_label_t remote_label;
|
||||||
int reflect;
|
int reflect;
|
||||||
|
|
||||||
if (!rn || !ri || !to)
|
if (!rn || !pi || !to)
|
||||||
return MPLS_INVALID_LABEL;
|
return MPLS_INVALID_LABEL;
|
||||||
|
|
||||||
remote_label = ri->extra ? ri->extra->label[0] : MPLS_INVALID_LABEL;
|
remote_label = pi->extra ? pi->extra->label[0] : MPLS_INVALID_LABEL;
|
||||||
from = ri->peer;
|
from = pi->peer;
|
||||||
reflect =
|
reflect =
|
||||||
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
|
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
|
||||||
|
|
||||||
@ -120,7 +120,8 @@ mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
|
|||||||
return rn->local_label;
|
return rn->local_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri, int reg)
|
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
|
int reg)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
@ -142,11 +143,11 @@ void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri, int reg)
|
|||||||
stream_putw(s, PREFIX_FAMILY(p));
|
stream_putw(s, PREFIX_FAMILY(p));
|
||||||
stream_put_prefix(s, p);
|
stream_put_prefix(s, p);
|
||||||
if (reg) {
|
if (reg) {
|
||||||
assert(ri);
|
assert(pi);
|
||||||
if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
if (pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
||||||
if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
if (pi->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
||||||
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
|
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
|
||||||
stream_putl(s, ri->attr->label_index);
|
stream_putl(s, pi->attr->label_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
||||||
|
@ -27,13 +27,13 @@
|
|||||||
#define BGP_PREVENT_VRF_2_VRF_LEAK 0xFFFFFFFE
|
#define BGP_PREVENT_VRF_2_VRF_LEAK 0xFFFFFFFE
|
||||||
|
|
||||||
struct bgp_node;
|
struct bgp_node;
|
||||||
struct bgp_info;
|
struct bgp_path_info;
|
||||||
struct peer;
|
struct peer;
|
||||||
|
|
||||||
extern void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri,
|
extern void bgp_reg_dereg_for_label(struct bgp_node *rn,
|
||||||
int reg);
|
struct bgp_path_info *pi, int reg);
|
||||||
extern int bgp_parse_fec_update(void);
|
extern int bgp_parse_fec_update(void);
|
||||||
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
|
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *to, afi_t afi, safi_t safi);
|
struct peer *to, afi_t afi, safi_t safi);
|
||||||
|
|
||||||
extern int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
|
extern int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
|
||||||
@ -85,9 +85,9 @@ static inline void bgp_unset_valid_label(mpls_label_t *label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void bgp_register_for_label(struct bgp_node *rn,
|
static inline void bgp_register_for_label(struct bgp_node *rn,
|
||||||
struct bgp_info *ri)
|
struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
bgp_reg_dereg_for_label(rn, ri, 1);
|
bgp_reg_dereg_for_label(rn, pi, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bgp_unregister_for_label(struct bgp_node *rn)
|
static inline void bgp_unregister_for_label(struct bgp_node *rn)
|
||||||
|
314
bgpd/bgp_mpath.c
314
bgpd/bgp_mpath.c
@ -113,45 +113,47 @@ static int bgp_interface_same(struct interface *ifp1, struct interface *ifp2)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_nexthop_cmp
|
* bgp_path_info_nexthop_cmp
|
||||||
*
|
*
|
||||||
* Compare the nexthops of two paths. Return value is less than, equal to,
|
* Compare the nexthops of two paths. Return value is less than, equal to,
|
||||||
* or greater than zero if bi1 is respectively less than, equal to,
|
* or greater than zero if bpi1 is respectively less than, equal to,
|
||||||
* or greater than bi2.
|
* or greater than bpi2.
|
||||||
*/
|
*/
|
||||||
int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,
|
||||||
|
struct bgp_path_info *bpi2)
|
||||||
{
|
{
|
||||||
int compare;
|
int compare;
|
||||||
struct in6_addr addr1, addr2;
|
struct in6_addr addr1, addr2;
|
||||||
|
|
||||||
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
|
compare = IPV4_ADDR_CMP(&bpi1->attr->nexthop, &bpi2->attr->nexthop);
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
if (bi1->attr->mp_nexthop_len == bi2->attr->mp_nexthop_len) {
|
if (bpi1->attr->mp_nexthop_len == bpi2->attr->mp_nexthop_len) {
|
||||||
switch (bi1->attr->mp_nexthop_len) {
|
switch (bpi1->attr->mp_nexthop_len) {
|
||||||
case BGP_ATTR_NHLEN_IPV4:
|
case BGP_ATTR_NHLEN_IPV4:
|
||||||
case BGP_ATTR_NHLEN_VPNV4:
|
case BGP_ATTR_NHLEN_VPNV4:
|
||||||
compare = IPV4_ADDR_CMP(
|
compare = IPV4_ADDR_CMP(
|
||||||
&bi1->attr->mp_nexthop_global_in,
|
&bpi1->attr->mp_nexthop_global_in,
|
||||||
&bi2->attr->mp_nexthop_global_in);
|
&bpi2->attr->mp_nexthop_global_in);
|
||||||
break;
|
break;
|
||||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
|
||||||
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
|
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
|
||||||
compare = IPV6_ADDR_CMP(
|
compare = IPV6_ADDR_CMP(
|
||||||
&bi1->attr->mp_nexthop_global,
|
&bpi1->attr->mp_nexthop_global,
|
||||||
&bi2->attr->mp_nexthop_global);
|
&bpi2->attr->mp_nexthop_global);
|
||||||
break;
|
break;
|
||||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
||||||
addr1 = (bi1->attr->mp_nexthop_prefer_global)
|
addr1 = (bpi1->attr->mp_nexthop_prefer_global)
|
||||||
? bi1->attr->mp_nexthop_global
|
? bpi1->attr->mp_nexthop_global
|
||||||
: bi1->attr->mp_nexthop_local;
|
: bpi1->attr->mp_nexthop_local;
|
||||||
addr2 = (bi2->attr->mp_nexthop_prefer_global)
|
addr2 = (bpi2->attr->mp_nexthop_prefer_global)
|
||||||
? bi2->attr->mp_nexthop_global
|
? bpi2->attr->mp_nexthop_global
|
||||||
: bi2->attr->mp_nexthop_local;
|
: bpi2->attr->mp_nexthop_local;
|
||||||
|
|
||||||
if (!bi1->attr->mp_nexthop_prefer_global
|
if (!bpi1->attr->mp_nexthop_prefer_global
|
||||||
&& !bi2->attr->mp_nexthop_prefer_global)
|
&& !bpi2->attr->mp_nexthop_prefer_global)
|
||||||
compare = !bgp_interface_same(
|
compare = !bgp_interface_same(
|
||||||
bi1->peer->ifp, bi2->peer->ifp);
|
bpi1->peer->ifp,
|
||||||
|
bpi2->peer->ifp);
|
||||||
|
|
||||||
if (!compare)
|
if (!compare)
|
||||||
compare = IPV6_ADDR_CMP(&addr1, &addr2);
|
compare = IPV6_ADDR_CMP(&addr1, &addr2);
|
||||||
@ -163,14 +165,15 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
* link-local
|
* link-local
|
||||||
* nexthops but another IPv6 peer only sends you global
|
* nexthops but another IPv6 peer only sends you global
|
||||||
*/
|
*/
|
||||||
else if (bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
|
else if (bpi1->attr->mp_nexthop_len
|
||||||
|| bi1->attr->mp_nexthop_len
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL
|
||||||
|
|| bpi1->attr->mp_nexthop_len
|
||||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
||||||
compare = IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global,
|
compare = IPV6_ADDR_CMP(&bpi1->attr->mp_nexthop_global,
|
||||||
&bi2->attr->mp_nexthop_global);
|
&bpi2->attr->mp_nexthop_global);
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
if (bi1->attr->mp_nexthop_len
|
if (bpi1->attr->mp_nexthop_len
|
||||||
< bi2->attr->mp_nexthop_len)
|
< bpi2->attr->mp_nexthop_len)
|
||||||
compare = -1;
|
compare = -1;
|
||||||
else
|
else
|
||||||
compare = 1;
|
compare = 1;
|
||||||
@ -182,7 +185,7 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_cmp
|
* bgp_path_info_mpath_cmp
|
||||||
*
|
*
|
||||||
* This function determines our multipath list ordering. By ordering
|
* This function determines our multipath list ordering. By ordering
|
||||||
* the list we can deterministically select which paths are included
|
* the list we can deterministically select which paths are included
|
||||||
@ -193,26 +196,26 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
* The order of paths is determined first by received nexthop, and then
|
* The order of paths is determined first by received nexthop, and then
|
||||||
* by peer address if the nexthops are the same.
|
* by peer address if the nexthops are the same.
|
||||||
*/
|
*/
|
||||||
static int bgp_info_mpath_cmp(void *val1, void *val2)
|
static int bgp_path_info_mpath_cmp(void *val1, void *val2)
|
||||||
{
|
{
|
||||||
struct bgp_info *bi1, *bi2;
|
struct bgp_path_info *bpi1, *bpi2;
|
||||||
int compare;
|
int compare;
|
||||||
|
|
||||||
bi1 = val1;
|
bpi1 = val1;
|
||||||
bi2 = val2;
|
bpi2 = val2;
|
||||||
|
|
||||||
compare = bgp_info_nexthop_cmp(bi1, bi2);
|
compare = bgp_path_info_nexthop_cmp(bpi1, bpi2);
|
||||||
|
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
if (!bi1->peer->su_remote && !bi2->peer->su_remote)
|
if (!bpi1->peer->su_remote && !bpi2->peer->su_remote)
|
||||||
compare = 0;
|
compare = 0;
|
||||||
else if (!bi1->peer->su_remote)
|
else if (!bpi1->peer->su_remote)
|
||||||
compare = 1;
|
compare = 1;
|
||||||
else if (!bi2->peer->su_remote)
|
else if (!bpi2->peer->su_remote)
|
||||||
compare = -1;
|
compare = -1;
|
||||||
else
|
else
|
||||||
compare = sockunion_cmp(bi1->peer->su_remote,
|
compare = sockunion_cmp(bpi1->peer->su_remote,
|
||||||
bi2->peer->su_remote);
|
bpi2->peer->su_remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
return compare;
|
return compare;
|
||||||
@ -228,7 +231,7 @@ void bgp_mp_list_init(struct list *mp_list)
|
|||||||
{
|
{
|
||||||
assert(mp_list);
|
assert(mp_list);
|
||||||
memset(mp_list, 0, sizeof(struct list));
|
memset(mp_list, 0, sizeof(struct list));
|
||||||
mp_list->cmp = bgp_info_mpath_cmp;
|
mp_list->cmp = bgp_path_info_mpath_cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -247,31 +250,31 @@ void bgp_mp_list_clear(struct list *mp_list)
|
|||||||
*
|
*
|
||||||
* Adds a multipath entry to the mp_list
|
* Adds a multipath entry to the mp_list
|
||||||
*/
|
*/
|
||||||
void bgp_mp_list_add(struct list *mp_list, struct bgp_info *mpinfo)
|
void bgp_mp_list_add(struct list *mp_list, struct bgp_path_info *mpinfo)
|
||||||
{
|
{
|
||||||
assert(mp_list && mpinfo);
|
assert(mp_list && mpinfo);
|
||||||
listnode_add_sort(mp_list, mpinfo);
|
listnode_add_sort(mp_list, mpinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_new
|
* bgp_path_info_mpath_new
|
||||||
*
|
*
|
||||||
* Allocate and zero memory for a new bgp_info_mpath element
|
* Allocate and zero memory for a new bgp_path_info_mpath element
|
||||||
*/
|
*/
|
||||||
static struct bgp_info_mpath *bgp_info_mpath_new(void)
|
static struct bgp_path_info_mpath *bgp_path_info_mpath_new(void)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *new_mpath;
|
struct bgp_path_info_mpath *new_mpath;
|
||||||
new_mpath =
|
new_mpath = XCALLOC(MTYPE_BGP_MPATH_INFO,
|
||||||
XCALLOC(MTYPE_BGP_MPATH_INFO, sizeof(struct bgp_info_mpath));
|
sizeof(struct bgp_path_info_mpath));
|
||||||
return new_mpath;
|
return new_mpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_free
|
* bgp_path_info_mpath_free
|
||||||
*
|
*
|
||||||
* Release resources for a bgp_info_mpath element and zero out pointer
|
* Release resources for a bgp_path_info_mpath element and zero out pointer
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_free(struct bgp_info_mpath **mpath)
|
void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath)
|
||||||
{
|
{
|
||||||
if (mpath && *mpath) {
|
if (mpath && *mpath) {
|
||||||
if ((*mpath)->mp_attr)
|
if ((*mpath)->mp_attr)
|
||||||
@ -282,37 +285,38 @@ void bgp_info_mpath_free(struct bgp_info_mpath **mpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_get
|
* bgp_path_info_mpath_get
|
||||||
*
|
*
|
||||||
* Fetch the mpath element for the given bgp_info. Used for
|
* Fetch the mpath element for the given bgp_path_info. Used for
|
||||||
* doing lazy allocation.
|
* doing lazy allocation.
|
||||||
*/
|
*/
|
||||||
static struct bgp_info_mpath *bgp_info_mpath_get(struct bgp_info *binfo)
|
static struct bgp_path_info_mpath *
|
||||||
|
bgp_path_info_mpath_get(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
if (!binfo->mpath) {
|
if (!path->mpath) {
|
||||||
mpath = bgp_info_mpath_new();
|
mpath = bgp_path_info_mpath_new();
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return NULL;
|
return NULL;
|
||||||
binfo->mpath = mpath;
|
path->mpath = mpath;
|
||||||
mpath->mp_info = binfo;
|
mpath->mp_info = path;
|
||||||
}
|
}
|
||||||
return binfo->mpath;
|
return path->mpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_enqueue
|
* bgp_path_info_mpath_enqueue
|
||||||
*
|
*
|
||||||
* Enqueue a path onto the multipath list given the previous multipath
|
* Enqueue a path onto the multipath list given the previous multipath
|
||||||
* list entry
|
* list entry
|
||||||
*/
|
*/
|
||||||
static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
|
static void bgp_path_info_mpath_enqueue(struct bgp_path_info *prev_info,
|
||||||
struct bgp_info *binfo)
|
struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *prev, *mpath;
|
struct bgp_path_info_mpath *prev, *mpath;
|
||||||
|
|
||||||
prev = bgp_info_mpath_get(prev_info);
|
prev = bgp_path_info_mpath_get(prev_info);
|
||||||
mpath = bgp_info_mpath_get(binfo);
|
mpath = bgp_path_info_mpath_get(path);
|
||||||
if (!prev || !mpath)
|
if (!prev || !mpath)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -322,17 +326,17 @@ static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
|
|||||||
prev->mp_next->mp_prev = mpath;
|
prev->mp_next->mp_prev = mpath;
|
||||||
prev->mp_next = mpath;
|
prev->mp_next = mpath;
|
||||||
|
|
||||||
SET_FLAG(binfo->flags, BGP_INFO_MULTIPATH);
|
SET_FLAG(path->flags, BGP_PATH_MULTIPATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_dequeue
|
* bgp_path_info_mpath_dequeue
|
||||||
*
|
*
|
||||||
* Remove a path from the multipath list
|
* Remove a path from the multipath list
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_dequeue(struct bgp_info *binfo)
|
void bgp_path_info_mpath_dequeue(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath = binfo->mpath;
|
struct bgp_path_info_mpath *mpath = path->mpath;
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return;
|
return;
|
||||||
if (mpath->mp_prev)
|
if (mpath->mp_prev)
|
||||||
@ -340,101 +344,105 @@ void bgp_info_mpath_dequeue(struct bgp_info *binfo)
|
|||||||
if (mpath->mp_next)
|
if (mpath->mp_next)
|
||||||
mpath->mp_next->mp_prev = mpath->mp_prev;
|
mpath->mp_next->mp_prev = mpath->mp_prev;
|
||||||
mpath->mp_next = mpath->mp_prev = NULL;
|
mpath->mp_next = mpath->mp_prev = NULL;
|
||||||
UNSET_FLAG(binfo->flags, BGP_INFO_MULTIPATH);
|
UNSET_FLAG(path->flags, BGP_PATH_MULTIPATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_next
|
* bgp_path_info_mpath_next
|
||||||
*
|
*
|
||||||
* Given a bgp_info, return the next multipath entry
|
* Given a bgp_path_info, return the next multipath entry
|
||||||
*/
|
*/
|
||||||
struct bgp_info *bgp_info_mpath_next(struct bgp_info *binfo)
|
struct bgp_path_info *bgp_path_info_mpath_next(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
if (!binfo->mpath || !binfo->mpath->mp_next)
|
if (!path->mpath || !path->mpath->mp_next)
|
||||||
return NULL;
|
return NULL;
|
||||||
return binfo->mpath->mp_next->mp_info;
|
return path->mpath->mp_next->mp_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_first
|
* bgp_path_info_mpath_first
|
||||||
*
|
*
|
||||||
* Given bestpath bgp_info, return the first multipath entry.
|
* Given bestpath bgp_path_info, return the first multipath entry.
|
||||||
*/
|
*/
|
||||||
struct bgp_info *bgp_info_mpath_first(struct bgp_info *binfo)
|
struct bgp_path_info *bgp_path_info_mpath_first(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
return bgp_info_mpath_next(binfo);
|
return bgp_path_info_mpath_next(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_count
|
* bgp_path_info_mpath_count
|
||||||
*
|
*
|
||||||
* Given the bestpath bgp_info, return the number of multipath entries
|
* Given the bestpath bgp_path_info, return the number of multipath entries
|
||||||
*/
|
*/
|
||||||
uint32_t bgp_info_mpath_count(struct bgp_info *binfo)
|
uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
if (!binfo->mpath)
|
if (!path->mpath)
|
||||||
return 0;
|
return 0;
|
||||||
return binfo->mpath->mp_count;
|
return path->mpath->mp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_count_set
|
* bgp_path_info_mpath_count_set
|
||||||
*
|
*
|
||||||
* Sets the count of multipaths into bestpath's mpath element
|
* Sets the count of multipaths into bestpath's mpath element
|
||||||
*/
|
*/
|
||||||
static void bgp_info_mpath_count_set(struct bgp_info *binfo, uint32_t count)
|
static void bgp_path_info_mpath_count_set(struct bgp_path_info *path,
|
||||||
|
uint32_t count)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
if (!count && !binfo->mpath)
|
if (!count && !path->mpath)
|
||||||
return;
|
return;
|
||||||
mpath = bgp_info_mpath_get(binfo);
|
mpath = bgp_path_info_mpath_get(path);
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return;
|
return;
|
||||||
mpath->mp_count = count;
|
mpath->mp_count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_attr
|
* bgp_path_info_mpath_attr
|
||||||
*
|
*
|
||||||
* Given bestpath bgp_info, return aggregated attribute set used
|
* Given bestpath bgp_path_info, return aggregated attribute set used
|
||||||
* for advertising the multipath route
|
* for advertising the multipath route
|
||||||
*/
|
*/
|
||||||
struct attr *bgp_info_mpath_attr(struct bgp_info *binfo)
|
struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
if (!binfo->mpath)
|
if (!path->mpath)
|
||||||
return NULL;
|
return NULL;
|
||||||
return binfo->mpath->mp_attr;
|
return path->mpath->mp_attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_attr_set
|
* bgp_path_info_mpath_attr_set
|
||||||
*
|
*
|
||||||
* Sets the aggregated attribute into bestpath's mpath element
|
* Sets the aggregated attribute into bestpath's mpath element
|
||||||
*/
|
*/
|
||||||
static void bgp_info_mpath_attr_set(struct bgp_info *binfo, struct attr *attr)
|
static void bgp_path_info_mpath_attr_set(struct bgp_path_info *path,
|
||||||
|
struct attr *attr)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
if (!attr && !binfo->mpath)
|
if (!attr && !path->mpath)
|
||||||
return;
|
return;
|
||||||
mpath = bgp_info_mpath_get(binfo);
|
mpath = bgp_path_info_mpath_get(path);
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return;
|
return;
|
||||||
mpath->mp_attr = attr;
|
mpath->mp_attr = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_update
|
* bgp_path_info_mpath_update
|
||||||
*
|
*
|
||||||
* Compare and sync up the multipath list with the mp_list generated by
|
* Compare and sync up the multipath list with the mp_list generated by
|
||||||
* bgp_best_selection
|
* bgp_best_selection
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||||
struct bgp_info *old_best, struct list *mp_list,
|
struct bgp_path_info *new_best,
|
||||||
|
struct bgp_path_info *old_best,
|
||||||
|
struct list *mp_list,
|
||||||
struct bgp_maxpaths_cfg *mpath_cfg)
|
struct bgp_maxpaths_cfg *mpath_cfg)
|
||||||
{
|
{
|
||||||
uint16_t maxpaths, mpath_count, old_mpath_count;
|
uint16_t maxpaths, mpath_count, old_mpath_count;
|
||||||
struct listnode *mp_node, *mp_next_node;
|
struct listnode *mp_node, *mp_next_node;
|
||||||
struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
|
struct bgp_path_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
|
||||||
int mpath_changed, debug;
|
int mpath_changed, debug;
|
||||||
char pfx_buf[PREFIX2STR_BUFFER], nh_buf[2][INET6_ADDRSTRLEN];
|
char pfx_buf[PREFIX2STR_BUFFER], nh_buf[2][INET6_ADDRSTRLEN];
|
||||||
char path_buf[PATH_ADDPATH_STR_BUFFER];
|
char path_buf[PATH_ADDPATH_STR_BUFFER];
|
||||||
@ -454,17 +462,17 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
if (new_best) {
|
if (new_best) {
|
||||||
mpath_count++;
|
mpath_count++;
|
||||||
if (new_best != old_best)
|
if (new_best != old_best)
|
||||||
bgp_info_mpath_dequeue(new_best);
|
bgp_path_info_mpath_dequeue(new_best);
|
||||||
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
|
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
|
||||||
? mpath_cfg->maxpaths_ibgp
|
? mpath_cfg->maxpaths_ibgp
|
||||||
: mpath_cfg->maxpaths_ebgp;
|
: mpath_cfg->maxpaths_ebgp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_best) {
|
if (old_best) {
|
||||||
cur_mpath = bgp_info_mpath_first(old_best);
|
cur_mpath = bgp_path_info_mpath_first(old_best);
|
||||||
old_mpath_count = bgp_info_mpath_count(old_best);
|
old_mpath_count = bgp_path_info_mpath_count(old_best);
|
||||||
bgp_info_mpath_count_set(old_best, 0);
|
bgp_path_info_mpath_count_set(old_best, 0);
|
||||||
bgp_info_mpath_dequeue(old_best);
|
bgp_path_info_mpath_dequeue(old_best);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -485,7 +493,7 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
* to skip over it
|
* to skip over it
|
||||||
*/
|
*/
|
||||||
while (mp_node || cur_mpath) {
|
while (mp_node || cur_mpath) {
|
||||||
struct bgp_info *tmp_info;
|
struct bgp_path_info *tmp_info;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can bail out of this loop if all existing paths on the
|
* We can bail out of this loop if all existing paths on the
|
||||||
@ -496,7 +504,8 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
mp_next_node = mp_node ? listnextnode(mp_node) : NULL;
|
mp_next_node = mp_node ? listnextnode(mp_node) : NULL;
|
||||||
next_mpath = cur_mpath ? bgp_info_mpath_next(cur_mpath) : NULL;
|
next_mpath =
|
||||||
|
cur_mpath ? bgp_path_info_mpath_next(cur_mpath) : NULL;
|
||||||
tmp_info = mp_node ? listgetdata(mp_node) : NULL;
|
tmp_info = mp_node ? listgetdata(mp_node) : NULL;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -512,14 +521,16 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
*/
|
*/
|
||||||
if (mp_node && (listgetdata(mp_node) == cur_mpath)) {
|
if (mp_node && (listgetdata(mp_node) == cur_mpath)) {
|
||||||
list_delete_node(mp_list, mp_node);
|
list_delete_node(mp_list, mp_node);
|
||||||
bgp_info_mpath_dequeue(cur_mpath);
|
bgp_path_info_mpath_dequeue(cur_mpath);
|
||||||
if ((mpath_count < maxpaths)
|
if ((mpath_count < maxpaths)
|
||||||
&& bgp_info_nexthop_cmp(prev_mpath, cur_mpath)) {
|
&& bgp_path_info_nexthop_cmp(prev_mpath,
|
||||||
bgp_info_mpath_enqueue(prev_mpath, cur_mpath);
|
cur_mpath)) {
|
||||||
|
bgp_path_info_mpath_enqueue(prev_mpath,
|
||||||
|
cur_mpath);
|
||||||
prev_mpath = cur_mpath;
|
prev_mpath = cur_mpath;
|
||||||
mpath_count++;
|
mpath_count++;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
cur_mpath, path_buf);
|
cur_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: %s is still multipath, cur count %d",
|
"%s: %s is still multipath, cur count %d",
|
||||||
@ -528,7 +539,7 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
} else {
|
} else {
|
||||||
mpath_changed = 1;
|
mpath_changed = 1;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
cur_mpath, path_buf);
|
cur_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: remove mpath %s nexthop %s, cur count %d",
|
"%s: remove mpath %s nexthop %s, cur count %d",
|
||||||
@ -548,7 +559,8 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
|
|
||||||
if (cur_mpath
|
if (cur_mpath
|
||||||
&& (!mp_node
|
&& (!mp_node
|
||||||
|| (bgp_info_mpath_cmp(cur_mpath, listgetdata(mp_node))
|
|| (bgp_path_info_mpath_cmp(cur_mpath,
|
||||||
|
listgetdata(mp_node))
|
||||||
< 0))) {
|
< 0))) {
|
||||||
/*
|
/*
|
||||||
* If here, we have an old multipath and either the
|
* If here, we have an old multipath and either the
|
||||||
@ -557,11 +569,11 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
* multipath, so we need to purge this path from the
|
* multipath, so we need to purge this path from the
|
||||||
* multipath list
|
* multipath list
|
||||||
*/
|
*/
|
||||||
bgp_info_mpath_dequeue(cur_mpath);
|
bgp_path_info_mpath_dequeue(cur_mpath);
|
||||||
mpath_changed = 1;
|
mpath_changed = 1;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(cur_mpath,
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
path_buf);
|
cur_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: remove mpath %s nexthop %s, cur count %d",
|
"%s: remove mpath %s nexthop %s, cur count %d",
|
||||||
pfx_buf, path_buf,
|
pfx_buf, path_buf,
|
||||||
@ -595,17 +607,19 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
assert(new_mpath);
|
assert(new_mpath);
|
||||||
assert(prev_mpath);
|
assert(prev_mpath);
|
||||||
if ((mpath_count < maxpaths) && (new_mpath != new_best)
|
if ((mpath_count < maxpaths) && (new_mpath != new_best)
|
||||||
&& bgp_info_nexthop_cmp(prev_mpath, new_mpath)) {
|
&& bgp_path_info_nexthop_cmp(prev_mpath,
|
||||||
|
new_mpath)) {
|
||||||
if (new_mpath == next_mpath)
|
if (new_mpath == next_mpath)
|
||||||
bgp_info_mpath_next(new_mpath);
|
bgp_path_info_mpath_next(new_mpath);
|
||||||
bgp_info_mpath_dequeue(new_mpath);
|
bgp_path_info_mpath_dequeue(new_mpath);
|
||||||
|
|
||||||
bgp_info_mpath_enqueue(prev_mpath, new_mpath);
|
bgp_path_info_mpath_enqueue(prev_mpath,
|
||||||
|
new_mpath);
|
||||||
prev_mpath = new_mpath;
|
prev_mpath = new_mpath;
|
||||||
mpath_changed = 1;
|
mpath_changed = 1;
|
||||||
mpath_count++;
|
mpath_count++;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
new_mpath, path_buf);
|
new_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: add mpath %s nexthop %s, cur count %d",
|
"%s: add mpath %s nexthop %s, cur count %d",
|
||||||
@ -629,39 +643,39 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
pfx_buf, mpath_count,
|
pfx_buf, mpath_count,
|
||||||
mpath_changed ? "YES" : "NO");
|
mpath_changed ? "YES" : "NO");
|
||||||
|
|
||||||
bgp_info_mpath_count_set(new_best, mpath_count - 1);
|
bgp_path_info_mpath_count_set(new_best, mpath_count - 1);
|
||||||
if (mpath_changed
|
if (mpath_changed
|
||||||
|| (bgp_info_mpath_count(new_best) != old_mpath_count))
|
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
|
||||||
SET_FLAG(new_best->flags, BGP_INFO_MULTIPATH_CHG);
|
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_mp_dmed_deselect
|
* bgp_mp_dmed_deselect
|
||||||
*
|
*
|
||||||
* Clean up multipath information for BGP_INFO_DMED_SELECTED path that
|
* Clean up multipath information for BGP_PATH_DMED_SELECTED path that
|
||||||
* is not selected as best path
|
* is not selected as best path
|
||||||
*/
|
*/
|
||||||
void bgp_mp_dmed_deselect(struct bgp_info *dmed_best)
|
void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best)
|
||||||
{
|
{
|
||||||
struct bgp_info *mpinfo, *mpnext;
|
struct bgp_path_info *mpinfo, *mpnext;
|
||||||
|
|
||||||
if (!dmed_best)
|
if (!dmed_best)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (mpinfo = bgp_info_mpath_first(dmed_best); mpinfo;
|
for (mpinfo = bgp_path_info_mpath_first(dmed_best); mpinfo;
|
||||||
mpinfo = mpnext) {
|
mpinfo = mpnext) {
|
||||||
mpnext = bgp_info_mpath_next(mpinfo);
|
mpnext = bgp_path_info_mpath_next(mpinfo);
|
||||||
bgp_info_mpath_dequeue(mpinfo);
|
bgp_path_info_mpath_dequeue(mpinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_info_mpath_count_set(dmed_best, 0);
|
bgp_path_info_mpath_count_set(dmed_best, 0);
|
||||||
UNSET_FLAG(dmed_best->flags, BGP_INFO_MULTIPATH_CHG);
|
UNSET_FLAG(dmed_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||||
assert(bgp_info_mpath_first(dmed_best) == 0);
|
assert(bgp_path_info_mpath_first(dmed_best) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_aggregate_update
|
* bgp_path_info_mpath_aggregate_update
|
||||||
*
|
*
|
||||||
* Set the multipath aggregate attribute. We need to see if the
|
* Set the multipath aggregate attribute. We need to see if the
|
||||||
* aggregate has changed and then set the ATTR_CHANGED flag on the
|
* aggregate has changed and then set the ATTR_CHANGED flag on the
|
||||||
@ -672,10 +686,10 @@ void bgp_mp_dmed_deselect(struct bgp_info *dmed_best)
|
|||||||
* is no change in multipath selection and no attribute change in
|
* is no change in multipath selection and no attribute change in
|
||||||
* any multipath.
|
* any multipath.
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
|
||||||
struct bgp_info *old_best)
|
struct bgp_path_info *old_best)
|
||||||
{
|
{
|
||||||
struct bgp_info *mpinfo;
|
struct bgp_path_info *mpinfo;
|
||||||
struct aspath *aspath;
|
struct aspath *aspath;
|
||||||
struct aspath *asmerge;
|
struct aspath *asmerge;
|
||||||
struct attr *new_attr, *old_attr;
|
struct attr *new_attr, *old_attr;
|
||||||
@ -686,19 +700,19 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
struct attr attr = {0};
|
struct attr attr = {0};
|
||||||
|
|
||||||
if (old_best && (old_best != new_best)
|
if (old_best && (old_best != new_best)
|
||||||
&& (old_attr = bgp_info_mpath_attr(old_best))) {
|
&& (old_attr = bgp_path_info_mpath_attr(old_best))) {
|
||||||
bgp_attr_unintern(&old_attr);
|
bgp_attr_unintern(&old_attr);
|
||||||
bgp_info_mpath_attr_set(old_best, NULL);
|
bgp_path_info_mpath_attr_set(old_best, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_best)
|
if (!new_best)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bgp_info_mpath_count(new_best)) {
|
if (!bgp_path_info_mpath_count(new_best)) {
|
||||||
if ((new_attr = bgp_info_mpath_attr(new_best))) {
|
if ((new_attr = bgp_path_info_mpath_attr(new_best))) {
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
bgp_info_mpath_attr_set(new_best, NULL);
|
bgp_path_info_mpath_attr_set(new_best, NULL);
|
||||||
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
|
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -718,8 +732,8 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
|
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
for (mpinfo = bgp_info_mpath_first(new_best); mpinfo;
|
for (mpinfo = bgp_path_info_mpath_first(new_best); mpinfo;
|
||||||
mpinfo = bgp_info_mpath_next(mpinfo)) {
|
mpinfo = bgp_path_info_mpath_next(mpinfo)) {
|
||||||
asmerge =
|
asmerge =
|
||||||
aspath_aggregate(aspath, mpinfo->attr->aspath);
|
aspath_aggregate(aspath, mpinfo->attr->aspath);
|
||||||
aspath_free(aspath);
|
aspath_free(aspath);
|
||||||
@ -789,11 +803,11 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
|
|
||||||
new_attr = bgp_attr_intern(&attr);
|
new_attr = bgp_attr_intern(&attr);
|
||||||
|
|
||||||
if (new_attr != bgp_info_mpath_attr(new_best)) {
|
if (new_attr != bgp_path_info_mpath_attr(new_best)) {
|
||||||
if ((old_attr = bgp_info_mpath_attr(new_best)))
|
if ((old_attr = bgp_path_info_mpath_attr(new_best)))
|
||||||
bgp_attr_unintern(&old_attr);
|
bgp_attr_unintern(&old_attr);
|
||||||
bgp_info_mpath_attr_set(new_best, new_attr);
|
bgp_path_info_mpath_attr_set(new_best, new_attr);
|
||||||
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
|
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
|
||||||
} else
|
} else
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,18 @@
|
|||||||
#ifndef _QUAGGA_BGP_MPATH_H
|
#ifndef _QUAGGA_BGP_MPATH_H
|
||||||
#define _QUAGGA_BGP_MPATH_H
|
#define _QUAGGA_BGP_MPATH_H
|
||||||
|
|
||||||
/* Supplemental information linked to bgp_info for keeping track of
|
/* Supplemental information linked to bgp_path_info for keeping track of
|
||||||
* multipath selections, lazily allocated to save memory
|
* multipath selections, lazily allocated to save memory
|
||||||
*/
|
*/
|
||||||
struct bgp_info_mpath {
|
struct bgp_path_info_mpath {
|
||||||
/* Points to the first multipath (on bestpath) or the next multipath */
|
/* Points to the first multipath (on bestpath) or the next multipath */
|
||||||
struct bgp_info_mpath *mp_next;
|
struct bgp_path_info_mpath *mp_next;
|
||||||
|
|
||||||
/* Points to the previous multipath or NULL on bestpath */
|
/* Points to the previous multipath or NULL on bestpath */
|
||||||
struct bgp_info_mpath *mp_prev;
|
struct bgp_path_info_mpath *mp_prev;
|
||||||
|
|
||||||
/* Points to bgp_info associated with this multipath info */
|
/* Points to bgp_path_info associated with this multipath info */
|
||||||
struct bgp_info *mp_info;
|
struct bgp_path_info *mp_info;
|
||||||
|
|
||||||
/* When attached to best path, the number of selected multipaths */
|
/* When attached to best path, the number of selected multipaths */
|
||||||
uint32_t mp_count;
|
uint32_t mp_count;
|
||||||
@ -50,27 +50,33 @@ extern int bgp_maximum_paths_unset(struct bgp *, afi_t, safi_t, int);
|
|||||||
/* Functions used by bgp_best_selection to record current
|
/* Functions used by bgp_best_selection to record current
|
||||||
* multipath selections
|
* multipath selections
|
||||||
*/
|
*/
|
||||||
extern int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2);
|
extern int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,
|
||||||
|
struct bgp_path_info *bpi2);
|
||||||
extern void bgp_mp_list_init(struct list *);
|
extern void bgp_mp_list_init(struct list *);
|
||||||
extern void bgp_mp_list_clear(struct list *);
|
extern void bgp_mp_list_clear(struct list *);
|
||||||
extern void bgp_mp_list_add(struct list *, struct bgp_info *);
|
extern void bgp_mp_list_add(struct list *mp_list, struct bgp_path_info *mpinfo);
|
||||||
extern void bgp_mp_dmed_deselect(struct bgp_info *);
|
extern void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best);
|
||||||
extern void bgp_info_mpath_update(struct bgp_node *, struct bgp_info *,
|
extern void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||||
struct bgp_info *, struct list *,
|
struct bgp_path_info *new_best,
|
||||||
struct bgp_maxpaths_cfg *);
|
struct bgp_path_info *old_best,
|
||||||
extern void bgp_info_mpath_aggregate_update(struct bgp_info *,
|
struct list *mp_list,
|
||||||
struct bgp_info *);
|
struct bgp_maxpaths_cfg *mpath_cfg);
|
||||||
|
extern void
|
||||||
|
bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
|
||||||
|
struct bgp_path_info *old_best);
|
||||||
|
|
||||||
/* Unlink and free multipath information associated with a bgp_info */
|
/* Unlink and free multipath information associated with a bgp_path_info */
|
||||||
extern void bgp_info_mpath_dequeue(struct bgp_info *);
|
extern void bgp_path_info_mpath_dequeue(struct bgp_path_info *path);
|
||||||
extern void bgp_info_mpath_free(struct bgp_info_mpath **);
|
extern void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath);
|
||||||
|
|
||||||
/* Walk list of multipaths associated with a best path */
|
/* Walk list of multipaths associated with a best path */
|
||||||
extern struct bgp_info *bgp_info_mpath_first(struct bgp_info *);
|
extern struct bgp_path_info *
|
||||||
extern struct bgp_info *bgp_info_mpath_next(struct bgp_info *);
|
bgp_path_info_mpath_first(struct bgp_path_info *path);
|
||||||
|
extern struct bgp_path_info *
|
||||||
|
bgp_path_info_mpath_next(struct bgp_path_info *path);
|
||||||
|
|
||||||
/* Accessors for multipath information */
|
/* Accessors for multipath information */
|
||||||
extern uint32_t bgp_info_mpath_count(struct bgp_info *);
|
extern uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path);
|
||||||
extern struct attr *bgp_info_mpath_attr(struct bgp_info *);
|
extern struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path);
|
||||||
|
|
||||||
#endif /* _QUAGGA_BGP_MPATH_H */
|
#endif /* _QUAGGA_BGP_MPATH_H */
|
||||||
|
@ -402,22 +402,23 @@ static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
|
static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label,
|
||||||
|
uint32_t n)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if (!bi->extra) {
|
if (!bpi->extra) {
|
||||||
if (!n)
|
if (!n)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n != bi->extra->num_labels)
|
if (n != bpi->extra->num_labels)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
if (label[i] != bi->extra->label[i])
|
if (label[i] != bpi->extra->label[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -426,8 +427,7 @@ static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
|
|||||||
/*
|
/*
|
||||||
* make encoded route labels match specified encoded label set
|
* make encoded route labels match specified encoded label set
|
||||||
*/
|
*/
|
||||||
static void setlabels(
|
static void setlabels(struct bgp_path_info *bpi,
|
||||||
struct bgp_info *bi,
|
|
||||||
mpls_label_t *label, /* array of labels */
|
mpls_label_t *label, /* array of labels */
|
||||||
uint32_t num_labels)
|
uint32_t num_labels)
|
||||||
{
|
{
|
||||||
@ -436,12 +436,12 @@ static void setlabels(
|
|||||||
assert(num_labels <= BGP_MAX_LABELS);
|
assert(num_labels <= BGP_MAX_LABELS);
|
||||||
|
|
||||||
if (!num_labels) {
|
if (!num_labels) {
|
||||||
if (bi->extra)
|
if (bpi->extra)
|
||||||
bi->extra->num_labels = 0;
|
bpi->extra->num_labels = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bgp_info_extra *extra = bgp_info_extra_get(bi);
|
struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi);
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < num_labels; ++i) {
|
for (i = 0; i < num_labels; ++i) {
|
||||||
@ -454,35 +454,27 @@ static void setlabels(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns pointer to new bgp_info upon success
|
* returns pointer to new bgp_path_info upon success
|
||||||
*/
|
*/
|
||||||
static struct bgp_info *
|
static struct bgp_path_info *
|
||||||
leak_update(
|
leak_update(struct bgp *bgp, /* destination bgp instance */
|
||||||
struct bgp *bgp, /* destination bgp instance */
|
struct bgp_node *bn, struct attr *new_attr, /* already interned */
|
||||||
struct bgp_node *bn,
|
afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
|
||||||
struct attr *new_attr, /* already interned */
|
mpls_label_t *label, uint32_t num_labels, void *parent,
|
||||||
afi_t afi,
|
struct bgp *bgp_orig, struct prefix *nexthop_orig,
|
||||||
safi_t safi,
|
int nexthop_self_flag, int debug)
|
||||||
struct bgp_info *source_bi,
|
|
||||||
mpls_label_t *label,
|
|
||||||
uint32_t num_labels,
|
|
||||||
void *parent,
|
|
||||||
struct bgp *bgp_orig,
|
|
||||||
struct prefix *nexthop_orig,
|
|
||||||
int nexthop_self_flag,
|
|
||||||
int debug)
|
|
||||||
{
|
{
|
||||||
struct prefix *p = &bn->p;
|
struct prefix *p = &bn->p;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct bgp_info *bi_ultimate;
|
struct bgp_path_info *bpi_ultimate;
|
||||||
struct bgp_info *new;
|
struct bgp_path_info *new;
|
||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
|
prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
|
||||||
zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
|
zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
|
||||||
__func__, bgp->name_pretty, buf_prefix,
|
__func__, bgp->name_pretty, buf_prefix,
|
||||||
source_bi->type, source_bi->sub_type);
|
source_bpi->type, source_bpi->sub_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -494,31 +486,30 @@ leak_update(
|
|||||||
* should have nexthop tracking, we must find the ultimate
|
* should have nexthop tracking, we must find the ultimate
|
||||||
* parent so we can check its sub_type.
|
* parent so we can check its sub_type.
|
||||||
*
|
*
|
||||||
* As of now, source_bi may at most be a second-generation route
|
* As of now, source_bpi may at most be a second-generation route
|
||||||
* (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
|
* (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
|
||||||
* Using a loop here supports more complex intra-bgp import-export
|
* Using a loop here supports more complex intra-bgp import-export
|
||||||
* schemes that could be implemented in the future.
|
* schemes that could be implemented in the future.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
for (bi_ultimate = source_bi;
|
for (bpi_ultimate = source_bpi;
|
||||||
bi_ultimate->extra && bi_ultimate->extra->parent;
|
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
||||||
bi_ultimate = bi_ultimate->extra->parent)
|
bpi_ultimate = bpi_ultimate->extra->parent)
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* match parent
|
* match parent
|
||||||
*/
|
*/
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (bi->extra && bi->extra->parent == parent)
|
if (bpi->extra && bpi->extra->parent == parent)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
bool labelssame = labels_same(bi, label, num_labels);
|
bool labelssame = labels_same(bpi, label, num_labels);
|
||||||
|
|
||||||
if (attrhash_cmp(bi->attr, new_attr)
|
if (attrhash_cmp(bpi->attr, new_attr) && labelssame
|
||||||
&& labelssame
|
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
|
||||||
|
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -530,43 +521,42 @@ leak_update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* attr is changed */
|
/* attr is changed */
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
|
||||||
|
|
||||||
/* Rewrite BGP route information. */
|
/* Rewrite BGP route information. */
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||||
bgp_info_restore(bn, bi);
|
bgp_path_info_restore(bn, bpi);
|
||||||
else
|
else
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
bgp_attr_unintern(&bi->attr);
|
bgp_attr_unintern(&bpi->attr);
|
||||||
bi->attr = new_attr;
|
bpi->attr = new_attr;
|
||||||
bi->uptime = bgp_clock();
|
bpi->uptime = bgp_clock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rewrite labels
|
* rewrite labels
|
||||||
*/
|
*/
|
||||||
if (!labelssame)
|
if (!labelssame)
|
||||||
setlabels(bi, label, num_labels);
|
setlabels(bpi, label, num_labels);
|
||||||
|
|
||||||
if (nexthop_self_flag)
|
if (nexthop_self_flag)
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_ANNC_NH_SELF);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
|
||||||
|
|
||||||
struct bgp *bgp_nexthop = bgp;
|
struct bgp *bgp_nexthop = bgp;
|
||||||
int nh_valid;
|
int nh_valid;
|
||||||
|
|
||||||
if (bi->extra && bi->extra->bgp_orig)
|
if (bpi->extra && bpi->extra->bgp_orig)
|
||||||
bgp_nexthop = bi->extra->bgp_orig;
|
bgp_nexthop = bpi->extra->bgp_orig;
|
||||||
|
|
||||||
/* No nexthop tracking for redistributed routes */
|
/* No nexthop tracking for redistributed routes */
|
||||||
if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
||||||
nh_valid = 1;
|
nh_valid = 1;
|
||||||
else
|
else
|
||||||
/*
|
/*
|
||||||
* TBD do we need to do anything about the
|
* TBD do we need to do anything about the
|
||||||
* 'connected' parameter?
|
* 'connected' parameter?
|
||||||
*/
|
*/
|
||||||
nh_valid = bgp_find_or_add_nexthop(
|
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
|
||||||
bgp, bgp_nexthop,
|
afi, bpi, NULL, 0);
|
||||||
afi, bi, NULL, 0);
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||||
@ -574,10 +564,10 @@ leak_update(
|
|||||||
bgp_nexthop->name_pretty);
|
bgp_nexthop->name_pretty);
|
||||||
|
|
||||||
if (nh_valid)
|
if (nh_valid)
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_VALID);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
|
||||||
|
|
||||||
/* Process change. */
|
/* Process change. */
|
||||||
bgp_aggregate_increment(bgp, p, bi, afi, safi);
|
bgp_aggregate_increment(bgp, p, bpi, afi, safi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
|
|
||||||
@ -585,22 +575,22 @@ leak_update(
|
|||||||
zlog_debug("%s: ->%s: %s Found route, changed attr",
|
zlog_debug("%s: ->%s: %s Found route, changed attr",
|
||||||
__func__, bgp->name_pretty, buf_prefix);
|
__func__, bgp->name_pretty, buf_prefix);
|
||||||
|
|
||||||
return bi;
|
return bpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
|
||||||
bgp->peer_self, new_attr, bn);
|
bgp->peer_self, new_attr, bn);
|
||||||
|
|
||||||
if (nexthop_self_flag)
|
if (nexthop_self_flag)
|
||||||
bgp_info_set_flag(bn, new, BGP_INFO_ANNC_NH_SELF);
|
bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
|
||||||
|
|
||||||
bgp_info_extra_get(new);
|
bgp_path_info_extra_get(new);
|
||||||
|
|
||||||
if (num_labels)
|
if (num_labels)
|
||||||
setlabels(new, label, num_labels);
|
setlabels(new, label, num_labels);
|
||||||
|
|
||||||
new->extra->parent = bgp_info_lock(parent);
|
new->extra->parent = bgp_path_info_lock(parent);
|
||||||
bgp_lock_node((struct bgp_node *)((struct bgp_info *)parent)->net);
|
bgp_lock_node((struct bgp_node *)((struct bgp_path_info *)parent)->net);
|
||||||
if (bgp_orig)
|
if (bgp_orig)
|
||||||
new->extra->bgp_orig = bgp_lock(bgp_orig);
|
new->extra->bgp_orig = bgp_lock(bgp_orig);
|
||||||
if (nexthop_orig)
|
if (nexthop_orig)
|
||||||
@ -620,7 +610,7 @@ leak_update(
|
|||||||
* their originating protocols will do the tracking and
|
* their originating protocols will do the tracking and
|
||||||
* withdraw those routes if the nexthops become unreachable
|
* withdraw those routes if the nexthops become unreachable
|
||||||
*/
|
*/
|
||||||
if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
||||||
nh_valid = 1;
|
nh_valid = 1;
|
||||||
else
|
else
|
||||||
/*
|
/*
|
||||||
@ -635,10 +625,10 @@ leak_update(
|
|||||||
__func__, (nh_valid ? "" : "not "),
|
__func__, (nh_valid ? "" : "not "),
|
||||||
bgp_nexthop->name_pretty);
|
bgp_nexthop->name_pretty);
|
||||||
if (nh_valid)
|
if (nh_valid)
|
||||||
bgp_info_set_flag(bn, new, BGP_INFO_VALID);
|
bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
|
||||||
|
|
||||||
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
||||||
bgp_info_add(bn, new);
|
bgp_path_info_add(bn, new);
|
||||||
|
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
@ -653,10 +643,10 @@ leak_update(
|
|||||||
/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
|
/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
|
||||||
void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||||
struct bgp *bgp_vrf, /* from */
|
struct bgp *bgp_vrf, /* from */
|
||||||
struct bgp_info *info_vrf) /* route */
|
struct bgp_path_info *path_vrf) /* route */
|
||||||
{
|
{
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||||
struct prefix *p = &info_vrf->net->p;
|
struct prefix *p = &path_vrf->net->p;
|
||||||
afi_t afi = family2afi(p->family);
|
afi_t afi = family2afi(p->family);
|
||||||
struct attr static_attr = {0};
|
struct attr static_attr = {0};
|
||||||
struct attr *new_attr = NULL;
|
struct attr *new_attr = NULL;
|
||||||
@ -670,12 +660,12 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
|
zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
|
||||||
|
|
||||||
if (debug && info_vrf->attr->ecommunity) {
|
if (debug && path_vrf->attr->ecommunity) {
|
||||||
char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
|
char *s = ecommunity_ecom2str(path_vrf->attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
|
|
||||||
zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__,
|
zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
|
||||||
bgp_vrf->name, info_vrf->type, s);
|
bgp_vrf->name, path_vrf->type, s);
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,7 +679,7 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* loop check - should not be an imported route. */
|
/* loop check - should not be an imported route. */
|
||||||
if (info_vrf->extra && info_vrf->extra->bgp_orig)
|
if (path_vrf->extra && path_vrf->extra->bgp_orig)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
@ -700,13 +690,13 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
|
bgp_attr_dup(&static_attr, path_vrf->attr); /* shallow copy */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* route map handling
|
* route map handling
|
||||||
*/
|
*/
|
||||||
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
|
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -818,8 +808,8 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
* IPv4 nexthops as the attr has been copied
|
* IPv4 nexthops as the attr has been copied
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
if (afi == AFI_IP &&
|
if (afi == AFI_IP
|
||||||
!BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf->attr)) {
|
&& !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
|
||||||
static_attr.mp_nexthop_global_in.s_addr =
|
static_attr.mp_nexthop_global_in.s_addr =
|
||||||
static_attr.nexthop.s_addr;
|
static_attr.nexthop.s_addr;
|
||||||
static_attr.mp_nexthop_len = 4;
|
static_attr.mp_nexthop_len = 4;
|
||||||
@ -859,10 +849,10 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
||||||
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
||||||
|
|
||||||
struct bgp_info *new_info;
|
struct bgp_path_info *new_info;
|
||||||
|
|
||||||
new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
|
new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, path_vrf,
|
||||||
&label, 1, info_vrf, bgp_vrf, NULL,
|
&label, 1, path_vrf, bgp_vrf, NULL,
|
||||||
nexthop_self_flag, debug);
|
nexthop_self_flag, debug);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -880,13 +870,13 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
|
|
||||||
void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
||||||
struct bgp *bgp_vrf, /* from */
|
struct bgp *bgp_vrf, /* from */
|
||||||
struct bgp_info *info_vrf) /* route */
|
struct bgp_path_info *path_vrf) /* route */
|
||||||
{
|
{
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||||
struct prefix *p = &info_vrf->net->p;
|
struct prefix *p = &path_vrf->net->p;
|
||||||
afi_t afi = family2afi(p->family);
|
afi_t afi = family2afi(p->family);
|
||||||
safi_t safi = SAFI_MPLS_VPN;
|
safi_t safi = SAFI_MPLS_VPN;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
const char *debugmsg;
|
const char *debugmsg;
|
||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
@ -896,16 +886,16 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
|
"%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
|
||||||
__func__, bgp_vrf->name_pretty, buf_prefix,
|
__func__, bgp_vrf->name_pretty, buf_prefix,
|
||||||
info_vrf->type, info_vrf->sub_type);
|
path_vrf->type, path_vrf->sub_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info_vrf->sub_type != BGP_ROUTE_NORMAL
|
if (path_vrf->sub_type != BGP_ROUTE_NORMAL
|
||||||
&& info_vrf->sub_type != BGP_ROUTE_STATIC
|
&& path_vrf->sub_type != BGP_ROUTE_STATIC
|
||||||
&& info_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
|
&& path_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: wrong sub_type %d", __func__,
|
zlog_debug("%s: wrong sub_type %d", __func__,
|
||||||
info_vrf->sub_type);
|
path_vrf->sub_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!bgp_vpn)
|
if (!bgp_vpn)
|
||||||
@ -924,27 +914,27 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
|
zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
|
||||||
|
|
||||||
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
||||||
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vrf -> vpn
|
* vrf -> vpn
|
||||||
* match original bi imported from
|
* match original bpi imported from
|
||||||
*/
|
*/
|
||||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||||
if (bi->extra && bi->extra->parent == info_vrf) {
|
if (bpi->extra && bpi->extra->parent == path_vrf) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
/* withdraw from looped vrfs as well */
|
/* withdraw from looped vrfs as well */
|
||||||
vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
|
vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
|
||||||
|
|
||||||
bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp_vpn, p, bpi, afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp_vpn, bn, afi, safi);
|
bgp_process(bgp_vpn, bn, afi, safi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
@ -959,14 +949,14 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
|
|||||||
safi_t safi = SAFI_MPLS_VPN;
|
safi_t safi = SAFI_MPLS_VPN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk vpn table, delete bi with bgp_orig == bgp_vrf
|
* Walk vpn table, delete bpi with bgp_orig == bgp_vrf
|
||||||
*/
|
*/
|
||||||
for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
|
for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
|
||||||
prn = bgp_route_next(prn)) {
|
prn = bgp_route_next(prn)) {
|
||||||
|
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
/* This is the per-RD table of prefixes */
|
/* This is the per-RD table of prefixes */
|
||||||
table = prn->info;
|
table = prn->info;
|
||||||
@ -984,24 +974,24 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
|
|||||||
prefix2str(&bn->p, buf, sizeof(buf)));
|
prefix2str(&bn->p, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: type %d, sub_type %d",
|
zlog_debug("%s: type %d, sub_type %d",
|
||||||
__func__, bi->type,
|
__func__, bpi->type,
|
||||||
bi->sub_type);
|
bpi->sub_type);
|
||||||
if (bi->sub_type != BGP_ROUTE_IMPORTED)
|
if (bpi->sub_type != BGP_ROUTE_IMPORTED)
|
||||||
continue;
|
continue;
|
||||||
if (!bi->extra)
|
if (!bpi->extra)
|
||||||
continue;
|
continue;
|
||||||
if ((struct bgp *)bi->extra->bgp_orig
|
if ((struct bgp *)bpi->extra->bgp_orig
|
||||||
== bgp_vrf) {
|
== bgp_vrf) {
|
||||||
/* delete route */
|
/* delete route */
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: deleting it\n",
|
zlog_debug("%s: deleting it\n",
|
||||||
__func__);
|
__func__);
|
||||||
bgp_aggregate_decrement(bgp_vpn, &bn->p,
|
bgp_aggregate_decrement(bgp_vpn, &bn->p,
|
||||||
bi, afi, safi);
|
bpi, afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp_vpn, bn, afi, safi);
|
bgp_process(bgp_vpn, bn, afi, safi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1014,7 +1004,7 @@ void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
|
|||||||
afi_t afi)
|
afi_t afi)
|
||||||
{
|
{
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -1027,21 +1017,22 @@ void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
|
|||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: node=%p", __func__, bn);
|
zlog_debug("%s: node=%p", __func__, bn);
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: calling vpn_leak_from_vrf_update",
|
"%s: calling vpn_leak_from_vrf_update",
|
||||||
__func__);
|
__func__);
|
||||||
vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
|
vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
static void
|
||||||
|
vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
||||||
struct bgp *bgp_vpn, /* from */
|
struct bgp *bgp_vpn, /* from */
|
||||||
struct bgp_info *info_vpn) /* route */
|
struct bgp_path_info *path_vpn) /* route */
|
||||||
{
|
{
|
||||||
struct prefix *p = &info_vpn->net->p;
|
struct prefix *p = &path_vpn->net->p;
|
||||||
afi_t afi = family2afi(p->family);
|
afi_t afi = family2afi(p->family);
|
||||||
|
|
||||||
struct attr static_attr = {0};
|
struct attr static_attr = {0};
|
||||||
@ -1053,7 +1044,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
mpls_label_t *pLabels = NULL;
|
mpls_label_t *pLabels = NULL;
|
||||||
uint32_t num_labels = 0;
|
uint32_t num_labels = 0;
|
||||||
int nexthop_self_flag = 1;
|
int nexthop_self_flag = 1;
|
||||||
struct bgp_info *bi_ultimate = NULL;
|
struct bgp_path_info *bpi_ultimate = NULL;
|
||||||
int origin_local = 0;
|
int origin_local = 0;
|
||||||
struct bgp *src_vrf;
|
struct bgp *src_vrf;
|
||||||
|
|
||||||
@ -1068,7 +1059,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
/* Check for intersection of route targets */
|
/* Check for intersection of route targets */
|
||||||
if (!ecom_intersect(
|
if (!ecom_intersect(
|
||||||
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
||||||
info_vpn->attr->ecommunity)) {
|
path_vpn->attr->ecommunity)) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1077,7 +1068,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
zlog_debug("%s: updating to vrf %s", __func__,
|
zlog_debug("%s: updating to vrf %s", __func__,
|
||||||
bgp_vrf->name_pretty);
|
bgp_vrf->name_pretty);
|
||||||
|
|
||||||
bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
|
bgp_attr_dup(&static_attr, path_vpn->attr); /* shallow copy */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nexthop: stash and clear
|
* Nexthop: stash and clear
|
||||||
@ -1086,7 +1077,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
* Stash it for later label resolution by vrf ingress path and then
|
* Stash it for later label resolution by vrf ingress path and then
|
||||||
* overwrite with 0, i.e., "me", for the sake of vrf advertisement.
|
* overwrite with 0, i.e., "me", for the sake of vrf advertisement.
|
||||||
*/
|
*/
|
||||||
uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
|
uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
|
||||||
|
|
||||||
if (nhfamily != AF_UNSPEC)
|
if (nhfamily != AF_UNSPEC)
|
||||||
static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
|
static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
|
||||||
@ -1096,7 +1087,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
switch (nhfamily) {
|
switch (nhfamily) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
/* save */
|
/* save */
|
||||||
nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
|
nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
|
||||||
nexthop_orig.prefixlen = 32;
|
nexthop_orig.prefixlen = 32;
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
||||||
@ -1105,14 +1096,14 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
nexthop_orig.u.prefix4.s_addr;
|
nexthop_orig.u.prefix4.s_addr;
|
||||||
|
|
||||||
static_attr.mp_nexthop_global_in =
|
static_attr.mp_nexthop_global_in =
|
||||||
info_vpn->attr->mp_nexthop_global_in;
|
path_vpn->attr->mp_nexthop_global_in;
|
||||||
static_attr.mp_nexthop_len =
|
static_attr.mp_nexthop_len =
|
||||||
info_vpn->attr->mp_nexthop_len;
|
path_vpn->attr->mp_nexthop_len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
/* save */
|
/* save */
|
||||||
nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
|
nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
|
||||||
nexthop_orig.prefixlen = 128;
|
nexthop_orig.prefixlen = 128;
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
||||||
@ -1126,7 +1117,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
* route map handling
|
* route map handling
|
||||||
*/
|
*/
|
||||||
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
|
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -1174,30 +1165,30 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
||||||
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
|
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
|
||||||
/* work back to original route */
|
/* work back to original route */
|
||||||
for (bi_ultimate = info_vpn;
|
for (bpi_ultimate = path_vpn;
|
||||||
bi_ultimate->extra && bi_ultimate->extra->parent;
|
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
||||||
bi_ultimate = bi_ultimate->extra->parent)
|
bpi_ultimate = bpi_ultimate->extra->parent)
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if original route was unicast,
|
* if original route was unicast,
|
||||||
* then it did not arrive over vpn
|
* then it did not arrive over vpn
|
||||||
*/
|
*/
|
||||||
if (bi_ultimate->net) {
|
if (bpi_ultimate->net) {
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
|
|
||||||
table = bgp_node_table(bi_ultimate->net);
|
table = bgp_node_table(bpi_ultimate->net);
|
||||||
if (table && (table->safi == SAFI_UNICAST))
|
if (table && (table->safi == SAFI_UNICAST))
|
||||||
origin_local = 1;
|
origin_local = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy labels */
|
/* copy labels */
|
||||||
if (!origin_local &&
|
if (!origin_local && path_vpn->extra
|
||||||
info_vpn->extra && info_vpn->extra->num_labels) {
|
&& path_vpn->extra->num_labels) {
|
||||||
num_labels = info_vpn->extra->num_labels;
|
num_labels = path_vpn->extra->num_labels;
|
||||||
if (num_labels > BGP_MAX_LABELS)
|
if (num_labels > BGP_MAX_LABELS)
|
||||||
num_labels = BGP_MAX_LABELS;
|
num_labels = BGP_MAX_LABELS;
|
||||||
pLabels = info_vpn->extra->label;
|
pLabels = path_vpn->extra->label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1212,19 +1203,18 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
* For VRF-2-VRF route-leaking,
|
* For VRF-2-VRF route-leaking,
|
||||||
* the source will be the originating VRF.
|
* the source will be the originating VRF.
|
||||||
*/
|
*/
|
||||||
if (info_vpn->extra && info_vpn->extra->bgp_orig)
|
if (path_vpn->extra && path_vpn->extra->bgp_orig)
|
||||||
src_vrf = info_vpn->extra->bgp_orig;
|
src_vrf = path_vpn->extra->bgp_orig;
|
||||||
else
|
else
|
||||||
src_vrf = bgp_vpn;
|
src_vrf = bgp_vpn;
|
||||||
|
|
||||||
leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
|
leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
|
||||||
pLabels, num_labels,
|
num_labels, path_vpn, /* parent */
|
||||||
info_vpn, /* parent */
|
|
||||||
src_vrf, &nexthop_orig, nexthop_self_flag, debug);
|
src_vrf, &nexthop_orig, nexthop_self_flag, debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
||||||
struct bgp_info *info_vpn) /* route */
|
struct bgp_path_info *path_vpn) /* route */
|
||||||
{
|
{
|
||||||
struct listnode *mnode, *mnnode;
|
struct listnode *mnode, *mnnode;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
@ -1232,20 +1222,20 @@ void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
|||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
|
zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
|
||||||
|
|
||||||
/* 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 (!info_vpn->extra
|
if (!path_vpn->extra
|
||||||
|| info_vpn->extra->bgp_orig != bgp) { /* no loop */
|
|| path_vpn->extra->bgp_orig != bgp) { /* no loop */
|
||||||
vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
|
vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||||
struct bgp_info *info_vpn) /* route */
|
struct bgp_path_info *path_vpn) /* route */
|
||||||
{
|
{
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -1253,38 +1243,38 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
|||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct listnode *mnode, *mnnode;
|
struct listnode *mnode, *mnnode;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
const char *debugmsg;
|
const char *debugmsg;
|
||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
|
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
|
prefix2str(&path_vpn->net->p, buf_prefix, sizeof(buf_prefix));
|
||||||
zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
|
zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__,
|
||||||
__func__, buf_prefix,
|
buf_prefix, path_vpn->type, path_vpn->sub_type);
|
||||||
info_vpn->type, info_vpn->sub_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
|
zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
|
||||||
|
|
||||||
if (!info_vpn->net) {
|
if (!path_vpn->net) {
|
||||||
#if ENABLE_BGP_VNC
|
#if ENABLE_BGP_VNC
|
||||||
/* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
|
/* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
|
||||||
if (info_vpn->type == ZEBRA_ROUTE_BGP &&
|
if (path_vpn->type == ZEBRA_ROUTE_BGP
|
||||||
info_vpn->sub_type == BGP_ROUTE_RFP) {
|
&& path_vpn->sub_type == BGP_ROUTE_RFP) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
|
zlog_debug(
|
||||||
|
"%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
|
||||||
__func__);
|
__func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = &info_vpn->net->p;
|
p = &path_vpn->net->p;
|
||||||
afi = family2afi(p->family);
|
afi = family2afi(p->family);
|
||||||
|
|
||||||
/* Loop over VRFs */
|
/* Loop over VRFs */
|
||||||
@ -1299,7 +1289,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
|||||||
/* Check for intersection of route targets */
|
/* Check for intersection of route targets */
|
||||||
if (!ecom_intersect(bgp->vpn_policy[afi]
|
if (!ecom_intersect(bgp->vpn_policy[afi]
|
||||||
.rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
.rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
||||||
info_vpn->attr->ecommunity)) {
|
path_vpn->attr->ecommunity)) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1309,19 +1299,20 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
|||||||
bgp->name_pretty);
|
bgp->name_pretty);
|
||||||
|
|
||||||
bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
|
bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
|
||||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||||
if (bi->extra
|
if (bpi->extra
|
||||||
&& (struct bgp_info *)bi->extra->parent
|
&& (struct bgp_path_info *)bpi->extra->parent
|
||||||
== info_vpn) {
|
== path_vpn) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: deleting bi %p", __func__, bi);
|
zlog_debug("%s: deleting bpi %p", __func__,
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bpi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
@ -1332,25 +1323,25 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
|
|||||||
afi_t afi)
|
afi_t afi)
|
||||||
{
|
{
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
safi_t safi = SAFI_UNICAST;
|
safi_t safi = SAFI_UNICAST;
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: entry", __func__);
|
zlog_debug("%s: entry", __func__);
|
||||||
/*
|
/*
|
||||||
* Walk vrf table, delete bi with bgp_orig in a different vrf
|
* Walk vrf table, delete bpi with bgp_orig in a different vrf
|
||||||
*/
|
*/
|
||||||
for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
|
for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
|
||||||
bn = bgp_route_next(bn)) {
|
bn = bgp_route_next(bn)) {
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
|
if (bpi->extra && bpi->extra->bgp_orig != bgp_vrf) {
|
||||||
|
|
||||||
/* delete route */
|
/* delete route */
|
||||||
bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
|
bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi,
|
||||||
afi, safi);
|
afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp_vrf, bn, afi, safi);
|
bgp_process(bgp_vrf, bn, afi, safi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1375,7 +1366,7 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
|
|||||||
|
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
memset(&prd, 0, sizeof(prd));
|
memset(&prd, 0, sizeof(prd));
|
||||||
prd.family = AF_UNSPEC;
|
prd.family = AF_UNSPEC;
|
||||||
@ -1390,13 +1381,14 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
|
|||||||
|
|
||||||
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 (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
|
if (bpi->extra
|
||||||
|
&& bpi->extra->bgp_orig == bgp_vrf)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
|
vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
|
||||||
bi);
|
bpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,10 @@ extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
|
|||||||
int tags, bool use_json);
|
int tags, bool use_json);
|
||||||
|
|
||||||
extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
||||||
struct bgp_info *info_vrf);
|
struct bgp_path_info *path_vrf);
|
||||||
|
|
||||||
extern void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
extern void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
||||||
struct bgp_info *info_vrf);
|
struct bgp_path_info *path_vrf);
|
||||||
|
|
||||||
extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
|
extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
|
||||||
struct bgp *bgp_vrf, afi_t afi);
|
struct bgp *bgp_vrf, afi_t afi);
|
||||||
@ -70,10 +70,10 @@ extern void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, struct bgp *bgp_vpn,
|
|||||||
afi_t afi);
|
afi_t afi);
|
||||||
|
|
||||||
extern void vpn_leak_to_vrf_update(struct bgp *bgp_vpn,
|
extern void vpn_leak_to_vrf_update(struct bgp *bgp_vpn,
|
||||||
struct bgp_info *info_vpn);
|
struct bgp_path_info *path_vpn);
|
||||||
|
|
||||||
extern void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,
|
extern void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,
|
||||||
struct bgp_info *info_vpn);
|
struct bgp_path_info *path_vpn);
|
||||||
|
|
||||||
extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
|
extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
|
||||||
extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
|
extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
|
||||||
|
@ -63,7 +63,7 @@ struct bgp_nexthop_cache {
|
|||||||
|
|
||||||
struct bgp_node *node;
|
struct bgp_node *node;
|
||||||
void *nht_info; /* In BGP, peer session */
|
void *nht_info; /* In BGP, peer session */
|
||||||
LIST_HEAD(path_list, bgp_info) paths;
|
LIST_HEAD(path_list, bgp_path_info) paths;
|
||||||
unsigned int path_count;
|
unsigned int path_count;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
};
|
};
|
||||||
@ -74,8 +74,6 @@ struct tip_addr {
|
|||||||
int refcnt;
|
int refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int bgp_nexthop_lookup(afi_t, struct peer *peer, struct bgp_info *,
|
|
||||||
int *, int *);
|
|
||||||
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
|
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
|
||||||
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
|
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
|
||||||
extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
|
extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
|
||||||
|
@ -50,9 +50,9 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
|||||||
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
||||||
int is_bgp_static_route);
|
int is_bgp_static_route);
|
||||||
static void evaluate_paths(struct bgp_nexthop_cache *bnc);
|
static void evaluate_paths(struct bgp_nexthop_cache *bnc);
|
||||||
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p);
|
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
|
||||||
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
static void path_nh_map(struct bgp_path_info *path,
|
||||||
int keep);
|
struct bgp_nexthop_cache *bnc, int keep);
|
||||||
|
|
||||||
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
|
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ static int bgp_isvalid_labeled_nexthop(struct bgp_nexthop_cache *bnc)
|
|||||||
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)));
|
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_find_nexthop(struct bgp_info *path, int connected)
|
int bgp_find_nexthop(struct bgp_path_info *path, int connected)
|
||||||
{
|
{
|
||||||
struct bgp_nexthop_cache *bnc = path->nexthop;
|
struct bgp_nexthop_cache *bnc = path->nexthop;
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_unlink_nexthop(struct bgp_info *path)
|
void bgp_unlink_nexthop(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_nexthop_cache *bnc = path->nexthop;
|
struct bgp_nexthop_cache *bnc = path->nexthop;
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
|
|||||||
* we need both the bgp_route and bgp_nexthop pointers.
|
* we need both the bgp_route and bgp_nexthop pointers.
|
||||||
*/
|
*/
|
||||||
int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||||
afi_t afi, struct bgp_info *ri,
|
afi_t afi, struct bgp_path_info *pi,
|
||||||
struct peer *peer, int connected)
|
struct peer *peer, int connected)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
@ -151,9 +151,9 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
struct prefix p;
|
struct prefix p;
|
||||||
int is_bgp_static_route = 0;
|
int is_bgp_static_route = 0;
|
||||||
|
|
||||||
if (ri) {
|
if (pi) {
|
||||||
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP)
|
is_bgp_static_route = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||||
&& (ri->sub_type == BGP_ROUTE_STATIC))
|
&& (pi->sub_type == BGP_ROUTE_STATIC))
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
@ -161,12 +161,12 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
to derive
|
to derive
|
||||||
address-family from the next-hop. */
|
address-family from the next-hop. */
|
||||||
if (!is_bgp_static_route)
|
if (!is_bgp_static_route)
|
||||||
afi = BGP_ATTR_NEXTHOP_AFI_IP6(ri->attr) ? AFI_IP6
|
afi = BGP_ATTR_NEXTHOP_AFI_IP6(pi->attr) ? AFI_IP6
|
||||||
: AFI_IP;
|
: AFI_IP;
|
||||||
|
|
||||||
/* This will return TRUE if the global IPv6 NH is a link local
|
/* This will return TRUE if the global IPv6 NH is a link local
|
||||||
* addr */
|
* addr */
|
||||||
if (make_prefix(afi, ri, &p) < 0)
|
if (make_prefix(afi, pi, &p) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (peer) {
|
} else if (peer) {
|
||||||
if (!sockunion2hostprefix(&peer->su, &p)) {
|
if (!sockunion2hostprefix(&peer->su, &p)) {
|
||||||
@ -246,19 +246,19 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
bnc->flags |= BGP_NEXTHOP_VALID;
|
bnc->flags |= BGP_NEXTHOP_VALID;
|
||||||
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
|
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
|
||||||
register_zebra_rnh(bnc, is_bgp_static_route);
|
register_zebra_rnh(bnc, is_bgp_static_route);
|
||||||
if (ri && ri->nexthop != bnc) {
|
if (pi && pi->nexthop != bnc) {
|
||||||
/* Unlink from existing nexthop cache, if any. This will also
|
/* Unlink from existing nexthop cache, if any. This will also
|
||||||
* free
|
* free
|
||||||
* the nexthop cache entry, if appropriate.
|
* the nexthop cache entry, if appropriate.
|
||||||
*/
|
*/
|
||||||
bgp_unlink_nexthop(ri);
|
bgp_unlink_nexthop(pi);
|
||||||
|
|
||||||
path_nh_map(ri, bnc, 1); /* updates NHT ri list reference */
|
path_nh_map(pi, bnc, 1); /* updates NHT pi list reference */
|
||||||
|
|
||||||
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
|
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
|
||||||
(bgp_info_extra_get(ri))->igpmetric = bnc->metric;
|
(bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
|
||||||
else if (ri->extra)
|
else if (pi->extra)
|
||||||
ri->extra->igpmetric = 0;
|
pi->extra->igpmetric = 0;
|
||||||
} else if (peer)
|
} else if (peer)
|
||||||
bnc->nht_info = (void *)peer; /* NHT peer reference */
|
bnc->nht_info = (void *)peer; /* NHT peer reference */
|
||||||
|
|
||||||
@ -527,11 +527,11 @@ void bgp_cleanup_nexthops(struct bgp *bgp)
|
|||||||
* make_prefix - make a prefix structure from the path (essentially
|
* make_prefix - make a prefix structure from the path (essentially
|
||||||
* path's node.
|
* path's node.
|
||||||
*/
|
*/
|
||||||
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
int is_bgp_static = ((ri->type == ZEBRA_ROUTE_BGP)
|
int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||||
&& (ri->sub_type == BGP_ROUTE_STATIC))
|
&& (pi->sub_type == BGP_ROUTE_STATIC))
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
@ -540,10 +540,10 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
|||||||
case AFI_IP:
|
case AFI_IP:
|
||||||
p->family = AF_INET;
|
p->family = AF_INET;
|
||||||
if (is_bgp_static) {
|
if (is_bgp_static) {
|
||||||
p->u.prefix4 = ri->net->p.u.prefix4;
|
p->u.prefix4 = pi->net->p.u.prefix4;
|
||||||
p->prefixlen = ri->net->p.prefixlen;
|
p->prefixlen = pi->net->p.prefixlen;
|
||||||
} else {
|
} else {
|
||||||
p->u.prefix4 = ri->attr->nexthop;
|
p->u.prefix4 = pi->attr->nexthop;
|
||||||
p->prefixlen = IPV4_MAX_BITLEN;
|
p->prefixlen = IPV4_MAX_BITLEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -551,10 +551,10 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
|||||||
p->family = AF_INET6;
|
p->family = AF_INET6;
|
||||||
|
|
||||||
if (is_bgp_static) {
|
if (is_bgp_static) {
|
||||||
p->u.prefix6 = ri->net->p.u.prefix6;
|
p->u.prefix6 = pi->net->p.u.prefix6;
|
||||||
p->prefixlen = ri->net->p.prefixlen;
|
p->prefixlen = pi->net->p.prefixlen;
|
||||||
} else {
|
} else {
|
||||||
p->u.prefix6 = ri->attr->mp_nexthop_global;
|
p->u.prefix6 = pi->attr->mp_nexthop_global;
|
||||||
p->prefixlen = IPV6_MAX_BITLEN;
|
p->prefixlen = IPV6_MAX_BITLEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -673,7 +673,7 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
|||||||
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *path;
|
struct bgp_path_info *path;
|
||||||
int afi;
|
int afi;
|
||||||
struct peer *peer = (struct peer *)bnc->nht_info;
|
struct peer *peer = (struct peer *)bnc->nht_info;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
@ -740,14 +740,16 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
|||||||
(bnc_is_valid_nexthop ? "" : "not "));
|
(bnc_is_valid_nexthop ? "" : "not "));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0)
|
if ((CHECK_FLAG(path->flags, BGP_PATH_VALID) ? 1 : 0)
|
||||||
!= bnc_is_valid_nexthop) {
|
!= bnc_is_valid_nexthop) {
|
||||||
if (CHECK_FLAG(path->flags, BGP_INFO_VALID)) {
|
if (CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
|
||||||
bgp_aggregate_decrement(bgp_path, &rn->p,
|
bgp_aggregate_decrement(bgp_path, &rn->p,
|
||||||
path, afi, safi);
|
path, afi, safi);
|
||||||
bgp_info_unset_flag(rn, path, BGP_INFO_VALID);
|
bgp_path_info_unset_flag(rn, path,
|
||||||
|
BGP_PATH_VALID);
|
||||||
} else {
|
} else {
|
||||||
bgp_info_set_flag(rn, path, BGP_INFO_VALID);
|
bgp_path_info_set_flag(rn, path,
|
||||||
|
BGP_PATH_VALID);
|
||||||
bgp_aggregate_increment(bgp_path, &rn->p,
|
bgp_aggregate_increment(bgp_path, &rn->p,
|
||||||
path, afi, safi);
|
path, afi, safi);
|
||||||
}
|
}
|
||||||
@ -756,13 +758,14 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
|||||||
/* Copy the metric to the path. Will be used for bestpath
|
/* Copy the metric to the path. Will be used for bestpath
|
||||||
* computation */
|
* computation */
|
||||||
if (bgp_isvalid_nexthop(bnc) && bnc->metric)
|
if (bgp_isvalid_nexthop(bnc) && bnc->metric)
|
||||||
(bgp_info_extra_get(path))->igpmetric = bnc->metric;
|
(bgp_path_info_extra_get(path))->igpmetric =
|
||||||
|
bnc->metric;
|
||||||
else if (path->extra)
|
else if (path->extra)
|
||||||
path->extra->igpmetric = 0;
|
path->extra->igpmetric = 0;
|
||||||
|
|
||||||
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
|
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
|
||||||
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
|
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
|
||||||
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
|
SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED);
|
||||||
|
|
||||||
bgp_process(bgp_path, rn, afi, safi);
|
bgp_process(bgp_path, rn, afi, safi);
|
||||||
}
|
}
|
||||||
@ -786,8 +789,8 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
|||||||
* make - if set, make the association. if unset, just break the existing
|
* make - if set, make the association. if unset, just break the existing
|
||||||
* association.
|
* association.
|
||||||
*/
|
*/
|
||||||
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
static void path_nh_map(struct bgp_path_info *path,
|
||||||
int make)
|
struct bgp_nexthop_cache *bnc, int make)
|
||||||
{
|
{
|
||||||
if (path->nexthop) {
|
if (path->nexthop) {
|
||||||
LIST_REMOVE(path, nh_thread);
|
LIST_REMOVE(path, nh_thread);
|
||||||
|
@ -32,7 +32,7 @@ extern void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id);
|
|||||||
* p - path for which the nexthop object is being looked up
|
* p - path for which the nexthop object is being looked up
|
||||||
* connected - True if NH MUST be a connected route
|
* connected - True if NH MUST be a connected route
|
||||||
*/
|
*/
|
||||||
extern int bgp_find_nexthop(struct bgp_info *p, int connected);
|
extern int bgp_find_nexthop(struct bgp_path_info *p, int connected);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
|
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
|
||||||
@ -47,16 +47,17 @@ extern int bgp_find_nexthop(struct bgp_info *p, int connected);
|
|||||||
* connected - True if NH MUST be a connected route
|
* connected - True if NH MUST be a connected route
|
||||||
*/
|
*/
|
||||||
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
||||||
struct bgp *bgp_nexthop, afi_t a, struct bgp_info *p,
|
struct bgp *bgp_nexthop, afi_t a,
|
||||||
struct peer *peer, int connected);
|
struct bgp_path_info *p, struct peer *peer,
|
||||||
|
int connected);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* p - path structure.
|
* p - path structure.
|
||||||
*/
|
*/
|
||||||
extern void bgp_unlink_nexthop(struct bgp_info *p);
|
extern void bgp_unlink_nexthop(struct bgp_path_info *p);
|
||||||
void bgp_unlink_nexthop_by_peer(struct peer *);
|
void bgp_unlink_nexthop_by_peer(struct peer *peer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
|
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
|
||||||
|
219
bgpd/bgp_pbr.c
219
bgpd/bgp_pbr.c
@ -227,7 +227,7 @@ struct bgp_pbr_or_filter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct nexthop *nh,
|
struct nexthop *nh,
|
||||||
float *rate);
|
float *rate);
|
||||||
@ -627,7 +627,7 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
|
|||||||
|
|
||||||
/* return -1 if build or validation failed */
|
/* return -1 if build or validation failed */
|
||||||
static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
||||||
struct bgp_info *info,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_entry_main *api)
|
struct bgp_pbr_entry_main *api)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -645,8 +645,8 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* extract actiosn from flowspec ecom list */
|
/* extract actiosn from flowspec ecom list */
|
||||||
if (info && info->attr && info->attr->ecommunity) {
|
if (path && path->attr && path->attr->ecommunity) {
|
||||||
ecom = info->attr->ecommunity;
|
ecom = path->attr->ecommunity;
|
||||||
for (i = 0; i < ecom->size; i++) {
|
for (i = 0; i < ecom->size; i++) {
|
||||||
ecom_eval = (struct ecommunity_val *)
|
ecom_eval = (struct ecommunity_val *)
|
||||||
(ecom->val + (i * ECOMMUNITY_SIZE));
|
(ecom->val + (i * ECOMMUNITY_SIZE));
|
||||||
@ -690,7 +690,7 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
|||||||
(char)ECOMMUNITY_REDIRECT_IP_NH)) {
|
(char)ECOMMUNITY_REDIRECT_IP_NH)) {
|
||||||
api_action->action = ACTION_REDIRECT_IP;
|
api_action->action = ACTION_REDIRECT_IP;
|
||||||
api_action->u.zr.redirect_ip_v4.s_addr =
|
api_action->u.zr.redirect_ip_v4.s_addr =
|
||||||
info->attr->nexthop.s_addr;
|
path->attr->nexthop.s_addr;
|
||||||
api_action->u.zr.duplicate = ecom_eval->val[7];
|
api_action->u.zr.duplicate = ecom_eval->val[7];
|
||||||
} else {
|
} else {
|
||||||
if (ecom_eval->val[0] !=
|
if (ecom_eval->val[0] !=
|
||||||
@ -1223,16 +1223,16 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
|
|||||||
bgp_send_pbr_ipset_entry_match(bpme, false);
|
bgp_send_pbr_ipset_entry_match(bpme, false);
|
||||||
bpme->installed = false;
|
bpme->installed = false;
|
||||||
bpme->backpointer = NULL;
|
bpme->backpointer = NULL;
|
||||||
if (bpme->bgp_info) {
|
if (bpme->path) {
|
||||||
struct bgp_info *bgp_info;
|
struct bgp_path_info *path;
|
||||||
struct bgp_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
/* unlink bgp_info to bpme */
|
/* unlink bgp_path_info to bpme */
|
||||||
bgp_info = (struct bgp_info *)bpme->bgp_info;
|
path = (struct bgp_path_info *)bpme->path;
|
||||||
extra = bgp_info_extra_get(bgp_info);
|
extra = bgp_path_info_extra_get(path);
|
||||||
if (extra->bgp_fs_pbr)
|
if (extra->bgp_fs_pbr)
|
||||||
listnode_delete(extra->bgp_fs_pbr, bpme);
|
listnode_delete(extra->bgp_fs_pbr, bpme);
|
||||||
bpme->bgp_info = NULL;
|
bpme->path = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_release(bpm->entry_hash, bpme);
|
hash_release(bpm->entry_hash, bpme);
|
||||||
@ -1304,9 +1304,8 @@ static int bgp_pbr_get_remaining_entry(struct hash_backet *backet, void *arg)
|
|||||||
return HASHWALK_ABORT;
|
return HASHWALK_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
|
static void bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf)
|
||||||
struct bgp_pbr_filter *bpf)
|
|
||||||
{
|
{
|
||||||
struct bgp_pbr_match temp;
|
struct bgp_pbr_match temp;
|
||||||
struct bgp_pbr_match_entry temp2;
|
struct bgp_pbr_match_entry temp2;
|
||||||
@ -1438,13 +1437,10 @@ static uint8_t bgp_pbr_next_type_entry(uint8_t type_entry)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_icmp_action(struct bgp *bgp,
|
static void bgp_pbr_icmp_action(struct bgp *bgp, struct bgp_path_info *path,
|
||||||
struct bgp_info *binfo,
|
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_or_filter *bpof,
|
struct bgp_pbr_or_filter *bpof, bool add,
|
||||||
bool add,
|
struct nexthop *nh, float *rate)
|
||||||
struct nexthop *nh,
|
|
||||||
float *rate)
|
|
||||||
{
|
{
|
||||||
struct bgp_pbr_range_port srcp, dstp;
|
struct bgp_pbr_range_port srcp, dstp;
|
||||||
struct bgp_pbr_val_mask *icmp_type, *icmp_code;
|
struct bgp_pbr_val_mask *icmp_type, *icmp_code;
|
||||||
@ -1466,11 +1462,11 @@ static void bgp_pbr_icmp_action(struct bgp *bgp,
|
|||||||
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
||||||
dstp.min_port = icmp_code->val;
|
dstp.min_port = icmp_code->val;
|
||||||
if (add)
|
if (add)
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||||
bpf, nh, rate);
|
bgp, path, bpf, nh, rate);
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(
|
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
bgp, binfo, bpf);
|
bgp, path, bpf);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1487,31 +1483,27 @@ static void bgp_pbr_icmp_action(struct bgp *bgp,
|
|||||||
dstp.max_port = 255;
|
dstp.max_port = 255;
|
||||||
if (add)
|
if (add)
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||||
bgp, binfo,
|
bgp, path, bpf, nh, rate);
|
||||||
bpf, nh, rate);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
binfo, bpf);
|
bgp, path, bpf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
||||||
dstp.min_port = icmp_code->val;
|
dstp.min_port = icmp_code->val;
|
||||||
if (add)
|
if (add)
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||||
bgp, binfo,
|
bgp, path, bpf, nh, rate);
|
||||||
bpf, nh, rate);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(
|
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
bgp, binfo, bpf);
|
bgp, path, bpf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_remove_from_zebra_recursive(struct bgp *bgp,
|
static void bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_or_filter *bpof, uint8_t type_entry)
|
||||||
struct bgp_pbr_or_filter *bpof,
|
|
||||||
uint8_t type_entry)
|
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct bgp_pbr_val_mask *valmask;
|
struct bgp_pbr_val_mask *valmask;
|
||||||
@ -1520,8 +1512,8 @@ static void bgp_pbr_policyroute_remove_from_zebra_recursive(struct bgp *bgp,
|
|||||||
struct bgp_pbr_val_mask **target_val;
|
struct bgp_pbr_val_mask **target_val;
|
||||||
|
|
||||||
if (type_entry == 0)
|
if (type_entry == 0)
|
||||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path,
|
||||||
binfo, bpf);
|
bpf);
|
||||||
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
||||||
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
||||||
orig_list = bpof->tcpflags;
|
orig_list = bpof->tcpflags;
|
||||||
@ -1538,53 +1530,43 @@ static void bgp_pbr_policyroute_remove_from_zebra_recursive(struct bgp *bgp,
|
|||||||
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
||||||
(bpof->icmp_type || bpof->icmp_code)) {
|
(bpof->icmp_type || bpof->icmp_code)) {
|
||||||
/* enumerate list for icmp - must be last one */
|
/* enumerate list for icmp - must be last one */
|
||||||
bgp_pbr_icmp_action(bgp, binfo, bpf, bpof, false, NULL, NULL);
|
bgp_pbr_icmp_action(bgp, path, bpf, bpof, false, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return bgp_pbr_policyroute_remove_from_zebra_recursive(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
binfo,
|
bgp, path, bpf, bpof, next_type_entry);
|
||||||
bpf, bpof,
|
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
||||||
*target_val = valmask;
|
*target_val = valmask;
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, next_type_entry);
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_remove_from_zebra(struct bgp *bgp,
|
static void bgp_pbr_policyroute_remove_from_zebra(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
|
||||||
struct bgp_pbr_or_filter *bpof)
|
struct bgp_pbr_or_filter *bpof)
|
||||||
{
|
{
|
||||||
if (!bpof)
|
if (!bpof)
|
||||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path,
|
||||||
binfo,
|
|
||||||
bpf);
|
bpf);
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_TCP_FLAGS);
|
||||||
FLOWSPEC_TCP_FLAGS);
|
|
||||||
else if (bpof->dscp)
|
else if (bpof->dscp)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_DSCP);
|
||||||
FLOWSPEC_DSCP);
|
|
||||||
else if (bpof->pkt_len)
|
else if (bpof->pkt_len)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_PKT_LEN);
|
||||||
FLOWSPEC_PKT_LEN);
|
|
||||||
else if (bpof->fragment)
|
else if (bpof->fragment)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_FRAGMENT);
|
||||||
FLOWSPEC_FRAGMENT);
|
|
||||||
else if (bpof->icmp_type || bpof->icmp_code)
|
else if (bpof->icmp_type || bpof->icmp_code)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_ICMP_TYPE);
|
||||||
FLOWSPEC_ICMP_TYPE);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, binfo, bpf);
|
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path, bpf);
|
||||||
/* flush bpof */
|
/* flush bpof */
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
list_delete_all_node(bpof->tcpflags);
|
list_delete_all_node(bpof->tcpflags);
|
||||||
@ -1692,7 +1674,7 @@ static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct nexthop *nh,
|
struct nexthop *nh,
|
||||||
float *rate)
|
float *rate)
|
||||||
@ -1848,19 +1830,21 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
bpme->installed = false;
|
bpme->installed = false;
|
||||||
bpme->install_in_progress = false;
|
bpme->install_in_progress = false;
|
||||||
/* link bgp info to bpme */
|
/* link bgp info to bpme */
|
||||||
bpme->bgp_info = (void *)binfo;
|
bpme->path = (void *)path;
|
||||||
} else
|
} else
|
||||||
bpme_found = true;
|
bpme_found = true;
|
||||||
|
|
||||||
/* already installed */
|
/* already installed */
|
||||||
if (bpme_found) {
|
if (bpme_found) {
|
||||||
struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
|
struct bgp_path_info_extra *extra =
|
||||||
|
bgp_path_info_extra_get(path);
|
||||||
|
|
||||||
if (extra && extra->bgp_fs_pbr &&
|
if (extra && extra->bgp_fs_pbr &&
|
||||||
listnode_lookup(extra->bgp_fs_pbr, bpme)) {
|
listnode_lookup(extra->bgp_fs_pbr, bpme)) {
|
||||||
if (BGP_DEBUG(pbr, PBR_ERROR))
|
if (BGP_DEBUG(pbr, PBR_ERROR))
|
||||||
zlog_err("%s: entry %p/%p already installed in bgp pbr",
|
zlog_err(
|
||||||
__func__, binfo, bpme);
|
"%s: entry %p/%p already installed in bgp pbr",
|
||||||
|
__func__, path, bpme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1911,12 +1895,9 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_or_filter *bpof, struct nexthop *nh, float *rate,
|
||||||
struct bgp_pbr_or_filter *bpof,
|
|
||||||
struct nexthop *nh,
|
|
||||||
float *rate,
|
|
||||||
uint8_t type_entry)
|
uint8_t type_entry)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
@ -1926,8 +1907,8 @@ static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
|||||||
struct bgp_pbr_val_mask **target_val;
|
struct bgp_pbr_val_mask **target_val;
|
||||||
|
|
||||||
if (type_entry == 0)
|
if (type_entry == 0)
|
||||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf,
|
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh,
|
||||||
nh, rate);
|
rate);
|
||||||
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
||||||
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
||||||
orig_list = bpof->tcpflags;
|
orig_list = bpof->tcpflags;
|
||||||
@ -1944,59 +1925,45 @@ static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
|||||||
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
||||||
(bpof->icmp_type || bpof->icmp_code)) {
|
(bpof->icmp_type || bpof->icmp_code)) {
|
||||||
/* enumerate list for icmp - must be last one */
|
/* enumerate list for icmp - must be last one */
|
||||||
bgp_pbr_icmp_action(bgp, binfo, bpf, bpof, true, nh, rate);
|
bgp_pbr_icmp_action(bgp, path, bpf, bpof, true, nh, rate);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
return bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof, nh, rate,
|
bgp, path, bpf, bpof, nh, rate, next_type_entry);
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
||||||
*target_val = valmask;
|
*target_val = valmask;
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, next_type_entry);
|
||||||
nh, rate,
|
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_or_filter *bpof,
|
struct bgp_pbr_or_filter *bpof,
|
||||||
struct nexthop *nh,
|
struct nexthop *nh, float *rate)
|
||||||
float *rate)
|
|
||||||
{
|
{
|
||||||
if (!bpof)
|
if (!bpof)
|
||||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
|
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh,
|
||||||
bpf, nh, rate);
|
rate);
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_TCP_FLAGS);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_TCP_FLAGS);
|
|
||||||
else if (bpof->dscp)
|
else if (bpof->dscp)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_DSCP);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_DSCP);
|
|
||||||
else if (bpof->pkt_len)
|
else if (bpof->pkt_len)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_PKT_LEN);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_PKT_LEN);
|
|
||||||
else if (bpof->fragment)
|
else if (bpof->fragment)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_FRAGMENT);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_FRAGMENT);
|
|
||||||
else if (bpof->icmp_type || bpof->icmp_code)
|
else if (bpof->icmp_type || bpof->icmp_code)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof, nh, rate,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_ICMP_TYPE);
|
||||||
FLOWSPEC_ICMP_TYPE);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf,
|
bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh, rate);
|
||||||
nh, rate);
|
|
||||||
/* flush bpof */
|
/* flush bpof */
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
list_delete_all_node(bpof->tcpflags);
|
list_delete_all_node(bpof->tcpflags);
|
||||||
@ -2012,10 +1979,8 @@ static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
|||||||
list_delete_all_node(bpof->icmp_code);
|
list_delete_all_node(bpof->icmp_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_handle_entry(struct bgp *bgp,
|
static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
|
||||||
struct bgp_info *binfo,
|
struct bgp_pbr_entry_main *api, bool add)
|
||||||
struct bgp_pbr_entry_main *api,
|
|
||||||
bool add)
|
|
||||||
{
|
{
|
||||||
struct nexthop nh;
|
struct nexthop nh;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -2151,9 +2116,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
bpf.src_port = srcp;
|
bpf.src_port = srcp;
|
||||||
bpf.dst_port = dstp;
|
bpf.dst_port = dstp;
|
||||||
if (!add)
|
if (!add)
|
||||||
return bgp_pbr_policyroute_remove_from_zebra(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf,
|
||||||
binfo,
|
&bpof);
|
||||||
&bpf, &bpof);
|
|
||||||
/* no action for add = true */
|
/* no action for add = true */
|
||||||
for (i = 0; i < api->action_num; i++) {
|
for (i = 0; i < api->action_num; i++) {
|
||||||
switch (api->actions[i].action) {
|
switch (api->actions[i].action) {
|
||||||
@ -2162,9 +2126,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
if (api->actions[i].u.r.rate == 0) {
|
if (api->actions[i].u.r.rate == 0) {
|
||||||
nh.vrf_id = api->vrf_id;
|
nh.vrf_id = api->vrf_id;
|
||||||
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra(
|
||||||
&bpf, &bpof,
|
bgp, path, &bpf, &bpof, &nh, &rate);
|
||||||
&nh, &rate);
|
|
||||||
} else {
|
} else {
|
||||||
/* update rate. can be reentrant */
|
/* update rate. can be reentrant */
|
||||||
rate = api->actions[i].u.r.rate;
|
rate = api->actions[i].u.r.rate;
|
||||||
@ -2204,8 +2167,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
nh.gate.ipv4.s_addr =
|
nh.gate.ipv4.s_addr =
|
||||||
api->actions[i].u.zr.redirect_ip_v4.s_addr;
|
api->actions[i].u.zr.redirect_ip_v4.s_addr;
|
||||||
nh.vrf_id = api->vrf_id;
|
nh.vrf_id = api->vrf_id;
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||||
&bpf, &bpof,
|
|
||||||
&nh, &rate);
|
&nh, &rate);
|
||||||
/* XXX combination with REDIRECT_VRF
|
/* XXX combination with REDIRECT_VRF
|
||||||
* + REDIRECT_NH_IP not done
|
* + REDIRECT_NH_IP not done
|
||||||
@ -2215,8 +2177,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
case ACTION_REDIRECT:
|
case ACTION_REDIRECT:
|
||||||
nh.vrf_id = api->actions[i].u.redirect_vrf;
|
nh.vrf_id = api->actions[i].u.redirect_vrf;
|
||||||
nh.type = NEXTHOP_TYPE_IPV4;
|
nh.type = NEXTHOP_TYPE_IPV4;
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||||
&bpf, &bpof,
|
|
||||||
&nh, &rate);
|
&nh, &rate);
|
||||||
continue_loop = 0;
|
continue_loop = 0;
|
||||||
break;
|
break;
|
||||||
@ -2236,7 +2197,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
||||||
struct bgp_info *info, afi_t afi, safi_t safi,
|
struct bgp_path_info *info, afi_t afi, safi_t safi,
|
||||||
bool nlri_update)
|
bool nlri_update)
|
||||||
{
|
{
|
||||||
struct bgp_pbr_entry_main api;
|
struct bgp_pbr_entry_main api;
|
||||||
|
@ -219,7 +219,7 @@ struct bgp_pbr_match_entry {
|
|||||||
uint16_t dst_port_max;
|
uint16_t dst_port_max;
|
||||||
uint8_t proto;
|
uint8_t proto;
|
||||||
|
|
||||||
void *bgp_info;
|
void *path;
|
||||||
|
|
||||||
bool installed;
|
bool installed;
|
||||||
bool install_in_progress;
|
bool install_in_progress;
|
||||||
@ -279,11 +279,10 @@ extern int bgp_pbr_match_hash_equal(const void *arg1,
|
|||||||
void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api);
|
void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api);
|
||||||
|
|
||||||
struct bgp_node;
|
struct bgp_node;
|
||||||
struct bgp_info;
|
struct bgp_path_info;
|
||||||
extern void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
extern void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
||||||
struct bgp_info *new_select,
|
struct bgp_path_info *new_select, afi_t afi,
|
||||||
afi_t afi, safi_t safi,
|
safi_t safi, bool nlri_update);
|
||||||
bool nlri_update);
|
|
||||||
|
|
||||||
/* bgp pbr utilities */
|
/* bgp pbr utilities */
|
||||||
extern struct bgp_pbr_interface *pbr_interface_lookup(const char *name);
|
extern struct bgp_pbr_interface *pbr_interface_lookup(const char *name);
|
||||||
|
1811
bgpd/bgp_route.c
1811
bgpd/bgp_route.c
File diff suppressed because it is too large
Load Diff
154
bgpd/bgp_route.h
154
bgpd/bgp_route.h
@ -72,11 +72,11 @@ enum bgp_show_adj_route_type {
|
|||||||
*/
|
*/
|
||||||
#define BGP_MAX_LABELS 2
|
#define BGP_MAX_LABELS 2
|
||||||
|
|
||||||
/* Ancillary information to struct bgp_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.
|
||||||
*/
|
*/
|
||||||
struct bgp_info_extra {
|
struct bgp_path_info_extra {
|
||||||
/* Pointer to dampening structure. */
|
/* Pointer to dampening structure. */
|
||||||
struct bgp_damp_info *damp_info;
|
struct bgp_damp_info *damp_info;
|
||||||
|
|
||||||
@ -150,13 +150,13 @@ struct bgp_info_extra {
|
|||||||
struct list *bgp_fs_pbr;
|
struct list *bgp_fs_pbr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bgp_info {
|
struct bgp_path_info {
|
||||||
/* For linked list. */
|
/* For linked list. */
|
||||||
struct bgp_info *next;
|
struct bgp_path_info *next;
|
||||||
struct bgp_info *prev;
|
struct bgp_path_info *prev;
|
||||||
|
|
||||||
/* For nexthop linked list */
|
/* For nexthop linked list */
|
||||||
LIST_ENTRY(bgp_info) nh_thread;
|
LIST_ENTRY(bgp_path_info) nh_thread;
|
||||||
|
|
||||||
/* Back pointer to the prefix node */
|
/* Back pointer to the prefix node */
|
||||||
struct bgp_node *net;
|
struct bgp_node *net;
|
||||||
@ -171,11 +171,11 @@ struct bgp_info {
|
|||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
/* Extra information */
|
/* Extra information */
|
||||||
struct bgp_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
|
|
||||||
/* Multipath information */
|
/* Multipath information */
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
|
|
||||||
/* Uptime. */
|
/* Uptime. */
|
||||||
time_t uptime;
|
time_t uptime;
|
||||||
@ -185,21 +185,21 @@ struct bgp_info {
|
|||||||
|
|
||||||
/* BGP information status. */
|
/* BGP information status. */
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
#define BGP_INFO_IGP_CHANGED (1 << 0)
|
#define BGP_PATH_IGP_CHANGED (1 << 0)
|
||||||
#define BGP_INFO_DAMPED (1 << 1)
|
#define BGP_PATH_DAMPED (1 << 1)
|
||||||
#define BGP_INFO_HISTORY (1 << 2)
|
#define BGP_PATH_HISTORY (1 << 2)
|
||||||
#define BGP_INFO_SELECTED (1 << 3)
|
#define BGP_PATH_SELECTED (1 << 3)
|
||||||
#define BGP_INFO_VALID (1 << 4)
|
#define BGP_PATH_VALID (1 << 4)
|
||||||
#define BGP_INFO_ATTR_CHANGED (1 << 5)
|
#define BGP_PATH_ATTR_CHANGED (1 << 5)
|
||||||
#define BGP_INFO_DMED_CHECK (1 << 6)
|
#define BGP_PATH_DMED_CHECK (1 << 6)
|
||||||
#define BGP_INFO_DMED_SELECTED (1 << 7)
|
#define BGP_PATH_DMED_SELECTED (1 << 7)
|
||||||
#define BGP_INFO_STALE (1 << 8)
|
#define BGP_PATH_STALE (1 << 8)
|
||||||
#define BGP_INFO_REMOVED (1 << 9)
|
#define BGP_PATH_REMOVED (1 << 9)
|
||||||
#define BGP_INFO_COUNTED (1 << 10)
|
#define BGP_PATH_COUNTED (1 << 10)
|
||||||
#define BGP_INFO_MULTIPATH (1 << 11)
|
#define BGP_PATH_MULTIPATH (1 << 11)
|
||||||
#define BGP_INFO_MULTIPATH_CHG (1 << 12)
|
#define BGP_PATH_MULTIPATH_CHG (1 << 12)
|
||||||
#define BGP_INFO_RIB_ATTR_CHG (1 << 13)
|
#define BGP_PATH_RIB_ATTR_CHG (1 << 13)
|
||||||
#define BGP_INFO_ANNC_NH_SELF (1 << 14)
|
#define BGP_PATH_ANNC_NH_SELF (1 << 14)
|
||||||
|
|
||||||
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
|
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@ -224,9 +224,9 @@ struct bgp_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Structure used in BGP path selection */
|
/* Structure used in BGP path selection */
|
||||||
struct bgp_info_pair {
|
struct bgp_path_info_pair {
|
||||||
struct bgp_info *old;
|
struct bgp_path_info *old;
|
||||||
struct bgp_info *new;
|
struct bgp_path_info *new;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BGP static route configuration. */
|
/* BGP static route configuration. */
|
||||||
@ -277,20 +277,20 @@ struct bgp_static {
|
|||||||
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
|
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
|
||||||
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
|
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
|
||||||
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
|
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
|
||||||
#define BGP_INFO_COUNTABLE(BI) \
|
#define BGP_PATH_COUNTABLE(BI) \
|
||||||
(!CHECK_FLAG((BI)->flags, BGP_INFO_HISTORY) \
|
(!CHECK_FLAG((BI)->flags, BGP_PATH_HISTORY) \
|
||||||
&& !CHECK_FLAG((BI)->flags, BGP_INFO_REMOVED))
|
&& !CHECK_FLAG((BI)->flags, BGP_PATH_REMOVED))
|
||||||
|
|
||||||
/* Flags which indicate a route is unuseable in some form */
|
/* Flags which indicate a route is unuseable in some form */
|
||||||
#define BGP_INFO_UNUSEABLE \
|
#define BGP_PATH_UNUSEABLE \
|
||||||
(BGP_INFO_HISTORY | BGP_INFO_DAMPED | BGP_INFO_REMOVED)
|
(BGP_PATH_HISTORY | BGP_PATH_DAMPED | BGP_PATH_REMOVED)
|
||||||
/* Macro to check BGP information is alive or not. Sadly,
|
/* Macro to check BGP information is alive or not. Sadly,
|
||||||
* not equivalent to just checking previous, because of the
|
* not equivalent to just checking previous, because of the
|
||||||
* sense of the additional VALID flag.
|
* sense of the additional VALID flag.
|
||||||
*/
|
*/
|
||||||
#define BGP_INFO_HOLDDOWN(BI) \
|
#define BGP_PATH_HOLDDOWN(BI) \
|
||||||
(!CHECK_FLAG((BI)->flags, BGP_INFO_VALID) \
|
(!CHECK_FLAG((BI)->flags, BGP_PATH_VALID) \
|
||||||
|| CHECK_FLAG((BI)->flags, BGP_INFO_UNUSEABLE))
|
|| CHECK_FLAG((BI)->flags, BGP_PATH_UNUSEABLE))
|
||||||
|
|
||||||
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
|
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
|
||||||
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
|
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
|
||||||
@ -318,7 +318,11 @@ struct bgp_static {
|
|||||||
/* path PREFIX (addpath rxid NUMBER) */
|
/* path PREFIX (addpath rxid NUMBER) */
|
||||||
#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32
|
#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32
|
||||||
|
|
||||||
enum bgp_path_type { BGP_PATH_ALL, BGP_PATH_BESTPATH, BGP_PATH_MULTIPATH };
|
enum bgp_path_type {
|
||||||
|
BGP_PATH_SHOW_ALL,
|
||||||
|
BGP_PATH_SHOW_BESTPATH,
|
||||||
|
BGP_PATH_SHOW_MULTIPATH
|
||||||
|
};
|
||||||
|
|
||||||
static inline void bgp_bump_version(struct bgp_node *node)
|
static inline void bgp_bump_version(struct bgp_node *node)
|
||||||
{
|
{
|
||||||
@ -335,7 +339,7 @@ static inline int bgp_fibupd_safi(safi_t safi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
extern void bgp_rib_remove(struct bgp_node *rn, struct bgp_info *ri,
|
extern void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *peer, afi_t afi, safi_t safi);
|
struct peer *peer, afi_t afi, safi_t safi);
|
||||||
extern void bgp_process_queue_init(void);
|
extern void bgp_process_queue_init(void);
|
||||||
extern void bgp_route_init(void);
|
extern void bgp_route_init(void);
|
||||||
@ -354,15 +358,19 @@ extern void bgp_clear_stale_route(struct peer *, afi_t, safi_t);
|
|||||||
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
||||||
safi_t safi, struct prefix *p,
|
safi_t safi, struct prefix *p,
|
||||||
struct prefix_rd *prd);
|
struct prefix_rd *prd);
|
||||||
extern struct bgp_info *bgp_info_lock(struct bgp_info *);
|
extern struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path);
|
||||||
extern struct bgp_info *bgp_info_unlock(struct bgp_info *);
|
extern struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path);
|
||||||
extern void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri);
|
extern void bgp_path_info_add(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri);
|
extern void bgp_path_info_reap(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri);
|
extern void bgp_path_info_delete(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *);
|
extern struct bgp_path_info_extra *
|
||||||
extern void bgp_info_set_flag(struct bgp_node *, struct bgp_info *, uint32_t);
|
bgp_path_info_extra_get(struct bgp_path_info *path);
|
||||||
extern void bgp_info_unset_flag(struct bgp_node *, struct bgp_info *, uint32_t);
|
extern void bgp_path_info_set_flag(struct bgp_node *rn,
|
||||||
extern void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf);
|
struct bgp_path_info *path, uint32_t flag);
|
||||||
|
extern void bgp_path_info_unset_flag(struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *path, uint32_t flag);
|
||||||
|
extern void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi,
|
||||||
|
char *buf);
|
||||||
|
|
||||||
extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);
|
extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);
|
||||||
|
|
||||||
@ -416,38 +424,44 @@ extern void bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t);
|
|||||||
extern void bgp_config_write_distance(struct vty *, struct bgp *, afi_t,
|
extern void bgp_config_write_distance(struct vty *, struct bgp *, afi_t,
|
||||||
safi_t);
|
safi_t);
|
||||||
|
|
||||||
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
|
extern void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
|
||||||
struct bgp_info *, afi_t, safi_t);
|
struct bgp_path_info *path, afi_t afi,
|
||||||
extern void bgp_aggregate_decrement(struct bgp *, struct prefix *,
|
safi_t safi);
|
||||||
struct bgp_info *, afi_t, safi_t);
|
extern void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
|
||||||
|
struct bgp_path_info *path, afi_t afi,
|
||||||
|
safi_t safi);
|
||||||
|
|
||||||
extern uint8_t bgp_distance_apply(struct prefix *, struct bgp_info *, afi_t,
|
extern uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *path,
|
||||||
safi_t, struct bgp *);
|
afi_t afi, safi_t safi, struct bgp *bgp);
|
||||||
|
|
||||||
extern afi_t bgp_node_afi(struct vty *);
|
extern afi_t bgp_node_afi(struct vty *);
|
||||||
extern safi_t bgp_node_safi(struct vty *);
|
extern safi_t bgp_node_safi(struct vty *);
|
||||||
|
|
||||||
extern struct bgp_info *info_make(int type, int sub_type,
|
extern struct bgp_path_info *info_make(int type, int sub_type,
|
||||||
unsigned short instance, struct peer *peer,
|
unsigned short instance,
|
||||||
struct attr *attr, struct bgp_node *rn);
|
struct peer *peer, struct attr *attr,
|
||||||
|
struct bgp_node *rn);
|
||||||
|
|
||||||
extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
|
extern void route_vty_out(struct vty *vty, struct prefix *p,
|
||||||
safi_t, json_object *);
|
struct bgp_path_info *path, int display, safi_t safi,
|
||||||
extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
|
json_object *json_paths);
|
||||||
int, safi_t, json_object *);
|
extern void route_vty_out_tag(struct vty *vty, struct prefix *p,
|
||||||
|
struct bgp_path_info *path, int display,
|
||||||
|
safi_t safi, json_object *json);
|
||||||
extern void route_vty_out_tmp(struct vty *vty, struct prefix *p,
|
extern void route_vty_out_tmp(struct vty *vty, struct prefix *p,
|
||||||
struct attr *attr, safi_t safi, bool use_json,
|
struct attr *attr, safi_t safi, bool use_json,
|
||||||
json_object *json_ar);
|
json_object *json_ar);
|
||||||
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
|
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *binfo, int display,
|
struct bgp_path_info *path, int display,
|
||||||
json_object *json);
|
json_object *json);
|
||||||
|
|
||||||
extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
|
extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
|
||||||
struct bgp_info *selected,
|
struct bgp_path_info *selected,
|
||||||
struct bgp_node *rn,
|
struct bgp_node *rn,
|
||||||
uint32_t addpath_tx_id);
|
uint32_t addpath_tx_id);
|
||||||
|
|
||||||
extern int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
|
extern int subgroup_announce_check(struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *pi,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
struct prefix *p, struct attr *attr);
|
struct prefix *p, struct attr *attr);
|
||||||
|
|
||||||
@ -458,28 +472,30 @@ extern void bgp_process_queues_drain_immediate(void);
|
|||||||
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
|
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
|
||||||
safi_t safi, struct prefix *p,
|
safi_t safi, struct prefix *p,
|
||||||
struct prefix_rd *prd);
|
struct prefix_rd *prd);
|
||||||
extern struct bgp_info *bgp_info_new(void);
|
extern struct bgp_path_info *bgp_path_info_new(void);
|
||||||
extern void bgp_info_restore(struct bgp_node *, struct bgp_info *);
|
extern void bgp_path_info_restore(struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *path);
|
||||||
|
|
||||||
extern int bgp_info_cmp_compatible(struct bgp *, struct bgp_info *,
|
extern int bgp_path_info_cmp_compatible(struct bgp *bgp,
|
||||||
struct bgp_info *, char *pfx_buf, afi_t afi,
|
struct bgp_path_info *new,
|
||||||
safi_t safi);
|
struct bgp_path_info *exist,
|
||||||
|
char *pfx_buf, afi_t afi, safi_t safi);
|
||||||
extern void bgp_attr_add_gshut_community(struct attr *attr);
|
extern void bgp_attr_add_gshut_community(struct attr *attr);
|
||||||
|
|
||||||
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
|
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
|
||||||
struct bgp_maxpaths_cfg *mpath_cfg,
|
struct bgp_maxpaths_cfg *mpath_cfg,
|
||||||
struct bgp_info_pair *result, afi_t afi,
|
struct bgp_path_info_pair *result, afi_t afi,
|
||||||
safi_t safi);
|
safi_t safi);
|
||||||
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
|
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
|
||||||
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
|
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
|
||||||
struct bgp_info *selected);
|
struct bgp_path_info *selected);
|
||||||
|
|
||||||
extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
|
extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
|
||||||
struct bgp_node *rn,
|
struct bgp_node *rn,
|
||||||
struct prefix_rd *prd, afi_t afi,
|
struct prefix_rd *prd, afi_t afi,
|
||||||
safi_t safi, json_object *json);
|
safi_t safi, json_object *json);
|
||||||
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
|
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
|
||||||
struct prefix *p, struct bgp_info *binfo,
|
struct prefix *p, struct bgp_path_info *path,
|
||||||
afi_t afi, safi_t safi,
|
afi_t afi, safi_t safi,
|
||||||
json_object *json_paths);
|
json_object *json_paths);
|
||||||
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
|
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -217,12 +217,12 @@ static route_map_result_t route_match(void *rule, const struct prefix *prefix,
|
|||||||
route_map_object_t type, void *object)
|
route_map_object_t type, void *object)
|
||||||
{
|
{
|
||||||
int *rpki_status = rule;
|
int *rpki_status = rule;
|
||||||
struct bgp_info *bgp_info;
|
struct bgp_path_info *path;
|
||||||
|
|
||||||
if (type == RMAP_BGP) {
|
if (type == RMAP_BGP) {
|
||||||
bgp_info = object;
|
path = object;
|
||||||
|
|
||||||
if (rpki_validate_prefix(bgp_info->peer, bgp_info->attr, prefix)
|
if (rpki_validate_prefix(path->peer, path->attr, prefix)
|
||||||
== *rpki_status) {
|
== *rpki_status) {
|
||||||
return RMAP_MATCH;
|
return RMAP_MATCH;
|
||||||
}
|
}
|
||||||
@ -418,13 +418,13 @@ static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
|
|||||||
|
|
||||||
for (ain = bgp_node->adj_in; ain; ain = ain->next) {
|
for (ain = bgp_node->adj_in; ain; ain = ain->next) {
|
||||||
int ret;
|
int ret;
|
||||||
struct bgp_info *bgp_info = bgp_node->info;
|
struct bgp_path_info *path = bgp_node->info;
|
||||||
mpls_label_t *label = NULL;
|
mpls_label_t *label = NULL;
|
||||||
uint32_t num_labels = 0;
|
uint32_t num_labels = 0;
|
||||||
|
|
||||||
if (bgp_info && bgp_info->extra) {
|
if (path && path->extra) {
|
||||||
label = bgp_info->extra->label;
|
label = path->extra->label;
|
||||||
num_labels = bgp_info->extra->num_labels;
|
num_labels = path->extra->num_labels;
|
||||||
}
|
}
|
||||||
ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
|
ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
|
||||||
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
||||||
|
@ -674,14 +674,15 @@ static uint8_t *bgpRcvdPathAttrTable(struct variable *v, oid name[],
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
||||||
size_t *length, struct bgp *bgp,
|
size_t *length, struct bgp *bgp,
|
||||||
struct prefix_ipv4 *addr, int exact)
|
struct prefix_ipv4 *addr,
|
||||||
|
int exact)
|
||||||
{
|
{
|
||||||
oid *offset;
|
oid *offset;
|
||||||
int offsetlen;
|
int offsetlen;
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
struct bgp_info *min;
|
struct bgp_path_info *min;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
union sockunion su;
|
union sockunion su;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -714,9 +715,9 @@ static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
|||||||
if (rn) {
|
if (rn) {
|
||||||
bgp_unlock_node(rn);
|
bgp_unlock_node(rn);
|
||||||
|
|
||||||
for (binfo = rn->info; binfo; binfo = binfo->next)
|
for (path = rn->info; path; path = path->next)
|
||||||
if (sockunion_same(&binfo->peer->su, &su))
|
if (sockunion_same(&path->peer->su, &su))
|
||||||
return binfo;
|
return path;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = name + v->namelen;
|
offset = name + v->namelen;
|
||||||
@ -761,22 +762,22 @@ static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
|||||||
do {
|
do {
|
||||||
min = NULL;
|
min = NULL;
|
||||||
|
|
||||||
for (binfo = rn->info; binfo; binfo = binfo->next) {
|
for (path = rn->info; path; path = path->next) {
|
||||||
if (binfo->peer->su.sin.sin_family == AF_INET
|
if (path->peer->su.sin.sin_family == AF_INET
|
||||||
&& ntohl(paddr.s_addr)
|
&& ntohl(paddr.s_addr)
|
||||||
< ntohl(binfo->peer->su.sin
|
< ntohl(path->peer->su.sin
|
||||||
.sin_addr
|
.sin_addr
|
||||||
.s_addr)) {
|
.s_addr)) {
|
||||||
if (min) {
|
if (min) {
|
||||||
if (ntohl(binfo->peer->su.sin
|
if (ntohl(path->peer->su.sin
|
||||||
.sin_addr
|
.sin_addr
|
||||||
.s_addr)
|
.s_addr)
|
||||||
< ntohl(min->peer->su.sin
|
< ntohl(min->peer->su.sin
|
||||||
.sin_addr
|
.sin_addr
|
||||||
.s_addr))
|
.s_addr))
|
||||||
min = binfo;
|
min = path;
|
||||||
} else
|
} else
|
||||||
min = binfo;
|
min = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +813,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
WriteMethod **write_method)
|
WriteMethod **write_method)
|
||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
struct prefix_ipv4 addr;
|
struct prefix_ipv4 addr;
|
||||||
|
|
||||||
bgp = bgp_get_default();
|
bgp = bgp_get_default();
|
||||||
@ -824,13 +825,13 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
return NULL;
|
return NULL;
|
||||||
memset(&addr, 0, sizeof(struct prefix_ipv4));
|
memset(&addr, 0, sizeof(struct prefix_ipv4));
|
||||||
|
|
||||||
binfo = bgp4PathAttrLookup(v, name, length, bgp, &addr, exact);
|
path = bgp4PathAttrLookup(v, name, length, bgp, &addr, exact);
|
||||||
if (!binfo)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch (v->magic) {
|
switch (v->magic) {
|
||||||
case BGP4PATHATTRPEER: /* 1 */
|
case BGP4PATHATTRPEER: /* 1 */
|
||||||
return SNMP_IPADDRESS(binfo->peer->su.sin.sin_addr);
|
return SNMP_IPADDRESS(path->peer->su.sin.sin_addr);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
|
case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
|
||||||
return SNMP_INTEGER(addr.prefixlen);
|
return SNMP_INTEGER(addr.prefixlen);
|
||||||
@ -839,28 +840,28 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
return SNMP_IPADDRESS(addr.prefix);
|
return SNMP_IPADDRESS(addr.prefix);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRORIGIN: /* 4 */
|
case BGP4PATHATTRORIGIN: /* 4 */
|
||||||
return SNMP_INTEGER(binfo->attr->origin);
|
return SNMP_INTEGER(path->attr->origin);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRASPATHSEGMENT: /* 5 */
|
case BGP4PATHATTRASPATHSEGMENT: /* 5 */
|
||||||
return aspath_snmp_pathseg(binfo->attr->aspath, var_len);
|
return aspath_snmp_pathseg(path->attr->aspath, var_len);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRNEXTHOP: /* 6 */
|
case BGP4PATHATTRNEXTHOP: /* 6 */
|
||||||
return SNMP_IPADDRESS(binfo->attr->nexthop);
|
return SNMP_IPADDRESS(path->attr->nexthop);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRMULTIEXITDISC: /* 7 */
|
case BGP4PATHATTRMULTIEXITDISC: /* 7 */
|
||||||
return SNMP_INTEGER(binfo->attr->med);
|
return SNMP_INTEGER(path->attr->med);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRLOCALPREF: /* 8 */
|
case BGP4PATHATTRLOCALPREF: /* 8 */
|
||||||
return SNMP_INTEGER(binfo->attr->local_pref);
|
return SNMP_INTEGER(path->attr->local_pref);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
|
case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
|
||||||
return SNMP_INTEGER(1);
|
return SNMP_INTEGER(1);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRAGGREGATORAS: /* 10 */
|
case BGP4PATHATTRAGGREGATORAS: /* 10 */
|
||||||
return SNMP_INTEGER(binfo->attr->aggregator_as);
|
return SNMP_INTEGER(path->attr->aggregator_as);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
|
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
|
||||||
return SNMP_IPADDRESS(binfo->attr->aggregator_addr);
|
return SNMP_IPADDRESS(path->attr->aggregator_addr);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
|
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
|
||||||
return SNMP_INTEGER(-1);
|
return SNMP_INTEGER(-1);
|
||||||
@ -868,7 +869,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
case BGP4PATHATTRBEST: /* 13 */
|
case BGP4PATHATTRBEST: /* 13 */
|
||||||
#define BGP4_PathAttrBest_false 1
|
#define BGP4_PathAttrBest_false 1
|
||||||
#define BGP4_PathAttrBest_true 2
|
#define BGP4_PathAttrBest_true 2
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
|
if (CHECK_FLAG(path->flags, BGP_INFO_SELECTED))
|
||||||
return SNMP_INTEGER(BGP4_PathAttrBest_true);
|
return SNMP_INTEGER(BGP4_PathAttrBest_true);
|
||||||
else
|
else
|
||||||
return SNMP_INTEGER(BGP4_PathAttrBest_false);
|
return SNMP_INTEGER(BGP4_PathAttrBest_false);
|
||||||
|
@ -104,7 +104,7 @@ struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||||||
route_table_set_info(rt->route_table, rt);
|
route_table_set_info(rt->route_table, rt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pointer to bgp instance allows working back from bgp_info to bgp
|
* pointer to bgp instance allows working back from bgp_path_info to bgp
|
||||||
*/
|
*/
|
||||||
rt->bgp = bgp;
|
rt->bgp = bgp;
|
||||||
|
|
||||||
|
@ -1906,7 +1906,7 @@ int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
* configured addpath-tx knob
|
* configured addpath-tx knob
|
||||||
*/
|
*/
|
||||||
int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
struct bgp_info *ri)
|
struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
||||||
PEER_FLAG_ADDPATH_TX_ALL_PATHS))
|
PEER_FLAG_ADDPATH_TX_ALL_PATHS))
|
||||||
@ -1914,7 +1914,7 @@ int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
|
|
||||||
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
||||||
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)
|
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)
|
||||||
&& CHECK_FLAG(ri->flags, BGP_INFO_DMED_SELECTED))
|
&& CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -293,7 +293,7 @@ typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
|
|||||||
struct updwalk_context {
|
struct updwalk_context {
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint64_t updgrp_id;
|
uint64_t updgrp_id;
|
||||||
uint64_t subgrp_id;
|
uint64_t subgrp_id;
|
||||||
bgp_policy_type_e policy_type;
|
bgp_policy_type_e policy_type;
|
||||||
@ -442,7 +442,7 @@ extern void subgroup_announce_all(struct update_subgroup *subgrp);
|
|||||||
extern void subgroup_default_originate(struct update_subgroup *subgrp,
|
extern void subgroup_default_originate(struct update_subgroup *subgrp,
|
||||||
int withdraw);
|
int withdraw);
|
||||||
extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct bgp_node *rn, struct bgp_info *ri);
|
struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern void subgroup_clear_table(struct update_subgroup *subgrp);
|
extern void subgroup_clear_table(struct update_subgroup *subgrp);
|
||||||
extern void update_group_announce(struct bgp *bgp);
|
extern void update_group_announce(struct bgp *bgp);
|
||||||
extern void update_group_announce_rrclients(struct bgp *bgp);
|
extern void update_group_announce_rrclients(struct bgp *bgp);
|
||||||
@ -455,7 +455,8 @@ extern void bgp_adj_out_remove_subgroup(struct bgp_node *rn,
|
|||||||
struct update_subgroup *subgrp);
|
struct update_subgroup *subgrp);
|
||||||
extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
struct attr *attr, struct bgp_info *binfo);
|
struct attr *attr,
|
||||||
|
struct bgp_path_info *path);
|
||||||
extern void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
|
extern void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
char withdraw, uint32_t addpath_tx_id);
|
char withdraw, uint32_t addpath_tx_id);
|
||||||
@ -469,7 +470,7 @@ extern int update_group_clear_update_dbg(struct update_group *updgrp,
|
|||||||
extern void update_bgp_group_free(struct bgp *bgp);
|
extern void update_bgp_group_free(struct bgp *bgp);
|
||||||
extern int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
|
extern int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
|
||||||
extern int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
extern int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
struct bgp_info *ri);
|
struct bgp_path_info *pi);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inline functions
|
* Inline functions
|
||||||
|
@ -101,7 +101,7 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
{
|
{
|
||||||
struct updwalk_context *ctx = arg;
|
struct updwalk_context *ctx = arg;
|
||||||
struct update_subgroup *subgrp;
|
struct update_subgroup *subgrp;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
@ -140,15 +140,15 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
adj_next = adj->next;
|
adj_next = adj->next;
|
||||||
|
|
||||||
if (adj->subgroup == subgrp) {
|
if (adj->subgroup == subgrp) {
|
||||||
for (ri = ctx->rn->info; ri;
|
for (pi = ctx->rn->info; pi;
|
||||||
ri = ri->next) {
|
pi = pi->next) {
|
||||||
if (ri->addpath_tx_id
|
if (pi->addpath_tx_id
|
||||||
== adj->addpath_tx_id) {
|
== adj->addpath_tx_id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ri) {
|
if (!pi) {
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, NULL,
|
subgrp, NULL,
|
||||||
ctx->rn,
|
ctx->rn,
|
||||||
@ -157,32 +157,32 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ri = ctx->rn->info; ri; ri = ri->next) {
|
for (pi = ctx->rn->info; pi; pi = pi->next) {
|
||||||
/* Skip the bestpath for now */
|
/* Skip the bestpath for now */
|
||||||
if (ri == ctx->ri)
|
if (pi == ctx->pi)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, ri, ctx->rn,
|
subgrp, pi, ctx->rn,
|
||||||
ri->addpath_tx_id);
|
pi->addpath_tx_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the bestpath last so the "show [ip]
|
/* Process the bestpath last so the "show [ip]
|
||||||
* bgp neighbor x.x.x.x advertised"
|
* bgp neighbor x.x.x.x advertised"
|
||||||
* output shows the attributes from the bestpath
|
* output shows the attributes from the bestpath
|
||||||
*/
|
*/
|
||||||
if (ctx->ri)
|
if (ctx->pi)
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, ctx->ri, ctx->rn,
|
subgrp, ctx->pi, ctx->rn,
|
||||||
ctx->ri->addpath_tx_id);
|
ctx->pi->addpath_tx_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* An update-group that does not use addpath */
|
/* An update-group that does not use addpath */
|
||||||
else {
|
else {
|
||||||
if (ctx->ri) {
|
if (ctx->pi) {
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, ctx->ri, ctx->rn,
|
subgrp, ctx->pi, ctx->rn,
|
||||||
ctx->ri->addpath_tx_id);
|
ctx->pi->addpath_tx_id);
|
||||||
} else {
|
} else {
|
||||||
/* Find the addpath_tx_id of the path we
|
/* Find the addpath_tx_id of the path we
|
||||||
* had advertised and
|
* had advertised and
|
||||||
@ -429,7 +429,7 @@ bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
|
|||||||
|
|
||||||
void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp, struct attr *attr,
|
struct update_subgroup *subgrp, struct attr *attr,
|
||||||
struct bgp_info *binfo)
|
struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_adj_out *adj = NULL;
|
struct bgp_adj_out *adj = NULL;
|
||||||
struct bgp_advertise *adv;
|
struct bgp_advertise *adv;
|
||||||
@ -438,10 +438,10 @@ void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Look for adjacency information. */
|
/* Look for adjacency information. */
|
||||||
adj = adj_lookup(rn, subgrp, binfo->addpath_tx_id);
|
adj = adj_lookup(rn, subgrp, path->addpath_tx_id);
|
||||||
|
|
||||||
if (!adj) {
|
if (!adj) {
|
||||||
adj = bgp_adj_out_alloc(subgrp, rn, binfo->addpath_tx_id);
|
adj = bgp_adj_out_alloc(subgrp, rn, path->addpath_tx_id);
|
||||||
if (!adj)
|
if (!adj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -452,8 +452,9 @@ void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
|||||||
|
|
||||||
adv = adj->adv;
|
adv = adj->adv;
|
||||||
adv->rn = rn;
|
adv->rn = rn;
|
||||||
assert(adv->binfo == NULL);
|
assert(adv->pathi == NULL);
|
||||||
adv->binfo = bgp_info_lock(binfo); /* bgp_info adj_out reference */
|
/* bgp_path_info adj_out reference */
|
||||||
|
adv->pathi = bgp_path_info_lock(path);
|
||||||
|
|
||||||
if (attr)
|
if (attr)
|
||||||
adv->baa = bgp_advertise_intern(subgrp->hash, attr);
|
adv->baa = bgp_advertise_intern(subgrp->hash, attr);
|
||||||
@ -568,7 +569,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
|
|||||||
struct bgp_table *table)
|
struct bgp_table *table)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -594,7 +595,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
|
|||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
|
|
||||||
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
|
if (CHECK_FLAG(ri->flags, BGP_PATH_SELECTED)
|
||||||
|| (addpath_capable
|
|| (addpath_capable
|
||||||
&& bgp_addpath_tx_path(peer, afi, safi, ri))) {
|
&& bgp_addpath_tx_path(peer, afi, safi, ri))) {
|
||||||
if (subgroup_announce_check(rn, ri, subgrp,
|
if (subgroup_announce_check(rn, ri, subgrp,
|
||||||
@ -663,11 +664,11 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
|||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct bgp_info *info, init_info, tmp_info;
|
struct bgp_path_info *info, init_info, tmp_info;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct peer *from;
|
struct peer *from;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
int ret = RMAP_DENYMATCH;
|
int ret = RMAP_DENYMATCH;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -830,10 +831,10 @@ void subgroup_announce_all(struct update_subgroup *subgrp)
|
|||||||
* input route.
|
* input route.
|
||||||
*/
|
*/
|
||||||
void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct bgp_node *rn, struct bgp_info *ri)
|
struct bgp_node *rn, struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
struct updwalk_context ctx;
|
struct updwalk_context ctx;
|
||||||
ctx.ri = ri;
|
ctx.pi = pi;
|
||||||
ctx.rn = rn;
|
ctx.rn = rn;
|
||||||
update_group_af_walk(bgp, afi, safi, group_announce_route_walkcb, &ctx);
|
update_group_af_walk(bgp, afi, safi, group_announce_route_walkcb, &ctx);
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
struct bgp_adj_out *adj;
|
struct bgp_adj_out *adj;
|
||||||
struct bgp_advertise *adv;
|
struct bgp_advertise *adv;
|
||||||
struct bgp_node *rn = NULL;
|
struct bgp_node *rn = NULL;
|
||||||
struct bgp_info *binfo = NULL;
|
struct bgp_path_info *path = NULL;
|
||||||
bgp_size_t total_attr_len = 0;
|
bgp_size_t total_attr_len = 0;
|
||||||
unsigned long attrlen_pos = 0;
|
unsigned long attrlen_pos = 0;
|
||||||
size_t mpattrlen_pos = 0;
|
size_t mpattrlen_pos = 0;
|
||||||
@ -731,7 +731,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
rn = adv->rn;
|
rn = adv->rn;
|
||||||
adj = adv->adj;
|
adj = adv->adj;
|
||||||
addpath_tx_id = adj->addpath_tx_id;
|
addpath_tx_id = adj->addpath_tx_id;
|
||||||
binfo = adv->binfo;
|
path = adv->pathi;
|
||||||
|
|
||||||
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
||||||
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||||
@ -747,8 +747,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
if (stream_empty(s)) {
|
if (stream_empty(s)) {
|
||||||
struct peer *from = NULL;
|
struct peer *from = NULL;
|
||||||
|
|
||||||
if (binfo)
|
if (path)
|
||||||
from = binfo->peer;
|
from = path->peer;
|
||||||
|
|
||||||
/* 1: Write the BGP message header - 16 bytes marker, 2
|
/* 1: Write the BGP message header - 16 bytes marker, 2
|
||||||
* bytes length,
|
* bytes length,
|
||||||
@ -821,13 +821,13 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
prd = (struct prefix_rd *)&rn->prn->p;
|
prd = (struct prefix_rd *)&rn->prn->p;
|
||||||
|
|
||||||
if (safi == SAFI_LABELED_UNICAST) {
|
if (safi == SAFI_LABELED_UNICAST) {
|
||||||
label = bgp_adv_label(rn, binfo, peer, afi,
|
label = bgp_adv_label(rn, path, peer, afi,
|
||||||
safi);
|
safi);
|
||||||
label_pnt = &label;
|
label_pnt = &label;
|
||||||
num_labels = 1;
|
num_labels = 1;
|
||||||
} else if (binfo && binfo->extra) {
|
} else if (path && path->extra) {
|
||||||
label_pnt = &binfo->extra->label[0];
|
label_pnt = &path->extra->label[0];
|
||||||
num_labels = binfo->extra->num_labels;
|
num_labels = path->extra->num_labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream_empty(snlri))
|
if (stream_empty(snlri))
|
||||||
|
@ -7524,12 +7524,13 @@ DEFUN (show_bgp_memory,
|
|||||||
count = mtype_stats_alloc(MTYPE_BGP_ROUTE);
|
count = mtype_stats_alloc(MTYPE_BGP_ROUTE);
|
||||||
vty_out(vty, "%ld BGP routes, using %s of memory\n", count,
|
vty_out(vty, "%ld BGP routes, using %s of memory\n", count,
|
||||||
mtype_memstr(memstrbuf, sizeof(memstrbuf),
|
mtype_memstr(memstrbuf, sizeof(memstrbuf),
|
||||||
count * sizeof(struct bgp_info)));
|
count * sizeof(struct bgp_path_info)));
|
||||||
if ((count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA)))
|
if ((count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA)))
|
||||||
vty_out(vty, "%ld BGP route ancillaries, using %s of memory\n",
|
vty_out(vty, "%ld BGP route ancillaries, using %s of memory\n",
|
||||||
count,
|
count,
|
||||||
mtype_memstr(memstrbuf, sizeof(memstrbuf),
|
mtype_memstr(
|
||||||
count * sizeof(struct bgp_info_extra)));
|
memstrbuf, sizeof(memstrbuf),
|
||||||
|
count * sizeof(struct bgp_path_info_extra)));
|
||||||
|
|
||||||
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,
|
||||||
|
140
bgpd/bgp_zebra.c
140
bgpd/bgp_zebra.c
@ -925,41 +925,40 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
|
static struct in6_addr *
|
||||||
ifindex_t *ifindex)
|
bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *path, ifindex_t *ifindex)
|
||||||
{
|
{
|
||||||
struct in6_addr *nexthop = NULL;
|
struct in6_addr *nexthop = NULL;
|
||||||
|
|
||||||
/* Only global address nexthop exists. */
|
/* Only global address nexthop exists. */
|
||||||
if (info->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
|
if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
|
||||||
nexthop = &info->attr->mp_nexthop_global;
|
nexthop = &path->attr->mp_nexthop_global;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->attr->nh_ifindex;
|
*ifindex = path->attr->nh_ifindex;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If both global and link-local address present. */
|
/* If both global and link-local address present. */
|
||||||
if (info->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
||||||
/* Check if route-map is set to prefer global over link-local */
|
/* Check if route-map is set to prefer global over link-local */
|
||||||
if (info->attr->mp_nexthop_prefer_global) {
|
if (path->attr->mp_nexthop_prefer_global) {
|
||||||
nexthop = &info->attr->mp_nexthop_global;
|
nexthop = &path->attr->mp_nexthop_global;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->attr->nh_ifindex;
|
*ifindex = path->attr->nh_ifindex;
|
||||||
} else {
|
} else {
|
||||||
/* Workaround for Cisco's nexthop bug. */
|
/* Workaround for Cisco's nexthop bug. */
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(
|
if (IN6_IS_ADDR_UNSPECIFIED(
|
||||||
&info->attr->mp_nexthop_global)
|
&path->attr->mp_nexthop_global)
|
||||||
&& info->peer->su_remote->sa.sa_family
|
&& path->peer->su_remote->sa.sa_family
|
||||||
== AF_INET6) {
|
== AF_INET6) {
|
||||||
nexthop =
|
nexthop =
|
||||||
&info->peer->su_remote->sin6.sin6_addr;
|
&path->peer->su_remote->sin6.sin6_addr;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->peer->nexthop.ifp
|
*ifindex = path->peer->nexthop.ifp
|
||||||
->ifindex;
|
->ifindex;
|
||||||
} else {
|
} else {
|
||||||
nexthop = &info->attr->mp_nexthop_local;
|
nexthop = &path->attr->mp_nexthop_local;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->attr->nh_lla_ifindex;
|
*ifindex = path->attr->nh_lla_ifindex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -968,12 +967,12 @@ static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
||||||
struct bgp_info *info)
|
struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
ret = route_map_apply(map, p, RMAP_BGP, info);
|
ret = route_map_apply(map, p, RMAP_BGP, path);
|
||||||
bgp_attr_flush(info->attr);
|
bgp_attr_flush(path->attr);
|
||||||
|
|
||||||
if (ret != RMAP_DENYMATCH)
|
if (ret != RMAP_DENYMATCH)
|
||||||
return 1;
|
return 1;
|
||||||
@ -986,7 +985,7 @@ static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
|||||||
inet_ntop(AF_INET, &p->u.prefix4, buf[0],
|
inet_ntop(AF_INET, &p->u.prefix4, buf[0],
|
||||||
sizeof(buf[0])),
|
sizeof(buf[0])),
|
||||||
p->prefixlen,
|
p->prefixlen,
|
||||||
inet_ntop(AF_INET, &info->attr->nexthop, buf[1],
|
inet_ntop(AF_INET, &path->attr->nexthop, buf[1],
|
||||||
sizeof(buf[1])));
|
sizeof(buf[1])));
|
||||||
}
|
}
|
||||||
if (p->family == AF_INET6) {
|
if (p->family == AF_INET6) {
|
||||||
@ -994,7 +993,7 @@ static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
|||||||
ifindex_t ifindex;
|
ifindex_t ifindex;
|
||||||
struct in6_addr *nexthop;
|
struct in6_addr *nexthop;
|
||||||
|
|
||||||
nexthop = bgp_info_to_ipv6_nexthop(info, &ifindex);
|
nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"Zebra rmap deny: IPv6 route %s/%d nexthop %s",
|
"Zebra rmap deny: IPv6 route %s/%d nexthop %s",
|
||||||
inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
|
inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
|
||||||
@ -1121,17 +1120,15 @@ static int update_ipv4nh_for_route_install(int nh_othervrf,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_ipv6nh_for_route_install(int nh_othervrf,
|
static int
|
||||||
struct in6_addr *nexthop,
|
update_ipv6nh_for_route_install(int nh_othervrf, struct in6_addr *nexthop,
|
||||||
ifindex_t ifindex,
|
ifindex_t ifindex, struct bgp_path_info *pi,
|
||||||
struct bgp_info *ri,
|
struct bgp_path_info *best_pi, bool is_evpn,
|
||||||
struct bgp_info *best_ri,
|
|
||||||
bool is_evpn,
|
|
||||||
struct zapi_nexthop *api_nh)
|
struct zapi_nexthop *api_nh)
|
||||||
{
|
{
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
attr = ri->attr;
|
attr = pi->attr;
|
||||||
|
|
||||||
if (is_evpn)
|
if (is_evpn)
|
||||||
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
@ -1150,22 +1147,22 @@ static int update_ipv6nh_for_route_install(int nh_othervrf,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
|
||||||
if (ri == best_ri &&
|
if (pi == best_pi
|
||||||
attr->mp_nexthop_len
|
&& attr->mp_nexthop_len
|
||||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||||
if (ri->peer->nexthop.ifp)
|
if (pi->peer->nexthop.ifp)
|
||||||
ifindex = ri->peer->nexthop.ifp
|
ifindex =
|
||||||
->ifindex;
|
pi->peer->nexthop.ifp->ifindex;
|
||||||
if (!ifindex) {
|
if (!ifindex) {
|
||||||
if (ri->peer->conf_if)
|
if (pi->peer->conf_if)
|
||||||
ifindex = ri->peer->ifp->ifindex;
|
ifindex = pi->peer->ifp->ifindex;
|
||||||
else if (ri->peer->ifname)
|
else if (pi->peer->ifname)
|
||||||
ifindex = ifname2ifindex(
|
ifindex = ifname2ifindex(
|
||||||
ri->peer->ifname,
|
pi->peer->ifname,
|
||||||
ri->peer->bgp->vrf_id);
|
pi->peer->bgp->vrf_id);
|
||||||
else if (ri->peer->nexthop.ifp)
|
else if (pi->peer->nexthop.ifp)
|
||||||
ifindex = ri->peer->nexthop.ifp
|
ifindex =
|
||||||
->ifindex;
|
pi->peer->nexthop.ifp->ifindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifindex == 0)
|
if (ifindex == 0)
|
||||||
@ -1183,7 +1180,7 @@ static int update_ipv6nh_for_route_install(int nh_othervrf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||||
struct bgp_info *info, struct bgp *bgp, afi_t afi,
|
struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
|
||||||
safi_t safi)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
@ -1193,11 +1190,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
int has_valid_label = 0;
|
int has_valid_label = 0;
|
||||||
uint8_t distance;
|
uint8_t distance;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct bgp_info *mpinfo;
|
struct bgp_path_info *mpinfo;
|
||||||
uint32_t metric;
|
uint32_t metric;
|
||||||
struct attr local_attr;
|
struct attr local_attr;
|
||||||
struct bgp_info local_info;
|
struct bgp_path_info local_info;
|
||||||
struct bgp_info *mpinfo_cp = &local_info;
|
struct bgp_path_info *mpinfo_cp = &local_info;
|
||||||
route_tag_t tag;
|
route_tag_t tag;
|
||||||
mpls_label_t label;
|
mpls_label_t label;
|
||||||
int nh_othervrf = 0;
|
int nh_othervrf = 0;
|
||||||
@ -1242,7 +1239,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
|
|
||||||
/* Obtain peer from parent */
|
/* Obtain peer from parent */
|
||||||
if (info->extra && info->extra->parent)
|
if (info->extra && info->extra->parent)
|
||||||
peer = ((struct bgp_info *)(info->extra->parent))->peer;
|
peer = ((struct bgp_path_info *)(info->extra->parent))
|
||||||
|
->peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag = info->attr->tag;
|
tag = info->attr->tag;
|
||||||
@ -1266,7 +1264,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
|
|
||||||
/* Metric is currently based on the best-path only */
|
/* Metric is currently based on the best-path only */
|
||||||
metric = info->attr->med;
|
metric = info->attr->med;
|
||||||
for (mpinfo = info; mpinfo; mpinfo = bgp_info_mpath_next(mpinfo)) {
|
for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
|
||||||
if (valid_nh_count >= multipath_num)
|
if (valid_nh_count >= multipath_num)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1356,7 +1354,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
tag = mpinfo_cp->attr->tag;
|
tag = mpinfo_cp->attr->tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nexthop = bgp_info_to_ipv6_nexthop(mpinfo_cp,
|
nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
|
||||||
&ifindex);
|
&ifindex);
|
||||||
nh_updated = update_ipv6nh_for_route_install(
|
nh_updated = update_ipv6nh_for_route_install(
|
||||||
nh_othervrf, nexthop, ifindex,
|
nh_othervrf, nexthop, ifindex,
|
||||||
@ -1466,7 +1464,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
|
|
||||||
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
|
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
|
||||||
* know of this instance.
|
* know of this instance.
|
||||||
@ -1479,18 +1477,18 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (pi = rn->info; pi; pi = pi->next)
|
||||||
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
|
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
|
||||||
|
|
||||||
(ri->type == ZEBRA_ROUTE_BGP
|
(pi->type == ZEBRA_ROUTE_BGP
|
||||||
&& (ri->sub_type == BGP_ROUTE_NORMAL
|
&& (pi->sub_type == BGP_ROUTE_NORMAL
|
||||||
|| ri->sub_type == BGP_ROUTE_IMPORTED)))
|
|| pi->sub_type == BGP_ROUTE_IMPORTED)))
|
||||||
|
|
||||||
bgp_zebra_announce(rn, &rn->p, ri, bgp, afi,
|
bgp_zebra_announce(rn, &rn->p, pi, bgp, afi,
|
||||||
safi);
|
safi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
|
void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *info,
|
||||||
struct bgp *bgp, safi_t safi)
|
struct bgp *bgp, safi_t safi)
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
@ -1680,7 +1678,7 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
|
|||||||
afi_t afi, int type, uint32_t metric)
|
afi_t afi, int type, uint32_t metric)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
|
|
||||||
if (red->redist_metric_flag && red->redist_metric == metric)
|
if (red->redist_metric_flag && red->redist_metric == metric)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1690,21 +1688,21 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
|
|||||||
|
|
||||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE
|
if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||||
&& ri->type == type
|
&& pi->type == type
|
||||||
&& ri->instance == red->instance) {
|
&& pi->instance == red->instance) {
|
||||||
struct attr *old_attr;
|
struct attr *old_attr;
|
||||||
struct attr new_attr;
|
struct attr new_attr;
|
||||||
|
|
||||||
bgp_attr_dup(&new_attr, ri->attr);
|
bgp_attr_dup(&new_attr, pi->attr);
|
||||||
new_attr.med = red->redist_metric;
|
new_attr.med = red->redist_metric;
|
||||||
old_attr = ri->attr;
|
old_attr = pi->attr;
|
||||||
ri->attr = bgp_attr_intern(&new_attr);
|
pi->attr = bgp_attr_intern(&new_attr);
|
||||||
bgp_attr_unintern(&old_attr);
|
bgp_attr_unintern(&old_attr);
|
||||||
|
|
||||||
bgp_info_set_flag(rn, ri,
|
bgp_path_info_set_flag(rn, pi,
|
||||||
BGP_INFO_ATTR_CHANGED);
|
BGP_PATH_ATTR_CHANGED);
|
||||||
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2081,17 +2079,17 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
|
|||||||
break;
|
break;
|
||||||
case ZAPI_IPSET_ENTRY_INSTALLED:
|
case ZAPI_IPSET_ENTRY_INSTALLED:
|
||||||
{
|
{
|
||||||
struct bgp_info *bgp_info;
|
struct bgp_path_info *path;
|
||||||
struct bgp_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
bgp_pbime->installed = true;
|
bgp_pbime->installed = true;
|
||||||
bgp_pbime->install_in_progress = false;
|
bgp_pbime->install_in_progress = false;
|
||||||
if (BGP_DEBUG(zebra, ZEBRA))
|
if (BGP_DEBUG(zebra, ZEBRA))
|
||||||
zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
|
zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
|
||||||
__PRETTY_FUNCTION__);
|
__PRETTY_FUNCTION__);
|
||||||
/* link bgp_info to bpme */
|
/* link bgp_path_info to bpme */
|
||||||
bgp_info = (struct bgp_info *)bgp_pbime->bgp_info;
|
path = (struct bgp_path_info *)bgp_pbime->path;
|
||||||
extra = bgp_info_extra_get(bgp_info);
|
extra = bgp_path_info_extra_get(path);
|
||||||
if (extra->bgp_fs_pbr == NULL)
|
if (extra->bgp_fs_pbr == NULL)
|
||||||
extra->bgp_fs_pbr = list_new();
|
extra->bgp_fs_pbr = list_new();
|
||||||
listnode_add(extra->bgp_fs_pbr, bgp_pbime);
|
listnode_add(extra->bgp_fs_pbr, bgp_pbime);
|
||||||
|
@ -36,11 +36,12 @@ extern void bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t,
|
|||||||
safi_t);
|
safi_t);
|
||||||
extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
||||||
safi_t);
|
safi_t);
|
||||||
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
|
extern void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||||
struct bgp_info *, struct bgp *, afi_t, safi_t);
|
struct bgp_path_info *path, struct bgp *bgp,
|
||||||
|
afi_t afi, safi_t safi);
|
||||||
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
|
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
|
||||||
extern void bgp_zebra_withdraw(struct prefix *, struct bgp_info *,
|
extern void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *path,
|
||||||
struct bgp *, safi_t);
|
struct bgp *bgp, safi_t safi);
|
||||||
|
|
||||||
extern void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer);
|
extern void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer);
|
||||||
extern void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer);
|
extern void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer);
|
||||||
|
@ -361,7 +361,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
{
|
{
|
||||||
afi_t afi; /* of the VN address */
|
afi_t afi; /* of the VN address */
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
char buf[PREFIX_STRLEN];
|
char buf[PREFIX_STRLEN];
|
||||||
char buf2[RD_ADDRSTRLEN];
|
char buf2[RD_ADDRSTRLEN];
|
||||||
struct prefix_rd prd0;
|
struct prefix_rd prd0;
|
||||||
@ -384,21 +384,22 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
__func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
|
__func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
|
||||||
afi, safi, bn, (bn ? bn->info : NULL));
|
afi, safi, bn, (bn ? bn->info : NULL));
|
||||||
|
|
||||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
"%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
|
"%s: trying bpi=%p, bpi->peer=%p, bpi->type=%d, bpi->sub_type=%d, bpi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
|
||||||
__func__, bi, bi->peer, bi->type, bi->sub_type,
|
__func__, bpi, bpi->peer, bpi->type, bpi->sub_type,
|
||||||
(bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL),
|
(bpi->extra ? bpi->extra->vnc.export.rfapi_handle
|
||||||
((bi->attr
|
: NULL),
|
||||||
&& CHECK_FLAG(bi->attr->flag,
|
((bpi->attr
|
||||||
|
&& CHECK_FLAG(bpi->attr->flag,
|
||||||
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
|
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
|
||||||
? bi->attr->local_pref
|
? bpi->attr->local_pref
|
||||||
: 0));
|
: 0));
|
||||||
|
|
||||||
if (bi->peer == peer && bi->type == type
|
if (bpi->peer == peer && bpi->type == type
|
||||||
&& bi->sub_type == sub_type && bi->extra
|
&& bpi->sub_type == sub_type && bpi->extra
|
||||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose("%s: matched it", __func__);
|
vnc_zlog_debug_verbose("%s: matched it", __func__);
|
||||||
|
|
||||||
@ -412,8 +413,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
* route. Leave the route itself in place.
|
* route. Leave the route itself in place.
|
||||||
* TBD add return code reporting of success/failure
|
* TBD add return code reporting of success/failure
|
||||||
*/
|
*/
|
||||||
if (!bi || !bi->extra
|
if (!bpi || !bpi->extra
|
||||||
|| !bi->extra->vnc.export.local_nexthops) {
|
|| !bpi->extra->vnc.export.local_nexthops) {
|
||||||
/*
|
/*
|
||||||
* no local nexthops
|
* no local nexthops
|
||||||
*/
|
*/
|
||||||
@ -429,7 +430,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct rfapi_nexthop *pLnh = NULL;
|
struct rfapi_nexthop *pLnh = NULL;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(bi->extra->vnc.export.local_nexthops,
|
for (ALL_LIST_ELEMENTS_RO(bpi->extra->vnc.export.local_nexthops,
|
||||||
node, pLnh)) {
|
node, pLnh)) {
|
||||||
|
|
||||||
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
||||||
@ -438,7 +439,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pLnh) {
|
if (pLnh) {
|
||||||
listnode_delete(bi->extra->vnc.export.local_nexthops,
|
listnode_delete(bpi->extra->vnc.export.local_nexthops,
|
||||||
pLnh);
|
pLnh);
|
||||||
|
|
||||||
/* silly rabbit, listnode_delete doesn't invoke
|
/* silly rabbit, listnode_delete doesn't invoke
|
||||||
@ -458,7 +459,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
*/
|
*/
|
||||||
rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
|
rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
prefix2str(p, buf, sizeof(buf));
|
prefix2str(p, buf, sizeof(buf));
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
"%s: Found route (safi=%d) to delete at prefix %s",
|
"%s: Found route (safi=%d) to delete at prefix %s",
|
||||||
@ -474,7 +475,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
table = (struct bgp_table *)(prn->info);
|
table = (struct bgp_table *)(prn->info);
|
||||||
|
|
||||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||||
bgp, prd, table, p, bi);
|
bgp, prd, table, p, bpi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(prn);
|
bgp_unlock_node(prn);
|
||||||
}
|
}
|
||||||
@ -482,13 +483,11 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
/*
|
/*
|
||||||
* Delete local_nexthops list
|
* Delete local_nexthops list
|
||||||
*/
|
*/
|
||||||
if (bi->extra && bi->extra->vnc.export.local_nexthops) {
|
if (bpi->extra && bpi->extra->vnc.export.local_nexthops)
|
||||||
list_delete(
|
list_delete(&bpi->extra->vnc.export.local_nexthops);
|
||||||
&bi->extra->vnc.export.local_nexthops);
|
|
||||||
}
|
|
||||||
|
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
} else {
|
} else {
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
@ -575,8 +574,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
afi_t afi; /* of the VN address */
|
afi_t afi; /* of the VN address */
|
||||||
struct bgp_info *new;
|
struct bgp_path_info *new;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
|
|
||||||
struct attr attr = {0};
|
struct attr attr = {0};
|
||||||
@ -946,29 +945,29 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
* ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
|
* ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
|
||||||
* aspath: POINTS TO interned/refcounted hashed block
|
* aspath: POINTS TO interned/refcounted hashed block
|
||||||
*/
|
*/
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
/* probably only need to check
|
/* probably only need to check
|
||||||
* bi->extra->vnc.export.rfapi_handle */
|
* bpi->extra->vnc.export.rfapi_handle */
|
||||||
if (bi->peer == rfd->peer && bi->type == type
|
if (bpi->peer == rfd->peer && bpi->type == type
|
||||||
&& bi->sub_type == sub_type && bi->extra
|
&& bpi->sub_type == sub_type && bpi->extra
|
||||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adding new local_nexthop, which does not by itself change
|
* Adding new local_nexthop, which does not by itself change
|
||||||
* what is advertised via BGP
|
* what is advertised via BGP
|
||||||
*/
|
*/
|
||||||
if (lnh) {
|
if (lnh) {
|
||||||
if (!bi->extra->vnc.export.local_nexthops) {
|
if (!bpi->extra->vnc.export.local_nexthops) {
|
||||||
/* TBD make arrangements to free when needed */
|
/* TBD make arrangements to free when needed */
|
||||||
bi->extra->vnc.export.local_nexthops =
|
bpi->extra->vnc.export.local_nexthops =
|
||||||
list_new();
|
list_new();
|
||||||
bi->extra->vnc.export.local_nexthops->del =
|
bpi->extra->vnc.export.local_nexthops->del =
|
||||||
rfapi_nexthop_free;
|
rfapi_nexthop_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,8 +978,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
struct rfapi_nexthop *pLnh = NULL;
|
struct rfapi_nexthop *pLnh = NULL;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(
|
for (ALL_LIST_ELEMENTS_RO(
|
||||||
bi->extra->vnc.export.local_nexthops, node,
|
bpi->extra->vnc.export.local_nexthops,
|
||||||
pLnh)) {
|
node, pLnh)) {
|
||||||
|
|
||||||
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
||||||
break;
|
break;
|
||||||
@ -993,13 +992,13 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
if (!pLnh) {
|
if (!pLnh) {
|
||||||
pLnh = rfapi_nexthop_new(lnh);
|
pLnh = rfapi_nexthop_new(lnh);
|
||||||
listnode_add(
|
listnode_add(
|
||||||
bi->extra->vnc.export.local_nexthops,
|
bpi->extra->vnc.export.local_nexthops,
|
||||||
pLnh);
|
pLnh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrhash_cmp(bi->attr, new_attr)
|
if (attrhash_cmp(bpi->attr, new_attr)
|
||||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
|
|
||||||
@ -1010,7 +1009,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
/* The attribute is changed. */
|
/* The attribute is changed. */
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
|
||||||
|
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
struct bgp_node *prn = NULL;
|
struct bgp_node *prn = NULL;
|
||||||
@ -1022,19 +1021,19 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
table = (struct bgp_table *)(prn->info);
|
table = (struct bgp_table *)(prn->info);
|
||||||
|
|
||||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||||
bgp, prd, table, p, bi);
|
bgp, prd, table, p, bpi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(prn);
|
bgp_unlock_node(prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rewrite BGP route information. */
|
/* Rewrite BGP route information. */
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||||
bgp_info_restore(bn, bi);
|
bgp_path_info_restore(bn, bpi);
|
||||||
else
|
else
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
bgp_attr_unintern(&bi->attr);
|
bgp_attr_unintern(&bpi->attr);
|
||||||
bi->attr = new_attr;
|
bpi->attr = new_attr;
|
||||||
bi->uptime = bgp_clock();
|
bpi->uptime = bgp_clock();
|
||||||
|
|
||||||
|
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
@ -1047,13 +1046,13 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
table = (struct bgp_table *)(prn->info);
|
table = (struct bgp_table *)(prn->info);
|
||||||
|
|
||||||
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||||
bgp, prd, table, p, bi);
|
bgp, prd, table, p, bpi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(prn);
|
bgp_unlock_node(prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process change. */
|
/* Process change. */
|
||||||
bgp_aggregate_increment(bgp, p, bi, afi, safi);
|
bgp_aggregate_increment(bgp, p, bpi, afi, safi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
|
|
||||||
@ -1066,16 +1065,16 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
new = bgp_info_new();
|
new = bgp_path_info_new();
|
||||||
new->type = type;
|
new->type = type;
|
||||||
new->sub_type = sub_type;
|
new->sub_type = sub_type;
|
||||||
new->peer = rfd->peer;
|
new->peer = rfd->peer;
|
||||||
SET_FLAG(new->flags, BGP_INFO_VALID);
|
SET_FLAG(new->flags, BGP_PATH_VALID);
|
||||||
new->attr = new_attr;
|
new->attr = new_attr;
|
||||||
new->uptime = bgp_clock();
|
new->uptime = bgp_clock();
|
||||||
|
|
||||||
/* save backref to rfapi handle */
|
/* save backref to rfapi handle */
|
||||||
assert(bgp_info_extra_get(new));
|
assert(bgp_path_info_extra_get(new));
|
||||||
new->extra->vnc.export.rfapi_handle = (void *)rfd;
|
new->extra->vnc.export.rfapi_handle = (void *)rfd;
|
||||||
encode_label(label_val, &new->extra->label[0]);
|
encode_label(label_val, &new->extra->label[0]);
|
||||||
|
|
||||||
@ -1087,7 +1086,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
}
|
}
|
||||||
|
|
||||||
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
||||||
bgp_info_add(bn, new);
|
bgp_path_info_add(bn, new);
|
||||||
|
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
struct bgp_node *prn = NULL;
|
struct bgp_node *prn = NULL;
|
||||||
@ -3690,7 +3689,7 @@ static void rfapi_print_exported(struct bgp *bgp)
|
|||||||
{
|
{
|
||||||
struct bgp_node *rdn;
|
struct bgp_node *rdn;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
if (!bgp)
|
if (!bgp)
|
||||||
return;
|
return;
|
||||||
@ -3705,8 +3704,8 @@ static void rfapi_print_exported(struct bgp *bgp)
|
|||||||
if (!rn->info)
|
if (!rn->info)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi((void *)2, bi); /* 2 => stderr */
|
rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3720,8 +3719,8 @@ static void rfapi_print_exported(struct bgp *bgp)
|
|||||||
if (!rn->info)
|
if (!rn->info)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi((void *)2, bi); /* 2 => stderr */
|
rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,16 @@ extern void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p,
|
|||||||
|
|
||||||
extern void rfapiProcessPeerDown(struct peer *peer);
|
extern void rfapiProcessPeerDown(struct peer *peer);
|
||||||
|
|
||||||
extern void vnc_zebra_announce(struct prefix *p, struct bgp_info *new_select,
|
extern void vnc_zebra_announce(struct prefix *p,
|
||||||
|
struct bgp_path_info *new_select,
|
||||||
struct bgp *bgp);
|
struct bgp *bgp);
|
||||||
|
|
||||||
extern void vnc_zebra_withdraw(struct prefix *p, struct bgp_info *old_select);
|
extern void vnc_zebra_withdraw(struct prefix *p,
|
||||||
|
struct bgp_path_info *old_select);
|
||||||
|
|
||||||
|
|
||||||
extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *bi, safi_t safi);
|
struct bgp_path_info *bpi, safi_t safi);
|
||||||
|
|
||||||
|
|
||||||
extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi);
|
extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@
|
|||||||
/*
|
/*
|
||||||
* These are per-rt-import-list
|
* These are per-rt-import-list
|
||||||
*
|
*
|
||||||
* routes are not segregated by RD - the RD is stored in bgp_info_extra
|
* routes are not segregated by RD - the RD is stored in bgp_path_info_extra
|
||||||
* and is needed to determine if two prefixes are the same.
|
* and is needed to determine if two prefixes are the same.
|
||||||
*/
|
*/
|
||||||
struct rfapi_import_table {
|
struct rfapi_import_table {
|
||||||
@ -51,18 +51,18 @@ struct rfapi_import_table {
|
|||||||
int imported_count[AFI_MAX];
|
int imported_count[AFI_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RFAPI_LOCAL_BI(bi) \
|
#define RFAPI_LOCAL_BI(bpi) \
|
||||||
(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP))
|
(((bpi)->type == ZEBRA_ROUTE_BGP) && ((bpi)->sub_type == BGP_ROUTE_RFP))
|
||||||
|
|
||||||
#define RFAPI_DIRECT_IMPORT_BI(bi) \
|
#define RFAPI_DIRECT_IMPORT_BI(bpi) \
|
||||||
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|
(((bpi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|
||||||
|| ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
|| ((bpi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
||||||
|
|
||||||
#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \
|
#define RFAPI_UPDATE_ITABLE_COUNT(bpi, itable, afi, cnt) \
|
||||||
if (RFAPI_LOCAL_BI(bi)) { \
|
if (RFAPI_LOCAL_BI(bpi)) { \
|
||||||
(itable)->local_count[(afi)] += (cnt); \
|
(itable)->local_count[(afi)] += (cnt); \
|
||||||
} else { \
|
} else { \
|
||||||
if (RFAPI_DIRECT_IMPORT_BI(bi)) \
|
if (RFAPI_DIRECT_IMPORT_BI(bpi)) \
|
||||||
(itable)->imported_count[(afi)] += (cnt); \
|
(itable)->imported_count[(afi)] += (cnt); \
|
||||||
else \
|
else \
|
||||||
(itable)->remote_count[(afi)] += (cnt); \
|
(itable)->remote_count[(afi)] += (cnt); \
|
||||||
@ -75,9 +75,9 @@ extern void rfapiDebugBacktrace(void);
|
|||||||
extern void rfapiCheckRouteCount(void);
|
extern void rfapiCheckRouteCount(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print BI in an Import Table
|
* Print BPI in an Import Table
|
||||||
*/
|
*/
|
||||||
extern void rfapiPrintBi(void *stream, struct bgp_info *bi);
|
extern void rfapiPrintBi(void *stream, struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern void rfapiShowImportTable(void *stream, const char *label,
|
extern void rfapiShowImportTable(void *stream, const char *label,
|
||||||
struct agg_table *rt, int isvpn);
|
struct agg_table *rt, int isvpn);
|
||||||
@ -94,7 +94,7 @@ extern void rfapiImportTableRefDelByIt(struct bgp *bgp,
|
|||||||
* Construct an rfapi nexthop list based on the routes attached to
|
* Construct an rfapi nexthop list based on the routes attached to
|
||||||
* the specified node.
|
* the specified node.
|
||||||
*
|
*
|
||||||
* If there are any routes that do NOT have BGP_INFO_REMOVED set,
|
* If there are any routes that do NOT have BGP_PATH_REMOVED set,
|
||||||
* return those only. If there are ONLY routes with BGP_INFO_REMOVED,
|
* return those only. If there are ONLY routes with BGP_INFO_REMOVED,
|
||||||
* then return those, and also include all the non-removed routes from the
|
* then return those, and also include all the non-removed routes from the
|
||||||
* next less-specific node (i.e., this node's parent) at the end.
|
* next less-specific node (i.e., this node's parent) at the end.
|
||||||
@ -128,7 +128,7 @@ extern int rfapiHasNonRemovedRoutes(struct agg_node *rn);
|
|||||||
|
|
||||||
extern int rfapiProcessDeferredClose(struct thread *t);
|
extern int rfapiProcessDeferredClose(struct thread *t);
|
||||||
|
|
||||||
extern int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p);
|
extern int rfapiGetUnAddrOfVpnBi(struct bgp_path_info *bpi, struct prefix *p);
|
||||||
|
|
||||||
extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p);
|
extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p);
|
||||||
|
|
||||||
@ -146,10 +146,10 @@ extern void rfapiBgpInfoFilteredImportVPN(
|
|||||||
struct prefix *p,
|
struct prefix *p,
|
||||||
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
|
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
|
||||||
afi_t afi, struct prefix_rd *prd,
|
afi_t afi, struct prefix_rd *prd,
|
||||||
struct attr *attr, /* part of bgp_info */
|
struct attr *attr, /* part of bgp_path_info */
|
||||||
uint8_t type, /* part of bgp_info */
|
uint8_t type, /* part of bgp_path_info */
|
||||||
uint8_t sub_type, /* part of bgp_info */
|
uint8_t sub_type, /* part of bgp_path_info */
|
||||||
uint32_t *label); /* part of bgp_info */
|
uint32_t *label); /* part of bgp_path_info */
|
||||||
|
|
||||||
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
|
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
|
||||||
struct agg_node *rn, struct rfapi_ip_prefix *rprefix,
|
struct agg_node *rn, struct rfapi_ip_prefix *rprefix,
|
||||||
|
@ -226,7 +226,7 @@ void rfapiMonitorExtraFlush(safi_t safi, struct agg_node *rn)
|
|||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
}
|
}
|
||||||
if (hie->u.vpn.idx_rd) {
|
if (hie->u.vpn.idx_rd) {
|
||||||
/* looping through bi->extra->vnc.import.rd is tbd */
|
/* looping through bpi->extra->vnc.import.rd is tbd */
|
||||||
while (!skiplist_delete_first(hie->u.vpn.idx_rd)) {
|
while (!skiplist_delete_first(hie->u.vpn.idx_rd)) {
|
||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
}
|
}
|
||||||
@ -346,16 +346,16 @@ struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
|
|||||||
for (rn = agg_node_match(rfd->import_table->imported_vpn[afi], p);
|
for (rn = agg_node_match(rfd->import_table->imported_vpn[afi], p);
|
||||||
rn;) {
|
rn;) {
|
||||||
|
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct prefix pfx_dummy;
|
struct prefix pfx_dummy;
|
||||||
|
|
||||||
/* TBD update this code to use new valid_interior_count */
|
/* TBD update this code to use new valid_interior_count */
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
/*
|
/*
|
||||||
* If there is a cached ENCAP UN address, it's a usable
|
* If there is a cached ENCAP UN address, it's a usable
|
||||||
* VPN route
|
* VPN route
|
||||||
*/
|
*/
|
||||||
if (bi->extra && bi->extra->vnc.import.un_family) {
|
if (bpi->extra && bpi->extra->vnc.import.un_family) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,11 +364,11 @@ struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
|
|||||||
* address,
|
* address,
|
||||||
* it's a usable VPN route.
|
* it's a usable VPN route.
|
||||||
*/
|
*/
|
||||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_dummy)) {
|
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_dummy)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bi)
|
if (bpi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
|
@ -45,7 +45,7 @@ struct rfapi_monitor_encap {
|
|||||||
struct rfapi_monitor_encap *next;
|
struct rfapi_monitor_encap *next;
|
||||||
struct rfapi_monitor_encap *prev;
|
struct rfapi_monitor_encap *prev;
|
||||||
struct agg_node *node; /* VPN node */
|
struct agg_node *node; /* VPN node */
|
||||||
struct bgp_info *bi; /* VPN bi */
|
struct bgp_path_info *bpi; /* VPN bpi */
|
||||||
struct agg_node *rn; /* parent node */
|
struct agg_node *rn; /* parent node */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ struct rfapi_it_extra {
|
|||||||
* Encap TLV */
|
* Encap TLV */
|
||||||
int valid_interior_count;
|
int valid_interior_count;
|
||||||
|
|
||||||
/* unicast exterior routes, key=bi,
|
/* unicast exterior routes, key=bpi,
|
||||||
* val=allocated prefix */
|
* val=allocated prefix */
|
||||||
struct skiplist *source;
|
struct skiplist *source;
|
||||||
} e;
|
} e;
|
||||||
|
@ -212,7 +212,7 @@ struct rfapi {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* when importing bgp-direct routes in resolve-nve mode,
|
* when importing bgp-direct routes in resolve-nve mode,
|
||||||
* this list maps unicast route nexthops to their bgp_infos
|
* this list maps unicast route nexthops to their bgp_path_infos
|
||||||
* in the unicast table
|
* in the unicast table
|
||||||
*/
|
*/
|
||||||
struct skiplist *resolve_nve_nexthop;
|
struct skiplist *resolve_nve_nexthop;
|
||||||
|
@ -616,18 +616,18 @@ void rfapiRibFree(struct rfapi_descriptor *rfd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copies struct bgp_info to struct rfapi_info, except for rk fields and un
|
* Copies struct bgp_path_info to struct rfapi_info, except for rk fields and un
|
||||||
*/
|
*/
|
||||||
static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri,
|
||||||
uint32_t lifetime)
|
uint32_t lifetime)
|
||||||
{
|
{
|
||||||
struct bgp_attr_encap_subtlv *pEncap;
|
struct bgp_attr_encap_subtlv *pEncap;
|
||||||
|
|
||||||
ri->cost = rfapiRfpCost(bi->attr);
|
ri->cost = rfapiRfpCost(bpi->attr);
|
||||||
ri->lifetime = lifetime;
|
ri->lifetime = lifetime;
|
||||||
|
|
||||||
/* This loop based on rfapiRouteInfo2NextHopEntry() */
|
/* This loop based on rfapiRouteInfo2NextHopEntry() */
|
||||||
for (pEncap = bi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) {
|
for (pEncap = bpi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) {
|
||||||
struct bgp_tea_options *hop;
|
struct bgp_tea_options *hop;
|
||||||
|
|
||||||
switch (pEncap->type) {
|
switch (pEncap->type) {
|
||||||
@ -665,13 +665,13 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rfapi_un_options_free(ri->un_options); /* maybe free old version */
|
rfapi_un_options_free(ri->un_options); /* maybe free old version */
|
||||||
ri->un_options = rfapi_encap_tlv_to_un_option(bi->attr);
|
ri->un_options = rfapi_encap_tlv_to_un_option(bpi->attr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VN options
|
* VN options
|
||||||
*/
|
*/
|
||||||
if (bi->extra
|
if (bpi->extra
|
||||||
&& decode_rd_type(bi->extra->vnc.import.rd.val)
|
&& decode_rd_type(bpi->extra->vnc.import.rd.val)
|
||||||
== RD_TYPE_VNC_ETH) {
|
== RD_TYPE_VNC_ETH) {
|
||||||
/* ethernet route */
|
/* ethernet route */
|
||||||
|
|
||||||
@ -683,21 +683,21 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
|
|
||||||
vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
|
vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
|
||||||
|
|
||||||
/* copy from RD already stored in bi, so we don't need it_node
|
/* copy from RD already stored in bpi, so we don't need it_node
|
||||||
*/
|
*/
|
||||||
memcpy(&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val + 2,
|
memcpy(&vo->v.l2addr.macaddr, bpi->extra->vnc.import.rd.val + 2,
|
||||||
ETH_ALEN);
|
ETH_ALEN);
|
||||||
|
|
||||||
(void)rfapiEcommunityGetLNI(bi->attr->ecommunity,
|
(void)rfapiEcommunityGetLNI(bpi->attr->ecommunity,
|
||||||
&vo->v.l2addr.logical_net_id);
|
&vo->v.l2addr.logical_net_id);
|
||||||
(void)rfapiEcommunityGetEthernetTag(bi->attr->ecommunity,
|
(void)rfapiEcommunityGetEthernetTag(bpi->attr->ecommunity,
|
||||||
&vo->v.l2addr.tag_id);
|
&vo->v.l2addr.tag_id);
|
||||||
|
|
||||||
/* local_nve_id comes from RD */
|
/* local_nve_id comes from RD */
|
||||||
vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1];
|
vo->v.l2addr.local_nve_id = bpi->extra->vnc.import.rd.val[1];
|
||||||
|
|
||||||
/* label comes from MP_REACH_NLRI label */
|
/* label comes from MP_REACH_NLRI label */
|
||||||
vo->v.l2addr.label = decode_label(&bi->extra->label[0]);
|
vo->v.l2addr.label = decode_label(&bpi->extra->label[0]);
|
||||||
|
|
||||||
rfapi_vn_options_free(
|
rfapi_vn_options_free(
|
||||||
ri->vn_options); /* maybe free old version */
|
ri->vn_options); /* maybe free old version */
|
||||||
@ -707,8 +707,8 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
/*
|
/*
|
||||||
* If there is an auxiliary IP address (L2 can have it), copy it
|
* If there is an auxiliary IP address (L2 can have it), copy it
|
||||||
*/
|
*/
|
||||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
ri->rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,7 +733,7 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
int rfapiRibPreloadBi(
|
int rfapiRibPreloadBi(
|
||||||
struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */
|
struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */
|
||||||
struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime,
|
struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime,
|
||||||
struct bgp_info *bi)
|
struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
struct rfapi_descriptor *rfd;
|
struct rfapi_descriptor *rfd;
|
||||||
struct skiplist *slRibPt = NULL;
|
struct skiplist *slRibPt = NULL;
|
||||||
@ -751,13 +751,13 @@ int rfapiRibPreloadBi(
|
|||||||
|
|
||||||
memset((void *)&rk, 0, sizeof(rk));
|
memset((void *)&rk, 0, sizeof(rk));
|
||||||
rk.vn = *pfx_vn;
|
rk.vn = *pfx_vn;
|
||||||
rk.rd = bi->extra->vnc.import.rd;
|
rk.rd = bpi->extra->vnc.import.rd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is an auxiliary IP address (L2 can have it), copy it
|
* If there is an auxiliary IP address (L2 can have it), copy it
|
||||||
*/
|
*/
|
||||||
if (bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -774,13 +774,13 @@ int rfapiRibPreloadBi(
|
|||||||
|
|
||||||
/* found: update contents of existing route in RIB */
|
/* found: update contents of existing route in RIB */
|
||||||
ori->un = *pfx_un;
|
ori->un = *pfx_un;
|
||||||
rfapiRibBi2Ri(bi, ori, lifetime);
|
rfapiRibBi2Ri(bpi, ori, lifetime);
|
||||||
} else {
|
} else {
|
||||||
/* not found: add new route to RIB */
|
/* not found: add new route to RIB */
|
||||||
ori = rfapi_info_new();
|
ori = rfapi_info_new();
|
||||||
ori->rk = rk;
|
ori->rk = rk;
|
||||||
ori->un = *pfx_un;
|
ori->un = *pfx_un;
|
||||||
rfapiRibBi2Ri(bi, ori, lifetime);
|
rfapiRibBi2Ri(bpi, ori, lifetime);
|
||||||
|
|
||||||
if (!slRibPt) {
|
if (!slRibPt) {
|
||||||
slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL);
|
slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL);
|
||||||
@ -1590,7 +1590,7 @@ void rfapiRibUpdatePendingNode(
|
|||||||
struct agg_node *it_node, uint32_t lifetime)
|
struct agg_node *it_node, uint32_t lifetime)
|
||||||
{
|
{
|
||||||
struct prefix *prefix;
|
struct prefix *prefix;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct agg_node *pn;
|
struct agg_node *pn;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
uint32_t queued_flag;
|
uint32_t queued_flag;
|
||||||
@ -1640,25 +1640,25 @@ void rfapiRibUpdatePendingNode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The BIs in the import table are already sorted by cost
|
* The BPIs in the import table are already sorted by cost
|
||||||
*/
|
*/
|
||||||
for (bi = it_node->info; bi; bi = bi->next) {
|
for (bpi = it_node->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
struct rfapi_info *ri;
|
struct rfapi_info *ri;
|
||||||
struct prefix pfx_nh;
|
struct prefix pfx_nh;
|
||||||
|
|
||||||
if (!bi->attr) {
|
if (!bpi->attr) {
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
/* TBD increment error stats counter */
|
/* TBD increment error stats counter */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!bi->extra) {
|
if (!bpi->extra) {
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
/* TBD increment error stats counter */
|
/* TBD increment error stats counter */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rfapiNexthop2Prefix(bi->attr, &pfx_nh);
|
rfapiNexthop2Prefix(bpi->attr, &pfx_nh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Omit route if nexthop is self
|
* Omit route if nexthop is self
|
||||||
@ -1675,15 +1675,15 @@ void rfapiRibUpdatePendingNode(
|
|||||||
|
|
||||||
ri = rfapi_info_new();
|
ri = rfapi_info_new();
|
||||||
ri->rk.vn = pfx_nh;
|
ri->rk.vn = pfx_nh;
|
||||||
ri->rk.rd = bi->extra->vnc.import.rd;
|
ri->rk.rd = bpi->extra->vnc.import.rd;
|
||||||
/*
|
/*
|
||||||
* If there is an auxiliary IP address (L2 can have it), copy it
|
* If there is an auxiliary IP address (L2 can have it), copy it
|
||||||
*/
|
*/
|
||||||
if (bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
ri->rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rfapiGetUnAddrOfVpnBi(bi, &ri->un)) {
|
if (rfapiGetUnAddrOfVpnBi(bpi, &ri->un)) {
|
||||||
rfapi_info_free(ri);
|
rfapi_info_free(ri);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1711,7 +1711,7 @@ void rfapiRibUpdatePendingNode(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rfapiRibBi2Ri(bi, ri, lifetime);
|
rfapiRibBi2Ri(bpi, ri, lifetime);
|
||||||
|
|
||||||
if (!pn->info) {
|
if (!pn->info) {
|
||||||
pn->info = list_new();
|
pn->info = list_new();
|
||||||
|
@ -105,7 +105,7 @@ extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp,
|
|||||||
|
|
||||||
extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node,
|
extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node,
|
||||||
struct prefix *pfx_vn, struct prefix *pfx_un,
|
struct prefix *pfx_vn, struct prefix *pfx_un,
|
||||||
uint32_t lifetime, struct bgp_info *bi);
|
uint32_t lifetime, struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern struct rfapi_next_hop_entry *
|
extern struct rfapi_next_hop_entry *
|
||||||
rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
|
rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
|
||||||
|
@ -394,7 +394,7 @@ int rfapiStream2Vty(void *stream, /* input */
|
|||||||
|
|
||||||
/* called from bgpd/bgp_vty.c'route_vty_out() */
|
/* called from bgpd/bgp_vty.c'route_vty_out() */
|
||||||
void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *bi, safi_t safi)
|
struct bgp_path_info *bpi, safi_t safi)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
uint32_t lifetime;
|
uint32_t lifetime;
|
||||||
@ -410,7 +410,7 @@ void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
|||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
struct prefix pfx_un;
|
struct prefix pfx_un;
|
||||||
|
|
||||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) {
|
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
vty_out(vty, "UN=%s",
|
vty_out(vty, "UN=%s",
|
||||||
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
||||||
@ -418,27 +418,27 @@ void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->attr && bi->attr->ecommunity) {
|
if (bpi->attr && bpi->attr->ecommunity) {
|
||||||
s = ecommunity_ecom2str(bi->attr->ecommunity,
|
s = ecommunity_ecom2str(bpi->attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
vty_out(vty, " EC{%s}", s);
|
vty_out(vty, " EC{%s}", s);
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->extra != NULL) {
|
if (bpi->extra != NULL) {
|
||||||
if (bi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
|
if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
|
||||||
vty_out(vty, " label=VRF2VRF");
|
vty_out(vty, " label=VRF2VRF");
|
||||||
else
|
else
|
||||||
vty_out(vty, " label=%u",
|
vty_out(vty, " label=%u",
|
||||||
decode_label(&bi->extra->label[0]));
|
decode_label(&bpi->extra->label[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rfapiGetVncLifetime(bi->attr, &lifetime)) {
|
if (!rfapiGetVncLifetime(bpi->attr, &lifetime)) {
|
||||||
vty_out(vty, " life=%d", lifetime);
|
vty_out(vty, " life=%d", lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bi->type),
|
vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bpi->type),
|
||||||
bi->sub_type);
|
bpi->sub_type);
|
||||||
|
|
||||||
vty_out(vty, "%s", HVTYNL);
|
vty_out(vty, "%s", HVTYNL);
|
||||||
}
|
}
|
||||||
@ -477,9 +477,9 @@ void rfapiPrintAttrPtrs(void *stream, struct attr *attr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print BI in an Import Table
|
* Print BPI in an Import Table
|
||||||
*/
|
*/
|
||||||
void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
void rfapiPrintBi(void *stream, struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
char *s;
|
char *s;
|
||||||
@ -503,12 +503,13 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bi)
|
if (!bpi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
|
||||||
&& bi->extra->vnc.import.timer) {
|
&& bpi->extra->vnc.import.timer) {
|
||||||
struct thread *t = (struct thread *)bi->extra->vnc.import.timer;
|
struct thread *t =
|
||||||
|
(struct thread *)bpi->extra->vnc.import.timer;
|
||||||
r = snprintf(p, REMAIN, " [%4lu] ",
|
r = snprintf(p, REMAIN, " [%4lu] ",
|
||||||
thread_timer_remain_second(t));
|
thread_timer_remain_second(t));
|
||||||
INCP;
|
INCP;
|
||||||
@ -518,14 +519,14 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
INCP;
|
INCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->extra) {
|
if (bpi->extra) {
|
||||||
/* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
|
/* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
|
||||||
if (decode_rd_type(bi->extra->vnc.import.rd.val)
|
if (decode_rd_type(bpi->extra->vnc.import.rd.val)
|
||||||
== RD_TYPE_VNC_ETH) {
|
== RD_TYPE_VNC_ETH) {
|
||||||
has_macaddr = 1;
|
has_macaddr = 1;
|
||||||
memcpy(macaddr.octet, bi->extra->vnc.import.rd.val + 2,
|
memcpy(macaddr.octet, bpi->extra->vnc.import.rd.val + 2,
|
||||||
6);
|
6);
|
||||||
l2hid = bi->extra->vnc.import.rd.val[1];
|
l2hid = bpi->extra->vnc.import.rd.val[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,24 +538,24 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
* RFP option sizes (they are opaque values)
|
* RFP option sizes (they are opaque values)
|
||||||
* extended communities (RTs)
|
* extended communities (RTs)
|
||||||
*/
|
*/
|
||||||
if (bi->attr) {
|
if (bpi->attr) {
|
||||||
uint32_t lifetime;
|
uint32_t lifetime;
|
||||||
int printed_1st_gol = 0;
|
int printed_1st_gol = 0;
|
||||||
struct bgp_attr_encap_subtlv *pEncap;
|
struct bgp_attr_encap_subtlv *pEncap;
|
||||||
struct prefix pfx_un;
|
struct prefix pfx_un;
|
||||||
int af = BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len);
|
int af = BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len);
|
||||||
|
|
||||||
/* Nexthop */
|
/* Nexthop */
|
||||||
if (af == AF_INET) {
|
if (af == AF_INET) {
|
||||||
r = snprintf(p, REMAIN, "%s",
|
r = snprintf(p, REMAIN, "%s",
|
||||||
inet_ntop(AF_INET,
|
inet_ntop(AF_INET,
|
||||||
&bi->attr->mp_nexthop_global_in,
|
&bpi->attr->mp_nexthop_global_in,
|
||||||
buf, BUFSIZ));
|
buf, BUFSIZ));
|
||||||
INCP;
|
INCP;
|
||||||
} else if (af == AF_INET6) {
|
} else if (af == AF_INET6) {
|
||||||
r = snprintf(p, REMAIN, "%s",
|
r = snprintf(p, REMAIN, "%s",
|
||||||
inet_ntop(AF_INET6,
|
inet_ntop(AF_INET6,
|
||||||
&bi->attr->mp_nexthop_global,
|
&bpi->attr->mp_nexthop_global,
|
||||||
buf, BUFSIZ));
|
buf, BUFSIZ));
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
@ -565,7 +566,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
/*
|
/*
|
||||||
* VNC tunnel subtlv, if present, contains UN address
|
* VNC tunnel subtlv, if present, contains UN address
|
||||||
*/
|
*/
|
||||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) {
|
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
|
||||||
r = snprintf(p, REMAIN, " un=%s",
|
r = snprintf(p, REMAIN, " un=%s",
|
||||||
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
||||||
BUFSIZ));
|
BUFSIZ));
|
||||||
@ -573,7 +574,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Lifetime */
|
/* Lifetime */
|
||||||
if (rfapiGetVncLifetime(bi->attr, &lifetime)) {
|
if (rfapiGetVncLifetime(bpi->attr, &lifetime)) {
|
||||||
r = snprintf(p, REMAIN, " nolife");
|
r = snprintf(p, REMAIN, " nolife");
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
@ -585,7 +586,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RFP option lengths */
|
/* RFP option lengths */
|
||||||
for (pEncap = bi->attr->vnc_subtlvs; pEncap;
|
for (pEncap = bpi->attr->vnc_subtlvs; pEncap;
|
||||||
pEncap = pEncap->next) {
|
pEncap = pEncap->next) {
|
||||||
|
|
||||||
if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) {
|
if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) {
|
||||||
@ -604,8 +605,8 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RT list */
|
/* RT list */
|
||||||
if (bi->attr->ecommunity) {
|
if (bpi->attr->ecommunity) {
|
||||||
s = ecommunity_ecom2str(bi->attr->ecommunity,
|
s = ecommunity_ecom2str(bpi->attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
r = snprintf(p, REMAIN, " %s", s);
|
r = snprintf(p, REMAIN, " %s", s);
|
||||||
INCP;
|
INCP;
|
||||||
@ -613,13 +614,13 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = snprintf(p, REMAIN, " bi@%p", bi);
|
r = snprintf(p, REMAIN, " bpi@%p", bpi);
|
||||||
INCP;
|
INCP;
|
||||||
|
|
||||||
r = snprintf(p, REMAIN, " p@%p", bi->peer);
|
r = snprintf(p, REMAIN, " p@%p", bpi->peer);
|
||||||
INCP;
|
INCP;
|
||||||
|
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||||
r = snprintf(p, REMAIN, " HD=yes");
|
r = snprintf(p, REMAIN, " HD=yes");
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
@ -627,15 +628,16 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
INCP;
|
INCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->attr) {
|
if (bpi->attr) {
|
||||||
|
|
||||||
if (bi->attr->weight) {
|
if (bpi->attr->weight) {
|
||||||
r = snprintf(p, REMAIN, " W=%d", bi->attr->weight);
|
r = snprintf(p, REMAIN, " W=%d", bpi->attr->weight);
|
||||||
INCP;
|
INCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
|
if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
|
||||||
r = snprintf(p, REMAIN, " LP=%d", bi->attr->local_pref);
|
r = snprintf(p, REMAIN, " LP=%d",
|
||||||
|
bpi->attr->local_pref);
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
r = snprintf(p, REMAIN, " LP=unset");
|
r = snprintf(p, REMAIN, " LP=unset");
|
||||||
@ -643,8 +645,8 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bi->type),
|
r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bpi->type),
|
||||||
bi->sub_type);
|
bpi->sub_type);
|
||||||
INCP;
|
INCP;
|
||||||
|
|
||||||
fp(out, "%s%s", line, HVTYNL);
|
fp(out, "%s%s", line, HVTYNL);
|
||||||
@ -656,7 +658,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
HVTYNL);
|
HVTYNL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rfapiGetL2o(bi->attr, &l2o_buf)) {
|
if (!rfapiGetL2o(bpi->attr, &l2o_buf)) {
|
||||||
fp(out,
|
fp(out,
|
||||||
" L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
|
" L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
|
||||||
l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
|
l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
|
||||||
@ -665,12 +667,12 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id,
|
l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id,
|
||||||
HVTYNL);
|
HVTYNL);
|
||||||
}
|
}
|
||||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
const char *sp;
|
const char *sp;
|
||||||
|
|
||||||
sp = rfapi_ntop(bi->extra->vnc.import.aux_prefix.family,
|
sp = rfapi_ntop(bpi->extra->vnc.import.aux_prefix.family,
|
||||||
&bi->extra->vnc.import.aux_prefix.u.prefix, buf,
|
&bpi->extra->vnc.import.aux_prefix.u.prefix,
|
||||||
BUFSIZ);
|
buf, BUFSIZ);
|
||||||
buf[BUFSIZ - 1] = 0;
|
buf[BUFSIZ - 1] = 0;
|
||||||
if (sp) {
|
if (sp) {
|
||||||
fp(out, " IP: %s%s", sp, HVTYNL);
|
fp(out, " IP: %s%s", sp, HVTYNL);
|
||||||
@ -678,7 +680,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct rfapi_un_option *uo =
|
struct rfapi_un_option *uo =
|
||||||
rfapi_encap_tlv_to_un_option(bi->attr);
|
rfapi_encap_tlv_to_un_option(bpi->attr);
|
||||||
if (uo) {
|
if (uo) {
|
||||||
rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel);
|
rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel);
|
||||||
rfapi_un_options_free(uo);
|
rfapi_un_options_free(uo);
|
||||||
@ -734,13 +736,13 @@ static void rfapiDebugPrintMonitorEncap(void *stream,
|
|||||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fp(out, " Mon m=%p, next=%p, node=%p, bi=%p%s", m, m->next, m->node,
|
fp(out, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m, m->next, m->node,
|
||||||
m->bi, HVTYNL);
|
m->bpi, HVTYNL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rfapiShowItNode(void *stream, struct agg_node *rn)
|
void rfapiShowItNode(void *stream, struct agg_node *rn)
|
||||||
{
|
{
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
int (*fp)(void *, const char *, ...);
|
int (*fp)(void *, const char *, ...);
|
||||||
@ -755,8 +757,8 @@ void rfapiShowItNode(void *stream, struct agg_node *rn)
|
|||||||
rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
|
rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
|
||||||
rn->p.prefixlen, rn, rn->lock, HVTYNL);
|
rn->p.prefixlen, rn, rn->lock, HVTYNL);
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi(stream, bi);
|
rfapiPrintBi(stream, bpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* doesn't show montors */
|
/* doesn't show montors */
|
||||||
@ -779,7 +781,7 @@ void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
|
|||||||
fp(out, "Import Table [%s]%s", label, HVTYNL);
|
fp(out, "Import Table [%s]%s", label, HVTYNL);
|
||||||
|
|
||||||
for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
|
for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
if (rn->p.family == AF_ETHERNET) {
|
if (rn->p.family == AF_ETHERNET) {
|
||||||
rfapiEthAddr2Str(&rn->p.u.prefix_eth, buf, BUFSIZ);
|
rfapiEthAddr2Str(&rn->p.u.prefix_eth, buf, BUFSIZ);
|
||||||
@ -791,8 +793,8 @@ void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
|
|||||||
rn->lock - 1, /* account for loop iterator locking */
|
rn->lock - 1, /* account for loop iterator locking */
|
||||||
HVTYNL);
|
HVTYNL);
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi(stream, bi);
|
rfapiPrintBi(stream, bpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isvpn) {
|
if (isvpn) {
|
||||||
@ -1008,7 +1010,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||||
struct agg_node *rn, struct bgp_info *bi)
|
struct agg_node *rn, struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
int (*fp)(void *, const char *, ...);
|
int (*fp)(void *, const char *, ...);
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
@ -1047,26 +1049,26 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
* UN addr
|
* UN addr
|
||||||
*/
|
*/
|
||||||
buf_un[0] = 0;
|
buf_un[0] = 0;
|
||||||
if (!rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) {
|
if (!rfapiGetUnAddrOfVpnBi(bpi, &pfx_un)) {
|
||||||
snprintf(buf_un, BUFSIZ, "%s",
|
snprintf(buf_un, BUFSIZ, "%s",
|
||||||
inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop,
|
inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop,
|
||||||
BUFSIZ));
|
BUFSIZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
rfapiGetTunnelType(bi->attr, &tun_type);
|
rfapiGetTunnelType(bpi->attr, &tun_type);
|
||||||
/*
|
/*
|
||||||
* VN addr
|
* VN addr
|
||||||
*/
|
*/
|
||||||
buf_vn[0] = 0;
|
buf_vn[0] = 0;
|
||||||
rfapiNexthop2Prefix(bi->attr, &pfx_vn);
|
rfapiNexthop2Prefix(bpi->attr, &pfx_vn);
|
||||||
if (tun_type == BGP_ENCAP_TYPE_MPLS) {
|
if (tun_type == BGP_ENCAP_TYPE_MPLS) {
|
||||||
/* MPLS carries un in nrli next hop (same as vn for IP tunnels)
|
/* MPLS carries un in nrli next hop (same as vn for IP tunnels)
|
||||||
*/
|
*/
|
||||||
snprintf(buf_un, BUFSIZ, "%s",
|
snprintf(buf_un, BUFSIZ, "%s",
|
||||||
inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
|
inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
|
||||||
BUFSIZ));
|
BUFSIZ));
|
||||||
if (bi->extra) {
|
if (bpi->extra) {
|
||||||
uint32_t l = decode_label(&bi->extra->label[0]);
|
uint32_t l = decode_label(&bpi->extra->label[0]);
|
||||||
snprintf(buf_vn, BUFSIZ, "Label: %d", l);
|
snprintf(buf_vn, BUFSIZ, "Label: %d", l);
|
||||||
} else /* should never happen */
|
} else /* should never happen */
|
||||||
{
|
{
|
||||||
@ -1085,10 +1087,10 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
* See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
|
* See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
|
||||||
* back to cost.
|
* back to cost.
|
||||||
*/
|
*/
|
||||||
if (bi->attr) {
|
if (bpi->attr) {
|
||||||
uint32_t local_pref;
|
uint32_t local_pref;
|
||||||
if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
||||||
local_pref = bi->attr->local_pref;
|
local_pref = bpi->attr->local_pref;
|
||||||
else
|
else
|
||||||
local_pref = 0;
|
local_pref = 0;
|
||||||
cost = (local_pref > 255) ? 0 : 255 - local_pref;
|
cost = (local_pref > 255) ? 0 : 255 - local_pref;
|
||||||
@ -1103,7 +1105,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
|
|
||||||
/* Lifetime */
|
/* Lifetime */
|
||||||
/* NB rfapiGetVncLifetime sets infinite value when returning !0 */
|
/* NB rfapiGetVncLifetime sets infinite value when returning !0 */
|
||||||
if (rfapiGetVncLifetime(bi->attr, &lifetime)
|
if (rfapiGetVncLifetime(bpi->attr, &lifetime)
|
||||||
|| (lifetime == RFAPI_INFINITE_LIFETIME)) {
|
|| (lifetime == RFAPI_INFINITE_LIFETIME)) {
|
||||||
|
|
||||||
fp(out, "%-10s ", "infinite");
|
fp(out, "%-10s ", "infinite");
|
||||||
@ -1113,20 +1115,21 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
fp(out, "%-10s ", buf_lifetime);
|
fp(out, "%-10s ", buf_lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
|
||||||
&& bi->extra->vnc.import.timer) {
|
&& bpi->extra->vnc.import.timer) {
|
||||||
|
|
||||||
uint32_t remaining;
|
uint32_t remaining;
|
||||||
time_t age;
|
time_t age;
|
||||||
char buf_age[BUFSIZ];
|
char buf_age[BUFSIZ];
|
||||||
|
|
||||||
struct thread *t = (struct thread *)bi->extra->vnc.import.timer;
|
struct thread *t =
|
||||||
|
(struct thread *)bpi->extra->vnc.import.timer;
|
||||||
remaining = thread_timer_remain_second(t);
|
remaining = thread_timer_remain_second(t);
|
||||||
|
|
||||||
#if RFAPI_REGISTRATIONS_REPORT_AGE
|
#if RFAPI_REGISTRATIONS_REPORT_AGE
|
||||||
/*
|
/*
|
||||||
* Calculate when the timer started. Doing so here saves
|
* Calculate when the timer started. Doing so here saves
|
||||||
* us a timestamp field in "struct bgp_info".
|
* us a timestamp field in "struct bgp_path_info".
|
||||||
*
|
*
|
||||||
* See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
|
* See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
|
||||||
* original calculation.
|
* original calculation.
|
||||||
@ -1140,12 +1143,12 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
|
|
||||||
fp(out, "%-10s ", buf_age);
|
fp(out, "%-10s ", buf_age);
|
||||||
|
|
||||||
} else if (RFAPI_LOCAL_BI(bi)) {
|
} else if (RFAPI_LOCAL_BI(bpi)) {
|
||||||
|
|
||||||
char buf_age[BUFSIZ];
|
char buf_age[BUFSIZ];
|
||||||
|
|
||||||
if (bi->extra && bi->extra->vnc.import.create_time) {
|
if (bpi->extra && bpi->extra->vnc.import.create_time) {
|
||||||
rfapiFormatAge(bi->extra->vnc.import.create_time,
|
rfapiFormatAge(bpi->extra->vnc.import.create_time,
|
||||||
buf_age, BUFSIZ);
|
buf_age, BUFSIZ);
|
||||||
} else {
|
} else {
|
||||||
buf_age[0] = '?';
|
buf_age[0] = '?';
|
||||||
@ -1161,12 +1164,12 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
* print that on the next line
|
* print that on the next line
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
const char *sp;
|
const char *sp;
|
||||||
|
|
||||||
sp = rfapi_ntop(
|
sp = rfapi_ntop(
|
||||||
bi->extra->vnc.import.aux_prefix.family,
|
bpi->extra->vnc.import.aux_prefix.family,
|
||||||
&bi->extra->vnc.import.aux_prefix.u.prefix,
|
&bpi->extra->vnc.import.aux_prefix.u.prefix,
|
||||||
buf_ntop, BUFSIZ);
|
buf_ntop, BUFSIZ);
|
||||||
buf_ntop[BUFSIZ - 1] = 0;
|
buf_ntop[BUFSIZ - 1] = 0;
|
||||||
|
|
||||||
@ -1177,8 +1180,8 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) {
|
if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra) {
|
||||||
uint32_t l = decode_label(&bi->extra->label[0]);
|
uint32_t l = decode_label(&bpi->extra->label[0]);
|
||||||
if (!MPLS_LABEL_IS_NULL(l)) {
|
if (!MPLS_LABEL_IS_NULL(l)) {
|
||||||
fp(out, " Label: %d", l);
|
fp(out, " Label: %d", l);
|
||||||
if (nlines == 1)
|
if (nlines == 1)
|
||||||
@ -1222,7 +1225,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
for (rn = agg_route_top(it->imported_vpn[afi]); rn;
|
for (rn = agg_route_top(it->imported_vpn[afi]); rn;
|
||||||
rn = agg_route_next(rn)) {
|
rn = agg_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
int count_only;
|
int count_only;
|
||||||
|
|
||||||
/* allow for wider or more narrow mask from user */
|
/* allow for wider or more narrow mask from user */
|
||||||
@ -1232,30 +1235,32 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
else
|
else
|
||||||
count_only = 0;
|
count_only = 0;
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
if (!show_local && RFAPI_LOCAL_BI(bi)) {
|
if (!show_local && RFAPI_LOCAL_BI(bpi)) {
|
||||||
|
|
||||||
/* local route from RFP */
|
/* local route from RFP */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!show_remote && !RFAPI_LOCAL_BI(bi)) {
|
if (!show_remote && !RFAPI_LOCAL_BI(bpi)) {
|
||||||
|
|
||||||
/* remote route */
|
/* remote route */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_expiring
|
if (show_expiring
|
||||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
&& !CHECK_FLAG(bpi->flags,
|
||||||
|
BGP_PATH_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!show_expiring
|
if (!show_expiring
|
||||||
&& CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
&& CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (bi->type == ZEBRA_ROUTE_BGP_DIRECT
|
if (bpi->type == ZEBRA_ROUTE_BGP_DIRECT
|
||||||
|| bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
|
|| bpi->type
|
||||||
|
== ZEBRA_ROUTE_BGP_DIRECT_EXT) {
|
||||||
if (!show_imported)
|
if (!show_imported)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@ -1277,7 +1282,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
type = "Holddown";
|
type = "Holddown";
|
||||||
} else {
|
} else {
|
||||||
if (RFAPI_LOCAL_BI(
|
if (RFAPI_LOCAL_BI(
|
||||||
bi)) {
|
bpi)) {
|
||||||
type = "Local";
|
type = "Local";
|
||||||
} else {
|
} else {
|
||||||
type = "Remote";
|
type = "Remote";
|
||||||
@ -1327,7 +1332,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
"Lifetime", agetype, HVTYNL);
|
"Lifetime", agetype, HVTYNL);
|
||||||
}
|
}
|
||||||
printed += rfapiPrintRemoteRegBi(bgp, stream,
|
printed += rfapiPrintRemoteRegBi(bgp, stream,
|
||||||
rn, bi);
|
rn, bpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1535,7 +1540,7 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
|||||||
{
|
{
|
||||||
afi_t afi; /* of the VN address */
|
afi_t afi; /* of the VN address */
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
uint8_t type = ZEBRA_ROUTE_BGP;
|
uint8_t type = ZEBRA_ROUTE_BGP;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
int printed = 0;
|
int printed = 0;
|
||||||
@ -1543,7 +1548,7 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
|||||||
struct prefix_rd *prd;
|
struct prefix_rd *prd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the bgp_info in the RIB corresponding to this
|
* Find the bgp_path in the RIB corresponding to this
|
||||||
* prefix and rfd
|
* prefix and rfd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1565,12 +1570,12 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
|||||||
|
|
||||||
vty_out(vty, " bn=%p%s", bn, HVTYNL);
|
vty_out(vty, " bn=%p%s", bn, HVTYNL);
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (bi->peer == rfd->peer && bi->type == type
|
if (bpi->peer == rfd->peer && bpi->type == type
|
||||||
&& bi->sub_type == BGP_ROUTE_RFP && bi->extra
|
&& bpi->sub_type == BGP_ROUTE_RFP && bpi->extra
|
||||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||||
|
|
||||||
rfapiPrintBi(vty, bi);
|
rfapiPrintBi(vty, bpi);
|
||||||
printed = 1;
|
printed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,14 +173,14 @@ static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce)
|
|||||||
|
|
||||||
|
|
||||||
void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi)
|
struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
struct attr *attr = bi->attr;
|
struct attr *attr = bpi->attr;
|
||||||
struct peer *peer = bi->peer;
|
struct peer *peer = bpi->peer;
|
||||||
struct prefix *prefix = &rn->p;
|
struct prefix *prefix = &rn->p;
|
||||||
afi_t afi = family2afi(prefix->family);
|
afi_t afi = family2afi(prefix->family);
|
||||||
struct bgp_node *urn;
|
struct bgp_node *urn;
|
||||||
struct bgp_info *ubi;
|
struct bgp_path_info *ubpi;
|
||||||
struct attr hattr;
|
struct attr hattr;
|
||||||
struct attr *iattr;
|
struct attr *iattr;
|
||||||
struct prefix ce_nexthop;
|
struct prefix ce_nexthop;
|
||||||
@ -193,10 +193,10 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bi->type != ZEBRA_ROUTE_BGP)
|
if ((bpi->type != ZEBRA_ROUTE_BGP)
|
||||||
|| (bi->sub_type != BGP_ROUTE_NORMAL
|
|| (bpi->sub_type != BGP_ROUTE_NORMAL
|
||||||
&& bi->sub_type != BGP_ROUTE_RFP
|
&& bpi->sub_type != BGP_ROUTE_RFP
|
||||||
&& bi->sub_type != BGP_ROUTE_STATIC)) {
|
&& bpi->sub_type != BGP_ROUTE_STATIC)) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
"%s: wrong route type/sub_type for export, skipping",
|
"%s: wrong route type/sub_type for export, skipping",
|
||||||
@ -256,17 +256,17 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
*/
|
*/
|
||||||
urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST,
|
urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST,
|
||||||
prefix, NULL);
|
prefix, NULL);
|
||||||
for (ubi = urn->info; ubi; ubi = ubi->next) {
|
for (ubpi = urn->info; ubpi; ubpi = ubpi->next) {
|
||||||
struct prefix unicast_nexthop;
|
struct prefix unicast_nexthop;
|
||||||
|
|
||||||
if (CHECK_FLAG(ubi->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(ubpi->flags, BGP_PATH_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rfapiUnicastNexthop2Prefix(afi, ubi->attr, &unicast_nexthop);
|
rfapiUnicastNexthop2Prefix(afi, ubpi->attr, &unicast_nexthop);
|
||||||
|
|
||||||
if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT
|
if (ubpi->type == ZEBRA_ROUTE_VNC_DIRECT
|
||||||
&& ubi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
&& ubpi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||||
&& ubi->peer == peer
|
&& ubpi->peer == peer
|
||||||
&& prefix_same(&unicast_nexthop, &ce_nexthop)) {
|
&& prefix_same(&unicast_nexthop, &ce_nexthop)) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
@ -282,7 +282,7 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
*/
|
*/
|
||||||
encap_attr_export_ce(&hattr, attr, &ce_nexthop);
|
encap_attr_export_ce(&hattr, attr, &ce_nexthop);
|
||||||
if (bgp->rfapi_cfg->routemap_export_bgp) {
|
if (bgp->rfapi_cfg->routemap_export_bgp) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -328,10 +328,10 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
* "Withdrawing a Route" export process
|
* "Withdrawing a Route" export process
|
||||||
*/
|
*/
|
||||||
void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi)
|
struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
afi_t afi = family2afi(rn->p.family);
|
afi_t afi = family2afi(rn->p.family);
|
||||||
struct bgp_info *vbi;
|
struct bgp_path_info *vbpi;
|
||||||
struct prefix ce_nexthop;
|
struct prefix ce_nexthop;
|
||||||
|
|
||||||
if (!afi) {
|
if (!afi) {
|
||||||
@ -364,7 +364,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
* This works only for IPv4 because IPv6 addresses are too big
|
* This works only for IPv4 because IPv6 addresses are too big
|
||||||
* to fit in an extended community
|
* to fit in an extended community
|
||||||
*/
|
*/
|
||||||
if (getce(bgp, bi->attr, &ce_nexthop)) {
|
if (getce(bgp, bpi->attr, &ce_nexthop)) {
|
||||||
vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping",
|
vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping",
|
||||||
__func__);
|
__func__);
|
||||||
return;
|
return;
|
||||||
@ -376,13 +376,13 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
* route from the unicast RIB
|
* route from the unicast RIB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (vbi = rn->info; vbi; vbi = vbi->next) {
|
for (vbpi = rn->info; vbpi; vbpi = vbpi->next) {
|
||||||
struct prefix ce;
|
struct prefix ce;
|
||||||
if (bi == vbi)
|
if (bpi == vbpi)
|
||||||
continue;
|
continue;
|
||||||
if (bi->peer != vbi->peer)
|
if (bpi->peer != vbpi->peer)
|
||||||
continue;
|
continue;
|
||||||
if (getce(bgp, vbi->attr, &ce))
|
if (getce(bgp, vbpi->attr, &ce))
|
||||||
continue;
|
continue;
|
||||||
if (prefix_same(&ce, &ce_nexthop)) {
|
if (prefix_same(&ce, &ce_nexthop)) {
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
@ -395,7 +395,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
/*
|
/*
|
||||||
* withdraw the route
|
* withdraw the route
|
||||||
*/
|
*/
|
||||||
bgp_withdraw(bi->peer, &rn->p, 0, /* addpath_id */
|
bgp_withdraw(bpi->peer, &rn->p, 0, /* addpath_id */
|
||||||
NULL, /* attr, ignored */
|
NULL, /* attr, ignored */
|
||||||
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
||||||
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
|
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
|
||||||
@ -405,7 +405,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
|
static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
|
||||||
{
|
{
|
||||||
struct agg_node *rn;
|
struct agg_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
|
|
||||||
vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi);
|
vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi);
|
||||||
|
|
||||||
@ -480,8 +480,8 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
|
|||||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct bgp_info *next;
|
struct bgp_path_info *next;
|
||||||
|
|
||||||
for (ri = rn->info, next = NULL; ri; ri = next) {
|
for (ri = rn->info, next = NULL; ri; ri = next) {
|
||||||
|
|
||||||
@ -516,24 +516,24 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
|
|||||||
static struct ecommunity *vnc_route_origin_ecom(struct agg_node *rn)
|
static struct ecommunity *vnc_route_origin_ecom(struct agg_node *rn)
|
||||||
{
|
{
|
||||||
struct ecommunity *new;
|
struct ecommunity *new;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
if (!rn->info)
|
if (!rn->info)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
new = ecommunity_new();
|
new = ecommunity_new();
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
struct ecommunity_val roec;
|
struct ecommunity_val roec;
|
||||||
|
|
||||||
switch (BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len)) {
|
switch (BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len)) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
memset(&roec, 0, sizeof(roec));
|
memset(&roec, 0, sizeof(roec));
|
||||||
roec.val[0] = 0x01;
|
roec.val[0] = 0x01;
|
||||||
roec.val[1] = 0x03;
|
roec.val[1] = 0x03;
|
||||||
memcpy(roec.val + 2,
|
memcpy(roec.val + 2,
|
||||||
&bi->attr->mp_nexthop_global_in.s_addr, 4);
|
&bpi->attr->mp_nexthop_global_in.s_addr, 4);
|
||||||
roec.val[6] = 0;
|
roec.val[6] = 0;
|
||||||
roec.val[7] = 0;
|
roec.val[7] = 0;
|
||||||
ecommunity_add_val(new, &roec);
|
ecommunity_add_val(new, &roec);
|
||||||
@ -996,7 +996,7 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
|
|||||||
struct rfapi_descriptor *irfd = rfd;
|
struct rfapi_descriptor *irfd = rfd;
|
||||||
struct attr hattr;
|
struct attr hattr;
|
||||||
struct attr *iattr;
|
struct attr *iattr;
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
|
|
||||||
if (rfapiRaddr2Qprefix(&irfd->vn_addr,
|
if (rfapiRaddr2Qprefix(&irfd->vn_addr,
|
||||||
&nhp))
|
&nhp))
|
||||||
@ -1165,7 +1165,7 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
|
|||||||
afi_t afi, struct rfapi_descriptor *irfd)
|
afi_t afi, struct rfapi_descriptor *irfd)
|
||||||
{
|
{
|
||||||
struct prefix nhp;
|
struct prefix nhp;
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
struct attr hattr;
|
struct attr hattr;
|
||||||
struct attr *iattr;
|
struct attr *iattr;
|
||||||
|
|
||||||
@ -1629,7 +1629,7 @@ void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* "Adding a Route" export process
|
* "Adding a Route" export process
|
||||||
* TBD do we need to check bi->type and bi->sub_type here, or does
|
* TBD do we need to check bpi->type and bpi->sub_type here, or does
|
||||||
* caller do it?
|
* caller do it?
|
||||||
*/
|
*/
|
||||||
void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
|
void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
|
||||||
@ -1684,7 +1684,7 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
|
|||||||
if (encap_attr_export(&hattr, attr, NULL, NULL))
|
if (encap_attr_export(&hattr, attr, NULL, NULL))
|
||||||
return;
|
return;
|
||||||
if (hc->routemap_export_bgp) {
|
if (hc->routemap_export_bgp) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -1753,7 +1753,7 @@ static int vncExportWithdrawTimer(struct thread *t)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* "Withdrawing a Route" export process
|
* "Withdrawing a Route" export process
|
||||||
* TBD do we need to check bi->type and bi->sub_type here, or does
|
* TBD do we need to check bpi->type and bpi->sub_type here, or does
|
||||||
* caller do it?
|
* caller do it?
|
||||||
*/
|
*/
|
||||||
void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi,
|
void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi,
|
||||||
@ -1839,7 +1839,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
|
|||||||
|
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
|
|
||||||
memset(&prd, 0, sizeof(prd));
|
memset(&prd, 0, sizeof(prd));
|
||||||
prd.family = AF_UNSPEC;
|
prd.family = AF_UNSPEC;
|
||||||
@ -1910,7 +1910,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hc->routemap_export_bgp) {
|
if (hc->routemap_export_bgp) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -2001,8 +2001,8 @@ void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi)
|
|||||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct bgp_info *next;
|
struct bgp_path_info *next;
|
||||||
|
|
||||||
for (ri = rn->info, next = NULL; ri; ri = next) {
|
for (ri = rn->info, next = NULL; ri; ri = next) {
|
||||||
|
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
#include "rfapi_private.h"
|
#include "rfapi_private.h"
|
||||||
|
|
||||||
extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi);
|
struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi);
|
struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern void vnc_direct_bgp_add_prefix(struct bgp *bgp,
|
extern void vnc_direct_bgp_add_prefix(struct bgp *bgp,
|
||||||
struct rfapi_import_table *import_table,
|
struct rfapi_import_table *import_table,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -35,10 +35,10 @@ extern uint32_t calc_local_pref(struct attr *attr, struct peer *peer);
|
|||||||
extern int vnc_prefix_cmp(void *pfx1, void *pfx2);
|
extern int vnc_prefix_cmp(void *pfx1, void *pfx2);
|
||||||
|
|
||||||
extern void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix,
|
extern void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix,
|
||||||
struct bgp_info *info);
|
struct bgp_path_info *info);
|
||||||
|
|
||||||
extern void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix,
|
extern void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix,
|
||||||
struct bgp_info *info);
|
struct bgp_path_info *info);
|
||||||
|
|
||||||
extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi);
|
extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi);
|
||||||
|
|
||||||
@ -52,23 +52,22 @@ extern void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi);
|
|||||||
extern void vnc_import_bgp_exterior_add_route(
|
extern void vnc_import_bgp_exterior_add_route(
|
||||||
struct bgp *bgp, /* exterior instance, we hope */
|
struct bgp *bgp, /* exterior instance, we hope */
|
||||||
struct prefix *prefix, /* unicast prefix */
|
struct prefix *prefix, /* unicast prefix */
|
||||||
struct bgp_info *info); /* unicast info */
|
struct bgp_path_info *info); /* unicast info */
|
||||||
|
|
||||||
extern void
|
extern void vnc_import_bgp_exterior_del_route(
|
||||||
vnc_import_bgp_exterior_del_route(struct bgp *bgp,
|
struct bgp *bgp, struct prefix *prefix, /* unicast prefix */
|
||||||
struct prefix *prefix, /* unicast prefix */
|
struct bgp_path_info *info); /* unicast info */
|
||||||
struct bgp_info *info); /* unicast info */
|
|
||||||
|
|
||||||
extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||||
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
||||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||||
struct prefix *prefix, /* VPN prefix */
|
struct prefix *prefix, /* VPN prefix */
|
||||||
struct bgp_info *bi); /* new VPN host route */
|
struct bgp_path_info *bpi); /* new VPN host route */
|
||||||
|
|
||||||
extern void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
extern void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||||
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
||||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||||
struct prefix *prefix, /* VPN prefix */
|
struct prefix *prefix, /* VPN prefix */
|
||||||
struct bgp_info *bi); /* old VPN host route */
|
struct bgp_path_info *bpi); /* old VPN host route */
|
||||||
|
|
||||||
#endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */
|
#endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */
|
||||||
|
@ -30,12 +30,12 @@
|
|||||||
extern void vnc_import_bgp_exterior_add_route_interior(
|
extern void vnc_import_bgp_exterior_add_route_interior(
|
||||||
struct bgp *bgp, struct rfapi_import_table *it,
|
struct bgp *bgp, struct rfapi_import_table *it,
|
||||||
struct agg_node *rn_interior, /* VPN IT node */
|
struct agg_node *rn_interior, /* VPN IT node */
|
||||||
struct bgp_info *bi_interior); /* VPN IT route */
|
struct bgp_path_info *bpi_interior); /* VPN IT route */
|
||||||
|
|
||||||
extern void vnc_import_bgp_exterior_del_route_interior(
|
extern void vnc_import_bgp_exterior_del_route_interior(
|
||||||
struct bgp *bgp, struct rfapi_import_table *it,
|
struct bgp *bgp, struct rfapi_import_table *it,
|
||||||
struct agg_node *rn_interior, /* VPN IT node */
|
struct agg_node *rn_interior, /* VPN IT node */
|
||||||
struct bgp_info *bi_interior); /* VPN IT route */
|
struct bgp_path_info *bpi_interior); /* VPN IT route */
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi,
|
vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi,
|
||||||
|
@ -316,7 +316,7 @@ static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type)
|
|||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
|
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (ri = rn->info; ri; ri = ri->next) {
|
||||||
if (ri->type
|
if (ri->type
|
||||||
|
@ -241,7 +241,7 @@ Legend:
|
|||||||
/\ struct bgp_node: a BGP destination/route/prefix
|
/\ struct bgp_node: a BGP destination/route/prefix
|
||||||
\/
|
\/
|
||||||
|
|
||||||
[ ] struct bgp_info: a BGP path (e.g. route received from a peer)
|
[ ] struct bgp_path_info: a BGP path (e.g. route received from a peer)
|
||||||
|
|
||||||
_
|
_
|
||||||
(_) struct bgp_nexthop_cache: a BGP nexthop
|
(_) struct bgp_nexthop_cache: a BGP nexthop
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# ...
|
# ...
|
||||||
# (gdb) cont
|
# (gdb) cont
|
||||||
# Breakpoint 3, bgp_write_packet (peer=0x7fa885199080) at bgp_packet.c:614
|
# Breakpoint 3, bgp_write_packet (peer=0x7fa885199080) at bgp_packet.c:614
|
||||||
# 614 if (CHECK_FLAG (adv->binfo->peer->cap,PEER_CAP_RESTART_RCV)
|
# 614 if (CHECK_FLAG (adv->path->peer->cap,PEER_CAP_RESTART_RCV)
|
||||||
# (gdb) dump_prefix4 &adv->rn->p
|
# (gdb) dump_prefix4 &adv->rn->p
|
||||||
# IPv4:10.1.1.0/24
|
# IPv4:10.1.1.0/24
|
||||||
# (gdb) dump_prefix &adv->rn->p
|
# (gdb) dump_prefix &adv->rn->p
|
||||||
|
@ -207,7 +207,7 @@ struct peer test_mp_list_peer[] = {
|
|||||||
};
|
};
|
||||||
int test_mp_list_peer_count = sizeof(test_mp_list_peer) / sizeof(struct peer);
|
int test_mp_list_peer_count = sizeof(test_mp_list_peer) / sizeof(struct peer);
|
||||||
struct attr test_mp_list_attr[4];
|
struct attr test_mp_list_attr[4];
|
||||||
struct bgp_info test_mp_list_info[] = {
|
struct bgp_path_info test_mp_list_info[] = {
|
||||||
{.peer = &test_mp_list_peer[0], .attr = &test_mp_list_attr[0]},
|
{.peer = &test_mp_list_peer[0], .attr = &test_mp_list_attr[0]},
|
||||||
{.peer = &test_mp_list_peer[1], .attr = &test_mp_list_attr[1]},
|
{.peer = &test_mp_list_peer[1], .attr = &test_mp_list_attr[1]},
|
||||||
{.peer = &test_mp_list_peer[2], .attr = &test_mp_list_attr[1]},
|
{.peer = &test_mp_list_peer[2], .attr = &test_mp_list_attr[1]},
|
||||||
@ -215,7 +215,7 @@ struct bgp_info test_mp_list_info[] = {
|
|||||||
{.peer = &test_mp_list_peer[4], .attr = &test_mp_list_attr[3]},
|
{.peer = &test_mp_list_peer[4], .attr = &test_mp_list_attr[3]},
|
||||||
};
|
};
|
||||||
int test_mp_list_info_count =
|
int test_mp_list_info_count =
|
||||||
sizeof(test_mp_list_info) / sizeof(struct bgp_info);
|
sizeof(test_mp_list_info) / sizeof(struct bgp_path_info);
|
||||||
|
|
||||||
static int setup_bgp_mp_list(testcase_t *t)
|
static int setup_bgp_mp_list(testcase_t *t)
|
||||||
{
|
{
|
||||||
@ -247,7 +247,7 @@ static int run_bgp_mp_list(testcase_t *t)
|
|||||||
{
|
{
|
||||||
struct list mp_list;
|
struct list mp_list;
|
||||||
struct listnode *mp_node;
|
struct listnode *mp_node;
|
||||||
struct bgp_info *info;
|
struct bgp_path_info *info;
|
||||||
int i;
|
int i;
|
||||||
int test_result = TEST_PASSED;
|
int test_result = TEST_PASSED;
|
||||||
bgp_mp_list_init(&mp_list);
|
bgp_mp_list_init(&mp_list);
|
||||||
@ -289,24 +289,24 @@ testcase_t test_bgp_mp_list = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*=========================================================
|
/*=========================================================
|
||||||
* Testcase for bgp_info_mpath_update
|
* Testcase for bgp_path_info_mpath_update
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct bgp_node test_rn;
|
struct bgp_node test_rn;
|
||||||
|
|
||||||
static int setup_bgp_info_mpath_update(testcase_t *t)
|
static int setup_bgp_path_info_mpath_update(testcase_t *t)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
str2prefix("42.1.1.0/24", &test_rn.p);
|
str2prefix("42.1.1.0/24", &test_rn.p);
|
||||||
setup_bgp_mp_list(t);
|
setup_bgp_mp_list(t);
|
||||||
for (i = 0; i < test_mp_list_info_count; i++)
|
for (i = 0; i < test_mp_list_info_count; i++)
|
||||||
bgp_info_add(&test_rn, &test_mp_list_info[i]);
|
bgp_path_info_add(&test_rn, &test_mp_list_info[i]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_bgp_info_mpath_update(testcase_t *t)
|
static int run_bgp_path_info_mpath_update(testcase_t *t)
|
||||||
{
|
{
|
||||||
struct bgp_info *new_best, *old_best, *mpath;
|
struct bgp_path_info *new_best, *old_best, *mpath;
|
||||||
struct list mp_list;
|
struct list mp_list;
|
||||||
struct bgp_maxpaths_cfg mp_cfg = {3, 3};
|
struct bgp_maxpaths_cfg mp_cfg = {3, 3};
|
||||||
int test_result = TEST_PASSED;
|
int test_result = TEST_PASSED;
|
||||||
@ -317,33 +317,35 @@ static int run_bgp_info_mpath_update(testcase_t *t)
|
|||||||
bgp_mp_list_add(&mp_list, &test_mp_list_info[1]);
|
bgp_mp_list_add(&mp_list, &test_mp_list_info[1]);
|
||||||
new_best = &test_mp_list_info[3];
|
new_best = &test_mp_list_info[3];
|
||||||
old_best = NULL;
|
old_best = NULL;
|
||||||
bgp_info_mpath_update(&test_rn, new_best, old_best, &mp_list, &mp_cfg);
|
bgp_path_info_mpath_update(&test_rn, new_best, old_best, &mp_list,
|
||||||
|
&mp_cfg);
|
||||||
bgp_mp_list_clear(&mp_list);
|
bgp_mp_list_clear(&mp_list);
|
||||||
EXPECT_TRUE(bgp_info_mpath_count(new_best) == 2, test_result);
|
EXPECT_TRUE(bgp_path_info_mpath_count(new_best) == 2, test_result);
|
||||||
mpath = bgp_info_mpath_first(new_best);
|
mpath = bgp_path_info_mpath_first(new_best);
|
||||||
EXPECT_TRUE(mpath == &test_mp_list_info[0], test_result);
|
EXPECT_TRUE(mpath == &test_mp_list_info[0], test_result);
|
||||||
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_INFO_MULTIPATH), test_result);
|
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_PATH_MULTIPATH), test_result);
|
||||||
mpath = bgp_info_mpath_next(mpath);
|
mpath = bgp_path_info_mpath_next(mpath);
|
||||||
EXPECT_TRUE(mpath == &test_mp_list_info[1], test_result);
|
EXPECT_TRUE(mpath == &test_mp_list_info[1], test_result);
|
||||||
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_INFO_MULTIPATH), test_result);
|
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_PATH_MULTIPATH), test_result);
|
||||||
|
|
||||||
bgp_mp_list_add(&mp_list, &test_mp_list_info[0]);
|
bgp_mp_list_add(&mp_list, &test_mp_list_info[0]);
|
||||||
bgp_mp_list_add(&mp_list, &test_mp_list_info[1]);
|
bgp_mp_list_add(&mp_list, &test_mp_list_info[1]);
|
||||||
new_best = &test_mp_list_info[0];
|
new_best = &test_mp_list_info[0];
|
||||||
old_best = &test_mp_list_info[3];
|
old_best = &test_mp_list_info[3];
|
||||||
bgp_info_mpath_update(&test_rn, new_best, old_best, &mp_list, &mp_cfg);
|
bgp_path_info_mpath_update(&test_rn, new_best, old_best, &mp_list,
|
||||||
|
&mp_cfg);
|
||||||
bgp_mp_list_clear(&mp_list);
|
bgp_mp_list_clear(&mp_list);
|
||||||
EXPECT_TRUE(bgp_info_mpath_count(new_best) == 1, test_result);
|
EXPECT_TRUE(bgp_path_info_mpath_count(new_best) == 1, test_result);
|
||||||
mpath = bgp_info_mpath_first(new_best);
|
mpath = bgp_path_info_mpath_first(new_best);
|
||||||
EXPECT_TRUE(mpath == &test_mp_list_info[1], test_result);
|
EXPECT_TRUE(mpath == &test_mp_list_info[1], test_result);
|
||||||
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_INFO_MULTIPATH), test_result);
|
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_PATH_MULTIPATH), test_result);
|
||||||
EXPECT_TRUE(!CHECK_FLAG(test_mp_list_info[0].flags, BGP_INFO_MULTIPATH),
|
EXPECT_TRUE(!CHECK_FLAG(test_mp_list_info[0].flags, BGP_PATH_MULTIPATH),
|
||||||
test_result);
|
test_result);
|
||||||
|
|
||||||
return test_result;
|
return test_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cleanup_bgp_info_mpath_update(testcase_t *t)
|
static int cleanup_bgp_path_info_mpath_update(testcase_t *t)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -353,11 +355,11 @@ static int cleanup_bgp_info_mpath_update(testcase_t *t)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
testcase_t test_bgp_info_mpath_update = {
|
testcase_t test_bgp_path_info_mpath_update = {
|
||||||
.desc = "Test bgp_info_mpath_update",
|
.desc = "Test bgp_path_info_mpath_update",
|
||||||
.setup = setup_bgp_info_mpath_update,
|
.setup = setup_bgp_path_info_mpath_update,
|
||||||
.run = run_bgp_info_mpath_update,
|
.run = run_bgp_path_info_mpath_update,
|
||||||
.cleanup = cleanup_bgp_info_mpath_update,
|
.cleanup = cleanup_bgp_path_info_mpath_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*=========================================================
|
/*=========================================================
|
||||||
@ -365,7 +367,7 @@ testcase_t test_bgp_info_mpath_update = {
|
|||||||
*/
|
*/
|
||||||
testcase_t *all_tests[] = {
|
testcase_t *all_tests[] = {
|
||||||
&test_bgp_cfg_maximum_paths, &test_bgp_mp_list,
|
&test_bgp_cfg_maximum_paths, &test_bgp_mp_list,
|
||||||
&test_bgp_info_mpath_update,
|
&test_bgp_path_info_mpath_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
int all_tests_count = (sizeof(all_tests) / sizeof(testcase_t *));
|
int all_tests_count = (sizeof(all_tests) / sizeof(testcase_t *));
|
||||||
|
@ -5,5 +5,5 @@ class TestMpath(frrtest.TestMultiOut):
|
|||||||
|
|
||||||
TestMpath.okfail("bgp maximum-paths config")
|
TestMpath.okfail("bgp maximum-paths config")
|
||||||
TestMpath.okfail("bgp_mp_list")
|
TestMpath.okfail("bgp_mp_list")
|
||||||
TestMpath.okfail("bgp_info_mpath_update")
|
TestMpath.okfail("bgp_path_info_mpath_update")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user