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

aggregation added.

This commit is contained in:
snar
2008-05-20 13:12:44 +00:00
parent 6ae91f41f2
commit 71e339c35c
6 changed files with 219 additions and 8 deletions

View File

@ -1,3 +1,5 @@
0.1.3 (2008-05-20):
- aggregation (-A) now supported for Cisco prefix-lists.
0.1.2 (2008-05-19):
- final support for asn32, now with correct syntax for Juniper.

22
bgpq3.c
View File

@ -17,15 +17,18 @@
#include "sx_report.h"
extern int debug_expander;
extern int debug_aggregation;
extern int pipelining;
int
usage(int ecode)
{
printf("\nUsage: bgpq3 [-h] [-S sources] [-P|G <number>|f <number>] [-36]"
printf("\nUsage: bgpq3 [-h] [-S sources] [-P|G <number>|f <number>] [-36A]"
" <OBJECTS>...\n");
printf(" -3 : assume that your device is asn32-safe\n");
printf(" -6 : generate IPv6 prefix-lists (IPv4 by default)\n");
printf(" -A : try to aggregate prefix-lists as much as possible"
" (Cisco only)\n");
printf(" -d : generate some debugging output\n");
printf(" -f number : generate input as-path access-list\n");
printf(" -G number : generate output as-path access-list\n");
@ -90,12 +93,12 @@ main(int argc, char* argv[])
int c;
struct bgpq_expander expander;
int af=AF_INET;
int widthSet=0;
int widthSet=0, aggregate=0;
bgpq_expander_init(&expander,af);
expander.sources=getenv("IRRD_SOURCES");
while((c=getopt(argc,argv,"36dhS:Jf:l:W:PG:T"))!=EOF) {
while((c=getopt(argc,argv,"36AdhS:Jf:l:W:PG:T"))!=EOF) {
switch(c) {
case '3':
expander.asn32=1;
@ -104,6 +107,10 @@ main(int argc, char* argv[])
expander.family=AF_INET6;
expander.tree->family=AF_INET6;
break;
case 'A':
if(aggregate) debug_aggregation++;
aggregate=1;
break;
case 'd': debug_expander++;
break;
case 'J': expander.vendor=V_JUNIPER;
@ -172,6 +179,12 @@ main(int argc, char* argv[])
expander.asnumber=23456;
};
if(aggregate && expander.vendor==V_JUNIPER) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work with"
" Juniper\n");
exit(1);
};
if(!argv[0]) usage(1);
while(argv[0]) {
@ -195,6 +208,9 @@ main(int argc, char* argv[])
exit(1);
};
if(aggregate)
sx_radix_tree_aggregate(expander.tree);
switch(expander.generation) {
case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n");
exit(1);

View File

@ -202,11 +202,26 @@ bgpq3_print_cprefix(struct sx_radix_node* n, void* ff)
{
char prefix[128];
FILE* f=(FILE*)ff;
if(n->isGlue) return;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
fprintf(f,"%s prefix-list %s permit %s\n",
(n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",prefix);
if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) {
fprintf(f,"%s prefix-list %s permit %s ge %u le %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix,
n->aggregateLow,n->aggregateHi);
} else {
fprintf(f,"%s prefix-list %s permit %s le %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix,
n->aggregateHi);
};
} else {
fprintf(f,"%s prefix-list %s permit %s\n",
(n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",prefix);
};
checkSon:
if(n->son)
bgpq3_print_cprefix(n->son,ff);
};
int

View File

@ -506,6 +506,7 @@ bgpq_expand(struct bgpq_expander* b)
snprintf(sources,sizeof(sources),"!s%s\n", b->sources);
fseek(f,0,SEEK_END);
fwrite(sources,strlen(sources),1,f);
fgets(sources,sizeof(sources),f);
};
if(b->identify) {
@ -513,6 +514,7 @@ bgpq_expand(struct bgpq_expander* b)
snprintf(ident,sizeof(ident),"!n" PACKAGE_STRING "\n");
fseek(f,0,SEEK_END);
fwrite(ident,strlen(ident),1,f);
fgets(ident,sizeof(ident),f);
};
for(mc=b->macroses;mc;mc=mc->next) {

View File

@ -11,6 +11,8 @@
#include "sx_prefix.h"
#include "sx_report.h"
int debug_aggregation=0;
struct sx_prefix*
sx_prefix_alloc(struct sx_prefix* p)
{
@ -451,6 +453,174 @@ sx_radix_tree_foreach(struct sx_radix_tree* tree,
sx_radix_node_foreach(tree->head,func,udata);
return 0;
};
int
sx_radix_node_aggregate(struct sx_radix_node* node)
{
if(node->l)
sx_radix_node_aggregate(node->l);
if(node->r)
sx_radix_node_aggregate(node->r);
if(debug_aggregation) {
printf("Aggregating on node: ");
sx_prefix_fprint(stdout,&node->prefix);
printf(" %s%s%u,%u\n", node->isGlue?"Glue ":"",
node->isAggregate?"Aggregate ":"",node->aggregateLow,
node->aggregateHi);
if(node->r) {
printf("R-Tree: ");
sx_prefix_fprint(stdout,&node->r->prefix);
printf(" %s%s%u,%u\n", (node->r->isGlue)?"Glue ":"",
(node->r->isAggregate)?"Aggregate ":"",
node->r->aggregateLow,node->r->aggregateHi);
if(node->r->son) {
printf("R-Son: ");
sx_prefix_fprint(stdout,&node->r->son->prefix);
printf(" %s%s%u,%u\n",node->r->son->isGlue?"Glue ":"",
node->r->son->isAggregate?"Aggregate ":"",
node->r->son->aggregateLow,node->r->son->aggregateHi);
};
};
if(node->l) {
printf("L-Tree: ");
sx_prefix_fprint(stdout,&node->l->prefix);
printf(" %s%s%u,%u\n",node->l->isGlue?"Glue ":"",
node->l->isAggregate?"Aggregate ":"",
node->l->aggregateLow,node->l->aggregateHi);
if(node->l->son) {
printf("L-Son: ");
sx_prefix_fprint(stdout,&node->l->son->prefix);
printf(" %s%s%u,%u\n",node->l->son->isGlue?"Glue ":"",
node->l->son->isAggregate?"Aggregate ":"",
node->l->son->aggregateLow,node->l->son->aggregateHi);
};
};
};
if(node->r && node->l) {
if(!node->r->isAggregate && !node->l->isAggregate &&
!node->r->isGlue && !node->l->isGlue &&
node->r->prefix.masklen==node->l->prefix.masklen) {
if(node->r->prefix.masklen==node->prefix.masklen+1) {
node->isAggregate=1;
node->r->isGlue=1;
node->l->isGlue=1;
node->aggregateHi=node->r->prefix.masklen;
if(node->isGlue) {
node->isGlue=0;
node->aggregateLow=node->r->prefix.masklen;
} else {
node->aggregateLow=node->prefix.masklen;
};
};
if(node->r->son && node->l->son &&
node->r->son->isAggregate && node->l->son->isAggregate &&
node->r->son->aggregateHi==node->l->son->aggregateHi &&
node->r->son->aggregateLow==node->l->son->aggregateLow)
{
node->son=sx_radix_node_new(&node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->r->son->aggregateHi;
node->son->aggregateLow=node->r->son->aggregateLow;
node->r->son->isGlue=1;
node->l->son->isGlue=1;
};
} else if(node->r->isAggregate && node->l->isAggregate &&
node->r->aggregateHi==node->l->aggregateHi &&
node->r->aggregateLow==node->l->aggregateLow) {
if(node->r->prefix.masklen==node->prefix.masklen+1) {
if(node->isGlue) {
node->r->isGlue=1;
node->l->isGlue=1;
node->isAggregate=1;
node->isGlue=0;
node->aggregateHi=node->r->aggregateHi;
node->aggregateLow=node->r->aggregateLow;
} else if(node->r->prefix.masklen==node->r->aggregateLow) {
node->r->isGlue=1;
node->l->isGlue=1;
node->isAggregate=1;
node->aggregateHi=node->r->aggregateHi;
node->aggregateLow=node->prefix.masklen;
} else {
node->son=sx_radix_node_new(&node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->r->aggregateHi;
node->son->aggregateLow=node->r->aggregateLow;
node->r->isGlue=1;
node->l->isGlue=1;
if(node->r->son && node->l->son &&
node->r->son->aggregateHi==node->l->son->aggregateHi &&
node->r->son->aggregateLow==node->l->son->aggregateLow)
{
node->son->son=sx_radix_node_new(&node->prefix);
node->son->son->isGlue=0;
node->son->son->isAggregate=1;
node->son->son->aggregateHi=node->r->son->aggregateHi;
node->son->son->aggregateLow=node->r->son->aggregateLow;
node->r->son->isGlue=1;
node->l->son->isGlue=1;
};
};
};
} else if(node->l->son &&
node->r->isAggregate && node->l->son->isAggregate &&
node->r->aggregateHi==node->l->son->aggregateHi &&
node->r->aggregateLow==node->l->son->aggregateLow) {
if(node->r->prefix.masklen==node->prefix.masklen+1) {
if(node->isGlue) {
node->r->isGlue=1;
node->l->son->isGlue=1;
node->isAggregate=1;
node->isGlue=0;
node->aggregateHi=node->r->aggregateHi;
node->aggregateLow=node->r->aggregateLow;
} else {
node->son=sx_radix_node_new(&node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->r->aggregateHi;
node->son->aggregateLow=node->r->aggregateLow;
node->r->isGlue=1;
node->l->son->isGlue=1;
};
};
} else if(node->r->son &&
node->l->isAggregate && node->r->son->isAggregate &&
node->l->aggregateHi==node->r->son->aggregateHi &&
node->l->aggregateLow==node->r->son->aggregateLow) {
if(node->l->prefix.masklen==node->prefix.masklen+1) {
if(node->isGlue) {
node->l->isGlue=1;
node->r->son->isGlue=1;
node->isAggregate=1;
node->isGlue=0;
node->aggregateHi=node->l->aggregateHi;
node->aggregateLow=node->l->aggregateLow;
} else {
node->son=sx_radix_node_new(&node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->l->aggregateHi;
node->son->aggregateLow=node->l->aggregateLow;
node->l->isGlue=1;
node->r->son->isGlue=1;
};
};
};
};
return 0;
};
int
sx_radix_tree_aggregate(struct sx_radix_tree* tree)
{
if(tree && tree->head) return sx_radix_node_aggregate(tree->head);
return 0;
};

View File

@ -17,9 +17,13 @@ typedef struct sx_prefix {
} sx_prefix_t;
typedef struct sx_radix_node {
struct sx_radix_node* parent, *l, *r;
struct sx_radix_node* parent, *l, *r, *son;
void* payload;
int isGlue;
unsigned int isGlue:1;
unsigned int isAggregated:1;
unsigned int isAggregate:1;
unsigned int aggregateLow;
unsigned int aggregateHi;
struct sx_prefix prefix;
} sx_radix_node_t;
@ -52,5 +56,7 @@ int sx_radix_node_foreach(struct sx_radix_node* node,
void (*func)(struct sx_radix_node*, void*), void* udata);
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);
#endif