summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables/Makefile.am2
-rw-r--r--iptables/nft-arp.c55
-rw-r--r--iptables/nft.h3
-rw-r--r--iptables/xtables-arp-standalone.c19
-rw-r--r--iptables/xtables-arp.c39
-rw-r--r--iptables/xtables-multi.h2
-rw-r--r--iptables/xtables-nft-multi.c4
-rw-r--r--iptables/xtables-restore.c26
-rw-r--r--iptables/xtables-save.c39
9 files changed, 146 insertions, 43 deletions
diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index 2cbd5861..d0218ddc 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -81,6 +81,8 @@ x_sbin_links = iptables-nft iptables-nft-restore iptables-nft-save \
iptables-translate ip6tables-translate \
iptables-restore-translate ip6tables-restore-translate \
arptables-nft arptables \
+ arptables-nft-restore arptables-restore \
+ arptables-nft-save arptables-save \
ebtables-nft ebtables \
ebtables-nft-restore ebtables-restore \
ebtables-nft-save ebtables-save \
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index 570a2589..f58109e5 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -436,7 +436,7 @@ static void nft_arp_print_header(unsigned int format, const char *chain,
}
}
-static void nft_arp_print_rule_details(struct arpt_entry *fw,
+static void nft_arp_print_rule_details(const struct arpt_entry *fw,
unsigned int format)
{
char buf[BUFSIZ];
@@ -580,35 +580,48 @@ after_devdst:
}
static void
-nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format)
+__nft_arp_save_rule(const void *data, unsigned int format)
{
- struct iptables_command_state cs = {};
-
- nft_arp_rule_to_cs(r, &cs);
-
- if (format & FMT_LINENUMBERS)
- printf("%u ", num);
+ const struct iptables_command_state *cs = data;
- nft_arp_print_rule_details(&cs.arp, format);
+ nft_arp_print_rule_details(&cs->arp, format);
- if (cs.jumpto != NULL && strcmp(cs.jumpto, "") != 0) {
- printf("-j %s", cs.jumpto);
- } else if (cs.target) {
- printf("-j %s", cs.target->name);
- cs.target->print(&cs.arp, cs.target->t, format & FMT_NUMERIC);
+ if (cs->jumpto != NULL && strcmp(cs->jumpto, "") != 0) {
+ printf("-j %s", cs->jumpto);
+ } else if (cs->target) {
+ printf("-j %s", cs->target->name);
+ cs->target->print(&cs->arp, cs->target->t, format & FMT_NUMERIC);
}
if (!(format & FMT_NOCOUNTS)) {
printf(", pcnt=");
- xtables_print_num(cs.arp.counters.pcnt, format);
+ xtables_print_num(cs->arp.counters.pcnt, format);
printf("-- bcnt=");
- xtables_print_num(cs.arp.counters.bcnt, format);
+ xtables_print_num(cs->arp.counters.bcnt, format);
}
if (!(format & FMT_NONEWLINE))
fputc('\n', stdout);
}
+static void
+nft_arp_save_rule(const void *data, unsigned int format)
+{
+ __nft_arp_save_rule(data, format | FMT_NUMERIC);
+}
+
+static void
+nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format)
+{
+ struct iptables_command_state cs = {};
+
+ if (format & FMT_LINENUMBERS)
+ printf("%u ", num);
+
+ nft_arp_rule_to_cs(r, &cs);
+ __nft_arp_save_rule(&cs, format);
+}
+
static bool nft_arp_is_same(const void *data_a,
const void *data_b)
{
@@ -656,6 +669,13 @@ static bool nft_arp_rule_find(struct nft_family_ops *ops, struct nftnl_rule *r,
return true;
}
+static void nft_arp_save_chain(const struct nftnl_chain *c, const char *policy)
+{
+ const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+
+ printf(":%s %s\n", chain, policy ?: "-");
+}
+
struct nft_family_ops nft_family_ops_arp = {
.add = nft_arp_add,
.is_same = nft_arp_is_same,
@@ -665,8 +685,9 @@ struct nft_family_ops nft_family_ops_arp = {
.parse_immediate = nft_arp_parse_immediate,
.print_header = nft_arp_print_header,
.print_rule = nft_arp_print_rule,
- .save_rule = NULL,
+ .save_rule = nft_arp_save_rule,
.save_counters = NULL,
+ .save_chain = nft_arp_save_chain,
.post_parse = NULL,
.rule_to_cs = nft_arp_rule_to_cs,
.clear_cs = NULL,
diff --git a/iptables/nft.h b/iptables/nft.h
index d16ded09..eb14e908 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -145,7 +145,8 @@ const char *nft_strerror(int err);
/* For xtables.c */
int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
/* For xtables-arptables.c */
-int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table);
+int nft_init_arp(struct nft_handle *h, const char *pname);
+int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
/* For xtables-eb.c */
int nft_init_eb(struct nft_handle *h, const char *pname);
int ebt_get_current_chain(const char *chain);
diff --git a/iptables/xtables-arp-standalone.c b/iptables/xtables-arp-standalone.c
index 6553d28f..eca7bb97 100644
--- a/iptables/xtables-arp-standalone.c
+++ b/iptables/xtables-arp-standalone.c
@@ -47,24 +47,11 @@ int xtables_arp_main(int argc, char *argv[])
{
int ret;
char *table = "filter";
- struct nft_handle h = {
- .family = NFPROTO_ARP,
- };
+ struct nft_handle h;
- arptables_globals.program_name = "arptables";
- ret = xtables_init_all(&arptables_globals, NFPROTO_ARP);
- if (ret < 0) {
- fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
- arptables_globals.program_name,
- arptables_globals.program_version);
- exit(1);
- }
+ nft_init_arp(&h, "arptables");
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensionsa();
-#endif
-
- ret = do_commandarp(&h, argc, argv, &table);
+ ret = do_commandarp(&h, argc, argv, &table, false);
if (ret)
ret = nft_commit(&h);
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index 62282f42..a457ea30 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -928,7 +928,36 @@ delete_entry(const char *chain,
return ret;
}
-int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
+int nft_init_arp(struct nft_handle *h, const char *pname)
+{
+ arptables_globals.program_name = pname;
+ if (xtables_init_all(&arptables_globals, NFPROTO_ARP) < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
+ arptables_globals.program_name,
+ arptables_globals.program_version);
+ exit(1);
+ }
+
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensionsa();
+#endif
+
+ memset(h, 0, sizeof(*h));
+ h->family = NFPROTO_ARP;
+
+ if (nft_init(h, xtables_arp) < 0)
+ xtables_error(OTHER_PROBLEM,
+ "Could not initialize nftables layer.");
+
+ h->ops = nft_family_ops_lookup(h->family);
+ if (h->ops == NULL)
+ xtables_error(PARAMETER_PROBLEM, "Unknown family");
+
+ return 0;
+}
+
+int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
+ bool restore)
{
struct iptables_command_state cs = {
.jumpto = "",
@@ -1356,14 +1385,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
"chain name `%s' too long (must be under %i chars)",
chain, ARPT_FUNCTION_MAXNAMELEN);
- if (nft_init(h, xtables_arp) < 0)
- xtables_error(OTHER_PROBLEM,
- "Could not initialize nftables layer.");
-
- h->ops = nft_family_ops_lookup(h->family);
- if (h->ops == NULL)
- xtables_error(PARAMETER_PROBLEM, "Unknown family");
-
if (command == CMD_APPEND
|| command == CMD_DELETE
|| command == CMD_INSERT
diff --git a/iptables/xtables-multi.h b/iptables/xtables-multi.h
index 84457618..0fedb430 100644
--- a/iptables/xtables-multi.h
+++ b/iptables/xtables-multi.h
@@ -15,6 +15,8 @@ extern int xtables_eb_xlate_main(int, char **);
extern int xtables_ip4_xlate_restore_main(int, char **);
extern int xtables_ip6_xlate_restore_main(int, char **);
extern int xtables_arp_main(int, char **);
+extern int xtables_arp_restore_main(int, char **);
+extern int xtables_arp_save_main(int, char **);
extern int xtables_eb_main(int, char **);
extern int xtables_eb_restore_main(int, char **);
extern int xtables_eb_save_main(int, char **);
diff --git a/iptables/xtables-nft-multi.c b/iptables/xtables-nft-multi.c
index d9cca088..e2b7c641 100644
--- a/iptables/xtables-nft-multi.c
+++ b/iptables/xtables-nft-multi.c
@@ -32,6 +32,10 @@ static const struct subcommand multi_subcommands[] = {
{"ip6tables-restore-translate", xtables_ip6_xlate_restore_main},
{"arptables", xtables_arp_main},
{"arptables-nft", xtables_arp_main},
+ {"arptables-restore", xtables_arp_restore_main},
+ {"arptables-nft-restore", xtables_arp_restore_main},
+ {"arptables-save", xtables_arp_save_main},
+ {"arptables-nft-save", xtables_arp_save_main},
{"ebtables-translate", xtables_eb_xlate_main},
{"ebtables", xtables_eb_main},
{"ebtables-restore", xtables_eb_restore_main},
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index a76acfd4..d2b79208 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -529,3 +529,29 @@ int xtables_eb_restore_main(int argc, char *argv[])
return 0;
}
+
+struct nft_xt_restore_cb arp_restore_cb = {
+ .chain_list = get_chain_list,
+ .commit = nft_commit,
+ .table_new = nft_table_new,
+ .table_flush = nft_table_flush,
+ .chain_user_flush = nft_chain_user_flush,
+ .chain_del = chain_delete,
+ .do_command = do_commandarp,
+ .chain_set = nft_chain_set,
+ .chain_user_add = nft_chain_user_add,
+};
+
+int xtables_arp_restore_main(int argc, char *argv[])
+{
+ struct nft_xt_restore_parse p = {
+ .in = stdin,
+ };
+ struct nft_handle h;
+
+ nft_init_arp(&h, "arptables-restore");
+ xtables_restore_parse(&h, &p, &arp_restore_cb, argc, argv);
+ nft_fini(&h);
+
+ return 0;
+}
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index c9df51d5..fc51fcfe 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -287,3 +287,42 @@ int xtables_eb_save_main(int argc_, char *argv_[])
nft_for_each_table(&h, __ebt_save, !!ctr);
return 0;
}
+
+int xtables_arp_save_main(int argc, char **argv)
+{
+ struct nft_handle h = {
+ .family = NFPROTO_ARP,
+ };
+ int c;
+
+ xtables_globals.program_name = "arptables-save";
+ c = xtables_init_all(&xtables_globals, h.family);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version);
+ exit(1);
+ }
+
+ if (nft_init(&h, xtables_arp) < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (!nft_table_find(&h, "filter"))
+ return 0;
+
+ if (!nft_is_table_compatible(&h, "filter")) {
+ printf("# Table `filter' is incompatible, use 'nft' tool.\n");
+ return 0;
+ }
+
+ printf("*filter\n");
+ nft_chain_save(&h, nft_chain_dump(&h), "filter");
+ nft_rule_save(&h, "filter", FMT_NOCOUNTS);
+ printf("\n");
+ return 0;
+}