Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ Use specified sources only (recommended: RADB,RIPE,APNIC).

Disable pipelining. (not recommended)

#### -V

Generate config for Vyatta/VyOS/EdgeOS (default: Cisco)


#### -W `length`

Generate as-path strings of a given length maximum (0 for infinity).
Expand Down
2 changes: 2 additions & 0 deletions bgpq3.8
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ generate sequence numbers in IOS-style prefix-lists.
use specified sources only (recommended: RADB,RIPE,APNIC).
.It Fl T
disable pipelining.
.It Fl N
generate config for Vyatta/Vyos/EdgeOS (Cisco IOS by default).
.It Fl W Ar len
generate as-path strings of no more than len items (use 0 for inifinity).
.It Fl X
Expand Down
14 changes: 12 additions & 2 deletions bgpq3.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ usage(int ecode)
" RADB,RIPE,APNIC)\n");
printf(" -s : generate sequence numbers in prefix-lists (IOS only)\n");
printf(" -T : disable pipelining (experimental, faster mode)\n");
printf(" -V : generate config for Vyatta/VyOS/EdgeOS (Cisco IOS by default)\n");
printf(" -W len : specify max-entries on as-path line (use 0 for "
"infinity)\n");
printf(" -X : generate config for IOS XR (Cisco IOS by default)\n");
Expand All @@ -85,7 +86,7 @@ void
vendor_exclusive()
{
fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (JunOS), "
"-j (JSON), -N (NOKIA SR OS) and -X (IOS XR) options are mutually exclusive\n");
"-j (JSON), -N (NOKIA SR OS), -X (IOS XR) -V (Vyatta) options are mutually exclusive\n");
exit(1);
};

Expand Down Expand Up @@ -137,7 +138,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:Xsz"))
while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJf:l:L:m:M:NVW:Ppr:R:G:Th:Xsz"))
!=EOF) {
switch(c) {
case '2':
Expand Down Expand Up @@ -298,6 +299,9 @@ main(int argc, char* argv[])
break;
case 'S': expander.sources=optarg;
break;
case 'V': if(expander.vendor) vendor_exclusive();
expander.vendor=V_VYATTA;
break;
case 'W': expander.aswidth=atoi(optarg);
if(expander.aswidth<0) {
sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg);
Expand Down Expand Up @@ -407,6 +411,12 @@ main(int argc, char* argv[])
exit(1);
};

if(expander.vendor==V_VYATTA && expander.generation!=T_PREFIXLIST &&
expander.generation!=T_ASPATH && expander.generation!=T_OASPATH) {
sx_report(SX_FATAL, "Sorry, only prefix-sets and as-paths "
"supported for Vyatta output\n");
};

if(aggregate && expander.generation<T_PREFIXLIST) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) used only for prefix-"
"lists, extended access-lists and route-filters\n");
Expand Down
3 changes: 2 additions & 1 deletion bgpq3.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ typedef enum {
V_BIRD,
V_OPENBGPD,
V_FORMAT,
V_NOKIA
V_NOKIA,
V_VYATTA
} bgpq_vendor_t;

typedef enum {
Expand Down
144 changes: 144 additions & 0 deletions bgpq3_printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extern int debug_expander;
int bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b);
int bgpq3_print_bird_aspath(FILE* f, struct bgpq_expander* b);
int bgpq3_print_openbgpd_aspath(FILE* f, struct bgpq_expander* b);
int bgpq3_print_vyatta_aspath(FILE* f, struct bgpq_expander* b);
int bgpq3_print_vyatta_oaspath(FILE* f, struct bgpq_expander* b);

int
bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b)
Expand Down Expand Up @@ -120,6 +122,7 @@ bgpq3_print_cisco_xr_aspath(FILE* f, struct bgpq_expander* b)
fprintf(f,"\nend-set\n");
return 0;
};

int
bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b)
{
Expand Down Expand Up @@ -429,6 +432,8 @@ bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
return bgpq3_print_openbgpd_aspath(f,b);
} else if(b->vendor==V_NOKIA) {
return bgpq3_print_nokia_aspath(f,b);
} else if(b->vendor==V_VYATTA) {
return bgpq3_print_vyatta_aspath(f,b);
} else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
};
Expand All @@ -448,6 +453,8 @@ bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b)
return bgpq3_print_openbgpd_oaspath(f,b);
} else if(b->vendor==V_NOKIA) {
return bgpq3_print_nokia_oaspath(f,b);
} else if(b->vendor==V_VYATTA) {
return bgpq3_print_vyatta_oaspath(f,b);
} else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
};
Expand Down Expand Up @@ -1002,6 +1009,141 @@ bgpq3_print_nokia_prefixlist(FILE* f, struct bgpq_expander* b)
return 0;
};

int
bgpq3_print_vyatta_aspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, lineNo=1, i, j, k;
fprintf(f,"delete policy as-path-list %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,"set policy as-path-list %s rule %u action permit\n",
b->name?b->name:"NN",lineNo);
fprintf(f,"set policy as-path-list %s rule %u regex '^%u(_%u)*$'\n",
b->name?b->name:"NN",lineNo,b->asnumber,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,"set policy as-path-list %s rule %u action permit\n",
b->name?b->name:"NN",lineNo);
fprintf(f,"set policy as-path-list %s rule %u regex '^%u(_[0-9]+)*_(%u",
b->name?b->name:"NN",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");
return 0;
};

int
bgpq3_print_vyatta_oaspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, lineNo=1, i, j, k;
fprintf(f,"delete policy as-path-list %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,"set policy as-path-list %s rule %u action permit\n",
b->name?b->name:"NN",lineNo);
fprintf(f,"set policy as-path-list %s rule %u regex '^(_%u)*$'\n",
b->name?b->name:"NN",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,"set policy as-path-list %s rule %u action permit\n",
b->name?b->name:"NN",lineNo);
fprintf(f,"set policy as-path-list %s rule %u regex '^(_[0-9]+)*_(%u",
b->name?b->name:"NN",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");
return 0;
};

void
bgpq3_print_vprefix(struct sx_radix_node* n, void* ff)
{
char prefix[128];
FILE* f=(FILE*)ff;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
seq++;
if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) {
fprintf(f,"set policy prefix-list%s %s rule %i action permit\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq);
fprintf(f,"set policy prefix-list%s %s rule %i prefix %s\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq,prefix);
fprintf(f,"set policy prefix-list%s %s rule %i ge %u\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq,n->aggregateLow);
fprintf(f,"set policy prefix-list%s %s rule %i le %u\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq,n->aggregateHi);
} else {
fprintf(f,"set policy prefix-list%s %s rule %i action permit\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq);
fprintf(f,"set policy prefix-list%s %s rule %i prefix %s\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq,prefix);
fprintf(f,"set policy prefix-list%s %s rule %i le %u\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq,n->aggregateHi);
};
} else {
fprintf(f,"set policy prefix-list%s %s rule %i action permit\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq);
fprintf(f,"set policy prefix-list%s %s rule %i prefix %s\n",
n->prefix.family==AF_INET6?"6":"",bname?bname:"NN",seq,prefix);
};
checkSon:
if(n->son)
bgpq3_print_vprefix(n->son,ff);
};

int
bgpq3_print_vyatta_prefixlist(FILE* f, struct bgpq_expander* b)
{
bname=b->name ? b->name : "NN";
seq=b->sequence;
fprintf(f,"delete policy prefix-list%s %s\n",
(b->family==AF_INET6)?"6":"",bname);
sx_radix_tree_foreach(b->tree,bgpq3_print_vprefix,f);
return 0;
};

int
bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
{
Expand Down Expand Up @@ -1045,6 +1187,7 @@ bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b);
case V_FORMAT: return bgpq3_print_format_prefixlist(f,b);
case V_NOKIA: return bgpq3_print_nokia_prefixlist(f,b);
case V_VYATTA: return bgpq3_print_vyatta_prefixlist(f,b);
};
return 0;
};
Expand All @@ -1061,6 +1204,7 @@ bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
case V_OPENBGPD: return bgpq3_print_openbgpd_prefixlist(f,b);
case V_FORMAT: sx_report(SX_FATAL, "unreachable point\n");
case V_NOKIA: return bgpq3_print_nokia_ipprefixlist(f,b);
case V_VYATTA: sx_report(SX_FATAL, "unreachable point\n");
};
return 0;
};
Expand Down