mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
Prefiltering routes by net and custom hook for partial reloads
This commit is contained in:
parent
45e8629f53
commit
898cc7ee9b
19
nest/proto.c
19
nest/proto.c
@ -51,6 +51,7 @@ static char *proto_state_name(struct proto *p);
|
||||
static void channel_init_limit(struct channel *c, struct limit *l, int dir, struct channel_limit *cf);
|
||||
static void channel_update_limit(struct channel *c, struct limit *l, int dir, struct channel_limit *cf);
|
||||
static void channel_reset_limit(struct channel *c, struct limit *l, int dir);
|
||||
static int channel_refeed_prefilter(const struct rt_prefilter *p, const net_addr *n);
|
||||
static void channel_feed_end(struct channel *c);
|
||||
static void channel_stop_export(struct channel *c);
|
||||
static void channel_export_stopped(struct rt_export_request *req);
|
||||
@ -622,6 +623,7 @@ channel_start_export(struct channel *c)
|
||||
c->refeed_req.dump_req = channel_dump_refeed_req;
|
||||
c->refeed_req.log_state_change = channel_refeed_log_state_change;
|
||||
c->refeed_req.mark_seen = channel_rpe_mark_seen_refeed;
|
||||
c->refeed_req.prefilter.hook = channel_refeed_prefilter;
|
||||
|
||||
DBG("%s.%s: Channel start export req=%p\n", c->proto->name, c->name, &c->out_req);
|
||||
rt_request_export(c->table, &c->out_req);
|
||||
@ -719,9 +721,26 @@ channel_init_feeding(struct channel *c)
|
||||
c->refeeding = c->refeed_pending;
|
||||
c->refeed_pending = NULL;
|
||||
c->refeed_trie = f_new_trie(lp_new(c->proto->pool), 0);
|
||||
|
||||
rt_request_export(c->table, &c->refeed_req);
|
||||
}
|
||||
|
||||
static int
|
||||
channel_refeed_prefilter(const struct rt_prefilter *p, const net_addr *n)
|
||||
{
|
||||
const struct channel *c =
|
||||
SKIP_BACK(struct channel, refeed_req,
|
||||
SKIP_BACK(struct rt_export_request, prefilter, p)
|
||||
);
|
||||
|
||||
for (struct channel_feeding_request *cfr = c->refeeding; cfr; cfr = cfr->next)
|
||||
if (!cfr->trie || trie_match_net(cfr->trie, n))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
channel_feed_end(struct channel *c)
|
||||
{
|
||||
|
@ -2229,6 +2229,7 @@ rt_table_export_start_feed(struct rtable_private *tab, struct rt_table_export_ho
|
||||
/* fall through */
|
||||
case TE_ADDR_NONE:
|
||||
case TE_ADDR_TRIE:
|
||||
case TE_ADDR_HOOK:
|
||||
FIB_ITERATE_INIT(&hook->feed_fit, &tab->fib);
|
||||
hook->h.event.hook = rt_feed_by_fib;
|
||||
break;
|
||||
@ -2327,6 +2328,7 @@ rt_table_export_stop_locked(struct rt_export_hook *hh)
|
||||
}
|
||||
/* fall through */
|
||||
case TE_ADDR_NONE:
|
||||
case TE_ADDR_HOOK:
|
||||
case TE_ADDR_TRIE:
|
||||
fit_get(&tab->fib, &hook->feed_fit);
|
||||
break;
|
||||
@ -4423,6 +4425,8 @@ rt_feed_by_fib(void *data)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
req_trace(c->h.req, D_ROUTES, "Feeding %N rejected by prefilter", n->n.addr);
|
||||
}
|
||||
FIB_ITERATE_END;
|
||||
}
|
||||
|
@ -304,6 +304,7 @@ struct rt_prefilter {
|
||||
union {
|
||||
const struct f_trie *trie;
|
||||
const net_addr *addr; /* Network prefilter address */
|
||||
int (*hook)(const struct rt_prefilter *, const net_addr *);
|
||||
};
|
||||
/* Network prefilter mode (TE_ADDR_*) */
|
||||
enum {
|
||||
@ -312,6 +313,7 @@ struct rt_prefilter {
|
||||
TE_ADDR_FOR, /* Longest prefix match - show route for <addr> */
|
||||
TE_ADDR_IN, /* Interval query - show route in <addr> */
|
||||
TE_ADDR_TRIE, /* Query defined by trie */
|
||||
TE_ADDR_HOOK, /* Query processed by supplied custom hook */
|
||||
} mode;
|
||||
} PACKED;
|
||||
|
||||
@ -352,6 +354,7 @@ static inline int rt_prefilter_net(const struct rt_prefilter *p, const net_addr
|
||||
case TE_ADDR_EQUAL: return net_equal(n, p->addr);
|
||||
case TE_ADDR_FOR: return net_in_netX(p->addr, n);
|
||||
case TE_ADDR_TRIE: return trie_match_net(p->trie, n);
|
||||
case TE_ADDR_HOOK: return p->hook(p, n);
|
||||
}
|
||||
|
||||
bug("Crazy prefilter application attempt failed wildly.");
|
||||
|
Loading…
Reference in New Issue
Block a user