diff options
author | David Lamparter <equinox@diac24.net> | 2021-02-18 22:52:23 +0100 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2021-03-27 16:56:55 +0100 |
commit | 212e04e5a7f682594dab26cd8354bc4fa040b61f (patch) | |
tree | 59a09a812b868332f073985494ee0a61910da9fd /lib/prefix.c | |
parent | tools/gcc-plugin: support [un]signed in pragma (diff) | |
download | frr-212e04e5a7f682594dab26cd8354bc4fa040b61f.tar.xz frr-212e04e5a7f682594dab26cd8354bc4fa040b61f.zip |
lib: rework printfrr extensions to output directly
Allowing printfrr extensions to directly write to the output buffer has
a few advantages:
- there is no arbitrary length limit imposed (previously 64)
- the output doesn't need to be copied another time
- the extension can directly use bprintfrr() to put together pieces
The downside is that the theoretical length (regardless of available
buffer space) must be computed correctly.
Extended unit tests to test these paths a bit more thoroughly.
Signed-off-by: David Lamparter <equinox@diac24.net>
Diffstat (limited to 'lib/prefix.c')
-rw-r--r-- | lib/prefix.c | 94 |
1 files changed, 47 insertions, 47 deletions
diff --git a/lib/prefix.c b/lib/prefix.c index afc4d3d5c..169e9ed57 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1361,92 +1361,92 @@ char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len) } printfrr_ext_autoreg_p("EA", printfrr_ea) -static ssize_t printfrr_ea(char *buf, size_t bsz, const char *fmt, +static ssize_t printfrr_ea(struct fbuf *buf, const char **fmt, int prec, const void *ptr) { const struct ethaddr *mac = ptr; + char cbuf[ETHER_ADDR_STRLEN]; - if (mac) - prefix_mac2str(mac, buf, bsz); - else - strlcpy(buf, "NULL", bsz); + if (!mac) + return bputs(buf, "NULL"); - return 2; + /* need real length even if buffer is too short */ + prefix_mac2str(mac, cbuf, sizeof(cbuf)); + return bputs(buf, cbuf); } printfrr_ext_autoreg_p("IA", printfrr_ia) -static ssize_t printfrr_ia(char *buf, size_t bsz, const char *fmt, +static ssize_t printfrr_ia(struct fbuf *buf, const char **fmt, int prec, const void *ptr) { const struct ipaddr *ipa = ptr; + char cbuf[INET6_ADDRSTRLEN]; - if (ipa) - ipaddr2str(ipa, buf, bsz); - else - strlcpy(buf, "NULL", bsz); + if (!ipa) + return bputs(buf, "NULL"); - return 2; + ipaddr2str(ipa, cbuf, sizeof(cbuf)); + return bputs(buf, cbuf); } printfrr_ext_autoreg_p("I4", printfrr_i4) -static ssize_t printfrr_i4(char *buf, size_t bsz, const char *fmt, +static ssize_t printfrr_i4(struct fbuf *buf, const char **fmt, int prec, const void *ptr) { - if (ptr) - inet_ntop(AF_INET, ptr, buf, bsz); - else - strlcpy(buf, "NULL", bsz); + char cbuf[INET_ADDRSTRLEN]; + + if (!ptr) + return bputs(buf, "NULL"); - return 2; + inet_ntop(AF_INET, ptr, cbuf, sizeof(cbuf)); + return bputs(buf, cbuf); } printfrr_ext_autoreg_p("I6", printfrr_i6) -static ssize_t printfrr_i6(char *buf, size_t bsz, const char *fmt, +static ssize_t printfrr_i6(struct fbuf *buf, const char **fmt, int prec, const void *ptr) { - if (ptr) - inet_ntop(AF_INET6, ptr, buf, bsz); - else - strlcpy(buf, "NULL", bsz); + char cbuf[INET6_ADDRSTRLEN]; + + if (!ptr) + return bputs(buf, "NULL"); - return 2; + inet_ntop(AF_INET6, ptr, cbuf, sizeof(cbuf)); + return bputs(buf, cbuf); } printfrr_ext_autoreg_p("FX", printfrr_pfx) -static ssize_t printfrr_pfx(char *buf, size_t bsz, const char *fmt, +static ssize_t printfrr_pfx(struct fbuf *buf, const char **fmt, int prec, const void *ptr) { - if (ptr) - prefix2str(ptr, buf, bsz); - else - strlcpy(buf, "NULL", bsz); + char cbuf[PREFIX_STRLEN]; + + if (!ptr) + return bputs(buf, "NULL"); - return 2; + prefix2str(ptr, cbuf, sizeof(cbuf)); + return bputs(buf, cbuf); } printfrr_ext_autoreg_p("SG4", printfrr_psg) -static ssize_t printfrr_psg(char *buf, size_t bsz, const char *fmt, +static ssize_t printfrr_psg(struct fbuf *buf, const char **fmt, int prec, const void *ptr) { const struct prefix_sg *sg = ptr; - struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 }; + ssize_t ret = 0; - if (sg) { - if (sg->src.s_addr == INADDR_ANY) - bprintfrr(&fb, "(*,"); - else - bprintfrr(&fb, "(%pI4,", &sg->src); - - if (sg->grp.s_addr == INADDR_ANY) - bprintfrr(&fb, "*)"); - else - bprintfrr(&fb, "%pI4)", &sg->grp); + if (!sg) + return bputs(buf, "NULL"); - fb.pos[0] = '\0'; + if (sg->src.s_addr == INADDR_ANY) + ret += bputs(buf, "(*,"); + else + ret += bprintfrr(buf, "(%pI4,", &sg->src); - } else { - strlcpy(buf, "NULL", bsz); - } + if (sg->grp.s_addr == INADDR_ANY) + ret += bputs(buf, "*)"); + else + ret += bprintfrr(buf, "%pI4)", &sg->grp); - return 3; + return ret; } |