]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xshared: Share print_header() with legacy iptables
authorPhil Sutter <phil@nwl.cc>
Tue, 17 Nov 2020 01:49:32 +0000 (02:49 +0100)
committerPhil Sutter <phil@nwl.cc>
Tue, 23 Nov 2021 14:01:23 +0000 (15:01 +0100)
Legacy iptables fetches the relevant data via libiptc before calling the
shared routine which merely prints data as requested.

Drop the 'basechain' parameter, instead make sure a policy name is
passed only with base chains. Since the function is not shared with
ebtables (which uses a very rudimental header instead), this is safe.

In order to support legacy iptables' checking of iptc_get_references()
return code (printing an error message instead of the reference count),
make refs parameter signed and print the error message if it's negative.

Signed-off-by: Phil Sutter <phil@nwl.cc>
iptables/ip6tables.c
iptables/iptables.c
iptables/nft-arp.c
iptables/nft-bridge.c
iptables/nft-shared.c
iptables/nft-shared.h
iptables/nft.c
iptables/xshared.c
iptables/xshared.h

index 3d304d441c10a234021760868e15c11524b8e8ff..5a64566eecd2a138989db4b1fa121c48e04aacac 100644 (file)
@@ -233,56 +233,6 @@ static int is_exthdr(uint16_t proto)
                proto == IPPROTO_DSTOPTS);
 }
 
-static void
-print_header(unsigned int format, const char *chain, struct xtc_handle *handle)
-{
-       struct xt_counters counters;
-       const char *pol = ip6tc_get_policy(chain, &counters, handle);
-       printf("Chain %s", chain);
-       if (pol) {
-               printf(" (policy %s", pol);
-               if (!(format & FMT_NOCOUNTS)) {
-                       fputc(' ', stdout);
-                       xtables_print_num(counters.pcnt, (format|FMT_NOTABLE));
-                       fputs("packets, ", stdout);
-                       xtables_print_num(counters.bcnt, (format|FMT_NOTABLE));
-                       fputs("bytes", stdout);
-               }
-               printf(")\n");
-       } else {
-               unsigned int refs;
-               if (!ip6tc_get_references(&refs, chain, handle))
-                       printf(" (ERROR obtaining refs)\n");
-               else
-                       printf(" (%u references)\n", refs);
-       }
-
-       if (format & FMT_LINENUMBERS)
-               printf(FMT("%-4s ", "%s "), "num");
-       if (!(format & FMT_NOCOUNTS)) {
-               if (format & FMT_KILOMEGAGIGA) {
-                       printf(FMT("%5s ","%s "), "pkts");
-                       printf(FMT("%5s ","%s "), "bytes");
-               } else {
-                       printf(FMT("%8s ","%s "), "pkts");
-                       printf(FMT("%10s ","%s "), "bytes");
-               }
-       }
-       if (!(format & FMT_NOTARGET))
-               printf(FMT("%-9s ","%s "), "target");
-       fputs(" prot ", stdout);
-       if (format & FMT_OPTIONS)
-               fputs("opt", stdout);
-       if (format & FMT_VIA) {
-               printf(FMT(" %-6s ","%s "), "in");
-               printf(FMT("%-6s ","%s "), "out");
-       }
-       printf(FMT(" %-19s ","%s "), "source");
-       printf(FMT(" %-19s "," %s "), "destination");
-       printf("\n");
-}
-
-
 static int
 print_match(const struct xt_entry_match *m,
            const struct ip6t_ip6 *ip,
@@ -662,8 +612,18 @@ list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
 
                if (found) printf("\n");
 
-               if (!rulenum)
-                   print_header(format, this, handle);
+               if (!rulenum) {
+                       struct xt_counters counters;
+                       unsigned int urefs;
+                       const char *pol;
+                       int refs = - 1;
+
+                       pol = ip6tc_get_policy(this, &counters, handle);
+                       if (!pol && ip6tc_get_references(&urefs, this, handle))
+                               refs = urefs;
+
+                       print_header(format, this, pol, &counters, refs, 0);
+               }
                i = ip6tc_first_rule(this, handle);
 
                num = 0;
index 12a5423ec271d4d12a0b72444694f43c89b445d2..ac51c612d92f24e65dc5a36eeed103071aab4de2 100644 (file)
@@ -224,56 +224,6 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...)
 /* Christophe Burki wants `-p 6' to imply `-m tcp'.  */
 
 
-static void
-print_header(unsigned int format, const char *chain, struct xtc_handle *handle)
-{
-       struct xt_counters counters;
-       const char *pol = iptc_get_policy(chain, &counters, handle);
-       printf("Chain %s", chain);
-       if (pol) {
-               printf(" (policy %s", pol);
-               if (!(format & FMT_NOCOUNTS)) {
-                       fputc(' ', stdout);
-                       xtables_print_num(counters.pcnt, (format|FMT_NOTABLE));
-                       fputs("packets, ", stdout);
-                       xtables_print_num(counters.bcnt, (format|FMT_NOTABLE));
-                       fputs("bytes", stdout);
-               }
-               printf(")\n");
-       } else {
-               unsigned int refs;
-               if (!iptc_get_references(&refs, chain, handle))
-                       printf(" (ERROR obtaining refs)\n");
-               else
-                       printf(" (%u references)\n", refs);
-       }
-
-       if (format & FMT_LINENUMBERS)
-               printf(FMT("%-4s ", "%s "), "num");
-       if (!(format & FMT_NOCOUNTS)) {
-               if (format & FMT_KILOMEGAGIGA) {
-                       printf(FMT("%5s ","%s "), "pkts");
-                       printf(FMT("%5s ","%s "), "bytes");
-               } else {
-                       printf(FMT("%8s ","%s "), "pkts");
-                       printf(FMT("%10s ","%s "), "bytes");
-               }
-       }
-       if (!(format & FMT_NOTARGET))
-               printf(FMT("%-9s ","%s "), "target");
-       fputs(" prot ", stdout);
-       if (format & FMT_OPTIONS)
-               fputs("opt", stdout);
-       if (format & FMT_VIA) {
-               printf(FMT(" %-6s ","%s "), "in");
-               printf(FMT("%-6s ","%s "), "out");
-       }
-       printf(FMT(" %-19s ","%s "), "source");
-       printf(FMT(" %-19s "," %s "), "destination");
-       printf("\n");
-}
-
-
 static int
 print_match(const struct xt_entry_match *m,
            const struct ipt_ip *ip,
@@ -652,8 +602,18 @@ list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
 
                if (found) printf("\n");
 
-               if (!rulenum)
-                       print_header(format, this, handle);
+               if (!rulenum) {
+                       struct xt_counters counters;
+                       unsigned int urefs;
+                       const char *pol;
+                       int refs = -1;
+
+                       pol = iptc_get_policy(this, &counters, handle);
+                       if (!pol && iptc_get_references(&urefs, this, handle))
+                               refs = urefs;
+
+                       print_header(format, this, pol, &counters, refs, 0);
+               }
                i = iptc_first_rule(this, handle);
 
                num = 0;
index b7536e61a255fad343185a7107a55f6f9999921a..b211a30937db3376437f42b748067ae67a4ce790 100644 (file)
@@ -308,11 +308,10 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 static void nft_arp_print_header(unsigned int format, const char *chain,
                                 const char *pol,
                                 const struct xt_counters *counters,
-                                bool basechain, uint32_t refs,
-                                uint32_t entries)
+                                int refs, uint32_t entries)
 {
        printf("Chain %s", chain);
-       if (basechain && pol) {
+       if (pol) {
                printf(" (policy %s", pol);
                if (!(format & FMT_NOCOUNTS)) {
                        fputc(' ', stdout);
@@ -323,7 +322,7 @@ static void nft_arp_print_header(unsigned int format, const char *chain,
                }
                printf(")\n");
        } else {
-               printf(" (%u references)\n", refs);
+               printf(" (%d references)\n", refs);
        }
 }
 
index cc2a48dbf7741453c272992d2a62d83c7df6e029..5cde302c4f189621284f8b6127f935bf37034f16 100644 (file)
@@ -534,7 +534,7 @@ static void nft_bridge_print_table_header(const char *tablename)
 static void nft_bridge_print_header(unsigned int format, const char *chain,
                                    const char *pol,
                                    const struct xt_counters *counters,
-                                   bool basechain, uint32_t refs, uint32_t entries)
+                                   int refs, uint32_t entries)
 {
        printf("Bridge chain: %s, entries: %u, policy: %s\n",
               chain, entries, pol ?: "RETURN");
index eb0070075d9eb8e7e54f9fb129884db3ea4454ac..a6a79c8cda084e0abaa4d0828660ba4736d67403 100644 (file)
@@ -714,50 +714,6 @@ void nft_clear_iptables_command_state(struct iptables_command_state *cs)
        }
 }
 
-void print_header(unsigned int format, const char *chain, const char *pol,
-                 const struct xt_counters *counters, bool basechain,
-                 uint32_t refs, uint32_t entries)
-{
-       printf("Chain %s", chain);
-       if (basechain) {
-               printf(" (policy %s", pol);
-               if (!(format & FMT_NOCOUNTS)) {
-                       fputc(' ', stdout);
-                       xtables_print_num(counters->pcnt, (format|FMT_NOTABLE));
-                       fputs("packets, ", stdout);
-                       xtables_print_num(counters->bcnt, (format|FMT_NOTABLE));
-                       fputs("bytes", stdout);
-               }
-               printf(")\n");
-       } else {
-               printf(" (%u references)\n", refs);
-       }
-
-       if (format & FMT_LINENUMBERS)
-               printf(FMT("%-4s ", "%s "), "num");
-       if (!(format & FMT_NOCOUNTS)) {
-               if (format & FMT_KILOMEGAGIGA) {
-                       printf(FMT("%5s ","%s "), "pkts");
-                       printf(FMT("%5s ","%s "), "bytes");
-               } else {
-                       printf(FMT("%8s ","%s "), "pkts");
-                       printf(FMT("%10s ","%s "), "bytes");
-               }
-       }
-       if (!(format & FMT_NOTARGET))
-               printf(FMT("%-9s ","%s "), "target");
-       fputs(" prot ", stdout);
-       if (format & FMT_OPTIONS)
-               fputs("opt", stdout);
-       if (format & FMT_VIA) {
-               printf(FMT(" %-6s ","%s "), "in");
-               printf(FMT("%-6s ","%s "), "out");
-       }
-       printf(FMT(" %-19s ","%s "), "source");
-       printf(FMT(" %-19s "," %s "), "destination");
-       printf("\n");
-}
-
 void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy)
 {
        const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
index e18df20d9fc380869d60bb792cd26649a337b39b..de684374ef9e062a3b61d34855f73ecdb2ae5f4f 100644 (file)
@@ -94,8 +94,8 @@ struct nft_family_ops {
        void (*print_table_header)(const char *tablename);
        void (*print_header)(unsigned int format, const char *chain,
                             const char *pol,
-                            const struct xt_counters *counters, bool basechain,
-                            uint32_t refs, uint32_t entries);
+                            const struct xt_counters *counters,
+                            int refs, uint32_t entries);
        void (*print_rule)(struct nft_handle *h, struct nftnl_rule *r,
                           unsigned int num, unsigned int format);
        void (*save_rule)(const void *data, unsigned int format);
@@ -164,9 +164,6 @@ void nft_rule_to_iptables_command_state(struct nft_handle *h,
                                        const struct nftnl_rule *r,
                                        struct iptables_command_state *cs);
 void nft_clear_iptables_command_state(struct iptables_command_state *cs);
-void print_header(unsigned int format, const char *chain, const char *pol,
-                 const struct xt_counters *counters, bool basechain,
-                 uint32_t refs, uint32_t entries);
 void print_matches_and_target(struct iptables_command_state *cs,
                              unsigned int format);
 void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy);
index 282d417f3bc85341b1a01a5546fb301fa5da05cb..887c735b3f6e65404c5970e4c268fccde7b510d9 100644 (file)
@@ -2398,7 +2398,6 @@ static void __nft_print_header(struct nft_handle *h,
 {
        struct nftnl_chain *c = nc->nftnl;
        const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
-       bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM);
        uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE);
        uint32_t entries = nft_rule_count(h, c);
        struct xt_counters ctrs = {
@@ -2407,11 +2406,12 @@ static void __nft_print_header(struct nft_handle *h,
        };
        const char *pname = NULL;
 
-       if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY))
+       if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM) &&
+           nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY))
                pname = policy_name[nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY)];
 
        h->ops->print_header(format, chain_name, pname,
-                       &ctrs, basechain, refs - entries, entries);
+                            &ctrs, refs - entries, entries);
 }
 
 struct nft_rule_list_cb_data {
index e8c8939cf8e3e65d9a1e561d79bb447426917992..37ea71068b69c92d1daeadb033d6321984f96109 100644 (file)
@@ -547,6 +547,52 @@ void debug_print_argv(struct argv_store *store)
 }
 #endif
 
+void print_header(unsigned int format, const char *chain, const char *pol,
+                 const struct xt_counters *counters,
+                 int refs, uint32_t entries)
+{
+       printf("Chain %s", chain);
+       if (pol) {
+               printf(" (policy %s", pol);
+               if (!(format & FMT_NOCOUNTS)) {
+                       fputc(' ', stdout);
+                       xtables_print_num(counters->pcnt, (format|FMT_NOTABLE));
+                       fputs("packets, ", stdout);
+                       xtables_print_num(counters->bcnt, (format|FMT_NOTABLE));
+                       fputs("bytes", stdout);
+               }
+               printf(")\n");
+       } else if (refs < 0) {
+               printf(" (ERROR obtaining refs)\n");
+       } else {
+               printf(" (%d references)\n", refs);
+       }
+
+       if (format & FMT_LINENUMBERS)
+               printf(FMT("%-4s ", "%s "), "num");
+       if (!(format & FMT_NOCOUNTS)) {
+               if (format & FMT_KILOMEGAGIGA) {
+                       printf(FMT("%5s ","%s "), "pkts");
+                       printf(FMT("%5s ","%s "), "bytes");
+               } else {
+                       printf(FMT("%8s ","%s "), "pkts");
+                       printf(FMT("%10s ","%s "), "bytes");
+               }
+       }
+       if (!(format & FMT_NOTARGET))
+               printf(FMT("%-9s ","%s "), "target");
+       fputs(" prot ", stdout);
+       if (format & FMT_OPTIONS)
+               fputs("opt", stdout);
+       if (format & FMT_VIA) {
+               printf(FMT(" %-6s ","%s "), "in");
+               printf(FMT("%-6s ","%s "), "out");
+       }
+       printf(FMT(" %-19s ","%s "), "source");
+       printf(FMT(" %-19s "," %s "), "destination");
+       printf("\n");
+}
+
 const char *ipv4_addr_to_string(const struct in_addr *addr,
                                const struct in_addr *mask,
                                unsigned int format)
index 48f314cac8f45c1be937f577047f5356e58e9aa4..757940090dd69875e3e69c3290d1dd7a24efe1cf 100644 (file)
@@ -220,6 +220,9 @@ void debug_print_argv(struct argv_store *store);
 const char *ipv4_addr_to_string(const struct in_addr *addr,
                                const struct in_addr *mask,
                                unsigned int format);
+void print_header(unsigned int format, const char *chain, const char *pol,
+                 const struct xt_counters *counters,
+                 int refs, uint32_t entries);
 void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
 void save_ipv4_addr(char letter, const struct in_addr *addr,
                    const struct in_addr *mask, int invert);