diff --git a/CHANGES b/CHANGES index 47e931a..e8612a7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,23 @@ +0.1.6 (2008-08-08): + - maxsockbuf call added, that can help with pipelining of really large + as-sets. + - new key -M for juniper route-filters, f.e.: + bgpq3 -JEM "protocol bgp;\n community no-export" -l PolicyName/TermName + will generate term with additional match conditions, like: + + policy-options { + policy-statement PolicyName { + term TermName { + replace: + from { + protocol bgp; + community no-export; + route-filter 10.0.0.0/24 exact; + } + } + } + } + 0.1.5 (2008-06-02): - route-set's expansion added. Fully functional for IPv4 prefixes, but not for IPv6 - only those prefixes explicitely marked as 'member-of: RS..' diff --git a/bgpq3.c b/bgpq3.c index b190f2b..63174d1 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -36,9 +36,11 @@ usage(int ecode) printf(" -G number : generate output as-path access-list\n"); printf(" -h : this help\n"); printf(" -J : generate config for JunOS (Cisco IOS by default)\n"); - printf(" -l : use specified name for generated access/prefix/.." + printf(" -M match : extra match conditions for JunOS route-filters\n"); + printf(" -l name : use specified name for generated access/prefix/.." " list\n"); - printf(" -P : generate prefix-list (default)\n"); + printf(" -P : generate prefix-list (default, just for backward" + " compatibility)\n"); printf(" -R len : allow specific routes up to masklen specified\n"); printf(" -S sources: use only specified sources (default:" " RADB,RIPE,APNIC)\n"); @@ -102,7 +104,7 @@ main(int argc, char* argv[]) bgpq_expander_init(&expander,af); expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"36AdEhS:Jf:l:W:PR:G:T"))!=EOF) { + while((c=getopt(argc,argv,"36AdEhS:Jf:l:M:W:PR:G:T"))!=EOF) { switch(c) { case '3': expander.asn32=1; @@ -145,6 +147,35 @@ main(int argc, char* argv[]) break; case 'l': expander.name=optarg; break; + case 'M': { + char* c, *d; + expander.match=strdup(optarg); + c=d=expander.match; + while(*c) { + if(*c=='\\') { + if(*(c+1)=='n') { + *d='\n'; + d++; + c+=2; + } else if(*(c+1)=='r') { + *d='\r'; + d++; + c+=2; + } else if(*(c+1)=='\\') { + *d='\\'; + d++; + c+=2; + }; + } else { + if(c!=d) { + *d=*c; + }; + d++; + c++; + }; + }; + *d=0; + }; case 'T': pipelining=0; break; case 'S': expander.sources=optarg; @@ -262,12 +293,12 @@ main(int argc, char* argv[]) exit(1); }; - if(aggregate) - sx_radix_tree_aggregate(expander.tree); - if(refine) sx_radix_tree_refine(expander.tree,refine); + if(aggregate) + sx_radix_tree_aggregate(expander.tree); + switch(expander.generation) { default : case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n"); diff --git a/bgpq3.h b/bgpq3.h index e09c480..50c3262 100644 --- a/bgpq3.h +++ b/bgpq3.h @@ -39,6 +39,7 @@ struct bgpq_expander { unsigned char* asn32s[65536]; struct bgpq_prequest* firstpipe, *lastpipe; int piped; + char* match; }; diff --git a/bgpq3_printer.c b/bgpq3_printer.c index 9f4c873..ad9463d 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -267,6 +267,7 @@ bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) netmask=0; } else { netmask<<=(32-n->prefix.masklen); + netmask&=0xfffffffful; }; netmask=htonl(netmask); @@ -282,7 +283,7 @@ bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) wildaddr=wildaddr&(~wild2addr); if(masklen==32) mask=0xfffffffful; - else mask=0xfffffffful<<(32-masklen); + else mask=0xfffffffful & (0xfffffffful<<(32-masklen)); if(n->aggregateHi==32) wild2addr=0; else wild2addr=0xfffffffful>>n->aggregateHi; @@ -331,10 +332,14 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) if(b->name && (c=strchr(b->name,'/'))) { *c=0; fprintf(f,"policy-options {\n policy-statement %s {\n term %s {\n" - "replace:\n from {\n protocol bgp;\n", b->name, c+1); + "replace:\n from {\n", b->name, c+1); + if(b->match) + fprintf(f," %s;\n",b->match); } else { fprintf(f,"policy-options {\n policy-statement %s { \n" - "replace:\n from {\n protocol bgp;\n", b->name?b->name:"NN"); + "replace:\n from {\n", b->name?b->name:"NN"); + if(b->match) + fprintf(f," %s;\n",b->match); }; sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f); if(c) { diff --git a/bgpq_expander.c b/bgpq_expander.c index ecea4c3..7d1db38 100644 --- a/bgpq_expander.c +++ b/bgpq_expander.c @@ -44,6 +44,7 @@ bgpq_expander_init(struct bgpq_expander* b, int af) exit(1); }; memset(b->asn32s[0],0,8192); + b->identify=1; return 1; fixups: diff --git a/configure b/configure index bcb97dd..6c723bf 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.59 for bgpq3 0.1.5. +# Generated by GNU Autoconf 2.59 for bgpq3 0.1.6. # # Report bugs to . # @@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='bgpq3' PACKAGE_TARNAME='bgpq3' -PACKAGE_VERSION='0.1.5' -PACKAGE_STRING='bgpq3 0.1.5' +PACKAGE_VERSION='0.1.6' +PACKAGE_STRING='bgpq3 0.1.6' PACKAGE_BUGREPORT='snar@paranoia.ru' ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LIBOBJS LTLIBOBJS' @@ -738,7 +738,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.5 to adapt to many kinds of systems. +\`configure' configures bgpq3 0.1.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -795,7 +795,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bgpq3 0.1.5:";; + short | recursive ) echo "Configuration of bgpq3 0.1.6:";; esac cat <<\_ACEOF @@ -906,7 +906,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -bgpq3 configure 0.1.5 +bgpq3 configure 0.1.6 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -920,7 +920,7 @@ cat >&5 <<_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.5, which was +It was created by bgpq3 $as_me 0.1.6, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -2909,7 +2909,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by bgpq3 $as_me 0.1.5, which was +This file was extended by bgpq3 $as_me 0.1.6, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2969,7 +2969,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -bgpq3 config.status 0.1.5 +bgpq3 config.status 0.1.6 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.in b/configure.in index cfb2148..fa414fa 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -AC_INIT(bgpq3,0.1.5,snar@paranoia.ru) +AC_INIT(bgpq3,0.1.6,snar@paranoia.ru) AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_INSTALL diff --git a/sx_prefix.c b/sx_prefix.c index c9797cc..2686a58 100644 --- a/sx_prefix.c +++ b/sx_prefix.c @@ -622,10 +622,13 @@ sx_radix_tree_aggregate(struct sx_radix_tree* tree) return 0; }; -static void -setGlue(struct sx_radix_node* node, void* udata) +static void +setGlueUpTo(struct sx_radix_node* node, void* udata) { - if(node) node->isGlue=1; + unsigned refine=(unsigned)udata; + if(node && node->prefix.masklen <= refine) { + node->isGlue=1; + }; }; int @@ -635,12 +638,18 @@ sx_radix_node_refine(struct sx_radix_node* node, unsigned refine) node->isAggregate=1; node->aggregateLow=node->prefix.masklen; node->aggregateHi=refine; - if(node->l) sx_radix_node_foreach(node->l, setGlue, NULL); - if(node->r) sx_radix_node_foreach(node->r, setGlue, NULL); + if(node->l) { + sx_radix_node_foreach(node->l, setGlueUpTo, (void*)refine); + sx_radix_node_refine(node->l, refine); + }; + if(node->r) { + sx_radix_node_foreach(node->r, setGlueUpTo, (void*)refine); + sx_radix_node_refine(node->r, refine); + }; } else if(!node->isGlue && node->prefix.masklen==refine) { /* not setting aggregate in this case */ - if(node->l) sx_radix_node_foreach(node->l, setGlue, NULL); - if(node->r) sx_radix_node_foreach(node->r, setGlue, NULL); + if(node->l) sx_radix_node_refine(node->l, refine); + if(node->r) sx_radix_node_refine(node->r, refine); } else if(node->isGlue) { if(node->r) sx_radix_node_refine(node->r, refine); if(node->l) sx_radix_node_refine(node->l, refine);