diff --git a/filter/filter.h b/filter/filter.h index 2b2d23c2..97d5a814 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -175,12 +175,12 @@ void val_format(struct f_val v, buffer *buf); #define T_PREFIX_SET 0x81 -#define SA_FROM 1 -#define SA_GW 2 -#define SA_NET 3 -#define SA_PROTO 4 -#define SA_SOURCE 5 -#define SA_SCOPE 6 +#define SA_FROM 1 +#define SA_GW 2 +#define SA_NET 3 +#define SA_PROTO 4 +#define SA_SOURCE 5 +#define SA_SCOPE 6 #define SA_CAST 7 #define SA_DEST 8 #define SA_IFNAME 9 diff --git a/filter/filter_test.c b/filter/filter_test.c index dd4ec2d8..cc193819 100644 --- a/filter/filter_test.c +++ b/filter/filter_test.c @@ -6,23 +6,28 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include #include #include "test/birdtest.h" -#include "test/utils.h" +#include #include "filter/filter.h" #include "lib/main_helper.h" +#include "conf/conf.h" static int -t_filter(void) +t_simple(void) { #define TESTING_FILTER_NAME "testing_filter" bt_bird_init(); - bt_config_parse( + struct config *cfg = bt_config_parse( BT_CONFIG_PARSE_ROUTER_ID BT_CONFIG_PARSE_KERNEL_DEVICE "\n" @@ -33,11 +38,37 @@ t_filter(void) " else\n" " reject;\n" "}\n" + "\n" + "filter " TESTING_FILTER_NAME "2\n" + "{\n" + " if net ~ 10.0.0.0/20 then\n" + " accept;\n" + " else {\n" + " reject; } \n" + "}\n" + "\n" ); struct symbol *sym = NULL; sym = cf_find_symbol(TESTING_FILTER_NAME); + struct symbol *sym2 = NULL; + sym2 = cf_find_symbol(TESTING_FILTER_NAME "2"); + + + struct filter *f = sym->def; + struct filter *f2 = sym2->def; + bt_assert(strcmp(filter_name(f), TESTING_FILTER_NAME) == 0); + + + bt_assert(filter_same(f,f2)); + + bt_debug("f_eval_asn: %u \n", f_eval_asn(f->root)); + bt_debug("f_eval_int: %u \n", f_eval_int(f->root)); + struct f_val v = f_eval(f->root, cfg->mem); + bt_debug("v type: %d \n", v.type); + + /* TODO: check the testing filter */ return BT_SUCCESS; @@ -61,16 +92,17 @@ load_file(const char *filename) } static int -t_example_config_files(void *filename_void) +t_example_config_files(const void *filename_void) { bt_bird_init(); const char *filename = filename_void; + bt_debug("Testing BIRD configuration from %s\n", filename); + char *cfg_str = load_file(filename); bt_config_parse(cfg_str); mb_free(cfg_str); - bt_debug("Parsing configuration from %s\n", filename); config_name = filename; read_config(); struct config *conf = read_config(); @@ -84,15 +116,19 @@ main(int argc, char *argv[]) { bt_init(argc, argv); - bt_test_suite(t_filter, "Test all example config files"); + bt_test_suite(t_simple, "Simple filter testing"); const char *files[] = { "filter/test.conf", "filter/test.conf2", + "filter/test_bgp_filtering.conf", +#ifdef IPV6 "filter/test6.conf", +#endif }; size_t files_arr_size = sizeof(files)/sizeof(files[0]); - for (size_t i = 0; i < files_arr_size; i++) + size_t i; + for (i = 0; i < files_arr_size; i++) bt_test_suite_arg_extra(t_example_config_files, files[i], BT_DEFAULT_FORKING, 30, "Test a example config file %s", files[i]); return bt_end(); diff --git a/filter/test.conf b/filter/test.conf index a99d0a51..ff719df1 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -397,7 +397,7 @@ string st; print "1.2.3.4 = ", onetwo; i = 4200000000; - print "4200000000 = ", i, " false: ", i = 4200000000, " ", i > 4100000000, " false: ", i > 4250000000; + print "4200000000 = ", i, " true: ", i = 4200000000, " ", i > 4100000000, " false: ", i > 4250000000; test_undef(2); test_undef(3); @@ -408,7 +408,7 @@ string st; print "done"; quitbird; -# print "*** FAIL: this is unreachable"; + print "*** FAIL: this is unreachable"; } filter testf diff --git a/filter/test.conf2 b/filter/test.conf2 index 60bdd965..625b26f9 100644 --- a/filter/test.conf2 +++ b/filter/test.conf2 @@ -50,9 +50,9 @@ protocol static { rip_metric = rip_metric + 5; print rip_metric; bgp_community = - empty - ; - print "nazdar"; + print "hi"; bgp_community = add(bgp_community, (1,2)); - print "cau"; + print "hello"; bgp_community = add(bgp_community, (2,3)); bgp_community.add((4,5)); print "community = ", bgp_community; diff --git a/filter/test6.conf b/filter/test6.conf index f25ffc47..6952e201 100644 --- a/filter/test6.conf +++ b/filter/test6.conf @@ -30,7 +30,7 @@ function fifteen() return 15; } -function paths() +function _paths() bgpmask pm1; bgpmask pm2; bgppath p2; @@ -97,7 +97,7 @@ ip p; pair pp; int set is; prefix set pxs; -string s; +string str; { print "Testing filter language:"; i = four; @@ -129,8 +129,8 @@ string s; print "Testing pairs: (1,2) = ", (1,2), " = ", pp; print "Testing enums: ", RTS_DUMMY, " ", RTS_STATIC; - s = "Hello"; - print "Testing string: ", s, " true: ", s ~ "Hell*", " false: ", s ~ "ell*"; + str = "Hello"; + print "Testing string: ", str, " true: ", str ~ "Hell*", " false: ", str ~ "ell*"; b = true; print "Testing bool: ", b, ", ", !b; @@ -156,7 +156,7 @@ string s; i = fifteen(); print "Testing function calls: 15 = ", i; - paths(); + _paths(); print "done"; quitbird; diff --git a/filter/test_bgp_filtering.conf b/filter/test_bgp_filtering.conf new file mode 100644 index 00000000..941dc702 --- /dev/null +++ b/filter/test_bgp_filtering.conf @@ -0,0 +1,119 @@ +router id 62.168.0.1; + +function net_martian() +{ + return net ~ [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+, 10.0.0.0/8+, + 127.0.0.0/8+, 224.0.0.0/4+, 240.0.0.0/4+, 0.0.0.0/32-, 0.0.0.0/0{25,32}, 0.0.0.0/0{0,7} ]; +} + +function net_local() +{ + return net ~ [ 12.10.0.0/16+, 34.10.0.0/16+ ]; +} + +function rt_import(int asn; int set peer_asns; prefix set peer_nets) +{ + if ! (net ~ peer_nets) then return false; + if ! (bgp_path.last ~ peer_asns) then return false; + if bgp_path.first != asn then return false; + if bgp_path.len > 64 then return false; + if bgp_next_hop != from then return false; + return true; +} + +function rt_import_all(int asn) +{ + if net_martian() || net_local() then return false; + if bgp_path.first != asn then return false; + if bgp_path.len > 64 then return false; + if bgp_next_hop != from then return false; + return true; +} + +function rt_import_rs(int asn) +{ + if net_martian() || net_local() then return false; + if bgp_path.len > 64 then return false; + return true; +} + +function rt_export() +{ + if proto = "static_bgp" then return true; + if source != RTS_BGP then return false; + if net_martian() then return false; + if bgp_path.len > 64 then return false; + # return bgp_next_hop ~ [ 100.1.1.1, 100.1.1.2, 200.1.1.1 ]; + return bgp_path.first ~ [ 345, 346 ]; +} + + +function rt_export_all() +{ + if proto = "static_bgp" then return true; + if source != RTS_BGP then return false; + if net_martian() then return false; + if bgp_path.len > 64 then return false; + return true; +} + +filter bgp_in_uplink_123 +{ + if ! rt_import_all(123) then reject; + accept; +} + +filter bgp_out_uplink_123 +{ + if ! rt_export() then reject; + accept; +} + + +filter bgp_in_peer_234 +{ + if ! rt_import(234, [ 234, 1234, 2345, 3456 ], + [ 12.34.0.0/16, 23.34.0.0/16, 34.56.0.0/16 ]) + then reject; + accept; +} + +filter bgp_out_peer_234 +{ + if ! rt_export() then reject; + accept; +} + +filter bgp_in_rs +{ + if ! rt_import_rs(bgp_path.last) then reject; + accept; +} + +filter bgp_out_rs +{ + if ! rt_export() then reject; + accept; +} + + +filter bgp_in_client_345 +{ + if ! rt_import(345, [ 345 ], [ 34.5.0.0/16 ]) then reject; + accept; +} + +filter bgp_out_client_345 +{ + if ! rt_export_all() then reject; + accept; +} + +function __startup() +{ + quitbird; +} + +eval __startup(); + +