diff --git a/bgpq4.c b/bgpq4.c index 38aaabf..0998ede 100644 --- a/bgpq4.c +++ b/bgpq4.c @@ -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; }; diff --git a/bgpq4_printer.c b/bgpq4_printer.c index 4a32599..d8e85a3 100644 --- a/bgpq4_printer.c +++ b/bgpq4_printer.c @@ -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); }; diff --git a/bgpq_expander.c b/bgpq_expander.c index 4389ba1..dcaf351 100644 --- a/bgpq_expander.c +++ b/bgpq_expander.c @@ -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; }; diff --git a/expander_freeall.c b/expander_freeall.c new file mode 100644 index 0000000..1edf6e0 --- /dev/null +++ b/expander_freeall.c @@ -0,0 +1,76 @@ +#include +#include + + +#include + +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"); + +} + diff --git a/expander_freeall.h b/expander_freeall.h new file mode 100644 index 0000000..2979b21 --- /dev/null +++ b/expander_freeall.h @@ -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); diff --git a/sx_prefix.c b/sx_prefix.c index d5ce839..c56587d 100644 --- a/sx_prefix.c +++ b/sx_prefix.c @@ -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(ebprefix.masklen) { + } else if(ebprefix->masklen) { return candidate; } else if(ebmasklen) { /* 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(ebmasklen && ebprefix.masklen) { - struct sx_prefix neoRoot=*prefix; + eb=sx_prefix_eqbits(prefix,chead->prefix); + if(ebmasklen && ebprefix->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 && ebprefix.masklen) { + } else if(eb==prefix->masklen && ebprefix->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 && ebmasklen) { + } else if(eb==chead->prefix->masklen && ebmasklen) { 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.masklenisGlue && node->prefix->masklenisAggregate=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); diff --git a/sx_prefix.h b/sx_prefix.h index a893057..b7133e6 100644 --- a/sx_prefix.h +++ b/sx_prefix.h @@ -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);