From: Claudio Jeker Subject: bgpd: add log_roa() and log_aspa() To: tech@openbsd.org Date: Wed, 10 Jan 2024 12:05:54 +0100 Extract the code to print a roa or aspa entry from printconf and convert it into log_roa() and log_aspa(). Now log_aspa() is a bit complex because the size of the buffer is not known. This now mallocs a buffer large enough and then tries to reuse that buffer. I hope I did not screw this up too badly. A follow up diff will use these log functions in the rtr code. -- :wq Claudio Index: bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v diff -u -p -r1.479 bgpd.h --- bgpd.h 8 Jan 2024 15:08:34 -0000 1.479 +++ bgpd.h 10 Jan 2024 10:36:44 -0000 @@ -1541,6 +1541,8 @@ const char *log_as(uint32_t); const char *log_rd(uint64_t); const char *log_ext_subtype(int, uint8_t); const char *log_reason(const char *); +const char *log_roa(struct roa *); +const char *log_aspa(struct aspa_set *); const char *log_rtr_error(enum rtr_error); const char *log_policy(enum role); int aspath_snprint(char *, size_t, void *, uint16_t); Index: printconf.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v diff -u -p -r1.168 printconf.c --- printconf.c 16 Aug 2023 08:26:35 -0000 1.168 +++ printconf.c 10 Jan 2024 10:59:23 -0000 @@ -687,22 +687,13 @@ void print_roa(struct roa_tree *r) { struct roa *roa; - struct bgpd_addr addr; if (RB_EMPTY(r)) return; printf("roa-set {"); RB_FOREACH(roa, roa_tree, r) { - printf("\n\t"); - addr.aid = roa->aid; - addr.v6 = roa->prefix.inet6; - printf("%s/%u", log_addr(&addr), roa->prefixlen); - if (roa->prefixlen != roa->maxlen) - printf(" maxlen %u", roa->maxlen); - printf(" source-as %u", roa->asnum); - if (roa->expires != 0) - printf(" expires %lld", (long long)roa->expires); + printf("\n\t%s", log_roa(roa)); } printf("\n}\n\n"); } @@ -711,21 +702,13 @@ void print_aspa(struct aspa_tree *a) { struct aspa_set *aspa; - uint32_t i; if (RB_EMPTY(a)) return; printf("aspa-set {"); RB_FOREACH(aspa, aspa_tree, a) { - printf("\n\t"); - printf("customer-as %s", log_as(aspa->as)); - if (aspa->expires != 0) - printf(" expires %lld", (long long)aspa->expires); - printf(" provider-as { "); - for (i = 0; i < aspa->num; i++) - printf("%s ", log_as(aspa->tas[i])); - printf("}"); + printf("\n\t%s", log_aspa(aspa)); } printf("\n}\n\n"); } Index: util.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/util.c,v diff -u -p -r1.77 util.c --- util.c 17 Apr 2023 08:02:21 -0000 1.77 +++ util.c 10 Jan 2024 10:44:27 -0000 @@ -165,6 +165,78 @@ log_reason(const char *communication) { return buf; } +static const char * +log_expires(time_t expires) +{ + static char buf[32]; + + buf[0] = '\0'; + if (expires != 0) + snprintf(buf, sizeof(buf), " expires %lld", (long long)expires); + return buf; +} + +const char * +log_roa(struct roa *roa) +{ + static char buf[256]; + struct bgpd_addr addr = { .aid = roa->aid, .v6 = roa->prefix.inet6 }; + char maxbuf[32]; + + maxbuf[0] = '\0'; + if (roa->prefixlen != roa->maxlen) + snprintf(maxbuf, sizeof(maxbuf), " maxlen %u", roa->maxlen); + snprintf(buf, sizeof(buf), "%s/%u%s source-as %u%s", log_addr(&addr), + roa->prefixlen, maxbuf, roa->asnum, log_expires(roa->expires)); + return buf; +} + +const char * +log_aspa(struct aspa_set *aspa) +{ + static char *buf; + static size_t len; + char asbuf[16]; + size_t needed; + uint32_t i; + + /* include enough space for header and trailer */ + if ((uint64_t)aspa->num > (SIZE_MAX / 12 - 72)) + goto fail; + needed = (uint64_t)aspa->num * 12 + 72; + if (needed > len) { + free(buf); + len = needed; + if ((buf = malloc(len)) == NULL) + goto fail; + } + + snprintf(buf, len, "customer-as %s%s provider-as { ", + log_as(aspa->as), log_expires(aspa->expires)); + + for (i = 0; i < aspa->num; i++) { + snprintf(asbuf, sizeof(asbuf), "%s ", log_as(aspa->tas[i])); + if (strlcat(buf, asbuf, len) >= len) + goto fail; + } + if (strlcat(buf, "}", len) >= len) + goto fail; + return buf; + + fail: + { + static char errbuf[256]; + + free(buf); + buf = NULL; + len = 0; + snprintf(errbuf, sizeof(errbuf), + "customer-as %s%s provider-as { ... }", + log_as(aspa->as), log_expires(aspa->expires)); + return errbuf; + } +} + const char * log_rtr_error(enum rtr_error err) {