mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 18:09:00 +00:00
Addpath does not work for soft-reconfiguration
This commit is contained in:
parent
801a9bcc7f
commit
43143c8f2c
@ -189,13 +189,14 @@ bgp_adj_out_lookup (struct peer *peer, struct prefix *p,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr)
|
bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr,
|
||||||
|
u_int32_t addpath_id)
|
||||||
{
|
{
|
||||||
struct bgp_adj_in *adj;
|
struct bgp_adj_in *adj;
|
||||||
|
|
||||||
for (adj = rn->adj_in; adj; adj = adj->next)
|
for (adj = rn->adj_in; adj; adj = adj->next)
|
||||||
{
|
{
|
||||||
if (adj->peer == peer)
|
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
|
||||||
{
|
{
|
||||||
if (adj->attr != attr)
|
if (adj->attr != attr)
|
||||||
{
|
{
|
||||||
@ -208,6 +209,7 @@ bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr)
|
|||||||
adj = XCALLOC (MTYPE_BGP_ADJ_IN, sizeof (struct bgp_adj_in));
|
adj = XCALLOC (MTYPE_BGP_ADJ_IN, sizeof (struct bgp_adj_in));
|
||||||
adj->peer = peer_lock (peer); /* adj_in peer reference */
|
adj->peer = peer_lock (peer); /* adj_in peer reference */
|
||||||
adj->attr = bgp_attr_intern (attr);
|
adj->attr = bgp_attr_intern (attr);
|
||||||
|
adj->addpath_rx_id = addpath_id;
|
||||||
BGP_ADJ_IN_ADD (rn, adj);
|
BGP_ADJ_IN_ADD (rn, adj);
|
||||||
bgp_lock_node (rn);
|
bgp_lock_node (rn);
|
||||||
}
|
}
|
||||||
@ -222,21 +224,27 @@ bgp_adj_in_remove (struct bgp_node *rn, struct bgp_adj_in *bai)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer)
|
bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
|
||||||
|
u_int32_t addpath_id)
|
||||||
{
|
{
|
||||||
struct bgp_adj_in *adj;
|
struct bgp_adj_in *adj;
|
||||||
|
struct bgp_adj_in *adj_next;
|
||||||
|
|
||||||
for (adj = rn->adj_in; adj; adj = adj->next)
|
adj = rn->adj_in;
|
||||||
if (adj->peer == peer)
|
while (adj)
|
||||||
break;
|
{
|
||||||
|
adj_next = adj->next;
|
||||||
if (! adj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
|
||||||
|
{
|
||||||
bgp_adj_in_remove (rn, adj);
|
bgp_adj_in_remove (rn, adj);
|
||||||
bgp_unlock_node (rn);
|
bgp_unlock_node (rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adj = adj_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_sync_init (struct peer *peer)
|
bgp_sync_init (struct peer *peer)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +101,9 @@ struct bgp_adj_in
|
|||||||
|
|
||||||
/* Received attribute. */
|
/* Received attribute. */
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
|
/* Addpath identifier */
|
||||||
|
u_int32_t addpath_rx_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BGP advertisement list. */
|
/* BGP advertisement list. */
|
||||||
@ -168,8 +171,8 @@ struct bgp_synchronize
|
|||||||
extern int bgp_adj_out_lookup (struct peer *, struct prefix *, afi_t, safi_t,
|
extern int bgp_adj_out_lookup (struct peer *, struct prefix *, afi_t, safi_t,
|
||||||
struct bgp_node *);
|
struct bgp_node *);
|
||||||
|
|
||||||
extern void bgp_adj_in_set (struct bgp_node *, struct peer *, struct attr *);
|
extern void bgp_adj_in_set (struct bgp_node *, struct peer *, struct attr *, u_int32_t);
|
||||||
extern void bgp_adj_in_unset (struct bgp_node *, struct peer *);
|
extern void bgp_adj_in_unset (struct bgp_node *, struct peer *, u_int32_t);
|
||||||
extern void bgp_adj_in_remove (struct bgp_node *, struct bgp_adj_in *);
|
extern void bgp_adj_in_remove (struct bgp_node *, struct bgp_adj_in *);
|
||||||
|
|
||||||
extern void bgp_sync_init (struct peer *);
|
extern void bgp_sync_init (struct peer *);
|
||||||
|
@ -2882,7 +2882,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
|||||||
Adj-RIBs-In. */
|
Adj-RIBs-In. */
|
||||||
if (! soft_reconfig && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
|
if (! soft_reconfig && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
|
||||||
&& peer != bgp->peer_self)
|
&& peer != bgp->peer_self)
|
||||||
bgp_adj_in_set (rn, peer, attr);
|
bgp_adj_in_set (rn, peer, attr, addpath_id);
|
||||||
|
|
||||||
/* Check previously received route. */
|
/* Check previously received route. */
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
@ -3281,7 +3281,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
|||||||
further calculation. */
|
further calculation. */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
|
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
|
||||||
&& peer != bgp->peer_self)
|
&& peer != bgp->peer_self)
|
||||||
bgp_adj_in_unset (rn, peer);
|
bgp_adj_in_unset (rn, peer, addpath_id);
|
||||||
|
|
||||||
/* Lookup withdrawn route. */
|
/* Lookup withdrawn route. */
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
@ -3485,7 +3485,7 @@ bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
struct bgp_info *ri = rn->info;
|
struct bgp_info *ri = rn->info;
|
||||||
u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
|
u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
|
||||||
|
|
||||||
ret = bgp_update (peer, &rn->p, ri->addpath_rx_id, ain->attr,
|
ret = bgp_update (peer, &rn->p, ain->addpath_rx_id, ain->attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
prd, tag, 1);
|
prd, tag, 1);
|
||||||
|
|
||||||
@ -3494,7 +3494,6 @@ bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
bgp_unlock_node (rn);
|
bgp_unlock_node (rn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3543,6 +3542,9 @@ bgp_clear_route_node (struct work_queue *wq, void *data)
|
|||||||
|
|
||||||
assert (rn && peer);
|
assert (rn && peer);
|
||||||
|
|
||||||
|
/* It is possible that we have multiple paths for a prefix from a peer
|
||||||
|
* if that peer is using AddPath.
|
||||||
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
if (ri->peer == peer || cnq->purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
|
if (ri->peer == peer || cnq->purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
|
||||||
{
|
{
|
||||||
@ -3554,7 +3556,6 @@ bgp_clear_route_node (struct work_queue *wq, void *data)
|
|||||||
bgp_info_set_flag (rn, ri, BGP_INFO_STALE);
|
bgp_info_set_flag (rn, ri, BGP_INFO_STALE);
|
||||||
else
|
else
|
||||||
bgp_rib_remove (rn, ri, peer, afi, safi);
|
bgp_rib_remove (rn, ri, peer, afi, safi);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return WQ_SUCCESS;
|
return WQ_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -3624,6 +3625,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
{
|
{
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
struct bgp_adj_in *ain;
|
struct bgp_adj_in *ain;
|
||||||
|
struct bgp_adj_in *ain_next;
|
||||||
struct bgp_adj_out *aout;
|
struct bgp_adj_out *aout;
|
||||||
|
|
||||||
/* XXX:TODO: This is suboptimal, every non-empty route_node is
|
/* XXX:TODO: This is suboptimal, every non-empty route_node is
|
||||||
@ -3656,13 +3658,22 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
* Given that our per-peer prefix-counts now should be reliable,
|
* Given that our per-peer prefix-counts now should be reliable,
|
||||||
* this may actually be achievable. It doesn't seem to be a huge
|
* this may actually be achievable. It doesn't seem to be a huge
|
||||||
* problem at this time,
|
* problem at this time,
|
||||||
|
*
|
||||||
|
* It is possible that we have multiple paths for a prefix from a peer
|
||||||
|
* if that peer is using AddPath.
|
||||||
*/
|
*/
|
||||||
for (ain = rn->adj_in; ain; ain = ain->next)
|
ain = rn->adj_in;
|
||||||
|
while (ain)
|
||||||
|
{
|
||||||
|
ain_next = ain->next;
|
||||||
|
|
||||||
if (ain->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
|
if (ain->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
|
||||||
{
|
{
|
||||||
bgp_adj_in_remove (rn, ain);
|
bgp_adj_in_remove (rn, ain);
|
||||||
bgp_unlock_node (rn);
|
bgp_unlock_node (rn);
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
ain = ain_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3788,16 +3799,29 @@ bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_adj_in *ain;
|
struct bgp_adj_in *ain;
|
||||||
|
struct bgp_adj_in *ain_next;
|
||||||
|
|
||||||
table = peer->bgp->rib[afi][safi];
|
table = peer->bgp->rib[afi][safi];
|
||||||
|
|
||||||
|
/* It is possible that we have multiple paths for a prefix from a peer
|
||||||
|
* if that peer is using AddPath.
|
||||||
|
*/
|
||||||
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
|
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
|
||||||
for (ain = rn->adj_in; ain ; ain = ain->next)
|
{
|
||||||
|
ain = rn->adj_in;
|
||||||
|
|
||||||
|
while (ain)
|
||||||
|
{
|
||||||
|
ain_next = ain->next;
|
||||||
|
|
||||||
if (ain->peer == peer)
|
if (ain->peer == peer)
|
||||||
{
|
{
|
||||||
bgp_adj_in_remove (rn, ain);
|
bgp_adj_in_remove (rn, ain);
|
||||||
bgp_unlock_node (rn);
|
bgp_unlock_node (rn);
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
ain = ain_next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user