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

Merge branch 'sha90w-bgpq3-nokia-support'

This commit is contained in:
Alexandre Snarskii
2017-03-05 20:32:22 +03:00
7 changed files with 214 additions and 23 deletions

View File

@@ -59,7 +59,7 @@ Use asdot notation for Cisco as-path access-lists.
#### -E #### -E
Generate extended access-list (Cisco) or policy-statement term using Generate extended access-list (Cisco) or policy-statement term using
route-filters (Juniper). route-filters (Juniper) or [ip|ipv6]-prefix-list (Nokia)
#### -f `AS number` #### -f `AS number`
@@ -93,6 +93,10 @@ Maximum length of accepted prefixes (default: `32` for IPv4, `128` for IPv6).
Extra match conditions for Juniper route-filters. See the examples section. Extra match conditions for Juniper route-filters. See the examples section.
#### -N
Generate config for Nokia SR OS (former Alcatel-Lucent) (default: Cisco)
#### -l `name` #### -l `name`
`Name` of generated configuration stanza. `Name` of generated configuration stanza.

16
bgpq3.8
View File

@@ -38,7 +38,7 @@
.Fl F Ar fmt | .Fl F Ar fmt |
.Fl G Ar asn .Fl G Ar asn
.Oc .Oc
.Op Fl 2346ABbDdJjsX .Op Fl 2346ABbDdJjNsX
.Op Fl r Ar len .Op Fl r Ar len
.Op Fl R Ar len .Op Fl R Ar len
.Op Fl m Ar max .Op Fl m Ar max
@@ -74,8 +74,8 @@ enable some debugging output.
.It Fl D .It Fl D
use asdot notation for Cisco as-path access-lists. use asdot notation for Cisco as-path access-lists.
.It Fl E .It Fl E
generate extended access-list (Cisco) or policy-statement term using generate extended access-list (Cisco), policy-statement term using
route-filters (Juniper). route-filters (Juniper) or [ip|ipv6]-prefix-list (Nokia).
.It Fl f Ar number .It Fl f Ar number
generate input as-path access-list. generate input as-path access-list.
.It Fl F Ar fmt .It Fl F Ar fmt
@@ -88,15 +88,17 @@ host running IRRD database (default: whois.radb.net).
generate config for Juniper (default: Cisco). generate config for Juniper (default: Cisco).
.It Fl j .It Fl j
generate output in JSON format (default: Cisco). generate output in JSON format (default: Cisco).
.It Fl l Ar name
name of generated entry.
.It Fl L Ar limit
limit recursion depth when expanding as-sets.
.It Fl m Ar len .It Fl m Ar len
maximum prefix-length of accepted prefixes (default: 32 for IPv4 and maximum prefix-length of accepted prefixes (default: 32 for IPv4 and
128 for IPv6). 128 for IPv6).
.It Fl M Ar match .It Fl M Ar match
extra match conditions for Juniper route-filters. extra match conditions for Juniper route-filters.
.It Fl l Ar name .It Fl N
name of generated entry. generate config for Nokia SR OS (Cisco IOS by default).
.It Fl L Ar limit
limit recursion depth when expanding as-sets.
.It Fl p .It Fl p
accept routes registered for private ASNs (default: disabled) accept routes registered for private ASNs (default: disabled)
.It Fl P .It Fl P

34
bgpq3.c
View File

@@ -39,8 +39,9 @@ usage(int ecode)
printf(" -b : generate BIRD output (Cisco IOS by default)\n"); printf(" -b : generate BIRD output (Cisco IOS by default)\n");
printf(" -d : generate some debugging output\n"); printf(" -d : generate some debugging output\n");
printf(" -D : use asdot notation in as-path (Cisco only)\n"); printf(" -D : use asdot notation in as-path (Cisco only)\n");
printf(" -E : generate extended access-list(Cisco) or " printf(" -E : generate extended access-list(Cisco), "
"route-filter(Juniper)\n"); "route-filter(Juniper) or\n"
" [ip|ipv6]-prefix-list (Nokia)\n");
printf(" -f number : generate input as-path access-list\n"); printf(" -f number : generate input as-path access-list\n");
printf(" -F fmt : generate output in user-defined format\n"); printf(" -F fmt : generate output in user-defined format\n");
printf(" -G number : generate output as-path access-list\n"); printf(" -G number : generate output as-path access-list\n");
@@ -55,6 +56,7 @@ usage(int ecode)
printf(" -L depth : limit recursion depth (default: unlimited)\n"), printf(" -L depth : limit recursion depth (default: unlimited)\n"),
printf(" -l name : use specified name for generated access/prefix/.." printf(" -l name : use specified name for generated access/prefix/.."
" list\n"); " list\n");
printf(" -N : generate config for Nokia SR OS (Cisco IOS by default)\n");
printf(" -P : generate prefix-list (default, just for backward" printf(" -P : generate prefix-list (default, just for backward"
" compatibility)\n"); " compatibility)\n");
printf(" -R len : allow more specific routes up to specified masklen\n"); printf(" -R len : allow more specific routes up to specified masklen\n");
@@ -83,7 +85,7 @@ void
vendor_exclusive() vendor_exclusive()
{ {
fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (JunOS), " fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (JunOS), "
"-j (JSON) and -X (IOS XR) options are mutually exclusive\n"); "-j (JSON), -N (NOKIA SR OS) and -X (IOS XR) options are mutually exclusive\n");
exit(1); exit(1);
}; };
@@ -135,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,"2346AbBdDEF:S:jJf:l:L:m:M:W:Ppr:R:G:Th:Xs")) while((c=getopt(argc,argv,"2346AbBdDEF:S:jJf:l:L:m:M:NW:Ppr:R:G:Th:Xs"))
!=EOF) { !=EOF) {
switch(c) { switch(c) {
case '2': case '2':
@@ -284,6 +286,9 @@ main(int argc, char* argv[])
*d=0; *d=0;
}; };
break; break;
case 'N': if(expander.vendor) vendor_exclusive();
expander.vendor=V_NOKIA;
break;
case 'T': pipelining=0; case 'T': pipelining=0;
break; break;
case 's': expander.sequence=1; case 's': expander.sequence=1;
@@ -317,6 +322,8 @@ main(int argc, char* argv[])
expander.aswidth=8; expander.aswidth=8;
} else if(expander.vendor==V_BIRD) { } else if(expander.vendor==V_BIRD) {
expander.aswidth=10; expander.aswidth=10;
} else if(expander.vendor==V_NOKIA) {
expander.aswidth=8;
}; };
} else if(expander.generation==T_OASPATH) { } else if(expander.generation==T_OASPATH) {
if(expander.vendor==V_CISCO) { if(expander.vendor==V_CISCO) {
@@ -325,6 +332,8 @@ main(int argc, char* argv[])
expander.aswidth=7; expander.aswidth=7;
} else if(expander.vendor==V_JUNIPER) { } else if(expander.vendor==V_JUNIPER) {
expander.aswidth=8; expander.aswidth=8;
} else if(expander.vendor==V_NOKIA) {
expander.aswidth=8;
}; };
}; };
}; };
@@ -380,6 +389,12 @@ main(int argc, char* argv[])
exit(1); exit(1);
}; };
if(aggregate && expander.vendor==V_NOKIA) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) is not supported on "
"Nokia equipment (-N)\n");
exit(1);
};
if(aggregate && expander.generation<T_PREFIXLIST) { if(aggregate && expander.generation<T_PREFIXLIST) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) used only for prefix-" sx_report(SX_FATAL, "Sorry, aggregation (-A) used only for prefix-"
"lists, extended access-lists and route-filters\n"); "lists, extended access-lists and route-filters\n");
@@ -436,6 +451,17 @@ main(int argc, char* argv[])
"Use route-filters (-E) instead\n", refineLow); "Use route-filters (-E) instead\n", refineLow);
}; };
}; };
if(expander.vendor==V_NOKIA) {
if(refine) {
sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) "
"not supported on Nokia (-N)\n", refine);
} else {
sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) "
"not supported on Nokia (-N)\n", refineLow);
};
};
if(expander.generation<T_PREFIXLIST) { if(expander.generation<T_PREFIXLIST) {
if(refine) { if(refine) {
sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) " sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) "

View File

@@ -17,7 +17,8 @@ typedef enum {
V_JSON, V_JSON,
V_BIRD, V_BIRD,
V_OPENBGPD, V_OPENBGPD,
V_FORMAT V_FORMAT,
V_NOKIA
} bgpq_vendor_t; } bgpq_vendor_t;
typedef enum { typedef enum {

View File

@@ -323,6 +323,91 @@ bgpq3_print_openbgpd_oaspath(FILE* f, struct bgpq_expander* b)
return 0; return 0;
}; };
int
bgpq3_print_nokia_aspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, lineNo=1, i, j, k;
fprintf(f,"configure router policy-options\nbegin\nno as-path-group \"%s\"\n",
b->name ? b->name : "NN");
fprintf(f,"as-path-group \"%s\"\n", b->name ? b->name : "NN");
if(b->asn32s[b->asnumber/65536] &&
b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]&
(0x80>>(b->asnumber%8))) {
fprintf(f," entry %u expression \"%u+\"\n", lineNo, b->asnumber);
lineNo++;
};
for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) {
for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) {
if(k*65536+i*8+j==b->asnumber) continue;
if(!nc) {
fprintf(f," entry %u expression \"%u.*[%u",
lineNo,b->asnumber,k*65536+i*8+j);
} else {
fprintf(f," %u",k*65536+i*8+j);
};
nc++;
if(nc==b->aswidth) {
fprintf(f,"]\"\n");
nc=0;
lineNo++;
};
};
};
};
};
if(nc) fprintf(f,"]\"\n");
fprintf(f,"exit\ncommit\n");
return 0;
};
int
bgpq3_print_nokia_oaspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, lineNo=1, i, j, k;
fprintf(f,"configure router policy-options\nbegin\nno as-path-group \"%s\"\n",
b->name ? b->name : "NN");
fprintf(f,"as-path-group \"%s\"\n", b->name ? b->name : "NN");
if(b->asn32s[b->asnumber/65536] &&
b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]&
(0x80>>(b->asnumber%8))) {
fprintf(f," entry %u expression \"%u+\"\n", lineNo, b->asnumber);
lineNo++;
};
for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) {
for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) {
if(k*65536+i*8+j==b->asnumber) continue;
if(!nc) {
fprintf(f," entry %u expression \".*[%u",
lineNo,k*65536+i*8+j);
} else {
fprintf(f," %u",k*65536+i*8+j);
}
nc++;
if(nc==b->aswidth) {
fprintf(f,"]\"\n");
nc=0;
lineNo++;
};
};
};
};
};
if(nc) fprintf(f,"]\"\n");
fprintf(f,"exit\ncommit\n");
return 0;
};
int int
bgpq3_print_aspath(FILE* f, struct bgpq_expander* b) bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
{ {
@@ -338,6 +423,8 @@ bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
return bgpq3_print_bird_aspath(f,b); return bgpq3_print_bird_aspath(f,b);
} else if(b->vendor==V_OPENBGPD) { } else if(b->vendor==V_OPENBGPD) {
return bgpq3_print_openbgpd_aspath(f,b); return bgpq3_print_openbgpd_aspath(f,b);
} else if(b->vendor==V_NOKIA) {
return bgpq3_print_nokia_aspath(f,b);
} else { } else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
}; };
@@ -355,6 +442,8 @@ bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b)
return bgpq3_print_cisco_xr_oaspath(f,b); return bgpq3_print_cisco_xr_oaspath(f,b);
} else if(b->vendor==V_OPENBGPD) { } else if(b->vendor==V_OPENBGPD) {
return bgpq3_print_openbgpd_oaspath(f,b); return bgpq3_print_openbgpd_oaspath(f,b);
} else if(b->vendor==V_NOKIA) {
return bgpq3_print_nokia_oaspath(f,b);
} else { } else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
}; };
@@ -689,6 +778,45 @@ checkSon:
bgpq3_print_ceacl(n->son,ff); bgpq3_print_ceacl(n->son,ff);
}; };
void
bgpq3_print_nokia_ipfilter(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_snprintf(&n->prefix,prefix,sizeof(prefix));
fprintf(f," prefix %s\n", prefix);
checkSon:
if(n->son)
bgpq3_print_nokia_ipfilter(n->son, ff);
};
void
bgpq3_print_nokia_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_snprintf(&n->prefix,prefix,sizeof(prefix));
if(!n->isAggregate) {
fprintf(f," prefix %s exact\n", prefix);
} else {
if(n->aggregateLow>n->prefix.masklen) {
fprintf(f," prefix %s prefix-length-range %u-%u\n",
prefix,n->aggregateLow,n->aggregateHi);
} else {
fprintf(f," prefix %s prefix-length-range %u-%u\n",
prefix, n->prefix.masklen, n->aggregateHi);
};
};
checkSon:
if(n->son)
bgpq3_print_nokia_prefix(n->son, ff);
};
int int
bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
@@ -840,6 +968,18 @@ bgpq3_print_format_prefixlist(FILE* f, struct bgpq_expander* b)
return 0; return 0;
}; };
int
bgpq3_print_nokia_prefixlist(FILE* f, struct bgpq_expander* b)
{
bname=b->name ? b->name : "NN";
fprintf(f,"configure router policy-options\nbegin\nno prefix-list \"%s\"\n",
bname);
fprintf(f,"prefix-list \"%s\"\n", bname);
sx_radix_tree_foreach(b->tree,bgpq3_print_nokia_prefix,f);
fprintf(f,"exit\ncommit\n");
return 0;
};
int int
bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b) bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
{ {
@@ -855,6 +995,22 @@ bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
return 0; return 0;
}; };
int
bgpq3_print_nokia_ipprefixlist(FILE* f, struct bgpq_expander* b)
{
bname=b->name ? b->name : "NN";
fprintf(f,"configure filter match-list\nno %s-prefix-list \"%s\"\n",
b->tree->family==AF_INET?"ip":"ipv6", bname);
fprintf(f,"%s-prefix-list \"%s\" create\n", b->tree->family==AF_INET?"ip":"ipv6", bname);
if (!sx_radix_tree_empty(b->tree)) {
sx_radix_tree_foreach(b->tree,bgpq3_print_nokia_ipfilter,f);
} else {
fprintf(f,"# generated ip-prefix-list %s is empty\n", bname);
};
fprintf(f,"exit\n");
return 0;
};
int int
bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
@@ -866,6 +1022,7 @@ bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
case V_BIRD: return bgpq3_print_bird_prefixlist(f,b); case V_BIRD: return bgpq3_print_bird_prefixlist(f,b);
case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b); case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b);
case V_FORMAT: return bgpq3_print_format_prefixlist(f,b); case V_FORMAT: return bgpq3_print_format_prefixlist(f,b);
case V_NOKIA: return bgpq3_print_nokia_prefixlist(f,b);
}; };
return 0; return 0;
}; };
@@ -881,6 +1038,7 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
case V_BIRD: sx_report(SX_FATAL, "unreachable point\n"); case V_BIRD: sx_report(SX_FATAL, "unreachable point\n");
case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b); case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b);
case V_FORMAT: sx_report(SX_FATAL, "unreachable point\n"); case V_FORMAT: sx_report(SX_FATAL, "unreachable point\n");
case V_NOKIA: return bgpq3_print_nokia_ipprefixlist(f,b);
}; };
return 0; return 0;
}; };

18
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for bgpq3 0.1.33. # Generated by GNU Autoconf 2.69 for bgpq3 0.1.34.
# #
# Report bugs to <snar@snar.spb.ru>. # Report bugs to <snar@snar.spb.ru>.
# #
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='bgpq3' PACKAGE_NAME='bgpq3'
PACKAGE_TARNAME='bgpq3' PACKAGE_TARNAME='bgpq3'
PACKAGE_VERSION='0.1.33' PACKAGE_VERSION='0.1.34'
PACKAGE_STRING='bgpq3 0.1.33' PACKAGE_STRING='bgpq3 0.1.34'
PACKAGE_BUGREPORT='snar@snar.spb.ru' PACKAGE_BUGREPORT='snar@snar.spb.ru'
PACKAGE_URL='' PACKAGE_URL=''
@@ -1228,7 +1228,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures bgpq3 0.1.33 to adapt to many kinds of systems. \`configure' configures bgpq3 0.1.34 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1289,7 +1289,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of bgpq3 0.1.33:";; short | recursive ) echo "Configuration of bgpq3 0.1.34:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1369,7 +1369,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
bgpq3 configure 0.1.33 bgpq3 configure 0.1.34
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1738,7 +1738,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by bgpq3 $as_me 0.1.33, which was It was created by bgpq3 $as_me 0.1.34, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@@ -4102,7 +4102,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by bgpq3 $as_me 0.1.33, which was This file was extended by bgpq3 $as_me 0.1.34, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -4164,7 +4164,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
bgpq3 config.status 0.1.33 bgpq3 config.status 0.1.34
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

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