From f3b772c10b782196060fe39ca6da142ba75e43d9 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 19 Jul 2018 18:32:05 +0200 Subject: xtables: introduce save_chain callback In preparation for ebtables-save implementation, introduce a callback for convenient per-family formatting of chains in save output. Signed-off-by: Phil Sutter Signed-off-by: Florian Westphal --- iptables/nft-ipv4.c | 1 + iptables/nft-ipv6.c | 1 + iptables/nft-shared.c | 11 +++++++++++ iptables/nft-shared.h | 3 +++ iptables/nft.c | 37 ++++++++++++++----------------------- 5 files changed, 30 insertions(+), 23 deletions(-) (limited to 'iptables') diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c index cbc4be73..0cfe84e1 100644 --- a/iptables/nft-ipv4.c +++ b/iptables/nft-ipv4.c @@ -485,6 +485,7 @@ struct nft_family_ops nft_family_ops_ipv4 = { .print_rule = nft_ipv4_print_rule, .save_rule = nft_ipv4_save_rule, .save_counters = save_counters, + .save_chain = nft_ipv46_save_chain, .proto_parse = nft_ipv4_proto_parse, .post_parse = nft_ipv4_post_parse, .parse_target = nft_ipv46_parse_target, diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index 6aa913ed..a33d4573 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -440,6 +440,7 @@ struct nft_family_ops nft_family_ops_ipv6 = { .print_rule = nft_ipv6_print_rule, .save_rule = nft_ipv6_save_rule, .save_counters = save_counters, + .save_chain = nft_ipv46_save_chain, .proto_parse = nft_ipv6_proto_parse, .post_parse = nft_ipv6_post_parse, .parse_target = nft_ipv46_parse_target, diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 60b539c8..66db7ed1 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -802,6 +803,16 @@ void save_counters(const void *data) (unsigned long long)cs->counters.bcnt); } +void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy) +{ + const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); + uint64_t pkts = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS); + uint64_t bytes = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES); + + printf(":%s %s [%"PRIu64":%"PRIu64"]\n", + chain, policy ?: "-", pkts, bytes); +} + void save_matches_and_target(struct xtables_rule_match *m, struct xtables_target *target, const char *jumpto, uint8_t flags, const void *fw) diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 20c19863..882f60e8 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -5,6 +5,7 @@ #include #include +#include #include @@ -95,6 +96,7 @@ struct nft_family_ops { unsigned int format); void (*save_rule)(const void *data, unsigned int format); void (*save_counters)(const void *data); + void (*save_chain)(const struct nftnl_chain *c, const char *policy); void (*proto_parse)(struct iptables_command_state *cs, struct xtables_args *args); void (*post_parse)(int command, struct iptables_command_state *cs, @@ -166,6 +168,7 @@ void save_rule_details(const struct iptables_command_state *cs, const char *outiface, unsigned const char *outiface_mask); void save_counters(const void *data); +void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy); void save_matches_and_target(struct xtables_rule_match *m, struct xtables_target *target, const char *jumpto, diff --git a/iptables/nft.c b/iptables/nft.c index 7ce7fd2f..9f650f5a 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1276,32 +1276,15 @@ static const char *policy_name[NF_ACCEPT+1] = { [NF_ACCEPT] = "ACCEPT", }; -static void nft_chain_print_save(struct nftnl_chain *c, bool basechain) -{ - const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - uint64_t pkts = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS); - uint64_t bytes = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES); - - /* print chain name */ - if (basechain) { - uint32_t pol = NF_ACCEPT; - - /* no default chain policy? don't crash, display accept */ - if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) - pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - - printf(":%s %s [%"PRIu64":%"PRIu64"]\n", chain, policy_name[pol], - pkts, bytes); - } else - printf(":%s - [%"PRIu64":%"PRIu64"]\n", chain, pkts, bytes); -} - int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table) { struct nftnl_chain_list_iter *iter; + struct nft_family_ops *ops; struct nftnl_chain *c; + ops = nft_family_ops_lookup(h->family); + iter = nftnl_chain_list_iter_create(list); if (iter == NULL) return 0; @@ -1310,13 +1293,21 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, while (c != NULL) { const char *chain_table = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - bool basechain = false; + const char *policy = NULL; if (strcmp(table, chain_table) != 0) goto next; - basechain = nft_chain_builtin(c); - nft_chain_print_save(c, basechain); + if (nft_chain_builtin(c)) { + uint32_t pol = NF_ACCEPT; + + if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) + pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); + policy = policy_name[pol]; + } + + if (ops->save_chain) + ops->save_chain(c, policy); next: c = nftnl_chain_list_iter_next(iter); } -- cgit v1.2.3