New "printfrr()" functionality available in FRR master
Hi all, we've recently merged (https://github.com/FRRouting/frr/pull/4333) new string formatting code which allows printing network/FRR-specific data types more easily. It's inspired by the Linux kernel and works by *appending* "sub-formats" after %p/%d printf specifiers. The idea is to remain compatible with normal %p/%d calling conventions (so compiler warnings keep working), but the code knows more about the pointer/integer that is passed. The idea is that instead of doing: if (debug) { char buf[]; zlog_debug("%s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); } you can do: if (debug) zlog_debug("%pI4", &addr); For example, "%pI4" is used to print a "struct in_addr *" as A.B.C.D, with the inet_ntop() call happening inside of printfrr() instead of separately beforehand. Note that for the compiler this just looks like "%p" and you're passing any random pointer. printfrr knows to interpret the "I4" and print the pointer contents as an IPv4 address instead. This is documented under doc/developer/logging.rst, cf. https://github.com/FRRouting/frr/blob/master/doc/developer/logging.rst Extended formats are registered with "printfrr_ext_autoreg", so you can also grep for that to see what's available. Currently, we have: %pI4 (struct in_addr *) %pI6 (struct in_addr6 *) %pFX (struct prefix *) %pSG4 (struct prefix_sg *) %pNH (struct nexthop *) %pRN (struct route_node *) They aren't put to much use yet, I'm planning to slowly introduce them and simplify existing code. I also expect that we add more printers as needed & we see fit. NB: all the zlog_* and vty_out functions use printfrr internally, so these extension work there. However, if you call snprintf(), you need to change that to snprintfrr()! I also have a work-in-progress gcc plugin that provides additional compiler warnings for these extensions. However, it needs a patched version of the gcc-python wrapper and isn't particularly easy to use, so I'm still pondering how to best integrate that. In any case, this is an extension purely for improved warnings and is not needed at all to use this functionality. Cheers, -David
Hi, On 6/7/19 12:43 PM, David Lamparter wrote:
The idea is that instead of doing:
if (debug) { char buf[]; zlog_debug("%s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); }
you can do:
if (debug) zlog_debug("%pI4", &addr);
For example, "%pI4" is used to print a "struct in_addr *" as A.B.C.D, with the inet_ntop() call happening inside of printfrr() instead of separately beforehand.
It's really cool to see this longstanding idea finally implemented. I think it will make it a lot nicer to write code for FRR, while at the same time allowing the code to be more concise and readable. Great job everyone who made this possible! All Best, Chris
participants (2)
-
Christian Franke -
David Lamparter