diff --git a/CHANGES b/CHANGES index 7cfe37d..547e0b8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,10 +1,12 @@ -untagged yet (2018-08-10) +untagged yet (2018-09-05) - initial support for Juniper route-filter-lists (JunOS 16.2+). - too large (>124bytes) sources list was not handled correctly. Reported by Pier Carlo Chiodi. - initial support for Huawei format (prefix-lists and as-path filters) New flag -U. Requested by Alexander Wagberg. - fix ipv6 prefix-ranges. Reported by Jay Ford. + - OpenBGPd change: -E now generates prefix-set instead of prefix-list. + Based on submission by Denis Fondras 0.1.35-rc2 (2017-06-14) - OpenBSD need . Reported by Denis Fondras. diff --git a/README.md b/README.md index 7cc55dc..13609e0 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ Use asdot notation for Cisco as-path access-lists. #### -E Generate extended access-list (Cisco) or policy-statement term using -route-filters (Juniper) or [ip|ipv6]-prefix-list (Nokia) +route-filters (Juniper), [ip|ipv6]-prefix-list (Nokia) or prefix-filter +(OpenBGPD) #### -f `AS number` diff --git a/bgpq3.8 b/bgpq3.8 index a9d7aa2..0de5075 100644 --- a/bgpq3.8 +++ b/bgpq3.8 @@ -78,7 +78,8 @@ enable some debugging output. use asdot notation for Cisco as-path access-lists. .It Fl E generate extended access-list (Cisco), policy-statement term using -route-filters (Juniper) or [ip|ipv6]-prefix-list (Nokia). +route-filters (Juniper), [ip|ipv6]-prefix-list (Nokia) or prefix-sets +(OpenBGPd). .It Fl f Ar number generate input as-path access-list. .It Fl F Ar fmt diff --git a/bgpq3.c b/bgpq3.c index c3abf1a..5098b51 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -40,8 +40,9 @@ usage(int ecode) printf(" -D : use asdot notation in as-path (Cisco only)\n"); printf(" -d : generate some debugging output\n"); printf(" -E : generate extended access-list(Cisco), " - "route-filter(Juniper) or\n" - " [ip|ipv6]-prefix-list (Nokia)\n"); + "route-filter(Juniper)\n" + " [ip|ipv6]-prefix-list (Nokia) or prefix-set (OpenBGPD)" + "\n"); printf(" -F fmt : generate output in user-defined format\n"); printf(" -f number : generate input as-path access-list\n"); printf(" -G number : generate output as-path access-list\n"); diff --git a/bgpq3_printer.c b/bgpq3_printer.c index 553e673..7346f8f 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -558,6 +558,7 @@ bgpq3_print_jprefix(struct sx_radix_node* n, void* ff) }; static int needscomma=0; +static int prefixset=0; void bgpq3_print_json_prefix(struct sx_radix_node* n, void* ff) @@ -684,6 +685,7 @@ void bgpq3_print_openbgpd_prefix(struct sx_radix_node* n, void* ff) { char prefix[128]; + int pc = needscomma & prefixset; FILE* f=(FILE*)ff; if(n->isGlue) goto checkSon; @@ -691,16 +693,16 @@ bgpq3_print_openbgpd_prefix(struct sx_radix_node* n, void* ff) f=stdout; sx_prefix_snprintf(&n->prefix, prefix, sizeof(prefix)); if (!n->isAggregate) { - fprintf(f, "\n\t%s \\", prefix); + fprintf(f, "%s\n\t%s", pc ? "," : " \\", prefix); } else if (n->aggregateLow == n->aggregateHi) { - fprintf(f, "\n\t%s prefixlen = %u \\", - prefix, n->aggregateHi); + fprintf(f, "%s\n\t%s prefixlen = %u", + pc ? "," : " \\", prefix, n->aggregateHi); } else if (n->aggregateLow > n->prefix.masklen) { - fprintf(f, "\n\t%s prefixlen %u - %u \\", - prefix, n->aggregateLow, n->aggregateHi); + fprintf(f, "%s\n\t%s prefixlen %u - %u", + pc ? "," : " \\", prefix, n->aggregateLow, n->aggregateHi); } else { - fprintf(f, "\n\t%s prefixlen %u - %u \\", - prefix, n->prefix.masklen, n->aggregateHi); + fprintf(f, "%s\n\t%s prefixlen %u - %u", + pc ? "," : " \\", prefix, n->prefix.masklen, n->aggregateHi); }; needscomma=1; checkSon: @@ -994,7 +996,6 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) return 0; }; - int bgpq3_print_openbgpd_prefixlist(FILE* f, struct bgpq_expander* b) { @@ -1012,9 +1013,9 @@ bgpq3_print_openbgpd_prefixlist(FILE* f, struct bgpq_expander* b) fprintf(f, "%s=\"", b->name); } } - fprintf(f,"prefix { \\"); + fprintf(f,"prefix {"); sx_radix_tree_foreach(b->tree,bgpq3_print_openbgpd_prefix,f); - fprintf(f, "\n\t}"); + fprintf(f, " \\\n\t}"); if(b->name){ if(strcmp(b->name, "NN") != 0) { fprintf(f, "\""); @@ -1027,6 +1028,29 @@ bgpq3_print_openbgpd_prefixlist(FILE* f, struct bgpq_expander* b) return 0; }; +int +bgpq3_print_openbgpd_prefixset(FILE* f, struct bgpq_expander* b) +{ + bname=b->name ? b->name : "NN"; + if (sx_radix_tree_empty(b->tree)) { + fprintf(f, "# generated prefix-set %s (AS %u) is empty\n", bname, + b->asnumber); + if (!b->asnumber) + fprintf(f, "# use -a to generate \"deny from ASN \" " + "instead of this list\n"); + }; + if (!sx_radix_tree_empty(b->tree) || !b->asnumber) { + fprintf(f,"prefix-set %s { ", b->name); + prefixset=1; + sx_radix_tree_foreach(b->tree,bgpq3_print_openbgpd_prefix,f); + fprintf(f, "\n\t}\n"); + } else { + fprintf(f, "deny from AS %u\n", b->asnumber); + }; + return 0; +}; + + int bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) { @@ -1199,7 +1223,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_OPENBGPD: return bgpq3_print_openbgpd_prefixset(f,b); case V_FORMAT: sx_report(SX_FATAL, "unreachable point\n"); case V_NOKIA: return bgpq3_print_nokia_ipprefixlist(f,b); case V_HUAWEI: return sx_report(SX_FATAL, "unreachable point\n");