1
0
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:
Alexandre Snarskii
2014-05-01 17:53:19 +04:00
parent 89d8643c80
commit 795bc91f23
7 changed files with 173 additions and 76 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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);

View File

@@ -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

View File

@@ -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