* [iptables PATCH 00/11] Share do_parse() between nft and legacy
@ 2021-12-24 17:17 Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 01/11] xtables: Drop xtables' family on demand feature Phil Sutter
` (10 more replies)
0 siblings, 11 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Patch 1 removes remains of an unused (and otherwise dropped) feature,
yet the change is necessary for the following ones. Patches 2-6 prepare
for patch 7 which moves do_parse() to xshared.c. Patches 8 and 9 prepare
for use of do_parse() from legacy code, Patches 10 and 11 finally drop
legacy ip(6)tables' rule parsing code.
Merry Xmas!
Phil Sutter (11):
xtables: Drop xtables' family on demand feature
xtables: Pull table validity check out of do_parse()
xtables: Move struct nft_xt_cmd_parse to xshared.h
xtables: Pass xtables_args to check_empty_interface()
xtables: Pass xtables_args to check_inverse()
xtables: Do not pass nft_handle to do_parse()
xshared: Move do_parse to shared space
xshared: Store parsed wait and wait_interval in xtables_args
nft: Move proto_parse and post_parse callbacks to xshared
iptables: Use xtables' do_parse() function
ip6tables: Use the shared do_parse, too
iptables/ip6tables.c | 499 ++---------------------
iptables/iptables.c | 484 ++--------------------
iptables/nft-ipv4.c | 59 +--
iptables/nft-ipv6.c | 76 +---
iptables/nft-shared.h | 49 ---
iptables/xshared.c | 684 ++++++++++++++++++++++++++++++++
iptables/xshared.h | 66 +++
iptables/xtables-eb-translate.c | 4 +-
iptables/xtables-translate.c | 13 +-
iptables/xtables.c | 573 +-------------------------
10 files changed, 839 insertions(+), 1668 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [iptables PATCH 01/11] xtables: Drop xtables' family on demand feature
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 02/11] xtables: Pull table validity check out of do_parse() Phil Sutter
` (9 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
This conditional h->family assignment was added by commit 3f7877e6be987
("xtables-restore: add -4 and -6 support") with the intention to support
something like 'xtables-restore -6 <ip6tables.dump', i.e. having
family-agnostic commands which accept flags to set the family. Yet
commit be70918eab26e ("xtables: rename xt-multi binaries to -nft,
-legacy") removed support for such command names back in 2018 and nobody
has complained so far. Therefore drop this leftover as it makes
do_parse() more generic.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 57bec76c31fb3..5c48bd94644f3 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -657,10 +657,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
xtables_error(PARAMETER_PROBLEM,
"nothing appropriate following !");
- /* Set only if required, needed by xtables-restore */
- if (h->family == AF_UNSPEC)
- h->family = args->family;
-
h->ops->post_parse(p->command, cs, args);
if (p->command == CMD_REPLACE &&
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 02/11] xtables: Pull table validity check out of do_parse()
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 01/11] xtables: Drop xtables' family on demand feature Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 03/11] xtables: Move struct nft_xt_cmd_parse to xshared.h Phil Sutter
` (8 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Makes do_parse() more generic, error codes don't change so this should
be safe.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 5c48bd94644f3..ac864eb24a35e 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -514,10 +514,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
xtables_error(PARAMETER_PROBLEM,
"The -t option cannot be used in %s.\n",
xt_params->program_name);
- if (!nft_table_builtin_find(h, optarg))
- xtables_error(VERSION_PROBLEM,
- "table '%s' does not exist",
- optarg);
p->table = optarg;
table_set = true;
break;
@@ -720,6 +716,10 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
do_parse(h, argc, argv, &p, &cs, &args);
+ if (!nft_table_builtin_find(h, p.table))
+ xtables_error(VERSION_PROBLEM,
+ "table '%s' does not exist",
+ p.table);
switch (p.command) {
case CMD_APPEND:
ret = h->ops->add_entry(h, p.chain, p.table, &cs, &args,
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 03/11] xtables: Move struct nft_xt_cmd_parse to xshared.h
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 01/11] xtables: Drop xtables' family on demand feature Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 02/11] xtables: Pull table validity check out of do_parse() Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 04/11] xtables: Pass xtables_args to check_empty_interface() Phil Sutter
` (7 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Preparing for shared use with legacy variants, move it to "neutral
ground" and give it a more generic name.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-shared.h | 14 +-------------
iptables/xshared.h | 12 ++++++++++++
iptables/xtables-eb-translate.c | 4 ++--
iptables/xtables-translate.c | 8 ++++----
iptables/xtables.c | 4 ++--
5 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index bcf8486eb44c4..4948aef761d10 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -210,20 +210,8 @@ struct xtables_args {
unsigned long long pcnt_cnt, bcnt_cnt;
};
-struct nft_xt_cmd_parse {
- unsigned int command;
- unsigned int rulenum;
- char *table;
- const char *chain;
- const char *newname;
- const char *policy;
- bool restore;
- int verbose;
- bool xlate;
-};
-
void do_parse(struct nft_handle *h, int argc, char *argv[],
- struct nft_xt_cmd_parse *p, struct iptables_command_state *cs,
+ struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args);
struct nftnl_chain_list;
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 2c05b0d7c4ace..dde94b7335f6a 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -262,4 +262,16 @@ int print_match_save(const struct xt_entry_match *e, const void *ip);
void xtables_printhelp(const struct xtables_rule_match *matches);
void exit_tryhelp(int status, int line) __attribute__((noreturn));
+struct xt_cmd_parse {
+ unsigned int command;
+ unsigned int rulenum;
+ char *table;
+ const char *chain;
+ const char *newname;
+ const char *policy;
+ bool restore;
+ int verbose;
+ bool xlate;
+};
+
#endif /* IPTABLES_XSHARED_H */
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index a6c86b6531e3f..86177024ec703 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -152,7 +152,7 @@ static void print_ebt_cmd(int argc, char *argv[])
printf("\n");
}
-static int nft_rule_eb_xlate_add(struct nft_handle *h, const struct nft_xt_cmd_parse *p,
+static int nft_rule_eb_xlate_add(struct nft_handle *h, const struct xt_cmd_parse *p,
const struct iptables_command_state *cs, bool append)
{
struct xt_xlate *xl = xt_xlate_alloc(10240);
@@ -191,7 +191,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
int selected_chain = -1;
struct xtables_rule_match *xtrm_i;
struct ebt_match *match;
- struct nft_xt_cmd_parse p = {
+ struct xt_cmd_parse p = {
.table = *table,
};
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index e2948c5009dd6..9d312b244657e 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -150,7 +150,7 @@ const char *family2str[] = {
};
static int nft_rule_xlate_add(struct nft_handle *h,
- const struct nft_xt_cmd_parse *p,
+ const struct xt_cmd_parse *p,
const struct iptables_command_state *cs,
bool append)
{
@@ -186,11 +186,11 @@ err_out:
return ret;
}
-static int xlate(struct nft_handle *h, struct nft_xt_cmd_parse *p,
+static int xlate(struct nft_handle *h, struct xt_cmd_parse *p,
struct iptables_command_state *cs,
struct xtables_args *args, bool append,
int (*cb)(struct nft_handle *h,
- const struct nft_xt_cmd_parse *p,
+ const struct xt_cmd_parse *p,
const struct iptables_command_state *cs,
bool append))
{
@@ -248,7 +248,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
char **table, bool restore)
{
int ret = 0;
- struct nft_xt_cmd_parse p = {
+ struct xt_cmd_parse p = {
.table = *table,
.restore = restore,
.xlate = true,
diff --git a/iptables/xtables.c b/iptables/xtables.c
index ac864eb24a35e..837b399aba5b3 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -187,7 +187,7 @@ static void check_inverse(struct nft_handle *h, const char option[],
}
void do_parse(struct nft_handle *h, int argc, char *argv[],
- struct nft_xt_cmd_parse *p, struct iptables_command_state *cs,
+ struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args)
{
struct xtables_match *m;
@@ -699,7 +699,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
bool restore)
{
int ret = 1;
- struct nft_xt_cmd_parse p = {
+ struct xt_cmd_parse p = {
.table = *table,
.restore = restore,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 04/11] xtables: Pass xtables_args to check_empty_interface()
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (2 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 03/11] xtables: Move struct nft_xt_cmd_parse to xshared.h Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 05/11] xtables: Pass xtables_args to check_inverse() Phil Sutter
` (6 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
It holds the accessed family field as well and is more generic than
nft_handle.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 837b399aba5b3..db0cec2461741 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -145,14 +145,14 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
return nft_cmd_rule_list_save(h, chain, table, rulenum, counters);
}
-static void check_empty_interface(struct nft_handle *h, const char *arg)
+static void check_empty_interface(struct xtables_args *args, const char *arg)
{
const char *msg = "Empty interface is likely to be undesired";
if (*arg != '\0')
return;
- if (h->family != NFPROTO_ARP)
+ if (args->family != NFPROTO_ARP)
xtables_error(PARAMETER_PROBLEM, msg);
fprintf(stderr, "%s", msg);
@@ -460,7 +460,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
break;
case 'i':
- check_empty_interface(h, optarg);
+ check_empty_interface(args, optarg);
check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_VIANAMEIN,
&args->invflags, invert);
@@ -470,7 +470,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
break;
case 'o':
- check_empty_interface(h, optarg);
+ check_empty_interface(args, optarg);
check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_VIANAMEOUT,
&args->invflags, invert);
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 05/11] xtables: Pass xtables_args to check_inverse()
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (3 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 04/11] xtables: Pass xtables_args to check_empty_interface() Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse() Phil Sutter
` (5 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
It holds the accessed family field as well and is more generic than
nft_handle.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/iptables/xtables.c b/iptables/xtables.c
index db0cec2461741..5e8c027b8471e 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -158,10 +158,10 @@ static void check_empty_interface(struct xtables_args *args, const char *arg)
fprintf(stderr, "%s", msg);
}
-static void check_inverse(struct nft_handle *h, const char option[],
+static void check_inverse(struct xtables_args *args, const char option[],
bool *invert, int *optidx, int argc)
{
- switch (h->family) {
+ switch (args->family) {
case NFPROTO_ARP:
break;
default:
@@ -364,7 +364,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
* Option selection
*/
case 'p':
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_PROTOCOL,
&args->invflags, invert);
@@ -387,14 +387,14 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
break;
case 's':
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_SOURCE,
&args->invflags, invert);
args->shostnetworkmask = argv[optind - 1];
break;
case 'd':
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_DESTINATION,
&args->invflags, invert);
args->dhostnetworkmask = argv[optind - 1];
@@ -410,21 +410,21 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
#endif
case 2:/* src-mac */
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_S_MAC, &args->invflags,
invert);
args->src_mac = argv[optind - 1];
break;
case 3:/* dst-mac */
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_D_MAC, &args->invflags,
invert);
args->dst_mac = argv[optind - 1];
break;
case 'l':/* hardware length */
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_H_LENGTH, &args->invflags,
invert);
args->arp_hlen = argv[optind - 1];
@@ -433,21 +433,21 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
case 8: /* was never supported, not even in arptables-legacy */
xtables_error(PARAMETER_PROBLEM, "not supported");
case 4:/* opcode */
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_OPCODE, &args->invflags,
invert);
args->arp_opcode = argv[optind - 1];
break;
case 5:/* h-type */
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_H_TYPE, &args->invflags,
invert);
args->arp_htype = argv[optind - 1];
break;
case 6:/* proto-type */
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_P_TYPE, &args->invflags,
invert);
args->arp_ptype = argv[optind - 1];
@@ -461,7 +461,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
case 'i':
check_empty_interface(args, optarg);
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_VIANAMEIN,
&args->invflags, invert);
xtables_parse_interface(argv[optind - 1],
@@ -471,7 +471,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
case 'o':
check_empty_interface(args, optarg);
- check_inverse(h, optarg, &invert, &optind, argc);
+ check_inverse(args, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_VIANAMEOUT,
&args->invflags, invert);
xtables_parse_interface(argv[optind - 1],
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse()
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (4 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 05/11] xtables: Pass xtables_args to check_inverse() Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2022-01-10 21:29 ` Pablo Neira Ayuso
2021-12-24 17:17 ` [iptables PATCH 07/11] xshared: Move do_parse to shared space Phil Sutter
` (4 subsequent siblings)
10 siblings, 1 reply; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Make it fit for sharing with legacy iptables, drop nft-specific
parameter. This requires to mirror proto_parse and post_parse callbacks
from family_ops somewhere reachable - use xt_cmd_parse, it holds other
"parser setup data" as well.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-shared.h | 35 +--------------------------------
iptables/xshared.h | 38 ++++++++++++++++++++++++++++++++++++
iptables/xtables-translate.c | 4 +++-
iptables/xtables.c | 13 +++++++-----
4 files changed, 50 insertions(+), 40 deletions(-)
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 4948aef761d10..7396fa991439f 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -177,40 +177,7 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data);
bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2);
bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2);
-struct addr_mask {
- union {
- struct in_addr *v4;
- struct in6_addr *v6;
- void *ptr;
- } addr;
-
- unsigned int naddrs;
-
- union {
- struct in_addr *v4;
- struct in6_addr *v6;
- void *ptr;
- } mask;
-};
-
-struct xtables_args {
- int family;
- uint16_t proto;
- uint8_t flags;
- uint16_t invflags;
- char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
- unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
- bool goto_set;
- const char *shostnetworkmask, *dhostnetworkmask;
- const char *pcnt, *bcnt;
- struct addr_mask s, d;
- const char *src_mac, *dst_mac;
- const char *arp_hlen, *arp_opcode;
- const char *arp_htype, *arp_ptype;
- unsigned long long pcnt_cnt, bcnt_cnt;
-};
-
-void do_parse(struct nft_handle *h, int argc, char *argv[],
+void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args);
diff --git a/iptables/xshared.h b/iptables/xshared.h
index dde94b7335f6a..1954168f64058 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -262,6 +262,39 @@ int print_match_save(const struct xt_entry_match *e, const void *ip);
void xtables_printhelp(const struct xtables_rule_match *matches);
void exit_tryhelp(int status, int line) __attribute__((noreturn));
+struct addr_mask {
+ union {
+ struct in_addr *v4;
+ struct in6_addr *v6;
+ void *ptr;
+ } addr;
+
+ unsigned int naddrs;
+
+ union {
+ struct in_addr *v4;
+ struct in6_addr *v6;
+ void *ptr;
+ } mask;
+};
+
+struct xtables_args {
+ int family;
+ uint16_t proto;
+ uint8_t flags;
+ uint16_t invflags;
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+ bool goto_set;
+ const char *shostnetworkmask, *dhostnetworkmask;
+ const char *pcnt, *bcnt;
+ struct addr_mask s, d;
+ const char *src_mac, *dst_mac;
+ const char *arp_hlen, *arp_opcode;
+ const char *arp_htype, *arp_ptype;
+ unsigned long long pcnt_cnt, bcnt_cnt;
+};
+
struct xt_cmd_parse {
unsigned int command;
unsigned int rulenum;
@@ -272,6 +305,11 @@ struct xt_cmd_parse {
bool restore;
int verbose;
bool xlate;
+ void (*proto_parse)(struct iptables_command_state *cs,
+ struct xtables_args *args);
+ void (*post_parse)(int command,
+ struct iptables_command_state *cs,
+ struct xtables_args *args);
};
#endif /* IPTABLES_XSHARED_H */
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index 9d312b244657e..b0b27695cbb8c 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -252,6 +252,8 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
.table = *table,
.restore = restore,
.xlate = true,
+ .proto_parse = h->ops->proto_parse,
+ .post_parse = h->ops->post_parse,
};
struct iptables_command_state cs = {
.jumpto = "",
@@ -265,7 +267,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
if (h->ops->init_cs)
h->ops->init_cs(&cs);
- do_parse(h, argc, argv, &p, &cs, &args);
+ do_parse(argc, argv, &p, &cs, &args);
cs.restore = restore;
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 5e8c027b8471e..d7e22285e089e 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -186,7 +186,7 @@ static void check_inverse(struct xtables_args *args, const char option[],
}
}
-void do_parse(struct nft_handle *h, int argc, char *argv[],
+void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args)
{
@@ -382,8 +382,8 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
"rule would never match protocol");
/* This needs to happen here to parse extensions */
- if (h->ops->proto_parse)
- h->ops->proto_parse(cs, args);
+ if (p->proto_parse)
+ p->proto_parse(cs, args);
break;
case 's':
@@ -653,7 +653,8 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
xtables_error(PARAMETER_PROBLEM,
"nothing appropriate following !");
- h->ops->post_parse(p->command, cs, args);
+ if (p->post_parse)
+ p->post_parse(p->command, cs, args);
if (p->command == CMD_REPLACE &&
(args->s.naddrs != 1 || args->d.naddrs != 1))
@@ -702,6 +703,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
struct xt_cmd_parse p = {
.table = *table,
.restore = restore,
+ .proto_parse = h->ops->proto_parse,
+ .post_parse = h->ops->post_parse,
};
struct iptables_command_state cs = {
.jumpto = "",
@@ -714,7 +717,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
if (h->ops->init_cs)
h->ops->init_cs(&cs);
- do_parse(h, argc, argv, &p, &cs, &args);
+ do_parse(argc, argv, &p, &cs, &args);
if (!nft_table_builtin_find(h, p.table))
xtables_error(VERSION_PROBLEM,
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 07/11] xshared: Move do_parse to shared space
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (5 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse() Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 08/11] xshared: Store parsed wait and wait_interval in xtables_args Phil Sutter
` (3 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Small adjustments were needed:
- Pass line variable via xt_cmd_parse, xshared.c does not have it in
namespace.
- Replace opts, prog_name and prog_vers defines by the respective
xt_params field reference.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-shared.h | 4 -
iptables/xshared.c | 553 ++++++++++++++++++++++++++++++++++
iptables/xshared.h | 5 +
iptables/xtables-translate.c | 1 +
iptables/xtables.c | 556 +----------------------------------
5 files changed, 560 insertions(+), 559 deletions(-)
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 7396fa991439f..a253dd70c335f 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -177,10 +177,6 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data);
bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2);
bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2);
-void do_parse(int argc, char *argv[],
- struct xt_cmd_parse *p, struct iptables_command_state *cs,
- struct xtables_args *args);
-
struct nftnl_chain_list;
struct nft_xt_restore_cb {
diff --git a/iptables/xshared.c b/iptables/xshared.c
index efee7a30b39fd..7702d899a3586 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1262,3 +1262,556 @@ void exit_tryhelp(int status, int line)
xtables_free_opts(1);
exit(status);
}
+
+static void check_empty_interface(struct xtables_args *args, const char *arg)
+{
+ const char *msg = "Empty interface is likely to be undesired";
+
+ if (*arg != '\0')
+ return;
+
+ if (args->family != NFPROTO_ARP)
+ xtables_error(PARAMETER_PROBLEM, msg);
+
+ fprintf(stderr, "%s", msg);
+}
+
+static void check_inverse(struct xtables_args *args, const char option[],
+ bool *invert, int *optidx, int argc)
+{
+ switch (args->family) {
+ case NFPROTO_ARP:
+ break;
+ default:
+ return;
+ }
+
+ if (!option || strcmp(option, "!"))
+ return;
+
+ fprintf(stderr, "Using intrapositioned negation (`--option ! this`) "
+ "is deprecated in favor of extrapositioned (`! --option this`).\n");
+
+ if (*invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Multiple `!' flags not allowed");
+ *invert = true;
+ if (optidx) {
+ *optidx = *optidx + 1;
+ if (argc && *optidx > argc)
+ xtables_error(PARAMETER_PROBLEM,
+ "no argument following `!'");
+ }
+}
+
+void do_parse(int argc, char *argv[],
+ struct xt_cmd_parse *p, struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ struct xtables_match *m;
+ struct xtables_rule_match *matchp;
+ bool wait_interval_set = false;
+ struct timeval wait_interval;
+ struct xtables_target *t;
+ bool table_set = false;
+ bool invert = false;
+ int wait = 0;
+
+ /* re-set optind to 0 in case do_command4 gets called
+ * a second time */
+ optind = 0;
+
+ /* clear mflags in case do_command4 gets called a second time
+ * (we clear the global list of all matches for security)*/
+ for (m = xtables_matches; m; m = m->next)
+ m->mflags = 0;
+
+ for (t = xtables_targets; t; t = t->next) {
+ t->tflags = 0;
+ t->used = 0;
+ }
+
+ /* Suppress error messages: we may add new options if we
+ demand-load a protocol. */
+ opterr = 0;
+
+ xt_params->opts = xt_params->orig_opts;
+ while ((cs->c = getopt_long(argc, argv, xt_params->optstring,
+ xt_params->opts, NULL)) != -1) {
+ switch (cs->c) {
+ /*
+ * Command selection
+ */
+ case 'A':
+ add_command(&p->command, CMD_APPEND, CMD_NONE, invert);
+ p->chain = optarg;
+ break;
+
+ case 'C':
+ add_command(&p->command, CMD_CHECK, CMD_NONE, invert);
+ p->chain = optarg;
+ break;
+
+ case 'D':
+ add_command(&p->command, CMD_DELETE, CMD_NONE, invert);
+ p->chain = optarg;
+ if (xs_has_arg(argc, argv)) {
+ p->rulenum = parse_rulenumber(argv[optind++]);
+ p->command = CMD_DELETE_NUM;
+ }
+ break;
+
+ case 'R':
+ add_command(&p->command, CMD_REPLACE, CMD_NONE, invert);
+ p->chain = optarg;
+ if (xs_has_arg(argc, argv))
+ p->rulenum = parse_rulenumber(argv[optind++]);
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "-%c requires a rule number",
+ cmd2char(CMD_REPLACE));
+ break;
+
+ case 'I':
+ add_command(&p->command, CMD_INSERT, CMD_NONE, invert);
+ p->chain = optarg;
+ if (xs_has_arg(argc, argv))
+ p->rulenum = parse_rulenumber(argv[optind++]);
+ else
+ p->rulenum = 1;
+ break;
+
+ case 'L':
+ add_command(&p->command, CMD_LIST,
+ CMD_ZERO | CMD_ZERO_NUM, invert);
+ if (optarg)
+ p->chain = optarg;
+ else if (xs_has_arg(argc, argv))
+ p->chain = argv[optind++];
+ if (xs_has_arg(argc, argv))
+ p->rulenum = parse_rulenumber(argv[optind++]);
+ break;
+
+ case 'S':
+ add_command(&p->command, CMD_LIST_RULES,
+ CMD_ZERO|CMD_ZERO_NUM, invert);
+ if (optarg)
+ p->chain = optarg;
+ else if (xs_has_arg(argc, argv))
+ p->chain = argv[optind++];
+ if (xs_has_arg(argc, argv))
+ p->rulenum = parse_rulenumber(argv[optind++]);
+ break;
+
+ case 'F':
+ add_command(&p->command, CMD_FLUSH, CMD_NONE, invert);
+ if (optarg)
+ p->chain = optarg;
+ else if (xs_has_arg(argc, argv))
+ p->chain = argv[optind++];
+ break;
+
+ case 'Z':
+ add_command(&p->command, CMD_ZERO,
+ CMD_LIST|CMD_LIST_RULES, invert);
+ if (optarg)
+ p->chain = optarg;
+ else if (xs_has_arg(argc, argv))
+ p->chain = argv[optind++];
+ if (xs_has_arg(argc, argv)) {
+ p->rulenum = parse_rulenumber(argv[optind++]);
+ p->command = CMD_ZERO_NUM;
+ }
+ break;
+
+ case 'N':
+ parse_chain(optarg);
+ add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE,
+ invert);
+ p->chain = optarg;
+ break;
+
+ case 'X':
+ add_command(&p->command, CMD_DELETE_CHAIN, CMD_NONE,
+ invert);
+ if (optarg)
+ p->chain = optarg;
+ else if (xs_has_arg(argc, argv))
+ p->chain = argv[optind++];
+ break;
+
+ case 'E':
+ add_command(&p->command, CMD_RENAME_CHAIN, CMD_NONE,
+ invert);
+ p->chain = optarg;
+ if (xs_has_arg(argc, argv))
+ p->newname = argv[optind++];
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "-%c requires old-chain-name and "
+ "new-chain-name",
+ cmd2char(CMD_RENAME_CHAIN));
+ break;
+
+ case 'P':
+ add_command(&p->command, CMD_SET_POLICY, CMD_NONE,
+ invert);
+ p->chain = optarg;
+ if (xs_has_arg(argc, argv))
+ p->policy = argv[optind++];
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "-%c requires a chain and a policy",
+ cmd2char(CMD_SET_POLICY));
+ break;
+
+ case 'h':
+ if (!optarg)
+ optarg = argv[optind];
+
+ /* iptables -p icmp -h */
+ if (!cs->matches && cs->protocol)
+ xtables_find_match(cs->protocol,
+ XTF_TRY_LOAD, &cs->matches);
+
+ xt_params->print_help(cs->matches);
+ p->command = CMD_NONE;
+ return;
+
+ /*
+ * Option selection
+ */
+ case 'p':
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_PROTOCOL,
+ &args->invflags, invert);
+
+ /* Canonicalize into lower case */
+ for (cs->protocol = argv[optind - 1];
+ *cs->protocol; cs->protocol++)
+ *cs->protocol = tolower(*cs->protocol);
+
+ cs->protocol = argv[optind - 1];
+ args->proto = xtables_parse_protocol(cs->protocol);
+
+ if (args->proto == 0 &&
+ (args->invflags & XT_INV_PROTO))
+ xtables_error(PARAMETER_PROBLEM,
+ "rule would never match protocol");
+
+ /* This needs to happen here to parse extensions */
+ if (p->proto_parse)
+ p->proto_parse(cs, args);
+ break;
+
+ case 's':
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_SOURCE,
+ &args->invflags, invert);
+ args->shostnetworkmask = argv[optind - 1];
+ break;
+
+ case 'd':
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_DESTINATION,
+ &args->invflags, invert);
+ args->dhostnetworkmask = argv[optind - 1];
+ break;
+
+#ifdef IPT_F_GOTO
+ case 'g':
+ set_option(&cs->options, OPT_JUMP, &args->invflags,
+ invert);
+ args->goto_set = true;
+ cs->jumpto = xt_parse_target(optarg);
+ break;
+#endif
+
+ case 2:/* src-mac */
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_S_MAC, &args->invflags,
+ invert);
+ args->src_mac = argv[optind - 1];
+ break;
+
+ case 3:/* dst-mac */
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_D_MAC, &args->invflags,
+ invert);
+ args->dst_mac = argv[optind - 1];
+ break;
+
+ case 'l':/* hardware length */
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_H_LENGTH, &args->invflags,
+ invert);
+ args->arp_hlen = argv[optind - 1];
+ break;
+
+ case 8: /* was never supported, not even in arptables-legacy */
+ xtables_error(PARAMETER_PROBLEM, "not supported");
+ case 4:/* opcode */
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_OPCODE, &args->invflags,
+ invert);
+ args->arp_opcode = argv[optind - 1];
+ break;
+
+ case 5:/* h-type */
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_H_TYPE, &args->invflags,
+ invert);
+ args->arp_htype = argv[optind - 1];
+ break;
+
+ case 6:/* proto-type */
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_P_TYPE, &args->invflags,
+ invert);
+ args->arp_ptype = argv[optind - 1];
+ break;
+
+ case 'j':
+ set_option(&cs->options, OPT_JUMP, &args->invflags,
+ invert);
+ command_jump(cs, argv[optind - 1]);
+ break;
+
+ case 'i':
+ check_empty_interface(args, optarg);
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_VIANAMEIN,
+ &args->invflags, invert);
+ xtables_parse_interface(argv[optind - 1],
+ args->iniface,
+ args->iniface_mask);
+ break;
+
+ case 'o':
+ check_empty_interface(args, optarg);
+ check_inverse(args, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_VIANAMEOUT,
+ &args->invflags, invert);
+ xtables_parse_interface(argv[optind - 1],
+ args->outiface,
+ args->outiface_mask);
+ break;
+
+ case 'f':
+ if (args->family == AF_INET6) {
+ xtables_error(PARAMETER_PROBLEM,
+ "`-f' is not supported in IPv6, "
+ "use -m frag instead");
+ }
+ set_option(&cs->options, OPT_FRAGMENT, &args->invflags,
+ invert);
+ args->flags |= IPT_F_FRAG;
+ break;
+
+ case 'v':
+ if (!p->verbose)
+ set_option(&cs->options, OPT_VERBOSE,
+ &args->invflags, invert);
+ p->verbose++;
+ break;
+
+ case 'm':
+ command_match(cs, invert);
+ break;
+
+ case 'n':
+ set_option(&cs->options, OPT_NUMERIC, &args->invflags,
+ invert);
+ break;
+
+ case 't':
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --table");
+ if (p->restore && table_set)
+ xtables_error(PARAMETER_PROBLEM,
+ "The -t option cannot be used in %s.\n",
+ xt_params->program_name);
+ p->table = optarg;
+ table_set = true;
+ break;
+
+ case 'x':
+ set_option(&cs->options, OPT_EXPANDED, &args->invflags,
+ invert);
+ break;
+
+ case 'V':
+ if (invert)
+ printf("Not %s ;-)\n",
+ xt_params->program_version);
+ else
+ printf("%s v%s\n",
+ xt_params->program_name,
+ xt_params->program_version);
+ exit(0);
+
+ case 'w':
+ if (p->restore) {
+ xtables_error(PARAMETER_PROBLEM,
+ "You cannot use `-w' from "
+ "iptables-restore");
+ }
+
+ wait = parse_wait_time(argc, argv);
+ break;
+
+ case 'W':
+ if (p->restore) {
+ xtables_error(PARAMETER_PROBLEM,
+ "You cannot use `-W' from "
+ "iptables-restore");
+ }
+
+ parse_wait_interval(argc, argv, &wait_interval);
+ wait_interval_set = true;
+ break;
+
+ case '0':
+ set_option(&cs->options, OPT_LINENUMBERS,
+ &args->invflags, invert);
+ break;
+
+ case 'M':
+ xtables_modprobe_program = optarg;
+ break;
+
+ case 'c':
+ set_option(&cs->options, OPT_COUNTERS, &args->invflags,
+ invert);
+ args->pcnt = optarg;
+ args->bcnt = strchr(args->pcnt + 1, ',');
+ if (args->bcnt)
+ args->bcnt++;
+ if (!args->bcnt && xs_has_arg(argc, argv))
+ args->bcnt = argv[optind++];
+ if (!args->bcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "-%c requires packet and byte counter",
+ opt2char(OPT_COUNTERS));
+
+ if (sscanf(args->pcnt, "%llu", &args->pcnt_cnt) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "-%c packet counter not numeric",
+ opt2char(OPT_COUNTERS));
+
+ if (sscanf(args->bcnt, "%llu", &args->bcnt_cnt) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "-%c byte counter not numeric",
+ opt2char(OPT_COUNTERS));
+ break;
+
+ case '4':
+ if (args->family == AF_INET)
+ break;
+
+ if (p->restore && args->family == AF_INET6)
+ return;
+
+ exit_tryhelp(2, p->line);
+
+ case '6':
+ if (args->family == AF_INET6)
+ break;
+
+ if (p->restore && args->family == AF_INET)
+ return;
+
+ exit_tryhelp(2, p->line);
+
+ case 1: /* non option */
+ if (optarg[0] == '!' && optarg[1] == '\0') {
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "multiple consecutive ! not"
+ " allowed");
+ invert = true;
+ optarg[0] = '\0';
+ continue;
+ }
+ fprintf(stderr, "Bad argument `%s'\n", optarg);
+ exit_tryhelp(2, p->line);
+
+ default:
+ if (command_default(cs, xt_params, invert))
+ /* cf. ip6tables.c */
+ continue;
+ break;
+ }
+ invert = false;
+ }
+
+ if (strcmp(p->table, "nat") == 0 &&
+ ((p->policy != NULL && strcmp(p->policy, "DROP") == 0) ||
+ (cs->jumpto != NULL && strcmp(cs->jumpto, "DROP") == 0)))
+ xtables_error(PARAMETER_PROBLEM,
+ "\nThe \"nat\" table is not intended for filtering, "
+ "the use of DROP is therefore inhibited.\n\n");
+
+ if (!wait && wait_interval_set)
+ xtables_error(PARAMETER_PROBLEM,
+ "--wait-interval only makes sense with --wait\n");
+
+ for (matchp = cs->matches; matchp; matchp = matchp->next)
+ xtables_option_mfcall(matchp->match);
+ if (cs->target != NULL)
+ xtables_option_tfcall(cs->target);
+
+ /* Fix me: must put inverse options checking here --MN */
+
+ if (optind < argc)
+ xtables_error(PARAMETER_PROBLEM,
+ "unknown arguments found on commandline");
+ if (!p->command)
+ xtables_error(PARAMETER_PROBLEM, "no command specified");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "nothing appropriate following !");
+
+ if (p->post_parse)
+ p->post_parse(p->command, cs, args);
+
+ if (p->command == CMD_REPLACE &&
+ (args->s.naddrs != 1 || args->d.naddrs != 1))
+ xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
+ "specify a unique address");
+
+ generic_opt_check(p->command, cs->options);
+
+ if (p->chain != NULL && strlen(p->chain) >= XT_EXTENSION_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "chain name `%s' too long (must be under %u chars)",
+ p->chain, XT_EXTENSION_MAXNAMELEN);
+
+ if (p->command == CMD_APPEND ||
+ p->command == CMD_DELETE ||
+ p->command == CMD_DELETE_NUM ||
+ p->command == CMD_CHECK ||
+ p->command == CMD_INSERT ||
+ p->command == CMD_REPLACE) {
+ if (strcmp(p->chain, "PREROUTING") == 0
+ || strcmp(p->chain, "INPUT") == 0) {
+ /* -o not valid with incoming packets. */
+ if (cs->options & OPT_VIANAMEOUT)
+ xtables_error(PARAMETER_PROBLEM,
+ "Can't use -%c with %s\n",
+ opt2char(OPT_VIANAMEOUT),
+ p->chain);
+ }
+
+ if (strcmp(p->chain, "POSTROUTING") == 0
+ || strcmp(p->chain, "OUTPUT") == 0) {
+ /* -i not valid with outgoing packets */
+ if (cs->options & OPT_VIANAMEIN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Can't use -%c with %s\n",
+ opt2char(OPT_VIANAMEIN),
+ p->chain);
+ }
+ }
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 1954168f64058..2737ba4b11c25 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -303,6 +303,7 @@ struct xt_cmd_parse {
const char *newname;
const char *policy;
bool restore;
+ int line;
int verbose;
bool xlate;
void (*proto_parse)(struct iptables_command_state *cs,
@@ -312,4 +313,8 @@ struct xt_cmd_parse {
struct xtables_args *args);
};
+void do_parse(int argc, char *argv[],
+ struct xt_cmd_parse *p, struct iptables_command_state *cs,
+ struct xtables_args *args);
+
#endif /* IPTABLES_XSHARED_H */
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index b0b27695cbb8c..076b7249329bc 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -251,6 +251,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
struct xt_cmd_parse p = {
.table = *table,
.restore = restore,
+ .line = line,
.xlate = true,
.proto_parse = h->ops->proto_parse,
.post_parse = h->ops->post_parse,
diff --git a/iptables/xtables.c b/iptables/xtables.c
index d7e22285e089e..6d79215755b3e 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -95,10 +95,6 @@ struct xtables_globals xtables_globals = {
.print_help = xtables_printhelp,
};
-#define opts xt_params->opts
-#define prog_name xt_params->program_name
-#define prog_vers xt_params->program_version
-
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
@@ -145,557 +141,6 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
return nft_cmd_rule_list_save(h, chain, table, rulenum, counters);
}
-static void check_empty_interface(struct xtables_args *args, const char *arg)
-{
- const char *msg = "Empty interface is likely to be undesired";
-
- if (*arg != '\0')
- return;
-
- if (args->family != NFPROTO_ARP)
- xtables_error(PARAMETER_PROBLEM, msg);
-
- fprintf(stderr, "%s", msg);
-}
-
-static void check_inverse(struct xtables_args *args, const char option[],
- bool *invert, int *optidx, int argc)
-{
- switch (args->family) {
- case NFPROTO_ARP:
- break;
- default:
- return;
- }
-
- if (!option || strcmp(option, "!"))
- return;
-
- fprintf(stderr, "Using intrapositioned negation (`--option ! this`) "
- "is deprecated in favor of extrapositioned (`! --option this`).\n");
-
- if (*invert)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple `!' flags not allowed");
- *invert = true;
- if (optidx) {
- *optidx = *optidx + 1;
- if (argc && *optidx > argc)
- xtables_error(PARAMETER_PROBLEM,
- "no argument following `!'");
- }
-}
-
-void do_parse(int argc, char *argv[],
- struct xt_cmd_parse *p, struct iptables_command_state *cs,
- struct xtables_args *args)
-{
- struct xtables_match *m;
- struct xtables_rule_match *matchp;
- bool wait_interval_set = false;
- struct timeval wait_interval;
- struct xtables_target *t;
- bool table_set = false;
- bool invert = false;
- int wait = 0;
-
- /* re-set optind to 0 in case do_command4 gets called
- * a second time */
- optind = 0;
-
- /* clear mflags in case do_command4 gets called a second time
- * (we clear the global list of all matches for security)*/
- for (m = xtables_matches; m; m = m->next)
- m->mflags = 0;
-
- for (t = xtables_targets; t; t = t->next) {
- t->tflags = 0;
- t->used = 0;
- }
-
- /* Suppress error messages: we may add new options if we
- demand-load a protocol. */
- opterr = 0;
-
- opts = xt_params->orig_opts;
- while ((cs->c = getopt_long(argc, argv, xt_params->optstring,
- opts, NULL)) != -1) {
- switch (cs->c) {
- /*
- * Command selection
- */
- case 'A':
- add_command(&p->command, CMD_APPEND, CMD_NONE, invert);
- p->chain = optarg;
- break;
-
- case 'C':
- add_command(&p->command, CMD_CHECK, CMD_NONE, invert);
- p->chain = optarg;
- break;
-
- case 'D':
- add_command(&p->command, CMD_DELETE, CMD_NONE, invert);
- p->chain = optarg;
- if (xs_has_arg(argc, argv)) {
- p->rulenum = parse_rulenumber(argv[optind++]);
- p->command = CMD_DELETE_NUM;
- }
- break;
-
- case 'R':
- add_command(&p->command, CMD_REPLACE, CMD_NONE, invert);
- p->chain = optarg;
- if (xs_has_arg(argc, argv))
- p->rulenum = parse_rulenumber(argv[optind++]);
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires a rule number",
- cmd2char(CMD_REPLACE));
- break;
-
- case 'I':
- add_command(&p->command, CMD_INSERT, CMD_NONE, invert);
- p->chain = optarg;
- if (xs_has_arg(argc, argv))
- p->rulenum = parse_rulenumber(argv[optind++]);
- else
- p->rulenum = 1;
- break;
-
- case 'L':
- add_command(&p->command, CMD_LIST,
- CMD_ZERO | CMD_ZERO_NUM, invert);
- if (optarg)
- p->chain = optarg;
- else if (xs_has_arg(argc, argv))
- p->chain = argv[optind++];
- if (xs_has_arg(argc, argv))
- p->rulenum = parse_rulenumber(argv[optind++]);
- break;
-
- case 'S':
- add_command(&p->command, CMD_LIST_RULES,
- CMD_ZERO|CMD_ZERO_NUM, invert);
- if (optarg)
- p->chain = optarg;
- else if (xs_has_arg(argc, argv))
- p->chain = argv[optind++];
- if (xs_has_arg(argc, argv))
- p->rulenum = parse_rulenumber(argv[optind++]);
- break;
-
- case 'F':
- add_command(&p->command, CMD_FLUSH, CMD_NONE, invert);
- if (optarg)
- p->chain = optarg;
- else if (xs_has_arg(argc, argv))
- p->chain = argv[optind++];
- break;
-
- case 'Z':
- add_command(&p->command, CMD_ZERO,
- CMD_LIST|CMD_LIST_RULES, invert);
- if (optarg)
- p->chain = optarg;
- else if (xs_has_arg(argc, argv))
- p->chain = argv[optind++];
- if (xs_has_arg(argc, argv)) {
- p->rulenum = parse_rulenumber(argv[optind++]);
- p->command = CMD_ZERO_NUM;
- }
- break;
-
- case 'N':
- parse_chain(optarg);
- add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE,
- invert);
- p->chain = optarg;
- break;
-
- case 'X':
- add_command(&p->command, CMD_DELETE_CHAIN, CMD_NONE,
- invert);
- if (optarg)
- p->chain = optarg;
- else if (xs_has_arg(argc, argv))
- p->chain = argv[optind++];
- break;
-
- case 'E':
- add_command(&p->command, CMD_RENAME_CHAIN, CMD_NONE,
- invert);
- p->chain = optarg;
- if (xs_has_arg(argc, argv))
- p->newname = argv[optind++];
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires old-chain-name and "
- "new-chain-name",
- cmd2char(CMD_RENAME_CHAIN));
- break;
-
- case 'P':
- add_command(&p->command, CMD_SET_POLICY, CMD_NONE,
- invert);
- p->chain = optarg;
- if (xs_has_arg(argc, argv))
- p->policy = argv[optind++];
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires a chain and a policy",
- cmd2char(CMD_SET_POLICY));
- break;
-
- case 'h':
- if (!optarg)
- optarg = argv[optind];
-
- /* iptables -p icmp -h */
- if (!cs->matches && cs->protocol)
- xtables_find_match(cs->protocol,
- XTF_TRY_LOAD, &cs->matches);
-
- xt_params->print_help(cs->matches);
- p->command = CMD_NONE;
- return;
-
- /*
- * Option selection
- */
- case 'p':
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_PROTOCOL,
- &args->invflags, invert);
-
- /* Canonicalize into lower case */
- for (cs->protocol = argv[optind - 1];
- *cs->protocol; cs->protocol++)
- *cs->protocol = tolower(*cs->protocol);
-
- cs->protocol = argv[optind - 1];
- args->proto = xtables_parse_protocol(cs->protocol);
-
- if (args->proto == 0 &&
- (args->invflags & XT_INV_PROTO))
- xtables_error(PARAMETER_PROBLEM,
- "rule would never match protocol");
-
- /* This needs to happen here to parse extensions */
- if (p->proto_parse)
- p->proto_parse(cs, args);
- break;
-
- case 's':
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_SOURCE,
- &args->invflags, invert);
- args->shostnetworkmask = argv[optind - 1];
- break;
-
- case 'd':
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_DESTINATION,
- &args->invflags, invert);
- args->dhostnetworkmask = argv[optind - 1];
- break;
-
-#ifdef IPT_F_GOTO
- case 'g':
- set_option(&cs->options, OPT_JUMP, &args->invflags,
- invert);
- args->goto_set = true;
- cs->jumpto = xt_parse_target(optarg);
- break;
-#endif
-
- case 2:/* src-mac */
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_S_MAC, &args->invflags,
- invert);
- args->src_mac = argv[optind - 1];
- break;
-
- case 3:/* dst-mac */
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_D_MAC, &args->invflags,
- invert);
- args->dst_mac = argv[optind - 1];
- break;
-
- case 'l':/* hardware length */
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_H_LENGTH, &args->invflags,
- invert);
- args->arp_hlen = argv[optind - 1];
- break;
-
- case 8: /* was never supported, not even in arptables-legacy */
- xtables_error(PARAMETER_PROBLEM, "not supported");
- case 4:/* opcode */
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_OPCODE, &args->invflags,
- invert);
- args->arp_opcode = argv[optind - 1];
- break;
-
- case 5:/* h-type */
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_H_TYPE, &args->invflags,
- invert);
- args->arp_htype = argv[optind - 1];
- break;
-
- case 6:/* proto-type */
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_P_TYPE, &args->invflags,
- invert);
- args->arp_ptype = argv[optind - 1];
- break;
-
- case 'j':
- set_option(&cs->options, OPT_JUMP, &args->invflags,
- invert);
- command_jump(cs, argv[optind - 1]);
- break;
-
- case 'i':
- check_empty_interface(args, optarg);
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_VIANAMEIN,
- &args->invflags, invert);
- xtables_parse_interface(argv[optind - 1],
- args->iniface,
- args->iniface_mask);
- break;
-
- case 'o':
- check_empty_interface(args, optarg);
- check_inverse(args, optarg, &invert, &optind, argc);
- set_option(&cs->options, OPT_VIANAMEOUT,
- &args->invflags, invert);
- xtables_parse_interface(argv[optind - 1],
- args->outiface,
- args->outiface_mask);
- break;
-
- case 'f':
- if (args->family == AF_INET6) {
- xtables_error(PARAMETER_PROBLEM,
- "`-f' is not supported in IPv6, "
- "use -m frag instead");
- }
- set_option(&cs->options, OPT_FRAGMENT, &args->invflags,
- invert);
- args->flags |= IPT_F_FRAG;
- break;
-
- case 'v':
- if (!p->verbose)
- set_option(&cs->options, OPT_VERBOSE,
- &args->invflags, invert);
- p->verbose++;
- break;
-
- case 'm':
- command_match(cs, invert);
- break;
-
- case 'n':
- set_option(&cs->options, OPT_NUMERIC, &args->invflags,
- invert);
- break;
-
- case 't':
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "unexpected ! flag before --table");
- if (p->restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option cannot be used in %s.\n",
- xt_params->program_name);
- p->table = optarg;
- table_set = true;
- break;
-
- case 'x':
- set_option(&cs->options, OPT_EXPANDED, &args->invflags,
- invert);
- break;
-
- case 'V':
- if (invert)
- printf("Not %s ;-)\n", prog_vers);
- else
- printf("%s v%s\n",
- prog_name, prog_vers);
- exit(0);
-
- case 'w':
- if (p->restore) {
- xtables_error(PARAMETER_PROBLEM,
- "You cannot use `-w' from "
- "iptables-restore");
- }
-
- wait = parse_wait_time(argc, argv);
- break;
-
- case 'W':
- if (p->restore) {
- xtables_error(PARAMETER_PROBLEM,
- "You cannot use `-W' from "
- "iptables-restore");
- }
-
- parse_wait_interval(argc, argv, &wait_interval);
- wait_interval_set = true;
- break;
-
- case '0':
- set_option(&cs->options, OPT_LINENUMBERS,
- &args->invflags, invert);
- break;
-
- case 'M':
- xtables_modprobe_program = optarg;
- break;
-
- case 'c':
- set_option(&cs->options, OPT_COUNTERS, &args->invflags,
- invert);
- args->pcnt = optarg;
- args->bcnt = strchr(args->pcnt + 1, ',');
- if (args->bcnt)
- args->bcnt++;
- if (!args->bcnt && xs_has_arg(argc, argv))
- args->bcnt = argv[optind++];
- if (!args->bcnt)
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires packet and byte counter",
- opt2char(OPT_COUNTERS));
-
- if (sscanf(args->pcnt, "%llu", &args->pcnt_cnt) != 1)
- xtables_error(PARAMETER_PROBLEM,
- "-%c packet counter not numeric",
- opt2char(OPT_COUNTERS));
-
- if (sscanf(args->bcnt, "%llu", &args->bcnt_cnt) != 1)
- xtables_error(PARAMETER_PROBLEM,
- "-%c byte counter not numeric",
- opt2char(OPT_COUNTERS));
- break;
-
- case '4':
- if (args->family == AF_INET)
- break;
-
- if (p->restore && args->family == AF_INET6)
- return;
-
- exit_tryhelp(2, line);
-
- case '6':
- if (args->family == AF_INET6)
- break;
-
- if (p->restore && args->family == AF_INET)
- return;
-
- exit_tryhelp(2, line);
-
- case 1: /* non option */
- if (optarg[0] == '!' && optarg[1] == '\0') {
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "multiple consecutive ! not"
- " allowed");
- invert = true;
- optarg[0] = '\0';
- continue;
- }
- fprintf(stderr, "Bad argument `%s'\n", optarg);
- exit_tryhelp(2, line);
-
- default:
- if (command_default(cs, xt_params, invert))
- /* cf. ip6tables.c */
- continue;
- break;
- }
- invert = false;
- }
-
- if (strcmp(p->table, "nat") == 0 &&
- ((p->policy != NULL && strcmp(p->policy, "DROP") == 0) ||
- (cs->jumpto != NULL && strcmp(cs->jumpto, "DROP") == 0)))
- xtables_error(PARAMETER_PROBLEM,
- "\nThe \"nat\" table is not intended for filtering, "
- "the use of DROP is therefore inhibited.\n\n");
-
- if (!wait && wait_interval_set)
- xtables_error(PARAMETER_PROBLEM,
- "--wait-interval only makes sense with --wait\n");
-
- for (matchp = cs->matches; matchp; matchp = matchp->next)
- xtables_option_mfcall(matchp->match);
- if (cs->target != NULL)
- xtables_option_tfcall(cs->target);
-
- /* Fix me: must put inverse options checking here --MN */
-
- if (optind < argc)
- xtables_error(PARAMETER_PROBLEM,
- "unknown arguments found on commandline");
- if (!p->command)
- xtables_error(PARAMETER_PROBLEM, "no command specified");
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "nothing appropriate following !");
-
- if (p->post_parse)
- p->post_parse(p->command, cs, args);
-
- if (p->command == CMD_REPLACE &&
- (args->s.naddrs != 1 || args->d.naddrs != 1))
- xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
- "specify a unique address");
-
- generic_opt_check(p->command, cs->options);
-
- if (p->chain != NULL && strlen(p->chain) >= XT_EXTENSION_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "chain name `%s' too long (must be under %u chars)",
- p->chain, XT_EXTENSION_MAXNAMELEN);
-
- if (p->command == CMD_APPEND ||
- p->command == CMD_DELETE ||
- p->command == CMD_DELETE_NUM ||
- p->command == CMD_CHECK ||
- p->command == CMD_INSERT ||
- p->command == CMD_REPLACE) {
- if (strcmp(p->chain, "PREROUTING") == 0
- || strcmp(p->chain, "INPUT") == 0) {
- /* -o not valid with incoming packets. */
- if (cs->options & OPT_VIANAMEOUT)
- xtables_error(PARAMETER_PROBLEM,
- "Can't use -%c with %s\n",
- opt2char(OPT_VIANAMEOUT),
- p->chain);
- }
-
- if (strcmp(p->chain, "POSTROUTING") == 0
- || strcmp(p->chain, "OUTPUT") == 0) {
- /* -i not valid with outgoing packets */
- if (cs->options & OPT_VIANAMEIN)
- xtables_error(PARAMETER_PROBLEM,
- "Can't use -%c with %s\n",
- opt2char(OPT_VIANAMEIN),
- p->chain);
- }
- }
-}
-
int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
bool restore)
{
@@ -703,6 +148,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
struct xt_cmd_parse p = {
.table = *table,
.restore = restore,
+ .line = line,
.proto_parse = h->ops->proto_parse,
.post_parse = h->ops->post_parse,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 08/11] xshared: Store parsed wait and wait_interval in xtables_args
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (6 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 07/11] xshared: Move do_parse to shared space Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 09/11] nft: Move proto_parse and post_parse callbacks to xshared Phil Sutter
` (2 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
While nft-variants don't care, legacy ones do.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xshared.c | 8 +++-----
iptables/xshared.h | 2 ++
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 7702d899a3586..021402ea6165e 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1311,11 +1311,9 @@ void do_parse(int argc, char *argv[],
struct xtables_match *m;
struct xtables_rule_match *matchp;
bool wait_interval_set = false;
- struct timeval wait_interval;
struct xtables_target *t;
bool table_set = false;
bool invert = false;
- int wait = 0;
/* re-set optind to 0 in case do_command4 gets called
* a second time */
@@ -1658,7 +1656,7 @@ void do_parse(int argc, char *argv[],
"iptables-restore");
}
- wait = parse_wait_time(argc, argv);
+ args->wait = parse_wait_time(argc, argv);
break;
case 'W':
@@ -1668,7 +1666,7 @@ void do_parse(int argc, char *argv[],
"iptables-restore");
}
- parse_wait_interval(argc, argv, &wait_interval);
+ parse_wait_interval(argc, argv, &args->wait_interval);
wait_interval_set = true;
break;
@@ -1753,7 +1751,7 @@ void do_parse(int argc, char *argv[],
"\nThe \"nat\" table is not intended for filtering, "
"the use of DROP is therefore inhibited.\n\n");
- if (!wait && wait_interval_set)
+ if (!args->wait && wait_interval_set)
xtables_error(PARAMETER_PROBLEM,
"--wait-interval only makes sense with --wait\n");
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 2737ba4b11c25..6ac1330537731 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -293,6 +293,8 @@ struct xtables_args {
const char *arp_hlen, *arp_opcode;
const char *arp_htype, *arp_ptype;
unsigned long long pcnt_cnt, bcnt_cnt;
+ int wait;
+ struct timeval wait_interval;
};
struct xt_cmd_parse {
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 09/11] nft: Move proto_parse and post_parse callbacks to xshared
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (7 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 08/11] xshared: Store parsed wait and wait_interval in xtables_args Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 10/11] iptables: Use xtables' do_parse() function Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 11/11] ip6tables: Use the shared do_parse, too Phil Sutter
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
They are not nft-variant-specific and may therefore be shared with
legacy.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-ipv4.c | 59 +--------------------
iptables/nft-ipv6.c | 76 +-------------------------
iptables/xshared.c | 126 ++++++++++++++++++++++++++++++++++++++++++++
iptables/xshared.h | 9 ++++
4 files changed, 139 insertions(+), 131 deletions(-)
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index f36260980e829..2588babd395a5 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -274,61 +274,6 @@ static void nft_ipv4_save_rule(const void *data, unsigned int format)
&cs->fw, format);
}
-static void nft_ipv4_proto_parse(struct iptables_command_state *cs,
- struct xtables_args *args)
-{
- cs->fw.ip.proto = args->proto;
- cs->fw.ip.invflags = args->invflags;
-}
-
-static void nft_ipv4_post_parse(int command,
- struct iptables_command_state *cs,
- struct xtables_args *args)
-{
- cs->fw.ip.flags = args->flags;
- /* We already set invflags in proto_parse, but we need to refresh it
- * to include new parsed options.
- */
- cs->fw.ip.invflags = args->invflags;
-
- memcpy(cs->fw.ip.iniface, args->iniface, IFNAMSIZ);
- memcpy(cs->fw.ip.iniface_mask,
- args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
-
- memcpy(cs->fw.ip.outiface, args->outiface, IFNAMSIZ);
- memcpy(cs->fw.ip.outiface_mask,
- args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
-
- if (args->goto_set)
- cs->fw.ip.flags |= IPT_F_GOTO;
-
- cs->counters.pcnt = args->pcnt_cnt;
- cs->counters.bcnt = args->bcnt_cnt;
-
- if (command & (CMD_REPLACE | CMD_INSERT |
- CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
- if (!(cs->options & OPT_DESTINATION))
- args->dhostnetworkmask = "0.0.0.0/0";
- if (!(cs->options & OPT_SOURCE))
- args->shostnetworkmask = "0.0.0.0/0";
- }
-
- if (args->shostnetworkmask)
- xtables_ipparse_multiple(args->shostnetworkmask,
- &args->s.addr.v4, &args->s.mask.v4,
- &args->s.naddrs);
- if (args->dhostnetworkmask)
- xtables_ipparse_multiple(args->dhostnetworkmask,
- &args->d.addr.v4, &args->d.mask.v4,
- &args->d.naddrs);
-
- if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
- (cs->fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
- xtables_error(PARAMETER_PROBLEM,
- "! not allowed with multiple"
- " source or destination IP addresses");
-}
-
static void xlate_ipv4_addr(const char *selector, const struct in_addr *addr,
const struct in_addr *mask,
bool inv, struct xt_xlate *xl)
@@ -510,8 +455,8 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.print_rule = nft_ipv4_print_rule,
.save_rule = nft_ipv4_save_rule,
.save_chain = nft_ipv46_save_chain,
- .proto_parse = nft_ipv4_proto_parse,
- .post_parse = nft_ipv4_post_parse,
+ .proto_parse = ipv4_proto_parse,
+ .post_parse = ipv4_post_parse,
.parse_target = nft_ipv46_parse_target,
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = nft_clear_iptables_command_state,
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 132130880a43a..6d288112abbfa 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -236,78 +236,6 @@ static void nft_ipv6_save_rule(const void *data, unsigned int format)
&cs->fw6, format);
}
-/* These are invalid numbers as upper layer protocol */
-static int is_exthdr(uint16_t proto)
-{
- return (proto == IPPROTO_ROUTING ||
- proto == IPPROTO_FRAGMENT ||
- proto == IPPROTO_AH ||
- proto == IPPROTO_DSTOPTS);
-}
-
-static void nft_ipv6_proto_parse(struct iptables_command_state *cs,
- struct xtables_args *args)
-{
- cs->fw6.ipv6.proto = args->proto;
- cs->fw6.ipv6.invflags = args->invflags;
-
- if (is_exthdr(cs->fw6.ipv6.proto)
- && (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0)
- fprintf(stderr,
- "Warning: never matched protocol: %s. "
- "use extension match instead.\n",
- cs->protocol);
-}
-
-static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs,
- struct xtables_args *args)
-{
- cs->fw6.ipv6.flags = args->flags;
- /* We already set invflags in proto_parse, but we need to refresh it
- * to include new parsed options.
- */
- cs->fw6.ipv6.invflags = args->invflags;
-
- memcpy(cs->fw6.ipv6.iniface, args->iniface, IFNAMSIZ);
- memcpy(cs->fw6.ipv6.iniface_mask,
- args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
-
- memcpy(cs->fw6.ipv6.outiface, args->outiface, IFNAMSIZ);
- memcpy(cs->fw6.ipv6.outiface_mask,
- args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
-
- if (args->goto_set)
- cs->fw6.ipv6.flags |= IP6T_F_GOTO;
-
- cs->fw6.counters.pcnt = args->pcnt_cnt;
- cs->fw6.counters.bcnt = args->bcnt_cnt;
-
- if (command & (CMD_REPLACE | CMD_INSERT |
- CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
- if (!(cs->options & OPT_DESTINATION))
- args->dhostnetworkmask = "::0/0";
- if (!(cs->options & OPT_SOURCE))
- args->shostnetworkmask = "::0/0";
- }
-
- if (args->shostnetworkmask)
- xtables_ip6parse_multiple(args->shostnetworkmask,
- &args->s.addr.v6,
- &args->s.mask.v6,
- &args->s.naddrs);
- if (args->dhostnetworkmask)
- xtables_ip6parse_multiple(args->dhostnetworkmask,
- &args->d.addr.v6,
- &args->d.mask.v6,
- &args->d.naddrs);
-
- if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
- (cs->fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
- xtables_error(PARAMETER_PROBLEM,
- "! not allowed with multiple"
- " source or destination IP addresses");
-}
-
static void xlate_ipv6_addr(const char *selector, const struct in6_addr *addr,
const struct in6_addr *mask,
int invert, struct xt_xlate *xl)
@@ -495,8 +423,8 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.print_rule = nft_ipv6_print_rule,
.save_rule = nft_ipv6_save_rule,
.save_chain = nft_ipv46_save_chain,
- .proto_parse = nft_ipv6_proto_parse,
- .post_parse = nft_ipv6_post_parse,
+ .proto_parse = ipv6_proto_parse,
+ .post_parse = ipv6_post_parse,
.parse_target = nft_ipv46_parse_target,
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = nft_clear_iptables_command_state,
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 021402ea6165e..1993c89541527 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1813,3 +1813,129 @@ void do_parse(int argc, char *argv[],
}
}
}
+
+void ipv4_proto_parse(struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ cs->fw.ip.proto = args->proto;
+ cs->fw.ip.invflags = args->invflags;
+}
+
+/* These are invalid numbers as upper layer protocol */
+static int is_exthdr(uint16_t proto)
+{
+ return (proto == IPPROTO_ROUTING ||
+ proto == IPPROTO_FRAGMENT ||
+ proto == IPPROTO_AH ||
+ proto == IPPROTO_DSTOPTS);
+}
+
+void ipv6_proto_parse(struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ cs->fw6.ipv6.proto = args->proto;
+ cs->fw6.ipv6.invflags = args->invflags;
+
+ if (is_exthdr(cs->fw6.ipv6.proto)
+ && (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0)
+ fprintf(stderr,
+ "Warning: never matched protocol: %s. "
+ "use extension match instead.\n",
+ cs->protocol);
+}
+
+void ipv4_post_parse(int command, struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ cs->fw.ip.flags = args->flags;
+ /* We already set invflags in proto_parse, but we need to refresh it
+ * to include new parsed options.
+ */
+ cs->fw.ip.invflags = args->invflags;
+
+ memcpy(cs->fw.ip.iniface, args->iniface, IFNAMSIZ);
+ memcpy(cs->fw.ip.iniface_mask,
+ args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+ memcpy(cs->fw.ip.outiface, args->outiface, IFNAMSIZ);
+ memcpy(cs->fw.ip.outiface_mask,
+ args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+ if (args->goto_set)
+ cs->fw.ip.flags |= IPT_F_GOTO;
+
+ cs->counters.pcnt = args->pcnt_cnt;
+ cs->counters.bcnt = args->bcnt_cnt;
+
+ if (command & (CMD_REPLACE | CMD_INSERT |
+ CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
+ if (!(cs->options & OPT_DESTINATION))
+ args->dhostnetworkmask = "0.0.0.0/0";
+ if (!(cs->options & OPT_SOURCE))
+ args->shostnetworkmask = "0.0.0.0/0";
+ }
+
+ if (args->shostnetworkmask)
+ xtables_ipparse_multiple(args->shostnetworkmask,
+ &args->s.addr.v4, &args->s.mask.v4,
+ &args->s.naddrs);
+ if (args->dhostnetworkmask)
+ xtables_ipparse_multiple(args->dhostnetworkmask,
+ &args->d.addr.v4, &args->d.mask.v4,
+ &args->d.naddrs);
+
+ if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
+ (cs->fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
+ xtables_error(PARAMETER_PROBLEM,
+ "! not allowed with multiple"
+ " source or destination IP addresses");
+}
+
+void ipv6_post_parse(int command, struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ cs->fw6.ipv6.flags = args->flags;
+ /* We already set invflags in proto_parse, but we need to refresh it
+ * to include new parsed options.
+ */
+ cs->fw6.ipv6.invflags = args->invflags;
+
+ memcpy(cs->fw6.ipv6.iniface, args->iniface, IFNAMSIZ);
+ memcpy(cs->fw6.ipv6.iniface_mask,
+ args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+ memcpy(cs->fw6.ipv6.outiface, args->outiface, IFNAMSIZ);
+ memcpy(cs->fw6.ipv6.outiface_mask,
+ args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+ if (args->goto_set)
+ cs->fw6.ipv6.flags |= IP6T_F_GOTO;
+
+ cs->fw6.counters.pcnt = args->pcnt_cnt;
+ cs->fw6.counters.bcnt = args->bcnt_cnt;
+
+ if (command & (CMD_REPLACE | CMD_INSERT |
+ CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
+ if (!(cs->options & OPT_DESTINATION))
+ args->dhostnetworkmask = "::0/0";
+ if (!(cs->options & OPT_SOURCE))
+ args->shostnetworkmask = "::0/0";
+ }
+
+ if (args->shostnetworkmask)
+ xtables_ip6parse_multiple(args->shostnetworkmask,
+ &args->s.addr.v6,
+ &args->s.mask.v6,
+ &args->s.naddrs);
+ if (args->dhostnetworkmask)
+ xtables_ip6parse_multiple(args->dhostnetworkmask,
+ &args->d.addr.v6,
+ &args->d.mask.v6,
+ &args->d.naddrs);
+
+ if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
+ (cs->fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
+ xtables_error(PARAMETER_PROBLEM,
+ "! not allowed with multiple"
+ " source or destination IP addresses");
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 6ac1330537731..296b3510226f3 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -319,4 +319,13 @@ void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args);
+void ipv4_proto_parse(struct iptables_command_state *cs,
+ struct xtables_args *args);
+void ipv6_proto_parse(struct iptables_command_state *cs,
+ struct xtables_args *args);
+void ipv4_post_parse(int command, struct iptables_command_state *cs,
+ struct xtables_args *args);
+void ipv6_post_parse(int command, struct iptables_command_state *cs,
+ struct xtables_args *args);
+
#endif /* IPTABLES_XSHARED_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 10/11] iptables: Use xtables' do_parse() function
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (8 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 09/11] nft: Move proto_parse and post_parse callbacks to xshared Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 11/11] ip6tables: Use the shared do_parse, too Phil Sutter
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
To do so, a few conversions are needed:
- Make use of xt_params->optstring
- Make use of xt_params->print_help callback
- Switch to using a proto_parse callback
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/iptables.c | 484 +++-----------------------------------------
iptables/xshared.c | 3 +
2 files changed, 36 insertions(+), 451 deletions(-)
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 7dc4cbc1c9c22..d1bc73f5a2021 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -87,21 +87,12 @@ static struct option original_opts[] = {
struct xtables_globals iptables_globals = {
.option_offset = 0,
.program_version = PACKAGE_VERSION " (legacy)",
+ .optstring = OPTSTRING_COMMON "R:S::W::" "46bfg:h::m:nvw::x",
.orig_opts = original_opts,
.compat_rev = xtables_compatible_revision,
+ .print_help = xtables_printhelp,
};
-#define opts iptables_globals.opts
-#define prog_name iptables_globals.program_name
-#define prog_vers iptables_globals.program_version
-
-static void
-exit_printhelp(const struct xtables_rule_match *matches)
-{
- xtables_printhelp(matches);
- exit(0);
-}
-
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
@@ -699,10 +690,21 @@ generate_entry(const struct ipt_entry *fw,
int do_command4(int argc, char *argv[], char **table,
struct xtc_handle **handle, bool restore)
{
+ struct xt_cmd_parse p = {
+ .table = *table,
+ .restore = restore,
+ .line = line,
+ .proto_parse = ipv4_proto_parse,
+ .post_parse = ipv4_post_parse,
+ };
struct iptables_command_state cs = {
.jumpto = "",
.argv = argv,
};
+ struct xtables_args args = {
+ .family = AF_INET,
+ .wait_interval.tv_sec = 1,
+ };
struct ipt_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in_addr *saddrs = NULL, *smasks = NULL;
@@ -710,433 +712,30 @@ int do_command4(int argc, char *argv[], char **table,
struct timeval wait_interval = {
.tv_sec = 1,
};
- bool wait_interval_set = false;
int verbose = 0;
int wait = 0;
const char *chain = NULL;
- const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
unsigned int rulenum = 0, command = 0;
- const char *pcnt = NULL, *bcnt = NULL;
int ret = 1;
- struct xtables_match *m;
- struct xtables_rule_match *matchp;
- struct xtables_target *t;
- unsigned long long cnt;
- bool table_set = false;
- uint16_t invflags = 0;
- bool invert = false;
-
- /* re-set optind to 0 in case do_command4 gets called
- * a second time */
- optind = 0;
-
- /* clear mflags in case do_command4 gets called a second time
- * (we clear the global list of all matches for security)*/
- for (m = xtables_matches; m; m = m->next)
- m->mflags = 0;
-
- for (t = xtables_targets; t; t = t->next) {
- t->tflags = 0;
- t->used = 0;
- }
-
- /* Suppress error messages: we may add new options if we
- demand-load a protocol. */
- opterr = 0;
- opts = xt_params->orig_opts;
- while ((cs.c = getopt_long(argc, argv,
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46",
- opts, NULL)) != -1) {
- switch (cs.c) {
- /*
- * Command selection
- */
- case 'A':
- add_command(&command, CMD_APPEND, CMD_NONE, invert);
- chain = optarg;
- break;
-
- case 'C':
- add_command(&command, CMD_CHECK, CMD_NONE, invert);
- chain = optarg;
- break;
-
- case 'D':
- add_command(&command, CMD_DELETE, CMD_NONE, invert);
- chain = optarg;
- if (xs_has_arg(argc, argv)) {
- rulenum = parse_rulenumber(argv[optind++]);
- command = CMD_DELETE_NUM;
- }
- break;
-
- case 'R':
- add_command(&command, CMD_REPLACE, CMD_NONE, invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires a rule number",
- cmd2char(CMD_REPLACE));
- break;
-
- case 'I':
- add_command(&command, CMD_INSERT, CMD_NONE, invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- else rulenum = 1;
- break;
-
- case 'L':
- add_command(&command, CMD_LIST,
- CMD_ZERO | CMD_ZERO_NUM, invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- break;
-
- case 'S':
- add_command(&command, CMD_LIST_RULES,
- CMD_ZERO|CMD_ZERO_NUM, invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- break;
-
- case 'F':
- add_command(&command, CMD_FLUSH, CMD_NONE, invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- break;
-
- case 'Z':
- add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES,
- invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- if (xs_has_arg(argc, argv)) {
- rulenum = parse_rulenumber(argv[optind++]);
- command = CMD_ZERO_NUM;
- }
- break;
-
- case 'N':
- parse_chain(optarg);
- add_command(&command, CMD_NEW_CHAIN, CMD_NONE, invert);
- chain = optarg;
- break;
-
- case 'X':
- add_command(&command, CMD_DELETE_CHAIN, CMD_NONE,
- invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- break;
-
- case 'E':
- add_command(&command, CMD_RENAME_CHAIN, CMD_NONE,
- invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- newname = argv[optind++];
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires old-chain-name and "
- "new-chain-name",
- cmd2char(CMD_RENAME_CHAIN));
- break;
-
- case 'P':
- add_command(&command, CMD_SET_POLICY, CMD_NONE,
- invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- policy = argv[optind++];
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires a chain and a policy",
- cmd2char(CMD_SET_POLICY));
- break;
-
- case 'h':
- if (!optarg)
- optarg = argv[optind];
-
- /* iptables -p icmp -h */
- if (!cs.matches && cs.protocol)
- xtables_find_match(cs.protocol,
- XTF_TRY_LOAD, &cs.matches);
-
- exit_printhelp(cs.matches);
-
- /*
- * Option selection
- */
- case 'p':
- set_option(&cs.options, OPT_PROTOCOL, &invflags,
- invert);
-
- /* Canonicalize into lower case */
- for (cs.protocol = optarg; *cs.protocol; cs.protocol++)
- *cs.protocol = tolower(*cs.protocol);
-
- cs.protocol = optarg;
- cs.fw.ip.proto = xtables_parse_protocol(cs.protocol);
-
- if (cs.fw.ip.proto == 0 && (invflags & XT_INV_PROTO))
- xtables_error(PARAMETER_PROBLEM,
- "rule would never match protocol");
- break;
-
- case 's':
- set_option(&cs.options, OPT_SOURCE, &invflags, invert);
- shostnetworkmask = optarg;
- break;
-
- case 'd':
- set_option(&cs.options, OPT_DESTINATION, &invflags,
- invert);
- dhostnetworkmask = optarg;
- break;
-
-#ifdef IPT_F_GOTO
- case 'g':
- set_option(&cs.options, OPT_JUMP, &invflags, invert);
- cs.fw.ip.flags |= IPT_F_GOTO;
- cs.jumpto = xt_parse_target(optarg);
- break;
-#endif
-
- case 'j':
- set_option(&cs.options, OPT_JUMP, &invflags, invert);
- command_jump(&cs, optarg);
- break;
-
-
- case 'i':
- if (*optarg == '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Empty interface is likely to be "
- "undesired");
- set_option(&cs.options, OPT_VIANAMEIN, &invflags,
- invert);
- xtables_parse_interface(optarg,
- cs.fw.ip.iniface,
- cs.fw.ip.iniface_mask);
- break;
-
- case 'o':
- if (*optarg == '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Empty interface is likely to be "
- "undesired");
- set_option(&cs.options, OPT_VIANAMEOUT, &invflags,
- invert);
- xtables_parse_interface(optarg,
- cs.fw.ip.outiface,
- cs.fw.ip.outiface_mask);
- break;
-
- case 'f':
- set_option(&cs.options, OPT_FRAGMENT, &invflags,
- invert);
- cs.fw.ip.flags |= IPT_F_FRAG;
- break;
-
- case 'v':
- if (!verbose)
- set_option(&cs.options, OPT_VERBOSE,
- &invflags, invert);
- verbose++;
- break;
-
- case 'w':
- if (restore) {
- xtables_error(PARAMETER_PROBLEM,
- "You cannot use `-w' from "
- "iptables-restore");
- }
- wait = parse_wait_time(argc, argv);
- break;
- case 'W':
- if (restore) {
- xtables_error(PARAMETER_PROBLEM,
- "You cannot use `-W' from "
- "iptables-restore");
- }
- parse_wait_interval(argc, argv, &wait_interval);
- wait_interval_set = true;
- break;
-
- case 'm':
- command_match(&cs, invert);
- break;
-
- case 'n':
- set_option(&cs.options, OPT_NUMERIC, &invflags,
- invert);
- break;
-
- case 't':
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "unexpected ! flag before --table");
- if (restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option cannot be used in %s.\n",
- xt_params->program_name);
- *table = optarg;
- table_set = true;
- break;
-
- case 'x':
- set_option(&cs.options, OPT_EXPANDED, &invflags,
- invert);
- break;
-
- case 'V':
- if (invert)
- printf("Not %s ;-)\n", prog_vers);
- else
- printf("%s v%s\n",
- prog_name, prog_vers);
- exit(0);
-
- case '0':
- set_option(&cs.options, OPT_LINENUMBERS, &invflags,
- invert);
- break;
-
- case 'M':
- xtables_modprobe_program = optarg;
- break;
-
- case 'c':
-
- set_option(&cs.options, OPT_COUNTERS, &invflags,
- invert);
- pcnt = optarg;
- bcnt = strchr(pcnt + 1, ',');
- if (bcnt)
- bcnt++;
- if (!bcnt && xs_has_arg(argc, argv))
- bcnt = argv[optind++];
- if (!bcnt)
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires packet and byte counter",
- opt2char(OPT_COUNTERS));
-
- if (sscanf(pcnt, "%llu", &cnt) != 1)
- xtables_error(PARAMETER_PROBLEM,
- "-%c packet counter not numeric",
- opt2char(OPT_COUNTERS));
- cs.fw.counters.pcnt = cnt;
-
- if (sscanf(bcnt, "%llu", &cnt) != 1)
- xtables_error(PARAMETER_PROBLEM,
- "-%c byte counter not numeric",
- opt2char(OPT_COUNTERS));
- cs.fw.counters.bcnt = cnt;
- break;
-
- case '4':
- /* This is indeed the IPv4 iptables */
- break;
-
- case '6':
- /* This is not the IPv6 ip6tables */
- if (line != -1)
- return 1; /* success: line ignored */
- fprintf(stderr, "This is the IPv4 version of iptables.\n");
- exit_tryhelp(2, line);
-
- case 1: /* non option */
- if (optarg[0] == '!' && optarg[1] == '\0') {
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "multiple consecutive ! not"
- " allowed");
- invert = true;
- optarg[0] = '\0';
- continue;
- }
- fprintf(stderr, "Bad argument `%s'\n", optarg);
- exit_tryhelp(2, line);
-
- default:
- if (command_default(&cs, &iptables_globals, invert))
- /* cf. ip6tables.c */
- continue;
- break;
- }
- invert = false;
- }
-
- if (!wait && wait_interval_set)
- xtables_error(PARAMETER_PROBLEM,
- "--wait-interval only makes sense with --wait\n");
-
- if (strcmp(*table, "nat") == 0 &&
- ((policy != NULL && strcmp(policy, "DROP") == 0) ||
- (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0)))
- xtables_error(PARAMETER_PROBLEM,
- "\nThe \"nat\" table is not intended for filtering, "
- "the use of DROP is therefore inhibited.\n\n");
-
- for (matchp = cs.matches; matchp; matchp = matchp->next)
- xtables_option_mfcall(matchp->match);
- if (cs.target != NULL)
- xtables_option_tfcall(cs.target);
-
- /* Fix me: must put inverse options checking here --MN */
-
- if (optind < argc)
- xtables_error(PARAMETER_PROBLEM,
- "unknown arguments found on commandline");
- if (!command)
- xtables_error(PARAMETER_PROBLEM, "no command specified");
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "nothing appropriate following !");
-
- cs.fw.ip.invflags = invflags;
-
- if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
- if (!(cs.options & OPT_DESTINATION))
- dhostnetworkmask = "0.0.0.0/0";
- if (!(cs.options & OPT_SOURCE))
- shostnetworkmask = "0.0.0.0/0";
- }
-
- if (shostnetworkmask)
- xtables_ipparse_multiple(shostnetworkmask, &saddrs,
- &smasks, &nsaddrs);
-
- if (dhostnetworkmask)
- xtables_ipparse_multiple(dhostnetworkmask, &daddrs,
- &dmasks, &ndaddrs);
-
- if ((nsaddrs > 1 || ndaddrs > 1) &&
- (cs.fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
- xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
- " source or destination IP addresses");
-
- if (command == CMD_REPLACE && (nsaddrs != 1 || ndaddrs != 1))
- xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
- "specify a unique address");
-
- generic_opt_check(command, cs.options);
+ do_parse(argc, argv, &p, &cs, &args);
+
+ command = p.command;
+ chain = p.chain;
+ *table = p.table;
+ rulenum = p.rulenum;
+ policy = p.policy;
+ newname = p.newname;
+ verbose = p.verbose;
+ wait = args.wait;
+ wait_interval = args.wait_interval;
+ nsaddrs = args.s.naddrs;
+ ndaddrs = args.d.naddrs;
+ saddrs = args.s.addr.v4;
+ daddrs = args.d.addr.v4;
+ smasks = args.s.mask.v4;
+ dmasks = args.d.mask.v4;
/* Attempt to acquire the xtables lock */
if (!restore)
@@ -1160,26 +759,6 @@ int do_command4(int argc, char *argv[], char **table,
|| command == CMD_CHECK
|| command == CMD_INSERT
|| command == CMD_REPLACE) {
- if (strcmp(chain, "PREROUTING") == 0
- || strcmp(chain, "INPUT") == 0) {
- /* -o not valid with incoming packets. */
- if (cs.options & OPT_VIANAMEOUT)
- xtables_error(PARAMETER_PROBLEM,
- "Can't use -%c with %s\n",
- opt2char(OPT_VIANAMEOUT),
- chain);
- }
-
- if (strcmp(chain, "POSTROUTING") == 0
- || strcmp(chain, "OUTPUT") == 0) {
- /* -i not valid with outgoing packets */
- if (cs.options & OPT_VIANAMEIN)
- xtables_error(PARAMETER_PROBLEM,
- "Can't use -%c with %s\n",
- opt2char(OPT_VIANAMEIN),
- chain);
- }
-
if (cs.target && iptc_is_chain(cs.jumpto, *handle)) {
fprintf(stderr,
"Warning: using chain %s, not extension\n",
@@ -1317,6 +896,9 @@ int do_command4(int argc, char *argv[], char **table,
case CMD_SET_POLICY:
ret = iptc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw.counters : NULL, *handle);
break;
+ case CMD_NONE:
+ /* do_parse ignored the line (eg: -4 with ip6tables-restore) */
+ break;
default:
/* We should never reach this... */
exit_tryhelp(2, line);
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 1993c89541527..1bce6715c3a9a 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1864,8 +1864,11 @@ void ipv4_post_parse(int command, struct iptables_command_state *cs,
if (args->goto_set)
cs->fw.ip.flags |= IPT_F_GOTO;
+ /* nft-variants use cs->counters, legacy uses cs->fw.counters */
cs->counters.pcnt = args->pcnt_cnt;
cs->counters.bcnt = args->bcnt_cnt;
+ cs->fw.counters.pcnt = args->pcnt_cnt;
+ cs->fw.counters.bcnt = args->bcnt_cnt;
if (command & (CMD_REPLACE | CMD_INSERT |
CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 11/11] ip6tables: Use the shared do_parse, too
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
` (9 preceding siblings ...)
2021-12-24 17:17 ` [iptables PATCH 10/11] iptables: Use xtables' do_parse() function Phil Sutter
@ 2021-12-24 17:17 ` Phil Sutter
10 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2021-12-24 17:17 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Same change as with iptables, merely have to set IP6T_F_PROTO flag in
ipv6_proto_parse().
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/ip6tables.c | 499 +++----------------------------------------
iptables/xshared.c | 4 +
2 files changed, 37 insertions(+), 466 deletions(-)
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index b4604f83cf8a4..fa3e6c1506e71 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -90,21 +90,12 @@ static struct option original_opts[] = {
struct xtables_globals ip6tables_globals = {
.option_offset = 0,
.program_version = PACKAGE_VERSION " (legacy)",
+ .optstring = OPTSTRING_COMMON "R:S::W::" "46bg:h::m:nvw::x",
.orig_opts = original_opts,
.compat_rev = xtables_compatible_revision,
+ .print_help = xtables_printhelp,
};
-#define opts ip6tables_globals.opts
-#define prog_name ip6tables_globals.program_name
-#define prog_vers ip6tables_globals.program_version
-
-static void
-exit_printhelp(const struct xtables_rule_match *matches)
-{
- xtables_printhelp(matches);
- exit(0);
-}
-
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
@@ -114,15 +105,6 @@ exit_printhelp(const struct xtables_rule_match *matches)
* return global static data.
*/
-/* These are invalid numbers as upper layer protocol */
-static int is_exthdr(uint16_t proto)
-{
- return (proto == IPPROTO_ROUTING ||
- proto == IPPROTO_FRAGMENT ||
- proto == IPPROTO_AH ||
- proto == IPPROTO_DSTOPTS);
-}
-
static int
print_match(const struct xt_entry_match *m,
const struct ip6t_ip6 *ip,
@@ -714,10 +696,21 @@ generate_entry(const struct ip6t_entry *fw,
int do_command6(int argc, char *argv[], char **table,
struct xtc_handle **handle, bool restore)
{
+ struct xt_cmd_parse p = {
+ .table = *table,
+ .restore = restore,
+ .line = line,
+ .proto_parse = ipv6_proto_parse,
+ .post_parse = ipv6_post_parse,
+ };
struct iptables_command_state cs = {
.jumpto = "",
.argv = argv,
};
+ struct xtables_args args = {
+ .family = AF_INET6,
+ .wait_interval.tv_sec = 1,
+ };
struct ip6t_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in6_addr *saddrs = NULL, *daddrs = NULL;
@@ -728,437 +721,28 @@ int do_command6(int argc, char *argv[], char **table,
struct timeval wait_interval = {
.tv_sec = 1,
};
- bool wait_interval_set = false;
const char *chain = NULL;
- const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
unsigned int rulenum = 0, command = 0;
- const char *pcnt = NULL, *bcnt = NULL;
int ret = 1;
- struct xtables_match *m;
- struct xtables_rule_match *matchp;
- struct xtables_target *t;
- unsigned long long cnt;
- bool table_set = false;
- uint16_t invflags = 0;
- bool invert = false;
-
- /* re-set optind to 0 in case do_command6 gets called
- * a second time */
- optind = 0;
-
- /* clear mflags in case do_command6 gets called a second time
- * (we clear the global list of all matches for security)*/
- for (m = xtables_matches; m; m = m->next)
- m->mflags = 0;
-
- for (t = xtables_targets; t; t = t->next) {
- t->tflags = 0;
- t->used = 0;
- }
-
- /* Suppress error messages: we may add new options if we
- demand-load a protocol. */
- opterr = 0;
-
- opts = xt_params->orig_opts;
- while ((cs.c = getopt_long(argc, argv,
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvw::W::nt:m:xc:g:46",
- opts, NULL)) != -1) {
- switch (cs.c) {
- /*
- * Command selection
- */
- case 'A':
- add_command(&command, CMD_APPEND, CMD_NONE, invert);
- chain = optarg;
- break;
-
- case 'C':
- add_command(&command, CMD_CHECK, CMD_NONE, invert);
- chain = optarg;
- break;
-
- case 'D':
- add_command(&command, CMD_DELETE, CMD_NONE, invert);
- chain = optarg;
- if (xs_has_arg(argc, argv)) {
- rulenum = parse_rulenumber(argv[optind++]);
- command = CMD_DELETE_NUM;
- }
- break;
-
- case 'R':
- add_command(&command, CMD_REPLACE, CMD_NONE, invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires a rule number",
- cmd2char(CMD_REPLACE));
- break;
-
- case 'I':
- add_command(&command, CMD_INSERT, CMD_NONE, invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- else rulenum = 1;
- break;
-
- case 'L':
- add_command(&command, CMD_LIST,
- CMD_ZERO | CMD_ZERO_NUM, invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- break;
-
- case 'S':
- add_command(&command, CMD_LIST_RULES,
- CMD_ZERO | CMD_ZERO_NUM, invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- if (xs_has_arg(argc, argv))
- rulenum = parse_rulenumber(argv[optind++]);
- break;
-
- case 'F':
- add_command(&command, CMD_FLUSH, CMD_NONE, invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- break;
-
- case 'Z':
- add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES,
- invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- if (xs_has_arg(argc, argv)) {
- rulenum = parse_rulenumber(argv[optind++]);
- command = CMD_ZERO_NUM;
- }
- break;
-
- case 'N':
- parse_chain(optarg);
- add_command(&command, CMD_NEW_CHAIN, CMD_NONE, invert);
- chain = optarg;
- break;
-
- case 'X':
- add_command(&command, CMD_DELETE_CHAIN, CMD_NONE,
- invert);
- if (optarg) chain = optarg;
- else if (xs_has_arg(argc, argv))
- chain = argv[optind++];
- break;
-
- case 'E':
- add_command(&command, CMD_RENAME_CHAIN, CMD_NONE,
- invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- newname = argv[optind++];
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires old-chain-name and "
- "new-chain-name",
- cmd2char(CMD_RENAME_CHAIN));
- break;
-
- case 'P':
- add_command(&command, CMD_SET_POLICY, CMD_NONE,
- invert);
- chain = optarg;
- if (xs_has_arg(argc, argv))
- policy = argv[optind++];
- else
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires a chain and a policy",
- cmd2char(CMD_SET_POLICY));
- break;
-
- case 'h':
- if (!optarg)
- optarg = argv[optind];
- /* ip6tables -p icmp -h */
- if (!cs.matches && cs.protocol)
- xtables_find_match(cs.protocol, XTF_TRY_LOAD,
- &cs.matches);
-
- exit_printhelp(cs.matches);
-
- /*
- * Option selection
- */
- case 'p':
- set_option(&cs.options, OPT_PROTOCOL, &invflags,
- invert);
-
- /* Canonicalize into lower case */
- for (cs.protocol = optarg; *cs.protocol; cs.protocol++)
- *cs.protocol = tolower(*cs.protocol);
-
- cs.protocol = optarg;
- cs.fw6.ipv6.proto = xtables_parse_protocol(cs.protocol);
- cs.fw6.ipv6.flags |= IP6T_F_PROTO;
-
- if (cs.fw6.ipv6.proto == 0 && (invflags & XT_INV_PROTO))
- xtables_error(PARAMETER_PROBLEM,
- "rule would never match protocol");
-
- if (is_exthdr(cs.fw6.ipv6.proto)
- && (invflags & XT_INV_PROTO) == 0)
- fprintf(stderr,
- "Warning: never matched protocol: %s. "
- "use extension match instead.\n",
- cs.protocol);
- break;
-
- case 's':
- set_option(&cs.options, OPT_SOURCE, &invflags, invert);
- shostnetworkmask = optarg;
- break;
-
- case 'd':
- set_option(&cs.options, OPT_DESTINATION, &invflags,
- invert);
- dhostnetworkmask = optarg;
- break;
-
-#ifdef IP6T_F_GOTO
- case 'g':
- set_option(&cs.options, OPT_JUMP, &invflags, invert);
- cs.fw6.ipv6.flags |= IP6T_F_GOTO;
- cs.jumpto = xt_parse_target(optarg);
- break;
-#endif
-
- case 'j':
- set_option(&cs.options, OPT_JUMP, &invflags, invert);
- command_jump(&cs, optarg);
- break;
-
-
- case 'i':
- if (*optarg == '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Empty interface is likely to be "
- "undesired");
- set_option(&cs.options, OPT_VIANAMEIN, &invflags,
- invert);
- xtables_parse_interface(optarg,
- cs.fw6.ipv6.iniface,
- cs.fw6.ipv6.iniface_mask);
- break;
-
- case 'o':
- if (*optarg == '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Empty interface is likely to be "
- "undesired");
- set_option(&cs.options, OPT_VIANAMEOUT, &invflags,
- invert);
- xtables_parse_interface(optarg,
- cs.fw6.ipv6.outiface,
- cs.fw6.ipv6.outiface_mask);
- break;
-
- case 'v':
- if (!verbose)
- set_option(&cs.options, OPT_VERBOSE,
- &invflags, invert);
- verbose++;
- break;
-
- case 'w':
- if (restore) {
- xtables_error(PARAMETER_PROBLEM,
- "You cannot use `-w' from "
- "ip6tables-restore");
- }
- wait = parse_wait_time(argc, argv);
- break;
-
- case 'W':
- if (restore) {
- xtables_error(PARAMETER_PROBLEM,
- "You cannot use `-W' from "
- "ip6tables-restore");
- }
- parse_wait_interval(argc, argv, &wait_interval);
- wait_interval_set = true;
- break;
-
- case 'm':
- command_match(&cs, invert);
- break;
-
- case 'n':
- set_option(&cs.options, OPT_NUMERIC, &invflags, invert);
- break;
-
- case 't':
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "unexpected ! flag before --table");
- if (restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option cannot be used in %s.\n",
- xt_params->program_name);
- *table = optarg;
- table_set = true;
- break;
-
- case 'x':
- set_option(&cs.options, OPT_EXPANDED, &invflags,
- invert);
- break;
-
- case 'V':
- if (invert)
- printf("Not %s ;-)\n", prog_vers);
- else
- printf("%s v%s\n",
- prog_name, prog_vers);
- exit(0);
-
- case '0':
- set_option(&cs.options, OPT_LINENUMBERS, &invflags,
- invert);
- break;
-
- case 'M':
- xtables_modprobe_program = optarg;
- break;
-
- case 'c':
-
- set_option(&cs.options, OPT_COUNTERS, &invflags,
- invert);
- pcnt = optarg;
- bcnt = strchr(pcnt + 1, ',');
- if (bcnt)
- bcnt++;
- if (!bcnt && xs_has_arg(argc, argv))
- bcnt = argv[optind++];
- if (!bcnt)
- xtables_error(PARAMETER_PROBLEM,
- "-%c requires packet and byte counter",
- opt2char(OPT_COUNTERS));
-
- if (sscanf(pcnt, "%llu", &cnt) != 1)
- xtables_error(PARAMETER_PROBLEM,
- "-%c packet counter not numeric",
- opt2char(OPT_COUNTERS));
- cs.fw6.counters.pcnt = cnt;
-
- if (sscanf(bcnt, "%llu", &cnt) != 1)
- xtables_error(PARAMETER_PROBLEM,
- "-%c byte counter not numeric",
- opt2char(OPT_COUNTERS));
- cs.fw6.counters.bcnt = cnt;
- break;
-
- case '4':
- /* This is not the IPv4 iptables */
- if (line != -1)
- return 1; /* success: line ignored */
- fprintf(stderr, "This is the IPv6 version of ip6tables.\n");
- exit_tryhelp(2, line);
-
- case '6':
- /* This is indeed the IPv6 ip6tables */
- break;
-
- case 1: /* non option */
- if (optarg[0] == '!' && optarg[1] == '\0') {
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "multiple consecutive ! not"
- " allowed");
- invert = true;
- optarg[0] = '\0';
- continue;
- }
- fprintf(stderr, "Bad argument `%s'\n", optarg);
- exit_tryhelp(2, line);
-
- default:
- if (command_default(&cs, &ip6tables_globals, invert))
- /*
- * If new options were loaded, we must retry
- * getopt immediately and not allow
- * invert=false to be executed.
- */
- continue;
- break;
- }
- invert = false;
- }
-
- if (!wait && wait_interval_set)
- xtables_error(PARAMETER_PROBLEM,
- "--wait-interval only makes sense with --wait\n");
-
- if (strcmp(*table, "nat") == 0 &&
- ((policy != NULL && strcmp(policy, "DROP") == 0) ||
- (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0)))
- xtables_error(PARAMETER_PROBLEM,
- "\nThe \"nat\" table is not intended for filtering, "
- "the use of DROP is therefore inhibited.\n\n");
-
- for (matchp = cs.matches; matchp; matchp = matchp->next)
- xtables_option_mfcall(matchp->match);
- if (cs.target != NULL)
- xtables_option_tfcall(cs.target);
-
- /* Fix me: must put inverse options checking here --MN */
-
- if (optind < argc)
- xtables_error(PARAMETER_PROBLEM,
- "unknown arguments found on commandline");
- if (!command)
- xtables_error(PARAMETER_PROBLEM, "no command specified");
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "nothing appropriate following !");
-
- cs.fw6.ipv6.invflags = invflags;
-
- if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
- if (!(cs.options & OPT_DESTINATION))
- dhostnetworkmask = "::0/0";
- if (!(cs.options & OPT_SOURCE))
- shostnetworkmask = "::0/0";
- }
-
- if (shostnetworkmask)
- xtables_ip6parse_multiple(shostnetworkmask, &saddrs,
- &smasks, &nsaddrs);
-
- if (dhostnetworkmask)
- xtables_ip6parse_multiple(dhostnetworkmask, &daddrs,
- &dmasks, &ndaddrs);
-
- if ((nsaddrs > 1 || ndaddrs > 1) &&
- (cs.fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
- xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
- " source or destination IP addresses");
-
- if (command == CMD_REPLACE && (nsaddrs != 1 || ndaddrs != 1))
- xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
- "specify a unique address");
-
- generic_opt_check(command, cs.options);
+ do_parse(argc, argv, &p, &cs, &args);
+
+ command = p.command;
+ chain = p.chain;
+ *table = p.table;
+ rulenum = p.rulenum;
+ policy = p.policy;
+ newname = p.newname;
+ verbose = p.verbose;
+ wait = args.wait;
+ wait_interval = args.wait_interval;
+ nsaddrs = args.s.naddrs;
+ ndaddrs = args.d.naddrs;
+ saddrs = args.s.addr.v6;
+ daddrs = args.d.addr.v6;
+ smasks = args.s.mask.v6;
+ dmasks = args.d.mask.v6;
/* Attempt to acquire the xtables lock */
if (!restore)
@@ -1182,26 +766,6 @@ int do_command6(int argc, char *argv[], char **table,
|| command == CMD_CHECK
|| command == CMD_INSERT
|| command == CMD_REPLACE) {
- if (strcmp(chain, "PREROUTING") == 0
- || strcmp(chain, "INPUT") == 0) {
- /* -o not valid with incoming packets. */
- if (cs.options & OPT_VIANAMEOUT)
- xtables_error(PARAMETER_PROBLEM,
- "Can't use -%c with %s\n",
- opt2char(OPT_VIANAMEOUT),
- chain);
- }
-
- if (strcmp(chain, "POSTROUTING") == 0
- || strcmp(chain, "OUTPUT") == 0) {
- /* -i not valid with outgoing packets */
- if (cs.options & OPT_VIANAMEIN)
- xtables_error(PARAMETER_PROBLEM,
- "Can't use -%c with %s\n",
- opt2char(OPT_VIANAMEIN),
- chain);
- }
-
if (cs.target && ip6tc_is_chain(cs.jumpto, *handle)) {
fprintf(stderr,
"Warning: using chain %s, not extension\n",
@@ -1337,6 +901,9 @@ int do_command6(int argc, char *argv[], char **table,
case CMD_SET_POLICY:
ret = ip6tc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw6.counters : NULL, *handle);
break;
+ case CMD_NONE:
+ /* do_parse ignored the line (eg: -4 with ip6tables-restore) */
+ break;
default:
/* We should never reach this... */
exit_tryhelp(2, line);
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 1bce6715c3a9a..3b363e72361e0 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1836,6 +1836,10 @@ void ipv6_proto_parse(struct iptables_command_state *cs,
cs->fw6.ipv6.proto = args->proto;
cs->fw6.ipv6.invflags = args->invflags;
+ /* this is needed for ip6tables-legacy only */
+ args->flags |= IP6T_F_PROTO;
+ cs->fw6.ipv6.flags |= IP6T_F_PROTO;
+
if (is_exthdr(cs->fw6.ipv6.proto)
&& (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0)
fprintf(stderr,
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse()
2021-12-24 17:17 ` [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse() Phil Sutter
@ 2022-01-10 21:29 ` Pablo Neira Ayuso
2022-01-10 21:35 ` Pablo Neira Ayuso
2022-01-11 10:34 ` Phil Sutter
0 siblings, 2 replies; 15+ messages in thread
From: Pablo Neira Ayuso @ 2022-01-10 21:29 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel
On Fri, Dec 24, 2021 at 06:17:49PM +0100, Phil Sutter wrote:
[...]
> diff --git a/iptables/xshared.h b/iptables/xshared.h
> index dde94b7335f6a..1954168f64058 100644
> --- a/iptables/xshared.h
> +++ b/iptables/xshared.h
[...]
> struct xt_cmd_parse {
> unsigned int command;
> unsigned int rulenum;
> @@ -272,6 +305,11 @@ struct xt_cmd_parse {
> bool restore;
> int verbose;
> bool xlate;
Probably wrap these two common functions between legacy and nft in a
structure? Something like: struct nft_parse_ops...
> + void (*proto_parse)(struct iptables_command_state *cs,
> + struct xtables_args *args);
> + void (*post_parse)(int command,
> + struct iptables_command_state *cs,
> + struct xtables_args *args);
> };
>
> #endif /* IPTABLES_XSHARED_H */
> diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
> index 9d312b244657e..b0b27695cbb8c 100644
> --- a/iptables/xtables-translate.c
> +++ b/iptables/xtables-translate.c
> @@ -252,6 +252,8 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
> .table = *table,
> .restore = restore,
> .xlate = true,
> + .proto_parse = h->ops->proto_parse,
> + .post_parse = h->ops->post_parse,
so you could just do:
.parse = h->ops->parse,
and if you need to extend this structure in the future for whatever
revolutionary reason, you will need to update this part of the code to
do:
.another_parse = h->ops->another_parse,
Apart from this, anything else LGTM.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse()
2022-01-10 21:29 ` Pablo Neira Ayuso
@ 2022-01-10 21:35 ` Pablo Neira Ayuso
2022-01-11 10:34 ` Phil Sutter
1 sibling, 0 replies; 15+ messages in thread
From: Pablo Neira Ayuso @ 2022-01-10 21:35 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel
On Mon, Jan 10, 2022 at 10:29:37PM +0100, Pablo Neira Ayuso wrote:
> On Fri, Dec 24, 2021 at 06:17:49PM +0100, Phil Sutter wrote:
> [...]
> > diff --git a/iptables/xshared.h b/iptables/xshared.h
> > index dde94b7335f6a..1954168f64058 100644
> > --- a/iptables/xshared.h
> > +++ b/iptables/xshared.h
> [...]
> > struct xt_cmd_parse {
> > unsigned int command;
> > unsigned int rulenum;
> > @@ -272,6 +305,11 @@ struct xt_cmd_parse {
> > bool restore;
> > int verbose;
> > bool xlate;
>
> Probably wrap these two common functions between legacy and nft in a
> structure? Something like: struct nft_parse_ops...
struct xt_parse_ops...
> > + void (*proto_parse)(struct iptables_command_state *cs,
> > + struct xtables_args *args);
> > + void (*post_parse)(int command,
> > + struct iptables_command_state *cs,
> > + struct xtables_args *args);
> > };
> >
> > #endif /* IPTABLES_XSHARED_H */
> > diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
> > index 9d312b244657e..b0b27695cbb8c 100644
> > --- a/iptables/xtables-translate.c
> > +++ b/iptables/xtables-translate.c
> > @@ -252,6 +252,8 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
> > .table = *table,
> > .restore = restore,
> > .xlate = true,
> > + .proto_parse = h->ops->proto_parse,
> > + .post_parse = h->ops->post_parse,
>
> so you could just do:
>
> .parse = h->ops->parse,
>
> and if you need to extend this structure in the future for whatever
> revolutionary reason, you will need to update this part of the code to
^....
you will *not* need
> do:
>
> .another_parse = h->ops->another_parse,
>
> Apart from this, anything else LGTM.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse()
2022-01-10 21:29 ` Pablo Neira Ayuso
2022-01-10 21:35 ` Pablo Neira Ayuso
@ 2022-01-11 10:34 ` Phil Sutter
1 sibling, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2022-01-11 10:34 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Mon, Jan 10, 2022 at 10:29:37PM +0100, Pablo Neira Ayuso wrote:
> On Fri, Dec 24, 2021 at 06:17:49PM +0100, Phil Sutter wrote:
> [...]
> > diff --git a/iptables/xshared.h b/iptables/xshared.h
> > index dde94b7335f6a..1954168f64058 100644
> > --- a/iptables/xshared.h
> > +++ b/iptables/xshared.h
> [...]
> > struct xt_cmd_parse {
> > unsigned int command;
> > unsigned int rulenum;
> > @@ -272,6 +305,11 @@ struct xt_cmd_parse {
> > bool restore;
> > int verbose;
> > bool xlate;
>
> Probably wrap these two common functions between legacy and nft in a
> structure? Something like: struct nft_parse_ops...
Ah yes, thanks for suggesting. Wrapping the callbacks didn't come to
mind despite the need for two assignments everywhere.
I'll fix and resubmit.
Cheers, Phil
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2022-01-11 10:34 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-24 17:17 [iptables PATCH 00/11] Share do_parse() between nft and legacy Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 01/11] xtables: Drop xtables' family on demand feature Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 02/11] xtables: Pull table validity check out of do_parse() Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 03/11] xtables: Move struct nft_xt_cmd_parse to xshared.h Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 04/11] xtables: Pass xtables_args to check_empty_interface() Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 05/11] xtables: Pass xtables_args to check_inverse() Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse() Phil Sutter
2022-01-10 21:29 ` Pablo Neira Ayuso
2022-01-10 21:35 ` Pablo Neira Ayuso
2022-01-11 10:34 ` Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 07/11] xshared: Move do_parse to shared space Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 08/11] xshared: Store parsed wait and wait_interval in xtables_args Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 09/11] nft: Move proto_parse and post_parse callbacks to xshared Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 10/11] iptables: Use xtables' do_parse() function Phil Sutter
2021-12-24 17:17 ` [iptables PATCH 11/11] ip6tables: Use the shared do_parse, too Phil Sutter
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.