mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-27 11:44:16 +00:00
Merge pull request #3444 from donaldsharp/adj_stuff
bgpd: Convert adj_out to a RB tree
This commit is contained in:
commit
6c9e36f8e2
@ -154,7 +154,7 @@ int bgp_adj_out_lookup(struct peer *peer, struct bgp_node *rn,
|
|||||||
safi_t safi;
|
safi_t safi;
|
||||||
int addpath_capable;
|
int addpath_capable;
|
||||||
|
|
||||||
for (adj = rn->adj_out; adj; adj = adj->next)
|
RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
|
||||||
SUBGRP_FOREACH_PEER (adj->subgroup, paf)
|
SUBGRP_FOREACH_PEER (adj->subgroup, paf)
|
||||||
if (paf->peer == peer) {
|
if (paf->peer == peer) {
|
||||||
afi = SUBGRP_AFI(adj->subgroup);
|
afi = SUBGRP_AFI(adj->subgroup);
|
||||||
|
@ -67,9 +67,8 @@ struct bgp_advertise {
|
|||||||
|
|
||||||
/* BGP adjacency out. */
|
/* BGP adjacency out. */
|
||||||
struct bgp_adj_out {
|
struct bgp_adj_out {
|
||||||
/* Lined list pointer. */
|
/* RB Tree of adjacency entries */
|
||||||
struct bgp_adj_out *next;
|
RB_ENTRY(bgp_adj_out) adj_entry;
|
||||||
struct bgp_adj_out *prev;
|
|
||||||
|
|
||||||
/* Advertised subgroup. */
|
/* Advertised subgroup. */
|
||||||
struct update_subgroup *subgroup;
|
struct update_subgroup *subgroup;
|
||||||
@ -89,6 +88,10 @@ struct bgp_adj_out {
|
|||||||
struct bgp_advertise *adv;
|
struct bgp_advertise *adv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
RB_HEAD(bgp_adj_out_rb, bgp_adj_out);
|
||||||
|
RB_PROTOTYPE(bgp_adj_out_rb, bgp_adj_out, adj_entry,
|
||||||
|
bgp_adj_out_compare);
|
||||||
|
|
||||||
/* BGP adjacency in. */
|
/* BGP adjacency in. */
|
||||||
struct bgp_adj_in {
|
struct bgp_adj_in {
|
||||||
/* Linked list pointer. */
|
/* Linked list pointer. */
|
||||||
@ -134,8 +137,6 @@ struct bgp_synchronize {
|
|||||||
|
|
||||||
#define BGP_ADJ_IN_ADD(N, A) BGP_PATH_INFO_ADD(N, A, adj_in)
|
#define BGP_ADJ_IN_ADD(N, A) BGP_PATH_INFO_ADD(N, A, adj_in)
|
||||||
#define BGP_ADJ_IN_DEL(N, A) BGP_PATH_INFO_DEL(N, A, adj_in)
|
#define BGP_ADJ_IN_DEL(N, A) BGP_PATH_INFO_DEL(N, A, adj_in)
|
||||||
#define BGP_ADJ_OUT_ADD(N, A) BGP_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) \
|
#define BGP_ADV_FIFO_ADD(F, N) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -10560,7 +10560,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
|
|||||||
output_count++;
|
output_count++;
|
||||||
}
|
}
|
||||||
} else if (type == bgp_show_adj_route_advertised) {
|
} else if (type == bgp_show_adj_route_advertised) {
|
||||||
for (adj = rn->adj_out; adj; adj = adj->next)
|
RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
|
||||||
SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
|
SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
|
||||||
if (paf->peer != peer || !adj->attr)
|
if (paf->peer != peer || !adj->attr)
|
||||||
continue;
|
continue;
|
||||||
|
@ -67,6 +67,8 @@ static struct route_node *bgp_node_create(route_table_delegate_t *delegate,
|
|||||||
{
|
{
|
||||||
struct bgp_node *node;
|
struct bgp_node *node;
|
||||||
node = XCALLOC(MTYPE_BGP_NODE, sizeof(struct bgp_node));
|
node = XCALLOC(MTYPE_BGP_NODE, sizeof(struct bgp_node));
|
||||||
|
|
||||||
|
RB_INIT(bgp_adj_out_rb, &node->adj_out);
|
||||||
return bgp_node_to_rnode(node);
|
return bgp_node_to_rnode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "bgpd.h"
|
#include "bgpd.h"
|
||||||
|
#include "bgp_advertise.h"
|
||||||
|
|
||||||
struct bgp_table {
|
struct bgp_table {
|
||||||
/* table belongs to this instance */
|
/* table belongs to this instance */
|
||||||
@ -52,7 +53,7 @@ struct bgp_node {
|
|||||||
*/
|
*/
|
||||||
ROUTE_NODE_FIELDS
|
ROUTE_NODE_FIELDS
|
||||||
|
|
||||||
struct bgp_adj_out *adj_out;
|
struct bgp_adj_out_rb adj_out;
|
||||||
|
|
||||||
struct bgp_adj_in *adj_in;
|
struct bgp_adj_in *adj_in;
|
||||||
|
|
||||||
|
@ -55,12 +55,24 @@
|
|||||||
/********************
|
/********************
|
||||||
* PRIVATE FUNCTIONS
|
* PRIVATE FUNCTIONS
|
||||||
********************/
|
********************/
|
||||||
|
static int bgp_adj_out_compare(const struct bgp_adj_out *o1,
|
||||||
|
const struct bgp_adj_out *o2)
|
||||||
|
{
|
||||||
|
if (o1->subgroup < o2->subgroup)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (o1->subgroup > o2->subgroup)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
RB_GENERATE(bgp_adj_out_rb, bgp_adj_out, adj_entry, bgp_adj_out_compare);
|
||||||
|
|
||||||
static inline struct bgp_adj_out *adj_lookup(struct bgp_node *rn,
|
static inline struct bgp_adj_out *adj_lookup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
uint32_t addpath_tx_id)
|
uint32_t addpath_tx_id)
|
||||||
{
|
{
|
||||||
struct bgp_adj_out *adj;
|
struct bgp_adj_out *adj, lookup;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -76,19 +88,16 @@ static inline struct bgp_adj_out *adj_lookup(struct bgp_node *rn,
|
|||||||
|
|
||||||
/* update-groups that do not support addpath will pass 0 for
|
/* update-groups that do not support addpath will pass 0 for
|
||||||
* addpath_tx_id so do not both matching against it */
|
* addpath_tx_id so do not both matching against it */
|
||||||
for (adj = rn->adj_out; adj; adj = adj->next) {
|
lookup.subgroup = subgrp;
|
||||||
if (adj->subgroup == subgrp) {
|
adj = RB_FIND(bgp_adj_out_rb, &rn->adj_out, &lookup);
|
||||||
if (addpath_capable) {
|
if (adj) {
|
||||||
if (adj->addpath_tx_id == addpath_tx_id) {
|
if (addpath_capable) {
|
||||||
break;
|
if (adj->addpath_tx_id == addpath_tx_id)
|
||||||
}
|
return adj;
|
||||||
} else {
|
} else
|
||||||
break;
|
return adj;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
return adj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adj_free(struct bgp_adj_out *adj)
|
static void adj_free(struct bgp_adj_out *adj)
|
||||||
@ -110,8 +119,7 @@ static void subgrp_withdraw_stale_addpath(struct updwalk_context *ctx,
|
|||||||
|
|
||||||
/* Look through all of the paths we have advertised for this rn and send
|
/* Look through all of the paths we have advertised for this rn and send
|
||||||
* a withdraw for the ones that are no longer present */
|
* a withdraw for the ones that are no longer present */
|
||||||
for (adj = ctx->rn->adj_out; adj; adj = adj_next) {
|
RB_FOREACH_SAFE (adj, bgp_adj_out_rb, &ctx->rn->adj_out, adj_next) {
|
||||||
adj_next = adj->next;
|
|
||||||
|
|
||||||
if (adj->subgroup == subgrp) {
|
if (adj->subgroup == subgrp) {
|
||||||
for (pi = ctx->rn->info; pi; pi = pi->next) {
|
for (pi = ctx->rn->info; pi; pi = pi->next) {
|
||||||
@ -204,10 +212,9 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
/* Find the addpath_tx_id of the path we
|
/* Find the addpath_tx_id of the path we
|
||||||
* had advertised and
|
* had advertised and
|
||||||
* send a withdraw */
|
* send a withdraw */
|
||||||
for (adj = ctx->rn->adj_out; adj;
|
RB_FOREACH_SAFE (adj, bgp_adj_out_rb,
|
||||||
adj = adj_next) {
|
&ctx->rn->adj_out,
|
||||||
adj_next = adj->next;
|
adj_next) {
|
||||||
|
|
||||||
if (adj->subgroup == subgrp) {
|
if (adj->subgroup == subgrp) {
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, NULL,
|
subgrp, NULL,
|
||||||
@ -243,7 +250,7 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp,
|
|||||||
output_count = 0;
|
output_count = 0;
|
||||||
|
|
||||||
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 (adj = rn->adj_out; adj; adj = adj->next)
|
RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
|
||||||
if (adj->subgroup == subgrp) {
|
if (adj->subgroup == subgrp) {
|
||||||
if (header1) {
|
if (header1) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
@ -394,7 +401,7 @@ struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp,
|
|||||||
adj = XCALLOC(MTYPE_BGP_ADJ_OUT, sizeof(struct bgp_adj_out));
|
adj = XCALLOC(MTYPE_BGP_ADJ_OUT, sizeof(struct bgp_adj_out));
|
||||||
adj->subgroup = subgrp;
|
adj->subgroup = subgrp;
|
||||||
if (rn) {
|
if (rn) {
|
||||||
BGP_ADJ_OUT_ADD(rn, adj);
|
RB_INSERT(bgp_adj_out_rb, &rn->adj_out, adj);
|
||||||
bgp_lock_node(rn);
|
bgp_lock_node(rn);
|
||||||
adj->rn = rn;
|
adj->rn = rn;
|
||||||
}
|
}
|
||||||
@ -551,7 +558,7 @@ void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
|
|||||||
subgroup_trigger_write(subgrp);
|
subgroup_trigger_write(subgrp);
|
||||||
} else {
|
} else {
|
||||||
/* Remove myself from adjacency. */
|
/* Remove myself from adjacency. */
|
||||||
BGP_ADJ_OUT_DEL(rn, adj);
|
RB_REMOVE(bgp_adj_out_rb, &rn->adj_out, adj);
|
||||||
|
|
||||||
/* Free allocated information. */
|
/* Free allocated information. */
|
||||||
adj_free(adj);
|
adj_free(adj);
|
||||||
@ -572,7 +579,7 @@ void bgp_adj_out_remove_subgroup(struct bgp_node *rn, struct bgp_adj_out *adj,
|
|||||||
if (adj->adv)
|
if (adj->adv)
|
||||||
bgp_advertise_clean_subgroup(subgrp, adj);
|
bgp_advertise_clean_subgroup(subgrp, adj);
|
||||||
|
|
||||||
BGP_ADJ_OUT_DEL(rn, adj);
|
RB_REMOVE(bgp_adj_out_rb, &rn->adj_out, adj);
|
||||||
adj_free(adj);
|
adj_free(adj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user