From b481111cf6f3593e9cb5e22cf35599b79c78def4 Mon Sep 17 00:00:00 2001 From: Job Snijders Date: Fri, 20 Aug 2021 00:50:56 +0000 Subject: [PATCH] Replace ASN storage facility with Red Black tree macros (RB_) --- expander.c | 149 +++---- extern.h | 26 +- main.c | 7 + printer.c | 1215 +++++++++++++++++++--------------------------------- 4 files changed, 532 insertions(+), 865 deletions(-) diff --git a/expander.c b/expander.c index 8f973b3..da4ac2e 100644 --- a/expander.c +++ b/expander.c @@ -58,7 +58,15 @@ tentry_cmp(struct sx_tentry *a, struct sx_tentry *b) return strcasecmp(a->text, b->text); } -RB_GENERATE_STATIC(tentree, sx_tentry, entries, tentry_cmp); +RB_GENERATE_STATIC(tentree, sx_tentry, entry, tentry_cmp); + +int +asn_cmp(struct asn_entry *a, struct asn_entry *b) +{ + return (a->asn < b->asn ? -1 : a->asn > b->asn); +} + +RB_GENERATE(asn_tree, asn_entry, entry, asn_cmp); int bgpq_expander_init(struct bgpq_expander *b, int af) @@ -80,22 +88,12 @@ bgpq_expander_init(struct bgpq_expander *b, int af) b->sources = ""; b->name = "NN"; b->aswidth = 8; - b->asn32s[0] = malloc(8192); - if (!b->asn32s[0]) { - sx_report(SX_FATAL,"Unable to allocate 8192 bytes: %s\n", - strerror(errno)); - exit(1); - } - memset(b->asn32s[0], 0, 8192); b->identify = 1; 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); - + RB_INIT(&b->asnlist); + STAILQ_INIT(&b->wq); STAILQ_INIT(&b->rq); STAILQ_INIT(&b->rsets); @@ -123,7 +121,7 @@ bgpq_expander_add_asset(struct bgpq_expander *b, char *as) le = sx_slentry_new(as); - STAILQ_INSERT_TAIL(&b->macroses, le, entries); + STAILQ_INSERT_TAIL(&b->macroses, le, entry); return 1; } @@ -141,7 +139,7 @@ bgpq_expander_add_rset(struct bgpq_expander *b, char *rs) if (!le) return 0; - STAILQ_INSERT_TAIL(&b->rsets, le, entries); + STAILQ_INSERT_TAIL(&b->rsets, le, entry); return 1; } @@ -183,46 +181,29 @@ bgpq_expander_add_stop(struct bgpq_expander *b, char *rs) int bgpq_expander_add_as(struct bgpq_expander *b, char *as) { - char *eoa; - uint32_t asn1 = 0, asn2 = 0; - uint32_t asno = 0; + char *eoa; + uint32_t asno = 0; + struct asn_entry *asne; if (!b || !as) return 0; asno = strtoul(as + 2, &eoa, 10); - if (eoa && *eoa != 0) { sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n", *eoa, as); return 0; } - if (asno > 65535) { - asn1 = asno / 65536; - asn2 = asno % 65536; - } else - asn1 = asno; - if (!expand_special_asn && ((asno >= 4200000000ul) || (asno >= 64496 && asno <= 65551))) return 0; - if (!b->asn32s[asn1]) { - b->asn32s[asn1] = malloc(8192); - if (!b->asn32s[asn1]) { - sx_report(SX_FATAL, "Unable to allocate 8192 " - "bytes: %s. Unable to add asn32 %s to " - " future expansion\n", strerror(errno), as); - return 0; - } - memset(b->asn32s[asn1], 0, 8192); - } + if ((asne = malloc(sizeof(struct asn_entry))) == NULL) + err(1, NULL); - if (asno > 65535) - b->asn32s[asn1][asn2 / 8] |= (0x80 >> (asn2 % 8)); - else - b->asn32s[0][asn1 / 8] |= (0x80 >> (asn1 % 8)); + asne->asn = asno; + RB_INSERT(asn_tree, &b->asnlist, asne); return 1; } @@ -449,12 +430,15 @@ bgpq_pipeline(struct bgpq_expander *b, static void bgpq_expander_invalidate_asn(struct bgpq_expander *b, const char *q) { - if (!strncmp(q, "!gas", 4) || !strncmp(q, "!6as", 4)) { - char *eptr; - unsigned long asn, asn0, asn1 = 0; + char *eptr; + unsigned long asn = 0; + struct asn_entry find, *res; + if (!strncmp(q, "!gas", 4) || !strncmp(q, "!6as", 4)) { + + errno = 0; asn = strtoul(q + 4, &eptr, 10); - if (q[0] == '\0' || *eptr != '\0') { + if (*eptr != '\n') { sx_report(SX_ERROR, "not a number: %s\n", q); return; } @@ -471,15 +455,16 @@ bgpq_expander_invalidate_asn(struct bgpq_expander *b, const char *q) return; } - asn1 = asn % 65536; - asn0 = asn / 65536; - if (!b->asn32s[asn0] || - !(b->asn32s[asn0][asn1/8] & (0x80 >> (asn1 % 8)))) { - sx_report(SX_NOTICE, "strange, invalidating inactive " - "asn %lu(%s)\n", asn, q); - } else { - b->asn32s[asn0][asn1 / 8] &= ~(0x80 >> (asn1 % 8)); + find.asn = asn; + res = RB_FIND(asn_tree, &b->asnlist, &find); + if (res == NULL) + return; + + if (RB_REMOVE(asn_tree, &b->asnlist, res) == NULL) { + sx_report(SX_ERROR, "failed to remove: %lu", asn); + return; } + } } @@ -884,6 +869,7 @@ bgpq_expand(struct bgpq_expander *b) struct slentry *mc; struct addrinfo hints, *res = NULL, *rp; struct linger sl; + struct asn_entry *asne; sl.l_onoff = 1; sl.l_linger = 5; @@ -1036,7 +1022,7 @@ bgpq_expand(struct bgpq_expander *b) if (pipelining) fcntl(fd, F_SETFL, O_NONBLOCK|(fcntl(fd, F_GETFL))); - STAILQ_FOREACH(mc, &b->macroses, entries) { + STAILQ_FOREACH(mc, &b->macroses, entry) { if (!b->maxdepth && RB_EMPTY(&b->stoplist)) { if (aquery) bgpq_expand_irrd(b, bgpq_expanded_prefix, b, @@ -1065,8 +1051,7 @@ bgpq_expand(struct bgpq_expander *b) } if (b->generation >= T_PREFIXLIST || b->validate_asns) { - uint32_t i, j, k; - STAILQ_FOREACH(mc, &b->rsets, entries) { + STAILQ_FOREACH(mc, &b->rsets, entry) { if (b->family == AF_INET) bgpq_expand_irrd(b, bgpq_expanded_prefix, NULL, "!i%s,1\n", mc->text); @@ -1074,33 +1059,27 @@ bgpq_expand(struct bgpq_expander *b) bgpq_expand_irrd(b, bgpq_expanded_v6prefix, NULL, "!i%s,1\n", mc->text); } - for (k=0; k < sizeof(b->asn32s) / sizeof(unsigned char *); 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 (b->family == AF_INET6) { - if (!pipelining) { - bgpq_expand_irrd(b, bgpq_expanded_v6prefix, - NULL, "!6as%" PRIu32 "\n", ( k << 16) + i * 8 + j); - } else { - bgpq_pipeline(b, bgpq_expanded_v6prefix, - NULL, "!6as%" PRIu32 "\n", (k << 16) + i * 8 + j); - } - } else { - if (!pipelining) { - bgpq_expand_irrd(b, bgpq_expanded_prefix, - NULL, "!gas%" PRIu32 "\n", (k << 16) + i * 8 + j); - } else { - bgpq_pipeline(b, bgpq_expanded_prefix, - NULL, "!gas%" PRIu32 "\n", ( k<< 16) + i* 8 + j); - } - } - } + + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (b->family == AF_INET6) { + if (!pipelining) { + bgpq_expand_irrd(b, bgpq_expanded_v6prefix, + NULL, "!6as%" PRIu32 "\n", asne->asn); + } else { + bgpq_pipeline(b, bgpq_expanded_v6prefix, + NULL, "!6as%" PRIu32 "\n", asne->asn); + } + } else { + if (!pipelining) { + bgpq_expand_irrd(b, bgpq_expanded_prefix, + NULL, "!gas%" PRIu32 "\n", asne->asn); + } else { + bgpq_pipeline(b, bgpq_expanded_prefix, + NULL, "!gas%" PRIu32 "\n", asne->asn); } } } + if (pipelining) { if (!STAILQ_EMPTY(&b->wq)) bgpq_write(b); @@ -1160,17 +1139,18 @@ bgpq_prequest_freeall(struct bgpq_prequest *bpr) { void expander_freeall(struct bgpq_expander *expander) { struct sx_tentry *var, *nxt; + struct asn_entry *asne, *asne_next; while (!STAILQ_EMPTY(&expander->macroses)) { struct slentry *n1 = STAILQ_FIRST(&expander->macroses); - STAILQ_REMOVE_HEAD(&expander->macroses, entries); + STAILQ_REMOVE_HEAD(&expander->macroses, entry); free(n1->text); free(n1); } while (!STAILQ_EMPTY(&expander->rsets)) { struct slentry *n1 = STAILQ_FIRST(&expander->rsets); - STAILQ_REMOVE_HEAD(&expander->rsets, entries); + STAILQ_REMOVE_HEAD(&expander->rsets, entry); free(n1->text); free(n1); } @@ -1189,10 +1169,11 @@ expander_freeall(struct bgpq_expander *expander) { free(var); } - for (int i = 0; i < 65536; i++) { - if (expander->asn32s[i] != NULL) { - free(expander->asn32s[i]); - } + for (asne = RB_MIN(asn_tree, &expander->asnlist); + asne != NULL; asne = asne_next) { + asne_next = RB_NEXT(asn_tree, &expander->asnlist, asne); + RB_REMOVE(asn_tree, &expander->asnlist, asne); + free(asne); } sx_radix_tree_freeall(expander->tree); diff --git a/extern.h b/extern.h index 42f1efd..3d8bf6e 100644 --- a/extern.h +++ b/extern.h @@ -30,19 +30,24 @@ #include "sx_prefix.h" struct slentry { - STAILQ_ENTRY(slentry) entries; + STAILQ_ENTRY(slentry) entry; char *text; }; struct slentry *sx_slentry_new(char *text); struct sx_tentry { - RB_ENTRY(sx_tentry) entries; + RB_ENTRY(sx_tentry) entry; char *text; }; struct sx_tentry *sx_tentry_new(char *text); +struct asn_entry { + RB_ENTRY(asn_entry) entry; + uint32_t asn; +}; + typedef enum { V_CISCO = 0, V_JUNIPER, @@ -102,12 +107,15 @@ struct bgpq_expander { char *format; unsigned int maxlen; int fd; - unsigned char *asn32s[65536]; + RB_HEAD(asn_tree, asn_entry) asnlist; STAILQ_HEAD(requests, request) wq, rq; STAILQ_HEAD(slentries, slentry) macroses, rsets; RB_HEAD(tentree, sx_tentry) already, stoplist; }; +int asn_cmp(struct asn_entry *, struct asn_entry *); +RB_PROTOTYPE(asn_tree, asn_entry, entry, asn_cmp); + int bgpq_expander_init(struct bgpq_expander *b, int af); int bgpq_expander_add_asset(struct bgpq_expander *b, char *set); int bgpq_expander_add_rset(struct bgpq_expander *b, char *set); @@ -118,12 +126,12 @@ int bgpq_expander_add_stop(struct bgpq_expander *b, char *object); int bgpq_expand(struct bgpq_expander *b); -int bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b); -int bgpq4_print_eacl(FILE *f, struct bgpq_expander *b); -int bgpq4_print_aspath(FILE *f, struct bgpq_expander *b); -int bgpq4_print_asset(FILE *f, struct bgpq_expander *b); -int bgpq4_print_oaspath(FILE *f, struct bgpq_expander *b); -int bgpq4_print_route_filter_list(FILE *f, struct bgpq_expander *b); +void bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b); +void bgpq4_print_eacl(FILE *f, struct bgpq_expander *b); +void bgpq4_print_aspath(FILE *f, struct bgpq_expander *b); +void bgpq4_print_asset(FILE *f, struct bgpq_expander *b); +void bgpq4_print_oaspath(FILE *f, struct bgpq_expander *b); +void bgpq4_print_route_filter_list(FILE *f, struct bgpq_expander *b); void sx_radix_node_freeall(struct sx_radix_node *n); void sx_radix_tree_freeall(struct sx_radix_tree *t); diff --git a/main.c b/main.c index 135102c..994e5d7 100644 --- a/main.c +++ b/main.c @@ -449,14 +449,18 @@ main(int argc, char* argv[]) case V_CISCO: case V_MIKROTIK: expander.aswidth = 4; + break; case V_CISCO_XR: expander.aswidth = 6; + break; case V_JUNIPER: case V_NOKIA: case V_NOKIA_MD: expander.aswidth = 8; + break; case V_BIRD: expander.aswidth = 10; + break; } } else if (expander.generation == T_OASPATH) { int vendor = expander.vendor; @@ -464,12 +468,15 @@ main(int argc, char* argv[]) case V_ARISTA: case V_CISCO: expander.aswidth = 5; + break; case V_CISCO_XR: expander.aswidth = 7; + break; case V_JUNIPER: case V_NOKIA: case V_NOKIA_MD: expander.aswidth = 8; + break; } } } diff --git a/printer.c b/printer.c index 9aae685..c1375f5 100644 --- a/printer.c +++ b/printer.c @@ -25,6 +25,7 @@ * SUCH DAMAGE. */ +#include #include #include #include @@ -39,116 +40,78 @@ extern int debug_expander; -int bgpq4_print_json_aspath(FILE *f, struct bgpq_expander *b); -int bgpq4_print_bird_aspath(FILE *f, struct bgpq_expander *b); -int bgpq4_print_openbgpd_aspath(FILE *f, struct bgpq_expander *b); -int bgpq4_print_openbgpd_asset(FILE *f, struct bgpq_expander *b); +void bgpq4_print_json_aspath(FILE *f, struct bgpq_expander *b); +void bgpq4_print_bird_aspath(FILE *f, struct bgpq_expander *b); +void bgpq4_print_openbgpd_aspath(FILE *f, struct bgpq_expander *b); +void bgpq4_print_openbgpd_asset(FILE *f, struct bgpq_expander *b); -static int +static void bgpq4_print_cisco_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k, empty = 1; + int nc = 0; + struct asn_entry *asne, find, *res; - fprintf(f, "no ip as-path access-list %s\n", b->name ? b->name : "NN"); + fprintf(f, "no ip as-path access-list %s\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber % 8))) { - fprintf(f,"ip as-path access-list %s permit ^%u(_%u)*$\n", - b->name ? b->name: "NN", b->asnumber, b->asnumber); - empty = 0; + if (RB_EMPTY(&b->asnlist)) { + fprintf(f, "ip as-path access-list %s deny .*\n", b->name); + return; } - for (k = 0; k < 65536; k++) { + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f, "ip as-path access-list %s permit" + " ^%u(_%u)*$\n", b->name, res->asn, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); + } - if (!b->asn32s[k]) - continue; + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) + fprintf(f, "ip as-path access-list %s permit" + " ^%u(_[0-9]+)*_(%u", b->name, b->asnumber, + asne->asn); + else + fprintf(f,"|%u", asne->asn); - for (i = 0; i < 8192; i++) { - for (j = 0; j < 8; j++) { - if (b->asn32s[k][i] & (0x80>>j)) { - - if ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f, "ip as-path access-list %s permit" - " ^%u(_[0-9]+)*_(%u", - b->name ? b->name : "NN", - b->asnumber, k * 65536 + i * 8 + j); - empty = 0; - } else { - fprintf(f,"|%u", k * 65536 + i * 8 + j); - empty = 0; - } - - nc++; - - if (nc == b->aswidth) { - fprintf(f, ")$\n"); - nc = 0; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, ")$\n"); + nc = 0; } } if (nc) fprintf(f,")$\n"); - - if (empty) - fprintf(f, "ip as-path access-list %s deny .*\n", - b->name ? b->name : "NN"); - - return 0; } -static int +static void bgpq4_print_cisco_xr_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k, comma = 0; + int nc = 0, comma = 1; + struct asn_entry *asne, find, *res; - fprintf(f, "as-path-set %s", b->name ? b->name : "NN"); + fprintf(f, "as-path-set %s", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber%8))) { - fprintf(f,"\n ios-regex '^%u(_%u)*$'", b->asnumber, - b->asnumber); - comma = 1; + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f, "\n ios-regex '^%u(_%u)*$'", res->asn, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f, "%s\n ios-regex '^%u(_[0-9]+)*_(%u", + comma ? "," : "", + b->asnumber, + asne->asn); + comma = 1; + } else + fprintf(f, "|%u", asne->asn); - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f, "%s\n ios-regex '^%u(_[0-9]+)*_(%u", - comma ? "," : "", - b->asnumber, - k * 65536 + i * 8 + j); - comma = 1; - } else { - fprintf(f, "|%u", - k * 65536 + i * 8 + j); - } - - nc++; - - if (nc == b->aswidth) { - fprintf(f, ")$'"); - nc = 0; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, ")$'"); + nc = 0; } } @@ -156,112 +119,74 @@ bgpq4_print_cisco_xr_aspath(FILE *f, struct bgpq_expander *b) fprintf(f, ")$'"); fprintf(f, "\nend-set\n"); - return 0; } -static int +static void bgpq4_print_cisco_oaspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k, empty = 1; + int nc = 0; + struct asn_entry *asne, find, *res; - fprintf(f, "no ip as-path access-list %s\n", b->name ? b->name : "NN"); + fprintf(f, "no ip as-path access-list %s\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber % 8))) { - fprintf(f,"ip as-path access-list %s permit ^(_%u)*$\n", - b->name ? b->name : "NN", - b->asnumber); - empty = 0; + if (RB_EMPTY(&b->asnlist)) { + fprintf(f, "ip as-path access-list %s deny .*\n", b->name); + return; } - for (k = 0; k < 65536; k++) { + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f, "ip as-path access-list %s permit ^(_%u)*$\n", + b->name, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); + } - if (!b->asn32s[k]) - continue; + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) + fprintf(f,"ip as-path access-list %s permit" + " ^(_[0-9]+)*_(%u", b->name, asne->asn); + else + fprintf(f,"|%u",asne->asn); - for (i = 0; i < 8192; i++) { - for (j = 0; j < 8; j++) { - if (b->asn32s[k][i] & (0x80 >> j)) { - - if ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f,"ip as-path access-list %s permit" - " ^(_[0-9]+)*_(%u", - b->name ? b->name : "NN", - k * 65536 + i * 8 + j); - empty = 0; - } else { - fprintf(f,"|%u",k*65536+i*8+j); - empty = 0; - } - - nc++; - - if (nc == b->aswidth) { - fprintf(f,")$\n"); - nc = 0; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f,")$\n"); + nc = 0; } } if (nc) fprintf(f, ")$\n"); - if (empty) - fprintf(f,"ip as-path access-list %s deny .*\n", - b->name ? b->name : "NN"); - - return 0; } -static int +static void bgpq4_print_cisco_xr_oaspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k, comma = 0; + int nc = 0, comma = 0; + struct asn_entry *asne, find, *res; - fprintf(f, "as-path-set %s", b->name ? b->name : "NN"); + fprintf(f, "as-path-set %s", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber % 8))) { - fprintf(f,"\n ios-regex '^(_%u)*$'", b->asnumber); + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f, "\n ios-regex '^(_%u)*$'", res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); comma = 1; } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f,"%s\n ios-regex '^(_[0-9]+)*_(%u", + comma ? "," : "", asne->asn); + comma = 1; + } else + fprintf(f,"|%u",asne->asn); - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f,"%s\n ios-regex '^(_[0-9]+)*_(%u", - comma ? "," : "", - k * 65536 + i * 8 + j); - comma = 1; - } else { - fprintf(f,"|%u",k*65536+i*8+j); - } - - nc++; - if (nc == b->aswidth) { - fprintf(f,")$'"); - nc = 0; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f,")$'"); + nc = 0; } } @@ -269,56 +194,39 @@ bgpq4_print_cisco_xr_oaspath(FILE *f, struct bgpq_expander *b) fprintf(f,")$'"); fprintf(f,"\nend-set\n"); - - return 0; } -static int +static void bgpq4_print_juniper_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, lineNo = 0, i, j, k; + int nc = 0, lineNo = 0; + struct asn_entry *asne, find, *res; fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n", - b->name ? b->name : "NN"); + b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65535][(b->asnumber % 65536) / 8] - & (0x80 >> (b->asnumber % 8))) { - fprintf(f," as-path a%u \"^%u(%u)*$\";\n", lineNo, - b->asnumber, b->asnumber); + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f, " as-path a0 \"^%u(%u)*$\";\n", res->asn, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); lineNo++; } + + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f, " as-path a%u \"^%u(.)*(%u", + lineNo, b->asnumber, + asne->asn); + } else { + fprintf(f,"|%u", asne->asn); + } - for (k = 0; k < 65536; k++) { + nc++; - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f, " as-path a%u \"^%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 == b->aswidth) { + fprintf(f, ")$\";\n"); + nc = 0; + lineNo++; } } @@ -328,56 +236,38 @@ bgpq4_print_juniper_aspath(FILE *f, struct bgpq_expander *b) fprintf(f, " as-path aNone \"!.*\";\n"); fprintf(f, " }\n}\n"); - - return 0; } -static int +static void bgpq4_print_juniper_oaspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, lineNo = 0, i, j, k; + int nc = 0, lineNo = 0; + struct asn_entry *asne, find, *res; - fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n", - b->name ? b->name : "NN"); + fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] - & (0x80 >> (b->asnumber % 8))) { + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { fprintf(f, " as-path a%u \"^%u(%u)*$\";\n", lineNo, - b->asnumber, b->asnumber); + res->asn, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); lineNo++; } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f," as-path a%u \"^(.)*(%u", + lineNo, + asne->asn); + } else { + fprintf(f, "|%u", asne->asn); + } - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f," as-path a%u \"^(.)*(%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++; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, ")$\";\n"); + nc = 0; + lineNo++; } } @@ -387,87 +277,53 @@ bgpq4_print_juniper_oaspath(FILE *f, struct bgpq_expander *b) fprintf(f, " as-path aNone \"!.*\";\n"); fprintf(f, " }\n}\n"); - - return 0; } -static int +static void bgpq4_print_openbgpd_oaspath(FILE *f, struct bgpq_expander *b) { - int i, j, k, lineNo = 0; + struct asn_entry *asne; - 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)) { - fprintf(f, "allow to AS %u AS %u\n", - b->asnumber, - k * 65536 + i * 8 + j); - lineNo++; - } - } - } + if (RB_EMPTY(&b->asnlist)) { + fprintf(f, "deny to AS %u\n", b->asnumber); + return; } - if (!lineNo) - fprintf(f, "deny to AS %u\n", b->asnumber); - - return 0; + RB_FOREACH(asne, asn_tree, &b->asnlist) + fprintf(f, "allow to AS %u AS %u\n", b->asnumber, asne->asn); } -static int +static void bgpq4_print_nokia_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, lineNo = 1, i, j, k; + int nc = 0, lineNo = 1; + struct asn_entry *asne, find, *res; fprintf(f, "configure router policy-options\n" - "begin\nno as-path-group \"%s\"\n", - b->name ? b->name : "NN"); + "begin\nno as-path-group \"%s\"\n", b->name); - fprintf(f, "as-path-group \"%s\"\n", b->name ? b->name : "NN"); + fprintf(f, "as-path-group \"%s\"\n", b->name); - 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); + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f, " entry 1 expression \"%u+\"\n", res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); lineNo++; } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f," entry %u expression \"%u.*[%u", + lineNo, b->asnumber, asne->asn); + } else { + fprintf(f, " %u", asne->asn); + } - 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 ((unsigned)(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++; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, "]\"\n"); + nc = 0; + lineNo++; } } @@ -475,58 +331,39 @@ bgpq4_print_nokia_aspath(FILE *f, struct bgpq_expander *b) fprintf(f, "]\"\n"); fprintf(f,"exit\ncommit\n"); - - return 0; } -static int +static void bgpq4_print_nokia_md_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, lineNo = 1, i, j, k; + int nc = 0, lineNo = 1; + struct asn_entry *asne, find, *res; fprintf(f,"/configure policy-options\ndelete as-path-group \"%s\"\n", - b->name ? b->name : "NN"); - fprintf(f,"as-path-group \"%s\" {\n", b->name ? b->name : "NN"); + b->name); + fprintf(f,"as-path-group \"%s\" {\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65535][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber % 8))) { - fprintf(f," entry %u {\n expression \"%u+\"\n }\n", - lineNo, b->asnumber); + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { + fprintf(f," entry 1 {\n expression \"%u+\"\n }\n", + res->asn); lineNo++; + RB_REMOVE(asn_tree, &b->asnlist, res); } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f," entry %u {\n expression \"%u.*[%u", + lineNo, b->asnumber, asne->asn); + } else { + fprintf(f, " %u", asne->asn); + } - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f," entry %u {\n 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 }\n"); - nc = 0; - lineNo++; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f,"]\"\n }\n"); + nc = 0; + lineNo++; } } @@ -534,232 +371,154 @@ bgpq4_print_nokia_md_aspath(FILE *f, struct bgpq_expander *b) fprintf(f,"]\"\n }\n"); fprintf(f, "}\n"); - - return 0; } -static int +static void bgpq4_print_huawei_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k, empty = 1; + int nc = 0; + struct asn_entry *asne, find, *res; - fprintf(f, "undo ip as-path-filter %s\n", - b->name ? b->name : "NN"); + fprintf(f, "undo ip as-path-filter %s\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65535][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber % 8))) { + if (RB_EMPTY(&b->asnlist)) { + fprintf(f,"ip as-path-filter %s deny .*\n", b->name); + return; + } + + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { fprintf(f, "ip as-path-filter %s permit ^%u(_%u)*$\n", - b->name ? b->name : "NN", b->asnumber, b->asnumber); - empty = 0; + b->name, res->asn, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) + fprintf(f, "ip as-path-filter %s permit ^%u(_[0-9]+)*" + "_(%u", b->name, b->asnumber, asne->asn); + else + fprintf(f, "|%u", asne->asn); - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f, "ip as-path-filter %s permit ^%u(_[0-9]+)*" - "_(%u", - b->name ? b->name : "NN", - b->asnumber, - k * 65536 + i * 8 + j); - empty = 0; - } else { - fprintf(f, "|%u", - k * 65536 + i * 8 + j); - } - - nc++; - - if (nc == b->aswidth) { - fprintf(f, ")$\n"); - nc = 0; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, ")$\n"); + nc = 0; } } if (nc) fprintf(f, ")$\n"); - - if (empty) - fprintf(f,"ip as-path-filter %s deny .*\n", - b->name ? b->name : "NN"); - - return 0; } -static int +static void bgpq4_print_huawei_oaspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k, empty = 1; + int nc = 0; + struct asn_entry *asne, find, *res; - fprintf(f,"undo ip as-path-filter %s\n", - b->name ? b->name : "NN"); + fprintf(f,"undo ip as-path-filter %s\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & - (0x80 >> (b->asnumber % 8))) { + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { fprintf(f,"ip as-path-filter %s permit ^(_%u)*$\n", - b->name ? b->name : "NN", b->asnumber); - empty = 0; + b->name, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); } - for ( k = 0 ; k < 65536 ; k++) { + if (RB_EMPTY(&b->asnlist)) { + fprintf(f, "ip as-path-filter %s deny .*\n", b->name); + return; + } - if (!b->asn32s[k]) - continue; + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f, "ip as-path-filter %s permit ^(_[0-9]+)*_(%u", + b->name, asne->asn); + } else { + fprintf(f, "|%u", asne->asn); + } - for (i = 0 ; i < 8192 ; i++) { - for (j = 0 ; j < 8 ; j++) { - - if (b->asn32s[k][i] & (0x80 >> j)) { - - if ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f, "ip as-path-filter %s permit ^(_[0-9]+)*_(%u", - b->name?b->name:"NN",k*65536+i*8+j); - } else { - fprintf(f, "|%u",k*65536+i*8+j); - } - - nc++; - empty = 0; - - if (nc == b->aswidth) { - fprintf(f, ")$\n"); - nc = 0; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, ")$\n"); + nc = 0; } } if (nc) fprintf(f, ")$\n"); - - if (empty) - fprintf(f, "ip as-path-filter %s deny .*\n", - b->name ? b->name : "NN"); - - return 0; } -static int +static void bgpq4_print_nokia_oaspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, lineNo = 1, i, j, k; + int nc = 0, lineNo = 1; + struct asn_entry *asne, find, *res; 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"); + "\"%s\"\n", b->name); + fprintf(f, "as-path-group \"%s\"\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8] & - (0x80 >> (b->asnumber % 8))) { + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { fprintf(f, " entry %u expression \"%u+\"\n", lineNo, b->asnumber); + RB_REMOVE(asn_tree, &b->asnlist, res); lineNo++; } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f," entry %u expression \".*[%u", + lineNo, asne->asn); + } else { + fprintf(f," %u", asne->asn); + } - 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 ((unsigned)(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++; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f,"]\"\n"); + nc = 0; + lineNo++; } } if (nc) fprintf(f, "]\"\n"); - - return 0; } -static int +static void bgpq4_print_nokia_md_oaspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, lineNo = 1, i, j, k; + int nc = 0, lineNo = 1; + struct asn_entry *asne, find, *res; fprintf(f, "/configure policy-options\ndelete as-path-group \"%s\"\n", - b->name ? b->name : "NN"); - fprintf(f, "as-path-group \"%s\" {\n", b->name ? b->name : "NN"); + b->name); + fprintf(f, "as-path-group \"%s\" {\n", b->name); - if (b->asn32s[b->asnumber / 65536] && - b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & - (0x80>>(b->asnumber%8))) { + find.asn = b->asnumber; + if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) { fprintf(f, " entry %u {\n expression \"%u+\"\n }\n", - lineNo, b->asnumber); + lineNo, res->asn); + RB_REMOVE(asn_tree, &b->asnlist, res); lineNo++; } - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f," entry %u {\n expression \".*[%u", + lineNo, asne->asn); + } else { + fprintf(f, " %u", asne->asn); + } - 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 ((unsigned)(k * 65536 + i * 8 + j) == b->asnumber) - continue; - - if (!nc) { - fprintf(f," entry %u {\n 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 }\n"); - nc = 0; - lineNo++; - } - } - } + nc++; + if (nc == b->aswidth) { + fprintf(f, "]\"\n }\n"); + nc = 0; + lineNo++; } } @@ -767,82 +526,92 @@ bgpq4_print_nokia_md_oaspath(FILE *f, struct bgpq_expander *b) fprintf(f,"]\"\n }\n"); fprintf(f, "}\n"); - - return 0; } -int +void bgpq4_print_aspath(FILE *f, struct bgpq_expander *b) { switch (b->vendor) { case V_JUNIPER: - return bgpq4_print_juniper_aspath(f, b); + bgpq4_print_juniper_aspath(f, b); + break; case V_CISCO: - return bgpq4_print_cisco_aspath(f, b); - case V_CISCO_XR: - return bgpq4_print_cisco_xr_aspath(f, b); - case V_JSON: - return bgpq4_print_json_aspath(f, b); - case V_BIRD: - return bgpq4_print_bird_aspath(f, b); - case V_OPENBGPD: - return bgpq4_print_openbgpd_aspath(f, b); - case V_NOKIA: - return bgpq4_print_nokia_aspath(f, b); - case V_NOKIA_MD: - return bgpq4_print_nokia_md_aspath(f, b); - case V_HUAWEI: - return bgpq4_print_huawei_aspath(f, b); case V_ARISTA: - return bgpq4_print_cisco_aspath(f, b); + bgpq4_print_cisco_aspath(f, b); + break; + case V_CISCO_XR: + bgpq4_print_cisco_xr_aspath(f, b); + break; + case V_JSON: + bgpq4_print_json_aspath(f, b); + break; + case V_BIRD: + bgpq4_print_bird_aspath(f, b); + break; + case V_OPENBGPD: + bgpq4_print_openbgpd_aspath(f, b); + break; + case V_NOKIA: + bgpq4_print_nokia_aspath(f, b); + break; + case V_NOKIA_MD: + bgpq4_print_nokia_md_aspath(f, b); + break; + case V_HUAWEI: + bgpq4_print_huawei_aspath(f, b); + break; default: sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); } - - return 0; } -int +void bgpq4_print_oaspath(FILE *f, struct bgpq_expander *b) { switch (b->vendor) { case V_JUNIPER: - return bgpq4_print_juniper_oaspath(f, b); + bgpq4_print_juniper_oaspath(f, b); + break; case V_CISCO: - return bgpq4_print_cisco_oaspath(f, b); - case V_CISCO_XR: - return bgpq4_print_cisco_xr_oaspath(f, b); - case V_OPENBGPD: - return bgpq4_print_openbgpd_oaspath(f, b); - case V_NOKIA: - return bgpq4_print_nokia_oaspath(f, b); - case V_NOKIA_MD: - return bgpq4_print_nokia_md_oaspath(f, b); - case V_HUAWEI: - return bgpq4_print_huawei_oaspath(f, b); case V_ARISTA: - return bgpq4_print_cisco_oaspath(f, b); + bgpq4_print_cisco_oaspath(f, b); + break; + case V_CISCO_XR: + bgpq4_print_cisco_xr_oaspath(f, b); + break; + case V_OPENBGPD: + bgpq4_print_openbgpd_oaspath(f, b); + break; + case V_NOKIA: + bgpq4_print_nokia_oaspath(f, b); + break; + case V_NOKIA_MD: + bgpq4_print_nokia_md_oaspath(f, b); + break; + case V_HUAWEI: + bgpq4_print_huawei_oaspath(f, b); + break; default: sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); } - - return 0; } -int +void bgpq4_print_asset(FILE *f, struct bgpq_expander *b) { switch (b->vendor) { case V_JSON: - return bgpq4_print_json_aspath(f, b); + bgpq4_print_json_aspath(f, b); + break; case V_OPENBGPD: - return bgpq4_print_openbgpd_asset(f, b); + bgpq4_print_openbgpd_asset(f, b); + break; case V_BIRD: - return bgpq4_print_bird_aspath(f, b); + bgpq4_print_bird_aspath(f, b); + break; default: sx_report(SX_FATAL, "as-sets (-t) supported for JSON, " "OpenBGPD, and BIRD only\n"); - return -1; } } @@ -899,47 +668,33 @@ checkSon: bgpq4_print_json_prefix(n->son, ff); } -int +void bgpq4_print_json_aspath(FILE *f, struct bgpq_expander *b) { - int nc = 0, i, j, k; + int nc = 0; + struct asn_entry *asne; - fprintf(f, "{\"%s\": [", b->name ? b->name : "NN"); + fprintf(f, "{\"%s\": [", b->name); - 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 (!nc) { - fprintf(f, "%s\n %u", - needscomma ? "," : "", - k * 65536 + i * 8 + j); - needscomma = 1; - } else { - fprintf(f, "%s%u", - needscomma ? "," : "", - k * 65536 + i * 8 + j); - needscomma = 1; - } - - nc++; - - if (nc == b->aswidth) - nc = 0; - } - } + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) { + fprintf(f, "%s\n %u", + needscomma ? "," : "", + asne->asn); + needscomma = 1; + } else { + fprintf(f, "%s%u", + needscomma ? "," : "", + asne->asn); + needscomma = 1; } + + nc++; + if (nc == b->aswidth) + nc = 0; } fprintf(f,"\n]}\n"); - - return 0; } static void @@ -973,51 +728,30 @@ checkSon: bgpq4_print_bird_prefix(n->son, ff); } -int +void bgpq4_print_bird_aspath(FILE* f, struct bgpq_expander* b) { - int nc = 0, i, j, k, empty = 1; - char buffer[2048]; - snprintf(buffer, sizeof(buffer), "%s = [", b->name ? b->name : "NN"); + int nc = 0; + struct asn_entry *asne; - for (k = 0; k < 65536; k++) { - if (!b->asn32s[k]) - continue; + fprintf(f, "%s = [", b->name); - for (i = 0; i < 8192; i++) { - for (j = 0; j < 8; j++) { - - if (b->asn32s[k][i] & (0x80 >> j)) { - - if (buffer[0]) - fprintf(f, "%s", buffer); - - buffer[0] = 0; - - if (!nc) { - fprintf(f, "%s%u", - empty ? "" : ",\n ", - k * 65536 + i * 8 + j); - empty = 0; - } else { - fprintf(f, ", %u", - k * 65536 + i * 8 + j); - } - - nc++; - - if (nc == b->aswidth) - nc = 0; - } - } - } - } - - if (!empty) + if (RB_EMPTY(&b->asnlist)) { fprintf(f, "];\n"); + return; + } + + RB_FOREACH(asne, asn_tree, &b->asnlist) { + if (!nc) + fprintf(f, "\n %u", asne->asn); + else + fprintf(f, ", %u", asne->asn); - return 0; + nc++; + if (nc == b->aswidth) + nc = 0; + } } static void @@ -1051,64 +785,37 @@ checkSon: bgpq4_print_openbgpd_prefix(n->son, ff); } -int +void bgpq4_print_openbgpd_asset(FILE *f, struct bgpq_expander *b) { - int i, j, k, nc = 0; + int nc = 0; + struct asn_entry *asne; - fprintf(f, "as-set %s {", b->name ? b->name : "NN"); + fprintf(f, "as-set %s {", b->name); - for (k = 0; k < 65536; k++) { + RB_FOREACH(asne, asn_tree, &b->asnlist) { + fprintf(f, "%s%u", nc == 0 ? "\n\t" : " ", asne->asn); - if (!b->asn32s[k]) - continue; - - for (i = 0; i < 8192; i++) { - for (j = 0; j < 8; j++) { - if (b->asn32s[k][i] & (0x80 >> j)) { - fprintf(f, "%s%u", - nc == 0 ? "\n\t" : " ", - k * 65536 + i * 8 + j); - - nc++; - - if (nc == b->aswidth) - nc = 0; - } - } + nc++; + if (nc == b->aswidth) + nc = 0; } - } fprintf(f, "\n}\n"); - - return 0; } -int +void bgpq4_print_openbgpd_aspath(FILE *f, struct bgpq_expander *b) { - int i, j, k, lineNo = 0; + struct asn_entry *asne; - 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)) { - fprintf(f, "allow from AS %u AS %u\n", - b->asnumber, k * 65536 + i * 8 + j); - lineNo++; - } - } - } - } - - if (!lineNo) + if (RB_EMPTY(&b->asnlist)) { fprintf(f, "deny from AS %u\n", b->asnumber); - - return 0; + return; + } + + RB_FOREACH(asne, asn_tree, &b->asnlist) + fprintf(f, "allow from AS %u AS %u\n", b->asnumber, asne->asn); } static int jrfilter_prefixed = 1; @@ -1496,7 +1203,7 @@ checkSon: } -static int +static void bgpq4_print_juniper_prefixlist(FILE *f, struct bgpq_expander *b) { fprintf(f, "policy-options {\nreplace:\n prefix-list %s {\n", @@ -1505,11 +1212,9 @@ bgpq4_print_juniper_prefixlist(FILE *f, struct bgpq_expander *b) sx_radix_tree_foreach(b->tree, bgpq4_print_jprefix, f); fprintf(f, " }\n}\n"); - - return 0; } -static int +static void bgpq4_print_juniper_routefilter(FILE *f, struct bgpq_expander *b) { char *c = NULL; @@ -1542,18 +1247,14 @@ bgpq4_print_juniper_routefilter(FILE *f, struct bgpq_expander *b) } else { fprintf(f, " }\n }\n}\n"); } - - return 0; } -static int +static void bgpq4_print_openbgpd_prefixlist(FILE *f, struct bgpq_expander *b) { - bname = b->name ? b->name : "NN"; - if (sx_radix_tree_empty(b->tree)) { fprintf(f, "# generated prefix-list %s (AS %u) is empty\n", - bname, b->asnumber); + b->name, b->asnumber); if (!b->asnumber) fprintf(f, "# use -a to generate \"deny from " "ASN \" instead of this list\n"); @@ -1577,11 +1278,9 @@ bgpq4_print_openbgpd_prefixlist(FILE *f, struct bgpq_expander *b) } else { fprintf(f, "deny from AS %u\n", b->asnumber); } - - return 0; } -static int +static void bgpq4_print_openbgpd_prefixset(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1592,11 +1291,9 @@ bgpq4_print_openbgpd_prefixset(FILE *f, struct bgpq_expander *b) sx_radix_tree_foreach(b->tree, bgpq4_print_openbgpd_prefix, f); fprintf(f, "\n}\n"); - - return 0; } -static int +static void bgpq4_print_cisco_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1616,38 +1313,30 @@ bgpq4_print_cisco_prefixlist(FILE *f, struct bgpq_expander *b) seq ? " seq 1" : "", (b->family == AF_INET) ? "0.0.0.0/0" : "::/0"); } - - return 0; } -static int +static void bgpq4_print_ciscoxr_prefixlist(FILE *f, struct bgpq_expander *b) { - bname = b->name ? b->name : "NN"; - - fprintf(f, "no prefix-set %s\nprefix-set %s\n", bname, bname); + fprintf(f, "no prefix-set %s\n", b->name); + fprintf(f, "prefix-set %s\n", b->name); sx_radix_tree_foreach(b->tree, bgpq4_print_cprefixxr, f); fprintf(f, "\nend-set\n"); - - return 0; } -static int +static void bgpq4_print_json_prefixlist(FILE *f, struct bgpq_expander *b) { - fprintf(f, "{ \"%s\": [", - b->name ? b->name : "NN"); + fprintf(f, "{ \"%s\": [", b->name); sx_radix_tree_foreach(b->tree, bgpq4_print_json_prefix, f); fprintf(f,"\n] }\n"); - - return 0; } -static int +static void bgpq4_print_bird_prefixlist(FILE *f, struct bgpq_expander *b) { if (!sx_radix_tree_empty(b->tree)) { @@ -1658,11 +1347,9 @@ bgpq4_print_bird_prefixlist(FILE *f, struct bgpq_expander *b) } else { SX_DEBUG(debug_expander, "skip empty prefix-list in BIRD format\n"); } - - return 0; } -static int +static void bgpq4_print_huawei_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1680,11 +1367,9 @@ bgpq4_print_huawei_prefixlist(FILE *f, struct bgpq_expander *b) seq ? " seq 1" : "", (b->family == AF_INET) ? "0.0.0.0/0" : "::/0"); } - - return 0; } -static int +static void bgpq4_print_arista_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1708,8 +1393,6 @@ bgpq4_print_arista_prefixlist(FILE *f, struct bgpq_expander *b) seq, (b->family == AF_INET) ? "0.0.0.0/0" : "::/0"); } - - return 0; } struct fpcbdata { @@ -1755,7 +1438,7 @@ checkSon: bgpq4_print_format_prefix(n->son, ff); } -static int +static void bgpq4_print_format_prefixlist(FILE *f, struct bgpq_expander *b) { struct fpcbdata ff = {.f=f, .b=b}; @@ -1767,11 +1450,9 @@ bgpq4_print_format_prefixlist(FILE *f, struct bgpq_expander *b) if (len < 2 || !(b->format[len-2] == '\\' && b->format[len-1] == 'n')) fprintf(f, "\n"); - - return 0; } -static int +static void bgpq4_print_nokia_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1780,10 +1461,9 @@ bgpq4_print_nokia_prefixlist(FILE *f, struct bgpq_expander *b) fprintf(f,"prefix-list \"%s\"\n", bname); sx_radix_tree_foreach(b->tree, bgpq4_print_nokia_prefix, f); fprintf(f,"exit\ncommit\n"); - return 0; } -static int +static void bgpq4_print_cisco_eacl(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1797,11 +1477,9 @@ bgpq4_print_cisco_eacl(FILE *f, struct bgpq_expander *b) fprintf(f, "! generated access-list %s is empty\n", bname); fprintf(f, "ip access-list extended %s deny any any\n", bname); } - - return 0; } -static int +static void bgpq4_print_nokia_ipprefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1819,11 +1497,9 @@ bgpq4_print_nokia_ipprefixlist(FILE *f, struct bgpq_expander *b) } fprintf(f,"exit\n"); - - return 0; } -static int +static void bgpq4_print_nokia_md_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1842,11 +1518,9 @@ bgpq4_print_nokia_md_prefixlist(FILE *f, struct bgpq_expander *b) } fprintf(f,"}\n"); - - return 0; } -static int +static void bgpq4_print_nokia_md_ipprefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1861,8 +1535,6 @@ bgpq4_print_nokia_md_ipprefixlist(FILE *f, struct bgpq_expander *b) } fprintf(f,"}\n"); - - return 0; } static void @@ -1906,7 +1578,7 @@ checkSon: bgpq4_print_kprefix(n->son, ff); } -static int +static void bgpq4_print_mikrotik_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; @@ -1916,77 +1588,79 @@ bgpq4_print_mikrotik_prefixlist(FILE *f, struct bgpq_expander *b) } else { fprintf(f, "# generated prefix-list %s is empty\n", bname); } - - return 0; } -int +void bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b) { switch (b->vendor) { case V_JUNIPER: - return bgpq4_print_juniper_prefixlist(f, b); + bgpq4_print_juniper_prefixlist(f, b); + break; case V_CISCO: - return bgpq4_print_cisco_prefixlist(f, b); + bgpq4_print_cisco_prefixlist(f, b); + break; case V_CISCO_XR: - return bgpq4_print_ciscoxr_prefixlist(f, b); + bgpq4_print_ciscoxr_prefixlist(f, b); + break; case V_JSON: - return bgpq4_print_json_prefixlist(f, b); + bgpq4_print_json_prefixlist(f, b); + break; case V_BIRD: - return bgpq4_print_bird_prefixlist(f, b); + bgpq4_print_bird_prefixlist(f, b); + break; case V_OPENBGPD: - return bgpq4_print_openbgpd_prefixlist(f, b); + bgpq4_print_openbgpd_prefixlist(f, b); + break; case V_FORMAT: - return bgpq4_print_format_prefixlist(f, b); + bgpq4_print_format_prefixlist(f, b); + break; case V_NOKIA: - return bgpq4_print_nokia_prefixlist(f, b); + bgpq4_print_nokia_prefixlist(f, b); + break; case V_NOKIA_MD: - return bgpq4_print_nokia_md_ipprefixlist(f, b); + bgpq4_print_nokia_md_ipprefixlist(f, b); + break; case V_HUAWEI: - return bgpq4_print_huawei_prefixlist(f, b); + bgpq4_print_huawei_prefixlist(f, b); + break; case V_MIKROTIK: - return bgpq4_print_mikrotik_prefixlist(f, b); + bgpq4_print_mikrotik_prefixlist(f, b); + break; case V_ARISTA: - return bgpq4_print_arista_prefixlist(f, b); + bgpq4_print_arista_prefixlist(f, b); + break; } - - return 0; } -int +void bgpq4_print_eacl(FILE *f, struct bgpq_expander *b) { switch (b->vendor) { case V_JUNIPER: - return bgpq4_print_juniper_routefilter(f, b); + bgpq4_print_juniper_routefilter(f, b); + break; case V_CISCO: - return bgpq4_print_cisco_eacl(f, b); - case V_CISCO_XR: - sx_report(SX_FATAL, "unreachable point\n"); - case V_JSON: - sx_report(SX_FATAL, "unreachable point\n"); - case V_BIRD: - sx_report(SX_FATAL, "unreachable point\n"); + bgpq4_print_cisco_eacl(f, b); + break; case V_OPENBGPD: - return bgpq4_print_openbgpd_prefixset(f, b); - case V_FORMAT: - sx_report(SX_FATAL, "unreachable point\n"); + bgpq4_print_openbgpd_prefixset(f, b); + break; case V_NOKIA: - return bgpq4_print_nokia_ipprefixlist(f, b); + bgpq4_print_nokia_ipprefixlist(f, b); + break; case V_NOKIA_MD: - return bgpq4_print_nokia_md_prefixlist(f, b); - case V_MIKROTIK: - return sx_report(SX_FATAL, "unreachable point\n"); - case V_HUAWEI: - return sx_report(SX_FATAL, "unreachable point\n"); + bgpq4_print_nokia_md_prefixlist(f, b); + break; case V_ARISTA: - return bgpq4_print_cisco_eacl(f, b); + bgpq4_print_cisco_eacl(f, b); + break; + default: + sx_report(SX_FATAL, "unreachable point\n"); } - - return 0; } -static int +static void bgpq4_print_juniper_route_filter_list(FILE *f, struct bgpq_expander *b) { fprintf(f, "policy-options {\nreplace:\n route-filter-list %s {\n", @@ -2001,19 +1675,16 @@ bgpq4_print_juniper_route_filter_list(FILE *f, struct bgpq_expander *b) } fprintf(f, " }\n}\n"); - - return 0; } -int +void bgpq4_print_route_filter_list(FILE *f, struct bgpq_expander *b) { switch(b->vendor) { case V_JUNIPER: - return bgpq4_print_juniper_route_filter_list(f, b); + bgpq4_print_juniper_route_filter_list(f, b); + break; default: sx_report(SX_FATAL, "unreachable point\n"); } - - return 0; }