From: Phil Sutter <phil@nwl.cc>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: [iptables PATCH v2 05/17] nft: Add family ops callbacks wrapping different nft_cmd_* functions
Date: Thu, 30 Sep 2021 16:04:07 +0200 [thread overview]
Message-ID: <20210930140419.6170-6-phil@nwl.cc> (raw)
In-Reply-To: <20210930140419.6170-1-phil@nwl.cc>
Commands supporting multiple source/destination addresses need to
iterate over them and call the respective nft_cmd_* function multiple
times. These loops are family-specific though as each family uses a
different data structure within struct iptables_command_state to store
the addresses.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-ipv4.c | 93 +++++++++++++++++++++
iptables/nft-ipv6.c | 104 +++++++++++++++++++++++
iptables/nft-shared.h | 18 ++++
iptables/xtables.c | 190 +++---------------------------------------
4 files changed, 228 insertions(+), 177 deletions(-)
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 34f94bd8cc24a..febd7673af4f8 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -468,6 +468,95 @@ static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl)
return ret;
}
+static int
+nft_ipv4_add_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose,
+ bool append, int rulenum)
+{
+ unsigned int i, j;
+ int ret = 1;
+
+ for (i = 0; i < args->s.naddrs; i++) {
+ cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
+ cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
+ for (j = 0; j < args->d.naddrs; j++) {
+ cs->fw.ip.dst.s_addr = args->d.addr.v4[j].s_addr;
+ cs->fw.ip.dmsk.s_addr = args->d.mask.v4[j].s_addr;
+
+ if (append) {
+ ret = nft_cmd_rule_append(h, chain, table,
+ cs, NULL, verbose);
+ } else {
+ ret = nft_cmd_rule_insert(h, chain, table,
+ cs, rulenum, verbose);
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int
+nft_ipv4_delete_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose)
+{
+ unsigned int i, j;
+ int ret = 1;
+
+ for (i = 0; i < args->s.naddrs; i++) {
+ cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
+ cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
+ for (j = 0; j < args->d.naddrs; j++) {
+ cs->fw.ip.dst.s_addr = args->d.addr.v4[j].s_addr;
+ cs->fw.ip.dmsk.s_addr = args->d.mask.v4[j].s_addr;
+ ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
+ }
+ }
+
+ return ret;
+}
+
+static int
+nft_ipv4_check_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose)
+{
+ unsigned int i, j;
+ int ret = 1;
+
+ for (i = 0; i < args->s.naddrs; i++) {
+ cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
+ cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
+ for (j = 0; j < args->d.naddrs; j++) {
+ cs->fw.ip.dst.s_addr = args->d.addr.v4[j].s_addr;
+ cs->fw.ip.dmsk.s_addr = args->d.mask.v4[j].s_addr;
+ ret = nft_cmd_rule_check(h, chain, table, cs, verbose);
+ }
+ }
+
+ return ret;
+}
+
+static int
+nft_ipv4_replace_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose,
+ int rulenum)
+{
+ cs->fw.ip.src.s_addr = args->s.addr.v4->s_addr;
+ cs->fw.ip.dst.s_addr = args->d.addr.v4->s_addr;
+ cs->fw.ip.smsk.s_addr = args->s.mask.v4->s_addr;
+ cs->fw.ip.dmsk.s_addr = args->d.mask.v4->s_addr;
+
+ return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
+}
+
struct nft_family_ops nft_family_ops_ipv4 = {
.add = nft_ipv4_add,
.is_same = nft_ipv4_is_same,
@@ -484,4 +573,8 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = nft_clear_iptables_command_state,
.xlate = nft_ipv4_xlate,
+ .add_entry = nft_ipv4_add_entry,
+ .delete_entry = nft_ipv4_delete_entry,
+ .check_entry = nft_ipv4_check_entry,
+ .replace_entry = nft_ipv4_replace_entry,
};
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index d9c9400ad7dc3..f0e64bbd4ab23 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -410,6 +410,106 @@ static int nft_ipv6_xlate(const void *data, struct xt_xlate *xl)
return ret;
}
+static int
+nft_ipv6_add_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose,
+ bool append, int rulenum)
+{
+ unsigned int i, j;
+ int ret = 1;
+
+ for (i = 0; i < args->s.naddrs; i++) {
+ memcpy(&cs->fw6.ipv6.src,
+ &args->s.addr.v6[i], sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.smsk,
+ &args->s.mask.v6[i], sizeof(struct in6_addr));
+ for (j = 0; j < args->d.naddrs; j++) {
+ memcpy(&cs->fw6.ipv6.dst,
+ &args->d.addr.v6[j], sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.dmsk,
+ &args->d.mask.v6[j], sizeof(struct in6_addr));
+ if (append) {
+ ret = nft_cmd_rule_append(h, chain, table,
+ cs, NULL, verbose);
+ } else {
+ ret = nft_cmd_rule_insert(h, chain, table,
+ cs, rulenum, verbose);
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int
+nft_ipv6_delete_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose)
+{
+ unsigned int i, j;
+ int ret = 1;
+
+ for (i = 0; i < args->s.naddrs; i++) {
+ memcpy(&cs->fw6.ipv6.src,
+ &args->s.addr.v6[i], sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.smsk,
+ &args->s.mask.v6[i], sizeof(struct in6_addr));
+ for (j = 0; j < args->d.naddrs; j++) {
+ memcpy(&cs->fw6.ipv6.dst,
+ &args->d.addr.v6[j], sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.dmsk,
+ &args->d.mask.v6[j], sizeof(struct in6_addr));
+ ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
+ }
+ }
+
+ return ret;
+}
+
+static int
+nft_ipv6_check_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose)
+{
+ unsigned int i, j;
+ int ret = 1;
+
+ for (i = 0; i < args->s.naddrs; i++) {
+ memcpy(&cs->fw6.ipv6.src,
+ &args->s.addr.v6[i], sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.smsk,
+ &args->s.mask.v6[i], sizeof(struct in6_addr));
+ for (j = 0; j < args->d.naddrs; j++) {
+ memcpy(&cs->fw6.ipv6.dst,
+ &args->d.addr.v6[j], sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.dmsk,
+ &args->d.mask.v6[j], sizeof(struct in6_addr));
+ ret = nft_cmd_rule_check(h, chain, table, cs, verbose);
+ }
+ }
+
+ return ret;
+}
+
+static int
+nft_ipv6_replace_entry(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose,
+ int rulenum)
+{
+ memcpy(&cs->fw6.ipv6.src, args->s.addr.v6, sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.dst, args->d.addr.v6, sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.smsk, args->s.mask.v6, sizeof(struct in6_addr));
+ memcpy(&cs->fw6.ipv6.dmsk, args->d.mask.v6, sizeof(struct in6_addr));
+
+ return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
+}
+
struct nft_family_ops nft_family_ops_ipv6 = {
.add = nft_ipv6_add,
.is_same = nft_ipv6_is_same,
@@ -426,4 +526,8 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = nft_clear_iptables_command_state,
.xlate = nft_ipv6_xlate,
+ .add_entry = nft_ipv6_add_entry,
+ .delete_entry = nft_ipv6_delete_entry,
+ .check_entry = nft_ipv6_check_entry,
+ .replace_entry = nft_ipv6_replace_entry,
};
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 44ad0811f4081..cb1c3fffe63b4 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -111,6 +111,24 @@ struct nft_family_ops {
struct iptables_command_state *cs);
void (*clear_cs)(struct iptables_command_state *cs);
int (*xlate)(const void *data, struct xt_xlate *xl);
+ int (*add_entry)(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose,
+ bool append, int rulenum);
+ int (*delete_entry)(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose);
+ int (*check_entry)(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose);
+ int (*replace_entry)(struct nft_handle *h,
+ const char *chain, const char *table,
+ struct iptables_command_state *cs,
+ struct xtables_args *args, bool verbose,
+ int rulenum);
};
void add_meta(struct nftnl_rule *r, uint32_t key);
diff --git a/iptables/xtables.c b/iptables/xtables.c
index f45e36086dcb8..9abfc8f8d7f32 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -223,168 +223,6 @@ xtables_exit_error(enum xtables_exittype status, const char *msg, ...)
/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
-static int
-add_entry(const char *chain,
- const char *table,
- struct iptables_command_state *cs,
- int rulenum, int family,
- const struct addr_mask s,
- const struct addr_mask d,
- bool verbose, struct nft_handle *h, bool append)
-{
- unsigned int i, j;
- int ret = 1;
-
- for (i = 0; i < s.naddrs; i++) {
- if (family == AF_INET) {
- cs->fw.ip.src.s_addr = s.addr.v4[i].s_addr;
- cs->fw.ip.smsk.s_addr = s.mask.v4[i].s_addr;
- for (j = 0; j < d.naddrs; j++) {
- cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
- cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
-
- if (append) {
- ret = nft_cmd_rule_append(h, chain, table,
- cs, NULL,
- verbose);
- } else {
- ret = nft_cmd_rule_insert(h, chain, table,
- cs, rulenum,
- verbose);
- }
- }
- } else if (family == AF_INET6) {
- memcpy(&cs->fw6.ipv6.src,
- &s.addr.v6[i], sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.smsk,
- &s.mask.v6[i], sizeof(struct in6_addr));
- for (j = 0; j < d.naddrs; j++) {
- memcpy(&cs->fw6.ipv6.dst,
- &d.addr.v6[j], sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.dmsk,
- &d.mask.v6[j], sizeof(struct in6_addr));
- if (append) {
- ret = nft_cmd_rule_append(h, chain, table,
- cs, NULL,
- verbose);
- } else {
- ret = nft_cmd_rule_insert(h, chain, table,
- cs, rulenum,
- verbose);
- }
- }
- }
- }
-
- return ret;
-}
-
-static int
-replace_entry(const char *chain, const char *table,
- struct iptables_command_state *cs,
- unsigned int rulenum,
- int family,
- const struct addr_mask s,
- const struct addr_mask d,
- bool verbose, struct nft_handle *h)
-{
- if (family == AF_INET) {
- cs->fw.ip.src.s_addr = s.addr.v4->s_addr;
- cs->fw.ip.dst.s_addr = d.addr.v4->s_addr;
- cs->fw.ip.smsk.s_addr = s.mask.v4->s_addr;
- cs->fw.ip.dmsk.s_addr = d.mask.v4->s_addr;
- } else if (family == AF_INET6) {
- memcpy(&cs->fw6.ipv6.src, s.addr.v6, sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.dst, d.addr.v6, sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.smsk, s.mask.v6, sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.dmsk, d.mask.v6, sizeof(struct in6_addr));
- } else
- return 1;
-
- return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
-}
-
-static int
-delete_entry(const char *chain, const char *table,
- struct iptables_command_state *cs,
- int family,
- const struct addr_mask s,
- const struct addr_mask d,
- bool verbose,
- struct nft_handle *h)
-{
- unsigned int i, j;
- int ret = 1;
-
- for (i = 0; i < s.naddrs; i++) {
- if (family == AF_INET) {
- cs->fw.ip.src.s_addr = s.addr.v4[i].s_addr;
- cs->fw.ip.smsk.s_addr = s.mask.v4[i].s_addr;
- for (j = 0; j < d.naddrs; j++) {
- cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
- cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
- ret = nft_cmd_rule_delete(h, chain,
- table, cs, verbose);
- }
- } else if (family == AF_INET6) {
- memcpy(&cs->fw6.ipv6.src,
- &s.addr.v6[i], sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.smsk,
- &s.mask.v6[i], sizeof(struct in6_addr));
- for (j = 0; j < d.naddrs; j++) {
- memcpy(&cs->fw6.ipv6.dst,
- &d.addr.v6[j], sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.dmsk,
- &d.mask.v6[j], sizeof(struct in6_addr));
- ret = nft_cmd_rule_delete(h, chain,
- table, cs, verbose);
- }
- }
- }
-
- return ret;
-}
-
-static int
-check_entry(const char *chain, const char *table,
- struct iptables_command_state *cs,
- int family,
- const struct addr_mask s,
- const struct addr_mask d,
- bool verbose, struct nft_handle *h)
-{
- unsigned int i, j;
- int ret = 1;
-
- for (i = 0; i < s.naddrs; i++) {
- if (family == AF_INET) {
- cs->fw.ip.src.s_addr = s.addr.v4[i].s_addr;
- cs->fw.ip.smsk.s_addr = s.mask.v4[i].s_addr;
- for (j = 0; j < d.naddrs; j++) {
- cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
- cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
- ret = nft_cmd_rule_check(h, chain,
- table, cs, verbose);
- }
- } else if (family == AF_INET6) {
- memcpy(&cs->fw6.ipv6.src,
- &s.addr.v6[i], sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.smsk,
- &s.mask.v6[i], sizeof(struct in6_addr));
- for (j = 0; j < d.naddrs; j++) {
- memcpy(&cs->fw6.ipv6.dst,
- &d.addr.v6[j], sizeof(struct in6_addr));
- memcpy(&cs->fw6.ipv6.dmsk,
- &d.mask.v6[j], sizeof(struct in6_addr));
- ret = nft_cmd_rule_check(h, chain,
- table, cs, verbose);
- }
- }
- }
-
- return ret;
-}
-
static int
list_entries(struct nft_handle *h, const char *chain, const char *table,
int rulenum, int verbose, int numeric, int expanded,
@@ -923,33 +761,31 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
switch (p.command) {
case CMD_APPEND:
- ret = add_entry(p.chain, p.table, &cs, 0, h->family,
- args.s, args.d,
- cs.options & OPT_VERBOSE, h, true);
+ ret = h->ops->add_entry(h, p.chain, p.table, &cs, &args,
+ cs.options & OPT_VERBOSE, true,
+ p.rulenum - 1);
break;
case CMD_DELETE:
- ret = delete_entry(p.chain, p.table, &cs, h->family,
- args.s, args.d,
- cs.options & OPT_VERBOSE, h);
+ ret = h->ops->delete_entry(h, p.chain, p.table, &cs, &args,
+ cs.options & OPT_VERBOSE);
break;
case CMD_DELETE_NUM:
ret = nft_cmd_rule_delete_num(h, p.chain, p.table,
p.rulenum - 1, p.verbose);
break;
case CMD_CHECK:
- ret = check_entry(p.chain, p.table, &cs, h->family,
- args.s, args.d,
- cs.options & OPT_VERBOSE, h);
+ ret = h->ops->check_entry(h, p.chain, p.table, &cs, &args,
+ cs.options & OPT_VERBOSE);
break;
case CMD_REPLACE:
- ret = replace_entry(p.chain, p.table, &cs, p.rulenum - 1,
- h->family, args.s, args.d,
- cs.options & OPT_VERBOSE, h);
+ ret = h->ops->replace_entry(h, p.chain, p.table, &cs, &args,
+ cs.options & OPT_VERBOSE,
+ p.rulenum - 1);
break;
case CMD_INSERT:
- ret = add_entry(p.chain, p.table, &cs, p.rulenum - 1,
- h->family, args.s, args.d,
- cs.options&OPT_VERBOSE, h, false);
+ ret = h->ops->add_entry(h, p.chain, p.table, &cs, &args,
+ cs.options & OPT_VERBOSE, false,
+ p.rulenum - 1);
break;
case CMD_FLUSH:
ret = nft_cmd_rule_flush(h, p.chain, p.table,
--
2.33.0
next prev parent reply other threads:[~2021-09-30 14:05 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-30 14:04 [iptables PATCH v2 00/17] Eliminate dedicated arptables-nft parser Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 01/17] nft: Introduce builtin_tables_lookup() Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 02/17] xshared: Store optstring in xtables_globals Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 03/17] nft-shared: Introduce init_cs family ops callback Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 04/17] xtables: Simplify addr_mask freeing Phil Sutter
2021-09-30 14:04 ` Phil Sutter [this message]
2021-09-30 14:04 ` [iptables PATCH v2 06/17] xtables-standalone: Drop version number from init errors Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 07/17] libxtables: Introduce xtables_globals print_help callback Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 08/17] arptables: Use standard data structures when parsing Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 09/17] nft-arp: Introduce post_parse callback Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 10/17] nft-shared: Make nft_check_xt_legacy() family agnostic Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 11/17] xtables: Derive xtables_globals from family Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 12/17] nft: Merge xtables-arp-standalone.c into xtables-standalone.c Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 13/17] xtables: arptables doesn't warn about empty interface Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 14/17] xtables: arptables accepts but ignores '-m' Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 15/17] xtables: arptables ignores wrong -t values Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 16/17] xtables: Support '!' betwen option and argument Phil Sutter
2021-09-30 14:04 ` [iptables PATCH v2 17/17] nft: Store maximum allowed chain name length in family ops Phil Sutter
2021-10-14 20:56 ` [iptables PATCH v2 00/17] Eliminate dedicated arptables-nft parser Pablo Neira Ayuso
2021-10-15 11:01 ` Phil Sutter
2021-10-15 11:25 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210930140419.6170-6-phil@nwl.cc \
--to=phil@nwl.cc \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).