diff --git a/CHANGES b/CHANGES index 6c54797..5d88c61 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +0.1.15 (2011-07-15) + - prefix-set's for Cisco IOS XR now supported too. + 0.1.14 (2011-06-18) - Fixed bug in sx_maxsockbuf in rare cases of OS maxsockbuf >2M. Thanks to Andreas Lundin. diff --git a/bgpq3.c b/bgpq3.c index 41e83be..e1fa414 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -47,6 +47,7 @@ usage(int ecode) printf(" -S sources: use only specified sources (default:" " RADB,RIPE,APNIC)\n"); printf(" -T : disable pipelining (experimental, faster mode)\n"); + printf(" -X : generate config for IOS XR (Cisco IOS by default)\n"); printf("\n" PACKAGE_NAME " version: " PACKAGE_VERSION "\n"); printf("Copyright(c) Alexandre Snarskii 2007-2009\n\n"); exit(ecode); @@ -60,6 +61,14 @@ exclusive() exit(1); }; +void +vendor_exclusive() +{ + fprintf(stderr, "-J (JunOS) and -X (IOS XR) options are mutually " + "exclusive\n"); + exit(1); +}; + int parseasnumber(struct bgpq_expander* expander, char* optarg) { @@ -106,7 +115,7 @@ main(int argc, char* argv[]) bgpq_expander_init(&expander,af); expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"36AdDES:Jf:l:M:W:PR:G:Th:"))!=EOF) { + while((c=getopt(argc,argv,"36AdDES:Jf:l:M:W:PR:G:Th:X"))!=EOF) { switch(c) { case '3': expander.asn32=1; @@ -128,7 +137,8 @@ main(int argc, char* argv[]) break; case 'h': expander.server=optarg; break; - case 'J': expander.vendor=V_JUNIPER; + case 'J': if(expander.vendor) vendor_exclusive(); + expander.vendor=V_JUNIPER; break; case 'f': if(expander.generation) exclusive(); @@ -193,6 +203,9 @@ main(int argc, char* argv[]) }; widthSet=1; break; + case 'X': if(expander.vendor) vendor_exclusive(); + expander.vendor=V_CISCO_XR; + break; default : usage(1); }; }; @@ -226,10 +239,13 @@ main(int argc, char* argv[]) sx_report(SX_FATAL,"Sorry, AS32-safety is not yet ready for Cisco\n"); }; */ + if(expander.vendor==V_CISCO_XR && expander.generation!=T_PREFIXLIST) { + sx_report(SX_FATAL, "Sorry, only prefix-sets supported for IOS XR\n"); + }; if(expander.asdot && expander.vendor!=V_CISCO) { sx_report(SX_FATAL,"asdot notation supported only for Cisco, Juniper" - " uses only asplain\n"); + " uses asplain only\n"); }; if(!expander.asn32 && expander.asnumber>65535) { diff --git a/bgpq3.h b/bgpq3.h index 26254e7..7453dd2 100644 --- a/bgpq3.h +++ b/bgpq3.h @@ -6,7 +6,8 @@ typedef enum { V_CISCO = 0, - V_JUNIPER + V_JUNIPER, + V_CISCO_XR } bgpq_vendor_t; typedef enum { diff --git a/bgpq3_printer.c b/bgpq3_printer.c index 133ed37..dcc49d1 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -264,6 +264,7 @@ checkSon: static char* bname=NULL; +static int needscomma=0; void bgpq3_print_cprefix(struct sx_radix_node* n, void* ff) @@ -292,6 +293,31 @@ checkSon: bgpq3_print_cprefix(n->son,ff); }; +void +bgpq3_print_cprefixxr(struct sx_radix_node* n, void* ff) +{ + char prefix[128]; + FILE* f=(FILE*)ff; + if(!f) f=stdout; + if(n->isGlue) goto checkSon; + sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); + if(n->isAggregate) { + if(n->aggregateLow>n->prefix.masklen) { + fprintf(f,"%s%s ge %u le %u", + needscomma?",\n ":" ", prefix, n->aggregateLow,n->aggregateHi); + } else { + fprintf(f,"%s%s le %u", needscomma?",\n ":" ", prefix, + n->aggregateHi); + }; + } else { + fprintf(f,"%s%s", needscomma?",\n ":" ", prefix); + }; + needscomma=1; +checkSon: + if(n->son) + bgpq3_print_cprefixxr(n->son,ff); +}; + void bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) { @@ -402,6 +428,16 @@ bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) return 0; }; +int +bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b) +{ + bname=b->name; + fprintf(f,"prefix-set %s\n", bname?bname:"NN"); + sx_radix_tree_foreach(b->tree,bgpq3_print_cprefixxr,f); + fprintf(f, "\nend-set\n"); + return 0; +}; + int bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b) { @@ -418,6 +454,7 @@ bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b) switch(b->vendor) { case V_JUNIPER: return bgpq3_print_juniper_prefixlist(f,b); case V_CISCO: return bgpq3_print_cisco_prefixlist(f,b); + case V_CISCO_XR: return bgpq3_print_ciscoxr_prefixlist(f,b); }; return 0; }; @@ -428,6 +465,7 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b) switch(b->vendor) { case V_JUNIPER: return bgpq3_print_juniper_routefilter(f,b); case V_CISCO: return bgpq3_print_cisco_eacl(f,b); + case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n"); }; return 0; };