[PATCH v3 11/11] fwd: Generalise fwd_rules_info()

David Gibson
2026-04-17T05:05:41Z

fwd_rules_info() is used to print a full table of forwarding rules for
debugging or the like. Currently it has one caller, and uses info() to
dump the messages. However for the upcoming configuration client, we're
going to want to dump the rules in some similar, but not quite identical
ways. For example, at different severity levels, or to stdout instead of
stderr / system log / logfile.

So, generalise fwd_rules_info() to fwd_rules_dump() which takes a printing
function as a parameter. Because we want this to work with "functions"
like info, which is actually a macro, we have to convert fwd_rules_dump()
to a macro as well. We also allow the prefix and suffix for each rule /
line to be provided as a parameter.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
conf.c | 3 ++-
fwd_rule.c | 16 ----------------
fwd_rule.h | 20 +++++++++++++++++++-
3 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/conf.c b/conf.c
index 5aacfe0f..05861072 100644
--- a/conf.c
+++ b/conf.c
@@ -902,7 +902,8 @@ dns6:
dir = "Inbound";

info("%s forwarding rules (%s):", dir, pif_name(i));
- fwd_rules_info(c->fwd[i]->rules, c->fwd[i]->count);
+ fwd_rules_dump(info, c->fwd[i]->rules, c->fwd[i]->count,
+ " ", "");
}
}

diff --git a/fwd_rule.c b/fwd_rule.c
index cb462401..0d2e1531 100644
--- a/fwd_rule.c
+++ b/fwd_rule.c
@@ -124,7 +124,6 @@ const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule)
*/
__attribute__((noinline))
#endif
-/* cppcheck-suppress staticFunction */
const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size)
{
const char *percent = *rule->ifname ? "%" : "";
@@ -158,21 +157,6 @@ const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size)
return dst;
}

-/**
- * fwd_rules_info() - Print forwarding rules for debugging
- * @fwd: Table to print
- */
-void fwd_rules_info(const struct fwd_rule *rules, size_t count)
-{
- unsigned i;
-
- for (i = 0; i < count; i++) {
- char buf[FWD_RULE_STRLEN];
-
- info(" %s", fwd_rule_fmt(&rules[i], buf, sizeof(buf)));
- }
-}
-
/**
* fwd_rule_conflicts() - Test if two rules conflict with each other
* @a, @b: Rules to test
diff --git a/fwd_rule.h b/fwd_rule.h
index f0f4efda..58551382 100644
--- a/fwd_rule.h
+++ b/fwd_rule.h
@@ -97,7 +97,25 @@ void fwd_probe_ephemeral(void);

const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule);
const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size);
-void fwd_rules_info(const struct fwd_rule *rules, size_t count);
void fwd_rule_parse(char optname, const char *optarg, struct fwd_table *fwd);

+/**
+ * fwd_rules_dump() - Dump forwarding rules
+ * @fn: Printing/logging function to call
+ * @rules: Array of rules to dump
+ * @count: Number of rules to dump
+ * @prefix: String to print at the start of each rule
+ * @suffix: String to print at the end of each rule
+ */
+#define fwd_rules_dump(fn, rules, count, prefix, suffix) \
+ do { \
+ unsigned i_; \
+ for (i_ = 0; i_ < (count); i_++) { \
+ char buf_[FWD_RULE_STRLEN]; \
+ fn("%s%s%s", prefix, \
+ fwd_rule_fmt(&(rules)[i_], buf_, sizeof(buf_)), \
+ suffix); \
+ } \
+ } while (0)
+
#endif /* FWD_RULE_H */
--
2.53.0