mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
fixup! rt-feed-by-fib: addr to trie
This commit is contained in:
parent
6d58ca731f
commit
4de40e6767
14
nest/proto.c
14
nest/proto.c
@ -523,22 +523,26 @@ channel_start_export(struct channel *c)
|
|||||||
|
|
||||||
ASSERT(c->channel_state == CS_UP);
|
ASSERT(c->channel_state == CS_UP);
|
||||||
|
|
||||||
c->reqv_trie_lp = lp_new(c->proto->pool);
|
|
||||||
struct f_trie * trie = f_new_trie(c->reqv_trie_lp, 0);
|
|
||||||
trie_add_prefix(trie, c->out_subprefix, net_pxlen(c->out_subprefix), net_pxlen(c->out_subprefix));
|
|
||||||
|
|
||||||
c->out_req = (struct rt_export_request) {
|
c->out_req = (struct rt_export_request) {
|
||||||
.name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
|
.name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
|
||||||
.list = proto_work_list(c->proto),
|
.list = proto_work_list(c->proto),
|
||||||
.pool = c->proto->pool,
|
.pool = c->proto->pool,
|
||||||
.feed_block_size = c->feed_block_size,
|
.feed_block_size = c->feed_block_size,
|
||||||
.prefilter.net_filter_trie = trie,
|
|
||||||
.prefilter.addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
|
.prefilter.addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
|
||||||
.trace_routes = c->debug | c->proto->debug,
|
.trace_routes = c->debug | c->proto->debug,
|
||||||
.dump_req = channel_dump_export_req,
|
.dump_req = channel_dump_export_req,
|
||||||
.log_state_change = channel_export_log_state_change,
|
.log_state_change = channel_export_log_state_change,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(c->out_subprefix!=0){
|
||||||
|
c->reqv_trie_lp = lp_new(c->proto->pool);
|
||||||
|
struct f_trie * trie = f_new_trie(c->reqv_trie_lp, 0);
|
||||||
|
if (c->out_subprefix->type == NET_IP4 || c->out_subprefix->type == NET_VPN4 || c->out_subprefix->type == NET_ROA4){
|
||||||
|
trie_add_prefix(trie, c->out_subprefix, net_pxlen(c->out_subprefix), 48);
|
||||||
|
}
|
||||||
|
else trie_add_prefix(trie, c->out_subprefix, net_pxlen(c->out_subprefix), 128);
|
||||||
|
c->out_req.prefilter.net_filter_trie = trie;
|
||||||
|
}
|
||||||
bmap_init(&c->export_map, c->proto->pool, 16);
|
bmap_init(&c->export_map, c->proto->pool, 16);
|
||||||
bmap_init(&c->export_reject_map, c->proto->pool, 16);
|
bmap_init(&c->export_reject_map, c->proto->pool, 16);
|
||||||
|
|
||||||
|
@ -1204,19 +1204,18 @@ rte_export(struct rt_table_export_hook *th, struct rt_pending_export *rpe)
|
|||||||
goto ignore; /* Seen already */
|
goto ignore; /* Seen already */
|
||||||
|
|
||||||
const net_addr *n = rpe->new_best ? rpe->new_best->rte.net : rpe->old_best->rte.net;
|
const net_addr *n = rpe->new_best ? rpe->new_best->rte.net : rpe->old_best->rte.net;
|
||||||
ASSERT_DIE(1);
|
|
||||||
switch (hook->req->prefilter.addr_mode)
|
switch (hook->req->prefilter.addr_mode)
|
||||||
{
|
{
|
||||||
case TE_ADDR_NONE:
|
case TE_ADDR_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_ADDR_IN:
|
case TE_ADDR_IN:
|
||||||
if (!net_in_netX(n, hook->req->prefilter.addr))
|
if (!net_in_netX_from_export_request(n, hook->req->prefilter.addr))
|
||||||
goto ignore;
|
goto ignore;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_ADDR_EQUAL:
|
case TE_ADDR_EQUAL:
|
||||||
if (!net_equal(n, hook->req->prefilter.addr))
|
if (!net_equal_from_export_request(n, hook->req->prefilter.addr))
|
||||||
goto ignore;
|
goto ignore;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2163,7 +2162,7 @@ rt_table_export_start_feed(struct rtable_private *tab, struct rt_table_export_ho
|
|||||||
{
|
{
|
||||||
hook->walk_state = mb_allocz(hook->h.pool, sizeof (struct f_trie_walk_state));
|
hook->walk_state = mb_allocz(hook->h.pool, sizeof (struct f_trie_walk_state));
|
||||||
hook->walk_lock = rt_lock_trie(tab);
|
hook->walk_lock = rt_lock_trie(tab);
|
||||||
trie_walk_init(hook->walk_state, tab->trie, req->addr);
|
trie_walk_init(hook->walk_state, tab->trie, req->prefilter.addr);
|
||||||
hook->h.event.hook = rt_feed_by_trie;
|
hook->h.event.hook = rt_feed_by_trie;
|
||||||
hook->walk_last.type = 0;
|
hook->walk_last.type = 0;
|
||||||
break;
|
break;
|
||||||
@ -4423,7 +4422,7 @@ rt_feed_equal(void *data)
|
|||||||
ASSERT_DIE(atomic_load_explicit(&c->h.export_state, memory_order_relaxed) == TES_FEEDING);
|
ASSERT_DIE(atomic_load_explicit(&c->h.export_state, memory_order_relaxed) == TES_FEEDING);
|
||||||
ASSERT_DIE(c->h.req->prefilter.addr_mode == TE_ADDR_EQUAL);
|
ASSERT_DIE(c->h.req->prefilter.addr_mode == TE_ADDR_EQUAL);
|
||||||
|
|
||||||
if (n = net_find(tab, c->h.req->addr))
|
if (n = net_find(tab, c->h.req->prefilter.addr))
|
||||||
ASSERT_DIE(rt_prepare_feed(c, n, &block));
|
ASSERT_DIE(rt_prepare_feed(c, n, &block));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4445,7 +4444,7 @@ rt_feed_for(void *data)
|
|||||||
ASSERT_DIE(atomic_load_explicit(&c->h.export_state, memory_order_relaxed) == TES_FEEDING);
|
ASSERT_DIE(atomic_load_explicit(&c->h.export_state, memory_order_relaxed) == TES_FEEDING);
|
||||||
ASSERT_DIE(c->h.req->prefilter.addr_mode == TE_ADDR_FOR);
|
ASSERT_DIE(c->h.req->prefilter.addr_mode == TE_ADDR_FOR);
|
||||||
|
|
||||||
if (n = net_route(tab, c->h.req->addr))
|
if (n = net_route(tab, c->h.req->prefilter.addr))
|
||||||
ASSERT_DIE(rt_prepare_feed(c, n, &block));
|
ASSERT_DIE(rt_prepare_feed(c, n, &block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
nest/rt.h
27
nest/rt.h
@ -291,13 +291,18 @@ struct rt_prefilter_address{
|
|||||||
const struct f_trie *net_filter_trie;
|
const struct f_trie *net_filter_trie;
|
||||||
const net_addr *addr; /* Network prefilter address */
|
const net_addr *addr; /* Network prefilter address */
|
||||||
};
|
};
|
||||||
u8 addr_mode; /* Network prefilter mode (TE_ADDR_*) */
|
/* Network prefilter mode (TE_ADDR_*) */
|
||||||
|
enum {
|
||||||
|
TE_ADDR_NONE=0, /* No address matching */
|
||||||
|
TE_ADDR_EQUAL, /* Exact query - show route <addr> */
|
||||||
|
TE_ADDR_FOR, /* Longest prefix match - show route for <addr> */
|
||||||
|
TE_ADDR_IN /* Interval query - show route in <addr> */
|
||||||
|
} addr_mode;
|
||||||
}PACKED;
|
}PACKED;
|
||||||
|
|
||||||
struct rt_export_request {
|
struct rt_export_request {
|
||||||
struct rt_export_hook *hook; /* Table part of the export */
|
struct rt_export_hook *hook; /* Table part of the export */
|
||||||
char *name;
|
char *name; /* Network prefilter address */
|
||||||
const net_addr *addr; /* Network prefilter address */
|
|
||||||
u8 trace_routes;
|
u8 trace_routes;
|
||||||
uint feed_block_size; /* How many routes to feed at once */
|
uint feed_block_size; /* How many routes to feed at once */
|
||||||
struct rt_prefilter_address prefilter;
|
struct rt_prefilter_address prefilter;
|
||||||
@ -321,6 +326,16 @@ struct rt_export_request {
|
|||||||
void (*log_state_change)(struct rt_export_request *req, u8);
|
void (*log_state_change)(struct rt_export_request *req, u8);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline int net_in_netX_from_export_request(const net_addr *a, const net_addr *n){
|
||||||
|
if (a->type != n->type)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int net_equal_from_export_request(const net_addr *a, const net_addr *b)
|
||||||
|
{ return (a->length == b->length) && !memcmp(a, b, a->length); }
|
||||||
|
|
||||||
struct rt_export_hook {
|
struct rt_export_hook {
|
||||||
node n;
|
node n;
|
||||||
struct rt_exporter *table; /* The connected table */
|
struct rt_exporter *table; /* The connected table */
|
||||||
@ -390,12 +405,6 @@ struct rt_table_export_hook {
|
|||||||
#define TES_STOP 4
|
#define TES_STOP 4
|
||||||
#define TES_MAX 5
|
#define TES_MAX 5
|
||||||
|
|
||||||
/* Value of addr_mode */
|
|
||||||
#define TE_ADDR_NONE 0 /* No address matching */
|
|
||||||
#define TE_ADDR_EQUAL 1 /* Exact query - show route <addr> */
|
|
||||||
#define TE_ADDR_FOR 2 /* Longest prefix match - show route for <addr> */
|
|
||||||
#define TE_ADDR_IN 3 /* Interval query - show route in <addr> */
|
|
||||||
|
|
||||||
|
|
||||||
#define TFT_FIB 1
|
#define TFT_FIB 1
|
||||||
#define TFT_TRIE 2
|
#define TFT_TRIE 2
|
||||||
|
@ -1896,7 +1896,7 @@ bgp_out_table_feed(void *data)
|
|||||||
|
|
||||||
int max = 512;
|
int max = 512;
|
||||||
|
|
||||||
const net_addr *neq = (hook->h.req->prefilter.addr_mode == TE_ADDR_EQUAL) ? hook->h.req->addr : NULL;
|
const net_addr *neq = (hook->h.req->prefilter.addr_mode == TE_ADDR_EQUAL) ? hook->h.req->prefilter.addr : NULL;
|
||||||
const net_addr *cand = NULL;
|
const net_addr *cand = NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -1905,7 +1905,7 @@ bgp_out_table_feed(void *data)
|
|||||||
switch (hook->h.req->prefilter.addr_mode)
|
switch (hook->h.req->prefilter.addr_mode)
|
||||||
{
|
{
|
||||||
case TE_ADDR_IN:
|
case TE_ADDR_IN:
|
||||||
if (!net_in_netX(n->net, hook->h.req->addr))
|
if (!net_in_netX_from_export_request(n->net, hook->h.req->prefilter.addr))
|
||||||
continue;
|
continue;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case TE_ADDR_NONE:
|
case TE_ADDR_NONE:
|
||||||
@ -1917,13 +1917,13 @@ bgp_out_table_feed(void *data)
|
|||||||
case TE_ADDR_FOR:
|
case TE_ADDR_FOR:
|
||||||
if (!neq)
|
if (!neq)
|
||||||
{
|
{
|
||||||
if (net_in_netX(hook->h.req->addr, n->net) && (!cand || (n->net->length > cand->length)))
|
if (net_in_netX_from_export_request(hook->h.req->prefilter.addr, n->net) && (!cand || (n->net->length > cand->length)))
|
||||||
cand = n->net;
|
cand = n->net;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case TE_ADDR_EQUAL:
|
case TE_ADDR_EQUAL:
|
||||||
if (!net_equal(n->net, neq))
|
if (!net_equal_from_export_request(n->net, neq))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user