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

Fix memory leaks

This commit is contained in:
Peter Schoenmaker
2018-12-10 05:26:33 -06:00
committed by Job Snijders
parent 858c6f99b2
commit 03e3b11d95
7 changed files with 244 additions and 125 deletions

View File

@@ -16,6 +16,7 @@
#include "bgpq4.h"
#include "sx_report.h"
#include "expander_freeall.h"
extern int debug_expander;
extern int debug_aggregation;
@@ -637,6 +638,8 @@ main(int argc, char* argv[])
break;
};
expander_freeall(&expander);
return 0;
};

View File

@@ -626,7 +626,7 @@ bgpq4_print_jprefix(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(n->isGlue) return;
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
fprintf(f," %s;\n",prefix);
};
@@ -641,11 +641,11 @@ bgpq4_print_json_prefix(struct sx_radix_node* n, void* ff)
goto checkSon;
if(!f)
f=stdout;
sx_prefix_jsnprintf(&n->prefix, prefix, sizeof(prefix));
sx_prefix_jsnprintf(n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }",
needscomma?",":"", prefix);
} else if (n->aggregateLow > n->prefix.masklen) {
} else if (n->aggregateLow > n->prefix->masklen) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false,\n "
"\"greater-equal\": %u, \"less-equal\": %u }",
needscomma?",":"", prefix,
@@ -701,16 +701,16 @@ bgpq4_print_bird_prefix(struct sx_radix_node* n, void* ff)
goto checkSon;
if(!f)
f=stdout;
sx_prefix_snprintf(&n->prefix, prefix, sizeof(prefix));
sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) {
fprintf(f, "%s\n %s",
needscomma?",":"", prefix);
} else if (n->aggregateLow > n->prefix.masklen) {
} else if (n->aggregateLow > n->prefix->masklen) {
fprintf(f, "%s\n %s{%u,%u}",
needscomma?",":"", prefix, n->aggregateLow, n->aggregateHi);
} else {
fprintf(f, "%s\n %s{%u,%u}",
needscomma?",":"", prefix, n->prefix.masklen, n->aggregateHi);
needscomma?",":"", prefix, n->prefix->masklen, n->aggregateHi);
};
needscomma=1;
checkSon:
@@ -762,17 +762,17 @@ bgpq4_print_openbgpd_prefix(struct sx_radix_node* n, void* ff)
goto checkSon;
if(!f)
f=stdout;
sx_prefix_snprintf(&n->prefix, prefix, sizeof(prefix));
sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) {
fprintf(f, "\n\t%s", prefix);
} else if (n->aggregateLow == n->aggregateHi) {
fprintf(f, "\n\t%s prefixlen = %u", prefix, n->aggregateHi);
} else if (n->aggregateLow > n->prefix.masklen) {
} else if (n->aggregateLow > n->prefix->masklen) {
fprintf(f, "\n\t%s prefixlen %u - %u",
prefix, n->aggregateLow, n->aggregateHi);
} else {
fprintf(f, "\n\t%s prefixlen %u - %u",
prefix, n->prefix.masklen, n->aggregateHi);
prefix, n->prefix->masklen, n->aggregateHi);
};
checkSon:
if(n->son)
@@ -836,12 +836,12 @@ bgpq4_print_jrfilter(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(n->isGlue) goto checkSon;
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
if(!n->isAggregate) {
fprintf(f," %s%s exact;\n",
jrfilter_prefixed ? "route-filter " : "", prefix);
} else {
if(n->aggregateLow>n->prefix.masklen) {
if(n->aggregateLow>n->prefix->masklen) {
fprintf(f," %s%s prefix-length-range /%u-/%u;\n",
jrfilter_prefixed ? "route-filter " : "",
prefix,n->aggregateLow,n->aggregateHi);
@@ -867,22 +867,22 @@ bgpq4_print_cprefix(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
if(seq)
snprintf(seqno, sizeof(seqno), " seq %i", seq++);
if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) {
if(n->aggregateLow>n->prefix->masklen) {
fprintf(f,"%s prefix-list %s%s permit %s ge %u le %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",seqno,
n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN",seqno,
prefix,n->aggregateLow,n->aggregateHi);
} else {
fprintf(f,"%s prefix-list %s%s permit %s le %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",seqno,
n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN",seqno,
prefix,n->aggregateHi);
};
} else {
fprintf(f,"%s prefix-list %s%s permit %s\n",
(n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",seqno,
(n->prefix->family==AF_INET)?"ip":"ipv6",bname?bname:"NN",seqno,
prefix);
};
checkSon:
@@ -897,9 +897,9 @@ bgpq4_print_cprefixxr(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) {
if(n->aggregateLow>n->prefix->masklen) {
fprintf(f,"%s%s ge %u le %u",
needscomma?",\n ":" ", prefix, n->aggregateLow,n->aggregateHi);
} else {
@@ -922,21 +922,21 @@ bgpq4_print_hprefix(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf_sep(&n->prefix,prefix,sizeof(prefix)," ");
sx_prefix_snprintf_sep(n->prefix,prefix,sizeof(prefix)," ");
if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) {
if(n->aggregateLow>n->prefix->masklen) {
fprintf(f,"ip %s-prefix %s permit %s greater-equal %u "
"less-equal %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",
n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN",
prefix,n->aggregateLow,n->aggregateHi);
} else {
fprintf(f,"ip %s-prefix %s permit %s less-equal %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",
n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN",
prefix,n->aggregateHi);
};
} else {
fprintf(f,"ip %s-prefix %s permit %s\n",
(n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",
(n->prefix->family==AF_INET)?"ip":"ipv6",bname?bname:"NN",
prefix);
};
checkSon:
@@ -954,14 +954,14 @@ bgpq4_print_ceacl(struct sx_radix_node* n, void* ff)
uint32_t netmask=0xfffffffful;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
c=strchr(prefix,'/');
if(c) *c=0;
if(n->prefix.masklen==32) {
if(n->prefix->masklen==32) {
netmask=0;
} else {
netmask<<=(32-n->prefix.masklen);
netmask<<=(32-n->prefix->masklen);
netmask&=0xfffffffful;
};
netmask=htonl(netmask);
@@ -969,7 +969,7 @@ bgpq4_print_ceacl(struct sx_radix_node* n, void* ff)
if(n->isAggregate) {
unsigned long mask=0xfffffffful, wildaddr, wild2addr, wildmask;
int masklen=n->aggregateLow;
wildaddr=0xfffffffful>>n->prefix.masklen;
wildaddr=0xfffffffful>>n->prefix->masklen;
if(n->aggregateHi==32) {
wild2addr=0;
} else {
@@ -989,10 +989,10 @@ bgpq4_print_ceacl(struct sx_radix_node* n, void* ff)
wildmask=htonl(wildmask);
if(wildaddr) {
fprintf(f," permit ip %s ", inet_ntoa(n->prefix.addr.addr));
fprintf(f," permit ip %s ", inet_ntoa(n->prefix->addr.addr));
fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&wildaddr));
} else {
fprintf(f," permit ip host %s ",inet_ntoa(n->prefix.addr.addr));
fprintf(f," permit ip host %s ",inet_ntoa(n->prefix->addr.addr));
};
if(wildmask) {
@@ -1017,7 +1017,7 @@ bgpq4_print_nokia_ipfilter(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(n->isGlue) goto checkSon;
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
fprintf(f," prefix %s\n", prefix);
checkSon:
if(n->son)
@@ -1031,7 +1031,7 @@ bgpq4_print_nokia_md_ipfilter(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(n->isGlue) goto checkSon;
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
fprintf(f," prefix %s { }\n", prefix);
checkSon:
if(n->son)
@@ -1045,16 +1045,16 @@ bgpq4_print_nokia_prefix(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(n->isGlue) goto checkSon;
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
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) {
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);
prefix, n->prefix->masklen, n->aggregateHi);
};
};
checkSon:
@@ -1070,11 +1070,11 @@ bgpq4_print_nokia_md_prefix(struct sx_radix_node* n, void* ff)
FILE* f=(FILE*)ff;
if(n->isGlue) goto checkSon;
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix));
if(!n->isAggregate) {
fprintf(f," prefix %s type exact {\n }\n", prefix);
} else {
if(n->aggregateLow>n->prefix.masklen) {
if(n->aggregateLow>n->prefix->masklen) {
fprintf(f," prefix %s type range {\n start-length %u\n"
" end-length %u\n }\n",
prefix,n->aggregateLow,n->aggregateHi);
@@ -1261,7 +1261,7 @@ bgpq4_print_format_prefix(struct sx_radix_node* n, void* ff)
if(!f)
f=stdout;
memset(prefix, 0, sizeof(prefix));
sx_prefix_snprintf_fmt(&n->prefix, prefix, sizeof(prefix),
sx_prefix_snprintf_fmt(n->prefix, prefix, sizeof(prefix),
b->name?b->name:"NN", b->format);
fprintf(f, "%s", prefix);
};

View File

@@ -25,6 +25,7 @@
#include "bgpq4.h"
#include "sx_report.h"
#include "sx_maxsockbuf.h"
#include "expander_freeall.h"
int debug_expander=0;
int pipelining=1;
@@ -65,6 +66,11 @@ bgpq_expander_init(struct bgpq_expander* b, int af)
b->server="rr.ntt.net";
b->port="43";
// b->wq = STAILQ_HEAD_INITIALZIER(b->wq);
// b->rq = STAILQ_HEAD_INITIALZIER(b->rq);
// b->rsets = STAILQ_HEAD_INITIALZIER(b->rsets);
// b->macroses = STAILQ_HEAD_INITIALZIER(b->macroses);
STAILQ_INIT(&b->wq);
STAILQ_INIT(&b->rq);
STAILQ_INIT(&b->rsets);
@@ -72,7 +78,7 @@ bgpq_expander_init(struct bgpq_expander* b, int af)
return 1;
fixups:
/* if(b->tree) XXXXXXXXXXXXX sx_radix_tree_destroy(b->tree); */
if(b->tree) sx_radix_tree_freeall(b->tree);
b->tree=NULL;
free(b);
return 0;
@@ -200,21 +206,22 @@ bgpq_expander_add_as(struct bgpq_expander* b, char* as)
int
bgpq_expander_add_prefix(struct bgpq_expander* b, char* prefix)
{
struct sx_prefix p;
if(!sx_prefix_parse(&p,0,prefix)) {
struct sx_prefix *p = sx_prefix_alloc(NULL);
if(!sx_prefix_parse(p,0,prefix)) {
sx_report(SX_ERROR,"Unable to parse prefix %s\n", prefix);
return 0;
} else if(p.family!=b->family) {
} else if(p->family!=b->family) {
SX_DEBUG(debug_expander,"Ignoring prefix %s with wrong address family\n"
,prefix);
return 0;
};
if(b->maxlen && p.masklen>b->maxlen) {
if(b->maxlen && p->masklen>b->maxlen) {
SX_DEBUG(debug_expander, "Ignoring prefix %s: masklen %i > max "
"masklen %u\n", prefix, p.masklen, b->maxlen);
"masklen %u\n", prefix, p->masklen, b->maxlen);
return 0;
};
sx_radix_tree_insert(b->tree,&p);
sx_radix_tree_insert(b->tree,p);
if (p) sx_prefix_destroy(p);
return 1;
};

76
expander_freeall.c Normal file
View File

@@ -0,0 +1,76 @@
#include <stdio.h>
#include <stdlib.h>
#include <bgpq3.h>
void sx_radix_node_freeall(struct sx_radix_node *n) {
if (n->l != NULL) {
sx_radix_node_freeall(n->l);
}
if (n->r != NULL) {
sx_radix_node_freeall(n->r);
}
if (n->son != NULL) {
sx_radix_node_freeall(n->son);
}
if (n->payload) {
free(n->payload);
}
sx_prefix_destroy(n->prefix);
free(n);
}
void sx_radix_tree_freeall(struct sx_radix_tree *t) {
sx_radix_node_freeall(t->head);
free(t);
}
void bgpq_prequest_freeall(struct bgpq_prequest *bpr) {
}
void expander_freeall(struct bgpq_expander *expander) {
printf("starting to free all\n");
// seg fault here
// if (expander->sources != NULL) {
// printf("freeing soruces\n");
// free(expander->sources);
//}
// if (expander->name != NULL) {
// printf("freeing name\n");
// free(expander->name);
//}
printf("freeing asn32s\n");
for (int i = 0; i < 65536; i++) {
if (expander->asn32s[i] != NULL) {
free(expander->asn32s[i]);
}
}
// if (expander->match != NULL) {
// printf("freeing match\n");
// free(expander->match);
//}
//if (expander->server != NULL) {
// printf("freeing server\n");
// free(expander->server);
//}
//if (expander->port != NULL) {
// printf("freeing port\n");
// free(expander->port);
//}
//if (expander->format != NULL) {
// printf("freeing format\n");
// free(expander->format);
//}
sx_radix_tree_freeall(expander->tree);
bgpq_prequest_freeall(expander->firstpipe);
bgpq_prequest_freeall(expander->lastpipe);
printf("finished freeing all\n");
}

5
expander_freeall.h Normal file
View File

@@ -0,0 +1,5 @@
void sx_radix_node_freeall(struct sx_radix_node *n);
void sx_radix_tree_freeall(struct sx_radix_tree *t);
void bgpq_prequest_freeall(struct bgpq_prequest *bpr);
void expander_freeall(struct bgpq_expander *expander);

View File

@@ -21,16 +21,26 @@ sx_prefix_alloc(struct sx_prefix* p)
struct sx_prefix* sp=malloc(sizeof(struct sx_prefix));
if(!sp) return NULL;
if(p) {
*sp=*p;
memcpy(sp, p, sizeof(struct sx_prefix));
} else {
memset(sp,0,sizeof(struct sx_prefix));
memset(sp,0,sizeof(struct sx_prefix));
};
return sp;
};
void
sx_prefix_destroy(struct sx_prefix* p)
{
if(p) free(p);
if(p) free(p);
};
void
sx_radix_node_destroy(struct sx_radix_node *n)
{
if (n) {
if (n->payload) free(n->payload);
if (n->prefix) free(n->prefix);
free(n);
}
};
void
@@ -178,18 +188,24 @@ sx_prefix_setbit(struct sx_prefix* p, int n)
int
sx_radix_tree_insert_specifics(struct sx_radix_tree* t, struct sx_prefix p,
sx_radix_tree_insert_specifics(struct sx_radix_tree* t, struct sx_prefix *p,
unsigned min, unsigned max)
{
if (p.masklen >= min)
sx_radix_tree_insert(t, &p);
if (p.masklen+1 > max)
return 1;
p.masklen+=1;
sx_radix_tree_insert_specifics(t, p, min, max);
sx_prefix_setbit(&p, p.masklen);
sx_radix_tree_insert_specifics(t, p, min, max);
return 1;
struct sx_prefix *np;
np = sx_prefix_alloc(p);
if (np->masklen >= min) {
struct sx_radix_node *nn = sx_radix_tree_insert(t, np);
sx_prefix_destroy(np);
np = nn->prefix;
}
if (np->masklen+1 > max)
return 1;
np->masklen+=1;
sx_radix_tree_insert_specifics(t, np, min, max);
sx_prefix_setbit(np, np->masklen);
sx_radix_tree_insert_specifics(t, np, min, max);
return 1;
};
int
@@ -197,32 +213,37 @@ sx_prefix_range_parse(struct sx_radix_tree* tree, int af, int maxlen,
char* text)
{
char* d=strchr(text, '^');
struct sx_prefix p;
struct sx_prefix *p;
unsigned long min, max;
p = sx_prefix_alloc(NULL);
if (!d || !d[1]) return 0;
*d = 0;
if (!sx_prefix_parse(&p, 0, text)) {
if (!sx_prefix_parse(p, 0, text)) {
sx_report(SX_ERROR, "Unable to parse prefix %s^%s\n", text, d+1);
return 0;
};
*d = '^';
if (af && p.family != af) {
SX_DEBUG(debug_expander, "Ignoring prefix %s, wrong af %i\n", text,
p.family);
if (af && p->family != af) {
sx_report(SX_ERROR, "Ignoring prefix %s, wrong af %i\n", text,
p->family);
return 0;
};
if (maxlen && p.masklen > maxlen) {
if (maxlen && p->masklen > maxlen) {
SX_DEBUG(debug_expander, "Ignoring prefix %s, masklen %i > max "
"masklen %u\n", text, p.masklen, maxlen);
"masklen %u\n", text, p->masklen, maxlen);
return 0;
};
if (d[1] == '-') {
min=p.masklen+1;
min=p->masklen+1;
max=maxlen;
} else if (d[1] == '+') {
min=p.masklen;
min=p->masklen;
max=maxlen;
} else if (isdigit(d[1])) {
char* dm = NULL;
@@ -237,9 +258,9 @@ sx_prefix_range_parse(struct sx_radix_tree* tree, int af, int maxlen,
sx_report(SX_ERROR, "Invalid prefix-range %s\n", text);
return 0;
};
if (min < p.masklen) {
if (min < p->masklen) {
sx_report(SX_ERROR, "Invalid prefix-range %s: min %lu < masklen %u\n",
text, min, p.masklen);
text, min, p->masklen);
return 0;
};
if (af == AF_INET && max > 32) {
@@ -313,7 +334,7 @@ sx_prefix_snprintf_fmt(struct sx_prefix* p, char* buffer, int size,
{
unsigned off=0;
const char* c=format;
struct sx_prefix q;
struct sx_prefix *q = sx_prefix_alloc(NULL);
while(*c) {
if(*c=='%') {
switch(*(c+1)) {
@@ -332,13 +353,13 @@ sx_prefix_snprintf_fmt(struct sx_prefix* p, char* buffer, int size,
off+=snprintf(buffer+off,size-off,"%s",name);
break;
case 'm':
sx_prefix_mask(p, &q);
inet_ntop(p->family,&q.addr,buffer+off,size-off);
sx_prefix_mask(p, q);
inet_ntop(p->family,&q->addr,buffer+off,size-off);
off=strlen(buffer);
break;
case 'i':
sx_prefix_imask(p, &q);
inet_ntop(p->family,&q.addr,buffer+off,size-off);
sx_prefix_imask(p, q);
inet_ntop(p->family,&q->addr,buffer+off,size-off);
off=strlen(buffer);
break;
default :
@@ -404,7 +425,7 @@ sx_radix_node_new(struct sx_prefix* prefix)
if(!rn) return NULL;
memset(rn,0,sizeof(struct sx_radix_node));
if(prefix) {
rn->prefix=*prefix; /* structure copy */
rn->prefix = sx_prefix_alloc(prefix);
};
return rn;
};
@@ -462,6 +483,7 @@ next:
} else {
sx_report(SX_ERROR,"Unlinking node with no parent and not root\n");
};
sx_radix_node_destroy(node);
return;
} else if(node->l) {
if(node->parent) {
@@ -481,6 +503,7 @@ next:
} else {
sx_report(SX_ERROR,"Unlinking node with no parent and not root\n");
};
sx_radix_node_destroy(node);
return;
} else {
/* the only case - node does not have descendants */
@@ -500,6 +523,7 @@ next:
} else {
sx_report(SX_ERROR,"Unlinking node with no parent and not root\n");
};
sx_radix_node_destroy(node);
return;
};
};
@@ -518,12 +542,12 @@ sx_radix_tree_lookup(struct sx_radix_tree* tree, struct sx_prefix* prefix)
chead=tree->head;
next:
eb=sx_prefix_eqbits(&chead->prefix,prefix);
if(eb==chead->prefix.masklen && eb==prefix->masklen) {
eb=sx_prefix_eqbits(chead->prefix,prefix);
if(eb==chead->prefix->masklen && eb==prefix->masklen) {
/* they are equal */
if(chead->isGlue) return candidate;
return chead;
} else if(eb<chead->prefix.masklen) {
} else if(eb<chead->prefix->masklen) {
return candidate;
} else if(eb<prefix->masklen) {
/* it equals chead->masklen */
@@ -553,7 +577,7 @@ next:
} else {
char pbuffer[128], cbuffer[128];
sx_prefix_snprintf(prefix,pbuffer,sizeof(pbuffer));
sx_prefix_snprintf(&chead->prefix,cbuffer,sizeof(cbuffer));
sx_prefix_snprintf(chead->prefix,cbuffer,sizeof(cbuffer));
printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n", eb,
pbuffer, cbuffer);
abort();
@@ -579,13 +603,16 @@ sx_radix_tree_insert(struct sx_radix_tree* tree, struct sx_prefix* prefix)
chead=tree->head;
next:
eb=sx_prefix_eqbits(prefix,&chead->prefix);
if(eb<prefix->masklen && eb<chead->prefix.masklen) {
struct sx_prefix neoRoot=*prefix;
eb=sx_prefix_eqbits(prefix,chead->prefix);
if(eb<prefix->masklen && eb<chead->prefix->masklen) {
struct sx_prefix *neoRoot = sx_prefix_alloc(prefix);
struct sx_radix_node* rn, *ret=sx_radix_node_new(prefix);
neoRoot.masklen=eb;
sx_prefix_adjust_masklen(&neoRoot);
rn=sx_radix_node_new(&neoRoot);
neoRoot->masklen=eb;
sx_prefix_adjust_masklen(neoRoot);
rn=sx_radix_node_new(neoRoot);
sx_prefix_destroy(neoRoot);
neoRoot = rn->prefix;
if(!rn) {
sx_report(SX_ERROR,"Unable to create node: %s\n", strerror(errno));
return NULL;
@@ -603,9 +630,9 @@ next:
rn->isGlue=1;
*candidate=rn;
return ret;
} else if(eb==prefix->masklen && eb<chead->prefix.masklen) {
} else if(eb==prefix->masklen && eb<chead->prefix->masklen) {
struct sx_radix_node* ret=sx_radix_node_new(prefix);
if(sx_prefix_isbitset(&chead->prefix,eb+1)) {
if(sx_prefix_isbitset(chead->prefix,eb+1)) {
ret->r=chead;
} else {
ret->l=chead;
@@ -614,7 +641,7 @@ next:
chead->parent=ret;
*candidate=ret;
return ret;
} else if(eb==chead->prefix.masklen && eb<prefix->masklen) {
} else if(eb==chead->prefix->masklen && eb<prefix->masklen) {
if(sx_prefix_isbitset(prefix,eb+1)) {
if(chead->r) {
candidate=&chead->r;
@@ -636,7 +663,7 @@ next:
return chead->l;
};
};
} else if(eb==chead->prefix.masklen && eb==prefix->masklen) {
} else if(eb==chead->prefix->masklen && eb==prefix->masklen) {
/* equal routes... */
if(chead->isGlue) {
chead->isGlue=0;
@@ -645,12 +672,12 @@ next:
} else {
char pbuffer[128], cbuffer[128];
sx_prefix_snprintf(prefix,pbuffer,sizeof(pbuffer));
sx_prefix_snprintf(&chead->prefix,cbuffer,sizeof(cbuffer));
sx_prefix_snprintf(chead->prefix,cbuffer,sizeof(cbuffer));
printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n", eb,
pbuffer, cbuffer);
abort();
};
};
}
void
sx_radix_node_fprintf(struct sx_radix_node* node, void* udata)
@@ -660,7 +687,7 @@ sx_radix_node_fprintf(struct sx_radix_node* node, void* udata)
if(!node) {
fprintf(out,"(null)\n");
} else {
sx_prefix_snprintf(&node->prefix,buffer,sizeof(buffer));
sx_prefix_snprintf(node->prefix,buffer,sizeof(buffer));
fprintf(out,"%s %s\n", buffer, node->isGlue?"(glue)":"");
};
};
@@ -694,19 +721,19 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
if(debug_aggregation) {
printf("Aggregating on node: ");
sx_prefix_fprint(stdout,&node->prefix);
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);
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);
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);
@@ -714,13 +741,13 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
};
if(node->l) {
printf("L-Tree: ");
sx_prefix_fprint(stdout,&node->l->prefix);
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);
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);
@@ -731,27 +758,27 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
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->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;
node->aggregateHi=node->r->prefix->masklen;
if(node->isGlue) {
node->isGlue=0;
node->aggregateLow=node->r->prefix.masklen;
node->aggregateLow=node->r->prefix->masklen;
} else {
node->aggregateLow=node->prefix.masklen;
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->r->prefix.masklen==node->prefix.masklen+1 &&
node->l->prefix.masklen==node->prefix.masklen+1)
node->r->prefix->masklen==node->prefix->masklen+1 &&
node->l->prefix->masklen==node->prefix->masklen+1)
{
node->son=sx_radix_node_new(&node->prefix);
node->son=sx_radix_node_new(node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->r->son->aggregateHi;
@@ -762,8 +789,8 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
} 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 &&
node->l->prefix.masklen==node->prefix.masklen+1) {
if(node->r->prefix->masklen==node->prefix->masklen+1 &&
node->l->prefix->masklen==node->prefix->masklen+1) {
if(node->isGlue) {
node->r->isGlue=1;
node->l->isGlue=1;
@@ -771,14 +798,14 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
node->isGlue=0;
node->aggregateHi=node->r->aggregateHi;
node->aggregateLow=node->r->aggregateLow;
} else if(node->r->prefix.masklen==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;
node->aggregateLow=node->prefix->masklen;
} else {
node->son=sx_radix_node_new(&node->prefix);
node->son=sx_radix_node_new(node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->r->aggregateHi;
@@ -789,7 +816,7 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
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=sx_radix_node_new(node->prefix);
node->son->son->isGlue=0;
node->son->son->isAggregate=1;
node->son->son->aggregateHi=node->r->son->aggregateHi;
@@ -803,8 +830,8 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
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 &&
node->l->prefix.masklen==node->prefix.masklen+1) {
if(node->r->prefix->masklen==node->prefix->masklen+1 &&
node->l->prefix->masklen==node->prefix->masklen+1) {
if(node->isGlue) {
node->r->isGlue=1;
node->l->son->isGlue=1;
@@ -813,7 +840,7 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
node->aggregateHi=node->r->aggregateHi;
node->aggregateLow=node->r->aggregateLow;
} else {
node->son=sx_radix_node_new(&node->prefix);
node->son=sx_radix_node_new(node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->r->aggregateHi;
@@ -826,8 +853,8 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
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 &&
node->r->prefix.masklen==node->prefix.masklen+1) {
if(node->l->prefix->masklen==node->prefix->masklen+1 &&
node->r->prefix->masklen==node->prefix->masklen+1) {
if(node->isGlue) {
node->l->isGlue=1;
node->r->son->isGlue=1;
@@ -836,7 +863,7 @@ sx_radix_node_aggregate(struct sx_radix_node* node)
node->aggregateHi=node->l->aggregateHi;
node->aggregateLow=node->l->aggregateLow;
} else {
node->son=sx_radix_node_new(&node->prefix);
node->son=sx_radix_node_new(node->prefix);
node->son->isGlue=0;
node->son->isAggregate=1;
node->son->aggregateHi=node->l->aggregateHi;
@@ -861,7 +888,7 @@ static void
setGlueUpTo(struct sx_radix_node* node, void* udata)
{
unsigned refine=*(unsigned*)udata;
if(node && node->prefix.masklen <= refine) {
if(node && node->prefix->masklen <= refine) {
node->isGlue=1;
};
};
@@ -869,9 +896,9 @@ setGlueUpTo(struct sx_radix_node* node, void* udata)
int
sx_radix_node_refine(struct sx_radix_node* node, unsigned refine)
{
if(!node->isGlue && node->prefix.masklen<refine) {
if(!node->isGlue && node->prefix->masklen<refine) {
node->isAggregate=1;
node->aggregateLow=node->prefix.masklen;
node->aggregateLow=node->prefix->masklen;
node->aggregateHi=refine;
if(node->l) {
sx_radix_node_foreach(node->l, setGlueUpTo, &refine);
@@ -881,7 +908,7 @@ sx_radix_node_refine(struct sx_radix_node* node, unsigned refine)
sx_radix_node_foreach(node->r, setGlueUpTo, &refine);
sx_radix_node_refine(node->r, refine);
};
} else if(!node->isGlue && node->prefix.masklen==refine) {
} else if(!node->isGlue && node->prefix->masklen==refine) {
/* not setting aggregate in this case */
if(node->l) sx_radix_node_refine(node->l, refine);
if(node->r) sx_radix_node_refine(node->r, refine);
@@ -911,7 +938,7 @@ static void
setGlueFrom(struct sx_radix_node* node, void* udata)
{
unsigned refine=*(unsigned*)udata;
if(node && node->prefix.masklen <= refine) {
if(node && node->prefix->masklen <= refine) {
node->isGlue=1;
};
};
@@ -919,11 +946,11 @@ setGlueFrom(struct sx_radix_node* node, void* udata)
static int
sx_radix_node_refineLow(struct sx_radix_node* node, unsigned refineLow)
{
if(!node->isGlue && node->prefix.masklen<=refineLow) {
if(!node->isGlue && node->prefix->masklen<=refineLow) {
if(!node->isAggregate) {
node->isAggregate=1;
node->aggregateLow=refineLow;
if(node->prefix.family == AF_INET) {
if(node->prefix->family == AF_INET) {
node->aggregateHi=32;
} else {
node->aggregateHi=128;
@@ -939,7 +966,7 @@ sx_radix_node_refineLow(struct sx_radix_node* node, unsigned refineLow)
sx_radix_node_foreach(node->r, setGlueFrom, &refineLow);
sx_radix_node_refineLow(node->r, refineLow);
};
} else if(!node->isGlue && node->prefix.masklen==refineLow) {
} else if(!node->isGlue && node->prefix->masklen==refineLow) {
/* not setting aggregate in this case */
if(node->l) sx_radix_node_refineLow(node->l, refineLow);
if(node->r) sx_radix_node_refineLow(node->r, refineLow);

View File

@@ -24,7 +24,7 @@ typedef struct sx_radix_node {
unsigned int isAggregate:1;
unsigned int aggregateLow;
unsigned int aggregateHi;
struct sx_prefix prefix;
struct sx_prefix *prefix;
} sx_radix_node_t;
typedef struct sx_radix_tree {
@@ -43,6 +43,7 @@ struct sx_radix_node* sx_radix_tree_lookup_exact(struct sx_radix_tree* tree,
struct sx_prefix* sx_prefix_alloc(struct sx_prefix* p);
void sx_prefix_destroy(struct sx_prefix* p);
void sx_radix_node_destroy(struct sx_radix_node* p);
void sx_prefix_adjust_masklen(struct sx_prefix* p);
struct sx_prefix* sx_prefix_new(int af, char* text);
int sx_prefix_parse(struct sx_prefix* p, int af, char* text);