From 94d138dada027a0de18079d5e803c5d1723fe8c8 Mon Sep 17 00:00:00 2001 From: Alexandre Snarskii Date: Fri, 14 Oct 2016 18:54:12 +0300 Subject: [PATCH] OpenBGPD support. --- CHANGES | 3 ++ README.md | 6 ++- bgpq3.8 | 4 +- bgpq3.c | 18 ++++++--- bgpq3.h | 1 + bgpq3_printer.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ configure | 18 ++++----- configure.in | 2 +- 8 files changed, 133 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index 1fa2397..4f966a3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +0.1.33 (2016-10-14) + - OpenBGPD support (-B). Submitted by Peter Hessler. + 0.1.32 (2016-08-28) - rollback 0.1.32-rc2 (2015-07-01) change: by default all IRRD sources are allowed by default. Documentation updated to mark radb,ripe,apnic diff --git a/README.md b/README.md index 35b6bcb..aaad635 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ SYNOPSIS -------- ``` - bgpq3 [-h host[:port]] [-S sources] [-EP] [-f asn | -G asn] [-2346AbDdJjpsX] [-F fmt] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS + bgpq3 [-h host[:port]] [-S sources] [-EP] [-f asn | -G asn] [-2346ABbDdJjpsX] [-F fmt] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS ``` DESCRIPTION @@ -36,6 +36,10 @@ Generate IPv6 prefix/access-lists (IPv4 by default). Try to aggregate generated filters as much as possible (not all output formats supported). +#### -B + +Generate output in OpenBGPD format (default: Cisco). + #### -b Generate output in BIRD format (default: Cisco). diff --git a/bgpq3.8 b/bgpq3.8 index b6b7b3c..1613fb5 100644 --- a/bgpq3.8 +++ b/bgpq3.8 @@ -37,7 +37,7 @@ .Fl f Ar asn | .Fl G Ar asn .Oc -.Op Fl 346AbDdJjsX +.Op Fl 346ABbDdJjsX .Op Fl r Ar len .Op Fl R Ar len .Op Fl m Ar max @@ -61,6 +61,8 @@ generate IPv6 prefix/access-lists (IPv4 by default). .It Fl A try to aggregate prefix-lists as much as possible (not all output formats supported). +.It Fl B +generate output in OpenBGPD format (default: Cisco) .It Fl b generate output in BIRD format (default: Cisco). .It Fl d diff --git a/bgpq3.c b/bgpq3.c index a1ef1cd..41d51c6 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -27,7 +27,7 @@ int usage(int ecode) { printf("\nUsage: bgpq3 [-h host[:port]] [-S sources] [-P|E|G |f ]" - " [-2346AbDJjXd] [-R len] ...\n"); + " [-2346ABbDJjXd] [-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"); @@ -35,6 +35,7 @@ usage(int ecode) printf(" -6 : generate IPv6 prefix-lists (IPv4 by default)\n"); printf(" -A : try to aggregate Cisco prefix-lists or Juniper " "route-filters\n as much as possible\n"); + printf(" -B : generate OpenBGPD output (Cisco IOS by default)\n"); printf(" -b : generate BIRD output (Cisco IOS by default)\n"); printf(" -d : generate some debugging output\n"); printf(" -D : use asdot notation in as-path (Cisco only)\n"); @@ -56,11 +57,11 @@ usage(int ecode) " list\n"); printf(" -P : generate prefix-list (default, just for backward" " 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 : generate sequence numbers in prefix-lists (IOS only)\n"); + printf(" -r len : allow more specific routes from masklen specified\n"); printf(" -S sources: use only specified sources (recommended:" " RADB,RIPE,APNIC)\n"); + printf(" -s : generate sequence numbers in prefix-lists (IOS only)\n"); printf(" -T : disable pipelining (experimental, faster mode)\n"); printf(" -W len : specify max-entries on as-path line (use 0 for " "infinity)\n"); @@ -81,8 +82,8 @@ exclusive() void vendor_exclusive() { - fprintf(stderr, "-b (BIRD), -F (formatted), -J (JunOS), -j (JSON) " - "and -X (IOS XR) options are mutually exclusive\n"); + fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (JunOS), " + "-j (JSON) and -X (IOS XR) options are mutually exclusive\n"); exit(1); }; @@ -134,7 +135,7 @@ main(int argc, char* argv[]) if (getenv("IRRD_SOURCES")) expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"2346AbdDEF:S:jJf:l:L:m:M:W:Ppr:R:G:Th:Xs")) + while((c=getopt(argc,argv,"2346AbBdDEF:S:jJf:l:L:m:M:W:Ppr:R:G:Th:Xs")) !=EOF) { switch(c) { case '2': @@ -168,6 +169,11 @@ main(int argc, char* argv[]) if(expander.vendor) vendor_exclusive(); expander.vendor=V_BIRD; break; + case 'B': + if(expander.vendor) vendor_exclusive(); + expander.vendor=V_OPENBGPD; + expander.asn32=1; + break; case 'd': debug_expander++; break; case 'D': expander.asdot=1; diff --git a/bgpq3.h b/bgpq3.h index 3039a3a..9cf143b 100644 --- a/bgpq3.h +++ b/bgpq3.h @@ -16,6 +16,7 @@ typedef enum { V_CISCO_XR, V_JSON, V_BIRD, + V_OPENBGPD, V_FORMAT } bgpq_vendor_t; diff --git a/bgpq3_printer.c b/bgpq3_printer.c index 670e474..9307a0d 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -18,6 +18,7 @@ extern int debug_expander; int bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b); int bgpq3_print_bird_aspath(FILE* f, struct bgpq_expander* b); +int bgpq3_print_openbgpd_aspath(FILE* f, struct bgpq_expander* b); int bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) @@ -303,6 +304,25 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) return 0; }; +int +bgpq3_print_openbgpd_oaspath(FILE* f, struct bgpq_expander* b) +{ + int i, j, k; + + for(k=0;k<65536;k++) { + if(!b->asn32s[k]) continue; + + for(i=0;i<8192;i++) { + for(j=0;j<8;j++) { + if(b->asn32s[k][i]&(0x80>>j)) { + fprintf(f, "%s%u%s%u\n", "allow to AS ", b->asnumber, " AS ", k*65536+i*8+j); + }; + }; + }; + }; + return 0; +}; + int bgpq3_print_aspath(FILE* f, struct bgpq_expander* b) { @@ -316,6 +336,8 @@ bgpq3_print_aspath(FILE* f, struct bgpq_expander* b) return bgpq3_print_json_aspath(f,b); } else if(b->vendor==V_BIRD) { return bgpq3_print_bird_aspath(f,b); + } else if(b->vendor==V_OPENBGPD) { + return bgpq3_print_openbgpd_aspath(f,b); } else { sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); }; @@ -331,6 +353,8 @@ bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b) return bgpq3_print_cisco_oaspath(f,b); } else if(b->vendor==V_CISCO_XR) { return bgpq3_print_cisco_xr_oaspath(f,b); + } else if(b->vendor==V_OPENBGPD) { + return bgpq3_print_openbgpd_oaspath(f,b); } else { sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); }; @@ -471,6 +495,53 @@ bgpq3_print_bird_aspath(FILE* f, struct bgpq_expander* b) return 0; }; +void +bgpq3_print_openbgpd_prefix(struct sx_radix_node* n, void* ff) +{ + char prefix[128]; + FILE* f=(FILE*)ff; + if(n->isGlue) + goto checkSon; + if(!f) + f=stdout; + sx_prefix_snprintf(&n->prefix, prefix, sizeof(prefix)); + if (!n->isAggregate) { + fprintf(f, "\n\t%s \\", prefix); + } else if (n->aggregateLow == n->aggregateHi) { + fprintf(f, "\n\t%s prefixlen = %u \\", + prefix, n->aggregateHi); + } else if (n->aggregateLow > n->prefix.masklen) { + fprintf(f, "\n\t%s prefixlen %u - %u \\", + prefix, n->aggregateLow, n->aggregateHi); + } else { + fprintf(f, "\n\t%s prefixlen %u - %u \\", + prefix, n->prefix.masklen, n->aggregateHi); + }; + needscomma=1; +checkSon: + if(n->son) + bgpq3_print_openbgpd_prefix(n->son, ff); +}; + +int +bgpq3_print_openbgpd_aspath(FILE* f, struct bgpq_expander* b) +{ + int i, j, k; + + for(k=0;k<65536;k++) { + if(!b->asn32s[k]) continue; + + for(i=0;i<8192;i++) { + for(j=0;j<8;j++) { + if(b->asn32s[k][i]&(0x80>>j)) { + fprintf(f, "%s%u%s%u\n", "allow from AS ", b->asnumber, " AS ", k*65536+i*8+j); + }; + }; + }; + }; + return 0; +}; + void bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff) { @@ -658,6 +729,32 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) return 0; }; + +int +bgpq3_print_openbgpd_prefixlist(FILE* f, struct bgpq_expander* b) +{ + if (!sx_radix_tree_empty(b->tree)) { + if(b->name){ + if(strcmp(b->name, "NN") != 0) { + fprintf(f, "%s=\"", b->name); + } + } + fprintf(f,"prefix { \\"); + sx_radix_tree_foreach(b->tree,bgpq3_print_openbgpd_prefix,f); + fprintf(f, "\n\t}"); + if(b->name){ + if(strcmp(b->name, "NN") != 0) { + fprintf(f, "\""); + } + } + fprintf(f, "\n"); + } else { + fprintf(f, "# generated prefix-list %s (AS %u) is empty\n", bname, b->asnumber); + fprintf(f, "deny from AS %u\n", b->asnumber); + }; + return 0; +}; + int bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) { @@ -767,6 +864,7 @@ bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b) case V_CISCO_XR: return bgpq3_print_ciscoxr_prefixlist(f,b); case V_JSON: return bgpq3_print_json_prefixlist(f,b); case V_BIRD: return bgpq3_print_bird_prefixlist(f,b); + case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b); case V_FORMAT: return bgpq3_print_format_prefixlist(f,b); }; return 0; @@ -781,6 +879,7 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b) case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n"); case V_JSON: sx_report(SX_FATAL, "unreachable point\n"); case V_BIRD: sx_report(SX_FATAL, "unreachable point\n"); + case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b); case V_FORMAT: sx_report(SX_FATAL, "unreachable point\n"); }; return 0; diff --git a/configure b/configure index 5e9ea7f..d7c70b3 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.32. +# Generated by GNU Autoconf 2.69 for bgpq3 0.1.33. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bgpq3' PACKAGE_TARNAME='bgpq3' -PACKAGE_VERSION='0.1.32' -PACKAGE_STRING='bgpq3 0.1.32' +PACKAGE_VERSION='0.1.33' +PACKAGE_STRING='bgpq3 0.1.33' PACKAGE_BUGREPORT='snar@snar.spb.ru' PACKAGE_URL='' @@ -1228,7 +1228,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.32 to adapt to many kinds of systems. +\`configure' configures bgpq3 0.1.33 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1289,7 +1289,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bgpq3 0.1.32:";; + short | recursive ) echo "Configuration of bgpq3 0.1.33:";; esac cat <<\_ACEOF @@ -1369,7 +1369,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bgpq3 configure 0.1.32 +bgpq3 configure 0.1.33 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1738,7 +1738,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.32, which was +It was created by bgpq3 $as_me 0.1.33, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4102,7 +4102,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.32, which was +This file was extended by bgpq3 $as_me 0.1.33, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4164,7 +4164,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.32 +bgpq3 config.status 0.1.33 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.in b/configure.in index 81bcecd..014722a 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -AC_INIT(bgpq3,0.1.32,snar@snar.spb.ru) +AC_INIT(bgpq3,0.1.33,snar@snar.spb.ru) AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_INSTALL