mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-02 21:24:26 +00:00
bgpd: convert NHT code to use rb-trees instead of routing tables
Fist, routing tables aren't the most appropriate data structure to store nexthops and imported routes since we don't need to do longest prefix matches with that information. Second, by converting the NHT code to use rb-trees, we can index the nexthops using additional information, not only the destination address. This will be useful later to index bgpd's nexthops by both destination and SR-TE color. Co-authored-by: Sebastien Merle <sebastien@netdef.org> Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
ff35a11676
commit
f663c5819c
@ -35,7 +35,6 @@
|
||||
#include "filter.h"
|
||||
|
||||
#include "bgpd/bgpd.h"
|
||||
#include "bgpd/bgp_table.h"
|
||||
#include "bgpd/bgp_route.h"
|
||||
#include "bgpd/bgp_attr.h"
|
||||
#include "bgpd/bgp_nexthop.h"
|
||||
@ -48,10 +47,15 @@
|
||||
|
||||
DEFINE_MTYPE_STATIC(BGPD, MARTIAN_STRING, "BGP Martian Address Intf String");
|
||||
|
||||
char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size)
|
||||
int bgp_nexthop_cache_compare(const struct bgp_nexthop_cache *a,
|
||||
const struct bgp_nexthop_cache *b)
|
||||
{
|
||||
prefix2str(bgp_dest_get_prefix(bnc->dest), buf, size);
|
||||
return buf;
|
||||
return prefix_cmp(&a->prefix, &b->prefix);
|
||||
}
|
||||
|
||||
const char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size)
|
||||
{
|
||||
return prefix2str(&bnc->prefix, buf, size);
|
||||
}
|
||||
|
||||
void bnc_nexthop_free(struct bgp_nexthop_cache *bnc)
|
||||
@ -59,32 +63,47 @@ void bnc_nexthop_free(struct bgp_nexthop_cache *bnc)
|
||||
nexthops_free(bnc->nexthop);
|
||||
}
|
||||
|
||||
struct bgp_nexthop_cache *bnc_new(void)
|
||||
struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
|
||||
struct prefix *prefix)
|
||||
{
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
|
||||
bnc = XCALLOC(MTYPE_BGP_NEXTHOP_CACHE,
|
||||
sizeof(struct bgp_nexthop_cache));
|
||||
bnc->prefix = *prefix;
|
||||
bnc->tree = tree;
|
||||
LIST_INIT(&(bnc->paths));
|
||||
bgp_nexthop_cache_add(tree, bnc);
|
||||
|
||||
return bnc;
|
||||
}
|
||||
|
||||
void bnc_free(struct bgp_nexthop_cache *bnc)
|
||||
{
|
||||
bnc_nexthop_free(bnc);
|
||||
bgp_nexthop_cache_del(bnc->tree, bnc);
|
||||
XFREE(MTYPE_BGP_NEXTHOP_CACHE, bnc);
|
||||
}
|
||||
|
||||
/* Reset and free all BGP nexthop cache. */
|
||||
static void bgp_nexthop_cache_reset(struct bgp_table *table)
|
||||
struct bgp_nexthop_cache *bnc_find(struct bgp_nexthop_cache_head *tree,
|
||||
struct prefix *prefix)
|
||||
{
|
||||
struct bgp_nexthop_cache bnc = {};
|
||||
|
||||
if (!tree)
|
||||
return NULL;
|
||||
|
||||
bnc.prefix = *prefix;
|
||||
return bgp_nexthop_cache_find(tree, &bnc);
|
||||
}
|
||||
|
||||
/* Reset and free all BGP nexthop cache. */
|
||||
static void bgp_nexthop_cache_reset(struct bgp_nexthop_cache_head *tree)
|
||||
{
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
|
||||
for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
if (!bnc)
|
||||
continue;
|
||||
while (bgp_nexthop_cache_count(tree) > 0) {
|
||||
bnc = bgp_nexthop_cache_first(tree);
|
||||
|
||||
while (!LIST_EMPTY(&(bnc->paths))) {
|
||||
struct bgp_path_info *path = LIST_FIRST(&(bnc->paths));
|
||||
@ -93,8 +112,6 @@ static void bgp_nexthop_cache_reset(struct bgp_table *table)
|
||||
}
|
||||
|
||||
bnc_free(bnc);
|
||||
bgp_dest_set_bgp_nexthop_info(dest, NULL);
|
||||
bgp_dest_unlock_node(dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,20 +790,19 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
|
||||
}
|
||||
|
||||
static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
|
||||
struct bgp_dest *dest,
|
||||
struct bgp_nexthop_cache *bnc,
|
||||
bool specific)
|
||||
{
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
time_t tbuf;
|
||||
struct peer *peer;
|
||||
const struct prefix *p = bgp_dest_get_prefix(dest);
|
||||
|
||||
peer = (struct peer *)bnc->nht_info;
|
||||
|
||||
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
|
||||
vty_out(vty, " %s valid [IGP metric %d], #paths %d",
|
||||
inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf)),
|
||||
inet_ntop(bnc->prefix.family, &bnc->prefix.u.prefix,
|
||||
buf, sizeof(buf)),
|
||||
bnc->metric, bnc->path_count);
|
||||
if (peer)
|
||||
vty_out(vty, ", peer %s", peer->host);
|
||||
@ -794,7 +810,8 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
|
||||
bgp_show_nexthops_detail(vty, bgp, bnc);
|
||||
} else {
|
||||
vty_out(vty, " %s invalid, #paths %d",
|
||||
inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf)),
|
||||
inet_ntop(bnc->prefix.family, &bnc->prefix.u.prefix,
|
||||
buf, sizeof(buf)),
|
||||
bnc->path_count);
|
||||
if (peer)
|
||||
vty_out(vty, ", peer %s", peer->host);
|
||||
@ -816,29 +833,21 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
|
||||
static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
|
||||
bool import_table)
|
||||
{
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
afi_t afi;
|
||||
struct bgp_table **table;
|
||||
struct bgp_nexthop_cache_head(*tree)[AFI_MAX];
|
||||
|
||||
if (import_table)
|
||||
vty_out(vty, "Current BGP import check cache:\n");
|
||||
else
|
||||
vty_out(vty, "Current BGP nexthop cache:\n");
|
||||
if (import_table)
|
||||
table = bgp->import_check_table;
|
||||
tree = &bgp->import_check_table;
|
||||
else
|
||||
table = bgp->nexthop_cache_table;
|
||||
tree = &bgp->nexthop_cache_table;
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
if (!table || !table[afi])
|
||||
continue;
|
||||
for (dest = bgp_table_top(table[afi]); dest;
|
||||
dest = bgp_route_next(dest)) {
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
if (!bnc)
|
||||
continue;
|
||||
bgp_show_nexthop(vty, bgp, dest, bnc, false);
|
||||
}
|
||||
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc)
|
||||
bgp_show_nexthop(vty, bgp, bnc, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,27 +868,21 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
|
||||
|
||||
if (nhopip_str) {
|
||||
struct prefix nhop;
|
||||
struct bgp_table **table;
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache_head (*tree)[AFI_MAX];
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
|
||||
if (!str2prefix(nhopip_str, &nhop)) {
|
||||
vty_out(vty, "nexthop address is malformed\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
table = import_table ? \
|
||||
bgp->import_check_table : bgp->nexthop_cache_table;
|
||||
dest = bgp_node_lookup(table[family2afi(nhop.family)], &nhop);
|
||||
if (!dest) {
|
||||
vty_out(vty, "specified nexthop is not found\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
tree = import_table ? &bgp->import_check_table
|
||||
: &bgp->nexthop_cache_table;
|
||||
bnc = bnc_find(tree[family2afi(nhop.family)], &nhop, 0);
|
||||
if (!bnc) {
|
||||
vty_out(vty, "specified nexthop does not have entry\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
bgp_show_nexthop(vty, bgp, dest, bnc, true);
|
||||
bgp_show_nexthop(vty, bgp, bnc, true);
|
||||
} else
|
||||
bgp_show_nexthops(vty, bgp, import_table);
|
||||
|
||||
@ -966,12 +969,10 @@ void bgp_scan_init(struct bgp *bgp)
|
||||
afi_t afi;
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
bgp->nexthop_cache_table[afi] =
|
||||
bgp_table_init(bgp, afi, SAFI_UNICAST);
|
||||
bgp_nexthop_cache_init(&bgp->nexthop_cache_table[afi]);
|
||||
bgp_nexthop_cache_init(&bgp->import_check_table[afi]);
|
||||
bgp->connected_table[afi] = bgp_table_init(bgp, afi,
|
||||
SAFI_UNICAST);
|
||||
bgp->import_check_table[afi] =
|
||||
bgp_table_init(bgp, afi, SAFI_UNICAST);
|
||||
}
|
||||
}
|
||||
|
||||
@ -988,16 +989,12 @@ void bgp_scan_finish(struct bgp *bgp)
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
/* Only the current one needs to be reset. */
|
||||
bgp_nexthop_cache_reset(bgp->nexthop_cache_table[afi]);
|
||||
bgp_table_unlock(bgp->nexthop_cache_table[afi]);
|
||||
bgp->nexthop_cache_table[afi] = NULL;
|
||||
bgp_nexthop_cache_reset(&bgp->nexthop_cache_table[afi]);
|
||||
bgp_nexthop_cache_reset(&bgp->import_check_table[afi]);
|
||||
|
||||
bgp->connected_table[afi]->route_table->cleanup =
|
||||
bgp_connected_cleanup;
|
||||
bgp_table_unlock(bgp->connected_table[afi]);
|
||||
bgp->connected_table[afi] = NULL;
|
||||
|
||||
bgp_table_unlock(bgp->import_check_table[afi]);
|
||||
bgp->import_check_table[afi] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "if.h"
|
||||
#include "queue.h"
|
||||
#include "prefix.h"
|
||||
#include "bgp_table.h"
|
||||
|
||||
#define NEXTHOP_FAMILY(nexthop_len) \
|
||||
(((nexthop_len) == 4 || (nexthop_len) == 12 \
|
||||
@ -36,8 +37,13 @@
|
||||
|
||||
#define BGP_MP_NEXTHOP_FAMILY NEXTHOP_FAMILY
|
||||
|
||||
PREDECL_RBTREE_UNIQ(bgp_nexthop_cache);
|
||||
|
||||
/* BGP nexthop cache value structure. */
|
||||
struct bgp_nexthop_cache {
|
||||
/* RB-tree entry. */
|
||||
struct bgp_nexthop_cache_item entry;
|
||||
|
||||
/* IGP route's metric. */
|
||||
uint32_t metric;
|
||||
|
||||
@ -61,13 +67,21 @@ struct bgp_nexthop_cache {
|
||||
#define BGP_NEXTHOP_METRIC_CHANGED (1 << 1)
|
||||
#define BGP_NEXTHOP_CONNECTED_CHANGED (1 << 2)
|
||||
|
||||
struct bgp_dest *dest;
|
||||
/* Back pointer to the cache tree this entry belongs to. */
|
||||
struct bgp_nexthop_cache_head *tree;
|
||||
|
||||
struct prefix prefix;
|
||||
void *nht_info; /* In BGP, peer session */
|
||||
LIST_HEAD(path_list, bgp_path_info) paths;
|
||||
unsigned int path_count;
|
||||
struct bgp *bgp;
|
||||
};
|
||||
|
||||
extern int bgp_nexthop_cache_compare(const struct bgp_nexthop_cache *a,
|
||||
const struct bgp_nexthop_cache *b);
|
||||
DECLARE_RBTREE_UNIQ(bgp_nexthop_cache, struct bgp_nexthop_cache, entry,
|
||||
bgp_nexthop_cache_compare);
|
||||
|
||||
/* Own tunnel-ip address structure */
|
||||
struct tip_addr {
|
||||
struct in_addr addr;
|
||||
@ -79,6 +93,12 @@ struct bgp_addrv6 {
|
||||
struct list *ifp_name_list;
|
||||
};
|
||||
|
||||
/* Forward declaration(s). */
|
||||
struct peer;
|
||||
struct update_subgroup;
|
||||
struct bgp_dest;
|
||||
struct attr;
|
||||
|
||||
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
|
||||
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
|
||||
extern bool bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
|
||||
@ -94,10 +114,13 @@ extern int bgp_config_write_scan_time(struct vty *);
|
||||
extern bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type,
|
||||
uint8_t sub_type, struct attr *attr,
|
||||
struct bgp_dest *dest);
|
||||
extern struct bgp_nexthop_cache *bnc_new(void);
|
||||
extern struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
|
||||
struct prefix *prefix);
|
||||
extern void bnc_free(struct bgp_nexthop_cache *bnc);
|
||||
extern struct bgp_nexthop_cache *bnc_find(struct bgp_nexthop_cache_head *tree,
|
||||
struct prefix *prefix);
|
||||
extern void bnc_nexthop_free(struct bgp_nexthop_cache *bnc);
|
||||
extern char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size);
|
||||
extern const char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size);
|
||||
extern void bgp_scan_init(struct bgp *bgp);
|
||||
extern void bgp_scan_finish(struct bgp *bgp);
|
||||
extern void bgp_scan_vty_init(void);
|
||||
|
144
bgpd/bgp_nht.c
144
bgpd/bgp_nht.c
@ -78,9 +78,6 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
|
||||
}
|
||||
unregister_zebra_rnh(bnc,
|
||||
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
|
||||
bgp_dest_set_bgp_nexthop_info(bnc->dest, NULL);
|
||||
bgp_dest_unlock_node(bnc->dest);
|
||||
bnc->dest = NULL;
|
||||
bnc_free(bnc);
|
||||
}
|
||||
}
|
||||
@ -100,16 +97,13 @@ void bgp_unlink_nexthop(struct bgp_path_info *path)
|
||||
void bgp_unlink_nexthop_by_peer(struct peer *peer)
|
||||
{
|
||||
struct prefix p;
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
afi_t afi = family2afi(peer->su.sa.sa_family);
|
||||
|
||||
if (!sockunion2hostprefix(&peer->su, &p))
|
||||
return;
|
||||
|
||||
dest = bgp_node_get(peer->bgp->nexthop_cache_table[afi], &p);
|
||||
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
bnc = bnc_find(&peer->bgp->nexthop_cache_table[afi], &p);
|
||||
if (!bnc)
|
||||
return;
|
||||
|
||||
@ -127,11 +121,10 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
afi_t afi, struct bgp_path_info *pi,
|
||||
struct peer *peer, int connected)
|
||||
{
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache_head *tree = NULL;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
struct prefix p;
|
||||
int is_bgp_static_route = 0;
|
||||
const struct prefix *bnc_p;
|
||||
|
||||
if (pi) {
|
||||
is_bgp_static_route = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||
@ -168,17 +161,14 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
return 0;
|
||||
|
||||
if (is_bgp_static_route)
|
||||
dest = bgp_node_get(bgp_nexthop->import_check_table[afi], &p);
|
||||
tree = &bgp_nexthop->import_check_table[afi];
|
||||
else
|
||||
dest = bgp_node_get(bgp_nexthop->nexthop_cache_table[afi], &p);
|
||||
tree = &bgp_nexthop->nexthop_cache_table[afi];
|
||||
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
bnc = bnc_find(tree, &p);
|
||||
if (!bnc) {
|
||||
bnc = bnc_new();
|
||||
bgp_dest_set_bgp_nexthop_info(dest, bnc);
|
||||
bnc->dest = dest;
|
||||
bnc = bnc_new(tree, &p);
|
||||
bnc->bgp = bgp_nexthop;
|
||||
bgp_dest_lock_node(dest);
|
||||
if (BGP_DEBUG(nht, NHT)) {
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
|
||||
@ -188,9 +178,6 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
}
|
||||
}
|
||||
|
||||
bnc_p = bgp_dest_get_prefix(bnc->dest);
|
||||
|
||||
bgp_dest_unlock_node(dest);
|
||||
if (is_bgp_static_route) {
|
||||
SET_FLAG(bnc->flags, BGP_STATIC_ROUTE);
|
||||
|
||||
@ -236,7 +223,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
|
||||
SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
|
||||
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)
|
||||
&& !is_default_host_route(bnc_p))
|
||||
&& !is_default_host_route(&bnc->prefix))
|
||||
register_zebra_rnh(bnc, is_bgp_static_route);
|
||||
|
||||
if (pi && pi->nexthop != bnc) {
|
||||
@ -269,7 +256,6 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||
|
||||
void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
|
||||
{
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
struct prefix p;
|
||||
|
||||
@ -279,9 +265,9 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
|
||||
if (!sockunion2hostprefix(&peer->su, &p))
|
||||
return;
|
||||
|
||||
dest = bgp_node_lookup(
|
||||
peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
|
||||
if (!dest) {
|
||||
bnc = bnc_find(&peer->bgp->nexthop_cache_table[family2afi(p.family)],
|
||||
&p);
|
||||
if (!bnc) {
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
zlog_debug(
|
||||
"Cannot find connected NHT node for peer %s(%s)",
|
||||
@ -289,17 +275,6 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
|
||||
return;
|
||||
}
|
||||
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
if (!bnc) {
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
zlog_debug(
|
||||
"Cannot find connected NHT node for peer %s(%s) on route_node as expected",
|
||||
peer->host, peer->bgp->name_pretty);
|
||||
bgp_dest_unlock_node(dest);
|
||||
return;
|
||||
}
|
||||
bgp_dest_unlock_node(dest);
|
||||
|
||||
if (bnc->nht_info != peer) {
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
zlog_debug(
|
||||
@ -317,15 +292,13 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
|
||||
"Freeing connected NHT node %p for peer %s(%s)",
|
||||
bnc, peer->host, bnc->bgp->name_pretty);
|
||||
unregister_zebra_rnh(bnc, 0);
|
||||
bgp_dest_set_bgp_nexthop_info(bnc->dest, NULL);
|
||||
bgp_dest_unlock_node(bnc->dest);
|
||||
bnc_free(bnc);
|
||||
}
|
||||
}
|
||||
|
||||
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
|
||||
{
|
||||
struct bgp_dest *dest = NULL;
|
||||
struct bgp_nexthop_cache_head *tree = NULL;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
struct nexthop *nexthop;
|
||||
struct nexthop *oldnh;
|
||||
@ -352,39 +325,23 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
|
||||
}
|
||||
|
||||
if (command == ZEBRA_NEXTHOP_UPDATE)
|
||||
dest = bgp_node_lookup(
|
||||
bgp->nexthop_cache_table[family2afi(nhr.prefix.family)],
|
||||
&nhr.prefix);
|
||||
tree = &bgp->nexthop_cache_table[family2afi(nhr.prefix.family)];
|
||||
else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
|
||||
dest = bgp_node_lookup(
|
||||
bgp->import_check_table[family2afi(nhr.prefix.family)],
|
||||
&nhr.prefix);
|
||||
tree = &bgp->import_check_table[family2afi(nhr.prefix.family)];
|
||||
|
||||
if (!dest) {
|
||||
if (BGP_DEBUG(nht, NHT)) {
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
prefix2str(&nhr.prefix, buf, sizeof(buf));
|
||||
zlog_debug("parse nexthop update(%s(%s)): rn not found",
|
||||
buf, bgp->name_pretty);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
bnc = bnc_find(tree, &nhr.prefix);
|
||||
if (!bnc) {
|
||||
if (BGP_DEBUG(nht, NHT)) {
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
|
||||
prefix2str(&nhr.prefix, buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"parse nexthop update(%s(%s)): bnc node info not found",
|
||||
"parse nexthop update(%s(%s)): bnc info not found",
|
||||
buf, bgp->name_pretty);
|
||||
}
|
||||
bgp_dest_unlock_node(dest);
|
||||
return;
|
||||
}
|
||||
|
||||
bgp_dest_unlock_node(dest);
|
||||
bnc->last_update = bgp_clock();
|
||||
bnc->change_flags = 0;
|
||||
|
||||
@ -503,20 +460,11 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
|
||||
*/
|
||||
void bgp_cleanup_nexthops(struct bgp *bgp)
|
||||
{
|
||||
afi_t afi;
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
if (!bgp->nexthop_cache_table[afi])
|
||||
continue;
|
||||
|
||||
for (dest = bgp_table_top(bgp->nexthop_cache_table[afi]); dest;
|
||||
dest = bgp_route_next(dest)) {
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
if (!bnc)
|
||||
continue;
|
||||
for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
|
||||
frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi],
|
||||
bnc) {
|
||||
/* Clear relevant flags. */
|
||||
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
|
||||
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
|
||||
@ -609,7 +557,6 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
|
||||
*/
|
||||
static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
|
||||
{
|
||||
const struct prefix *p;
|
||||
bool exact_match = false;
|
||||
int ret;
|
||||
|
||||
@ -631,23 +578,18 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
|
||||
"%s: We have not connected yet, cannot send nexthops",
|
||||
__func__);
|
||||
}
|
||||
p = bgp_dest_get_prefix(bnc->dest);
|
||||
if ((command == ZEBRA_NEXTHOP_REGISTER
|
||||
|| command == ZEBRA_IMPORT_ROUTE_REGISTER)
|
||||
&& (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
|
||||
|| CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)))
|
||||
exact_match = true;
|
||||
|
||||
if (BGP_DEBUG(zebra, ZEBRA)) {
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: sending cmd %s for %pFX (vrf %s)", __func__,
|
||||
zserv_command_string(command), &bnc->prefix,
|
||||
bnc->bgp->name_pretty);
|
||||
|
||||
prefix2str(p, buf, PREFIX2STR_BUFFER);
|
||||
zlog_debug("%s: sending cmd %s for %s (vrf %s)",
|
||||
__func__, zserv_command_string(command), buf,
|
||||
bnc->bgp->name_pretty);
|
||||
}
|
||||
|
||||
ret = zclient_send_rnh(zclient, command, p, exact_match,
|
||||
ret = zclient_send_rnh(zclient, command, &bnc->prefix, exact_match,
|
||||
bnc->bgp->vrf_id);
|
||||
/* TBD: handle the failure */
|
||||
if (ret < 0)
|
||||
@ -901,21 +843,11 @@ void path_nh_map(struct bgp_path_info *path, struct bgp_nexthop_cache *bnc,
|
||||
*/
|
||||
void bgp_nht_register_nexthops(struct bgp *bgp)
|
||||
{
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
afi_t afi;
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
if (!bgp->nexthop_cache_table[afi])
|
||||
continue;
|
||||
|
||||
for (dest = bgp_table_top(bgp->nexthop_cache_table[afi]); dest;
|
||||
dest = bgp_route_next(dest)) {
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
|
||||
if (!bnc)
|
||||
continue;
|
||||
for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
|
||||
frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi],
|
||||
bnc) {
|
||||
register_zebra_rnh(bnc, 0);
|
||||
}
|
||||
}
|
||||
@ -924,7 +856,6 @@ void bgp_nht_register_nexthops(struct bgp *bgp)
|
||||
void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
struct nexthop *nhop;
|
||||
struct interface *ifp;
|
||||
@ -934,10 +865,6 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
|
||||
return;
|
||||
|
||||
bgp = peer->bgp;
|
||||
|
||||
if (!bgp->nexthop_cache_table[AFI_IP6])
|
||||
return;
|
||||
|
||||
if (!sockunion2hostprefix(&peer->su, &p)) {
|
||||
zlog_warn("%s: Unable to convert sockunion to prefix for %s",
|
||||
__func__, peer->host);
|
||||
@ -946,11 +873,8 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
|
||||
|
||||
if (p.family != AF_INET6)
|
||||
return;
|
||||
dest = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p);
|
||||
if (!dest)
|
||||
return;
|
||||
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
bnc = bnc_find(&bgp->nexthop_cache_table[AFI_IP6], &p);
|
||||
if (!bnc)
|
||||
return;
|
||||
|
||||
@ -973,7 +897,6 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
|
||||
void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
struct bgp_dest *dest;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
struct nexthop *nhop;
|
||||
struct interface *ifp;
|
||||
@ -984,9 +907,6 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
|
||||
|
||||
bgp = peer->bgp;
|
||||
|
||||
if (!bgp->nexthop_cache_table[AFI_IP6])
|
||||
return;
|
||||
|
||||
if (!sockunion2hostprefix(&peer->su, &p)) {
|
||||
zlog_warn("%s: Unable to convert sockunion to prefix for %s",
|
||||
__func__, peer->host);
|
||||
@ -996,11 +916,7 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
|
||||
if (p.family != AF_INET6)
|
||||
return;
|
||||
|
||||
dest = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p);
|
||||
if (!dest)
|
||||
return;
|
||||
|
||||
bnc = bgp_dest_get_bgp_nexthop_info(dest);
|
||||
bnc = bnc_find(&bgp->nexthop_cache_table[AFI_IP6], &p);
|
||||
if (!bnc)
|
||||
return;
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "vxlan.h"
|
||||
#include "bgp_labelpool.h"
|
||||
#include "bgp_addpath_types.h"
|
||||
#include "bgp_nexthop.h"
|
||||
|
||||
#define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */
|
||||
#define BGP_PEER_MAX_HASH_SIZE 16384
|
||||
@ -482,11 +483,11 @@ struct bgp {
|
||||
/* BGP per AF peer count */
|
||||
uint32_t af_peer_count[AFI_MAX][SAFI_MAX];
|
||||
|
||||
/* Route table for next-hop lookup cache. */
|
||||
struct bgp_table *nexthop_cache_table[AFI_MAX];
|
||||
/* Tree for next-hop lookup cache. */
|
||||
struct bgp_nexthop_cache_head nexthop_cache_table[AFI_MAX];
|
||||
|
||||
/* Route table for import-check */
|
||||
struct bgp_table *import_check_table[AFI_MAX];
|
||||
/* Tree for import-check */
|
||||
struct bgp_nexthop_cache_head import_check_table[AFI_MAX];
|
||||
|
||||
struct bgp_table *connected_table[AFI_MAX];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user