Commit af582c48 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Route Origin Authorization basics.

 - ROA tables, which are used as a basic part for RPKI.
 - Commands for examining and modifying ROA tables.
 - Filter operators based on ROA tables consistent with RFC 6483.
parent fd087589
......@@ -536,6 +536,8 @@ cf_symbol_class_name(struct symbol *sym)
return "network address";
case SYM_TEMPLATE:
return "protocol template";
case SYM_ROA:
return "ROA table";
default:
return "unknown type";
}
......
......@@ -112,6 +112,7 @@ config_parse(struct config *c)
sysdep_preconfig(c);
protos_preconfig(c);
rt_preconfig(c);
roa_preconfig(c);
cf_parse();
protos_postconfig(c);
if (EMPTY_LIST(c->protos))
......@@ -210,6 +211,7 @@ config_do_commit(struct config *c, int type)
force_restart |= global_commit(c, old_config);
DBG("rt_commit\n");
rt_commit(c, old_config);
roa_commit(c, old_config);
DBG("protos_commit\n");
protos_commit(c, old_config, force_restart, type);
new_config = NULL; /* Just to be sure nobody uses that now */
......
......@@ -21,7 +21,9 @@ struct config {
linpool *mem; /* Linear pool containing configuration data */
list protos; /* Configured protocol instances (struct proto_config) */
list tables; /* Configured routing tables (struct rtable_config) */
list roa_tables; /* Configured ROA tables (struct roa_table_config) */
list logfiles; /* Configured log fils (sysdep) */
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
struct rtable_config *master_rtc; /* Configuration of master routing table */
......@@ -110,6 +112,7 @@ struct symbol {
#define SYM_TABLE 5
#define SYM_IPA 6
#define SYM_TEMPLATE 7
#define SYM_ROA 8
#define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */
......
......@@ -50,9 +50,11 @@ CF_DECLS
struct f_path_mask *h;
struct password_item *p;
struct rt_show_data *ra;
struct roa_show_data *ro;
struct sym_show_data *sd;
struct lsadb_show_data *ld;
struct iface *iface;
struct roa_table *rot;
void *g;
bird_clock_t time;
struct prefix px;
......
......@@ -358,6 +358,22 @@ protocol rip {
routing table is created implicitly, other routing tables have
to be added by this command.
<tag>roa table [ { roa table options ... } ] <m/name/</tag>
Create a new ROA (Route Origin Authorization) table. ROA
tables can be used to validate route origination of BGP
routes. A ROA table contains ROA entries, each consist of a
network prefix, a max prefix length and an AS number. A ROA
entry specifies prefixes which could be originated by that AS
number. ROA tables could be filled with data from RPKI (RFC
6480) or from public databases like Whois. ROA tables are
examined by <cf/roa_check()/ operator in filters.
Currently, there is just one option,
<cf>roa <m/prefix/ max <m/num/ as <m/num/</cf>, which
can be used to populate the ROA table with static ROA
entries. The option may be used multiple times. Other entries
can be added dynamically by <cf/add roa/ command.
<tag>eval <m/expr/</tag> Evaluates given filter expression. It
is used by us for testing of filters.
</descrip>
......@@ -570,7 +586,7 @@ This argument can be omitted if there exists only a single instance.
<tag>show interfaces [summary]</tag>
Show the list of interfaces. For each interface, print its type, state, MTU and addresses assigned.
<tag>show symbols [table|filter|function|protocol|template|<symbol>]</tag>
<tag>show symbols [table|filter|function|protocol|template|roa|<symbol>]</tag>
Show the list of symbols defined in the configuration (names of protocols, routing tables etc.).
<tag>show route [[for] <m/prefix/|<m/IP/] [table <m/sym/] [filter <m/f/|where <m/c/] [(export|preexport) <m/p/] [protocol <m/p/] [<m/options/]</tag>
......@@ -599,6 +615,29 @@ This argument can be omitted if there exists only a single instance.
number of networks, number of routes before and after filtering). If
you use <cf/count/ instead, only the statistics will be printed.
<tag>show xroa [<m/prefix/ | in <m/prefix/ | for <m/prefix/] [as <m/num/] [table <m/t/>]</tag>
Show contents of a ROA table (by default of the first one).
You can specify a <m/prefix/ to print ROA entries for a
specific network. If you use <cf>for <m/prefix/</cf>, you'll
get all entries relevant for route validation of the network
prefix; i.e., ROA entries whose prefixes cover the network
prefix. Or you can use <cf>in <m/prefix/</cf> to get ROA entries
covered by the network prefix. You could also use <cf/as/ option
to show just entries for given AS.
<tag>add roa <m/prefix/ max <m/num/] as <m/num/ [table <m/t/>]</tag>
Add a new ROA entry to a ROA table. Such entry is called
<it/dynamic/ compared to <it/static/ entries specified in the
config file. These dynamic entries survive reconfiguration.
<tag>delete roa <m/prefix/ max <m/num/] as <m/num/ [table <m/t/>]</tag>
Delete the specified ROA entry from a ROA table. Only dynamic
ROA entries (i.e., the ones added by <cf/add roa/ command) can
be deleted.
<tag>flush roa [table <m/t/>]</tag>
Remove all dynamic ROA entries from a ROA table.
<tag>configure [soft] ["<m/config file/"]</tag>
Reload configuration from a given file. BIRD will smoothly
switch itself to the new configuration, protocols are
......@@ -918,6 +957,17 @@ used on element and set of elements of the same type (returning true if element
on two strings (returning true if first string matches a shell-like pattern stored in second string) or on IP and prefix (returning true if IP is within the range defined by that prefix), or on
prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on number and bgppath (returning true if the number is in the path) or on pair/quad and clist (returning true if the pair/quad is element of the clist) or on clist and pair/quad set (returning true if there is an element of the clist that is also a member of the pair/quad set).
<p>There is one operator related to ROA infrastructure -
<cf/roa_check()/. It examines a ROA table and does RFC 6483 route
origin validation for a given network prefix. The basic usage
is <cf>roa_check(<m/table/)</cf>, which checks current route (which
should be from BGP to have AS_PATH argument) in the specified ROA
table and returns ROA_UNKNOWN if there is no relevant ROA, ROA_VALID
if there is a matching ROA, or ROA_INVALID if there are some relevant
ROAs but none of them match. There is also an extended variant
<cf>roa_check(<m/table/, <m/prefix/, <m/asn/)</cf>, which allows to
specify a prefix and an ASN as arguments.
<sect>Control structures
......
......@@ -259,6 +259,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
DEFINED,
ADD, DELETE, CONTAINS, RESET,
PREPEND, FIRST, LAST, MATCH,
ROA_CHECK,
EMPTY,
FILTER, WHERE, EVAL)
......@@ -755,6 +756,9 @@ term:
| DELETE '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; }
| FILTER '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'f'; }
| ROA_CHECK '(' SYM ')' { $$ = f_generate_roa_check($3, NULL, NULL); }
| ROA_CHECK '(' SYM ',' term ',' term ')' { $$ = f_generate_roa_check($3, $5, $7); }
/* | term '.' LEN { $$->code = P('P','l'); } */
/* function_call is inlined here */
......@@ -801,7 +805,6 @@ print_list: /* EMPTY */ { $$ = NULL; }
$$ = $1;
} else $$ = $3;
}
;
var_listn: term {
......
......@@ -54,6 +54,24 @@ f_generate_complex(int operation, int operation_aux, struct f_inst *dyn, struct
return set_dyn;
}
struct f_inst *
f_generate_roa_check(struct symbol *sym, struct f_inst *prefix, struct f_inst *asn)
{
struct f_inst_roa_check *ret = cfg_allocz(sizeof(struct f_inst_roa_check));
ret->i.code = P('R','C');
ret->i.lineno = ifs->conf_lino;
ret->i.arg1 = prefix;
ret->i.arg2 = asn;
/* prefix == NULL <-> asn == NULL */
if ((sym->class != SYM_ROA) || ! sym->def)
cf_error("%s is not a ROA table", sym->name);
ret->rtc = sym->def;
return &ret->i;
}
char *
filter_name(struct filter *filter)
{
......
......@@ -248,7 +248,7 @@ val_simple_in_range(struct f_val v1, struct f_val v2)
return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len);
if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX))
return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len) && (v1.val.px.len >= v2.val.px.len);
return net_in_net(v1.val.px.ip, v1.val.px.len, v2.val.px.ip, v2.val.px.len);
return CMP_ERROR;
}
......@@ -1208,6 +1208,38 @@ interpret(struct f_inst *what)
break;
case P('R','C'): /* ROA Check */
if (what->arg1)
{
TWOARGS;
if ((v1.type != T_PREFIX) || (v2.type != T_INT))
runtime("Invalid argument to roa_check()");
as = v2.val.i;
}
else
{
v1.val.px.ip = (*f_rte)->net->n.prefix;
v1.val.px.len = (*f_rte)->net->n.pxlen;
/* We ignore temporary attributes, probably not a problem here */
/* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
eattr *e = ea_find((*f_rte)->attrs->eattrs, EA_CODE(EAP_BGP, 0x02));
if (!e || e->type != EAF_TYPE_AS_PATH)
runtime("Missing AS_PATH attribute");
as_path_get_last(e->u.ptr, &as);
}
struct roa_table_config *rtc = ((struct f_inst_roa_check *) what)->rtc;
if (!rtc->table)
runtime("Missing ROA table");
res.type = T_ENUM_ROA;
res.val.i = roa_check(rtc->table, v1.val.px.ip, v1.val.px.len, as);
break;
default:
bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
}
......@@ -1332,6 +1364,13 @@ i_same(struct f_inst *f1, struct f_inst *f2)
case P('C','a'): TWOARGS; break;
case P('a','f'):
case P('a','l'): ONEARG; break;
case P('R','C'):
TWOARGS;
/* Does not really make sense - ROA check resuls may change anyway */
if (strcmp(((struct f_inst_roa_check *) f1)->rtc->name,
((struct f_inst_roa_check *) f2)->rtc->name))
return 0;
break;
default:
bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
}
......
......@@ -32,6 +32,12 @@ struct f_inst { /* Instruction */
#define arg1 a1.p
#define arg2 a2.p
/* Not enough fields in f_inst for three args used by roa_check() */
struct f_inst_roa_check {
struct f_inst i;
struct roa_table_config *rtc;
};
struct f_prefix {
ip_addr ip;
int len;
......@@ -66,6 +72,8 @@ struct f_inst *f_new_inst(void);
struct f_inst *f_new_dynamic_attr(int type, int f_type, int code); /* Type as core knows it, type as filters know it, and code of dynamic attribute */
struct f_tree *f_new_tree(void);
struct f_inst *f_generate_complex(int operation, int operation_aux, struct f_inst *dyn, struct f_inst *argument);
struct f_inst *f_generate_roa_check(struct symbol *sym, struct f_inst *prefix, struct f_inst *asn);
struct f_tree *build_tree(struct f_tree *);
struct f_tree *find_tree(struct f_tree *t, struct f_val val);
......@@ -141,6 +149,7 @@ int tree_compare(const void *p1, const void *p2);
#define T_ENUM_SCOPE 0x32
#define T_ENUM_RTC 0x33
#define T_ENUM_RTD 0x34
#define T_ENUM_ROA 0x35
/* new enums go here */
#define T_ENUM_EMPTY 0x3f /* Special hack for atomic_aggr */
......
......@@ -52,6 +52,32 @@ function fifteen()
return 15;
}
roa table rl
{
roa 10.110.0.0/16 max 16 as 1000;
roa 10.120.0.0/16 max 24 as 1000;
roa 10.130.0.0/16 max 24 as 2000;
roa 10.130.128.0/18 max 24 as 3000;
}
function test_roa()
{
# cannot be tested in __startup(), sorry
print "Testing ROA";
print "Should be true: ", roa_check(rl, 10.10.0.0/16, 1000) = ROA_UNKNOWN,
" ", roa_check(rl, 10.0.0.0/8, 1000) = ROA_UNKNOWN,
" ", roa_check(rl, 10.110.0.0/16, 1000) = ROA_VALID,
" ", roa_check(rl, 10.110.0.0/16, 2000) = ROA_INVALID,
" ", roa_check(rl, 10.110.32.0/20, 1000) = ROA_INVALID,
" ", roa_check(rl, 10.120.32.0/20, 1000) = ROA_VALID;
print "Should be true: ", roa_check(rl, 10.120.32.0/20, 2000) = ROA_INVALID,
" ", roa_check(rl, 10.120.32.32/28, 1000) = ROA_INVALID,
" ", roa_check(rl, 10.130.130.0/24, 1000) = ROA_INVALID,
" ", roa_check(rl, 10.130.130.0/24, 2000) = ROA_VALID,
" ", roa_check(rl, 10.130.30.0/24, 3000) = ROA_INVALID,
" ", roa_check(rl, 10.130.130.0/24, 3000) = ROA_VALID;
}
function paths()
bgpmask pm1;
bgpmask pm2;
......@@ -163,7 +189,7 @@ eclist el2;
print "eclist A isect B: ", filter( el, el2 );
print "eclist A \ B: ", delete( el, el2 );
# test_roa();
}
function bla()
......
......@@ -15,7 +15,10 @@
#include "ipv6.h"
#endif
#define ipa_in_net(x,n,p) (!ipa_nonzero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p))))
#define ipa_zero(x) (!ipa_nonzero(x))
#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
#define ipa_in_net(x,n,p) (ipa_zero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p))))
#define net_in_net(n1,l1,n2,l2) (((l1) >= (l2)) && (ipa_zero(ipa_and(ipa_xor((n1),(n2)),ipa_mkmask(l2)))))
/*
* ip_classify() returns either a negative number for invalid addresses
......@@ -50,9 +53,6 @@ struct prefix {
unsigned int len;
};
#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
#define ipa_zero(x) (!ipa_nonzero(x))
static inline int ipa_classify_net(ip_addr a)
{ return ipa_zero(a) ? (IADDR_HOST | SCOPE_UNIVERSE) : ipa_classify(a); }
......
source=rt-table.c rt-fib.c rt-attr.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
source=rt-table.c rt-fib.c rt-attr.c rt-roa.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
a-path.c a-set.c
root-rel=../
dir-name=nest
......
......@@ -72,6 +72,7 @@ print_size(char *dsc, size_t val)
extern pool *rt_table_pool;
extern pool *rta_pool;
extern pool *roa_pool;
extern pool *proto_pool;
void
......@@ -80,6 +81,7 @@ cmd_show_memory(void)
cli_msg(-1018, "BIRD memory usage");
print_size("Routing tables:", rmemsize(rt_table_pool));
print_size("Route attributes:", rmemsize(rta_pool));
print_size("ROA tables:", rmemsize(roa_pool));
print_size("Protocols:", rmemsize(proto_pool));
print_size("Total:", rmemsize(&root_pool));
cli_msg(0, "");
......
......@@ -19,6 +19,7 @@ CF_DEFINES
static struct proto_config *this_proto;
static struct iface_patt *this_ipatt;
static struct iface_patt_node *this_ipn;
static struct roa_table_config *this_roa_table;
static list *this_p_list;
static struct password_item *this_p_item;
static int password_id;
......@@ -44,7 +45,7 @@ CF_DECLS
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, XROA, MAX, FLUSH)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC)
......@@ -53,14 +54,17 @@ CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIREC
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <i32> idval
%type <f> imexport
%type <r> rtable
%type <s> optsym
%type <ra> r_args
%type <ro> roa_args
%type <rot> roa_table_arg
%type <sd> sym_args
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport roa_mode
%type <ps> proto_patt proto_patt2
CF_GRAMMAR
......@@ -113,6 +117,24 @@ newtab: TABLE SYM {
}
;
CF_ADDTO(conf, roa_table)
roa_table_start: ROA TABLE SYM {
this_roa_table = roa_new_table_config($3);
};
roa_table_opts:
/* empty */
| roa_table_opts ROA prefix MAX NUM AS NUM ';' {
roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
}
;
roa_table:
roa_table_start
| roa_table_start '{' roa_table_opts '}'
;
/* Definition of protocols */
CF_ADDTO(conf, proto)
......@@ -433,7 +455,44 @@ export_or_preexport:
| EXPORT { $$ = 2; }
;
CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|<symbol>], [[Show all known symbolic names]])
CF_CLI(SHOW XROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
{ roa_show($3); } ;
roa_args:
/* empty */ {
$$ = cfg_allocz(sizeof(struct roa_show_data));
$$->mode = ROA_SHOW_ALL;
$$->table = roa_table_default;
if (roa_table_default == NULL)
cf_error("No ROA table defined");
}
| roa_args roa_mode prefix {
$$ = $1;
if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
$$->prefix = $3.addr;
$$->pxlen = $3.len;
$$->mode = $2;
}
| roa_args AS NUM {
$$ = $1;
$$->asn = $3;
}
| roa_args TABLE SYM {
$$ = $1;
if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
$$->table = ((struct roa_table_config *)$3->def)->table;
}
;
roa_mode:
{ $$ = ROA_SHOW_PX; }
| IN { $$ = ROA_SHOW_IN; }
| FOR { $$ = ROA_SHOW_FOR; }
;
CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
{ cmd_show_symbols($3); } ;
sym_args:
......@@ -445,9 +504,34 @@ sym_args:
| sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
| sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
| sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
| sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
| sym_args SYM { $$ = $1; $$->sym = $2; }
;
roa_table_arg:
/* empty */ {
if (roa_table_default == NULL)
cf_error("No ROA table defined");
$$ = roa_table_default;
}
| TABLE SYM {
if ($2->class != SYM_ROA)
cf_error("%s is not a ROA table", $2->name);
$$ = ((struct roa_table_config *)$2->def)->table;
}
;
CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
{ roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); } ;
CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
{ roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); } ;
CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
{ roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); } ;
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
{ rdump(&root_pool); cli_msg(0, ""); } ;
......
......@@ -454,4 +454,84 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
/*
* Route Origin Authorization
*/
struct roa_item {
u32 asn;
byte maxlen;
byte src;
struct roa_item *next;
};
struct roa_node {
struct fib_node n;
struct roa_item *items;
// u32 cached_asn;
};
struct roa_table {
node n; /* Node in roa_table_list */
struct fib fib;
char *name; /* Name of this ROA table */
struct roa_table_config *cf; /* Configuration of this ROA table */
};
struct roa_item_config {
ip_addr prefix;
byte pxlen, maxlen;
u32 asn;
struct roa_item_config *next;
};
struct roa_table_config {
node n; /* Node in config->rpa_tables */
char *name; /* Name of this ROA table */
struct roa_table *table;
struct roa_item_config *roa_items; /* Preconfigured ROA items */
// char *filename;
// int gc_max_ops; /* Maximum number of operations before GC is run */
// int gc_min_time; /* Minimum time between two consecutive GC runs */
};
struct roa_show_data {
struct fib_iterator fit;
struct roa_table *table;
ip_addr prefix;
byte pxlen;
byte mode; /* ROA_SHOW_* values */
u32 asn; /* Filter ASN, 0 -> all */
};
#define ROA_UNKNOWN 0
#define ROA_VALID 1
#define ROA_INVALID 2
#define ROA_SRC_ANY 0
#define ROA_SRC_CONFIG 1
#define ROA_SRC_DYNAMIC 2
#define ROA_SHOW_ALL 0
#define ROA_SHOW_PX 1
#define ROA_SHOW_IN 2
#define ROA_SHOW_FOR 3
extern struct roa_table *roa_table_default;
void roa_add_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src);
void roa_delete_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src);
void roa_flush(struct roa_table *t, byte src);
byte roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn);
struct roa_table_config * roa_new_table_config(struct symbol *s);
void roa_add_item_config(struct roa_table_config *rtc, ip_addr prefix, byte pxlen, byte maxlen, u32 asn);
void roa_init(void);
void roa_preconfig(struct config *c);
void roa_commit(struct config *new, struct config *old);
void roa_show(struct roa_show_data *d);
#endif
This diff is collapsed.
......@@ -643,6 +643,7 @@ main(int argc, char **argv)
io_init();
rt_init();
if_init();
roa_init();
uid_t use_uid = get_uid(use_user);
gid_t use_gid = get_gid(use_group);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment