]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft: family_ops: Pass nft_handle to 'rule_to_cs' callback
authorPhil Sutter <phil@nwl.cc>
Tue, 20 Aug 2019 19:41:12 +0000 (21:41 +0200)
committerPhil Sutter <phil@nwl.cc>
Mon, 25 Nov 2019 22:30:56 +0000 (23:30 +0100)
This is the actual callback used to parse nftables rules. Pass
nft_handle to it so it can access the cache (and possible sets therein).

Having to pass nft_handle to nft_rule_print_save() allows to simplify it
a bit since no family ops lookup has to be done anymore.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft-arp.c
iptables/nft-bridge.c
iptables/nft-ipv4.c
iptables/nft-ipv6.c
iptables/nft-shared.c
iptables/nft-shared.h
iptables/nft.c
iptables/nft.h
iptables/xtables-monitor.c
iptables/xtables-save.c

index da22c12d34a7b5a7214486cccbd0ee02cb0ed4f5..d4a86610ec2171a0663968d79ff8dd81bc43d1ad 100644 (file)
@@ -590,7 +590,7 @@ nft_arp_print_rule(struct nft_handle *h, struct nftnl_rule *r,
        if (format & FMT_LINENUMBERS)
                printf("%u ", num);
 
-       nft_rule_to_iptables_command_state(r, &cs);
+       nft_rule_to_iptables_command_state(h, r, &cs);
 
        nft_arp_print_rule_details(&cs, format);
        print_matches_and_target(&cs, format);
@@ -641,7 +641,7 @@ static bool nft_arp_rule_find(struct nft_handle *h, struct nftnl_rule *r,
        bool ret = false;
 
        /* Delete by matching rule case */
-       nft_rule_to_iptables_command_state(r, &this);
+       nft_rule_to_iptables_command_state(h, r, &this);
 
        if (!nft_arp_is_same(&cs->arp, &this.arp))
                goto out;
index b0c6c5a4db3cd673c808a98f652781fe5f207f57..20ce92a6d52421f81b376161a414e4f13b41df3b 100644 (file)
@@ -333,11 +333,12 @@ static void nft_bridge_parse_target(struct xtables_target *t, void *data)
        cs->target = t;
 }
 
-static void nft_rule_to_ebtables_command_state(const struct nftnl_rule *r,
+static void nft_rule_to_ebtables_command_state(struct nft_handle *h,
+                                              const struct nftnl_rule *r,
                                               struct iptables_command_state *cs)
 {
        cs->eb.bitmask = EBT_NOPROTO;
-       nft_rule_to_iptables_command_state(r, cs);
+       nft_rule_to_iptables_command_state(h, r, cs);
 }
 
 static void print_iface(const char *option, const char *name, bool invert)
@@ -480,7 +481,7 @@ static void nft_bridge_print_rule(struct nft_handle *h, struct nftnl_rule *r,
        if (format & FMT_LINENUMBERS)
                printf("%d ", num);
 
-       nft_rule_to_ebtables_command_state(r, &cs);
+       nft_rule_to_ebtables_command_state(h, r, &cs);
        nft_bridge_save_rule(&cs, format);
        ebt_cs_clean(&cs);
 }
@@ -544,7 +545,7 @@ static bool nft_bridge_rule_find(struct nft_handle *h, struct nftnl_rule *r,
        struct iptables_command_state this = {};
        bool ret = false;
 
-       nft_rule_to_ebtables_command_state(r, &this);
+       nft_rule_to_ebtables_command_state(h, r, &this);
 
        DEBUGP("comparing with... ");
 
index 98d7f966e3694f19038241ad73e56a140562d159..70634f8fad84d9fa28f33f623c1ac942c65b30f4 100644 (file)
@@ -266,7 +266,7 @@ static void nft_ipv4_print_rule(struct nft_handle *h, struct nftnl_rule *r,
 {
        struct iptables_command_state cs = {};
 
-       nft_rule_to_iptables_command_state(r, &cs);
+       nft_rule_to_iptables_command_state(h, r, &cs);
 
        print_rule_details(&cs, cs.jumpto, cs.fw.ip.flags,
                           cs.fw.ip.invflags, cs.fw.ip.proto, num, format);
index 56236bff03c2b84ce2a2ab054ffd4eabcbcac599..d01491bfdb689572e14bea876b939332d401c39b 100644 (file)
@@ -192,7 +192,7 @@ static void nft_ipv6_print_rule(struct nft_handle *h, struct nftnl_rule *r,
 {
        struct iptables_command_state cs = {};
 
-       nft_rule_to_iptables_command_state(r, &cs);
+       nft_rule_to_iptables_command_state(h, r, &cs);
 
        print_rule_details(&cs, cs.jumpto, cs.fw6.ipv6.flags,
                           cs.fw6.ipv6.invflags, cs.fw6.ipv6.proto,
index b6d85f1af1da9665d4b7f59b67f2c934a18042fc..bdbd3238b28900e0ef404ee121c3efd66b69f0e8 100644 (file)
@@ -591,7 +591,8 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
                ops->parse_match(match, ctx->cs);
 }
 
-void nft_rule_to_iptables_command_state(const struct nftnl_rule *r,
+void nft_rule_to_iptables_command_state(struct nft_handle *h,
+                                       const struct nftnl_rule *r,
                                        struct iptables_command_state *cs)
 {
        struct nftnl_expr_iter *iter;
@@ -987,7 +988,7 @@ bool nft_ipv46_rule_find(struct nft_handle *h, struct nftnl_rule *r, void *data)
        struct iptables_command_state *cs = data, this = {};
        bool ret = false;
 
-       nft_rule_to_iptables_command_state(r, &this);
+       nft_rule_to_iptables_command_state(h, r, &this);
 
        DEBUGP("comparing with... ");
 #ifdef DEBUG_DEL
index 4523dda9410bc36fc39b2f949473f2583252421e..a85d5442c71075b6834451ebb9afab8f71ee39d6 100644 (file)
@@ -101,7 +101,7 @@ struct nft_family_ops {
                           struct xtables_args *args);
        void (*parse_match)(struct xtables_match *m, void *data);
        void (*parse_target)(struct xtables_target *t, void *data);
-       void (*rule_to_cs)(const struct nftnl_rule *r,
+       void (*rule_to_cs)(struct nft_handle *h, const struct nftnl_rule *r,
                           struct iptables_command_state *cs);
        void (*clear_cs)(struct iptables_command_state *cs);
        bool (*rule_find)(struct nft_handle *h, struct nftnl_rule *r,
@@ -138,7 +138,8 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
                unsigned char *outiface_mask, uint8_t *invflags);
 void print_proto(uint16_t proto, int invert);
 void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv);
-void nft_rule_to_iptables_command_state(const struct nftnl_rule *r,
+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,
index 049c3cfa10098b7ff4e09f252497c00c132a2499..36c3bc2d41764446e5366e5f07108ee1b5df93b0 100644 (file)
@@ -351,7 +351,7 @@ static int mnl_append_error(const struct nft_handle *h,
                         nftnl_rule_get_str(o->rule, NFTNL_RULE_CHAIN));
 #if 0
                {
-                       nft_rule_print_save(o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
+                       nft_rule_print_save(h, o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
                }
 #endif
                break;
@@ -1220,16 +1220,14 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
 }
 
 void
-nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type,
-                   unsigned int format)
+nft_rule_print_save(struct nft_handle *h, const struct nftnl_rule *r,
+                   enum nft_rule_print type, unsigned int format)
 {
        const char *chain = nftnl_rule_get_str(r, NFTNL_RULE_CHAIN);
-       int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
        struct iptables_command_state cs = {};
-       struct nft_family_ops *ops;
+       struct nft_family_ops *ops = h->ops;
 
-       ops = nft_family_ops_lookup(family);
-       ops->rule_to_cs(r, &cs);
+       ops->rule_to_cs(h, r, &cs);
 
        if (!(format & (FMT_NOCOUNTS | FMT_C_COUNTS)) && ops->save_counters)
                ops->save_counters(&cs);
@@ -1392,7 +1390,7 @@ static int nft_chain_save_rules(struct nft_handle *h,
 
        r = nftnl_rule_iter_next(iter);
        while (r != NULL) {
-               nft_rule_print_save(r, NFT_RULE_APPEND, format);
+               nft_rule_print_save(h, r, NFT_RULE_APPEND, format);
                r = nftnl_rule_iter_next(iter);
        }
 
@@ -2245,7 +2243,7 @@ static void
 list_save(struct nft_handle *h, struct nftnl_rule *r,
          unsigned int num, unsigned int format)
 {
-       nft_rule_print_save(r, NFT_RULE_APPEND, format);
+       nft_rule_print_save(h, r, NFT_RULE_APPEND, format);
 }
 
 static int __nftnl_rule_list_chain_save(struct nftnl_chain *c, void *data)
@@ -2357,7 +2355,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
                goto error;
        }
 
-       nft_rule_to_iptables_command_state(r, &cs);
+       nft_rule_to_iptables_command_state(h, r, &cs);
 
        cs.counters.pcnt = cs.counters.bcnt = 0;
 
index 94dc72d88b7db87779600dd250ebd38798df76a9..e157b525cffdc0a540fcf731e2c825388db470d3 100644 (file)
@@ -146,8 +146,8 @@ enum nft_rule_print {
        NFT_RULE_DEL,
 };
 
-void nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type,
-                        unsigned int format);
+void nft_rule_print_save(struct nft_handle *h, const struct nftnl_rule *r,
+                        enum nft_rule_print type, unsigned int format);
 
 uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag);
 
index eb80bac81c64525eeaf7e66a849422c3d5585baa..a5245d1422af93ec8a808c78c64a24de7acd54b1 100644 (file)
@@ -11,6 +11,7 @@
 
 #define _GNU_SOURCE
 #include "config.h"
+#include <errno.h>
 #include <stdlib.h>
 #include <time.h>
 #include <string.h>
@@ -41,6 +42,7 @@
 struct cb_arg {
        uint32_t nfproto;
        bool is_event;
+       struct nft_handle *h;
 };
 
 static int table_cb(const struct nlmsghdr *nlh, void *data)
@@ -106,7 +108,7 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data)
        }
 
        printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE));
-       nft_rule_print_save(r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
+       nft_rule_print_save(arg->h, r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
                                                           NFT_RULE_DEL,
                            counters ? 0 : FMT_NOCOUNTS);
 err_free:
@@ -593,7 +595,10 @@ int xtables_monitor_main(int argc, char *argv[])
        struct mnl_socket *nl;
        char buf[MNL_SOCKET_BUFFER_SIZE];
        uint32_t nfgroup = 0;
-       struct cb_arg cb_arg = {};
+       struct nft_handle h = {};
+       struct cb_arg cb_arg = {
+               .h = &h,
+       };
        int ret, c;
 
        xtables_globals.program_name = "xtables-monitor";
@@ -610,6 +615,14 @@ int xtables_monitor_main(int argc, char *argv[])
        init_extensions4();
 #endif
 
+       if (nft_init(&h, xtables_ipv4)) {
+               fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+                       xtables_globals.program_name,
+                       xtables_globals.program_version,
+                       strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
        opterr = 0;
        while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) {
                switch (c) {
index 44687f998c91a1f3e1ddd705e85ada1e92896f82..3a52f8c3d820991383e905ee90855f07c0c5cd62 100644 (file)
@@ -249,6 +249,9 @@ xtables_save_main(int family, int argc, char *argv[],
                                strerror(errno));
                exit(EXIT_FAILURE);
        }
+       h.ops = nft_family_ops_lookup(h.family);
+       if (!h.ops)
+               xtables_error(PARAMETER_PROBLEM, "Unknown family");
 
        ret = do_output(&h, tablename, &d);
        nft_fini(&h);