mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 13:27:53 +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
|
||||
using pointer to existing data
|
||||
many validity checks
|
||||
get new struct bgp_info (10 words/40 bytes)
|
||||
call bgp_info_add with rn and bgp_info
|
||||
get new struct bgp_path_info
|
||||
call bgp_path_info_add with rn and bgp_path_info
|
||||
call bgp_process
|
||||
|
||||
bgp_routemap.c
|
||||
@ -149,7 +149,7 @@ bgpd.c
|
||||
Question: How much memory does quagga's bgpd use as a function of
|
||||
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
|
||||
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
|
||||
|
@ -90,9 +90,9 @@ struct bgp_advertise *bgp_advertise_new(void)
|
||||
|
||||
void bgp_advertise_free(struct bgp_advertise *adv)
|
||||
{
|
||||
if (adv->binfo)
|
||||
bgp_info_unlock(
|
||||
adv->binfo); /* bgp_advertise bgp_info reference */
|
||||
if (adv->pathi)
|
||||
/* bgp_advertise bgp_path_info reference */
|
||||
bgp_path_info_unlock(adv->pathi);
|
||||
XFREE(MTYPE_BGP_ADVERTISE, adv);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ struct bgp_advertise {
|
||||
struct bgp_advertise_attr *baa;
|
||||
|
||||
/* BGP info. */
|
||||
struct bgp_info *binfo;
|
||||
struct bgp_path_info *pathi;
|
||||
};
|
||||
|
||||
/* BGP adjacency out. */
|
||||
@ -113,7 +113,7 @@ struct bgp_synchronize {
|
||||
};
|
||||
|
||||
/* BGP adjacency linked list. */
|
||||
#define BGP_INFO_ADD(N, A, TYPE) \
|
||||
#define BGP_PATH_INFO_ADD(N, A, TYPE) \
|
||||
do { \
|
||||
(A)->prev = NULL; \
|
||||
(A)->next = (N)->TYPE; \
|
||||
@ -122,7 +122,7 @@ struct bgp_synchronize {
|
||||
(N)->TYPE = (A); \
|
||||
} while (0)
|
||||
|
||||
#define BGP_INFO_DEL(N, A, TYPE) \
|
||||
#define BGP_PATH_INFO_DEL(N, A, TYPE) \
|
||||
do { \
|
||||
if ((A)->next) \
|
||||
(A)->next->prev = (A)->prev; \
|
||||
@ -132,10 +132,10 @@ struct bgp_synchronize {
|
||||
(N)->TYPE = (A)->next; \
|
||||
} while (0)
|
||||
|
||||
#define BGP_ADJ_IN_ADD(N,A) BGP_INFO_ADD(N,A,adj_in)
|
||||
#define BGP_ADJ_IN_DEL(N,A) BGP_INFO_DEL(N,A,adj_in)
|
||||
#define BGP_ADJ_OUT_ADD(N,A) BGP_INFO_ADD(N,A,adj_out)
|
||||
#define BGP_ADJ_OUT_DEL(N,A) BGP_INFO_DEL(N,A,adj_out)
|
||||
#define BGP_ADJ_IN_ADD(N, A) BGP_PATH_INFO_ADD(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_PATH_INFO_ADD(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) \
|
||||
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
|
||||
used list. */
|
||||
#define BGP_DAMP_LIST_ADD(N,A) BGP_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_ADD(N, A) BGP_PATH_INFO_ADD(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. */
|
||||
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 ) */
|
||||
for (; bdi; bdi = next) {
|
||||
struct bgp *bgp = bdi->binfo->peer->bgp;
|
||||
struct bgp *bgp = bdi->path->peer->bgp;
|
||||
|
||||
next = bdi->next;
|
||||
|
||||
@ -145,15 +145,15 @@ static int bgp_reuse_timer(struct thread *t)
|
||||
/* if (figure-of-merit < reuse). */
|
||||
if (bdi->penalty < damp->reuse_limit) {
|
||||
/* Reuse the route. */
|
||||
bgp_info_unset_flag(bdi->rn, bdi->binfo,
|
||||
BGP_INFO_DAMPED);
|
||||
bgp_path_info_unset_flag(bdi->rn, bdi->path,
|
||||
BGP_PATH_DAMPED);
|
||||
bdi->suppress_time = 0;
|
||||
|
||||
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
|
||||
bgp_info_unset_flag(bdi->rn, bdi->binfo,
|
||||
BGP_INFO_HISTORY);
|
||||
bgp_path_info_unset_flag(bdi->rn, bdi->path,
|
||||
BGP_PATH_HISTORY);
|
||||
bgp_aggregate_increment(bgp, &bdi->rn->p,
|
||||
bdi->binfo, bdi->afi,
|
||||
bdi->path, 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). */
|
||||
int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
||||
safi_t safi, int attr_change)
|
||||
int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
|
||||
afi_t afi, safi_t safi, int attr_change)
|
||||
{
|
||||
time_t t_now;
|
||||
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();
|
||||
|
||||
/* Processing Unreachable Messages. */
|
||||
if (binfo->extra)
|
||||
bdi = binfo->extra->damp_info;
|
||||
if (path->extra)
|
||||
bdi = path->extra->damp_info;
|
||||
|
||||
if (bdi == NULL) {
|
||||
/* 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,
|
||||
sizeof(struct bgp_damp_info));
|
||||
bdi->binfo = binfo;
|
||||
bdi->path = path;
|
||||
bdi->rn = rn;
|
||||
bdi->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->afi = afi;
|
||||
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);
|
||||
} else {
|
||||
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++;
|
||||
}
|
||||
|
||||
assert((rn == bdi->rn) && (binfo == bdi->binfo));
|
||||
assert((rn == bdi->rn) && (path == bdi->path));
|
||||
|
||||
bdi->lastrecord = BGP_RECORD_WITHDRAW;
|
||||
bdi->t_updated = t_now;
|
||||
|
||||
/* 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. */
|
||||
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 (bdi->penalty != last_penalty && bdi->index >= 0) {
|
||||
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
|
||||
insert into reuse_list. */
|
||||
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;
|
||||
BGP_DAMP_LIST_DEL(damp, 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
time_t t_now;
|
||||
struct bgp_damp_info *bdi;
|
||||
int status;
|
||||
|
||||
if (!binfo->extra || !((bdi = binfo->extra->damp_info)))
|
||||
if (!path->extra || !((bdi = path->extra->damp_info)))
|
||||
return BGP_DAMP_USED;
|
||||
|
||||
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->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))
|
||||
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)) {
|
||||
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_DAMP_LIST_ADD(damp, bdi);
|
||||
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. */
|
||||
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;
|
||||
struct bgp_damp_info *bdi;
|
||||
|
||||
assert(binfo->extra && binfo->extra->damp_info);
|
||||
assert(path->extra && path->extra->damp_info);
|
||||
|
||||
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;
|
||||
|
||||
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_DAMP_LIST_ADD(damp, bdi);
|
||||
bdi->penalty = damp->reuse_limit;
|
||||
bdi->suppress_time = 0;
|
||||
bdi->t_updated = t_now;
|
||||
|
||||
/* Need to announce UPDATE once this binfo is usable
|
||||
/* Need to announce UPDATE once this path is usable
|
||||
* again. */
|
||||
if (bdi->lastrecord == BGP_RECORD_UPDATE)
|
||||
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);
|
||||
|
||||
if (bdi->penalty <= damp->reuse_limit / 2.0) {
|
||||
/* release the bdi, bdi->binfo. */
|
||||
/* release the bdi, bdi->path. */
|
||||
bgp_damp_info_free(bdi, 1);
|
||||
return 0;
|
||||
} 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)
|
||||
{
|
||||
struct bgp_info *binfo;
|
||||
struct bgp_path_info *path;
|
||||
|
||||
if (!bdi)
|
||||
return;
|
||||
|
||||
binfo = bdi->binfo;
|
||||
binfo->extra->damp_info = NULL;
|
||||
path = bdi->path;
|
||||
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);
|
||||
else
|
||||
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)
|
||||
bgp_info_delete(bdi->rn, binfo);
|
||||
bgp_path_info_delete(bdi->rn, path);
|
||||
|
||||
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
|
||||
}
|
||||
@ -588,7 +590,7 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *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)
|
||||
{
|
||||
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];
|
||||
int penalty;
|
||||
|
||||
if (!binfo->extra)
|
||||
if (!path->extra)
|
||||
return;
|
||||
|
||||
/* BGP dampening information. */
|
||||
bdi = binfo->extra->damp_info;
|
||||
bdi = path->extra->damp_info;
|
||||
|
||||
/* If dampening is not enabled or there is no dampening information,
|
||||
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,
|
||||
json_path);
|
||||
|
||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
|
||||
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
|
||||
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
|
||||
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
|
||||
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
|
||||
json_path);
|
||||
} 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,
|
||||
json_path));
|
||||
|
||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
|
||||
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
|
||||
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
|
||||
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
|
||||
vty_out(vty, ", reuse in %s",
|
||||
bgp_get_reuse_time(penalty, timebuf,
|
||||
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,
|
||||
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;
|
||||
int penalty;
|
||||
|
||||
if (!binfo->extra)
|
||||
if (!path->extra)
|
||||
return NULL;
|
||||
|
||||
/* BGP dampening information. */
|
||||
bdi = binfo->extra->damp_info;
|
||||
bdi = path->extra->damp_info;
|
||||
|
||||
/* If dampening is not enabled or there is no dampening information,
|
||||
return immediately. */
|
||||
|
@ -43,8 +43,8 @@ struct bgp_damp_info {
|
||||
/* Time of route start to be suppressed. */
|
||||
time_t suppress_time;
|
||||
|
||||
/* Back reference to bgp_info. */
|
||||
struct bgp_info *binfo;
|
||||
/* Back reference to bgp_path_info. */
|
||||
struct bgp_path_info *path;
|
||||
|
||||
/* Back reference to bgp_node. */
|
||||
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,
|
||||
unsigned int, time_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,
|
||||
safi_t, int);
|
||||
extern int bgp_damp_update(struct bgp_info *, struct bgp_node *, afi_t, safi_t);
|
||||
extern int bgp_damp_scan(struct bgp_info *, afi_t, safi_t);
|
||||
extern void bgp_damp_info_free(struct bgp_damp_info *, int);
|
||||
extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
|
||||
afi_t afi, safi_t safi, int attr_change);
|
||||
extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn,
|
||||
afi_t afi, safi_t saff);
|
||||
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 int bgp_damp_decay(time_t, int);
|
||||
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);
|
||||
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,
|
||||
bool use_json, json_object *json);
|
||||
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,
|
||||
struct bgp_info *info,
|
||||
unsigned int seq)
|
||||
static struct bgp_path_info *
|
||||
bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
||||
struct bgp_path_info *path, unsigned int seq)
|
||||
{
|
||||
struct stream *obuf;
|
||||
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);
|
||||
|
||||
endp = stream_get_endp(obuf);
|
||||
for (; info; info = info->next) {
|
||||
for (; path; path = path->next) {
|
||||
size_t cur_endp;
|
||||
|
||||
/* Peer index */
|
||||
stream_putw(obuf, info->peer->table_dump_index);
|
||||
stream_putw(obuf, path->peer->table_dump_index);
|
||||
|
||||
/* Originated */
|
||||
stream_putl(obuf, time(NULL) - (bgp_clock() - info->uptime));
|
||||
stream_putl(obuf, time(NULL) - (bgp_clock() - path->uptime));
|
||||
|
||||
/* Dump attribute. */
|
||||
/* 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);
|
||||
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);
|
||||
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,
|
||||
unsigned int seq)
|
||||
{
|
||||
struct bgp_info *info;
|
||||
struct bgp_path_info *path;
|
||||
struct bgp_node *rn;
|
||||
struct bgp *bgp;
|
||||
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];
|
||||
|
||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||
info = rn->info;
|
||||
while (info) {
|
||||
info = bgp_dump_route_node_record(afi, rn, info, seq);
|
||||
path = rn->info;
|
||||
while (path) {
|
||||
path = bgp_dump_route_node_record(afi, rn, path, seq);
|
||||
seq++;
|
||||
}
|
||||
}
|
||||
|
835
bgpd/bgp_evpn.c
835
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. */
|
||||
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_node *rn;
|
||||
|
||||
@ -89,7 +89,7 @@ static inline int is_route_parent_evpn(struct bgp_info *ri)
|
||||
return 0;
|
||||
|
||||
/* 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;
|
||||
if (!rn)
|
||||
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,
|
||||
struct bgp_nlri *packet, int withdraw);
|
||||
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,
|
||||
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_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
||||
struct ethaddr *mac, struct ipaddr *ip);
|
||||
|
@ -536,7 +536,7 @@ static void show_esi_routes(struct bgp *bgp,
|
||||
{
|
||||
int header = 1;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
uint32_t prefix_cnt, path_cnt;
|
||||
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
|
||||
* 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;
|
||||
|
||||
if (json)
|
||||
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)
|
||||
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)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
struct bgp_table *table;
|
||||
int header = 1;
|
||||
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
|
||||
* 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;
|
||||
|
||||
if (vtep_ip.s_addr
|
||||
&& !IPV4_ADDR_SAME(&(vtep_ip),
|
||||
&(ri->attr->nexthop)))
|
||||
&(pi->attr->nexthop)))
|
||||
continue;
|
||||
|
||||
if (json)
|
||||
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)
|
||||
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_node *rn;
|
||||
struct bgp_node *rm;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
int rd_header;
|
||||
int header = 1;
|
||||
|
||||
@ -1046,14 +1046,14 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
||||
tbl_ver = table->version;
|
||||
|
||||
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++;
|
||||
if (type == bgp_show_type_neighbor) {
|
||||
union sockunion *su = output_arg;
|
||||
|
||||
if (ri->peer->su_remote == NULL
|
||||
if (pi->peer->su_remote == NULL
|
||||
|| !sockunion_same(
|
||||
ri->peer->su_remote, su))
|
||||
pi->peer->su_remote, su))
|
||||
continue;
|
||||
}
|
||||
if (header == 0) {
|
||||
@ -1162,14 +1162,14 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
||||
else
|
||||
json_array = NULL;
|
||||
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,
|
||||
json_array);
|
||||
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);
|
||||
else
|
||||
route_vty_out(vty, &rm->p, ri, 0,
|
||||
route_vty_out(vty, &rm->p, pi, 0,
|
||||
SAFI_EVPN, json_array);
|
||||
output_count++;
|
||||
}
|
||||
@ -2017,7 +2017,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
|
||||
struct bgpevpn *vpn;
|
||||
struct prefix_evpn p;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
uint32_t path_cnt = 0;
|
||||
afi_t afi;
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (json)
|
||||
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);
|
||||
|
||||
if (json)
|
||||
@ -2086,7 +2086,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
|
||||
struct bgpevpn *vpn;
|
||||
struct prefix_evpn p;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
uint32_t path_cnt = 0;
|
||||
afi_t afi;
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (json)
|
||||
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);
|
||||
|
||||
if (json)
|
||||
@ -2196,7 +2196,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
|
||||
{
|
||||
struct prefix_evpn p;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
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();
|
||||
|
||||
/* 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;
|
||||
|
||||
if (json)
|
||||
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);
|
||||
|
||||
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_table *table;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
int rd_header = 1;
|
||||
afi_t afi;
|
||||
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();
|
||||
|
||||
/* 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;
|
||||
|
||||
if (json)
|
||||
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);
|
||||
|
||||
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_table *table;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
int header = 1;
|
||||
int rd_header;
|
||||
afi_t afi;
|
||||
@ -2467,7 +2467,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
||||
* fit in
|
||||
* 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;
|
||||
path_cnt++;
|
||||
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)
|
||||
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);
|
||||
|
||||
if (json)
|
||||
|
@ -44,8 +44,8 @@ extern void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
|
||||
json_object *json_path);
|
||||
|
||||
extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
||||
struct bgp_info *binfo,
|
||||
int display, json_object *json_paths);
|
||||
struct bgp_path_info *path, int display,
|
||||
json_object *json_paths);
|
||||
extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
|
||||
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,
|
||||
struct bgp_info *binfo,
|
||||
int display, json_object *json_paths)
|
||||
struct bgp_path_info *path, int display,
|
||||
json_object *json_paths)
|
||||
{
|
||||
struct attr *attr;
|
||||
char return_string[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
|
||||
@ -274,9 +274,9 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
||||
else
|
||||
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",
|
||||
binfo->flags);
|
||||
path->flags);
|
||||
bgp_fs_nlri_get_string((unsigned char *)
|
||||
p->u.prefix_flowspec.ptr,
|
||||
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)
|
||||
json_object_array_add(json_paths, json_nlri_path);
|
||||
}
|
||||
if (!binfo)
|
||||
if (!path)
|
||||
return;
|
||||
if (binfo->attr && binfo->attr->ecommunity) {
|
||||
if (path->attr && path->attr->ecommunity) {
|
||||
/* Print attribute */
|
||||
attr = binfo->attr;
|
||||
attr = path->attr;
|
||||
s = ecommunity_ecom2str(attr->ecommunity,
|
||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||
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));
|
||||
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) {
|
||||
vty_out(vty, "\treceived for %8s\n", timebuf);
|
||||
} 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);
|
||||
}
|
||||
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) {
|
||||
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,
|
||||
unsigned long *output_cum, unsigned long *total_cum)
|
||||
{
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
struct bgp_node *rn;
|
||||
unsigned long total_count = 0;
|
||||
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();
|
||||
display = NLRI_STRING_FORMAT_JSON;
|
||||
}
|
||||
for (ri = rn->info; ri; ri = ri->next) {
|
||||
for (pi = rn->info; pi; pi = pi->next) {
|
||||
total_count++;
|
||||
route_vty_out_flowspec(vty, &rn->p,
|
||||
ri, display,
|
||||
route_vty_out_flowspec(vty, &rn->p, pi, display,
|
||||
json_paths);
|
||||
|
||||
}
|
||||
if (use_json) {
|
||||
vty_out(vty, "%s\n",
|
||||
|
@ -94,18 +94,18 @@ int bgp_parse_fec_update(void)
|
||||
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 *from;
|
||||
mpls_label_t remote_label;
|
||||
int reflect;
|
||||
|
||||
if (!rn || !ri || !to)
|
||||
if (!rn || !pi || !to)
|
||||
return MPLS_INVALID_LABEL;
|
||||
|
||||
remote_label = ri->extra ? ri->extra->label[0] : MPLS_INVALID_LABEL;
|
||||
from = ri->peer;
|
||||
remote_label = pi->extra ? pi->extra->label[0] : MPLS_INVALID_LABEL;
|
||||
from = pi->peer;
|
||||
reflect =
|
||||
((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;
|
||||
}
|
||||
|
||||
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 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_put_prefix(s, p);
|
||||
if (reg) {
|
||||
assert(ri);
|
||||
if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
||||
if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
||||
assert(pi);
|
||||
if (pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
||||
if (pi->attr->label_index != BGP_INVALID_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);
|
||||
|
@ -27,13 +27,13 @@
|
||||
#define BGP_PREVENT_VRF_2_VRF_LEAK 0xFFFFFFFE
|
||||
|
||||
struct bgp_node;
|
||||
struct bgp_info;
|
||||
struct bgp_path_info;
|
||||
struct peer;
|
||||
|
||||
extern void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri,
|
||||
int reg);
|
||||
extern void bgp_reg_dereg_for_label(struct bgp_node *rn,
|
||||
struct bgp_path_info *pi, int reg);
|
||||
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);
|
||||
|
||||
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,
|
||||
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)
|
||||
|
316
bgpd/bgp_mpath.c
316
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,
|
||||
* or greater than zero if bi1 is respectively less than, equal to,
|
||||
* or greater than bi2.
|
||||
* or greater than zero if bpi1 is respectively less than, equal to,
|
||||
* 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;
|
||||
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 (bi1->attr->mp_nexthop_len == bi2->attr->mp_nexthop_len) {
|
||||
switch (bi1->attr->mp_nexthop_len) {
|
||||
if (bpi1->attr->mp_nexthop_len == bpi2->attr->mp_nexthop_len) {
|
||||
switch (bpi1->attr->mp_nexthop_len) {
|
||||
case BGP_ATTR_NHLEN_IPV4:
|
||||
case BGP_ATTR_NHLEN_VPNV4:
|
||||
compare = IPV4_ADDR_CMP(
|
||||
&bi1->attr->mp_nexthop_global_in,
|
||||
&bi2->attr->mp_nexthop_global_in);
|
||||
&bpi1->attr->mp_nexthop_global_in,
|
||||
&bpi2->attr->mp_nexthop_global_in);
|
||||
break;
|
||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
|
||||
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
|
||||
compare = IPV6_ADDR_CMP(
|
||||
&bi1->attr->mp_nexthop_global,
|
||||
&bi2->attr->mp_nexthop_global);
|
||||
&bpi1->attr->mp_nexthop_global,
|
||||
&bpi2->attr->mp_nexthop_global);
|
||||
break;
|
||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
||||
addr1 = (bi1->attr->mp_nexthop_prefer_global)
|
||||
? bi1->attr->mp_nexthop_global
|
||||
: bi1->attr->mp_nexthop_local;
|
||||
addr2 = (bi2->attr->mp_nexthop_prefer_global)
|
||||
? bi2->attr->mp_nexthop_global
|
||||
: bi2->attr->mp_nexthop_local;
|
||||
addr1 = (bpi1->attr->mp_nexthop_prefer_global)
|
||||
? bpi1->attr->mp_nexthop_global
|
||||
: bpi1->attr->mp_nexthop_local;
|
||||
addr2 = (bpi2->attr->mp_nexthop_prefer_global)
|
||||
? bpi2->attr->mp_nexthop_global
|
||||
: bpi2->attr->mp_nexthop_local;
|
||||
|
||||
if (!bi1->attr->mp_nexthop_prefer_global
|
||||
&& !bi2->attr->mp_nexthop_prefer_global)
|
||||
if (!bpi1->attr->mp_nexthop_prefer_global
|
||||
&& !bpi2->attr->mp_nexthop_prefer_global)
|
||||
compare = !bgp_interface_same(
|
||||
bi1->peer->ifp, bi2->peer->ifp);
|
||||
bpi1->peer->ifp,
|
||||
bpi2->peer->ifp);
|
||||
|
||||
if (!compare)
|
||||
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
|
||||
* nexthops but another IPv6 peer only sends you global
|
||||
*/
|
||||
else if (bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
|
||||
|| bi1->attr->mp_nexthop_len
|
||||
else if (bpi1->attr->mp_nexthop_len
|
||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL
|
||||
|| bpi1->attr->mp_nexthop_len
|
||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
||||
compare = IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global,
|
||||
&bi2->attr->mp_nexthop_global);
|
||||
compare = IPV6_ADDR_CMP(&bpi1->attr->mp_nexthop_global,
|
||||
&bpi2->attr->mp_nexthop_global);
|
||||
if (!compare) {
|
||||
if (bi1->attr->mp_nexthop_len
|
||||
< bi2->attr->mp_nexthop_len)
|
||||
if (bpi1->attr->mp_nexthop_len
|
||||
< bpi2->attr->mp_nexthop_len)
|
||||
compare = -1;
|
||||
else
|
||||
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
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
bi1 = val1;
|
||||
bi2 = val2;
|
||||
bpi1 = val1;
|
||||
bpi2 = val2;
|
||||
|
||||
compare = bgp_info_nexthop_cmp(bi1, bi2);
|
||||
compare = bgp_path_info_nexthop_cmp(bpi1, bpi2);
|
||||
|
||||
if (!compare) {
|
||||
if (!bi1->peer->su_remote && !bi2->peer->su_remote)
|
||||
if (!bpi1->peer->su_remote && !bpi2->peer->su_remote)
|
||||
compare = 0;
|
||||
else if (!bi1->peer->su_remote)
|
||||
else if (!bpi1->peer->su_remote)
|
||||
compare = 1;
|
||||
else if (!bi2->peer->su_remote)
|
||||
else if (!bpi2->peer->su_remote)
|
||||
compare = -1;
|
||||
else
|
||||
compare = sockunion_cmp(bi1->peer->su_remote,
|
||||
bi2->peer->su_remote);
|
||||
compare = sockunion_cmp(bpi1->peer->su_remote,
|
||||
bpi2->peer->su_remote);
|
||||
}
|
||||
|
||||
return compare;
|
||||
@ -228,7 +231,7 @@ void bgp_mp_list_init(struct list *mp_list)
|
||||
{
|
||||
assert(mp_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
|
||||
*/
|
||||
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);
|
||||
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;
|
||||
new_mpath =
|
||||
XCALLOC(MTYPE_BGP_MPATH_INFO, sizeof(struct bgp_info_mpath));
|
||||
struct bgp_path_info_mpath *new_mpath;
|
||||
new_mpath = XCALLOC(MTYPE_BGP_MPATH_INFO,
|
||||
sizeof(struct bgp_path_info_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)->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.
|
||||
*/
|
||||
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;
|
||||
if (!binfo->mpath) {
|
||||
mpath = bgp_info_mpath_new();
|
||||
struct bgp_path_info_mpath *mpath;
|
||||
if (!path->mpath) {
|
||||
mpath = bgp_path_info_mpath_new();
|
||||
if (!mpath)
|
||||
return NULL;
|
||||
binfo->mpath = mpath;
|
||||
mpath->mp_info = binfo;
|
||||
path->mpath = mpath;
|
||||
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
|
||||
* list entry
|
||||
*/
|
||||
static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
|
||||
struct bgp_info *binfo)
|
||||
static void bgp_path_info_mpath_enqueue(struct bgp_path_info *prev_info,
|
||||
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);
|
||||
mpath = bgp_info_mpath_get(binfo);
|
||||
prev = bgp_path_info_mpath_get(prev_info);
|
||||
mpath = bgp_path_info_mpath_get(path);
|
||||
if (!prev || !mpath)
|
||||
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 = 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
|
||||
*/
|
||||
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)
|
||||
return;
|
||||
if (mpath->mp_prev)
|
||||
@ -340,101 +344,105 @@ void bgp_info_mpath_dequeue(struct bgp_info *binfo)
|
||||
if (mpath->mp_next)
|
||||
mpath->mp_next->mp_prev = mpath->mp_prev;
|
||||
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 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 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
|
||||
*/
|
||||
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;
|
||||
if (!count && !binfo->mpath)
|
||||
struct bgp_path_info_mpath *mpath;
|
||||
if (!count && !path->mpath)
|
||||
return;
|
||||
mpath = bgp_info_mpath_get(binfo);
|
||||
mpath = bgp_path_info_mpath_get(path);
|
||||
if (!mpath)
|
||||
return;
|
||||
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
|
||||
*/
|
||||
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 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
|
||||
*/
|
||||
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;
|
||||
if (!attr && !binfo->mpath)
|
||||
struct bgp_path_info_mpath *mpath;
|
||||
if (!attr && !path->mpath)
|
||||
return;
|
||||
mpath = bgp_info_mpath_get(binfo);
|
||||
mpath = bgp_path_info_mpath_get(path);
|
||||
if (!mpath)
|
||||
return;
|
||||
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
|
||||
* bgp_best_selection
|
||||
*/
|
||||
void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
||||
struct bgp_info *old_best, struct list *mp_list,
|
||||
struct bgp_maxpaths_cfg *mpath_cfg)
|
||||
void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
struct bgp_path_info *new_best,
|
||||
struct bgp_path_info *old_best,
|
||||
struct list *mp_list,
|
||||
struct bgp_maxpaths_cfg *mpath_cfg)
|
||||
{
|
||||
uint16_t maxpaths, mpath_count, old_mpath_count;
|
||||
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;
|
||||
char pfx_buf[PREFIX2STR_BUFFER], nh_buf[2][INET6_ADDRSTRLEN];
|
||||
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) {
|
||||
mpath_count++;
|
||||
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)
|
||||
? mpath_cfg->maxpaths_ibgp
|
||||
: mpath_cfg->maxpaths_ebgp;
|
||||
}
|
||||
|
||||
if (old_best) {
|
||||
cur_mpath = bgp_info_mpath_first(old_best);
|
||||
old_mpath_count = bgp_info_mpath_count(old_best);
|
||||
bgp_info_mpath_count_set(old_best, 0);
|
||||
bgp_info_mpath_dequeue(old_best);
|
||||
cur_mpath = bgp_path_info_mpath_first(old_best);
|
||||
old_mpath_count = bgp_path_info_mpath_count(old_best);
|
||||
bgp_path_info_mpath_count_set(old_best, 0);
|
||||
bgp_path_info_mpath_dequeue(old_best);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
@ -485,7 +493,7 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
||||
* to skip over it
|
||||
*/
|
||||
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
|
||||
@ -496,7 +504,8 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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)) {
|
||||
list_delete_node(mp_list, mp_node);
|
||||
bgp_info_mpath_dequeue(cur_mpath);
|
||||
bgp_path_info_mpath_dequeue(cur_mpath);
|
||||
if ((mpath_count < maxpaths)
|
||||
&& bgp_info_nexthop_cmp(prev_mpath, cur_mpath)) {
|
||||
bgp_info_mpath_enqueue(prev_mpath, cur_mpath);
|
||||
&& bgp_path_info_nexthop_cmp(prev_mpath,
|
||||
cur_mpath)) {
|
||||
bgp_path_info_mpath_enqueue(prev_mpath,
|
||||
cur_mpath);
|
||||
prev_mpath = cur_mpath;
|
||||
mpath_count++;
|
||||
if (debug) {
|
||||
bgp_info_path_with_addpath_rx_str(
|
||||
bgp_path_info_path_with_addpath_rx_str(
|
||||
cur_mpath, path_buf);
|
||||
zlog_debug(
|
||||
"%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 {
|
||||
mpath_changed = 1;
|
||||
if (debug) {
|
||||
bgp_info_path_with_addpath_rx_str(
|
||||
bgp_path_info_path_with_addpath_rx_str(
|
||||
cur_mpath, path_buf);
|
||||
zlog_debug(
|
||||
"%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
|
||||
&& (!mp_node
|
||||
|| (bgp_info_mpath_cmp(cur_mpath, listgetdata(mp_node))
|
||||
|| (bgp_path_info_mpath_cmp(cur_mpath,
|
||||
listgetdata(mp_node))
|
||||
< 0))) {
|
||||
/*
|
||||
* 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 list
|
||||
*/
|
||||
bgp_info_mpath_dequeue(cur_mpath);
|
||||
bgp_path_info_mpath_dequeue(cur_mpath);
|
||||
mpath_changed = 1;
|
||||
if (debug) {
|
||||
bgp_info_path_with_addpath_rx_str(cur_mpath,
|
||||
path_buf);
|
||||
bgp_path_info_path_with_addpath_rx_str(
|
||||
cur_mpath, path_buf);
|
||||
zlog_debug(
|
||||
"%s: remove mpath %s nexthop %s, cur count %d",
|
||||
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(prev_mpath);
|
||||
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)
|
||||
bgp_info_mpath_next(new_mpath);
|
||||
bgp_info_mpath_dequeue(new_mpath);
|
||||
bgp_path_info_mpath_next(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;
|
||||
mpath_changed = 1;
|
||||
mpath_count++;
|
||||
if (debug) {
|
||||
bgp_info_path_with_addpath_rx_str(
|
||||
bgp_path_info_path_with_addpath_rx_str(
|
||||
new_mpath, path_buf);
|
||||
zlog_debug(
|
||||
"%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,
|
||||
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
|
||||
|| (bgp_info_mpath_count(new_best) != old_mpath_count))
|
||||
SET_FLAG(new_best->flags, BGP_INFO_MULTIPATH_CHG);
|
||||
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
|
||||
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
return;
|
||||
|
||||
for (mpinfo = bgp_info_mpath_first(dmed_best); mpinfo;
|
||||
for (mpinfo = bgp_path_info_mpath_first(dmed_best); mpinfo;
|
||||
mpinfo = mpnext) {
|
||||
mpnext = bgp_info_mpath_next(mpinfo);
|
||||
bgp_info_mpath_dequeue(mpinfo);
|
||||
mpnext = bgp_path_info_mpath_next(mpinfo);
|
||||
bgp_path_info_mpath_dequeue(mpinfo);
|
||||
}
|
||||
|
||||
bgp_info_mpath_count_set(dmed_best, 0);
|
||||
UNSET_FLAG(dmed_best->flags, BGP_INFO_MULTIPATH_CHG);
|
||||
assert(bgp_info_mpath_first(dmed_best) == 0);
|
||||
bgp_path_info_mpath_count_set(dmed_best, 0);
|
||||
UNSET_FLAG(dmed_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
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
|
||||
* 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
|
||||
* any multipath.
|
||||
*/
|
||||
void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
||||
struct bgp_info *old_best)
|
||||
void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
|
||||
struct bgp_path_info *old_best)
|
||||
{
|
||||
struct bgp_info *mpinfo;
|
||||
struct bgp_path_info *mpinfo;
|
||||
struct aspath *aspath;
|
||||
struct aspath *asmerge;
|
||||
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};
|
||||
|
||||
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_info_mpath_attr_set(old_best, NULL);
|
||||
bgp_path_info_mpath_attr_set(old_best, NULL);
|
||||
}
|
||||
|
||||
if (!new_best)
|
||||
return;
|
||||
|
||||
if (!bgp_info_mpath_count(new_best)) {
|
||||
if ((new_attr = bgp_info_mpath_attr(new_best))) {
|
||||
if (!bgp_path_info_mpath_count(new_best)) {
|
||||
if ((new_attr = bgp_path_info_mpath_attr(new_best))) {
|
||||
bgp_attr_unintern(&new_attr);
|
||||
bgp_info_mpath_attr_set(new_best, NULL);
|
||||
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
|
||||
bgp_path_info_mpath_attr_set(new_best, NULL);
|
||||
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -718,8 +732,8 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
||||
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
|
||||
: NULL;
|
||||
|
||||
for (mpinfo = bgp_info_mpath_first(new_best); mpinfo;
|
||||
mpinfo = bgp_info_mpath_next(mpinfo)) {
|
||||
for (mpinfo = bgp_path_info_mpath_first(new_best); mpinfo;
|
||||
mpinfo = bgp_path_info_mpath_next(mpinfo)) {
|
||||
asmerge =
|
||||
aspath_aggregate(aspath, mpinfo->attr->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);
|
||||
|
||||
if (new_attr != bgp_info_mpath_attr(new_best)) {
|
||||
if ((old_attr = bgp_info_mpath_attr(new_best)))
|
||||
if (new_attr != bgp_path_info_mpath_attr(new_best)) {
|
||||
if ((old_attr = bgp_path_info_mpath_attr(new_best)))
|
||||
bgp_attr_unintern(&old_attr);
|
||||
bgp_info_mpath_attr_set(new_best, new_attr);
|
||||
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
|
||||
bgp_path_info_mpath_attr_set(new_best, new_attr);
|
||||
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
|
||||
} else
|
||||
bgp_attr_unintern(&new_attr);
|
||||
}
|
||||
|
@ -22,18 +22,18 @@
|
||||
#ifndef _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
|
||||
*/
|
||||
struct bgp_info_mpath {
|
||||
struct bgp_path_info_mpath {
|
||||
/* 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 */
|
||||
struct bgp_info_mpath *mp_prev;
|
||||
struct bgp_path_info_mpath *mp_prev;
|
||||
|
||||
/* Points to bgp_info associated with this multipath info */
|
||||
struct bgp_info *mp_info;
|
||||
/* Points to bgp_path_info associated with this multipath info */
|
||||
struct bgp_path_info *mp_info;
|
||||
|
||||
/* When attached to best path, the number of selected multipaths */
|
||||
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
|
||||
* 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_clear(struct list *);
|
||||
extern void bgp_mp_list_add(struct list *, struct bgp_info *);
|
||||
extern void bgp_mp_dmed_deselect(struct bgp_info *);
|
||||
extern void bgp_info_mpath_update(struct bgp_node *, struct bgp_info *,
|
||||
struct bgp_info *, struct list *,
|
||||
struct bgp_maxpaths_cfg *);
|
||||
extern void bgp_info_mpath_aggregate_update(struct bgp_info *,
|
||||
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_path_info *dmed_best);
|
||||
extern void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
struct bgp_path_info *new_best,
|
||||
struct bgp_path_info *old_best,
|
||||
struct list *mp_list,
|
||||
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 */
|
||||
extern void bgp_info_mpath_dequeue(struct bgp_info *);
|
||||
extern void bgp_info_mpath_free(struct bgp_info_mpath **);
|
||||
/* Unlink and free multipath information associated with a bgp_path_info */
|
||||
extern void bgp_path_info_mpath_dequeue(struct bgp_path_info *path);
|
||||
extern void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath);
|
||||
|
||||
/* Walk list of multipaths associated with a best path */
|
||||
extern struct bgp_info *bgp_info_mpath_first(struct bgp_info *);
|
||||
extern struct bgp_info *bgp_info_mpath_next(struct bgp_info *);
|
||||
extern struct bgp_path_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 */
|
||||
extern uint32_t bgp_info_mpath_count(struct bgp_info *);
|
||||
extern struct attr *bgp_info_mpath_attr(struct bgp_info *);
|
||||
extern uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path);
|
||||
extern struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path);
|
||||
|
||||
#endif /* _QUAGGA_BGP_MPATH_H */
|
||||
|
@ -402,22 +402,23 @@ static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
|
||||
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;
|
||||
|
||||
if (!bi->extra) {
|
||||
if (!bpi->extra) {
|
||||
if (!n)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n != bi->extra->num_labels)
|
||||
if (n != bpi->extra->num_labels)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (label[i] != bi->extra->label[i])
|
||||
if (label[i] != bpi->extra->label[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -426,22 +427,21 @@ static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
|
||||
/*
|
||||
* make encoded route labels match specified encoded label set
|
||||
*/
|
||||
static void setlabels(
|
||||
struct bgp_info *bi,
|
||||
mpls_label_t *label, /* array of labels */
|
||||
uint32_t num_labels)
|
||||
static void setlabels(struct bgp_path_info *bpi,
|
||||
mpls_label_t *label, /* array of labels */
|
||||
uint32_t num_labels)
|
||||
{
|
||||
if (num_labels)
|
||||
assert(label);
|
||||
assert(num_labels <= BGP_MAX_LABELS);
|
||||
|
||||
if (!num_labels) {
|
||||
if (bi->extra)
|
||||
bi->extra->num_labels = 0;
|
||||
if (bpi->extra)
|
||||
bpi->extra->num_labels = 0;
|
||||
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;
|
||||
|
||||
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 *
|
||||
leak_update(
|
||||
struct bgp *bgp, /* destination bgp instance */
|
||||
struct bgp_node *bn,
|
||||
struct attr *new_attr, /* already interned */
|
||||
afi_t afi,
|
||||
safi_t safi,
|
||||
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)
|
||||
static struct bgp_path_info *
|
||||
leak_update(struct bgp *bgp, /* destination bgp instance */
|
||||
struct bgp_node *bn, struct attr *new_attr, /* already interned */
|
||||
afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
|
||||
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 bgp_info *bi;
|
||||
struct bgp_info *bi_ultimate;
|
||||
struct bgp_info *new;
|
||||
struct bgp_path_info *bpi;
|
||||
struct bgp_path_info *bpi_ultimate;
|
||||
struct bgp_path_info *new;
|
||||
char buf_prefix[PREFIX_STRLEN];
|
||||
|
||||
if (debug) {
|
||||
prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
|
||||
zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
|
||||
__func__, bgp->name_pretty, buf_prefix,
|
||||
source_bi->type, source_bi->sub_type);
|
||||
__func__, bgp->name_pretty, buf_prefix,
|
||||
source_bpi->type, source_bpi->sub_type);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -494,31 +486,30 @@ leak_update(
|
||||
* should have nexthop tracking, we must find the ultimate
|
||||
* 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).
|
||||
* Using a loop here supports more complex intra-bgp import-export
|
||||
* schemes that could be implemented in the future.
|
||||
*
|
||||
*/
|
||||
for (bi_ultimate = source_bi;
|
||||
bi_ultimate->extra && bi_ultimate->extra->parent;
|
||||
bi_ultimate = bi_ultimate->extra->parent)
|
||||
;
|
||||
for (bpi_ultimate = source_bpi;
|
||||
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
||||
bpi_ultimate = bpi_ultimate->extra->parent)
|
||||
;
|
||||
|
||||
/*
|
||||
* match parent
|
||||
*/
|
||||
for (bi = bn->info; bi; bi = bi->next) {
|
||||
if (bi->extra && bi->extra->parent == parent)
|
||||
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||
if (bpi->extra && bpi->extra->parent == parent)
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi) {
|
||||
bool labelssame = labels_same(bi, label, num_labels);
|
||||
if (bpi) {
|
||||
bool labelssame = labels_same(bpi, label, num_labels);
|
||||
|
||||
if (attrhash_cmp(bi->attr, new_attr)
|
||||
&& labelssame
|
||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
||||
if (attrhash_cmp(bpi->attr, new_attr) && labelssame
|
||||
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||
|
||||
bgp_attr_unintern(&new_attr);
|
||||
if (debug)
|
||||
@ -530,43 +521,42 @@ leak_update(
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
||||
bgp_info_restore(bn, bi);
|
||||
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||
bgp_path_info_restore(bn, bpi);
|
||||
else
|
||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
||||
bgp_attr_unintern(&bi->attr);
|
||||
bi->attr = new_attr;
|
||||
bi->uptime = bgp_clock();
|
||||
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||
bgp_attr_unintern(&bpi->attr);
|
||||
bpi->attr = new_attr;
|
||||
bpi->uptime = bgp_clock();
|
||||
|
||||
/*
|
||||
* rewrite labels
|
||||
*/
|
||||
if (!labelssame)
|
||||
setlabels(bi, label, num_labels);
|
||||
setlabels(bpi, label, num_labels);
|
||||
|
||||
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;
|
||||
int nh_valid;
|
||||
|
||||
if (bi->extra && bi->extra->bgp_orig)
|
||||
bgp_nexthop = bi->extra->bgp_orig;
|
||||
if (bpi->extra && bpi->extra->bgp_orig)
|
||||
bgp_nexthop = bpi->extra->bgp_orig;
|
||||
|
||||
/* 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;
|
||||
else
|
||||
/*
|
||||
* TBD do we need to do anything about the
|
||||
* 'connected' parameter?
|
||||
*/
|
||||
nh_valid = bgp_find_or_add_nexthop(
|
||||
bgp, bgp_nexthop,
|
||||
afi, bi, NULL, 0);
|
||||
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
|
||||
afi, bpi, NULL, 0);
|
||||
|
||||
if (debug)
|
||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||
@ -574,10 +564,10 @@ leak_update(
|
||||
bgp_nexthop->name_pretty);
|
||||
|
||||
if (nh_valid)
|
||||
bgp_info_set_flag(bn, bi, BGP_INFO_VALID);
|
||||
bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
|
||||
|
||||
/* 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_unlock_node(bn);
|
||||
|
||||
@ -585,22 +575,22 @@ leak_update(
|
||||
zlog_debug("%s: ->%s: %s Found route, changed attr",
|
||||
__func__, bgp->name_pretty, buf_prefix);
|
||||
|
||||
return bi;
|
||||
return bpi;
|
||||
}
|
||||
|
||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
|
||||
bgp->peer_self, new_attr, bn);
|
||||
|
||||
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)
|
||||
setlabels(new, label, num_labels);
|
||||
|
||||
new->extra->parent = bgp_info_lock(parent);
|
||||
bgp_lock_node((struct bgp_node *)((struct bgp_info *)parent)->net);
|
||||
new->extra->parent = bgp_path_info_lock(parent);
|
||||
bgp_lock_node((struct bgp_node *)((struct bgp_path_info *)parent)->net);
|
||||
if (bgp_orig)
|
||||
new->extra->bgp_orig = bgp_lock(bgp_orig);
|
||||
if (nexthop_orig)
|
||||
@ -620,7 +610,7 @@ leak_update(
|
||||
* their originating protocols will do the tracking and
|
||||
* 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;
|
||||
else
|
||||
/*
|
||||
@ -635,10 +625,10 @@ leak_update(
|
||||
__func__, (nh_valid ? "" : "not "),
|
||||
bgp_nexthop->name_pretty);
|
||||
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_info_add(bn, new);
|
||||
bgp_path_info_add(bn, new);
|
||||
|
||||
bgp_unlock_node(bn);
|
||||
bgp_process(bgp, bn, afi, safi);
|
||||
@ -651,12 +641,12 @@ leak_update(
|
||||
}
|
||||
|
||||
/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
|
||||
void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||
struct bgp *bgp_vrf, /* from */
|
||||
struct bgp_info *info_vrf) /* route */
|
||||
void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||
struct bgp *bgp_vrf, /* from */
|
||||
struct bgp_path_info *path_vrf) /* route */
|
||||
{
|
||||
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);
|
||||
struct attr static_attr = {0};
|
||||
struct attr *new_attr = NULL;
|
||||
@ -670,12 +660,12 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||
if (debug)
|
||||
zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
|
||||
|
||||
if (debug && info_vrf->attr->ecommunity) {
|
||||
char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
|
||||
if (debug && path_vrf->attr->ecommunity) {
|
||||
char *s = ecommunity_ecom2str(path_vrf->attr->ecommunity,
|
||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||
|
||||
zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__,
|
||||
bgp_vrf->name, info_vrf->type, s);
|
||||
zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
|
||||
bgp_vrf->name, path_vrf->type, 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. */
|
||||
if (info_vrf->extra && info_vrf->extra->bgp_orig)
|
||||
if (path_vrf->extra && path_vrf->extra->bgp_orig)
|
||||
return;
|
||||
|
||||
|
||||
@ -700,13 +690,13 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||
return;
|
||||
}
|
||||
|
||||
bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
|
||||
bgp_attr_dup(&static_attr, path_vrf->attr); /* shallow copy */
|
||||
|
||||
/*
|
||||
* route map handling
|
||||
*/
|
||||
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;
|
||||
|
||||
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
|
||||
* otherwise.
|
||||
*/
|
||||
if (afi == AFI_IP &&
|
||||
!BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf->attr)) {
|
||||
if (afi == AFI_IP
|
||||
&& !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
|
||||
static_attr.mp_nexthop_global_in.s_addr =
|
||||
static_attr.nexthop.s_addr;
|
||||
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,
|
||||
&(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,
|
||||
&label, 1, info_vrf, bgp_vrf, NULL,
|
||||
new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, path_vrf,
|
||||
&label, 1, path_vrf, bgp_vrf, NULL,
|
||||
nexthop_self_flag, debug);
|
||||
|
||||
/*
|
||||
@ -878,15 +868,15 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||
vpn_leak_to_vrf_update(bgp_vrf, new_info);
|
||||
}
|
||||
|
||||
void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
||||
struct bgp *bgp_vrf, /* from */
|
||||
struct bgp_info *info_vrf) /* route */
|
||||
void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
||||
struct bgp *bgp_vrf, /* from */
|
||||
struct bgp_path_info *path_vrf) /* route */
|
||||
{
|
||||
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);
|
||||
safi_t safi = SAFI_MPLS_VPN;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
struct bgp_node *bn;
|
||||
const char *debugmsg;
|
||||
char buf_prefix[PREFIX_STRLEN];
|
||||
@ -896,16 +886,16 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
||||
zlog_debug(
|
||||
"%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
|
||||
__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
|
||||
&& info_vrf->sub_type != BGP_ROUTE_STATIC
|
||||
&& info_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
|
||||
if (path_vrf->sub_type != BGP_ROUTE_NORMAL
|
||||
&& path_vrf->sub_type != BGP_ROUTE_STATIC
|
||||
&& path_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
|
||||
|
||||
if (debug)
|
||||
zlog_debug("%s: wrong sub_type %d", __func__,
|
||||
info_vrf->sub_type);
|
||||
path_vrf->sub_type);
|
||||
return;
|
||||
}
|
||||
if (!bgp_vpn)
|
||||
@ -924,27 +914,27 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
||||
}
|
||||
|
||||
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,
|
||||
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
||||
|
||||
/*
|
||||
* vrf -> vpn
|
||||
* match original bi imported from
|
||||
* match original bpi imported from
|
||||
*/
|
||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
||||
if (bi->extra && bi->extra->parent == info_vrf) {
|
||||
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||
if (bpi->extra && bpi->extra->parent == path_vrf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bi) {
|
||||
if (bpi) {
|
||||
/* 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_info_delete(bn, bi);
|
||||
bgp_aggregate_decrement(bgp_vpn, p, bpi, afi, safi);
|
||||
bgp_path_info_delete(bn, bpi);
|
||||
bgp_process(bgp_vpn, bn, afi, safi);
|
||||
}
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
prn = bgp_route_next(prn)) {
|
||||
|
||||
struct bgp_table *table;
|
||||
struct bgp_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
|
||||
/* This is the per-RD table of prefixes */
|
||||
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)));
|
||||
}
|
||||
|
||||
for (bi = bn->info; bi; bi = bi->next) {
|
||||
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||
if (debug)
|
||||
zlog_debug("%s: type %d, sub_type %d",
|
||||
__func__, bi->type,
|
||||
bi->sub_type);
|
||||
if (bi->sub_type != BGP_ROUTE_IMPORTED)
|
||||
__func__, bpi->type,
|
||||
bpi->sub_type);
|
||||
if (bpi->sub_type != BGP_ROUTE_IMPORTED)
|
||||
continue;
|
||||
if (!bi->extra)
|
||||
if (!bpi->extra)
|
||||
continue;
|
||||
if ((struct bgp *)bi->extra->bgp_orig
|
||||
if ((struct bgp *)bpi->extra->bgp_orig
|
||||
== bgp_vrf) {
|
||||
/* delete route */
|
||||
if (debug)
|
||||
zlog_debug("%s: deleting it\n",
|
||||
__func__);
|
||||
bgp_aggregate_decrement(bgp_vpn, &bn->p,
|
||||
bi, afi, safi);
|
||||
bgp_info_delete(bn, bi);
|
||||
bpi, afi, safi);
|
||||
bgp_path_info_delete(bn, bpi);
|
||||
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)
|
||||
{
|
||||
struct bgp_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||
|
||||
if (debug)
|
||||
@ -1027,21 +1017,22 @@ void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
|
||||
if (debug)
|
||||
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)
|
||||
zlog_debug(
|
||||
"%s: calling vpn_leak_from_vrf_update",
|
||||
__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 */
|
||||
struct bgp *bgp_vpn, /* from */
|
||||
struct bgp_info *info_vpn) /* route */
|
||||
static void
|
||||
vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
||||
struct bgp *bgp_vpn, /* from */
|
||||
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);
|
||||
|
||||
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;
|
||||
uint32_t num_labels = 0;
|
||||
int nexthop_self_flag = 1;
|
||||
struct bgp_info *bi_ultimate = NULL;
|
||||
struct bgp_path_info *bpi_ultimate = NULL;
|
||||
int origin_local = 0;
|
||||
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 */
|
||||
if (!ecom_intersect(
|
||||
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
||||
info_vpn->attr->ecommunity)) {
|
||||
path_vpn->attr->ecommunity)) {
|
||||
|
||||
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__,
|
||||
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
|
||||
@ -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
|
||||
* 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)
|
||||
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) {
|
||||
case AF_INET:
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
|
||||
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 =
|
||||
info_vpn->attr->mp_nexthop_len;
|
||||
path_vpn->attr->mp_nexthop_len;
|
||||
}
|
||||
break;
|
||||
case AF_INET6:
|
||||
/* 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;
|
||||
|
||||
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
|
||||
*/
|
||||
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;
|
||||
|
||||
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],
|
||||
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
|
||||
/* work back to original route */
|
||||
for (bi_ultimate = info_vpn;
|
||||
bi_ultimate->extra && bi_ultimate->extra->parent;
|
||||
bi_ultimate = bi_ultimate->extra->parent)
|
||||
for (bpi_ultimate = path_vpn;
|
||||
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
||||
bpi_ultimate = bpi_ultimate->extra->parent)
|
||||
;
|
||||
|
||||
/*
|
||||
* if original route was unicast,
|
||||
* then it did not arrive over vpn
|
||||
*/
|
||||
if (bi_ultimate->net) {
|
||||
if (bpi_ultimate->net) {
|
||||
struct bgp_table *table;
|
||||
|
||||
table = bgp_node_table(bi_ultimate->net);
|
||||
table = bgp_node_table(bpi_ultimate->net);
|
||||
if (table && (table->safi == SAFI_UNICAST))
|
||||
origin_local = 1;
|
||||
}
|
||||
|
||||
/* copy labels */
|
||||
if (!origin_local &&
|
||||
info_vpn->extra && info_vpn->extra->num_labels) {
|
||||
num_labels = info_vpn->extra->num_labels;
|
||||
if (!origin_local && path_vpn->extra
|
||||
&& path_vpn->extra->num_labels) {
|
||||
num_labels = path_vpn->extra->num_labels;
|
||||
if (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,
|
||||
* the source will be the originating VRF.
|
||||
*/
|
||||
if (info_vpn->extra && info_vpn->extra->bgp_orig)
|
||||
src_vrf = info_vpn->extra->bgp_orig;
|
||||
if (path_vpn->extra && path_vpn->extra->bgp_orig)
|
||||
src_vrf = path_vpn->extra->bgp_orig;
|
||||
else
|
||||
src_vrf = bgp_vpn;
|
||||
|
||||
leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
|
||||
pLabels, num_labels,
|
||||
info_vpn, /* parent */
|
||||
src_vrf, &nexthop_orig, nexthop_self_flag, debug);
|
||||
leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
|
||||
num_labels, path_vpn, /* parent */
|
||||
src_vrf, &nexthop_orig, nexthop_self_flag, debug);
|
||||
}
|
||||
|
||||
void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
||||
struct bgp_info *info_vpn) /* route */
|
||||
void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
||||
struct bgp_path_info *path_vpn) /* route */
|
||||
{
|
||||
struct listnode *mnode, *mnnode;
|
||||
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);
|
||||
|
||||
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 */
|
||||
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
||||
|
||||
if (!info_vpn->extra
|
||||
|| info_vpn->extra->bgp_orig != bgp) { /* no loop */
|
||||
vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
|
||||
if (!path_vpn->extra
|
||||
|| path_vpn->extra->bgp_orig != bgp) { /* no loop */
|
||||
vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||
struct bgp_info *info_vpn) /* route */
|
||||
void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||
struct bgp_path_info *path_vpn) /* route */
|
||||
{
|
||||
struct prefix *p;
|
||||
afi_t afi;
|
||||
@ -1253,38 +1243,38 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||
struct bgp *bgp;
|
||||
struct listnode *mnode, *mnnode;
|
||||
struct bgp_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
const char *debugmsg;
|
||||
char buf_prefix[PREFIX_STRLEN];
|
||||
|
||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||
|
||||
if (debug) {
|
||||
prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
|
||||
zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
|
||||
__func__, buf_prefix,
|
||||
info_vpn->type, info_vpn->sub_type);
|
||||
prefix2str(&path_vpn->net->p, buf_prefix, sizeof(buf_prefix));
|
||||
zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__,
|
||||
buf_prefix, path_vpn->type, path_vpn->sub_type);
|
||||
}
|
||||
|
||||
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
|
||||
/* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
|
||||
if (info_vpn->type == ZEBRA_ROUTE_BGP &&
|
||||
info_vpn->sub_type == BGP_ROUTE_RFP) {
|
||||
/* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
|
||||
if (path_vpn->type == ZEBRA_ROUTE_BGP
|
||||
&& path_vpn->sub_type == BGP_ROUTE_RFP) {
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
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__);
|
||||
return;
|
||||
}
|
||||
|
||||
p = &info_vpn->net->p;
|
||||
p = &path_vpn->net->p;
|
||||
afi = family2afi(p->family);
|
||||
|
||||
/* Loop over VRFs */
|
||||
@ -1299,7 +1289,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||
/* Check for intersection of route targets */
|
||||
if (!ecom_intersect(bgp->vpn_policy[afi]
|
||||
.rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
||||
info_vpn->attr->ecommunity)) {
|
||||
path_vpn->attr->ecommunity)) {
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -1309,19 +1299,20 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||
bgp->name_pretty);
|
||||
|
||||
bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
|
||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
||||
if (bi->extra
|
||||
&& (struct bgp_info *)bi->extra->parent
|
||||
== info_vpn) {
|
||||
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||
if (bpi->extra
|
||||
&& (struct bgp_path_info *)bpi->extra->parent
|
||||
== path_vpn) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bi) {
|
||||
if (bpi) {
|
||||
if (debug)
|
||||
zlog_debug("%s: deleting bi %p", __func__, bi);
|
||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
||||
bgp_info_delete(bn, bi);
|
||||
zlog_debug("%s: deleting bpi %p", __func__,
|
||||
bpi);
|
||||
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||
bgp_path_info_delete(bn, bpi);
|
||||
bgp_process(bgp, bn, afi, safi);
|
||||
}
|
||||
bgp_unlock_node(bn);
|
||||
@ -1332,25 +1323,25 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
|
||||
afi_t afi)
|
||||
{
|
||||
struct bgp_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
safi_t safi = SAFI_UNICAST;
|
||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||
|
||||
if (debug)
|
||||
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;
|
||||
bn = bgp_route_next(bn)) {
|
||||
|
||||
for (bi = bn->info; bi; bi = bi->next) {
|
||||
if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
|
||||
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||
if (bpi->extra && bpi->extra->bgp_orig != bgp_vrf) {
|
||||
|
||||
/* delete route */
|
||||
bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
|
||||
bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi,
|
||||
afi, safi);
|
||||
bgp_info_delete(bn, bi);
|
||||
bgp_path_info_delete(bn, bpi);
|
||||
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_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
|
||||
memset(&prd, 0, sizeof(prd));
|
||||
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 (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;
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
struct bgp_info *info_vrf);
|
||||
struct bgp_path_info *path_vrf);
|
||||
|
||||
extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
|
||||
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);
|
||||
|
||||
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,
|
||||
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_withdraw(struct bgp *bgp, afi_t afi);
|
||||
|
@ -63,7 +63,7 @@ struct bgp_nexthop_cache {
|
||||
|
||||
struct bgp_node *node;
|
||||
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;
|
||||
struct bgp *bgp;
|
||||
};
|
||||
@ -74,8 +74,6 @@ struct tip_addr {
|
||||
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_delete(struct bgp *bgp, struct connected *c);
|
||||
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,
|
||||
int is_bgp_static_route);
|
||||
static void evaluate_paths(struct bgp_nexthop_cache *bnc);
|
||||
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p);
|
||||
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
||||
int keep);
|
||||
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
|
||||
static void path_nh_map(struct bgp_path_info *path,
|
||||
struct bgp_nexthop_cache *bnc, int keep);
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -143,7 +143,7 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
|
||||
* we need both the bgp_route and bgp_nexthop pointers.
|
||||
*/
|
||||
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 bgp_node *rn;
|
||||
@ -151,9 +151,9 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
struct prefix p;
|
||||
int is_bgp_static_route = 0;
|
||||
|
||||
if (ri) {
|
||||
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP)
|
||||
&& (ri->sub_type == BGP_ROUTE_STATIC))
|
||||
if (pi) {
|
||||
is_bgp_static_route = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||
&& (pi->sub_type == BGP_ROUTE_STATIC))
|
||||
? 1
|
||||
: 0;
|
||||
|
||||
@ -161,12 +161,12 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
to derive
|
||||
address-family from the next-hop. */
|
||||
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;
|
||||
|
||||
/* This will return TRUE if the global IPv6 NH is a link local
|
||||
* addr */
|
||||
if (make_prefix(afi, ri, &p) < 0)
|
||||
if (make_prefix(afi, pi, &p) < 0)
|
||||
return 1;
|
||||
} else if (peer) {
|
||||
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;
|
||||
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
|
||||
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
|
||||
* free
|
||||
* 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)
|
||||
(bgp_info_extra_get(ri))->igpmetric = bnc->metric;
|
||||
else if (ri->extra)
|
||||
ri->extra->igpmetric = 0;
|
||||
(bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
|
||||
else if (pi->extra)
|
||||
pi->extra->igpmetric = 0;
|
||||
} else if (peer)
|
||||
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
|
||||
* 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)
|
||||
&& (ri->sub_type == BGP_ROUTE_STATIC))
|
||||
int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||
&& (pi->sub_type == BGP_ROUTE_STATIC))
|
||||
? 1
|
||||
: 0;
|
||||
|
||||
@ -540,10 +540,10 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
||||
case AFI_IP:
|
||||
p->family = AF_INET;
|
||||
if (is_bgp_static) {
|
||||
p->u.prefix4 = ri->net->p.u.prefix4;
|
||||
p->prefixlen = ri->net->p.prefixlen;
|
||||
p->u.prefix4 = pi->net->p.u.prefix4;
|
||||
p->prefixlen = pi->net->p.prefixlen;
|
||||
} else {
|
||||
p->u.prefix4 = ri->attr->nexthop;
|
||||
p->u.prefix4 = pi->attr->nexthop;
|
||||
p->prefixlen = IPV4_MAX_BITLEN;
|
||||
}
|
||||
break;
|
||||
@ -551,10 +551,10 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
||||
p->family = AF_INET6;
|
||||
|
||||
if (is_bgp_static) {
|
||||
p->u.prefix6 = ri->net->p.u.prefix6;
|
||||
p->prefixlen = ri->net->p.prefixlen;
|
||||
p->u.prefix6 = pi->net->p.u.prefix6;
|
||||
p->prefixlen = pi->net->p.prefixlen;
|
||||
} else {
|
||||
p->u.prefix6 = ri->attr->mp_nexthop_global;
|
||||
p->u.prefix6 = pi->attr->mp_nexthop_global;
|
||||
p->prefixlen = IPV6_MAX_BITLEN;
|
||||
}
|
||||
break;
|
||||
@ -673,7 +673,7 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
||||
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *path;
|
||||
struct bgp_path_info *path;
|
||||
int afi;
|
||||
struct peer *peer = (struct peer *)bnc->nht_info;
|
||||
struct bgp_table *table;
|
||||
@ -740,14 +740,16 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
||||
(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) {
|
||||
if (CHECK_FLAG(path->flags, BGP_INFO_VALID)) {
|
||||
if (CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
|
||||
bgp_aggregate_decrement(bgp_path, &rn->p,
|
||||
path, afi, safi);
|
||||
bgp_info_unset_flag(rn, path, BGP_INFO_VALID);
|
||||
bgp_path_info_unset_flag(rn, path,
|
||||
BGP_PATH_VALID);
|
||||
} 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,
|
||||
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
|
||||
* computation */
|
||||
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)
|
||||
path->extra->igpmetric = 0;
|
||||
|
||||
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_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);
|
||||
}
|
||||
@ -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
|
||||
* association.
|
||||
*/
|
||||
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
||||
int make)
|
||||
static void path_nh_map(struct bgp_path_info *path,
|
||||
struct bgp_nexthop_cache *bnc, int make)
|
||||
{
|
||||
if (path->nexthop) {
|
||||
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
|
||||
* 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
|
||||
@ -47,16 +47,17 @@ extern int bgp_find_nexthop(struct bgp_info *p, int connected);
|
||||
* connected - True if NH MUST be a connected route
|
||||
*/
|
||||
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
||||
struct bgp *bgp_nexthop, afi_t a, struct bgp_info *p,
|
||||
struct peer *peer, int connected);
|
||||
struct bgp *bgp_nexthop, afi_t a,
|
||||
struct bgp_path_info *p, struct peer *peer,
|
||||
int connected);
|
||||
|
||||
/**
|
||||
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
||||
* ARGUMENTS:
|
||||
* p - path structure.
|
||||
*/
|
||||
extern void bgp_unlink_nexthop(struct bgp_info *p);
|
||||
void bgp_unlink_nexthop_by_peer(struct peer *);
|
||||
extern void bgp_unlink_nexthop(struct bgp_path_info *p);
|
||||
void bgp_unlink_nexthop_by_peer(struct peer *peer);
|
||||
|
||||
/**
|
||||
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
|
||||
|
237
bgpd/bgp_pbr.c
237
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,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_path_info *path,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct nexthop *nh,
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
@ -645,8 +645,8 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
/* extract actiosn from flowspec ecom list */
|
||||
if (info && info->attr && info->attr->ecommunity) {
|
||||
ecom = info->attr->ecommunity;
|
||||
if (path && path->attr && path->attr->ecommunity) {
|
||||
ecom = path->attr->ecommunity;
|
||||
for (i = 0; i < ecom->size; i++) {
|
||||
ecom_eval = (struct ecommunity_val *)
|
||||
(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)) {
|
||||
api_action->action = ACTION_REDIRECT_IP;
|
||||
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];
|
||||
} else {
|
||||
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);
|
||||
bpme->installed = false;
|
||||
bpme->backpointer = NULL;
|
||||
if (bpme->bgp_info) {
|
||||
struct bgp_info *bgp_info;
|
||||
struct bgp_info_extra *extra;
|
||||
if (bpme->path) {
|
||||
struct bgp_path_info *path;
|
||||
struct bgp_path_info_extra *extra;
|
||||
|
||||
/* unlink bgp_info to bpme */
|
||||
bgp_info = (struct bgp_info *)bpme->bgp_info;
|
||||
extra = bgp_info_extra_get(bgp_info);
|
||||
/* unlink bgp_path_info to bpme */
|
||||
path = (struct bgp_path_info *)bpme->path;
|
||||
extra = bgp_path_info_extra_get(path);
|
||||
if (extra->bgp_fs_pbr)
|
||||
listnode_delete(extra->bgp_fs_pbr, bpme);
|
||||
bpme->bgp_info = NULL;
|
||||
bpme->path = NULL;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf)
|
||||
static void bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf)
|
||||
{
|
||||
struct bgp_pbr_match temp;
|
||||
struct bgp_pbr_match_entry temp2;
|
||||
@ -1438,13 +1437,10 @@ static uint8_t bgp_pbr_next_type_entry(uint8_t type_entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bgp_pbr_icmp_action(struct bgp *bgp,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof,
|
||||
bool add,
|
||||
struct nexthop *nh,
|
||||
float *rate)
|
||||
static void bgp_pbr_icmp_action(struct bgp *bgp, struct bgp_path_info *path,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof, bool add,
|
||||
struct nexthop *nh, float *rate)
|
||||
{
|
||||
struct bgp_pbr_range_port srcp, dstp;
|
||||
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)) {
|
||||
dstp.min_port = icmp_code->val;
|
||||
if (add)
|
||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
|
||||
bpf, nh, rate);
|
||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||
bgp, path, bpf, nh, rate);
|
||||
else
|
||||
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||
bgp, binfo, bpf);
|
||||
bgp, path, bpf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1487,31 +1483,27 @@ static void bgp_pbr_icmp_action(struct bgp *bgp,
|
||||
dstp.max_port = 255;
|
||||
if (add)
|
||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||
bgp, binfo,
|
||||
bpf, nh, rate);
|
||||
bgp, path, bpf, nh, rate);
|
||||
else
|
||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
||||
binfo, bpf);
|
||||
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||
bgp, path, bpf);
|
||||
continue;
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
||||
dstp.min_port = icmp_code->val;
|
||||
if (add)
|
||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||
bgp, binfo,
|
||||
bpf, nh, rate);
|
||||
bgp, path, bpf, nh, rate);
|
||||
else
|
||||
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,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof,
|
||||
uint8_t type_entry)
|
||||
static void bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof, uint8_t type_entry)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
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;
|
||||
|
||||
if (type_entry == 0)
|
||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
||||
binfo, bpf);
|
||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path,
|
||||
bpf);
|
||||
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
||||
if (type_entry == FLOWSPEC_TCP_FLAGS && 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 &&
|
||||
(bpof->icmp_type || bpof->icmp_code)) {
|
||||
/* 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;
|
||||
} else {
|
||||
return bgp_pbr_policyroute_remove_from_zebra_recursive(bgp,
|
||||
binfo,
|
||||
bpf, bpof,
|
||||
next_type_entry);
|
||||
return bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, next_type_entry);
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
||||
*target_val = valmask;
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
next_type_entry);
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, next_type_entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void bgp_pbr_policyroute_remove_from_zebra(struct bgp *bgp,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof)
|
||||
static void bgp_pbr_policyroute_remove_from_zebra(
|
||||
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof)
|
||||
{
|
||||
if (!bpof)
|
||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
||||
binfo,
|
||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path,
|
||||
bpf);
|
||||
if (bpof->tcpflags)
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
FLOWSPEC_TCP_FLAGS);
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, FLOWSPEC_TCP_FLAGS);
|
||||
else if (bpof->dscp)
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
FLOWSPEC_DSCP);
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, FLOWSPEC_DSCP);
|
||||
else if (bpof->pkt_len)
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
FLOWSPEC_PKT_LEN);
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, FLOWSPEC_PKT_LEN);
|
||||
else if (bpof->fragment)
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
FLOWSPEC_FRAGMENT);
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, FLOWSPEC_FRAGMENT);
|
||||
else if (bpof->icmp_type || bpof->icmp_code)
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
FLOWSPEC_ICMP_TYPE);
|
||||
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||
bgp, path, bpf, bpof, FLOWSPEC_ICMP_TYPE);
|
||||
else
|
||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, binfo, bpf);
|
||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path, bpf);
|
||||
/* flush bpof */
|
||||
if (bpof->tcpflags)
|
||||
list_delete_all_node(bpof->tcpflags);
|
||||
@ -1692,10 +1674,10 @@ 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,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct nexthop *nh,
|
||||
float *rate)
|
||||
struct bgp_path_info *path,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct nexthop *nh,
|
||||
float *rate)
|
||||
{
|
||||
struct bgp_pbr_match temp;
|
||||
struct bgp_pbr_match_entry temp2;
|
||||
@ -1848,19 +1830,21 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||
bpme->installed = false;
|
||||
bpme->install_in_progress = false;
|
||||
/* link bgp info to bpme */
|
||||
bpme->bgp_info = (void *)binfo;
|
||||
bpme->path = (void *)path;
|
||||
} else
|
||||
bpme_found = true;
|
||||
|
||||
/* already installed */
|
||||
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 &&
|
||||
listnode_lookup(extra->bgp_fs_pbr, bpme)) {
|
||||
if (BGP_DEBUG(pbr, PBR_ERROR))
|
||||
zlog_err("%s: entry %p/%p already installed in bgp pbr",
|
||||
__func__, binfo, bpme);
|
||||
zlog_err(
|
||||
"%s: entry %p/%p already installed in bgp pbr",
|
||||
__func__, path, bpme);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1911,13 +1895,10 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||
|
||||
}
|
||||
|
||||
static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof,
|
||||
struct nexthop *nh,
|
||||
float *rate,
|
||||
uint8_t type_entry)
|
||||
static void bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof, struct nexthop *nh, float *rate,
|
||||
uint8_t type_entry)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct bgp_pbr_val_mask *valmask;
|
||||
@ -1926,8 +1907,8 @@ static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
||||
struct bgp_pbr_val_mask **target_val;
|
||||
|
||||
if (type_entry == 0)
|
||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf,
|
||||
nh, rate);
|
||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh,
|
||||
rate);
|
||||
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
||||
if (type_entry == FLOWSPEC_TCP_FLAGS && 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 &&
|
||||
(bpof->icmp_type || bpof->icmp_code)) {
|
||||
/* 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;
|
||||
} else {
|
||||
return bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof, nh, rate,
|
||||
next_type_entry);
|
||||
return bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, next_type_entry);
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
||||
*target_val = valmask;
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
nh, rate,
|
||||
next_type_entry);
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, next_type_entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof,
|
||||
struct nexthop *nh,
|
||||
float *rate)
|
||||
struct bgp_path_info *path,
|
||||
struct bgp_pbr_filter *bpf,
|
||||
struct bgp_pbr_or_filter *bpof,
|
||||
struct nexthop *nh, float *rate)
|
||||
{
|
||||
if (!bpof)
|
||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
|
||||
bpf, nh, rate);
|
||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh,
|
||||
rate);
|
||||
if (bpof->tcpflags)
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
nh, rate,
|
||||
FLOWSPEC_TCP_FLAGS);
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_TCP_FLAGS);
|
||||
else if (bpof->dscp)
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
nh, rate,
|
||||
FLOWSPEC_DSCP);
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_DSCP);
|
||||
else if (bpof->pkt_len)
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
nh, rate,
|
||||
FLOWSPEC_PKT_LEN);
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_PKT_LEN);
|
||||
else if (bpof->fragment)
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof,
|
||||
nh, rate,
|
||||
FLOWSPEC_FRAGMENT);
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_FRAGMENT);
|
||||
else if (bpof->icmp_type || bpof->icmp_code)
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
||||
bpf, bpof, nh, rate,
|
||||
FLOWSPEC_ICMP_TYPE);
|
||||
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_ICMP_TYPE);
|
||||
else
|
||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf,
|
||||
nh, rate);
|
||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh, rate);
|
||||
/* flush bpof */
|
||||
if (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);
|
||||
}
|
||||
|
||||
static void bgp_pbr_handle_entry(struct bgp *bgp,
|
||||
struct bgp_info *binfo,
|
||||
struct bgp_pbr_entry_main *api,
|
||||
bool add)
|
||||
static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
|
||||
struct bgp_pbr_entry_main *api, bool add)
|
||||
{
|
||||
struct nexthop nh;
|
||||
int i = 0;
|
||||
@ -2151,9 +2116,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
||||
bpf.src_port = srcp;
|
||||
bpf.dst_port = dstp;
|
||||
if (!add)
|
||||
return bgp_pbr_policyroute_remove_from_zebra(bgp,
|
||||
binfo,
|
||||
&bpf, &bpof);
|
||||
return bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf,
|
||||
&bpof);
|
||||
/* no action for add = true */
|
||||
for (i = 0; i < api->action_num; i++) {
|
||||
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) {
|
||||
nh.vrf_id = api->vrf_id;
|
||||
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
||||
&bpf, &bpof,
|
||||
&nh, &rate);
|
||||
bgp_pbr_policyroute_add_to_zebra(
|
||||
bgp, path, &bpf, &bpof, &nh, &rate);
|
||||
} else {
|
||||
/* update rate. can be reentrant */
|
||||
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 =
|
||||
api->actions[i].u.zr.redirect_ip_v4.s_addr;
|
||||
nh.vrf_id = api->vrf_id;
|
||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
||||
&bpf, &bpof,
|
||||
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||
&nh, &rate);
|
||||
/* XXX combination with REDIRECT_VRF
|
||||
* + REDIRECT_NH_IP not done
|
||||
@ -2215,8 +2177,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
||||
case ACTION_REDIRECT:
|
||||
nh.vrf_id = api->actions[i].u.redirect_vrf;
|
||||
nh.type = NEXTHOP_TYPE_IPV4;
|
||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
||||
&bpf, &bpof,
|
||||
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||
&nh, &rate);
|
||||
continue_loop = 0;
|
||||
break;
|
||||
@ -2236,8 +2197,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
||||
}
|
||||
|
||||
void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
||||
struct bgp_info *info, afi_t afi, safi_t safi,
|
||||
bool nlri_update)
|
||||
struct bgp_path_info *info, afi_t afi, safi_t safi,
|
||||
bool nlri_update)
|
||||
{
|
||||
struct bgp_pbr_entry_main api;
|
||||
|
||||
|
@ -219,7 +219,7 @@ struct bgp_pbr_match_entry {
|
||||
uint16_t dst_port_max;
|
||||
uint8_t proto;
|
||||
|
||||
void *bgp_info;
|
||||
void *path;
|
||||
|
||||
bool installed;
|
||||
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);
|
||||
|
||||
struct bgp_node;
|
||||
struct bgp_info;
|
||||
struct bgp_path_info;
|
||||
extern void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
||||
struct bgp_info *new_select,
|
||||
afi_t afi, safi_t safi,
|
||||
bool nlri_update);
|
||||
struct bgp_path_info *new_select, afi_t afi,
|
||||
safi_t safi, bool nlri_update);
|
||||
|
||||
/* bgp pbr utilities */
|
||||
extern struct bgp_pbr_interface *pbr_interface_lookup(const char *name);
|
||||
|
1807
bgpd/bgp_route.c
1807
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
|
||||
|
||||
/* Ancillary information to struct bgp_info,
|
||||
/* Ancillary information to struct bgp_path_info,
|
||||
* used for uncommonly used data (aggregation, MPLS, etc.)
|
||||
* and lazily allocated to save memory.
|
||||
*/
|
||||
struct bgp_info_extra {
|
||||
struct bgp_path_info_extra {
|
||||
/* Pointer to dampening structure. */
|
||||
struct bgp_damp_info *damp_info;
|
||||
|
||||
@ -150,13 +150,13 @@ struct bgp_info_extra {
|
||||
struct list *bgp_fs_pbr;
|
||||
};
|
||||
|
||||
struct bgp_info {
|
||||
struct bgp_path_info {
|
||||
/* For linked list. */
|
||||
struct bgp_info *next;
|
||||
struct bgp_info *prev;
|
||||
struct bgp_path_info *next;
|
||||
struct bgp_path_info *prev;
|
||||
|
||||
/* For nexthop linked list */
|
||||
LIST_ENTRY(bgp_info) nh_thread;
|
||||
LIST_ENTRY(bgp_path_info) nh_thread;
|
||||
|
||||
/* Back pointer to the prefix node */
|
||||
struct bgp_node *net;
|
||||
@ -171,11 +171,11 @@ struct bgp_info {
|
||||
struct attr *attr;
|
||||
|
||||
/* Extra information */
|
||||
struct bgp_info_extra *extra;
|
||||
struct bgp_path_info_extra *extra;
|
||||
|
||||
|
||||
/* Multipath information */
|
||||
struct bgp_info_mpath *mpath;
|
||||
struct bgp_path_info_mpath *mpath;
|
||||
|
||||
/* Uptime. */
|
||||
time_t uptime;
|
||||
@ -185,21 +185,21 @@ struct bgp_info {
|
||||
|
||||
/* BGP information status. */
|
||||
uint16_t flags;
|
||||
#define BGP_INFO_IGP_CHANGED (1 << 0)
|
||||
#define BGP_INFO_DAMPED (1 << 1)
|
||||
#define BGP_INFO_HISTORY (1 << 2)
|
||||
#define BGP_INFO_SELECTED (1 << 3)
|
||||
#define BGP_INFO_VALID (1 << 4)
|
||||
#define BGP_INFO_ATTR_CHANGED (1 << 5)
|
||||
#define BGP_INFO_DMED_CHECK (1 << 6)
|
||||
#define BGP_INFO_DMED_SELECTED (1 << 7)
|
||||
#define BGP_INFO_STALE (1 << 8)
|
||||
#define BGP_INFO_REMOVED (1 << 9)
|
||||
#define BGP_INFO_COUNTED (1 << 10)
|
||||
#define BGP_INFO_MULTIPATH (1 << 11)
|
||||
#define BGP_INFO_MULTIPATH_CHG (1 << 12)
|
||||
#define BGP_INFO_RIB_ATTR_CHG (1 << 13)
|
||||
#define BGP_INFO_ANNC_NH_SELF (1 << 14)
|
||||
#define BGP_PATH_IGP_CHANGED (1 << 0)
|
||||
#define BGP_PATH_DAMPED (1 << 1)
|
||||
#define BGP_PATH_HISTORY (1 << 2)
|
||||
#define BGP_PATH_SELECTED (1 << 3)
|
||||
#define BGP_PATH_VALID (1 << 4)
|
||||
#define BGP_PATH_ATTR_CHANGED (1 << 5)
|
||||
#define BGP_PATH_DMED_CHECK (1 << 6)
|
||||
#define BGP_PATH_DMED_SELECTED (1 << 7)
|
||||
#define BGP_PATH_STALE (1 << 8)
|
||||
#define BGP_PATH_REMOVED (1 << 9)
|
||||
#define BGP_PATH_COUNTED (1 << 10)
|
||||
#define BGP_PATH_MULTIPATH (1 << 11)
|
||||
#define BGP_PATH_MULTIPATH_CHG (1 << 12)
|
||||
#define BGP_PATH_RIB_ATTR_CHG (1 << 13)
|
||||
#define BGP_PATH_ANNC_NH_SELF (1 << 14)
|
||||
|
||||
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
|
||||
uint8_t type;
|
||||
@ -224,9 +224,9 @@ struct bgp_info {
|
||||
};
|
||||
|
||||
/* Structure used in BGP path selection */
|
||||
struct bgp_info_pair {
|
||||
struct bgp_info *old;
|
||||
struct bgp_info *new;
|
||||
struct bgp_path_info_pair {
|
||||
struct bgp_path_info *old;
|
||||
struct bgp_path_info *new;
|
||||
};
|
||||
|
||||
/* BGP static route configuration. */
|
||||
@ -277,20 +277,20 @@ struct bgp_static {
|
||||
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
|
||||
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
|
||||
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
|
||||
#define BGP_INFO_COUNTABLE(BI) \
|
||||
(!CHECK_FLAG((BI)->flags, BGP_INFO_HISTORY) \
|
||||
&& !CHECK_FLAG((BI)->flags, BGP_INFO_REMOVED))
|
||||
#define BGP_PATH_COUNTABLE(BI) \
|
||||
(!CHECK_FLAG((BI)->flags, BGP_PATH_HISTORY) \
|
||||
&& !CHECK_FLAG((BI)->flags, BGP_PATH_REMOVED))
|
||||
|
||||
/* Flags which indicate a route is unuseable in some form */
|
||||
#define BGP_INFO_UNUSEABLE \
|
||||
(BGP_INFO_HISTORY | BGP_INFO_DAMPED | BGP_INFO_REMOVED)
|
||||
#define BGP_PATH_UNUSEABLE \
|
||||
(BGP_PATH_HISTORY | BGP_PATH_DAMPED | BGP_PATH_REMOVED)
|
||||
/* Macro to check BGP information is alive or not. Sadly,
|
||||
* not equivalent to just checking previous, because of the
|
||||
* sense of the additional VALID flag.
|
||||
*/
|
||||
#define BGP_INFO_HOLDDOWN(BI) \
|
||||
(!CHECK_FLAG((BI)->flags, BGP_INFO_VALID) \
|
||||
|| CHECK_FLAG((BI)->flags, BGP_INFO_UNUSEABLE))
|
||||
#define BGP_PATH_HOLDDOWN(BI) \
|
||||
(!CHECK_FLAG((BI)->flags, BGP_PATH_VALID) \
|
||||
|| CHECK_FLAG((BI)->flags, BGP_PATH_UNUSEABLE))
|
||||
|
||||
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
|
||||
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
|
||||
@ -318,7 +318,11 @@ struct bgp_static {
|
||||
/* path PREFIX (addpath rxid NUMBER) */
|
||||
#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)
|
||||
{
|
||||
@ -335,7 +339,7 @@ static inline int bgp_fibupd_safi(safi_t safi)
|
||||
}
|
||||
|
||||
/* 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);
|
||||
extern void bgp_process_queue_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,
|
||||
safi_t safi, struct prefix *p,
|
||||
struct prefix_rd *prd);
|
||||
extern struct bgp_info *bgp_info_lock(struct bgp_info *);
|
||||
extern struct bgp_info *bgp_info_unlock(struct bgp_info *);
|
||||
extern void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri);
|
||||
extern void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri);
|
||||
extern void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri);
|
||||
extern struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *);
|
||||
extern void bgp_info_set_flag(struct bgp_node *, struct bgp_info *, uint32_t);
|
||||
extern void bgp_info_unset_flag(struct bgp_node *, struct bgp_info *, uint32_t);
|
||||
extern void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf);
|
||||
extern struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path);
|
||||
extern struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path);
|
||||
extern void bgp_path_info_add(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||
extern void bgp_path_info_reap(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||
extern void bgp_path_info_delete(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||
extern struct bgp_path_info_extra *
|
||||
bgp_path_info_extra_get(struct bgp_path_info *path);
|
||||
extern void bgp_path_info_set_flag(struct bgp_node *rn,
|
||||
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 *);
|
||||
|
||||
@ -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,
|
||||
safi_t);
|
||||
|
||||
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
|
||||
struct bgp_info *, afi_t, safi_t);
|
||||
extern void bgp_aggregate_decrement(struct bgp *, struct prefix *,
|
||||
struct bgp_info *, afi_t, safi_t);
|
||||
extern void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
|
||||
struct bgp_path_info *path, afi_t afi,
|
||||
safi_t safi);
|
||||
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,
|
||||
safi_t, struct bgp *);
|
||||
extern uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *path,
|
||||
afi_t afi, safi_t safi, struct bgp *bgp);
|
||||
|
||||
extern afi_t bgp_node_afi(struct vty *);
|
||||
extern safi_t bgp_node_safi(struct vty *);
|
||||
|
||||
extern struct bgp_info *info_make(int type, int sub_type,
|
||||
unsigned short instance, struct peer *peer,
|
||||
struct attr *attr, struct bgp_node *rn);
|
||||
extern struct bgp_path_info *info_make(int type, int sub_type,
|
||||
unsigned short instance,
|
||||
struct peer *peer, struct attr *attr,
|
||||
struct bgp_node *rn);
|
||||
|
||||
extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
|
||||
safi_t, json_object *);
|
||||
extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
|
||||
int, safi_t, json_object *);
|
||||
extern void route_vty_out(struct vty *vty, struct prefix *p,
|
||||
struct bgp_path_info *path, int display, safi_t safi,
|
||||
json_object *json_paths);
|
||||
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,
|
||||
struct attr *attr, safi_t safi, bool use_json,
|
||||
json_object *json_ar);
|
||||
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);
|
||||
|
||||
extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
|
||||
struct bgp_info *selected,
|
||||
struct bgp_path_info *selected,
|
||||
struct bgp_node *rn,
|
||||
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 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,
|
||||
safi_t safi, struct prefix *p,
|
||||
struct prefix_rd *prd);
|
||||
extern struct bgp_info *bgp_info_new(void);
|
||||
extern void bgp_info_restore(struct bgp_node *, struct bgp_info *);
|
||||
extern struct bgp_path_info *bgp_path_info_new(void);
|
||||
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 *,
|
||||
struct bgp_info *, char *pfx_buf, afi_t afi,
|
||||
safi_t safi);
|
||||
extern int bgp_path_info_cmp_compatible(struct bgp *bgp,
|
||||
struct bgp_path_info *new,
|
||||
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_best_selection(struct bgp *bgp, struct bgp_node *rn,
|
||||
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);
|
||||
extern void bgp_zebra_clear_route_change_flags(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,
|
||||
struct bgp_node *rn,
|
||||
struct prefix_rd *prd, afi_t afi,
|
||||
safi_t safi, json_object *json);
|
||||
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,
|
||||
json_object *json_paths);
|
||||
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)
|
||||
{
|
||||
int *rpki_status = rule;
|
||||
struct bgp_info *bgp_info;
|
||||
struct bgp_path_info *path;
|
||||
|
||||
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) {
|
||||
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) {
|
||||
int ret;
|
||||
struct bgp_info *bgp_info = bgp_node->info;
|
||||
struct bgp_path_info *path = bgp_node->info;
|
||||
mpls_label_t *label = NULL;
|
||||
uint32_t num_labels = 0;
|
||||
|
||||
if (bgp_info && bgp_info->extra) {
|
||||
label = bgp_info->extra->label;
|
||||
num_labels = bgp_info->extra->num_labels;
|
||||
if (path && path->extra) {
|
||||
label = path->extra->label;
|
||||
num_labels = path->extra->num_labels;
|
||||
}
|
||||
ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
|
||||
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
||||
|
@ -674,14 +674,15 @@ static uint8_t *bgpRcvdPathAttrTable(struct variable *v, oid name[],
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
||||
size_t *length, struct bgp *bgp,
|
||||
struct prefix_ipv4 *addr, int exact)
|
||||
static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
||||
size_t *length, struct bgp *bgp,
|
||||
struct prefix_ipv4 *addr,
|
||||
int exact)
|
||||
{
|
||||
oid *offset;
|
||||
int offsetlen;
|
||||
struct bgp_info *binfo;
|
||||
struct bgp_info *min;
|
||||
struct bgp_path_info *path;
|
||||
struct bgp_path_info *min;
|
||||
struct bgp_node *rn;
|
||||
union sockunion su;
|
||||
unsigned int len;
|
||||
@ -714,9 +715,9 @@ static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
||||
if (rn) {
|
||||
bgp_unlock_node(rn);
|
||||
|
||||
for (binfo = rn->info; binfo; binfo = binfo->next)
|
||||
if (sockunion_same(&binfo->peer->su, &su))
|
||||
return binfo;
|
||||
for (path = rn->info; path; path = path->next)
|
||||
if (sockunion_same(&path->peer->su, &su))
|
||||
return path;
|
||||
}
|
||||
} else {
|
||||
offset = name + v->namelen;
|
||||
@ -761,22 +762,22 @@ static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
||||
do {
|
||||
min = NULL;
|
||||
|
||||
for (binfo = rn->info; binfo; binfo = binfo->next) {
|
||||
if (binfo->peer->su.sin.sin_family == AF_INET
|
||||
for (path = rn->info; path; path = path->next) {
|
||||
if (path->peer->su.sin.sin_family == AF_INET
|
||||
&& ntohl(paddr.s_addr)
|
||||
< ntohl(binfo->peer->su.sin
|
||||
< ntohl(path->peer->su.sin
|
||||
.sin_addr
|
||||
.s_addr)) {
|
||||
if (min) {
|
||||
if (ntohl(binfo->peer->su.sin
|
||||
if (ntohl(path->peer->su.sin
|
||||
.sin_addr
|
||||
.s_addr)
|
||||
< ntohl(min->peer->su.sin
|
||||
.sin_addr
|
||||
.s_addr))
|
||||
min = binfo;
|
||||
min = path;
|
||||
} else
|
||||
min = binfo;
|
||||
min = path;
|
||||
}
|
||||
}
|
||||
|
||||
@ -812,7 +813,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
||||
WriteMethod **write_method)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
struct bgp_info *binfo;
|
||||
struct bgp_path_info *path;
|
||||
struct prefix_ipv4 addr;
|
||||
|
||||
bgp = bgp_get_default();
|
||||
@ -824,13 +825,13 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
||||
return NULL;
|
||||
memset(&addr, 0, sizeof(struct prefix_ipv4));
|
||||
|
||||
binfo = bgp4PathAttrLookup(v, name, length, bgp, &addr, exact);
|
||||
if (!binfo)
|
||||
path = bgp4PathAttrLookup(v, name, length, bgp, &addr, exact);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
switch (v->magic) {
|
||||
case BGP4PATHATTRPEER: /* 1 */
|
||||
return SNMP_IPADDRESS(binfo->peer->su.sin.sin_addr);
|
||||
return SNMP_IPADDRESS(path->peer->su.sin.sin_addr);
|
||||
break;
|
||||
case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
|
||||
return SNMP_INTEGER(addr.prefixlen);
|
||||
@ -839,28 +840,28 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
||||
return SNMP_IPADDRESS(addr.prefix);
|
||||
break;
|
||||
case BGP4PATHATTRORIGIN: /* 4 */
|
||||
return SNMP_INTEGER(binfo->attr->origin);
|
||||
return SNMP_INTEGER(path->attr->origin);
|
||||
break;
|
||||
case BGP4PATHATTRASPATHSEGMENT: /* 5 */
|
||||
return aspath_snmp_pathseg(binfo->attr->aspath, var_len);
|
||||
return aspath_snmp_pathseg(path->attr->aspath, var_len);
|
||||
break;
|
||||
case BGP4PATHATTRNEXTHOP: /* 6 */
|
||||
return SNMP_IPADDRESS(binfo->attr->nexthop);
|
||||
return SNMP_IPADDRESS(path->attr->nexthop);
|
||||
break;
|
||||
case BGP4PATHATTRMULTIEXITDISC: /* 7 */
|
||||
return SNMP_INTEGER(binfo->attr->med);
|
||||
return SNMP_INTEGER(path->attr->med);
|
||||
break;
|
||||
case BGP4PATHATTRLOCALPREF: /* 8 */
|
||||
return SNMP_INTEGER(binfo->attr->local_pref);
|
||||
return SNMP_INTEGER(path->attr->local_pref);
|
||||
break;
|
||||
case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
|
||||
return SNMP_INTEGER(1);
|
||||
break;
|
||||
case BGP4PATHATTRAGGREGATORAS: /* 10 */
|
||||
return SNMP_INTEGER(binfo->attr->aggregator_as);
|
||||
return SNMP_INTEGER(path->attr->aggregator_as);
|
||||
break;
|
||||
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
|
||||
return SNMP_IPADDRESS(binfo->attr->aggregator_addr);
|
||||
return SNMP_IPADDRESS(path->attr->aggregator_addr);
|
||||
break;
|
||||
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
|
||||
return SNMP_INTEGER(-1);
|
||||
@ -868,7 +869,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
||||
case BGP4PATHATTRBEST: /* 13 */
|
||||
#define BGP4_PathAttrBest_false 1
|
||||
#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);
|
||||
else
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
@ -1906,7 +1906,7 @@ int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi)
|
||||
* configured addpath-tx knob
|
||||
*/
|
||||
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],
|
||||
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],
|
||||
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 0;
|
||||
|
@ -293,7 +293,7 @@ typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
|
||||
struct updwalk_context {
|
||||
struct vty *vty;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
uint64_t updgrp_id;
|
||||
uint64_t subgrp_id;
|
||||
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,
|
||||
int withdraw);
|
||||
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 update_group_announce(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);
|
||||
extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||
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,
|
||||
struct update_subgroup *subgrp,
|
||||
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 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,
|
||||
struct bgp_info *ri);
|
||||
struct bgp_path_info *pi);
|
||||
|
||||
/*
|
||||
* Inline functions
|
||||
|
@ -101,7 +101,7 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
||||
{
|
||||
struct updwalk_context *ctx = arg;
|
||||
struct update_subgroup *subgrp;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
struct peer *peer;
|
||||
@ -140,15 +140,15 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
||||
adj_next = adj->next;
|
||||
|
||||
if (adj->subgroup == subgrp) {
|
||||
for (ri = ctx->rn->info; ri;
|
||||
ri = ri->next) {
|
||||
if (ri->addpath_tx_id
|
||||
for (pi = ctx->rn->info; pi;
|
||||
pi = pi->next) {
|
||||
if (pi->addpath_tx_id
|
||||
== adj->addpath_tx_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ri) {
|
||||
if (!pi) {
|
||||
subgroup_process_announce_selected(
|
||||
subgrp, NULL,
|
||||
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 */
|
||||
if (ri == ctx->ri)
|
||||
if (pi == ctx->pi)
|
||||
continue;
|
||||
|
||||
subgroup_process_announce_selected(
|
||||
subgrp, ri, ctx->rn,
|
||||
ri->addpath_tx_id);
|
||||
subgrp, pi, ctx->rn,
|
||||
pi->addpath_tx_id);
|
||||
}
|
||||
|
||||
/* Process the bestpath last so the "show [ip]
|
||||
* bgp neighbor x.x.x.x advertised"
|
||||
* output shows the attributes from the bestpath
|
||||
*/
|
||||
if (ctx->ri)
|
||||
if (ctx->pi)
|
||||
subgroup_process_announce_selected(
|
||||
subgrp, ctx->ri, ctx->rn,
|
||||
ctx->ri->addpath_tx_id);
|
||||
subgrp, ctx->pi, ctx->rn,
|
||||
ctx->pi->addpath_tx_id);
|
||||
}
|
||||
|
||||
/* An update-group that does not use addpath */
|
||||
else {
|
||||
if (ctx->ri) {
|
||||
if (ctx->pi) {
|
||||
subgroup_process_announce_selected(
|
||||
subgrp, ctx->ri, ctx->rn,
|
||||
ctx->ri->addpath_tx_id);
|
||||
subgrp, ctx->pi, ctx->rn,
|
||||
ctx->pi->addpath_tx_id);
|
||||
} else {
|
||||
/* Find the addpath_tx_id of the path we
|
||||
* 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,
|
||||
struct update_subgroup *subgrp, struct attr *attr,
|
||||
struct bgp_info *binfo)
|
||||
struct bgp_path_info *path)
|
||||
{
|
||||
struct bgp_adj_out *adj = NULL;
|
||||
struct bgp_advertise *adv;
|
||||
@ -438,10 +438,10 @@ void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||
return;
|
||||
|
||||
/* Look for adjacency information. */
|
||||
adj = adj_lookup(rn, subgrp, binfo->addpath_tx_id);
|
||||
adj = adj_lookup(rn, subgrp, path->addpath_tx_id);
|
||||
|
||||
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)
|
||||
return;
|
||||
}
|
||||
@ -452,8 +452,9 @@ void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||
|
||||
adv = adj->adv;
|
||||
adv->rn = rn;
|
||||
assert(adv->binfo == NULL);
|
||||
adv->binfo = bgp_info_lock(binfo); /* bgp_info adj_out reference */
|
||||
assert(adv->pathi == NULL);
|
||||
/* bgp_path_info adj_out reference */
|
||||
adv->pathi = bgp_path_info_lock(path);
|
||||
|
||||
if (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_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *ri;
|
||||
struct attr attr;
|
||||
struct peer *peer;
|
||||
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 (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
|
||||
&& bgp_addpath_tx_path(peer, afi, safi, ri))) {
|
||||
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 attr attr;
|
||||
struct bgp_info *info, init_info, tmp_info;
|
||||
struct bgp_path_info *info, init_info, tmp_info;
|
||||
struct prefix p;
|
||||
struct peer *from;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *ri;
|
||||
struct peer *peer;
|
||||
int ret = RMAP_DENYMATCH;
|
||||
afi_t afi;
|
||||
@ -830,10 +831,10 @@ void subgroup_announce_all(struct update_subgroup *subgrp)
|
||||
* input route.
|
||||
*/
|
||||
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;
|
||||
ctx.ri = ri;
|
||||
ctx.pi = pi;
|
||||
ctx.rn = rn;
|
||||
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_advertise *adv;
|
||||
struct bgp_node *rn = NULL;
|
||||
struct bgp_info *binfo = NULL;
|
||||
struct bgp_path_info *path = NULL;
|
||||
bgp_size_t total_attr_len = 0;
|
||||
unsigned long attrlen_pos = 0;
|
||||
size_t mpattrlen_pos = 0;
|
||||
@ -731,7 +731,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||
rn = adv->rn;
|
||||
adj = adv->adj;
|
||||
addpath_tx_id = adj->addpath_tx_id;
|
||||
binfo = adv->binfo;
|
||||
path = adv->pathi;
|
||||
|
||||
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
||||
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||
@ -747,8 +747,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||
if (stream_empty(s)) {
|
||||
struct peer *from = NULL;
|
||||
|
||||
if (binfo)
|
||||
from = binfo->peer;
|
||||
if (path)
|
||||
from = path->peer;
|
||||
|
||||
/* 1: Write the BGP message header - 16 bytes marker, 2
|
||||
* bytes length,
|
||||
@ -821,13 +821,13 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||
prd = (struct prefix_rd *)&rn->prn->p;
|
||||
|
||||
if (safi == SAFI_LABELED_UNICAST) {
|
||||
label = bgp_adv_label(rn, binfo, peer, afi,
|
||||
label = bgp_adv_label(rn, path, peer, afi,
|
||||
safi);
|
||||
label_pnt = &label;
|
||||
num_labels = 1;
|
||||
} else if (binfo && binfo->extra) {
|
||||
label_pnt = &binfo->extra->label[0];
|
||||
num_labels = binfo->extra->num_labels;
|
||||
} else if (path && path->extra) {
|
||||
label_pnt = &path->extra->label[0];
|
||||
num_labels = path->extra->num_labels;
|
||||
}
|
||||
|
||||
if (stream_empty(snlri))
|
||||
|
@ -7524,12 +7524,13 @@ DEFUN (show_bgp_memory,
|
||||
count = mtype_stats_alloc(MTYPE_BGP_ROUTE);
|
||||
vty_out(vty, "%ld BGP routes, using %s of memory\n", count,
|
||||
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)))
|
||||
vty_out(vty, "%ld BGP route ancillaries, using %s of memory\n",
|
||||
count,
|
||||
mtype_memstr(memstrbuf, sizeof(memstrbuf),
|
||||
count * sizeof(struct bgp_info_extra)));
|
||||
mtype_memstr(
|
||||
memstrbuf, sizeof(memstrbuf),
|
||||
count * sizeof(struct bgp_path_info_extra)));
|
||||
|
||||
if ((count = mtype_stats_alloc(MTYPE_BGP_STATIC)))
|
||||
vty_out(vty, "%ld Static routes, using %s of memory\n", count,
|
||||
|
162
bgpd/bgp_zebra.c
162
bgpd/bgp_zebra.c
@ -925,41 +925,40 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
|
||||
ifindex_t *ifindex)
|
||||
static struct in6_addr *
|
||||
bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *path, ifindex_t *ifindex)
|
||||
{
|
||||
struct in6_addr *nexthop = NULL;
|
||||
|
||||
/* Only global address nexthop exists. */
|
||||
if (info->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
|
||||
nexthop = &info->attr->mp_nexthop_global;
|
||||
if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
|
||||
nexthop = &path->attr->mp_nexthop_global;
|
||||
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 (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 */
|
||||
if (info->attr->mp_nexthop_prefer_global) {
|
||||
nexthop = &info->attr->mp_nexthop_global;
|
||||
if (path->attr->mp_nexthop_prefer_global) {
|
||||
nexthop = &path->attr->mp_nexthop_global;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||
*ifindex = info->attr->nh_ifindex;
|
||||
*ifindex = path->attr->nh_ifindex;
|
||||
} else {
|
||||
/* Workaround for Cisco's nexthop bug. */
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(
|
||||
&info->attr->mp_nexthop_global)
|
||||
&& info->peer->su_remote->sa.sa_family
|
||||
&path->attr->mp_nexthop_global)
|
||||
&& path->peer->su_remote->sa.sa_family
|
||||
== AF_INET6) {
|
||||
nexthop =
|
||||
&info->peer->su_remote->sin6.sin6_addr;
|
||||
&path->peer->su_remote->sin6.sin6_addr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||
*ifindex = info->peer->nexthop.ifp
|
||||
*ifindex = path->peer->nexthop.ifp
|
||||
->ifindex;
|
||||
} else {
|
||||
nexthop = &info->attr->mp_nexthop_local;
|
||||
nexthop = &path->attr->mp_nexthop_local;
|
||||
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,
|
||||
struct bgp_info *info)
|
||||
struct bgp_path_info *path)
|
||||
{
|
||||
route_map_result_t ret;
|
||||
|
||||
ret = route_map_apply(map, p, RMAP_BGP, info);
|
||||
bgp_attr_flush(info->attr);
|
||||
ret = route_map_apply(map, p, RMAP_BGP, path);
|
||||
bgp_attr_flush(path->attr);
|
||||
|
||||
if (ret != RMAP_DENYMATCH)
|
||||
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],
|
||||
sizeof(buf[0])),
|
||||
p->prefixlen,
|
||||
inet_ntop(AF_INET, &info->attr->nexthop, buf[1],
|
||||
inet_ntop(AF_INET, &path->attr->nexthop, buf[1],
|
||||
sizeof(buf[1])));
|
||||
}
|
||||
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;
|
||||
struct in6_addr *nexthop;
|
||||
|
||||
nexthop = bgp_info_to_ipv6_nexthop(info, &ifindex);
|
||||
nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex);
|
||||
zlog_debug(
|
||||
"Zebra rmap deny: IPv6 route %s/%d nexthop %s",
|
||||
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;
|
||||
}
|
||||
|
||||
static int update_ipv6nh_for_route_install(int nh_othervrf,
|
||||
struct in6_addr *nexthop,
|
||||
ifindex_t ifindex,
|
||||
struct bgp_info *ri,
|
||||
struct bgp_info *best_ri,
|
||||
bool is_evpn,
|
||||
struct zapi_nexthop *api_nh)
|
||||
static int
|
||||
update_ipv6nh_for_route_install(int nh_othervrf, struct in6_addr *nexthop,
|
||||
ifindex_t ifindex, struct bgp_path_info *pi,
|
||||
struct bgp_path_info *best_pi, bool is_evpn,
|
||||
struct zapi_nexthop *api_nh)
|
||||
{
|
||||
struct attr *attr;
|
||||
|
||||
attr = ri->attr;
|
||||
attr = pi->attr;
|
||||
|
||||
if (is_evpn)
|
||||
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||
@ -1150,22 +1147,22 @@ static int update_ipv6nh_for_route_install(int nh_othervrf,
|
||||
}
|
||||
} else {
|
||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
|
||||
if (ri == best_ri &&
|
||||
attr->mp_nexthop_len
|
||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||
if (ri->peer->nexthop.ifp)
|
||||
ifindex = ri->peer->nexthop.ifp
|
||||
->ifindex;
|
||||
if (pi == best_pi
|
||||
&& attr->mp_nexthop_len
|
||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||
if (pi->peer->nexthop.ifp)
|
||||
ifindex =
|
||||
pi->peer->nexthop.ifp->ifindex;
|
||||
if (!ifindex) {
|
||||
if (ri->peer->conf_if)
|
||||
ifindex = ri->peer->ifp->ifindex;
|
||||
else if (ri->peer->ifname)
|
||||
if (pi->peer->conf_if)
|
||||
ifindex = pi->peer->ifp->ifindex;
|
||||
else if (pi->peer->ifname)
|
||||
ifindex = ifname2ifindex(
|
||||
ri->peer->ifname,
|
||||
ri->peer->bgp->vrf_id);
|
||||
else if (ri->peer->nexthop.ifp)
|
||||
ifindex = ri->peer->nexthop.ifp
|
||||
->ifindex;
|
||||
pi->peer->ifname,
|
||||
pi->peer->bgp->vrf_id);
|
||||
else if (pi->peer->nexthop.ifp)
|
||||
ifindex =
|
||||
pi->peer->nexthop.ifp->ifindex;
|
||||
}
|
||||
|
||||
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,
|
||||
struct bgp_info *info, struct bgp *bgp, afi_t afi,
|
||||
struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
|
||||
safi_t safi)
|
||||
{
|
||||
struct zapi_route api;
|
||||
@ -1193,11 +1190,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||
int has_valid_label = 0;
|
||||
uint8_t distance;
|
||||
struct peer *peer;
|
||||
struct bgp_info *mpinfo;
|
||||
struct bgp_path_info *mpinfo;
|
||||
uint32_t metric;
|
||||
struct attr local_attr;
|
||||
struct bgp_info local_info;
|
||||
struct bgp_info *mpinfo_cp = &local_info;
|
||||
struct bgp_path_info local_info;
|
||||
struct bgp_path_info *mpinfo_cp = &local_info;
|
||||
route_tag_t tag;
|
||||
mpls_label_t label;
|
||||
int nh_othervrf = 0;
|
||||
@ -1242,7 +1239,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||
|
||||
/* Obtain peer from 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;
|
||||
@ -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 = 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)
|
||||
break;
|
||||
|
||||
@ -1356,8 +1354,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||
tag = mpinfo_cp->attr->tag;
|
||||
}
|
||||
}
|
||||
nexthop = bgp_info_to_ipv6_nexthop(mpinfo_cp,
|
||||
&ifindex);
|
||||
nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
|
||||
&ifindex);
|
||||
nh_updated = update_ipv6nh_for_route_install(
|
||||
nh_othervrf, nexthop, ifindex,
|
||||
mpinfo, info, is_evpn, api_nh);
|
||||
@ -1466,7 +1464,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
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
|
||||
* know of this instance.
|
||||
@ -1479,18 +1477,18 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
|
||||
return;
|
||||
|
||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
||||
for (ri = rn->info; ri; ri = ri->next)
|
||||
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
|
||||
for (pi = rn->info; pi; pi = pi->next)
|
||||
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
|
||||
|
||||
(ri->type == ZEBRA_ROUTE_BGP
|
||||
&& (ri->sub_type == BGP_ROUTE_NORMAL
|
||||
|| ri->sub_type == BGP_ROUTE_IMPORTED)))
|
||||
(pi->type == ZEBRA_ROUTE_BGP
|
||||
&& (pi->sub_type == BGP_ROUTE_NORMAL
|
||||
|| 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);
|
||||
}
|
||||
|
||||
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 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)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *pi;
|
||||
|
||||
if (red->redist_metric_flag && red->redist_metric == metric)
|
||||
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;
|
||||
rn = bgp_route_next(rn)) {
|
||||
for (ri = rn->info; ri; ri = ri->next) {
|
||||
if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||
&& ri->type == type
|
||||
&& ri->instance == red->instance) {
|
||||
for (pi = rn->info; pi; pi = pi->next) {
|
||||
if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||
&& pi->type == type
|
||||
&& pi->instance == red->instance) {
|
||||
struct attr *old_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;
|
||||
old_attr = ri->attr;
|
||||
ri->attr = bgp_attr_intern(&new_attr);
|
||||
old_attr = pi->attr;
|
||||
pi->attr = bgp_attr_intern(&new_attr);
|
||||
bgp_attr_unintern(&old_attr);
|
||||
|
||||
bgp_info_set_flag(rn, ri,
|
||||
BGP_INFO_ATTR_CHANGED);
|
||||
bgp_path_info_set_flag(rn, pi,
|
||||
BGP_PATH_ATTR_CHANGED);
|
||||
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
||||
}
|
||||
}
|
||||
@ -2081,20 +2079,20 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
|
||||
break;
|
||||
case ZAPI_IPSET_ENTRY_INSTALLED:
|
||||
{
|
||||
struct bgp_info *bgp_info;
|
||||
struct bgp_info_extra *extra;
|
||||
struct bgp_path_info *path;
|
||||
struct bgp_path_info_extra *extra;
|
||||
|
||||
bgp_pbime->installed = true;
|
||||
bgp_pbime->install_in_progress = false;
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
|
||||
__PRETTY_FUNCTION__);
|
||||
/* link bgp_info to bpme */
|
||||
bgp_info = (struct bgp_info *)bgp_pbime->bgp_info;
|
||||
extra = bgp_info_extra_get(bgp_info);
|
||||
if (extra->bgp_fs_pbr == NULL)
|
||||
extra->bgp_fs_pbr = list_new();
|
||||
listnode_add(extra->bgp_fs_pbr, bgp_pbime);
|
||||
bgp_pbime->installed = true;
|
||||
bgp_pbime->install_in_progress = false;
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
|
||||
__PRETTY_FUNCTION__);
|
||||
/* link bgp_path_info to bpme */
|
||||
path = (struct bgp_path_info *)bgp_pbime->path;
|
||||
extra = bgp_path_info_extra_get(path);
|
||||
if (extra->bgp_fs_pbr == NULL)
|
||||
extra->bgp_fs_pbr = list_new();
|
||||
listnode_add(extra->bgp_fs_pbr, bgp_pbime);
|
||||
}
|
||||
break;
|
||||
case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
|
||||
|
@ -36,11 +36,12 @@ extern void bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t,
|
||||
safi_t);
|
||||
extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
||||
safi_t);
|
||||
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
|
||||
struct bgp_info *, struct bgp *, afi_t, safi_t);
|
||||
extern void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||
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_withdraw(struct prefix *, struct bgp_info *,
|
||||
struct bgp *, safi_t);
|
||||
extern void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *path,
|
||||
struct bgp *bgp, safi_t safi);
|
||||
|
||||
extern void bgp_zebra_initiate_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 */
|
||||
struct bgp_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
char buf[PREFIX_STRLEN];
|
||||
char buf2[RD_ADDRSTRLEN];
|
||||
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)),
|
||||
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(
|
||||
"%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
|
||||
__func__, bi, bi->peer, bi->type, bi->sub_type,
|
||||
(bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL),
|
||||
((bi->attr
|
||||
&& CHECK_FLAG(bi->attr->flag,
|
||||
"%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__, bpi, bpi->peer, bpi->type, bpi->sub_type,
|
||||
(bpi->extra ? bpi->extra->vnc.export.rfapi_handle
|
||||
: NULL),
|
||||
((bpi->attr
|
||||
&& CHECK_FLAG(bpi->attr->flag,
|
||||
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
|
||||
? bi->attr->local_pref
|
||||
? bpi->attr->local_pref
|
||||
: 0));
|
||||
|
||||
if (bi->peer == peer && bi->type == type
|
||||
&& bi->sub_type == sub_type && bi->extra
|
||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||
if (bpi->peer == peer && bpi->type == type
|
||||
&& bpi->sub_type == sub_type && bpi->extra
|
||||
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||
|
||||
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.
|
||||
* TBD add return code reporting of success/failure
|
||||
*/
|
||||
if (!bi || !bi->extra
|
||||
|| !bi->extra->vnc.export.local_nexthops) {
|
||||
if (!bpi || !bpi->extra
|
||||
|| !bpi->extra->vnc.export.local_nexthops) {
|
||||
/*
|
||||
* no local nexthops
|
||||
*/
|
||||
@ -429,7 +430,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
||||
struct listnode *node;
|
||||
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)) {
|
||||
|
||||
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
||||
@ -438,7 +439,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
||||
}
|
||||
|
||||
if (pLnh) {
|
||||
listnode_delete(bi->extra->vnc.export.local_nexthops,
|
||||
listnode_delete(bpi->extra->vnc.export.local_nexthops,
|
||||
pLnh);
|
||||
|
||||
/* 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);
|
||||
|
||||
if (bi) {
|
||||
if (bpi) {
|
||||
prefix2str(p, buf, sizeof(buf));
|
||||
vnc_zlog_debug_verbose(
|
||||
"%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);
|
||||
|
||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||
bgp, prd, table, p, bi);
|
||||
bgp, prd, table, p, bpi);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
@ -482,13 +483,11 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
||||
/*
|
||||
* Delete local_nexthops list
|
||||
*/
|
||||
if (bi->extra && bi->extra->vnc.export.local_nexthops) {
|
||||
list_delete(
|
||||
&bi->extra->vnc.export.local_nexthops);
|
||||
}
|
||||
if (bpi->extra && bpi->extra->vnc.export.local_nexthops)
|
||||
list_delete(&bpi->extra->vnc.export.local_nexthops);
|
||||
|
||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
||||
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);
|
||||
} else {
|
||||
vnc_zlog_debug_verbose(
|
||||
@ -575,8 +574,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
||||
int flags)
|
||||
{
|
||||
afi_t afi; /* of the VN address */
|
||||
struct bgp_info *new;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *new;
|
||||
struct bgp_path_info *bpi;
|
||||
struct bgp_node *bn;
|
||||
|
||||
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
|
||||
* 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
|
||||
* bi->extra->vnc.export.rfapi_handle */
|
||||
if (bi->peer == rfd->peer && bi->type == type
|
||||
&& bi->sub_type == sub_type && bi->extra
|
||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||
* bpi->extra->vnc.export.rfapi_handle */
|
||||
if (bpi->peer == rfd->peer && bpi->type == type
|
||||
&& bpi->sub_type == sub_type && bpi->extra
|
||||
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bi) {
|
||||
if (bpi) {
|
||||
|
||||
/*
|
||||
* Adding new local_nexthop, which does not by itself change
|
||||
* what is advertised via BGP
|
||||
*/
|
||||
if (lnh) {
|
||||
if (!bi->extra->vnc.export.local_nexthops) {
|
||||
if (!bpi->extra->vnc.export.local_nexthops) {
|
||||
/* TBD make arrangements to free when needed */
|
||||
bi->extra->vnc.export.local_nexthops =
|
||||
bpi->extra->vnc.export.local_nexthops =
|
||||
list_new();
|
||||
bi->extra->vnc.export.local_nexthops->del =
|
||||
bpi->extra->vnc.export.local_nexthops->del =
|
||||
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;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(
|
||||
bi->extra->vnc.export.local_nexthops, node,
|
||||
pLnh)) {
|
||||
bpi->extra->vnc.export.local_nexthops,
|
||||
node, pLnh)) {
|
||||
|
||||
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
||||
break;
|
||||
@ -993,13 +992,13 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
||||
if (!pLnh) {
|
||||
pLnh = rfapi_nexthop_new(lnh);
|
||||
listnode_add(
|
||||
bi->extra->vnc.export.local_nexthops,
|
||||
bpi->extra->vnc.export.local_nexthops,
|
||||
pLnh);
|
||||
}
|
||||
}
|
||||
|
||||
if (attrhash_cmp(bi->attr, new_attr)
|
||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
||||
if (attrhash_cmp(bpi->attr, new_attr)
|
||||
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||
bgp_attr_unintern(&new_attr);
|
||||
bgp_unlock_node(bn);
|
||||
|
||||
@ -1010,7 +1009,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
||||
goto done;
|
||||
} else {
|
||||
/* 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) {
|
||||
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);
|
||||
|
||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||
bgp, prd, table, p, bi);
|
||||
bgp, prd, table, p, bpi);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
|
||||
/* Rewrite BGP route information. */
|
||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
||||
bgp_info_restore(bn, bi);
|
||||
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||
bgp_path_info_restore(bn, bpi);
|
||||
else
|
||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
||||
bgp_attr_unintern(&bi->attr);
|
||||
bi->attr = new_attr;
|
||||
bi->uptime = bgp_clock();
|
||||
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||
bgp_attr_unintern(&bpi->attr);
|
||||
bpi->attr = new_attr;
|
||||
bpi->uptime = bgp_clock();
|
||||
|
||||
|
||||
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);
|
||||
|
||||
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||
bgp, prd, table, p, bi);
|
||||
bgp, prd, table, p, bpi);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
|
||||
/* 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_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->sub_type = sub_type;
|
||||
new->peer = rfd->peer;
|
||||
SET_FLAG(new->flags, BGP_INFO_VALID);
|
||||
SET_FLAG(new->flags, BGP_PATH_VALID);
|
||||
new->attr = new_attr;
|
||||
new->uptime = bgp_clock();
|
||||
|
||||
/* 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;
|
||||
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_info_add(bn, new);
|
||||
bgp_path_info_add(bn, new);
|
||||
|
||||
if (safi == SAFI_MPLS_VPN) {
|
||||
struct bgp_node *prn = NULL;
|
||||
@ -3690,7 +3689,7 @@ static void rfapi_print_exported(struct bgp *bgp)
|
||||
{
|
||||
struct bgp_node *rdn;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
|
||||
if (!bgp)
|
||||
return;
|
||||
@ -3705,8 +3704,8 @@ static void rfapi_print_exported(struct bgp *bgp)
|
||||
if (!rn->info)
|
||||
continue;
|
||||
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
||||
for (bi = rn->info; bi; bi = bi->next) {
|
||||
rfapiPrintBi((void *)2, bi); /* 2 => stderr */
|
||||
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||
rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3720,8 +3719,8 @@ static void rfapi_print_exported(struct bgp *bgp)
|
||||
if (!rn->info)
|
||||
continue;
|
||||
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
||||
for (bi = rn->info; bi; bi = bi->next) {
|
||||
rfapiPrintBi((void *)2, bi); /* 2 => stderr */
|
||||
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||
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 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);
|
||||
|
||||
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,
|
||||
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);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
struct rfapi_import_table {
|
||||
@ -51,18 +51,18 @@ struct rfapi_import_table {
|
||||
int imported_count[AFI_MAX];
|
||||
};
|
||||
|
||||
#define RFAPI_LOCAL_BI(bi) \
|
||||
(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP))
|
||||
#define RFAPI_LOCAL_BI(bpi) \
|
||||
(((bpi)->type == ZEBRA_ROUTE_BGP) && ((bpi)->sub_type == BGP_ROUTE_RFP))
|
||||
|
||||
#define RFAPI_DIRECT_IMPORT_BI(bi) \
|
||||
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|
||||
|| ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
||||
#define RFAPI_DIRECT_IMPORT_BI(bpi) \
|
||||
(((bpi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|
||||
|| ((bpi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
||||
|
||||
#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \
|
||||
if (RFAPI_LOCAL_BI(bi)) { \
|
||||
#define RFAPI_UPDATE_ITABLE_COUNT(bpi, itable, afi, cnt) \
|
||||
if (RFAPI_LOCAL_BI(bpi)) { \
|
||||
(itable)->local_count[(afi)] += (cnt); \
|
||||
} else { \
|
||||
if (RFAPI_DIRECT_IMPORT_BI(bi)) \
|
||||
if (RFAPI_DIRECT_IMPORT_BI(bpi)) \
|
||||
(itable)->imported_count[(afi)] += (cnt); \
|
||||
else \
|
||||
(itable)->remote_count[(afi)] += (cnt); \
|
||||
@ -75,9 +75,9 @@ extern void rfapiDebugBacktrace(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,
|
||||
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
|
||||
* 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,
|
||||
* 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.
|
||||
@ -128,7 +128,7 @@ extern int rfapiHasNonRemovedRoutes(struct agg_node *rn);
|
||||
|
||||
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);
|
||||
|
||||
@ -146,10 +146,10 @@ extern void rfapiBgpInfoFilteredImportVPN(
|
||||
struct prefix *p,
|
||||
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
|
||||
afi_t afi, struct prefix_rd *prd,
|
||||
struct attr *attr, /* part of bgp_info */
|
||||
uint8_t type, /* part of bgp_info */
|
||||
uint8_t sub_type, /* part of bgp_info */
|
||||
uint32_t *label); /* part of bgp_info */
|
||||
struct attr *attr, /* part of bgp_path_info */
|
||||
uint8_t type, /* part of bgp_path_info */
|
||||
uint8_t sub_type, /* part of bgp_path_info */
|
||||
uint32_t *label); /* part of bgp_path_info */
|
||||
|
||||
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
|
||||
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);
|
||||
}
|
||||
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)) {
|
||||
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);
|
||||
rn;) {
|
||||
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
struct prefix pfx_dummy;
|
||||
|
||||
/* 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
|
||||
* VPN route
|
||||
*/
|
||||
if (bi->extra && bi->extra->vnc.import.un_family) {
|
||||
if (bpi->extra && bpi->extra->vnc.import.un_family) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -364,11 +364,11 @@ struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
|
||||
* address,
|
||||
* it's a usable VPN route.
|
||||
*/
|
||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_dummy)) {
|
||||
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_dummy)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bi)
|
||||
if (bpi)
|
||||
break;
|
||||
|
||||
agg_unlock_node(rn);
|
||||
|
@ -45,7 +45,7 @@ struct rfapi_monitor_encap {
|
||||
struct rfapi_monitor_encap *next;
|
||||
struct rfapi_monitor_encap *prev;
|
||||
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 */
|
||||
};
|
||||
|
||||
@ -83,7 +83,7 @@ struct rfapi_it_extra {
|
||||
* Encap TLV */
|
||||
int valid_interior_count;
|
||||
|
||||
/* unicast exterior routes, key=bi,
|
||||
/* unicast exterior routes, key=bpi,
|
||||
* val=allocated prefix */
|
||||
struct skiplist *source;
|
||||
} e;
|
||||
|
@ -212,7 +212,7 @@ struct rfapi {
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *pEncap;
|
||||
|
||||
ri->cost = rfapiRfpCost(bi->attr);
|
||||
ri->cost = rfapiRfpCost(bpi->attr);
|
||||
ri->lifetime = lifetime;
|
||||
|
||||
/* 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;
|
||||
|
||||
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 */
|
||||
ri->un_options = rfapi_encap_tlv_to_un_option(bi->attr);
|
||||
ri->un_options = rfapi_encap_tlv_to_un_option(bpi->attr);
|
||||
|
||||
/*
|
||||
* VN options
|
||||
*/
|
||||
if (bi->extra
|
||||
&& decode_rd_type(bi->extra->vnc.import.rd.val)
|
||||
if (bpi->extra
|
||||
&& decode_rd_type(bpi->extra->vnc.import.rd.val)
|
||||
== RD_TYPE_VNC_ETH) {
|
||||
/* ethernet route */
|
||||
|
||||
@ -683,21 +683,21 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
||||
|
||||
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);
|
||||
|
||||
(void)rfapiEcommunityGetLNI(bi->attr->ecommunity,
|
||||
(void)rfapiEcommunityGetLNI(bpi->attr->ecommunity,
|
||||
&vo->v.l2addr.logical_net_id);
|
||||
(void)rfapiEcommunityGetEthernetTag(bi->attr->ecommunity,
|
||||
(void)rfapiEcommunityGetEthernetTag(bpi->attr->ecommunity,
|
||||
&vo->v.l2addr.tag_id);
|
||||
|
||||
/* 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 */
|
||||
vo->v.l2addr.label = decode_label(&bi->extra->label[0]);
|
||||
vo->v.l2addr.label = decode_label(&bpi->extra->label[0]);
|
||||
|
||||
rfapi_vn_options_free(
|
||||
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 (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
||||
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
||||
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||
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(
|
||||
struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */
|
||||
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 skiplist *slRibPt = NULL;
|
||||
@ -751,13 +751,13 @@ int rfapiRibPreloadBi(
|
||||
|
||||
memset((void *)&rk, 0, sizeof(rk));
|
||||
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 (bi->extra->vnc.import.aux_prefix.family) {
|
||||
rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
||||
if (bpi->extra->vnc.import.aux_prefix.family) {
|
||||
rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -774,13 +774,13 @@ int rfapiRibPreloadBi(
|
||||
|
||||
/* found: update contents of existing route in RIB */
|
||||
ori->un = *pfx_un;
|
||||
rfapiRibBi2Ri(bi, ori, lifetime);
|
||||
rfapiRibBi2Ri(bpi, ori, lifetime);
|
||||
} else {
|
||||
/* not found: add new route to RIB */
|
||||
ori = rfapi_info_new();
|
||||
ori->rk = rk;
|
||||
ori->un = *pfx_un;
|
||||
rfapiRibBi2Ri(bi, ori, lifetime);
|
||||
rfapiRibBi2Ri(bpi, ori, lifetime);
|
||||
|
||||
if (!slRibPt) {
|
||||
slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL);
|
||||
@ -1590,7 +1590,7 @@ void rfapiRibUpdatePendingNode(
|
||||
struct agg_node *it_node, uint32_t lifetime)
|
||||
{
|
||||
struct prefix *prefix;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
struct agg_node *pn;
|
||||
afi_t afi;
|
||||
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 prefix pfx_nh;
|
||||
|
||||
if (!bi->attr) {
|
||||
if (!bpi->attr) {
|
||||
/* shouldn't happen */
|
||||
/* TBD increment error stats counter */
|
||||
continue;
|
||||
}
|
||||
if (!bi->extra) {
|
||||
if (!bpi->extra) {
|
||||
/* shouldn't happen */
|
||||
/* TBD increment error stats counter */
|
||||
continue;
|
||||
}
|
||||
|
||||
rfapiNexthop2Prefix(bi->attr, &pfx_nh);
|
||||
rfapiNexthop2Prefix(bpi->attr, &pfx_nh);
|
||||
|
||||
/*
|
||||
* Omit route if nexthop is self
|
||||
@ -1675,15 +1675,15 @@ void rfapiRibUpdatePendingNode(
|
||||
|
||||
ri = rfapi_info_new();
|
||||
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 (bi->extra->vnc.import.aux_prefix.family) {
|
||||
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
||||
if (bpi->extra->vnc.import.aux_prefix.family) {
|
||||
ri->rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||
}
|
||||
|
||||
if (rfapiGetUnAddrOfVpnBi(bi, &ri->un)) {
|
||||
if (rfapiGetUnAddrOfVpnBi(bpi, &ri->un)) {
|
||||
rfapi_info_free(ri);
|
||||
continue;
|
||||
}
|
||||
@ -1711,7 +1711,7 @@ void rfapiRibUpdatePendingNode(
|
||||
continue;
|
||||
}
|
||||
|
||||
rfapiRibBi2Ri(bi, ri, lifetime);
|
||||
rfapiRibBi2Ri(bpi, ri, lifetime);
|
||||
|
||||
if (!pn->info) {
|
||||
pn->info = list_new();
|
||||
|
@ -105,7 +105,7 @@ extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp,
|
||||
|
||||
extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node,
|
||||
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 *
|
||||
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() */
|
||||
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;
|
||||
uint32_t lifetime;
|
||||
@ -410,7 +410,7 @@ void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
||||
if (safi == SAFI_MPLS_VPN) {
|
||||
struct prefix pfx_un;
|
||||
|
||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) {
|
||||
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
|
||||
char buf[BUFSIZ];
|
||||
vty_out(vty, "UN=%s",
|
||||
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) {
|
||||
s = ecommunity_ecom2str(bi->attr->ecommunity,
|
||||
if (bpi->attr && bpi->attr->ecommunity) {
|
||||
s = ecommunity_ecom2str(bpi->attr->ecommunity,
|
||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||
vty_out(vty, " EC{%s}", s);
|
||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||
}
|
||||
|
||||
if (bi->extra != NULL) {
|
||||
if (bi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
|
||||
if (bpi->extra != NULL) {
|
||||
if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
|
||||
vty_out(vty, " label=VRF2VRF");
|
||||
else
|
||||
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, " type=%s, subtype=%d", zebra_route_string(bi->type),
|
||||
bi->sub_type);
|
||||
vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bpi->type),
|
||||
bpi->sub_type);
|
||||
|
||||
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 *s;
|
||||
@ -503,12 +503,13 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
|
||||
if (!bi)
|
||||
if (!bpi)
|
||||
return;
|
||||
|
||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra
|
||||
&& bi->extra->vnc.import.timer) {
|
||||
struct thread *t = (struct thread *)bi->extra->vnc.import.timer;
|
||||
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
|
||||
&& bpi->extra->vnc.import.timer) {
|
||||
struct thread *t =
|
||||
(struct thread *)bpi->extra->vnc.import.timer;
|
||||
r = snprintf(p, REMAIN, " [%4lu] ",
|
||||
thread_timer_remain_second(t));
|
||||
INCP;
|
||||
@ -518,14 +519,14 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
INCP;
|
||||
}
|
||||
|
||||
if (bi->extra) {
|
||||
if (bpi->extra) {
|
||||
/* 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) {
|
||||
has_macaddr = 1;
|
||||
memcpy(macaddr.octet, bi->extra->vnc.import.rd.val + 2,
|
||||
memcpy(macaddr.octet, bpi->extra->vnc.import.rd.val + 2,
|
||||
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)
|
||||
* extended communities (RTs)
|
||||
*/
|
||||
if (bi->attr) {
|
||||
if (bpi->attr) {
|
||||
uint32_t lifetime;
|
||||
int printed_1st_gol = 0;
|
||||
struct bgp_attr_encap_subtlv *pEncap;
|
||||
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 */
|
||||
if (af == AF_INET) {
|
||||
r = snprintf(p, REMAIN, "%s",
|
||||
inet_ntop(AF_INET,
|
||||
&bi->attr->mp_nexthop_global_in,
|
||||
&bpi->attr->mp_nexthop_global_in,
|
||||
buf, BUFSIZ));
|
||||
INCP;
|
||||
} else if (af == AF_INET6) {
|
||||
r = snprintf(p, REMAIN, "%s",
|
||||
inet_ntop(AF_INET6,
|
||||
&bi->attr->mp_nexthop_global,
|
||||
&bpi->attr->mp_nexthop_global,
|
||||
buf, BUFSIZ));
|
||||
INCP;
|
||||
} else {
|
||||
@ -565,7 +566,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
/*
|
||||
* 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",
|
||||
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
||||
BUFSIZ));
|
||||
@ -573,7 +574,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
}
|
||||
|
||||
/* Lifetime */
|
||||
if (rfapiGetVncLifetime(bi->attr, &lifetime)) {
|
||||
if (rfapiGetVncLifetime(bpi->attr, &lifetime)) {
|
||||
r = snprintf(p, REMAIN, " nolife");
|
||||
INCP;
|
||||
} else {
|
||||
@ -585,7 +586,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
}
|
||||
|
||||
/* RFP option lengths */
|
||||
for (pEncap = bi->attr->vnc_subtlvs; pEncap;
|
||||
for (pEncap = bpi->attr->vnc_subtlvs; pEncap;
|
||||
pEncap = pEncap->next) {
|
||||
|
||||
if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) {
|
||||
@ -604,8 +605,8 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
}
|
||||
|
||||
/* RT list */
|
||||
if (bi->attr->ecommunity) {
|
||||
s = ecommunity_ecom2str(bi->attr->ecommunity,
|
||||
if (bpi->attr->ecommunity) {
|
||||
s = ecommunity_ecom2str(bpi->attr->ecommunity,
|
||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||
r = snprintf(p, REMAIN, " %s", s);
|
||||
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;
|
||||
|
||||
r = snprintf(p, REMAIN, " p@%p", bi->peer);
|
||||
r = snprintf(p, REMAIN, " p@%p", bpi->peer);
|
||||
INCP;
|
||||
|
||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
||||
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||
r = snprintf(p, REMAIN, " HD=yes");
|
||||
INCP;
|
||||
} else {
|
||||
@ -627,15 +628,16 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
INCP;
|
||||
}
|
||||
|
||||
if (bi->attr) {
|
||||
if (bpi->attr) {
|
||||
|
||||
if (bi->attr->weight) {
|
||||
r = snprintf(p, REMAIN, " W=%d", bi->attr->weight);
|
||||
if (bpi->attr->weight) {
|
||||
r = snprintf(p, REMAIN, " W=%d", bpi->attr->weight);
|
||||
INCP;
|
||||
}
|
||||
|
||||
if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
|
||||
r = snprintf(p, REMAIN, " LP=%d", bi->attr->local_pref);
|
||||
if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
|
||||
r = snprintf(p, REMAIN, " LP=%d",
|
||||
bpi->attr->local_pref);
|
||||
INCP;
|
||||
} else {
|
||||
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),
|
||||
bi->sub_type);
|
||||
r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bpi->type),
|
||||
bpi->sub_type);
|
||||
INCP;
|
||||
|
||||
fp(out, "%s%s", line, HVTYNL);
|
||||
@ -656,7 +658,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
HVTYNL);
|
||||
}
|
||||
|
||||
if (!rfapiGetL2o(bi->attr, &l2o_buf)) {
|
||||
if (!rfapiGetL2o(bpi->attr, &l2o_buf)) {
|
||||
fp(out,
|
||||
" 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],
|
||||
@ -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,
|
||||
HVTYNL);
|
||||
}
|
||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
||||
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||
const char *sp;
|
||||
|
||||
sp = rfapi_ntop(bi->extra->vnc.import.aux_prefix.family,
|
||||
&bi->extra->vnc.import.aux_prefix.u.prefix, buf,
|
||||
BUFSIZ);
|
||||
sp = rfapi_ntop(bpi->extra->vnc.import.aux_prefix.family,
|
||||
&bpi->extra->vnc.import.aux_prefix.u.prefix,
|
||||
buf, BUFSIZ);
|
||||
buf[BUFSIZ - 1] = 0;
|
||||
if (sp) {
|
||||
fp(out, " IP: %s%s", sp, HVTYNL);
|
||||
@ -678,7 +680,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
||||
}
|
||||
{
|
||||
struct rfapi_un_option *uo =
|
||||
rfapi_encap_tlv_to_un_option(bi->attr);
|
||||
rfapi_encap_tlv_to_un_option(bpi->attr);
|
||||
if (uo) {
|
||||
rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel);
|
||||
rfapi_un_options_free(uo);
|
||||
@ -734,13 +736,13 @@ static void rfapiDebugPrintMonitorEncap(void *stream,
|
||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
|
||||
fp(out, " Mon m=%p, next=%p, node=%p, bi=%p%s", m, m->next, m->node,
|
||||
m->bi, HVTYNL);
|
||||
fp(out, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m, m->next, m->node,
|
||||
m->bpi, HVTYNL);
|
||||
}
|
||||
|
||||
void rfapiShowItNode(void *stream, struct agg_node *rn)
|
||||
{
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
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),
|
||||
rn->p.prefixlen, rn, rn->lock, HVTYNL);
|
||||
|
||||
for (bi = rn->info; bi; bi = bi->next) {
|
||||
rfapiPrintBi(stream, bi);
|
||||
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||
rfapiPrintBi(stream, bpi);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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) {
|
||||
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 */
|
||||
HVTYNL);
|
||||
|
||||
for (bi = rn->info; bi; bi = bi->next) {
|
||||
rfapiPrintBi(stream, bi);
|
||||
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||
rfapiPrintBi(stream, bpi);
|
||||
}
|
||||
|
||||
if (isvpn) {
|
||||
@ -1008,7 +1010,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
|
||||
}
|
||||
|
||||
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 *, ...);
|
||||
struct vty *vty;
|
||||
@ -1047,26 +1049,26 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||
* UN addr
|
||||
*/
|
||||
buf_un[0] = 0;
|
||||
if (!rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) {
|
||||
if (!rfapiGetUnAddrOfVpnBi(bpi, &pfx_un)) {
|
||||
snprintf(buf_un, BUFSIZ, "%s",
|
||||
inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop,
|
||||
BUFSIZ));
|
||||
}
|
||||
|
||||
rfapiGetTunnelType(bi->attr, &tun_type);
|
||||
rfapiGetTunnelType(bpi->attr, &tun_type);
|
||||
/*
|
||||
* VN addr
|
||||
*/
|
||||
buf_vn[0] = 0;
|
||||
rfapiNexthop2Prefix(bi->attr, &pfx_vn);
|
||||
rfapiNexthop2Prefix(bpi->attr, &pfx_vn);
|
||||
if (tun_type == BGP_ENCAP_TYPE_MPLS) {
|
||||
/* MPLS carries un in nrli next hop (same as vn for IP tunnels)
|
||||
*/
|
||||
snprintf(buf_un, BUFSIZ, "%s",
|
||||
inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
|
||||
BUFSIZ));
|
||||
if (bi->extra) {
|
||||
uint32_t l = decode_label(&bi->extra->label[0]);
|
||||
if (bpi->extra) {
|
||||
uint32_t l = decode_label(&bpi->extra->label[0]);
|
||||
snprintf(buf_vn, BUFSIZ, "Label: %d", l);
|
||||
} else /* should never happen */
|
||||
{
|
||||
@ -1085,10 +1087,10 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||
* See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
|
||||
* back to cost.
|
||||
*/
|
||||
if (bi->attr) {
|
||||
if (bpi->attr) {
|
||||
uint32_t local_pref;
|
||||
if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
||||
local_pref = bi->attr->local_pref;
|
||||
if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
||||
local_pref = bpi->attr->local_pref;
|
||||
else
|
||||
local_pref = 0;
|
||||
cost = (local_pref > 255) ? 0 : 255 - local_pref;
|
||||
@ -1103,7 +1105,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||
|
||||
/* Lifetime */
|
||||
/* NB rfapiGetVncLifetime sets infinite value when returning !0 */
|
||||
if (rfapiGetVncLifetime(bi->attr, &lifetime)
|
||||
if (rfapiGetVncLifetime(bpi->attr, &lifetime)
|
||||
|| (lifetime == RFAPI_INFINITE_LIFETIME)) {
|
||||
|
||||
fp(out, "%-10s ", "infinite");
|
||||
@ -1113,20 +1115,21 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||
fp(out, "%-10s ", buf_lifetime);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra
|
||||
&& bi->extra->vnc.import.timer) {
|
||||
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
|
||||
&& bpi->extra->vnc.import.timer) {
|
||||
|
||||
uint32_t remaining;
|
||||
time_t age;
|
||||
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);
|
||||
|
||||
#if RFAPI_REGISTRATIONS_REPORT_AGE
|
||||
/*
|
||||
* 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
|
||||
* original calculation.
|
||||
@ -1140,12 +1143,12 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||
|
||||
fp(out, "%-10s ", buf_age);
|
||||
|
||||
} else if (RFAPI_LOCAL_BI(bi)) {
|
||||
} else if (RFAPI_LOCAL_BI(bpi)) {
|
||||
|
||||
char buf_age[BUFSIZ];
|
||||
|
||||
if (bi->extra && bi->extra->vnc.import.create_time) {
|
||||
rfapiFormatAge(bi->extra->vnc.import.create_time,
|
||||
if (bpi->extra && bpi->extra->vnc.import.create_time) {
|
||||
rfapiFormatAge(bpi->extra->vnc.import.create_time,
|
||||
buf_age, BUFSIZ);
|
||||
} else {
|
||||
buf_age[0] = '?';
|
||||
@ -1161,12 +1164,12 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||
* 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;
|
||||
|
||||
sp = rfapi_ntop(
|
||||
bi->extra->vnc.import.aux_prefix.family,
|
||||
&bi->extra->vnc.import.aux_prefix.u.prefix,
|
||||
bpi->extra->vnc.import.aux_prefix.family,
|
||||
&bpi->extra->vnc.import.aux_prefix.u.prefix,
|
||||
buf_ntop, BUFSIZ);
|
||||
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) {
|
||||
uint32_t l = decode_label(&bi->extra->label[0]);
|
||||
if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra) {
|
||||
uint32_t l = decode_label(&bpi->extra->label[0]);
|
||||
if (!MPLS_LABEL_IS_NULL(l)) {
|
||||
fp(out, " Label: %d", l);
|
||||
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;
|
||||
rn = agg_route_next(rn)) {
|
||||
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
int count_only;
|
||||
|
||||
/* allow for wider or more narrow mask from user */
|
||||
@ -1232,30 +1235,32 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
||||
else
|
||||
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 */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!show_remote && !RFAPI_LOCAL_BI(bi)) {
|
||||
if (!show_remote && !RFAPI_LOCAL_BI(bpi)) {
|
||||
|
||||
/* remote route */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (show_expiring
|
||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
||||
&& !CHECK_FLAG(bpi->flags,
|
||||
BGP_PATH_REMOVED))
|
||||
continue;
|
||||
|
||||
if (!show_expiring
|
||||
&& CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
||||
&& CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||
continue;
|
||||
|
||||
if (bi->type == ZEBRA_ROUTE_BGP_DIRECT
|
||||
|| bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
|
||||
if (bpi->type == ZEBRA_ROUTE_BGP_DIRECT
|
||||
|| bpi->type
|
||||
== ZEBRA_ROUTE_BGP_DIRECT_EXT) {
|
||||
if (!show_imported)
|
||||
continue;
|
||||
} else {
|
||||
@ -1277,7 +1282,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
||||
type = "Holddown";
|
||||
} else {
|
||||
if (RFAPI_LOCAL_BI(
|
||||
bi)) {
|
||||
bpi)) {
|
||||
type = "Local";
|
||||
} else {
|
||||
type = "Remote";
|
||||
@ -1327,7 +1332,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
||||
"Lifetime", agetype, HVTYNL);
|
||||
}
|
||||
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 */
|
||||
struct bgp_node *bn;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
uint8_t type = ZEBRA_ROUTE_BGP;
|
||||
struct bgp *bgp;
|
||||
int printed = 0;
|
||||
@ -1543,7 +1548,7 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
||||
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
|
||||
*/
|
||||
|
||||
@ -1565,12 +1570,12 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
||||
|
||||
vty_out(vty, " bn=%p%s", bn, HVTYNL);
|
||||
|
||||
for (bi = bn->info; bi; bi = bi->next) {
|
||||
if (bi->peer == rfd->peer && bi->type == type
|
||||
&& bi->sub_type == BGP_ROUTE_RFP && bi->extra
|
||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||
if (bpi->peer == rfd->peer && bpi->type == type
|
||||
&& bpi->sub_type == BGP_ROUTE_RFP && bpi->extra
|
||||
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||
|
||||
rfapiPrintBi(vty, bi);
|
||||
rfapiPrintBi(vty, bpi);
|
||||
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,
|
||||
struct bgp_info *bi)
|
||||
struct bgp_path_info *bpi)
|
||||
{
|
||||
struct attr *attr = bi->attr;
|
||||
struct peer *peer = bi->peer;
|
||||
struct attr *attr = bpi->attr;
|
||||
struct peer *peer = bpi->peer;
|
||||
struct prefix *prefix = &rn->p;
|
||||
afi_t afi = family2afi(prefix->family);
|
||||
struct bgp_node *urn;
|
||||
struct bgp_info *ubi;
|
||||
struct bgp_path_info *ubpi;
|
||||
struct attr hattr;
|
||||
struct attr *iattr;
|
||||
struct prefix ce_nexthop;
|
||||
@ -193,10 +193,10 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bi->type != ZEBRA_ROUTE_BGP)
|
||||
|| (bi->sub_type != BGP_ROUTE_NORMAL
|
||||
&& bi->sub_type != BGP_ROUTE_RFP
|
||||
&& bi->sub_type != BGP_ROUTE_STATIC)) {
|
||||
if ((bpi->type != ZEBRA_ROUTE_BGP)
|
||||
|| (bpi->sub_type != BGP_ROUTE_NORMAL
|
||||
&& bpi->sub_type != BGP_ROUTE_RFP
|
||||
&& bpi->sub_type != BGP_ROUTE_STATIC)) {
|
||||
|
||||
vnc_zlog_debug_verbose(
|
||||
"%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,
|
||||
prefix, NULL);
|
||||
for (ubi = urn->info; ubi; ubi = ubi->next) {
|
||||
for (ubpi = urn->info; ubpi; ubpi = ubpi->next) {
|
||||
struct prefix unicast_nexthop;
|
||||
|
||||
if (CHECK_FLAG(ubi->flags, BGP_INFO_REMOVED))
|
||||
if (CHECK_FLAG(ubpi->flags, BGP_PATH_REMOVED))
|
||||
continue;
|
||||
|
||||
rfapiUnicastNexthop2Prefix(afi, ubi->attr, &unicast_nexthop);
|
||||
rfapiUnicastNexthop2Prefix(afi, ubpi->attr, &unicast_nexthop);
|
||||
|
||||
if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT
|
||||
&& ubi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||
&& ubi->peer == peer
|
||||
if (ubpi->type == ZEBRA_ROUTE_VNC_DIRECT
|
||||
&& ubpi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||
&& ubpi->peer == peer
|
||||
&& prefix_same(&unicast_nexthop, &ce_nexthop)) {
|
||||
|
||||
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);
|
||||
if (bgp->rfapi_cfg->routemap_export_bgp) {
|
||||
struct bgp_info info;
|
||||
struct bgp_path_info info;
|
||||
route_map_result_t ret;
|
||||
|
||||
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
|
||||
*/
|
||||
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);
|
||||
struct bgp_info *vbi;
|
||||
struct bgp_path_info *vbpi;
|
||||
struct prefix ce_nexthop;
|
||||
|
||||
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
|
||||
* 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",
|
||||
__func__);
|
||||
return;
|
||||
@ -376,13 +376,13 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||
* route from the unicast RIB
|
||||
*/
|
||||
|
||||
for (vbi = rn->info; vbi; vbi = vbi->next) {
|
||||
for (vbpi = rn->info; vbpi; vbpi = vbpi->next) {
|
||||
struct prefix ce;
|
||||
if (bi == vbi)
|
||||
if (bpi == vbpi)
|
||||
continue;
|
||||
if (bi->peer != vbi->peer)
|
||||
if (bpi->peer != vbpi->peer)
|
||||
continue;
|
||||
if (getce(bgp, vbi->attr, &ce))
|
||||
if (getce(bgp, vbpi->attr, &ce))
|
||||
continue;
|
||||
if (prefix_same(&ce, &ce_nexthop)) {
|
||||
vnc_zlog_debug_verbose(
|
||||
@ -395,8 +395,8 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||
/*
|
||||
* withdraw the route
|
||||
*/
|
||||
bgp_withdraw(bi->peer, &rn->p, 0, /* addpath_id */
|
||||
NULL, /* attr, ignored */
|
||||
bgp_withdraw(bpi->peer, &rn->p, 0, /* addpath_id */
|
||||
NULL, /* attr, ignored */
|
||||
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
||||
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
|
||||
NULL, 0, NULL); /* tag 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)
|
||||
{
|
||||
struct agg_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *ri;
|
||||
|
||||
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;
|
||||
rn = bgp_route_next(rn)) {
|
||||
|
||||
struct bgp_info *ri;
|
||||
struct bgp_info *next;
|
||||
struct bgp_path_info *ri;
|
||||
struct bgp_path_info *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)
|
||||
{
|
||||
struct ecommunity *new;
|
||||
struct bgp_info *bi;
|
||||
struct bgp_path_info *bpi;
|
||||
|
||||
if (!rn->info)
|
||||
return NULL;
|
||||
|
||||
new = ecommunity_new();
|
||||
|
||||
for (bi = rn->info; bi; bi = bi->next) {
|
||||
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||
|
||||
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:
|
||||
memset(&roec, 0, sizeof(roec));
|
||||
roec.val[0] = 0x01;
|
||||
roec.val[1] = 0x03;
|
||||
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[7] = 0;
|
||||
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 attr hattr;
|
||||
struct attr *iattr;
|
||||
struct bgp_info info;
|
||||
struct bgp_path_info info;
|
||||
|
||||
if (rfapiRaddr2Qprefix(&irfd->vn_addr,
|
||||
&nhp))
|
||||
@ -1165,7 +1165,7 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
|
||||
afi_t afi, struct rfapi_descriptor *irfd)
|
||||
{
|
||||
struct prefix nhp;
|
||||
struct bgp_info info;
|
||||
struct bgp_path_info info;
|
||||
struct attr hattr;
|
||||
struct attr *iattr;
|
||||
|
||||
@ -1629,7 +1629,7 @@ void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi)
|
||||
|
||||
/*
|
||||
* "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?
|
||||
*/
|
||||
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))
|
||||
return;
|
||||
if (hc->routemap_export_bgp) {
|
||||
struct bgp_info info;
|
||||
struct bgp_path_info info;
|
||||
route_map_result_t ret;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
@ -1753,7 +1753,7 @@ static int vncExportWithdrawTimer(struct thread *t)
|
||||
|
||||
/*
|
||||
* "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?
|
||||
*/
|
||||
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_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *ri;
|
||||
|
||||
memset(&prd, 0, sizeof(prd));
|
||||
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) {
|
||||
struct bgp_info info;
|
||||
struct bgp_path_info info;
|
||||
route_map_result_t ret;
|
||||
|
||||
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;
|
||||
rn = bgp_route_next(rn)) {
|
||||
|
||||
struct bgp_info *ri;
|
||||
struct bgp_info *next;
|
||||
struct bgp_path_info *ri;
|
||||
struct bgp_path_info *next;
|
||||
|
||||
for (ri = rn->info, next = NULL; ri; ri = next) {
|
||||
|
||||
|
@ -30,10 +30,10 @@
|
||||
#include "rfapi_private.h"
|
||||
|
||||
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,
|
||||
struct bgp_info *bi);
|
||||
struct bgp_path_info *bpi);
|
||||
|
||||
extern void vnc_direct_bgp_add_prefix(struct bgp *bgp,
|
||||
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 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,
|
||||
struct bgp_info *info);
|
||||
struct bgp_path_info *info);
|
||||
|
||||
extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi);
|
||||
|
||||
@ -50,25 +50,24 @@ extern void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi);
|
||||
|
||||
|
||||
extern void vnc_import_bgp_exterior_add_route(
|
||||
struct bgp *bgp, /* exterior instance, we hope */
|
||||
struct prefix *prefix, /* unicast prefix */
|
||||
struct bgp_info *info); /* unicast info */
|
||||
struct bgp *bgp, /* exterior instance, we hope */
|
||||
struct prefix *prefix, /* unicast prefix */
|
||||
struct bgp_path_info *info); /* unicast info */
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_del_route(struct bgp *bgp,
|
||||
struct prefix *prefix, /* unicast prefix */
|
||||
struct bgp_info *info); /* unicast info */
|
||||
extern void vnc_import_bgp_exterior_del_route(
|
||||
struct bgp *bgp, struct prefix *prefix, /* unicast prefix */
|
||||
struct bgp_path_info *info); /* unicast info */
|
||||
|
||||
extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||
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(
|
||||
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||
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_ */
|
||||
|
@ -29,13 +29,13 @@
|
||||
|
||||
extern void vnc_import_bgp_exterior_add_route_interior(
|
||||
struct bgp *bgp, struct rfapi_import_table *it,
|
||||
struct agg_node *rn_interior, /* VPN IT node */
|
||||
struct bgp_info *bi_interior); /* VPN IT route */
|
||||
struct agg_node *rn_interior, /* VPN IT node */
|
||||
struct bgp_path_info *bpi_interior); /* VPN IT route */
|
||||
|
||||
extern void vnc_import_bgp_exterior_del_route_interior(
|
||||
struct bgp *bgp, struct rfapi_import_table *it,
|
||||
struct agg_node *rn_interior, /* VPN IT node */
|
||||
struct bgp_info *bi_interior); /* VPN IT route */
|
||||
struct agg_node *rn_interior, /* VPN IT node */
|
||||
struct bgp_path_info *bpi_interior); /* VPN IT route */
|
||||
|
||||
extern void
|
||||
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)) {
|
||||
|
||||
struct bgp_info *ri;
|
||||
struct bgp_path_info *ri;
|
||||
|
||||
for (ri = rn->info; ri; ri = ri->next) {
|
||||
if (ri->type
|
||||
|
@ -241,7 +241,7 @@ Legend:
|
||||
/\ 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
|
||||
|
@ -16,7 +16,7 @@
|
||||
# ...
|
||||
# (gdb) cont
|
||||
# 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
|
||||
# IPv4:10.1.1.0/24
|
||||
# (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);
|
||||
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[1], .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]},
|
||||
};
|
||||
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)
|
||||
{
|
||||
@ -247,7 +247,7 @@ static int run_bgp_mp_list(testcase_t *t)
|
||||
{
|
||||
struct list mp_list;
|
||||
struct listnode *mp_node;
|
||||
struct bgp_info *info;
|
||||
struct bgp_path_info *info;
|
||||
int i;
|
||||
int test_result = TEST_PASSED;
|
||||
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;
|
||||
|
||||
static int setup_bgp_info_mpath_update(testcase_t *t)
|
||||
static int setup_bgp_path_info_mpath_update(testcase_t *t)
|
||||
{
|
||||
int i;
|
||||
str2prefix("42.1.1.0/24", &test_rn.p);
|
||||
setup_bgp_mp_list(t);
|
||||
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;
|
||||
}
|
||||
|
||||
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 bgp_maxpaths_cfg mp_cfg = {3, 3};
|
||||
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]);
|
||||
new_best = &test_mp_list_info[3];
|
||||
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);
|
||||
EXPECT_TRUE(bgp_info_mpath_count(new_best) == 2, test_result);
|
||||
mpath = bgp_info_mpath_first(new_best);
|
||||
EXPECT_TRUE(bgp_path_info_mpath_count(new_best) == 2, test_result);
|
||||
mpath = bgp_path_info_mpath_first(new_best);
|
||||
EXPECT_TRUE(mpath == &test_mp_list_info[0], test_result);
|
||||
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_INFO_MULTIPATH), test_result);
|
||||
mpath = bgp_info_mpath_next(mpath);
|
||||
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_PATH_MULTIPATH), test_result);
|
||||
mpath = bgp_path_info_mpath_next(mpath);
|
||||
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[1]);
|
||||
new_best = &test_mp_list_info[0];
|
||||
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);
|
||||
EXPECT_TRUE(bgp_info_mpath_count(new_best) == 1, test_result);
|
||||
mpath = bgp_info_mpath_first(new_best);
|
||||
EXPECT_TRUE(bgp_path_info_mpath_count(new_best) == 1, test_result);
|
||||
mpath = bgp_path_info_mpath_first(new_best);
|
||||
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(test_mp_list_info[0].flags, BGP_INFO_MULTIPATH),
|
||||
EXPECT_TRUE(CHECK_FLAG(mpath->flags, BGP_PATH_MULTIPATH), test_result);
|
||||
EXPECT_TRUE(!CHECK_FLAG(test_mp_list_info[0].flags, BGP_PATH_MULTIPATH),
|
||||
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;
|
||||
|
||||
@ -353,11 +355,11 @@ static int cleanup_bgp_info_mpath_update(testcase_t *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
testcase_t test_bgp_info_mpath_update = {
|
||||
.desc = "Test bgp_info_mpath_update",
|
||||
.setup = setup_bgp_info_mpath_update,
|
||||
.run = run_bgp_info_mpath_update,
|
||||
.cleanup = cleanup_bgp_info_mpath_update,
|
||||
testcase_t test_bgp_path_info_mpath_update = {
|
||||
.desc = "Test bgp_path_info_mpath_update",
|
||||
.setup = setup_bgp_path_info_mpath_update,
|
||||
.run = run_bgp_path_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[] = {
|
||||
&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 *));
|
||||
|
@ -5,5 +5,5 @@ class TestMpath(frrtest.TestMultiOut):
|
||||
|
||||
TestMpath.okfail("bgp maximum-paths config")
|
||||
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