From b5f411fa7ca743d8fc90687345a62a033b0bd572 Mon Sep 17 00:00:00 2001 From: Alexandre Snarskii Date: Sun, 28 Jun 2015 19:13:36 +0300 Subject: [PATCH] new flag -s: as-path sequencing for IOS/Arista. --- CHANGES | 12 ++++++++--- README.md | 7 ++++++- bgpq3.c | 15 +++++++++++--- bgpq3.h | 1 + bgpq3_printer.c | 53 ++++++++++++++++++++++++++++++++++--------------- bgpq_expander.c | 2 +- 6 files changed, 66 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 6e54b1e..469f164 100644 --- a/CHANGES +++ b/CHANGES @@ -1,12 +1,18 @@ -untagged yet (2015-06-26) - - bugfix: F source(s) unavailable message from IRRD was ignored +untagged yet (2015-06-28) + - bugfix: F source(s) unavailable message from IRRD was ignored. + Please note: this error is caught only when all the specified sources + are invalid. For example, 'bgpq3 -s nonexistant' will fail, however, + 'bgpq3 -s nonexistant,ripe' will not fail and will use only ripe source. + Thanks to Mikhail A. Grishin for reporting. + - new flag -s for IOS mode enables as-path sequencing. According to Job + Snijders this significantly speeds up Arista configuration load. 0.1.31 (2015-06-23) - pipelining mode now counts buffered requests and issues dequeue when new request can overflow allocated buffer. So, bgpq3 shall no more require TCP tuning (it is still recomended, though). - tcp tuning parameters decreased in README (sx_maxsockbuf will not - allow to grow buffer over 2Mb anyway). + allow buffer over 2Mb anyway). 0.1.30 (2015-06-16) - bugfix: private asns with number > 2^31 were printed as negative integers. diff --git a/README.md b/README.md index 66fc140..55ba6a4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ SYNOPSIS -------- ``` - bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-2346AbDdJjpX] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] + bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-2346AbDdJjpsX] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] ``` DESCRIPTION @@ -104,6 +104,11 @@ Allow more-specific routes with masklen starting with specified length. Allow more-specific routes up to specified masklen too. (Please, note: objects with prefix-length greater than specified length will be always allowed.) +#### -s + +Add sequence numbers to as-path filters (can only be used in combination +with Cisco IOS output). + #### -S `sources` Use specified sources only (default: RADB,RIPE,APNIC). diff --git a/bgpq3.c b/bgpq3.c index b665ef0..955ca43 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -26,7 +26,7 @@ int usage(int ecode) { printf("\nUsage: bgpq3 [-h host] [-S sources] [-P|E|G |f ]" - " [-2346AbDJjXd] [-R len] ...\n"); + " [-2346AbDJjsXd] [-R len] ...\n"); printf(" -2 : allow routes belonging to as23456 (transition-as) " "(default: false)\n"); printf(" -3 : assume that your device is asn32-safe\n"); @@ -54,6 +54,7 @@ usage(int ecode) " compatibility)\n"); printf(" -r len : allow more specific routes from masklen specified\n"); printf(" -R len : allow more specific routes up to specified masklen\n"); + printf(" -s : emit sequence numbers in IOS as-paths\n"); printf(" -S sources: use only specified sources (default:" " RADB,RIPE,APNIC)\n"); printf(" -T : disable pipelining (experimental, faster mode)\n"); @@ -128,7 +129,7 @@ main(int argc, char* argv[]) bgpq_expander_init(&expander,af); expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"2346AbdDES:jJf:l:m:M:W:Ppr:R:G:Th:X"))!=EOF) { + while((c=getopt(argc,argv,"2346AbdDEsS:jJf:l:m:M:W:Ppr:R:G:Th:X"))!=EOF) { switch(c) { case '2': expand_as23456=1; @@ -247,10 +248,12 @@ main(int argc, char* argv[]) break; case 'T': pipelining=0; break; + case 's': expander.ios_asn_sequence=1; + break; case 'S': expander.sources=optarg; break; case 'W': expander.aswidth=atoi(optarg); - if(expander.aswidth<0) { + if(expander.aswidth<=0) { sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg); exit(1); }; @@ -325,6 +328,12 @@ main(int argc, char* argv[]) exit(1); }; + if(expander.ios_asn_sequence && expander.vendor!=V_CISCO) { + sx_report(SX_FATAL, "Sorry, -s (as-path sequencing) works for IOS " + "only\n"); + exit(1); + }; + if(refineLow && !refine) { if(expander.family == AF_INET) refine = 32; diff --git a/bgpq3.h b/bgpq3.h index 596ae8a..a730d57 100644 --- a/bgpq3.h +++ b/bgpq3.h @@ -49,6 +49,7 @@ struct bgpq_expander { unsigned maxlen; int socksize; int qsize; + int ios_asn_sequence; }; diff --git a/bgpq3_printer.c b/bgpq3_printer.c index fc46503..452f20c 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -20,18 +20,23 @@ int bgpq3_print_bird_aspath(FILE* f, struct bgpq_expander* b); int bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k, empty=1; + int nc=0, i, j, k, empty=1, seq=1; + char sseq[16]; 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]& (0x80>>(b->asnumber%8))) { + if(b->ios_asn_sequence) + snprintf(sseq, sizeof(sseq), "seq %i ", seq++); if(b->asdot && b->asnumber>65535) { - fprintf(f,"ip as-path access-list %s permit ^%u.%u(_%u.%u)*$\n", + fprintf(f,"ip as-path access-list %s%s permit ^%u.%u(_%u.%u)*$\n", + b->ios_asn_sequence?sseq:"", 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 ^%u(_%u)*$\n", + fprintf(f,"ip as-path access-list %s%s permit ^%u(_%u)*$\n", + b->ios_asn_sequence?sseq:"", b->name?b->name:"NN",b->asnumber,b->asnumber); empty=0; }; @@ -44,14 +49,20 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; if(!nc) { + if(b->ios_asn_sequence) + snprintf(sseq, sizeof(sseq), "seq %i ", seq++); if(b->asdot && k>0) { - fprintf(f,"ip as-path access-list %s permit" - " ^%u(_[0-9]+)*_(%u.%u", b->name?b->name:"NN", + fprintf(f,"ip as-path access-list %s%s permit" + " ^%u(_[0-9]+)*_(%u.%u", + b->ios_asn_sequence?sseq:"", + b->name?b->name:"NN", b->asnumber,k,i*8+j); empty=0; } else { - fprintf(f,"ip as-path access-list %s permit" - " ^%u(_[0-9]+)*_(%u", b->name?b->name:"NN", + fprintf(f,"ip as-path access-list %s%s permit" + " ^%u(_[0-9]+)*_(%u", + b->ios_asn_sequence?sseq:"", + b->name?b->name:"NN", b->asnumber,k*65536+i*8+j); empty=0; }; @@ -81,17 +92,21 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) int bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k, empty=1; + int nc=0, i, j, k, empty=1, seq=1; + char sseq[16]; 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]& (0x80>>(b->asnumber%8))) { + if(b->ios_asn_sequence) + snprintf(sseq, sizeof(sseq), "seq %i ", seq++); if(b->asdot && b->asnumber>65535) { - fprintf(f,"ip as-path access-list %s permit ^(_%u.%u)*$\n", - b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536); + fprintf(f,"ip as-path access-list %s%s permit ^(_%u.%u)*$\n", + b->ios_asn_sequence?sseq:"",b->name?b->name:"NN", + b->asnumber/65536,b->asnumber%65536); } else { - fprintf(f,"ip as-path access-list %s permit ^(_%u)*$\n", - b->name?b->name:"NN",b->asnumber); + fprintf(f,"ip as-path access-list %s%s permit ^(_%u)*$\n", + b->ios_asn_sequence?sseq:"",b->name?b->name:"NN",b->asnumber); }; empty=0; }; @@ -102,14 +117,20 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; if(!nc) { + if(b->ios_asn_sequence) + snprintf(sseq, sizeof(sseq), "seq %i ", seq++); if(b->asdot && k>0) { - fprintf(f,"ip as-path access-list %s permit" - " ^(_[0-9]+)*_(%u.%u", b->name?b->name:"NN", + fprintf(f,"ip as-path access-list %s%s permit" + " ^(_[0-9]+)*_(%u.%u", + b->ios_asn_sequence?sseq:"", + b->name?b->name:"NN", k,i*8+j); empty=0; } else { - fprintf(f,"ip as-path access-list %s permit" - " ^(_[0-9]+)*_(%u", b->name?b->name:"NN", + fprintf(f,"ip as-path access-list %s%s permit" + " ^(_[0-9]+)*_(%u", + b->ios_asn_sequence?sseq:"", + b->name?b->name:"NN", k*65536+i*8+j); empty=0; }; diff --git a/bgpq_expander.c b/bgpq_expander.c index dcc10a5..5cc78bb 100644 --- a/bgpq_expander.c +++ b/bgpq_expander.c @@ -669,7 +669,7 @@ bgpq_expand(struct bgpq_expander* b) fwrite(sources,strlen(sources),1,f); fgets(sources,sizeof(sources),f); if(sources[0]!='C') { - sx_report(SX_ERROR, "Invalid sources '%s': %s\n", b->sources, + sx_report(SX_ERROR, "Invalid source(s) '%s': %s\n", b->sources, sources); exit(1); };