mirror of
https://github.com/bgp/bgpq4.git
synced 2024-05-11 05:55:05 +00:00
1.0.20-pre2: new flag -r <len>, allowing for generation of subset of
more-specific routes. Only more-specific with prefix-length of <len> or more are allowed.
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
||||
0.1.20-todo2 (2014-05-01)
|
||||
- new flag -r <len>, allowing bgpq to generate limited set of more-specific
|
||||
routes - only routes with prefix-length >= <len> are accepted.
|
||||
Thanks to Pavel Gulchouck for suggesion.
|
||||
|
||||
0.1.20-todo (2013-10-07)
|
||||
- socket close code fixed. Thanks to Martin J. Levy.
|
||||
- new flag -4, "force ipv4". Actually does a little more than allowing
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2007-2013 Alexandre Snarskii <snar@snar.spb.ru>
|
||||
* Copyright (c) 2007-2014 Alexandre Snarskii <snar@snar.spb.ru>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
74
README.md
74
README.md
@@ -1,16 +1,3 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.or
|
||||
g/TR/html4/loose.dtd">
|
||||
<html><head><style type='text/css'>
|
||||
h1 { color: #3c78b5; border-bottom: 3px solid #3c78b5; font-size: 180%; }
|
||||
h2 { color: #3c78b5; border-bottom: 2px solid #3c78b5; font-size: 140%; }
|
||||
h3 { color: #3c78b5; border-bottom: 1px dotted #3c78b5; font-size: 129%; }
|
||||
em { color: #0000FF; }
|
||||
code { font-size:12px; background-color:#f8f8ff; border:1px; }
|
||||
pre { border: 1px dotted #3c78b5; background-color: #f8f8ff; margin: 1em 1em;}
|
||||
body { width: 80%; margin: 0 3em; }
|
||||
ul { list-style: none; }
|
||||
</style></head><body>
|
||||
|
||||
NAME
|
||||
----
|
||||
|
||||
@@ -19,7 +6,7 @@ NAME
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-36ADdJjX] [-R len] [-m max] OBJECTS [...]
|
||||
bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-346ADdJjX] [-r len] [-R len] [-m max] OBJECTS [...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -97,6 +84,11 @@ The options are as follows:
|
||||
> generate prefix-list (default behaviour, flag added for backward
|
||||
compatibility only).
|
||||
|
||||
- -r len
|
||||
|
||||
> allow more-specific routes with masklen starting with specified
|
||||
length.
|
||||
|
||||
- -R len
|
||||
|
||||
> allow more-specific routes up to specified masklen too.
|
||||
@@ -115,7 +107,8 @@ The options are as follows:
|
||||
|
||||
> generate config for Cisco IOS XR devices (plain IOS by default).
|
||||
|
||||
`OBJECTS` means networks (in prefix format), autonomous systems and as-macros.
|
||||
`OBJECTS` means networks (in prefix format), autonomous systems, as-sets
|
||||
and route-sets.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
@@ -165,33 +158,34 @@ into single entry
|
||||
ip prefix-list eltel permit 89.112.0.0/18 ge 19 le 19.
|
||||
|
||||
Well, for Juniper we can generate even more interesting policy-statement,
|
||||
using `-M <extra match conditions>`, `-R <len>` and hierarchical names:
|
||||
using `-M <extra match conditions>`, `-r <len>`, `-R <len>` and hierarchical
|
||||
names:
|
||||
|
||||
user@host:~>bgpq3 -AJEl eltel/specifics -R 32 -M "community blackhole" AS20597
|
||||
policy-options {
|
||||
policy-statement eltel {
|
||||
term specifics {
|
||||
replace:
|
||||
from {
|
||||
community blackhole;
|
||||
route-filter 81.9.0.0/20 upto /32;
|
||||
route-filter 81.9.32.0/20 upto /32;
|
||||
route-filter 81.9.96.0/20 upto /32;
|
||||
route-filter 81.222.128.0/20 upto /32;
|
||||
route-filter 81.222.192.0/18 upto /32;
|
||||
route-filter 85.249.8.0/21 upto /32;
|
||||
route-filter 85.249.224.0/19 upto /32;
|
||||
route-filter 89.112.0.0/18 prefix-length-range /19-/32;
|
||||
route-filter 89.112.64.0/19 upto /32;
|
||||
route-filter 217.170.64.0/19 prefix-length-range /20-/32;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
user@host:~>bgpq3 -AJEl eltel/specifics -r 29 -R 32 -M "community blackhole" AS20597
|
||||
policy-options {
|
||||
policy-statement eltel {
|
||||
term specifics {
|
||||
replace:
|
||||
from {
|
||||
community blackhole;
|
||||
route-filter 81.9.0.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.9.32.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.9.96.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.222.128.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.222.192.0/18 prefix-length-range /29-/32;
|
||||
route-filter 85.249.8.0/21 prefix-length-range /29-/32;
|
||||
route-filter 85.249.224.0/19 prefix-length-range /29-/32;
|
||||
route-filter 89.112.0.0/17 prefix-length-range /29-/32;
|
||||
route-filter 217.170.64.0/19 prefix-length-range /29-/32;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generated policy-option term now allows all more-specific routes
|
||||
for eltel networks if they marked with community 'blackhole' (defined
|
||||
elsewhere in configuration).
|
||||
|
||||
generated policy-option term now allows more-specific routes in range
|
||||
/29 - /32 for eltel networks if they marked with community 'blackhole'
|
||||
(defined elsewhere in configuration).
|
||||
|
||||
Of course, `bgpq3` supports IPv6 (-6):
|
||||
|
||||
|
36
bgpq3.8
36
bgpq3.8
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2007-2013 Alexandre Snarskii
|
||||
.\" Copyright (c) 2007-2014 Alexandre Snarskii
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@@ -21,7 +21,6 @@
|
||||
.\" 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.10 2013/10/08 10:50:34 snar Exp $
|
||||
.\"
|
||||
.Dd Oct 27, 2008
|
||||
.Dt BGPQ3 8
|
||||
@@ -39,6 +38,7 @@
|
||||
.Fl G Ar asn
|
||||
.Oc
|
||||
.Op Fl 346ADdJjX
|
||||
.Op Fl r Ar len
|
||||
.Op Fl R Ar len
|
||||
.Op Fl m Ar max
|
||||
.Ar OBJECTS
|
||||
@@ -86,8 +86,10 @@ extra match conditions for Juniper route-filters.
|
||||
name of generated entry.
|
||||
.It Fl P
|
||||
generate prefix-list (default, backward compatibility).
|
||||
.It Fl r Ar len
|
||||
allow more specific routes starting with specified masklen too.
|
||||
.It Fl R Ar len
|
||||
allow specific routes up to specified masklen too.
|
||||
allow more specific routes up to specified masklen too.
|
||||
.It Fl S Ar sources
|
||||
use specified sources only (default: RADB,RIPE,APNIC).
|
||||
.It Fl T
|
||||
@@ -95,7 +97,7 @@ disable pipelining.
|
||||
.It Fl X
|
||||
generate config for Cisco IOS XR devices (plain IOS by default).
|
||||
.It Ar OBJECTS
|
||||
means networks (in prefix format), autonomous systems and as-macros.
|
||||
means networks (in prefix format), autonomous systems, as-sets and route-sets.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
Generating named juniper prefix-filter for AS20597:
|
||||
@@ -149,31 +151,31 @@ Well, for Juniper we can generate even more interesting policy-options,
|
||||
using -M <extra match conditions>, -R <len> and hierarchical names:
|
||||
.nf
|
||||
.RS
|
||||
~>bgpq3 -AJEl eltel/specifics -R 32 -M "community blackhole" AS20597
|
||||
./bgpq3 -AJEl eltel/specifics -r 29 -R 32 -M "community blackhole" AS20597
|
||||
policy-options {
|
||||
policy-statement eltel {
|
||||
term specifics {
|
||||
replace:
|
||||
from {
|
||||
community blackhole;
|
||||
route-filter 81.9.0.0/20 upto /32;
|
||||
route-filter 81.9.32.0/20 upto /32;
|
||||
route-filter 81.9.96.0/20 upto /32;
|
||||
route-filter 81.222.128.0/20 upto /32;
|
||||
route-filter 81.222.192.0/18 upto /32;
|
||||
route-filter 85.249.8.0/21 upto /32;
|
||||
route-filter 85.249.224.0/19 upto /32;
|
||||
route-filter 89.112.0.0/18 prefix-length-range /19-/32;
|
||||
route-filter 89.112.64.0/19 upto /32;
|
||||
route-filter 217.170.64.0/19 prefix-length-range /20-/32;
|
||||
route-filter 81.9.0.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.9.32.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.9.96.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.222.128.0/20 prefix-length-range /29-/32;
|
||||
route-filter 81.222.192.0/18 prefix-length-range /29-/32;
|
||||
route-filter 85.249.8.0/21 prefix-length-range /29-/32;
|
||||
route-filter 85.249.224.0/19 prefix-length-range /29-/32;
|
||||
route-filter 89.112.0.0/17 prefix-length-range /29-/32;
|
||||
route-filter 217.170.64.0/19 prefix-length-range /29-/32;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
generated policy-option term now allows all specifics for eltel networks
|
||||
if they match with special community 'blackhole'.
|
||||
generated policy-option term now allows all specifics with prefix-length
|
||||
between /29 and /32 for eltel networks if they match with special community
|
||||
'blackhole' (defined elsewhere in configuration).
|
||||
.Pp
|
||||
Of course, this version supports IPv6 (-6):
|
||||
.nf
|
||||
|
72
bgpq3.c
72
bgpq3.c
@@ -47,13 +47,14 @@ usage(int ecode)
|
||||
" list\n");
|
||||
printf(" -P : generate prefix-list (default, just for backward"
|
||||
" compatibility)\n");
|
||||
printf(" -R len : allow specific routes up to masklen specified\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 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 <snar@snar.spb.ru> 2007-2013\n\n");
|
||||
printf("Copyright(c) Alexandre Snarskii <snar@snar.spb.ru> 2007-2014\n\n");
|
||||
exit(ecode);
|
||||
};
|
||||
|
||||
@@ -114,13 +115,13 @@ main(int argc, char* argv[])
|
||||
int c;
|
||||
struct bgpq_expander expander;
|
||||
int af=AF_INET, selectedipv4 = 0;
|
||||
int widthSet=0, aggregate=0, refine=0;
|
||||
int widthSet=0, aggregate=0, refine=0, refineLow=0;
|
||||
unsigned long maxlen=0;
|
||||
|
||||
bgpq_expander_init(&expander,af);
|
||||
expander.sources=getenv("IRRD_SOURCES");
|
||||
|
||||
while((c=getopt(argc,argv,"346AdDES:jJf:l:m:M:W:PR:G:Th:X"))!=EOF) {
|
||||
while((c=getopt(argc,argv,"346AdDES:jJf:l:m:M:W:Pr:R:G:Th:X"))!=EOF) {
|
||||
switch(c) {
|
||||
case '3':
|
||||
expander.asn32=1;
|
||||
@@ -175,6 +176,13 @@ main(int argc, char* argv[])
|
||||
if(expander.generation) exclusive();
|
||||
expander.generation=T_PREFIXLIST;
|
||||
break;
|
||||
case 'r':
|
||||
refineLow=strtoul(optarg,NULL,10);
|
||||
if(!refineLow) {
|
||||
sx_report(SX_FATAL,"Invalid refineLow value: %s\n", optarg);
|
||||
exit(1);
|
||||
};
|
||||
break;
|
||||
case 'R':
|
||||
refine=strtoul(optarg,NULL,10);
|
||||
if(!refine) {
|
||||
@@ -260,12 +268,6 @@ main(int argc, char* argv[])
|
||||
expander.generation=T_PREFIXLIST;
|
||||
};
|
||||
|
||||
/*
|
||||
if(expander.vendor==V_CISCO && expander.asn32 &&
|
||||
expander.generation<T_PREFIXLIST) {
|
||||
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");
|
||||
};
|
||||
@@ -297,21 +299,52 @@ main(int argc, char* argv[])
|
||||
exit(1);
|
||||
};
|
||||
|
||||
if(refine) {
|
||||
if(expander.family==AF_INET6 && (refine>128)) {
|
||||
sx_report(SX_FATAL, "Invalid value for refinement: %u (1-128 for"
|
||||
if(refineLow && !refine) {
|
||||
if(expander.family == AF_INET)
|
||||
refine = 32;
|
||||
else
|
||||
refine = 128;
|
||||
};
|
||||
|
||||
if (refineLow && refineLow > refine) {
|
||||
sx_report(SX_FATAL, "Incompatible values for -r %u and -R %u\n",
|
||||
refineLow, refine);
|
||||
};
|
||||
|
||||
if(refine || refineLow) {
|
||||
if(expander.family==AF_INET6 && refine>128) {
|
||||
sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-128 for"
|
||||
" IPv6)\n", refine);
|
||||
} else if(expander.family==AF_INET6 && refineLow>128) {
|
||||
sx_report(SX_FATAL, "Invalid value for refineLow(-r): %u (1-128 for"
|
||||
" IPv6)\n", refineLow);
|
||||
} else if(expander.family==AF_INET && refine>32) {
|
||||
sx_report(SX_FATAL, "Invalid value for refinement: %u (1-32 for"
|
||||
sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-32 for"
|
||||
" IPv4)\n", refine);
|
||||
} else if(expander.family==AF_INET && refineLow>32) {
|
||||
sx_report(SX_FATAL, "Invalid value for refineLow(-r): %u (1-32 for"
|
||||
" IPv4)\n", refineLow);
|
||||
};
|
||||
|
||||
if(expander.vendor==V_JUNIPER && expander.generation==T_PREFIXLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) "
|
||||
"is not supported for Juniper prefix-lists\n", refine);
|
||||
if(refine) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) "
|
||||
"is not supported for Juniper prefix-lists.\n"
|
||||
"Use router-filters (-E) instead\n", refine);
|
||||
} else {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) "
|
||||
"is not supported for Juniper prefix-lists.\n"
|
||||
"Use route-filters (-E) instead\n", refineLow);
|
||||
};
|
||||
};
|
||||
if(expander.generation<T_PREFIXLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) "
|
||||
"supported only with prefix-list generation\n", refine);
|
||||
if(refine) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) "
|
||||
"supported only with prefix-list generation\n", refine);
|
||||
} else {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filter (-r %u) "
|
||||
"supported only with prefix-list generation\n", refineLow);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -371,6 +404,9 @@ main(int argc, char* argv[])
|
||||
if(refine)
|
||||
sx_radix_tree_refine(expander.tree,refine);
|
||||
|
||||
if(refineLow)
|
||||
sx_radix_tree_refineLow(expander.tree, refineLow);
|
||||
|
||||
if(aggregate)
|
||||
sx_radix_tree_aggregate(expander.tree);
|
||||
|
||||
|
59
sx_prefix.c
59
sx_prefix.c
@@ -695,8 +695,67 @@ sx_radix_tree_refine(struct sx_radix_tree* tree, unsigned refine)
|
||||
if(tree && tree->head) return sx_radix_node_refine(tree->head, refine);
|
||||
return 0;
|
||||
};
|
||||
|
||||
static void
|
||||
setGlueFrom(struct sx_radix_node* node, void* udata)
|
||||
{
|
||||
unsigned refine=*(unsigned*)udata;
|
||||
if(node && node->prefix.masklen <= refine) {
|
||||
node->isGlue=1;
|
||||
};
|
||||
};
|
||||
|
||||
static int
|
||||
sx_radix_node_refineLow(struct sx_radix_node* node, unsigned refineLow)
|
||||
{
|
||||
if(!node->isGlue && node->prefix.masklen<=refineLow) {
|
||||
if(!node->isAggregate) {
|
||||
node->isAggregate=1;
|
||||
node->aggregateLow=refineLow;
|
||||
if(node->prefix.family == AF_INET) {
|
||||
node->aggregateHi=32;
|
||||
} else {
|
||||
node->aggregateHi=128;
|
||||
}
|
||||
} else {
|
||||
node->aggregateLow=refineLow;
|
||||
};
|
||||
if(node->l) {
|
||||
sx_radix_node_foreach(node->l, setGlueFrom, &refineLow);
|
||||
sx_radix_node_refineLow(node->l, refineLow);
|
||||
};
|
||||
if(node->r) {
|
||||
sx_radix_node_foreach(node->r, setGlueFrom, &refineLow);
|
||||
sx_radix_node_refineLow(node->r, refineLow);
|
||||
};
|
||||
} else if(!node->isGlue && node->prefix.masklen==refineLow) {
|
||||
/* not setting aggregate in this case */
|
||||
if(node->l) sx_radix_node_refineLow(node->l, refineLow);
|
||||
if(node->r) sx_radix_node_refineLow(node->r, refineLow);
|
||||
} else if(node->isGlue) {
|
||||
if(node->r) sx_radix_node_refineLow(node->r, refineLow);
|
||||
if(node->l) sx_radix_node_refineLow(node->l, refineLow);
|
||||
} else {
|
||||
/* node->prefix.masklen > refine */
|
||||
/* do nothing, should pass specifics 'as is'. Also, do not
|
||||
process any embedded routes, their masklen is bigger, too...
|
||||
node->isGlue=1;
|
||||
if(node->l) sx_radix_node_foreach(node->l, setGlue, NULL);
|
||||
if(node->r) sx_radix_node_foreach(node->r, setGlue, NULL);
|
||||
*/
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
sx_radix_tree_refineLow(struct sx_radix_tree* tree, unsigned refineLow)
|
||||
{
|
||||
if(tree && tree->head)
|
||||
return sx_radix_node_refineLow(tree->head, refineLow);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
#if SX_PTREE_TEST
|
||||
int
|
||||
|
@@ -59,6 +59,7 @@ int sx_radix_tree_foreach(struct sx_radix_tree* tree,
|
||||
void (*func)(struct sx_radix_node*, void*), void* udata);
|
||||
int sx_radix_tree_aggregate(struct sx_radix_tree* tree);
|
||||
int sx_radix_tree_refine(struct sx_radix_tree* tree, unsigned refine);
|
||||
int sx_radix_tree_refineLow(struct sx_radix_tree* tree, unsigned refineLow);
|
||||
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user