1
0
mirror of https://github.com/bgp/bgpq4.git synced 2024-05-11 05:55:05 +00:00

0.1.18, JSON format.

This commit is contained in:
snar
2013-01-08 12:21:14 +00:00
parent c941adf85a
commit e640ac297d
12 changed files with 145 additions and 37 deletions

View File

@@ -1,3 +1,6 @@
0.1.18 (2013-01-08)
- JSON output format. Thanks to Job Snijders (Atrato Networks).
0.1.17 (2012-10-25)
- route-sets handling in command-line added. Thanks to Alexandr Turovsky
for pointing out.

View File

@@ -1,5 +1,5 @@
/*-
* Copyright (c) 2007-2012 Alexandre Snarskii <snar@snar.spb.ru>
* Copyright (c) 2007-2013 Alexandre Snarskii <snar@snar.spb.ru>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

16
bgpq3.8
View File

@@ -21,7 +21,7 @@
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\" "$Id: bgpq3.8,v 1.8 2012/08/29 10:58:20 snar Exp $
.\" "$Id: bgpq3.8,v 1.9 2013/01/08 12:21:14 snar Exp $
.\"
.Dd Oct 27, 2008
.Dt BGPQ3 8
@@ -38,7 +38,7 @@
.Fl f Ar asn |
.Fl G Ar asn
.Oc
.Op Fl 36ADd
.Op Fl 36ADdJjX
.Op Fl R Ar len
.Op Fl m Ar max
.Ar OBJECTS
@@ -56,8 +56,8 @@ assume that your device is asn32-safe.
.It Fl 6
generate IPv6 prefix/access-lists (IPv4 by default).
.It Fl A
try to aggregate prefix-lists as much as possible (Cisco prefix-lists and
Juniper route-filters only supported).
try to aggregate prefix-lists as much as possible (not all output
formats supported).
.It Fl d
enable some debugging output.
.It Fl D
@@ -70,12 +70,14 @@ generate input as-path access-list.
.It Fl G Ar number
generate output as-path access-list.
.It Fl h Ar host
host running IRRD database (default: whois.radb.net)
host running IRRD database (default: whois.radb.net).
.It Fl J
generate config for Juniper (Cisco by default).
generate config for Juniper (default: Cisco).
.It Fl j
generate output in JSON format (default: Cisco).
.It Fl m Ar len
maximum prefix-length of accepted prefixes (default: 32 for IPv4 and
128 for IPv6)
128 for IPv6).
.It Fl M Ar match
extra match conditions for Juniper route-filters.
.It Fl l Ar name

19
bgpq3.c
View File

@@ -24,7 +24,7 @@ int
usage(int ecode)
{
printf("\nUsage: bgpq3 [-h host] [-S sources] [-P|E|G <num>|f <num>]"
" [-36ADJXd] [-R len] <OBJECTS>...\n");
" [-36ADJjXd] [-R len] <OBJECTS>...\n");
printf(" -3 : assume that your device is asn32-safe\n");
printf(" -6 : generate IPv6 prefix-lists (IPv4 by default)\n");
printf(" -A : try to aggregate Cisco prefix-lists or Juniper "
@@ -38,6 +38,7 @@ usage(int ecode)
printf(" -h host : host running IRRD software (whois.radb.net by "
"default)\n");
printf(" -J : generate config for JunOS (Cisco IOS by default)\n");
printf(" -j : generate JSON output (Cisco IOS by default)\n");
printf(" -M match : extra match conditions for JunOS route-filters\n");
printf(" -m len : maximum prefix length (default: 32 for IPv4, "
"128 for IPv6)\n");
@@ -66,8 +67,8 @@ exclusive()
void
vendor_exclusive()
{
fprintf(stderr, "-J (JunOS) and -X (IOS XR) options are mutually "
"exclusive\n");
fprintf(stderr, "-J (JunOS), -j (JSON) and -X (IOS XR) options are mutually"
" exclusive\n");
exit(1);
};
@@ -118,7 +119,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:M:W:PR:G:Th:X"))!=EOF) {
while((c=getopt(argc,argv,"36AdDES:jJf:l:m:M:W:PR:G:Th:X"))!=EOF) {
switch(c) {
case '3':
expander.asn32=1;
@@ -143,6 +144,9 @@ main(int argc, char* argv[])
case 'J': if(expander.vendor) vendor_exclusive();
expander.vendor=V_JUNIPER;
break;
case 'j': if(expander.vendor) vendor_exclusive();
expander.vendor=V_JSON;
break;
case 'f':
if(expander.generation) exclusive();
expander.generation=T_ASPATH;
@@ -251,6 +255,10 @@ main(int argc, char* argv[])
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.vendor==V_JSON && expander.generation!=T_PREFIXLIST) {
sx_report(SX_FATAL, "Sorry, only prefix-lists supported for JSON "
"output\n");
};
if(expander.asdot && expander.vendor!=V_CISCO) {
sx_report(SX_FATAL,"asdot notation supported only for Cisco, Juniper"
@@ -268,6 +276,7 @@ main(int argc, char* argv[])
" of prefix-lists (-P, default)\n");
exit(1);
};
if(aggregate && expander.generation<T_PREFIXLIST) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) used only for prefix-"
"lists, extended access-lists and route-filters\n");
@@ -291,6 +300,7 @@ main(int argc, char* argv[])
"supported only with prefix-list generation\n", refine);
};
};
if(maxlen) {
if((expander.family==AF_INET6 && maxlen>128) ||
(expander.family==AF_INET && maxlen>32)) {
@@ -311,7 +321,6 @@ main(int argc, char* argv[])
" yet.\n");
};
if(!argv[0]) usage(1);
while(argv[0]) {

View File

@@ -7,7 +7,8 @@
typedef enum {
V_CISCO = 0,
V_JUNIPER,
V_CISCO_XR
V_CISCO_XR,
V_JSON
} bgpq_vendor_t;
typedef enum {

View File

@@ -17,7 +17,7 @@ ul { list-style: none; }
<h2>SYNOPSIS</h2>
<pre><code>bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-36ADd] [-R len] [-m max] OBJECTS [...]
<pre><code>bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-36ADdJjX] [-R len] [-m max] OBJECTS [...]
</code></pre>
<h2>DESCRIPTION</h2>
@@ -42,8 +42,8 @@ RADB data.</p>
<li><p>-A </p>
<blockquote>
<p>try to aggregate generated filters as much as possible (Cisco
prefix-lists and Juniper route-filters only supported).</p>
<p>try to aggregate generated filters as much as possible (not all
output formats supported).</p>
</blockquote></li>
<li><p>-d </p>
@@ -74,17 +74,22 @@ RADB data.</p>
<li><p>-h host</p>
<blockquote>
<p>host running IRRD database (default: whois.radb.net)</p>
<p>host running IRRD database (default: whois.radb.net).</p>
</blockquote></li>
<li><p>-J </p>
<blockquote>
<p>generate config for Juniper (Cisco by default).</p>
<p>generate config for Juniper (default: Cisco).</p>
</blockquote></li>
<li><p>-j </p>
<blockquote>
<p>generate output in JSON format (default: Cisco).</p>
</blockquote></li>
<li><p>-m len </p>
<blockquote>
<p>maximum length of accepted prefixes</p>
<p>maximum length of accepted prefixes (default: 32 for IPv4, 128 for IPv6).</p>
</blockquote></li>
<li><p>-M match </p>
@@ -254,6 +259,19 @@ have been added to list if it were not present.</p>
exits with status == 0. In case of errors they are printed to stderr and
program exits with non-zero status.</p>
<h2>NOTES ON ULTRA-LARGE PREFIX-LISTS</h2>
<p>When using <code>bgpq3</code> to expand extra-large AS-SETs, <code>bgpq3</code> may stuck
due to lacking tcp buffer size. To avoid this, tune your OS.
FreeBSD can be tuned in the following way:</p>
<pre><code>sysctl -w net.inet.tcp.sendbuf_max=16777216
</code></pre>
<p>Please note that generated prefix-lists may not fit your router's
limitations. For example, JunOS supports only 85,325 prefixes in
each prefix-list <a href="http://www.juniper.net/techpubs/en_US/junos11.4/topics/reference/configuration-statement/prefix-list-edit-policy-options.html">4</a>. </p>
<h2>SEE ALSO</h2>
<ol>
@@ -262,6 +280,7 @@ program exits with non-zero status.</p>
for information on 'asdot' and 'asplain' notations.</li>
<li><a href="http://www.cisco.com/en/US/prod/collateral/iosswrel/ps6537/ps6554/ps6599/data_sheet_C78-521821.html">Cisco documentation</a>
for information on Cisco implementation of ASN32.</li>
<li><a href="http://www.juniper.net/techpubs/en_US/junos11.4/topics/reference/configuration-statement/prefix-list-edit-policy-options.html">JunOS prefix-lists limitation</a></li>
</ol>
<h2>AUTHOR</h2>

View File

@@ -19,7 +19,7 @@ NAME
SYNOPSIS
--------
bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-36ADd] [-R len] [-m max] OBJECTS [...]
bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-36ADdJjX] [-R len] [-m max] OBJECTS [...]
DESCRIPTION
-----------
@@ -40,8 +40,8 @@ The options are as follows:
- -A
> try to aggregate generated filters as much as possible (Cisco
prefix-lists and Juniper route-filters only supported).
> try to aggregate generated filters as much as possible (not all
output formats supported).
- -d
@@ -66,15 +66,19 @@ The options are as follows:
- -h host
> host running IRRD database (default: whois.radb.net)
> host running IRRD database (default: whois.radb.net).
- -J
> generate config for Juniper (Cisco by default).
> generate config for Juniper (default: Cisco).
- -j
> generate output in JSON format (default: Cisco).
- -m len
> maximum length of accepted prefixes
> maximum length of accepted prefixes (default: 32 for IPv4, 128 for IPv6).
- -M match
@@ -230,6 +234,20 @@ When everything is OK, `bgpq3` generates result to standard output and
exits with status == 0. In case of errors they are printed to stderr and
program exits with non-zero status.
NOTES ON ULTRA-LARGE PREFIX-LISTS
---------------------------------
When using `bgpq3` to expand extra-large AS-SETs, `bgpq3` may stuck
due to lacking tcp buffer size. To avoid this, tune your OS.
FreeBSD can be tuned in the following way:
sysctl -w net.inet.tcp.sendbuf_max=16777216
Please note that generated prefix-lists may not fit your router's
limitations. For example, JunOS supports only 85,325 prefixes in
each prefix-list [4](http://www.juniper.net/techpubs/en_US/junos11.4/topics/reference/configuration-statement/prefix-list-edit-policy-options.html).
SEE ALSO
--------
@@ -238,6 +256,7 @@ SEE ALSO
for information on 'asdot' and 'asplain' notations.
3. [Cisco documentation](http://www.cisco.com/en/US/prod/collateral/iosswrel/ps6537/ps6554/ps6599/data_sheet_C78-521821.html)
for information on Cisco implementation of ASN32.
4. [JunOS prefix-lists limitation](http://www.juniper.net/techpubs/en_US/junos11.4/topics/reference/configuration-statement/prefix-list-edit-policy-options.html)
AUTHOR
------

View File

@@ -239,6 +239,37 @@ bgpq3_print_jprefix(struct sx_radix_node* n, void* ff)
fprintf(f," %s;\n",prefix);
};
static int needscomma=0;
void
bgpq3_print_json_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_jsnprintf(&n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }",
needscomma?",":"", prefix);
} else if (n->aggregateLow > n->prefix.masklen) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false,\n "
"\"greater-equal\": %u, \"less-equal\": %u }",
needscomma?",":"", prefix,
n->aggregateLow, n->aggregateHi);
} else {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false, "
"\"less-equal\": %u }",
needscomma?",":"", prefix, n->aggregateHi);
};
needscomma=1;
checkSon:
if(n->son)
bgpq3_print_json_prefix(n->son, ff);
};
void
bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff)
{
@@ -264,7 +295,6 @@ checkSon:
static char* bname=NULL;
static int needscomma=0;
void
bgpq3_print_cprefix(struct sx_radix_node* n, void* ff)
@@ -439,6 +469,16 @@ bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b)
return 0;
};
int
bgpq3_print_json_prefixlist(FILE* f, struct bgpq_expander* b)
{
fprintf(f,"{ \"%s\": [",
b->name?b->name:"NN");
sx_radix_tree_foreach(b->tree,bgpq3_print_json_prefix,f);
fprintf(f,"\n] }\n");
return 0;
};
int
bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
{
@@ -456,6 +496,7 @@ bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
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);
case V_JSON: return bgpq3_print_json_prefixlist(f,b);
};
return 0;
};
@@ -467,6 +508,7 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
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");
case V_JSON: sx_report(SX_FATAL, "unreachable point\n");
};
return 0;
};

18
configure vendored
View File

@@ -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.17.
# Generated by GNU Autoconf 2.69 for bgpq3 0.1.18.
#
# Report bugs to <snar@snar.spb.ru>.
#
@@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='bgpq3'
PACKAGE_TARNAME='bgpq3'
PACKAGE_VERSION='0.1.17'
PACKAGE_STRING='bgpq3 0.1.17'
PACKAGE_VERSION='0.1.18'
PACKAGE_STRING='bgpq3 0.1.18'
PACKAGE_BUGREPORT='snar@snar.spb.ru'
PACKAGE_URL=''
@@ -1186,7 +1186,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.17 to adapt to many kinds of systems.
\`configure' configures bgpq3 0.1.18 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1247,7 +1247,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of bgpq3 0.1.17:";;
short | recursive ) echo "Configuration of bgpq3 0.1.18:";;
esac
cat <<\_ACEOF
@@ -1326,7 +1326,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
bgpq3 configure 0.1.17
bgpq3 configure 0.1.18
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1494,7 +1494,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.17, which was
It was created by bgpq3 $as_me 0.1.18, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3368,7 +3368,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.17, which was
This file was extended by bgpq3 $as_me 0.1.18, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -3430,7 +3430,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.17
bgpq3 config.status 0.1.18
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT(bgpq3,0.1.17,snar@snar.spb.ru)
AC_INIT(bgpq3,0.1.18,snar@snar.spb.ru)
AC_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_PROG_INSTALL

View File

@@ -151,6 +151,18 @@ sx_prefix_snprintf(struct sx_prefix* p, char* rbuffer, int srb)
return snprintf(rbuffer,srb,"%s/%i",buffer,p->masklen);
};
int
sx_prefix_jsnprintf(struct sx_prefix* p, char* rbuffer, int srb)
{
char buffer[128];
if(!p) {
snprintf(rbuffer,srb,"(null)");
return 0;
};
inet_ntop(p->family,&p->addr,buffer,sizeof(buffer));
return snprintf(rbuffer,srb,"%s\\/%i",buffer,p->masklen);
};
struct sx_radix_tree*
sx_radix_tree_new(int af)
{

View File

@@ -48,6 +48,7 @@ struct sx_prefix* sx_prefix_new(int af, char* text);
int sx_prefix_parse(struct sx_prefix* p, int af, char* text);
int sx_prefix_fprint(FILE* f, struct sx_prefix* p);
int sx_prefix_snprintf(struct sx_prefix* p, char* rbuffer, int srb);
int sx_prefix_jsnprintf(struct sx_prefix* p, char* rbuffer, int srb);
struct sx_radix_tree* sx_radix_tree_new(int af);
struct sx_radix_node* sx_radix_node_new(struct sx_prefix* prefix);
struct sx_prefix* sx_prefix_overlay(struct sx_prefix* p, int n);