diff options
Diffstat (limited to 'nest/rt-roa.c')
-rw-r--r-- | nest/rt-roa.c | 440 |
1 files changed, 0 insertions, 440 deletions
diff --git a/nest/rt-roa.c b/nest/rt-roa.c deleted file mode 100644 index bf457e30..00000000 --- a/nest/rt-roa.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * BIRD -- Route Origin Authorization - * - * - * Can be freely distributed and used under the terms of the GNU GPL. - */ - -#undef LOCAL_DEBUG - -#include "nest/bird.h" -#include "nest/route.h" -#include "nest/cli.h" -#include "lib/lists.h" -#include "lib/resource.h" -#include "lib/event.h" -#include "lib/string.h" -#include "conf/conf.h" - - -pool *roa_pool; -static slab *roa_slab; /* Slab of struct roa_item */ -static list roa_table_list; /* List of struct roa_table */ -struct roa_table *roa_table_default; /* The first ROA table in the config */ - -static inline int -src_match(struct roa_item *it, byte src) -{ return !src || it->src == src; } - -/** - * roa_add_item - add a ROA entry - * @t: ROA table - * @prefix: prefix of the ROA entry - * @pxlen: prefix length of the ROA entry - * @maxlen: max length field of the ROA entry - * @asn: AS number field of the ROA entry - * @src: source of the ROA entry (ROA_SRC_*) - * - * The function adds a new ROA entry to the ROA table. If the same ROA - * is already in the table, nothing is added. @src field is used to - * distinguish different sources of ROAs. - */ -void -roa_add_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src) -{ - struct roa_node *n = fib_get(&t->fib, &prefix, pxlen); - - // if ((n->items == NULL) && (n->n.x0 != ROA_INVALID)) - // t->cached_items--; - - struct roa_item *it; - for (it = n->items; it; it = it->next) - if ((it->maxlen == maxlen) && (it->asn == asn) && src_match(it, src)) - return; - - it = sl_alloc(roa_slab); - it->asn = asn; - it->maxlen = maxlen; - it->src = src; - it->next = n->items; - n->items = it; -} - -/** - * roa_delete_item - delete a ROA entry - * @t: ROA table - * @prefix: prefix of the ROA entry - * @pxlen: prefix length of the ROA entry - * @maxlen: max length field of the ROA entry - * @asn: AS number field of the ROA entry - * @src: source of the ROA entry (ROA_SRC_*) - * - * The function removes a specified ROA entry from the ROA table and - * frees it. If @src field is not ROA_SRC_ANY, only entries from - * that source are considered. - */ -void -roa_delete_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src) -{ - struct roa_node *n = fib_find(&t->fib, &prefix, pxlen); - - if (!n) - return; - - struct roa_item *it, **itp; - for (itp = &n->items; it = *itp; itp = &it->next) - if ((it->maxlen == maxlen) && (it->asn == asn) && src_match(it, src)) - break; - - if (!it) - return; - - *itp = it->next; - sl_free(roa_slab, it); - - // if ((n->items == NULL) && (n->n.x0 != ROA_INVALID)) - // t->cached_items++; -} - - -/** - * roa_flush - flush a ROA table - * @t: ROA table - * @src: source of ROA entries (ROA_SRC_*) - * - * The function removes and frees ROA entries from the ROA table. If - * @src is ROA_SRC_ANY, all entries in the table are removed, - * otherwise only all entries from that source are removed. - */ -void -roa_flush(struct roa_table *t, byte src) -{ - struct roa_item *it, **itp; - struct roa_node *n; - - FIB_WALK(&t->fib, fn) - { - n = (struct roa_node *) fn; - - itp = &n->items; - while (it = *itp) - if (src_match(it, src)) - { - *itp = it->next; - sl_free(roa_slab, it); - } - else - itp = &it->next; - } - FIB_WALK_END; - - // TODO add cleanup of roa_nodes -} - - - -/* -byte -roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn) -{ - struct roa_node *n = fib_find(&t->fib, &prefix, pxlen); - - if (n && n->n.x0 == ROA_UNKNOWN) - return ROA_UNKNOWN; - - if (n && n->n.x0 == ROA_VALID && asn == n->cached_asn) - return ROA_VALID; - - byte rv = roa_match(t, n, prefix, pxlen, asn); - - if (rv != ROA_INVALID) - { - if (!n) - { - if (t->cached_items >= t->cached_items_max) - n = fib_get(&t->fib, &prefix, pxlen); - t->cached_items++; - } - - n->cached_asn = asn; - n->n.x0 = rv; - } - - return rv; -} -*/ - -/** - * roa_check - check validity of route origination in a ROA table - * @t: ROA table - * @prefix: network prefix to check - * @pxlen: length of network prefix - * @asn: AS number of network prefix - * - * Implements RFC 6483 route validation for the given network - * prefix. The procedure is to find all candidate ROAs - ROAs whose - * prefixes cover the give network prefix. If there is no candidate - * ROA, return ROA_UNKNOWN. If there is a candidate ROA with matching - * ASN and maxlen field greater than or equal to the given prefix - * length, return ROA_VALID. Otherwise return ROA_INVALID. If caller - * cannot determine origin AS, 0 could be used (in that case ROA_VALID - * cannot happen). - */ -byte -roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn) -{ - struct roa_node *n; - ip_addr px; - byte anything = 0; - - int len; - for (len = pxlen; len >= 0; len--) - { - px = ipa_and(prefix, ipa_mkmask(len)); - n = fib_find(&t->fib, &px, len); - - if (!n) - continue; - - struct roa_item *it; - for (it = n->items; it; it = it->next) - { - anything = 1; - if ((it->maxlen >= pxlen) && (it->asn == asn) && asn) - return ROA_VALID; - } - } - - return anything ? ROA_INVALID : ROA_UNKNOWN; -} - -static void -roa_node_init(struct fib_node *fn) -{ - struct roa_node *n = (struct roa_node *) fn; - n->items = NULL; -} - -static inline void -roa_populate(struct roa_table *t) -{ - struct roa_item_config *ric; - for (ric = t->cf->roa_items; ric; ric = ric->next) - roa_add_item(t, ric->prefix, ric->pxlen, ric->maxlen, ric->asn, ROA_SRC_CONFIG); -} - -static void -roa_new_table(struct roa_table_config *cf) -{ - struct roa_table *t; - - t = mb_allocz(roa_pool, sizeof(struct roa_table)); - fib_init(&t->fib, roa_pool, sizeof(struct roa_node), 0, roa_node_init); - t->name = cf->name; - t->cf = cf; - - cf->table = t; - add_tail(&roa_table_list, &t->n); - - roa_populate(t); -} - -struct roa_table_config * -roa_new_table_config(struct symbol *s) -{ - struct roa_table_config *rtc = cfg_allocz(sizeof(struct roa_table_config)); - - cf_define_symbol(s, SYM_ROA, rtc); - rtc->name = s->name; - add_tail(&new_config->roa_tables, &rtc->n); - return rtc; -} - -/** - * roa_add_item_config - add a static ROA entry to a ROA table configuration - * - * Arguments are self-explanatory. The first is the ROA table config, rest - * are specifying the ROA entry. - */ -void -roa_add_item_config(struct roa_table_config *rtc, ip_addr prefix, byte pxlen, byte maxlen, u32 asn) -{ - struct roa_item_config *ric = cfg_allocz(sizeof(struct roa_item_config)); - - ric->prefix = prefix; - ric->pxlen = pxlen; - ric->maxlen = maxlen; - ric->asn = asn; - ric->next = rtc->roa_items; - rtc->roa_items = ric; -} - -/** - * roa_init - initialize ROA tables - * - * This function is called during BIRD startup. It initializes - * the ROA table module. - */ -void -roa_init(void) -{ - roa_pool = rp_new(&root_pool, "ROA tables"); - roa_slab = sl_new(roa_pool, sizeof(struct roa_item)); - init_list(&roa_table_list); -} - -void -roa_preconfig(struct config *c) -{ - init_list(&c->roa_tables); -} - - -/** - * roa_commit - commit new ROA table configuration - * @new: new configuration - * @old: original configuration or %NULL if it's boot time config - * - * Scan differences between @old and @new configuration and modify the - * ROA tables according to these changes. If @new defines a previously - * unknown table, create it, if it omits a table existing in @old, - * delete it (there are no references, only indirect through struct - * roa_table_config). If it exists in both configurations, update the - * configured ROA entries. - */ -void -roa_commit(struct config *new, struct config *old) -{ - struct roa_table_config *cf; - struct roa_table *t, *tx; - - if (old) - WALK_LIST_DELSAFE(t, tx, roa_table_list) - { - struct symbol *sym = cf_find_symbol(new, t->name); - if (sym && sym->class == SYM_ROA) - { - /* Found old table in new config */ - cf = sym->def; - cf->table = t; - t->name = cf->name; - t->cf = cf; - - /* Reconfigure it */ - roa_flush(t, ROA_SRC_CONFIG); - roa_populate(t); - } - else - { - t->cf->table = NULL; - - /* Free it now */ - roa_flush(t, ROA_SRC_ANY); - rem_node(&t->n); - fib_free(&t->fib); - mb_free(t); - } - } - - /* Add new tables */ - WALK_LIST(cf, new->roa_tables) - if (! cf->table) - roa_new_table(cf); - - roa_table_default = EMPTY_LIST(new->roa_tables) ? NULL : - ((struct roa_table_config *) HEAD(new->roa_tables))->table; -} - - - -static void -roa_show_node(struct cli *c, struct roa_node *rn, int len, u32 asn) -{ - struct roa_item *ri; - - for (ri = rn->items; ri; ri = ri->next) - if ((ri->maxlen >= len) && (!asn || (ri->asn == asn))) - cli_printf(c, -1019, "%I/%d max %d as %u", rn->n.prefix, rn->n.pxlen, ri->maxlen, ri->asn); -} - -static void -roa_show_cont(struct cli *c) -{ - struct roa_show_data *d = c->rover; - struct fib *fib = &d->table->fib; - struct fib_iterator *it = &d->fit; - struct roa_node *rn; - unsigned max = 32; - - FIB_ITERATE_START(fib, it, f) - { - rn = (struct roa_node *) f; - - if (!max--) - { - FIB_ITERATE_PUT(it, f); - return; - } - - if ((d->mode == ROA_SHOW_ALL) || - net_in_net(rn->n.prefix, rn->n.pxlen, d->prefix, d->pxlen)) - roa_show_node(c, rn, 0, d->asn); - } - FIB_ITERATE_END(f); - - cli_printf(c, 0, ""); - c->cont = c->cleanup = NULL; -} - -static void -roa_show_cleanup(struct cli *c) -{ - struct roa_show_data *d = c->rover; - - /* Unlink the iterator */ - fit_get(&d->table->fib, &d->fit); -} - -void -roa_show(struct roa_show_data *d) -{ - struct roa_node *rn; - ip_addr px; - int len; - - switch (d->mode) - { - case ROA_SHOW_ALL: - case ROA_SHOW_IN: - FIB_ITERATE_INIT(&d->fit, &d->table->fib); - this_cli->cont = roa_show_cont; - this_cli->cleanup = roa_show_cleanup; - this_cli->rover = d; - break; - - case ROA_SHOW_PX: - rn = fib_find(&d->table->fib, &d->prefix, d->pxlen); - if (rn) - { - roa_show_node(this_cli, rn, 0, d->asn); - cli_msg(0, ""); - } - else - cli_msg(-8001, "Network not in table"); - break; - - case ROA_SHOW_FOR: - for (len = d->pxlen; len >= 0; len--) - { - px = ipa_and(d->prefix, ipa_mkmask(len)); - rn = fib_find(&d->table->fib, &px, len); - - if (!rn) - continue; - - roa_show_node(this_cli, rn, 0, d->asn); - } - cli_msg(0, ""); - break; - } -} |