mirror of
https://github.com/bgp/bgpq4
synced 2025-02-28 08:53:11 +00:00
juniper route-filter-lists (junos 16.2+).
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,4 +1,5 @@
|
||||
untagged yet (2017-07-19)
|
||||
untagged yet (2017-09-08)
|
||||
- initial support for Juniper route-filter-lists (JunOS 16.2+).
|
||||
- too large (>124bytes) sources list was not handled correctly.
|
||||
Reported by Pier Carlo Chiodi.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ SYNOPSIS
|
||||
--------
|
||||
|
||||
```
|
||||
bgpq3 [-h host[:port]] [-S sources] [-EP] [-f asn | -F fmt | -G asn] [-2346ABbDdJjpsX] [-a asn] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS
|
||||
bgpq3 [-h host[:port]] [-S sources] [-EPz] [-f asn | -F fmt | -G asn] [-2346ABbDdJjpsX] [-a asn] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS
|
||||
```
|
||||
|
||||
DESCRIPTION
|
||||
@@ -149,6 +149,10 @@ Generate as-path strings of a given length maximum (0 for infinity).
|
||||
|
||||
Generate config for Cisco IOS XR devices (plain IOS by default).
|
||||
|
||||
#### -z
|
||||
|
||||
Generate Juniper route-filter-list (JunOS 16.2+).
|
||||
|
||||
#### `OBJECTS`
|
||||
|
||||
`OBJECTS` means networks (in prefix format), autonomous systems, as-sets and
|
||||
|
||||
4
bgpq3.8
4
bgpq3.8
@@ -32,7 +32,7 @@
|
||||
.Nm
|
||||
.Op Fl h Ar host[:port]
|
||||
.Op Fl S Ar sources
|
||||
.Op Fl EP
|
||||
.Op Fl EPz
|
||||
.Oo
|
||||
.Fl f Ar asn |
|
||||
.Fl F Ar fmt |
|
||||
@@ -120,6 +120,8 @@ disable pipelining.
|
||||
generate as-path strings of no more than len items (use 0 for inifinity).
|
||||
.It Fl X
|
||||
generate config for Cisco IOS XR devices (plain IOS by default).
|
||||
.It Fl z
|
||||
generate route-filter-lists (JunOS 16.2+).
|
||||
.It Ar OBJECTS
|
||||
means networks (in prefix format), autonomous systems, as-sets and route-sets.
|
||||
.It Ar EXCEPT OBJECTS
|
||||
|
||||
25
bgpq3.c
25
bgpq3.c
@@ -137,7 +137,7 @@ main(int argc, char* argv[])
|
||||
if (getenv("IRRD_SOURCES"))
|
||||
expander.sources=getenv("IRRD_SOURCES");
|
||||
|
||||
while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJf:l:L:m:M:NW:Ppr:R:G:Th:Xs"))
|
||||
while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJf:l:L:m:M:NW:Ppr:R:G:Th:Xsz"))
|
||||
!=EOF) {
|
||||
switch(c) {
|
||||
case '2':
|
||||
@@ -308,6 +308,10 @@ main(int argc, char* argv[])
|
||||
case 'X': if(expander.vendor) vendor_exclusive();
|
||||
expander.vendor=V_CISCO_XR;
|
||||
break;
|
||||
case 'z':
|
||||
if(expander.generation) exclusive();
|
||||
expander.generation=T_ROUTE_FILTER_LIST;
|
||||
break;
|
||||
default : usage(1);
|
||||
};
|
||||
};
|
||||
@@ -368,6 +372,10 @@ main(int argc, char* argv[])
|
||||
"compatible with -R/-r options\n");
|
||||
exit(1);
|
||||
};
|
||||
if(expander.generation==T_ROUTE_FILTER_LIST && expander.vendor!=V_JUNIPER) {
|
||||
sx_report(SX_FATAL, "Route-filter-lists (-z) supported for Juniper (-J)"
|
||||
" output only\n");
|
||||
};
|
||||
|
||||
if(expander.asdot && expander.vendor!=V_CISCO) {
|
||||
sx_report(SX_FATAL,"asdot notation supported only for Cisco, "
|
||||
@@ -381,8 +389,9 @@ main(int argc, char* argv[])
|
||||
if(aggregate && expander.vendor==V_JUNIPER &&
|
||||
expander.generation==T_PREFIXLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work in"
|
||||
" Juniper prefix-lists\nYou can try route-filters (-E) instead"
|
||||
" of prefix-lists (-P, default)\n");
|
||||
" Juniper prefix-lists\nYou can try route-filters (-E) "
|
||||
"or route-filter-lists (-z) instead of prefix-lists "
|
||||
"(-P, default)\n");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
@@ -447,11 +456,13 @@ main(int argc, char* argv[])
|
||||
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);
|
||||
"Use router-filters (-E) or route-filter-lists (-z) "
|
||||
"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);
|
||||
"Use route-filters (-E) or route-filter-lists (-z) "
|
||||
"instead\n", refineLow);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -568,7 +579,6 @@ main(int argc, char* argv[])
|
||||
sx_radix_tree_aggregate(expander.tree);
|
||||
|
||||
switch(expander.generation) {
|
||||
default :
|
||||
case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n");
|
||||
exit(1);
|
||||
case T_ASPATH: bgpq3_print_aspath(stdout,&expander);
|
||||
@@ -579,6 +589,9 @@ main(int argc, char* argv[])
|
||||
break;
|
||||
case T_EACL: bgpq3_print_eacl(stdout,&expander);
|
||||
break;
|
||||
case T_ROUTE_FILTER_LIST:
|
||||
bgpq3_print_route_filter_list(stdout, &expander);
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
4
bgpq3.h
4
bgpq3.h
@@ -26,7 +26,8 @@ typedef enum {
|
||||
T_ASPATH,
|
||||
T_OASPATH,
|
||||
T_PREFIXLIST,
|
||||
T_EACL
|
||||
T_EACL,
|
||||
T_ROUTE_FILTER_LIST
|
||||
} bgpq_gen_t;
|
||||
|
||||
struct bgpq_expander;
|
||||
@@ -82,6 +83,7 @@ int bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b);
|
||||
int bgpq3_print_eacl(FILE* f, struct bgpq_expander* b);
|
||||
int bgpq3_print_aspath(FILE* f, struct bgpq_expander* b);
|
||||
int bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b);
|
||||
int bgpq3_print_route_filter_list(FILE* f, struct bgpq_expander* b);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char* dst, const char* src, size_t size);
|
||||
|
||||
@@ -639,6 +639,8 @@ bgpq3_print_openbgpd_aspath(FILE* f, struct bgpq_expander* b)
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int jrfilter_prefixed=1;
|
||||
|
||||
void
|
||||
bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff)
|
||||
{
|
||||
@@ -648,13 +650,17 @@ bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff)
|
||||
if(!f) f=stdout;
|
||||
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
|
||||
if(!n->isAggregate) {
|
||||
fprintf(f," route-filter %s exact;\n", prefix);
|
||||
fprintf(f," %s%s exact;\n",
|
||||
jrfilter_prefixed ? "route-filter " : "", prefix);
|
||||
} else {
|
||||
if(n->aggregateLow>n->prefix.masklen) {
|
||||
fprintf(f," route-filter %s prefix-length-range /%u-/%u;\n",
|
||||
fprintf(f," %s%s prefix-length-range /%u-/%u;\n",
|
||||
jrfilter_prefixed ? "route-filter " : "",
|
||||
prefix,n->aggregateLow,n->aggregateHi);
|
||||
} else {
|
||||
fprintf(f," route-filter %s upto /%u;\n", prefix,n->aggregateHi);
|
||||
fprintf(f," %s%s upto /%u;\n",
|
||||
jrfilter_prefixed ? "route-filter " : "",
|
||||
prefix,n->aggregateHi);
|
||||
};
|
||||
};
|
||||
checkSon:
|
||||
@@ -852,6 +858,7 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b)
|
||||
fprintf(f," %s;\n",b->match);
|
||||
};
|
||||
if(!sx_radix_tree_empty(b->tree)) {
|
||||
jrfilter_prefixed=1;
|
||||
sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f);
|
||||
} else {
|
||||
fprintf(f," route-filter %s/0 orlonger reject;\n",
|
||||
@@ -1057,3 +1064,29 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq3_print_juniper_route_filter_list(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
fprintf(f, "policy-options {\nreplace:\n route-filter-list %s {\n",
|
||||
b->name?b->name:"NN");
|
||||
if (sx_radix_tree_empty(b->tree)) {
|
||||
fprintf(f, " route-filter %s/0 orlonger reject;\n",
|
||||
b->tree->family == AF_INET ? "0.0.0.0" : "::");
|
||||
} else {
|
||||
jrfilter_prefixed=0;
|
||||
sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f);
|
||||
};
|
||||
fprintf(f, " }\n}\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq3_print_route_filter_list(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
switch(b->vendor) {
|
||||
case V_JUNIPER: return bgpq3_print_juniper_route_filter_list(f,b);
|
||||
default: sx_report(SX_FATAL, "unreachable point\n");
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user