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.
|
- too large (>124bytes) sources list was not handled correctly.
|
||||||
Reported by Pier Carlo Chiodi.
|
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
|
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).
|
Generate config for Cisco IOS XR devices (plain IOS by default).
|
||||||
|
|
||||||
|
#### -z
|
||||||
|
|
||||||
|
Generate Juniper route-filter-list (JunOS 16.2+).
|
||||||
|
|
||||||
#### `OBJECTS`
|
#### `OBJECTS`
|
||||||
|
|
||||||
`OBJECTS` means networks (in prefix format), autonomous systems, as-sets and
|
`OBJECTS` means networks (in prefix format), autonomous systems, as-sets and
|
||||||
|
|||||||
4
bgpq3.8
4
bgpq3.8
@@ -32,7 +32,7 @@
|
|||||||
.Nm
|
.Nm
|
||||||
.Op Fl h Ar host[:port]
|
.Op Fl h Ar host[:port]
|
||||||
.Op Fl S Ar sources
|
.Op Fl S Ar sources
|
||||||
.Op Fl EP
|
.Op Fl EPz
|
||||||
.Oo
|
.Oo
|
||||||
.Fl f Ar asn |
|
.Fl f Ar asn |
|
||||||
.Fl F Ar fmt |
|
.Fl F Ar fmt |
|
||||||
@@ -120,6 +120,8 @@ disable pipelining.
|
|||||||
generate as-path strings of no more than len items (use 0 for inifinity).
|
generate as-path strings of no more than len items (use 0 for inifinity).
|
||||||
.It Fl X
|
.It Fl X
|
||||||
generate config for Cisco IOS XR devices (plain IOS by default).
|
generate config for Cisco IOS XR devices (plain IOS by default).
|
||||||
|
.It Fl z
|
||||||
|
generate route-filter-lists (JunOS 16.2+).
|
||||||
.It Ar OBJECTS
|
.It Ar OBJECTS
|
||||||
means networks (in prefix format), autonomous systems, as-sets and route-sets.
|
means networks (in prefix format), autonomous systems, as-sets and route-sets.
|
||||||
.It Ar EXCEPT OBJECTS
|
.It Ar EXCEPT OBJECTS
|
||||||
|
|||||||
25
bgpq3.c
25
bgpq3.c
@@ -137,7 +137,7 @@ main(int argc, char* argv[])
|
|||||||
if (getenv("IRRD_SOURCES"))
|
if (getenv("IRRD_SOURCES"))
|
||||||
expander.sources=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) {
|
!=EOF) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case '2':
|
case '2':
|
||||||
@@ -308,6 +308,10 @@ main(int argc, char* argv[])
|
|||||||
case 'X': if(expander.vendor) vendor_exclusive();
|
case 'X': if(expander.vendor) vendor_exclusive();
|
||||||
expander.vendor=V_CISCO_XR;
|
expander.vendor=V_CISCO_XR;
|
||||||
break;
|
break;
|
||||||
|
case 'z':
|
||||||
|
if(expander.generation) exclusive();
|
||||||
|
expander.generation=T_ROUTE_FILTER_LIST;
|
||||||
|
break;
|
||||||
default : usage(1);
|
default : usage(1);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -368,6 +372,10 @@ main(int argc, char* argv[])
|
|||||||
"compatible with -R/-r options\n");
|
"compatible with -R/-r options\n");
|
||||||
exit(1);
|
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) {
|
if(expander.asdot && expander.vendor!=V_CISCO) {
|
||||||
sx_report(SX_FATAL,"asdot notation supported only for 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 &&
|
if(aggregate && expander.vendor==V_JUNIPER &&
|
||||||
expander.generation==T_PREFIXLIST) {
|
expander.generation==T_PREFIXLIST) {
|
||||||
sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work in"
|
sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work in"
|
||||||
" Juniper prefix-lists\nYou can try route-filters (-E) instead"
|
" Juniper prefix-lists\nYou can try route-filters (-E) "
|
||||||
" of prefix-lists (-P, default)\n");
|
"or route-filter-lists (-z) instead of prefix-lists "
|
||||||
|
"(-P, default)\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -447,11 +456,13 @@ main(int argc, char* argv[])
|
|||||||
if(refine) {
|
if(refine) {
|
||||||
sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) "
|
sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) "
|
||||||
"is not supported for Juniper prefix-lists.\n"
|
"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 {
|
} else {
|
||||||
sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) "
|
sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) "
|
||||||
"is not supported for Juniper prefix-lists.\n"
|
"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);
|
sx_radix_tree_aggregate(expander.tree);
|
||||||
|
|
||||||
switch(expander.generation) {
|
switch(expander.generation) {
|
||||||
default :
|
|
||||||
case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n");
|
case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
case T_ASPATH: bgpq3_print_aspath(stdout,&expander);
|
case T_ASPATH: bgpq3_print_aspath(stdout,&expander);
|
||||||
@@ -579,6 +589,9 @@ main(int argc, char* argv[])
|
|||||||
break;
|
break;
|
||||||
case T_EACL: bgpq3_print_eacl(stdout,&expander);
|
case T_EACL: bgpq3_print_eacl(stdout,&expander);
|
||||||
break;
|
break;
|
||||||
|
case T_ROUTE_FILTER_LIST:
|
||||||
|
bgpq3_print_route_filter_list(stdout, &expander);
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
4
bgpq3.h
4
bgpq3.h
@@ -26,7 +26,8 @@ typedef enum {
|
|||||||
T_ASPATH,
|
T_ASPATH,
|
||||||
T_OASPATH,
|
T_OASPATH,
|
||||||
T_PREFIXLIST,
|
T_PREFIXLIST,
|
||||||
T_EACL
|
T_EACL,
|
||||||
|
T_ROUTE_FILTER_LIST
|
||||||
} bgpq_gen_t;
|
} bgpq_gen_t;
|
||||||
|
|
||||||
struct bgpq_expander;
|
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_eacl(FILE* f, struct bgpq_expander* b);
|
||||||
int bgpq3_print_aspath(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_oaspath(FILE* f, struct bgpq_expander* b);
|
||||||
|
int bgpq3_print_route_filter_list(FILE* f, struct bgpq_expander* b);
|
||||||
|
|
||||||
#ifndef HAVE_STRLCPY
|
#ifndef HAVE_STRLCPY
|
||||||
size_t strlcpy(char* dst, const char* src, size_t size);
|
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;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int jrfilter_prefixed=1;
|
||||||
|
|
||||||
void
|
void
|
||||||
bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff)
|
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;
|
if(!f) f=stdout;
|
||||||
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
|
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
|
||||||
if(!n->isAggregate) {
|
if(!n->isAggregate) {
|
||||||
fprintf(f," route-filter %s exact;\n", prefix);
|
fprintf(f," %s%s exact;\n",
|
||||||
|
jrfilter_prefixed ? "route-filter " : "", prefix);
|
||||||
} else {
|
} else {
|
||||||
if(n->aggregateLow>n->prefix.masklen) {
|
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);
|
prefix,n->aggregateLow,n->aggregateHi);
|
||||||
} else {
|
} 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:
|
checkSon:
|
||||||
@@ -852,6 +858,7 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b)
|
|||||||
fprintf(f," %s;\n",b->match);
|
fprintf(f," %s;\n",b->match);
|
||||||
};
|
};
|
||||||
if(!sx_radix_tree_empty(b->tree)) {
|
if(!sx_radix_tree_empty(b->tree)) {
|
||||||
|
jrfilter_prefixed=1;
|
||||||
sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f);
|
sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f);
|
||||||
} else {
|
} else {
|
||||||
fprintf(f," route-filter %s/0 orlonger reject;\n",
|
fprintf(f," route-filter %s/0 orlonger reject;\n",
|
||||||
@@ -1057,3 +1064,29 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
|
|||||||
};
|
};
|
||||||
return 0;
|
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