From fe96b511ca02d7c228d6f6244c1a8f582bf2d1e2 Mon Sep 17 00:00:00 2001 From: Alexandre Snarskii Date: Thu, 31 Jul 2014 16:00:08 +0400 Subject: [PATCH] Empty objects handling: explicit deny-any instead of implicit accept-any. --- CHANGES | 5 +++++ bgpq3.c | 5 +++++ bgpq3_printer.c | 60 ++++++++++++++++++++++++++++++++++++++----------- configure | 18 +++++++-------- configure.in | 2 +- sx_prefix.c | 6 +++++ sx_prefix.h | 1 + 7 files changed, 74 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index 436c097..83ae478 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +0.1.24 (2014-07-31) + - empty prefix-lists (Cisco), extended access-lists (Cisco), as-path + filters (Cisco and Juniper) and route-filters (Juniper) handling: + explicit 'deny any' entry now generated instead of implicit 'permit-any'. + 0.1.23 (2014-07-30) - bugfix: use of -M option caused major slowdown as it turned off request pipelining... Thanks to Tore Anderson. diff --git a/bgpq3.c b/bgpq3.c index c4127be..88182e0 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -378,6 +378,11 @@ main(int argc, char* argv[]) " yet.\n"); }; + if(expander.match != NULL && (expander.vendor != V_JUNIPER || + expander.generation != T_EACL)) { + sx_report(SX_FATAL, "Sorry, extra match conditions (-M) can be used only with Juniper route-filters\n"); + }; + if(!argv[0]) usage(1); while(argv[0]) { diff --git a/bgpq3_printer.c b/bgpq3_printer.c index ea1bd35..4a22913 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -17,7 +17,7 @@ int bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k; + int nc=0, i, j, k, empty=1; fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN"); if(b->asn32s[b->asnumber/65536] && b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& @@ -26,9 +26,11 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) fprintf(f,"ip as-path access-list %s permit ^%i.%i(_%i.%i)*$\n", b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536, b->asnumber/65536,b->asnumber%65536); + empty=0; } else { fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n", b->name?b->name:"NN",b->asnumber,b->asnumber); + empty=0; }; }; for(k=0;k<65536;k++) { @@ -43,16 +45,20 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) fprintf(f,"ip as-path access-list %s permit" " ^%i(_[0-9]+)*_(%i.%i", b->name?b->name:"NN", b->asnumber,k,i*8+j); + empty=0; } else { fprintf(f,"ip as-path access-list %s permit" " ^%i(_[0-9]+)*_(%i", b->name?b->name:"NN", b->asnumber,k*65536+i*8+j); + empty=0; }; } else { if(b->asdot && k>0) { fprintf(f,"|%i.%i",k,i*8+j); + empty=0; } else { fprintf(f,"|%i",k*65536+i*8+j); + empty=0; }; } nc++; @@ -65,12 +71,14 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\n"); + if(empty) + fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN"); return 0; }; int bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k; + int nc=0, i, j, k, empty=1; fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN"); if(b->asn32s[b->asnumber/65536] && b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& @@ -82,6 +90,7 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) fprintf(f,"ip as-path access-list %s permit ^(_%i)*$\n", b->name?b->name:"NN",b->asnumber); }; + empty=0; }; for(k=0;k<65536;k++) { if(!b->asn32s[k]) continue; @@ -94,16 +103,20 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) fprintf(f,"ip as-path access-list %s permit" " ^(_[0-9]+)*_(%i.%i", b->name?b->name:"NN", k,i*8+j); + empty=0; } else { fprintf(f,"ip as-path access-list %s permit" " ^(_[0-9]+)*_(%i", b->name?b->name:"NN", k*65536+i*8+j); + empty=0; }; } else { if(b->asdot && k>0) { fprintf(f,"|%i.%i",k,i*8+j); + empty=0; } else { fprintf(f,"|%i",k*65536+i*8+j); + empty=0; }; } nc++; @@ -116,6 +129,8 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\n"); + if(empty) + fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN"); return 0; }; @@ -156,6 +171,8 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\";\n"); + else if(lineNo==0) + fprintf(f," as-path aNone \"!.*\";\n"); fprintf(f," }\n}\n"); return 0; }; @@ -198,6 +215,8 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\";\n"); + else if(lineNo==0) + fprintf(f," as-path aNone \"!.*\";\n"); fprintf(f," }\n}\n"); return 0; }; @@ -465,7 +484,12 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) if(b->match) fprintf(f," %s;\n",b->match); }; - sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f); + if(!sx_radix_tree_empty(b->tree)) { + sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f); + } else { + fprintf(f," route-filter %s/0 orlonger reject;\n", + b->tree->family == AF_INET ? "0.0.0.0" : "::"); + }; if(c) { fprintf(f, " }\n }\n }\n}\n"); } else { @@ -477,19 +501,24 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) int bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name; + bname=b->name ? b->name : "NN"; fprintf(f,"no %s prefix-list %s\n", - (b->family==AF_INET)?"ip":"ipv6",bname?bname:"NN"); - sx_radix_tree_foreach(b->tree,bgpq3_print_cprefix,f); + (b->family==AF_INET)?"ip":"ipv6",bname); + if (!sx_radix_tree_empty(b->tree)) { + sx_radix_tree_foreach(b->tree,bgpq3_print_cprefix,f); + } else { + fprintf(f, "! generated prefix-list %s is empty\n", bname); + fprintf(f, "%s prefix-list %s deny 0.0.0.0/0\n", + (b->family==AF_INET) ? "ip" : "ipv6", bname); + }; return 0; }; int bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name; - fprintf(f,"no prefix-set %s\nprefix-set %s\n", bname?bname:"NN", - bname?bname:"NN"); + bname=b->name ? b->name : "NN"; + fprintf(f,"no prefix-set %s\nprefix-set %s\n", bname, bname); sx_radix_tree_foreach(b->tree,bgpq3_print_cprefixxr,f); fprintf(f, "\nend-set\n"); return 0; @@ -518,10 +547,15 @@ bgpq3_print_bird_prefixlist(FILE* f, struct bgpq_expander* b) int bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b) { - bname=b->name; - fprintf(f,"no ip access-list extended %s\n", bname?bname:"NN"); - fprintf(f,"ip access-list extended %s\n", bname?bname:"NN"); - sx_radix_tree_foreach(b->tree,bgpq3_print_ceacl,f); + bname=b->name ? b->name : "NN"; + fprintf(f,"no ip access-list extended %s\n", bname); + if (!sx_radix_tree_empty(b->tree)) { + fprintf(f,"ip access-list extended %s\n", bname); + sx_radix_tree_foreach(b->tree,bgpq3_print_ceacl,f); + } else { + fprintf(f,"! generated access-list %s is empty\n", bname); + fprintf(f,"ip access-list extended %s deny any any\n", bname); + }; return 0; }; diff --git a/configure b/configure index 7520bdf..06fc32a 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for bgpq3 0.1.23. +# Generated by GNU Autoconf 2.69 for bgpq3 0.1.24. # # Report bugs to . # @@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bgpq3' PACKAGE_TARNAME='bgpq3' -PACKAGE_VERSION='0.1.23' -PACKAGE_STRING='bgpq3 0.1.23' +PACKAGE_VERSION='0.1.24' +PACKAGE_STRING='bgpq3 0.1.24' PACKAGE_BUGREPORT='snar@snar.spb.ru' PACKAGE_URL='' @@ -1187,7 +1187,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures bgpq3 0.1.23 to adapt to many kinds of systems. +\`configure' configures bgpq3 0.1.24 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1248,7 +1248,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bgpq3 0.1.23:";; + short | recursive ) echo "Configuration of bgpq3 0.1.24:";; esac cat <<\_ACEOF @@ -1327,7 +1327,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bgpq3 configure 0.1.23 +bgpq3 configure 0.1.24 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1495,7 +1495,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bgpq3 $as_me 0.1.23, which was +It was created by bgpq3 $as_me 0.1.24, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3413,7 +3413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bgpq3 $as_me 0.1.23, which was +This file was extended by bgpq3 $as_me 0.1.24, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3475,7 +3475,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -bgpq3 config.status 0.1.23 +bgpq3 config.status 0.1.24 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.in b/configure.in index 315eb87..082d195 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -AC_INIT(bgpq3,0.1.23,snar@snar.spb.ru) +AC_INIT(bgpq3,0.1.24,snar@snar.spb.ru) AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_INSTALL diff --git a/sx_prefix.c b/sx_prefix.c index d90bde4..a403f0b 100644 --- a/sx_prefix.c +++ b/sx_prefix.c @@ -189,6 +189,12 @@ sx_radix_tree_new(int af) return rt; }; +int +sx_radix_tree_empty(struct sx_radix_tree* t) +{ + return t->head == NULL; +}; + struct sx_radix_node* sx_radix_node_new(struct sx_prefix* prefix) { diff --git a/sx_prefix.h b/sx_prefix.h index 36bc909..ace7b24 100644 --- a/sx_prefix.h +++ b/sx_prefix.h @@ -52,6 +52,7 @@ int sx_prefix_jsnprintf(struct sx_prefix* p, char* rbuffer, int srb); struct sx_radix_tree* sx_radix_tree_new(int af); struct sx_radix_node* sx_radix_node_new(struct sx_prefix* prefix); struct sx_prefix* sx_prefix_overlay(struct sx_prefix* p, int n); +int sx_radix_tree_empty(struct sx_radix_tree* t); void sx_radix_node_fprintf(struct sx_radix_node* node, void* udata); int sx_radix_node_foreach(struct sx_radix_node* node, void (*func)(struct sx_radix_node*, void*), void* udata);