* [iptables PATCH 00/13] ebtables: Use the shared commandline parser
@ 2023-11-29 13:28 Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 01/13] xshared: do_parse: Skip option checking for CMD_DELETE_NUM Phil Sutter
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
This series converts do_commandeb() and do_commandeb_xlate() to call
do_parse() from xshared.c instead of iterating over argv themselves.
Patches 1-6 prepare the shared (parser) code for use by ebtables.
Patches 7-11 prepare ebtables code for the following integration in
patch 13. Patch 12 is a minor refactoring in xshared but fits fine right
before the merge as the introduced helper function is called two more
times by it.
Phil Sutter (13):
xshared: do_parse: Skip option checking for CMD_DELETE_NUM
xshared: Perform protocol value parsing in callback
xshared: Turn command_default() into a callback
xshared: Introduce print_help callback (again)
xshared: Support rule range deletion in do_parse()
xshared: Support for ebtables' --change-counters command
ebtables{,-translate}: Convert if-clause to switch()
ebtables: Change option values to avoid clashes
ebtables: Pass struct iptables_command_state to print_help()
ebtables: Make 'h' case just a call to print_help()
ebtables: Use struct xt_cmd_parse
xshared: Introduce option_test_and_reject()
ebtables: Use do_parse() from xshared
iptables/ip6tables.c | 2 +
iptables/iptables.c | 2 +
iptables/nft-arp.c | 2 +
iptables/nft-bridge.c | 121 +++++
iptables/nft-bridge.h | 13 +-
iptables/nft-cmd.h | 7 -
iptables/nft-ipv4.c | 2 +
iptables/nft-ipv6.c | 2 +
iptables/nft.h | 1 -
iptables/xshared.c | 218 +++++++--
iptables/xshared.h | 36 +-
iptables/xtables-eb-translate.c | 491 +++----------------
iptables/xtables-eb.c | 839 ++++++--------------------------
13 files changed, 567 insertions(+), 1169 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [iptables PATCH 01/13] xshared: do_parse: Skip option checking for CMD_DELETE_NUM
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 02/13] xshared: Perform protocol value parsing in callback Phil Sutter
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
This command will delete a rule by its number, not rule spec. No -i/-o
options are expected on commandline.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xshared.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/iptables/xshared.c b/iptables/xshared.c
index dca744773d773..53e6720169950 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1837,7 +1837,6 @@ void do_parse(int argc, char *argv[],
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) {
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 02/13] xshared: Perform protocol value parsing in callback
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 01/13] xshared: do_parse: Skip option checking for CMD_DELETE_NUM Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 03/13] xshared: Turn command_default() into a callback Phil Sutter
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
The code is same in iptables and ip6tables, but different in ebtables.
Therefore move it into the callback to keep that part of do_parse()
generic.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xshared.c | 22 ++++++++++++++--------
iptables/xshared.h | 1 -
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 53e6720169950..ff809f2be3438 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1547,12 +1547,6 @@ void do_parse(int argc, char *argv[],
*cs->protocol = tolower(*cs->protocol);
cs->protocol = optarg;
- 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->ops->proto_parse)
@@ -1865,7 +1859,13 @@ 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.proto = xtables_parse_protocol(cs->protocol);
+
+ if (cs->fw.ip.proto == 0 &&
+ (args->invflags & XT_INV_PROTO))
+ xtables_error(PARAMETER_PROBLEM,
+ "rule would never match protocol");
+
cs->fw.ip.invflags = args->invflags;
}
@@ -1881,7 +1881,13 @@ static int is_exthdr(uint16_t proto)
void ipv6_proto_parse(struct iptables_command_state *cs,
struct xtables_args *args)
{
- cs->fw6.ipv6.proto = args->proto;
+ cs->fw6.ipv6.proto = xtables_parse_protocol(cs->protocol);
+
+ if (cs->fw6.ipv6.proto == 0 &&
+ (args->invflags & XT_INV_PROTO))
+ xtables_error(PARAMETER_PROBLEM,
+ "rule would never match protocol");
+
cs->fw6.ipv6.invflags = args->invflags;
/* this is needed for ip6tables-legacy only */
diff --git a/iptables/xshared.h b/iptables/xshared.h
index d2ce72e90824a..3df2153fd6a10 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -249,7 +249,6 @@ struct addr_mask {
struct xtables_args {
int family;
- uint16_t proto;
uint8_t flags;
uint16_t invflags;
char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 03/13] xshared: Turn command_default() into a callback
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 01/13] xshared: do_parse: Skip option checking for CMD_DELETE_NUM Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 02/13] xshared: Perform protocol value parsing in callback Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 04/13] xshared: Introduce print_help callback (again) Phil Sutter
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Ebtables' variant is pretty different since all extensions are loaded up
front and some targets serve as "watcher" extensions, so let variants
specify the function to call for extension parameters.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/ip6tables.c | 1 +
iptables/iptables.c | 1 +
iptables/nft-arp.c | 1 +
iptables/nft-ipv4.c | 1 +
iptables/nft-ipv6.c | 1 +
iptables/xshared.c | 6 +++---
iptables/xshared.h | 4 ++++
7 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 53eeb6e90bbb7..96603756324a5 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -670,6 +670,7 @@ int do_command6(int argc, char *argv[], char **table,
.post_parse = ipv6_post_parse,
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
+ .command_default = command_default,
};
struct xt_cmd_parse p = {
.table = *table,
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 69dd289060528..b57483ef44514 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -664,6 +664,7 @@ int do_command4(int argc, char *argv[], char **table,
.post_parse = ipv4_post_parse,
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
+ .command_default = command_default,
};
struct xt_cmd_parse p = {
.table = *table,
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index c009dd83e26cf..f3e2920ac6d15 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -858,6 +858,7 @@ struct nft_family_ops nft_family_ops_arp = {
.post_parse = nft_arp_post_parse,
.option_name = nft_arp_option_name,
.option_invert = nft_arp_option_invert,
+ .command_default = command_default,
},
.rule_to_cs = nft_rule_to_iptables_command_state,
.init_cs = nft_arp_init_cs,
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index c140ffde34b62..754c776473143 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -354,6 +354,7 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.post_parse = ipv4_post_parse,
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
+ .command_default = command_default,
},
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = xtables_clear_iptables_command_state,
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 4bf4f54f18a00..b1b5891013577 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -345,6 +345,7 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.post_parse = ipv6_post_parse,
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
+ .command_default = command_default,
},
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = xtables_clear_iptables_command_state,
diff --git a/iptables/xshared.c b/iptables/xshared.c
index ff809f2be3438..29b3992904e68 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -122,8 +122,8 @@ static struct xtables_match *load_proto(struct iptables_command_state *cs)
cs->options & OPT_NUMERIC, &cs->matches);
}
-static int command_default(struct iptables_command_state *cs,
- struct xtables_globals *gl, bool invert)
+int command_default(struct iptables_command_state *cs,
+ struct xtables_globals *gl, bool invert)
{
struct xtables_rule_match *matchp;
struct xtables_match *m;
@@ -1784,7 +1784,7 @@ void do_parse(int argc, char *argv[],
exit_tryhelp(2, p->line);
default:
- if (command_default(cs, xt_params, invert))
+ if (p->ops->command_default(cs, xt_params, invert))
/* cf. ip6tables.c */
continue;
break;
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 3df2153fd6a10..bf24fd568a6f5 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -272,6 +272,8 @@ struct xt_cmd_parse_ops {
struct xtables_args *args);
const char *(*option_name)(int option);
int (*option_invert)(int option);
+ int (*command_default)(struct iptables_command_state *cs,
+ struct xtables_globals *gl, bool invert);
};
struct xt_cmd_parse {
@@ -289,6 +291,8 @@ struct xt_cmd_parse {
const char *ip46t_option_name(int option);
int ip46t_option_invert(int option);
+int command_default(struct iptables_command_state *cs,
+ struct xtables_globals *gl, bool invert);
void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 04/13] xshared: Introduce print_help callback (again)
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (2 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 03/13] xshared: Turn command_default() into a callback Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 05/13] xshared: Support rule range deletion in do_parse() Phil Sutter
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Prep work for ebtables parser to use do_parse(). Adding more special
casing to xtables_printhelp() causes a mess, so work with a callback
again.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/ip6tables.c | 1 +
iptables/iptables.c | 1 +
iptables/nft-arp.c | 1 +
iptables/nft-ipv4.c | 1 +
iptables/nft-ipv6.c | 1 +
iptables/xshared.c | 6 +++---
iptables/xshared.h | 2 ++
7 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 96603756324a5..4b5d4ac6878b7 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -671,6 +671,7 @@ int do_command6(int argc, char *argv[], char **table,
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
.command_default = command_default,
+ .print_help = xtables_printhelp,
};
struct xt_cmd_parse p = {
.table = *table,
diff --git a/iptables/iptables.c b/iptables/iptables.c
index b57483ef44514..5ae28fe04a5f5 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -665,6 +665,7 @@ int do_command4(int argc, char *argv[], char **table,
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
.command_default = command_default,
+ .print_help = xtables_printhelp,
};
struct xt_cmd_parse p = {
.table = *table,
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index f3e2920ac6d15..6011620cf52a7 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -859,6 +859,7 @@ struct nft_family_ops nft_family_ops_arp = {
.option_name = nft_arp_option_name,
.option_invert = nft_arp_option_invert,
.command_default = command_default,
+ .print_help = xtables_printhelp,
},
.rule_to_cs = nft_rule_to_iptables_command_state,
.init_cs = nft_arp_init_cs,
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 754c776473143..979880a3e7702 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -355,6 +355,7 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
.command_default = command_default,
+ .print_help = xtables_printhelp,
},
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = xtables_clear_iptables_command_state,
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index b1b5891013577..e4b1714d00c2f 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -346,6 +346,7 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.option_name = ip46t_option_name,
.option_invert = ip46t_option_invert,
.command_default = command_default,
+ .print_help = xtables_printhelp,
},
.rule_to_cs = nft_rule_to_iptables_command_state,
.clear_cs = xtables_clear_iptables_command_state,
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 29b3992904e68..177f3ddd1c19e 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1108,9 +1108,9 @@ int print_match_save(const struct xt_entry_match *e, const void *ip)
return 0;
}
-static void
-xtables_printhelp(const struct xtables_rule_match *matches)
+void xtables_printhelp(struct iptables_command_state *cs)
{
+ const struct xtables_rule_match *matches = cs->matches;
const char *prog_name = xt_params->program_name;
const char *prog_vers = xt_params->program_version;
@@ -1527,7 +1527,7 @@ void do_parse(int argc, char *argv[],
xtables_find_match(cs->protocol,
XTF_TRY_LOAD, &cs->matches);
- xtables_printhelp(cs->matches);
+ p->ops->print_help(cs);
xtables_clear_iptables_command_state(cs);
xtables_free_opts(1);
xtables_fini();
diff --git a/iptables/xshared.h b/iptables/xshared.h
index bf24fd568a6f5..69f50e505cb9b 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -274,6 +274,7 @@ struct xt_cmd_parse_ops {
int (*option_invert)(int option);
int (*command_default)(struct iptables_command_state *cs,
struct xtables_globals *gl, bool invert);
+ void (*print_help)(struct iptables_command_state *cs);
};
struct xt_cmd_parse {
@@ -289,6 +290,7 @@ struct xt_cmd_parse {
struct xt_cmd_parse_ops *ops;
};
+void xtables_printhelp(struct iptables_command_state *cs);
const char *ip46t_option_name(int option);
int ip46t_option_invert(int option);
int command_default(struct iptables_command_state *cs,
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 05/13] xshared: Support rule range deletion in do_parse()
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (3 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 04/13] xshared: Introduce print_help callback (again) Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 06/13] xshared: Support for ebtables' --change-counters command Phil Sutter
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
This is a distinct ebtables feature. Introduce struct
xt_cmd_parse::rule_ranges boolean indicating support for it and bail
otherwise if a range was specified by the user.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xshared.c | 34 +++++++++++++++++++++++++++++++++-
iptables/xshared.h | 2 ++
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 177f3ddd1c19e..62ae4141325ed 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -903,6 +903,38 @@ static int parse_rulenumber(const char *rule)
return rulenum;
}
+static void parse_rule_range(struct xt_cmd_parse *p, const char *argv)
+{
+ char *colon = strchr(argv, ':'), *buffer;
+
+ if (colon) {
+ if (!p->rule_ranges)
+ xtables_error(PARAMETER_PROBLEM,
+ "Rule ranges are not supported");
+
+ *colon = '\0';
+ if (*(colon + 1) == '\0')
+ p->rulenum_end = -1; /* Until the last rule */
+ else {
+ p->rulenum_end = strtol(colon + 1, &buffer, 10);
+ if (*buffer != '\0' || p->rulenum_end == 0)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid rule range end`%s'",
+ colon + 1);
+ }
+ }
+ if (colon == argv)
+ p->rulenum = 1; /* Beginning with the first rule */
+ else {
+ p->rulenum = strtol(argv, &buffer, 10);
+ if (*buffer != '\0' || p->rulenum == 0)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid rule number `%s'", argv);
+ }
+ if (!colon)
+ p->rulenum_end = p->rulenum;
+}
+
/* list the commands an option is allowed with */
#define CMD_IDRAC CMD_INSERT | CMD_DELETE | CMD_REPLACE | \
CMD_APPEND | CMD_CHECK
@@ -1411,7 +1443,7 @@ void do_parse(int argc, char *argv[],
add_command(&p->command, CMD_DELETE, CMD_NONE, invert);
p->chain = optarg;
if (xs_has_arg(argc, argv)) {
- p->rulenum = parse_rulenumber(argv[optind++]);
+ parse_rule_range(p, argv[optind++]);
p->command = CMD_DELETE_NUM;
}
break;
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 69f50e505cb9b..2fd15c725faaf 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -280,6 +280,7 @@ struct xt_cmd_parse_ops {
struct xt_cmd_parse {
unsigned int command;
unsigned int rulenum;
+ unsigned int rulenum_end;
char *table;
const char *chain;
const char *newname;
@@ -287,6 +288,7 @@ struct xt_cmd_parse {
bool restore;
int line;
int verbose;
+ bool rule_ranges;
struct xt_cmd_parse_ops *ops;
};
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 06/13] xshared: Support for ebtables' --change-counters command
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (4 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 05/13] xshared: Support rule range deletion in do_parse() Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 07/13] ebtables{,-translate}: Convert if-clause to switch() Phil Sutter
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
This is tricky because the short-option clashes with the --check
command. OTOH, ebtables supports --check as well (though without
short-option), so making do_parse() detect ebtables based on struct
xtables_args::family is probably still the least messy option.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-cmd.h | 7 ------
iptables/xshared.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-
iptables/xshared.h | 11 ++++++++-
3 files changed, 66 insertions(+), 9 deletions(-)
diff --git a/iptables/nft-cmd.h b/iptables/nft-cmd.h
index 8163b82c3511f..00ecc80249f0d 100644
--- a/iptables/nft-cmd.h
+++ b/iptables/nft-cmd.h
@@ -7,13 +7,6 @@
struct nftnl_rule;
-enum {
- CTR_OP_INC_PKTS = 1 << 0,
- CTR_OP_DEC_PKTS = 1 << 1,
- CTR_OP_INC_BYTES = 1 << 2,
- CTR_OP_DEC_BYTES = 1 << 3,
-};
-
struct nft_cmd {
struct list_head head;
int command;
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 62ae4141325ed..50f23757d4aff 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -937,7 +937,7 @@ static void parse_rule_range(struct xt_cmd_parse *p, const char *argv)
/* list the commands an option is allowed with */
#define CMD_IDRAC CMD_INSERT | CMD_DELETE | CMD_REPLACE | \
- CMD_APPEND | CMD_CHECK
+ CMD_APPEND | CMD_CHECK | CMD_CHANGE_COUNTERS
static const unsigned int options_v_commands[NUMBER_OF_OPT] = {
/*OPT_NUMERIC*/ CMD_LIST,
/*OPT_SOURCE*/ CMD_IDRAC,
@@ -1392,10 +1392,58 @@ static void parse_interface(const char *arg, char *iface)
strcpy(iface, arg);
}
+static bool
+parse_signed_counter(char *argv, unsigned long long *val, uint8_t *ctr_op,
+ uint8_t flag_inc, uint8_t flag_dec)
+{
+ char *endptr, *p = argv;
+
+ switch (*p) {
+ case '+':
+ *ctr_op |= flag_inc;
+ p++;
+ break;
+ case '-':
+ *ctr_op |= flag_dec;
+ p++;
+ break;
+ }
+ *val = strtoull(p, &endptr, 10);
+ return *endptr == '\0';
+}
+
+static void parse_change_counters_rule(int argc, char **argv,
+ struct xt_cmd_parse *p,
+ struct xtables_args *args)
+{
+ if (optind + 1 >= argc ||
+ (argv[optind][0] == '-' && !isdigit(argv[optind][1])) ||
+ (argv[optind + 1][0] == '-' && !isdigit(argv[optind + 1][1])))
+ xtables_error(PARAMETER_PROBLEM,
+ "The command -C needs at least 2 arguments");
+ if (optind + 2 < argc &&
+ (argv[optind + 2][0] != '-' || isdigit(argv[optind + 2][1]))) {
+ if (optind + 3 != argc)
+ xtables_error(PARAMETER_PROBLEM,
+ "No extra options allowed with -C start_nr[:end_nr] pcnt bcnt");
+ parse_rule_range(p, argv[optind++]);
+ }
+
+ if (!parse_signed_counter(argv[optind++], &args->pcnt_cnt,
+ &args->counter_op,
+ CTR_OP_INC_PKTS, CTR_OP_DEC_PKTS) ||
+ !parse_signed_counter(argv[optind++], &args->bcnt_cnt,
+ &args->counter_op,
+ CTR_OP_INC_BYTES, CTR_OP_DEC_BYTES))
+ xtables_error(PARAMETER_PROBLEM,
+ "Packet counter '%s' invalid", argv[optind - 1]);
+}
+
void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args)
{
+ bool family_is_bridge = args->family == NFPROTO_BRIDGE;
struct xtables_match *m;
struct xtables_rule_match *matchp;
bool wait_interval_set = false;
@@ -1435,6 +1483,13 @@ void do_parse(int argc, char *argv[],
break;
case 'C':
+ if (family_is_bridge) {
+ add_command(&p->command, CMD_CHANGE_COUNTERS,
+ CMD_NONE, invert);
+ p->chain = optarg;
+ parse_change_counters_rule(argc, argv, p, args);
+ break;
+ }
add_command(&p->command, CMD_CHECK, CMD_NONE, invert);
p->chain = optarg;
break;
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 2fd15c725faaf..68acfb4b406fb 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -69,8 +69,9 @@ enum {
CMD_LIST_RULES = 1 << 12,
CMD_ZERO_NUM = 1 << 13,
CMD_CHECK = 1 << 14,
+ CMD_CHANGE_COUNTERS = 1 << 15, /* ebtables only */
};
-#define NUMBER_OF_CMD 16
+#define NUMBER_OF_CMD 17
struct xtables_globals;
struct xtables_rule_match;
@@ -247,6 +248,13 @@ struct addr_mask {
} mask;
};
+enum {
+ CTR_OP_INC_PKTS = 1 << 0,
+ CTR_OP_DEC_PKTS = 1 << 1,
+ CTR_OP_INC_BYTES = 1 << 2,
+ CTR_OP_DEC_BYTES = 1 << 3,
+};
+
struct xtables_args {
int family;
uint8_t flags;
@@ -261,6 +269,7 @@ struct xtables_args {
const char *arp_hlen, *arp_opcode;
const char *arp_htype, *arp_ptype;
unsigned long long pcnt_cnt, bcnt_cnt;
+ uint8_t counter_op;
int wait;
};
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 07/13] ebtables{,-translate}: Convert if-clause to switch()
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (5 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 06/13] xshared: Support for ebtables' --change-counters command Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 08/13] ebtables: Change option values to avoid clashes Phil Sutter
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Parser merge prep work, align final do_commandeb*() parts with
do_commandx().
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables-eb-translate.c | 24 +++++++++--------
iptables/xtables-eb.c | 46 ++++++++++++++++++++-------------
2 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index da7e5e3dda1f3..d0fec9c6d5ae3 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -497,23 +497,25 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
cs.eb.ethproto = htons(cs.eb.ethproto);
- if (command == 'P') {
- return 0;
- } else if (command == 'F') {
- if (p.chain) {
- printf("flush chain bridge %s %s\n", p.table, p.chain);
- } else {
- printf("flush table bridge %s\n", p.table);
- }
- ret = 1;
- } else if (command == 'A') {
+ switch (command) {
+ case 'F':
+ if (p.chain) {
+ printf("flush chain bridge %s %s\n", p.table, p.chain);
+ } else {
+ printf("flush table bridge %s\n", p.table);
+ }
+ ret = 1;
+ break;
+ case 'A':
ret = nft_rule_eb_xlate_add(h, &p, &cs, true);
if (!ret)
print_ebt_cmd(argc, argv);
- } else if (command == 'I') {
+ break;
+ case 'I':
ret = nft_rule_eb_xlate_add(h, &p, &cs, false);
if (!ret)
print_ebt_cmd(argc, argv);
+ break;
}
ebt_cs_clean(&cs);
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index ddbe1b5a3adc0..db75e65caa02a 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -1168,47 +1168,57 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
* The kernel does not have to do this of course */
cs.eb.ethproto = htons(cs.eb.ethproto);
- if (command == 'P') {
+ switch (command) {
+ case 'P':
if (selected_chain >= NF_BR_NUMHOOKS) {
ret = ebt_cmd_user_chain_policy(h, *table, chain, policy);
- } else {
- if (strcmp(policy, "RETURN") == 0) {
- xtables_error(PARAMETER_PROBLEM,
- "Policy RETURN only allowed for user defined chains");
- }
- ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
- if (ret < 0)
- xtables_error(PARAMETER_PROBLEM, "Wrong policy");
+ break;
}
- } else if (command == 'L') {
+ if (strcmp(policy, "RETURN") == 0) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Policy RETURN only allowed for user defined chains");
+ }
+ ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
+ if (ret < 0)
+ xtables_error(PARAMETER_PROBLEM, "Wrong policy");
+ break;
+ case 'L':
ret = list_rules(h, chain, *table, rule_nr,
flags & OPT_VERBOSE,
0,
/*flags&OPT_EXPANDED*/0,
flags&LIST_N,
flags&LIST_C);
- }
- if (flags & OPT_ZERO) {
+ if (!(flags & OPT_ZERO))
+ break;
+ case 'Z':
ret = nft_cmd_chain_zero_counters(h, chain, *table,
flags & OPT_VERBOSE);
- } else if (command == 'F') {
+ break;
+ case 'F':
ret = nft_cmd_rule_flush(h, chain, *table, flags & OPT_VERBOSE);
- } else if (command == 'A') {
+ break;
+ case 'A':
ret = nft_cmd_rule_append(h, chain, *table, &cs,
flags & OPT_VERBOSE);
- } else if (command == 'I') {
+ break;
+ case 'I':
ret = nft_cmd_rule_insert(h, chain, *table, &cs,
rule_nr - 1, flags & OPT_VERBOSE);
- } else if (command == 'D') {
+ break;
+ case 'D':
ret = delete_entry(h, chain, *table, &cs, rule_nr - 1,
rule_nr_end, flags & OPT_VERBOSE);
- } else if (command == 14) {
+ break;
+ case 14:
ret = nft_cmd_rule_check(h, chain, *table,
&cs, flags & OPT_VERBOSE);
- } else if (command == 'C') {
+ break;
+ case 'C':
ret = change_entry_counters(h, chain, *table, &cs,
rule_nr - 1, rule_nr_end, chcounter,
flags & OPT_VERBOSE);
+ break;
}
ebt_cs_clean(&cs);
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 08/13] ebtables: Change option values to avoid clashes
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (6 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 07/13] ebtables{,-translate}: Convert if-clause to switch() Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 09/13] ebtables: Pass struct iptables_command_state to print_help() Phil Sutter
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
In order to parse input using do_parse(), distinct ebtables option's
values have to be distinct from others. Since arptables uses values 2-8
already, resort to values >10.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables-eb-translate.c | 14 +++++++-------
iptables/xtables-eb.c | 24 ++++++++++++------------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index d0fec9c6d5ae3..a2ab318cff251 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -292,9 +292,9 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
table_set = true;
break;
case 'i': /* Input interface */
- case 2 : /* Logical input interface */
+ case 15 : /* Logical input interface */
case 'o': /* Output interface */
- case 3 : /* Logical output interface */
+ case 16 : /* Logical output interface */
case 'j': /* Target */
case 'p': /* Net family protocol */
case 's': /* Source mac */
@@ -316,7 +316,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
ebtables_parse_interface(optarg, cs.eb.in);
break;
- } else if (c == 2) {
+ } else if (c == 15) {
ebt_check_option2(&flags, OPT_LOGICALIN);
if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
xtables_error(PARAMETER_PROBLEM,
@@ -336,7 +336,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
ebtables_parse_interface(optarg, cs.eb.out);
break;
- } else if (c == 3) {
+ } else if (c == 16) {
ebt_check_option2(&flags, OPT_LOGICALOUT);
if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
xtables_error(PARAMETER_PROBLEM,
@@ -424,14 +424,14 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
xtables_error(PARAMETER_PROBLEM,
"Sorry, protocols have values above or equal to 0x0600");
break;
- case 4 : /* Lc */
+ case 17 : /* Lc */
ebt_check_option2(&flags, LIST_C);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
"Use --Lc with -L");
flags |= LIST_C;
break;
- case 5 : /* Ln */
+ case 18 : /* Ln */
ebt_check_option2(&flags, LIST_N);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
@@ -441,7 +441,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
"--Lx is not compatible with --Ln");
flags |= LIST_N;
break;
- case 6 : /* Lx */
+ case 19 : /* Lx */
ebt_check_option2(&flags, LIST_X);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index db75e65caa02a..9afaa614bac5b 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -196,17 +196,17 @@ struct option ebt_original_options[] =
{ "insert" , required_argument, 0, 'I' },
{ "delete" , required_argument, 0, 'D' },
{ "list" , optional_argument, 0, 'L' },
- { "Lc" , no_argument , 0, 4 },
- { "Ln" , no_argument , 0, 5 },
- { "Lx" , no_argument , 0, 6 },
+ { "Lc" , no_argument , 0, 17 },
+ { "Ln" , no_argument , 0, 18 },
+ { "Lx" , no_argument , 0, 19 },
{ "Lmac2" , no_argument , 0, 12 },
{ "zero" , optional_argument, 0, 'Z' },
{ "flush" , optional_argument, 0, 'F' },
{ "policy" , required_argument, 0, 'P' },
{ "in-interface" , required_argument, 0, 'i' },
{ "in-if" , required_argument, 0, 'i' },
- { "logical-in" , required_argument, 0, 2 },
- { "logical-out" , required_argument, 0, 3 },
+ { "logical-in" , required_argument, 0, 15 },
+ { "logical-out" , required_argument, 0, 16 },
{ "out-interface" , required_argument, 0, 'o' },
{ "out-if" , required_argument, 0, 'o' },
{ "version" , no_argument , 0, 'V' },
@@ -940,9 +940,9 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
table_set = true;
break;
case 'i': /* Input interface */
- case 2 : /* Logical input interface */
+ case 15 : /* Logical input interface */
case 'o': /* Output interface */
- case 3 : /* Logical output interface */
+ case 16 : /* Logical output interface */
case 'j': /* Target */
case 'p': /* Net family protocol */
case 's': /* Source mac */
@@ -965,7 +965,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
ebtables_parse_interface(optarg, cs.eb.in);
break;
- } else if (c == 2) {
+ } else if (c == 15) {
ebt_check_option2(&flags, OPT_LOGICALIN);
if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
xtables_error(PARAMETER_PROBLEM,
@@ -985,7 +985,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
ebtables_parse_interface(optarg, cs.eb.out);
break;
- } else if (c == 3) {
+ } else if (c == 16) {
ebt_check_option2(&flags, OPT_LOGICALOUT);
if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
xtables_error(PARAMETER_PROBLEM,
@@ -1073,14 +1073,14 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
xtables_error(PARAMETER_PROBLEM,
"Sorry, protocols have values above or equal to 0x0600");
break;
- case 4 : /* Lc */
+ case 17 : /* Lc */
ebt_check_option2(&flags, LIST_C);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
"Use --Lc with -L");
flags |= LIST_C;
break;
- case 5 : /* Ln */
+ case 18 : /* Ln */
ebt_check_option2(&flags, LIST_N);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
@@ -1090,7 +1090,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
"--Lx is not compatible with --Ln");
flags |= LIST_N;
break;
- case 6 : /* Lx */
+ case 19 : /* Lx */
ebt_check_option2(&flags, LIST_X);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 09/13] ebtables: Pass struct iptables_command_state to print_help()
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (7 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 08/13] ebtables: Change option values to avoid clashes Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 10/13] ebtables: Make 'h' case just a call " Phil Sutter
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Parameters passed by the sole caller came from there already, apart from
'table' which is not used (ebtables-nft does not have per-table help
texts).
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables-eb.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 9afaa614bac5b..017e1ad364840 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -303,9 +303,11 @@ static struct option *merge_options(struct option *oldopts,
return merge;
}
-static void print_help(const struct xtables_target *t,
- const struct xtables_rule_match *m, const char *table)
+static void print_help(struct iptables_command_state *cs)
{
+ const struct xtables_rule_match *m = cs->matches;
+ struct xtables_target *t = cs->target;
+
printf("%s %s\n", prog_name, prog_vers);
printf(
"Usage:\n"
@@ -354,9 +356,6 @@ static void print_help(const struct xtables_target *t,
printf("\n");
t->help();
}
-
-// if (table->help)
-// table->help(ebt_hooknames);
}
/* Execute command L */
@@ -1144,7 +1143,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
ebt_print_error2("Bad table name");*/
if (command == 'h' && !(flags & OPT_ZERO)) {
- print_help(cs.target, cs.matches, *table);
+ print_help(&cs);
ret = 1;
}
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 10/13] ebtables: Make 'h' case just a call to print_help()
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (8 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 09/13] ebtables: Pass struct iptables_command_state to print_help() Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 11/13] ebtables: Use struct xt_cmd_parse Phil Sutter
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Move the special ebtables help parameter handling into its print_help()
function to prepare for it turning into a callback. Add new field 'argc'
to struct iptables_command_state to make this possible. It is actually
kind of consistent as it holds 'argv' already.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xshared.h | 1 +
iptables/xtables-eb.c | 61 +++++++++++++++++++++----------------------
2 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 68acfb4b406fb..de32198fa0b67 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -137,6 +137,7 @@ struct iptables_command_state {
char *protocol;
int proto_used;
const char *jumpto;
+ int argc;
char **argv;
bool restore;
};
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 017e1ad364840..8ab479237faa8 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -308,6 +308,33 @@ static void print_help(struct iptables_command_state *cs)
const struct xtables_rule_match *m = cs->matches;
struct xtables_target *t = cs->target;
+ while (optind < cs->argc) {
+ /*struct ebt_u_match *m;
+ struct ebt_u_watcher *w;*/
+
+ if (!strcasecmp("list_extensions", cs->argv[optind])) {
+ ebt_list_extensions(xtables_targets, cs->matches);
+ exit(0);
+ }
+ /*if ((m = ebt_find_match(cs->argv[optind])))
+ ebt_add_match(new_entry, m);
+ else if ((w = ebt_find_watcher(cs->argv[optind])))
+ ebt_add_watcher(new_entry, w);
+ else {*/
+ if (!(t = xtables_find_target(cs->argv[optind],
+ XTF_TRY_LOAD)))
+ xtables_error(PARAMETER_PROBLEM,
+ "Extension '%s' not found",
+ cs->argv[optind]);
+ if (cs->options & OPT_JUMP)
+ xtables_error(PARAMETER_PROBLEM,
+ "Sorry, you can only see help for one target extension at a time");
+ cs->options |= OPT_JUMP;
+ cs->target = t;
+ //}
+ optind++;
+ }
+
printf("%s %s\n", prog_name, prog_vers);
printf(
"Usage:\n"
@@ -735,6 +762,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
unsigned int flags = 0;
struct xtables_target *t;
struct iptables_command_state cs = {
+ .argc = argc,
.argv = argv,
.jumpto = "",
.eb.bitmask = EBT_NOPROTO,
@@ -897,32 +925,8 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
if (OPT_COMMANDS)
xtables_error(PARAMETER_PROBLEM,
"Multiple commands are not allowed");
- command = 'h';
-
- /* All other arguments should be extension names */
- while (optind < argc) {
- /*struct ebt_u_match *m;
- struct ebt_u_watcher *w;*/
-
- if (!strcasecmp("list_extensions", argv[optind])) {
- ebt_list_extensions(xtables_targets, cs.matches);
- exit(0);
- }
- /*if ((m = ebt_find_match(argv[optind])))
- ebt_add_match(new_entry, m);
- else if ((w = ebt_find_watcher(argv[optind])))
- ebt_add_watcher(new_entry, w);
- else {*/
- if (!(t = xtables_find_target(argv[optind], XTF_TRY_LOAD)))
- xtables_error(PARAMETER_PROBLEM,"Extension '%s' not found", argv[optind]);
- if (flags & OPT_JUMP)
- xtables_error(PARAMETER_PROBLEM,"Sorry, you can only see help for one target extension at a time");
- flags |= OPT_JUMP;
- cs.target = t;
- //}
- optind++;
- }
- break;
+ print_help(&cs);
+ exit(0);
case 't': /* Table */
if (restore && table_set)
xtables_error(PARAMETER_PROBLEM,
@@ -1142,11 +1146,6 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
if (!(table = ebt_find_table(replace->name)))
ebt_print_error2("Bad table name");*/
- if (command == 'h' && !(flags & OPT_ZERO)) {
- print_help(&cs);
- ret = 1;
- }
-
/* Do the final checks */
if (command == 'A' || command == 'I' ||
command == 'D' || command == 'C' || command == 14) {
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 11/13] ebtables: Use struct xt_cmd_parse
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (9 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 10/13] ebtables: Make 'h' case just a call " Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 12/13] xshared: Introduce option_test_and_reject() Phil Sutter
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
This is merely to reduce size of the parser merge patch, no functional
change intended.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables-eb.c | 59 ++++++++++++++++++++++++++-----------------
1 file changed, 36 insertions(+), 23 deletions(-)
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 8ab479237faa8..e03b2b2510eda 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -767,6 +767,8 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
.jumpto = "",
.eb.bitmask = EBT_NOPROTO,
};
+ struct xt_cmd_parse p = {
+ };
char command = 'h';
const char *chain = NULL;
const char *policy = NULL;
@@ -1166,56 +1168,67 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
* The kernel does not have to do this of course */
cs.eb.ethproto = htons(cs.eb.ethproto);
+ p.table = *table;
+ p.chain = chain;
+ p.policy = policy;
+ p.rulenum = rule_nr;
+ p.rulenum_end = rule_nr_end;
+ cs.options = flags;
+
switch (command) {
case 'P':
if (selected_chain >= NF_BR_NUMHOOKS) {
- ret = ebt_cmd_user_chain_policy(h, *table, chain, policy);
+ ret = ebt_cmd_user_chain_policy(h, p.table, p.chain,
+ p.policy);
break;
}
- if (strcmp(policy, "RETURN") == 0) {
+ if (strcmp(p.policy, "RETURN") == 0) {
xtables_error(PARAMETER_PROBLEM,
"Policy RETURN only allowed for user defined chains");
}
- ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
+ ret = nft_cmd_chain_set(h, p.table, p.chain, p.policy, NULL);
if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy");
break;
case 'L':
- ret = list_rules(h, chain, *table, rule_nr,
- flags & OPT_VERBOSE,
+ ret = list_rules(h, p.chain, p.table, p.rulenum,
+ cs.options & OPT_VERBOSE,
0,
- /*flags&OPT_EXPANDED*/0,
- flags&LIST_N,
- flags&LIST_C);
- if (!(flags & OPT_ZERO))
+ /*cs.options&OPT_EXPANDED*/0,
+ cs.options&LIST_N,
+ cs.options&LIST_C);
+ if (!(cs.options & OPT_ZERO))
break;
case 'Z':
- ret = nft_cmd_chain_zero_counters(h, chain, *table,
- flags & OPT_VERBOSE);
+ ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
+ cs.options & OPT_VERBOSE);
break;
case 'F':
- ret = nft_cmd_rule_flush(h, chain, *table, flags & OPT_VERBOSE);
+ ret = nft_cmd_rule_flush(h, p.chain, p.table,
+ cs.options & OPT_VERBOSE);
break;
case 'A':
- ret = nft_cmd_rule_append(h, chain, *table, &cs,
- flags & OPT_VERBOSE);
+ ret = nft_cmd_rule_append(h, p.chain, p.table, &cs,
+ cs.options & OPT_VERBOSE);
break;
case 'I':
- ret = nft_cmd_rule_insert(h, chain, *table, &cs,
- rule_nr - 1, flags & OPT_VERBOSE);
+ ret = nft_cmd_rule_insert(h, p.chain, p.table, &cs,
+ p.rulenum - 1,
+ cs.options & OPT_VERBOSE);
break;
case 'D':
- ret = delete_entry(h, chain, *table, &cs, rule_nr - 1,
- rule_nr_end, flags & OPT_VERBOSE);
+ ret = delete_entry(h, p.chain, p.table, &cs, p.rulenum - 1,
+ p.rulenum_end, cs.options & OPT_VERBOSE);
break;
case 14:
- ret = nft_cmd_rule_check(h, chain, *table,
- &cs, flags & OPT_VERBOSE);
+ ret = nft_cmd_rule_check(h, p.chain, p.table,
+ &cs, cs.options & OPT_VERBOSE);
break;
case 'C':
- ret = change_entry_counters(h, chain, *table, &cs,
- rule_nr - 1, rule_nr_end, chcounter,
- flags & OPT_VERBOSE);
+ ret = change_entry_counters(h, p.chain, p.table, &cs,
+ p.rulenum - 1, p.rulenum_end,
+ chcounter,
+ cs.options & OPT_VERBOSE);
break;
}
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 12/13] xshared: Introduce option_test_and_reject()
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (10 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 11/13] ebtables: Use struct xt_cmd_parse Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 13/13] ebtables: Use do_parse() from xshared Phil Sutter
2023-12-05 16:25 ` [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Just a small helper eliminating the repetitive code there.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xshared.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 50f23757d4aff..ebe172223486e 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1439,6 +1439,15 @@ static void parse_change_counters_rule(int argc, char **argv,
"Packet counter '%s' invalid", argv[optind - 1]);
}
+static void option_test_and_reject(struct xt_cmd_parse *p,
+ struct iptables_command_state *cs,
+ unsigned int option)
+{
+ if (cs->options & option)
+ xtables_error(PARAMETER_PROBLEM, "Can't use %s with %s",
+ p->ops->option_name(option), p->chain);
+}
+
void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args)
@@ -1924,21 +1933,13 @@ void do_parse(int argc, char *argv[],
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 %s with %s\n",
- p->ops->option_name(OPT_VIANAMEOUT),
- p->chain);
+ option_test_and_reject(p, cs, OPT_VIANAMEOUT);
}
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 %s with %s\n",
- p->ops->option_name(OPT_VIANAMEIN),
- p->chain);
+ option_test_and_reject(p, cs, OPT_VIANAMEIN);
}
}
}
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [iptables PATCH 13/13] ebtables: Use do_parse() from xshared
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (11 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 12/13] xshared: Introduce option_test_and_reject() Phil Sutter
@ 2023-11-29 13:28 ` Phil Sutter
2023-12-05 16:25 ` [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-11-29 13:28 UTC (permalink / raw)
To: netfilter-devel
Drop the custom commandline parsers from ebtables and
ebtables-translate, extend and use the shared one instead.
ebtables gains a few new features from doing this:
- Rule counters may be specified in the '-c N,M' syntax
- Support for --replace command
- Support for --list-rules command
- Zero individual rules
There is one known regression in this patch, namely maximum chain name
length shrinks to 28 characters (from 32). Since this limit changed for
iptables in the past as well (e.g. with commit 5429b41c2bb4a), assume
nobody really relies upon it anyway.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-bridge.c | 121 ++++++
iptables/nft-bridge.h | 13 +-
iptables/nft.h | 1 -
iptables/xshared.c | 71 +++-
iptables/xshared.h | 17 +-
iptables/xtables-eb-translate.c | 477 +++------------------
iptables/xtables-eb.c | 720 ++++----------------------------
7 files changed, 341 insertions(+), 1079 deletions(-)
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 1fcdeaf2cad68..60d5f4d0ba1b1 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -571,11 +571,132 @@ static int nft_bridge_xlate(const struct iptables_command_state *cs,
return ret;
}
+static const char *nft_bridge_option_name(int option)
+{
+ switch (option) {
+ /* ebtables specific ones */
+ case OPT_LOGICALIN: return "--logical-in";
+ case OPT_LOGICALOUT: return "--logical-out";
+ case OPT_LINENUMBERS: return "--Ln";
+ case OPT_LIST_C: return "--Lc";
+ case OPT_LIST_X: return "--Lx";
+ case OPT_LIST_MAC2: return "--Lmac2";
+ default: return ip46t_option_name(option);
+ }
+}
+
+static int nft_bridge_option_invert(int option)
+{
+ switch (option) {
+ case OPT_SOURCE: return EBT_ISOURCE;
+ case OPT_DESTINATION: return EBT_IDEST;
+ case OPT_PROTOCOL: return EBT_IPROTO;
+ case OPT_VIANAMEIN: return EBT_IIN;
+ case OPT_VIANAMEOUT: return EBT_IOUT;
+ case OPT_LOGICALIN: return EBT_ILOGICALIN;
+ case OPT_LOGICALOUT: return EBT_ILOGICALOUT;
+ default: return -1;
+ }
+}
+
+static void nft_bridge_proto_parse(struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ char *buffer;
+ int i;
+
+ cs->eb.bitmask &= ~((unsigned int)EBT_NOPROTO);
+
+ i = strtol(cs->protocol, &buffer, 16);
+ if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
+ xtables_error(PARAMETER_PROBLEM,
+ "Problem with the specified protocol");
+ if (*buffer != '\0') {
+ struct xt_ethertypeent *ent;
+
+ if (!strcmp(cs->protocol, "length")) {
+ cs->eb.bitmask |= EBT_802_3;
+ return;
+ }
+ ent = xtables_getethertypebyname(cs->protocol);
+ if (!ent)
+ xtables_error(PARAMETER_PROBLEM,
+ "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing",
+ cs->protocol);
+ cs->eb.ethproto = ent->e_ethertype;
+ } else
+ cs->eb.ethproto = i;
+
+ if (cs->eb.ethproto < 0x0600)
+ xtables_error(PARAMETER_PROBLEM,
+ "Sorry, protocols have values above or equal to 0x0600");
+}
+
+static void nft_bridge_post_parse(int command,
+ struct iptables_command_state *cs,
+ struct xtables_args *args)
+{
+ struct ebt_match *match;
+
+ cs->eb.invflags = args->invflags;
+
+ memcpy(cs->eb.in, args->iniface, IFNAMSIZ);
+ memcpy(cs->eb.out, args->outiface, IFNAMSIZ);
+ memcpy(cs->eb.logical_in, args->bri_iniface, IFNAMSIZ);
+ memcpy(cs->eb.logical_out, args->bri_outiface, IFNAMSIZ);
+
+ cs->counters.pcnt = args->pcnt_cnt;
+ cs->counters.bcnt = args->bcnt_cnt;
+
+ if (args->shostnetworkmask) {
+ if (xtables_parse_mac_and_mask(args->shostnetworkmask,
+ cs->eb.sourcemac,
+ cs->eb.sourcemsk))
+ xtables_error(PARAMETER_PROBLEM,
+ "Problem with specified source mac '%s'",
+ args->shostnetworkmask);
+ cs->eb.bitmask |= EBT_SOURCEMAC;
+ }
+ if (args->dhostnetworkmask) {
+ if (xtables_parse_mac_and_mask(args->dhostnetworkmask,
+ cs->eb.destmac,
+ cs->eb.destmsk))
+ xtables_error(PARAMETER_PROBLEM,
+ "Problem with specified destination mac '%s'",
+ args->dhostnetworkmask);
+ cs->eb.bitmask |= EBT_DESTMAC;
+ }
+
+ if ((cs->options & (OPT_LIST_X | OPT_LINENUMBERS)) ==
+ (OPT_LIST_X | OPT_LINENUMBERS))
+ xtables_error(PARAMETER_PROBLEM,
+ "--Lx is not compatible with --Ln");
+
+ /* So, the extensions can work with the host endian.
+ * The kernel does not have to do this of course */
+ cs->eb.ethproto = htons(cs->eb.ethproto);
+
+ for (match = cs->match_list; match; match = match->next) {
+ if (match->ismatch)
+ continue;
+
+ xtables_option_tfcall(match->u.watcher);
+ }
+}
+
struct nft_family_ops nft_family_ops_bridge = {
.add = nft_bridge_add,
.is_same = nft_bridge_is_same,
.print_payload = NULL,
.rule_parse = &nft_ruleparse_ops_bridge,
+ .cmd_parse = {
+ .proto_parse = nft_bridge_proto_parse,
+ .post_parse = nft_bridge_post_parse,
+ .option_name = nft_bridge_option_name,
+ .option_invert = nft_bridge_option_invert,
+ .command_default = ebt_command_default,
+ .print_help = nft_bridge_print_help,
+ },
.print_table_header = nft_bridge_print_table_header,
.print_header = nft_bridge_print_header,
.print_rule = nft_bridge_print_rule,
diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
index 0e6a29650acca..13b077fc4fbf3 100644
--- a/iptables/nft-bridge.h
+++ b/iptables/nft-bridge.h
@@ -8,13 +8,6 @@
#include <net/ethernet.h>
#include <libiptc/libxtc.h>
-/* We use replace->flags, so we can't use the following values:
- * 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO */
-#define LIST_N 0x04
-#define LIST_C 0x08
-#define LIST_X 0x10
-#define LIST_MAC2 0x20
-
extern unsigned char eb_mac_type_unicast[ETH_ALEN];
extern unsigned char eb_msk_type_unicast[ETH_ALEN];
extern unsigned char eb_mac_type_multicast[ETH_ALEN];
@@ -119,7 +112,8 @@ void ebt_add_match(struct xtables_match *m,
struct iptables_command_state *cs);
void ebt_add_watcher(struct xtables_target *watcher,
struct iptables_command_state *cs);
-int ebt_command_default(struct iptables_command_state *cs);
+int ebt_command_default(struct iptables_command_state *cs,
+ struct xtables_globals *unused, bool ebt_invert);
struct nft_among_pair {
struct ether_addr ether;
@@ -177,4 +171,7 @@ nft_among_insert_pair(struct nft_among_pair *pairs,
(*pcount)++;
}
+/* from xtables-eb.c */
+void nft_bridge_print_help(struct iptables_command_state *cs);
+
#endif
diff --git a/iptables/nft.h b/iptables/nft.h
index 79f1e037cd6d3..57533b6529f5b 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -234,7 +234,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, bo
/* For xtables-eb.c */
int nft_init_eb(struct nft_handle *h, const char *pname);
void nft_fini_eb(struct nft_handle *h);
-int ebt_get_current_chain(const char *chain);
int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
/*
diff --git a/iptables/xshared.c b/iptables/xshared.c
index ebe172223486e..5cae62b45cdf4 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -957,6 +957,11 @@ static const unsigned int options_v_commands[NUMBER_OF_OPT] = {
/*OPT_OPCODE*/ CMD_IDRAC,
/*OPT_H_TYPE*/ CMD_IDRAC,
/*OPT_P_TYPE*/ CMD_IDRAC,
+/*OPT_LOGICALIN*/ CMD_IDRAC,
+/*OPT_LOGICALOUT*/ CMD_IDRAC,
+/*OPT_LIST_C*/ CMD_LIST,
+/*OPT_LIST_X*/ CMD_LIST,
+/*OPT_LIST_MAC2*/ CMD_LIST,
};
#undef CMD_IDRAC
@@ -1301,6 +1306,7 @@ static void check_inverse(struct xtables_args *args, const char option[],
{
switch (args->family) {
case NFPROTO_ARP:
+ case NFPROTO_BRIDGE:
break;
default:
return;
@@ -1499,6 +1505,8 @@ void do_parse(int argc, char *argv[],
parse_change_counters_rule(argc, argv, p, args);
break;
}
+ /* fall through */
+ case 14: /* ebtables --check */
add_command(&p->command, CMD_CHECK, CMD_NONE, invert);
p->chain = optarg;
break;
@@ -1606,15 +1614,19 @@ void do_parse(int argc, char *argv[],
break;
case 'P':
- add_command(&p->command, CMD_SET_POLICY, CMD_NONE,
+ add_command(&p->command, CMD_SET_POLICY,
+ family_is_bridge ? CMD_NEW_CHAIN : CMD_NONE,
invert);
- p->chain = optarg;
- if (xs_has_arg(argc, argv))
+ if (p->command & CMD_NEW_CHAIN) {
+ p->policy = optarg;
+ } else if (xs_has_arg(argc, argv)) {
+ p->chain = optarg;
p->policy = argv[optind++];
- else
+ } else {
xtables_error(PARAMETER_PROBLEM,
"-%c requires a chain and a policy",
cmd2char(CMD_SET_POLICY));
+ }
break;
case 'h':
@@ -1716,6 +1728,45 @@ void do_parse(int argc, char *argv[],
args->arp_ptype = optarg;
break;
+ case 11: /* ebtables --init-table */
+ if (p->restore)
+ xtables_error(PARAMETER_PROBLEM,
+ "--init-table is not supported in daemon mode");
+ add_command(&p->command, CMD_INIT_TABLE, CMD_NONE, invert);
+ break;
+
+ case 12 : /* ebtables --Lmac2 */
+ set_option(p->ops, &cs->options, OPT_LIST_MAC2,
+ &args->invflags, invert);
+ break;
+
+ case 13 : /* ebtables --concurrent */
+ break;
+
+ case 15 : /* ebtables --logical-in */
+ check_inverse(args, optarg, &invert, argc, argv);
+ set_option(p->ops, &cs->options, OPT_LOGICALIN,
+ &args->invflags, invert);
+ parse_interface(optarg, args->bri_iniface);
+ break;
+
+ case 16 : /* ebtables --logical-out */
+ check_inverse(args, optarg, &invert, argc, argv);
+ set_option(p->ops, &cs->options, OPT_LOGICALOUT,
+ &args->invflags, invert);
+ parse_interface(optarg, args->bri_outiface);
+ break;
+
+ case 17 : /* ebtables --Lc */
+ set_option(p->ops, &cs->options, OPT_LIST_C,
+ &args->invflags, invert);
+ break;
+
+ case 19 : /* ebtables --Lx */
+ set_option(p->ops, &cs->options, OPT_LIST_X,
+ &args->invflags, invert);
+ break;
+
case 'j':
set_option(p->ops, &cs->options, OPT_JUMP,
&args->invflags, invert);
@@ -1815,6 +1866,7 @@ void do_parse(int argc, char *argv[],
break;
case '0':
+ case 18 : /* ebtables --Ln */
set_option(p->ops, &cs->options, OPT_LINENUMBERS,
&args->invflags, invert);
break;
@@ -1880,6 +1932,7 @@ void do_parse(int argc, char *argv[],
exit_tryhelp(2, p->line);
default:
+ check_inverse(args, optarg, &invert, argc, argv);
if (p->ops->command_default(cs, xt_params, invert))
/* cf. ip6tables.c */
continue;
@@ -1888,7 +1941,8 @@ void do_parse(int argc, char *argv[],
invert = false;
}
- if (strcmp(p->table, "nat") == 0 &&
+ if (!family_is_bridge &&
+ 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,
@@ -1929,17 +1983,22 @@ void do_parse(int argc, char *argv[],
p->command == CMD_DELETE ||
p->command == CMD_CHECK ||
p->command == CMD_INSERT ||
- p->command == CMD_REPLACE) {
+ p->command == CMD_REPLACE ||
+ p->command == CMD_CHANGE_COUNTERS) {
if (strcmp(p->chain, "PREROUTING") == 0
|| strcmp(p->chain, "INPUT") == 0) {
/* -o not valid with incoming packets. */
option_test_and_reject(p, cs, OPT_VIANAMEOUT);
+ /* same with --logical-out */
+ option_test_and_reject(p, cs, OPT_LOGICALOUT);
}
if (strcmp(p->chain, "POSTROUTING") == 0
|| strcmp(p->chain, "OUTPUT") == 0) {
/* -i not valid with outgoing packets */
option_test_and_reject(p, cs, OPT_VIANAMEIN);
+ /* same with --logical-in */
+ option_test_and_reject(p, cs, OPT_LOGICALIN);
}
}
}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index de32198fa0b67..2a9cdf45f581a 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -47,10 +47,11 @@ enum {
/* below are for ebtables only */
OPT_LOGICALIN = 1 << 18,
OPT_LOGICALOUT = 1 << 19,
- OPT_COMMAND = 1 << 20,
- OPT_ZERO = 1 << 21,
+ OPT_LIST_C = 1 << 20,
+ OPT_LIST_X = 1 << 21,
+ OPT_LIST_MAC2 = 1 << 22,
};
-#define NUMBER_OF_OPT 23
+#define NUMBER_OF_OPT 24
enum {
CMD_NONE = 0,
@@ -70,16 +71,17 @@ enum {
CMD_ZERO_NUM = 1 << 13,
CMD_CHECK = 1 << 14,
CMD_CHANGE_COUNTERS = 1 << 15, /* ebtables only */
+ CMD_INIT_TABLE = 1 << 16, /* ebtables only */
};
-#define NUMBER_OF_CMD 17
+#define NUMBER_OF_CMD 18
struct xtables_globals;
struct xtables_rule_match;
struct xtables_target;
-#define OPTSTRING_COMMON "-:A:C:D:E:F::I:L::M:N:P:VX::Z::" "c:d:i:j:o:p:s:t:v"
-#define IPT_OPTSTRING OPTSTRING_COMMON "R:S::W::" "46bfg:h::m:nw::x"
-#define ARPT_OPTSTRING OPTSTRING_COMMON "R:S::" "h::l:nx" /* "m:" */
+#define OPTSTRING_COMMON "-:A:C:D:E:F::I:L::M:N:P:R:S::VX::Z::" "c:d:i:j:o:p:s:t:v"
+#define IPT_OPTSTRING OPTSTRING_COMMON "W::" "46bfg:h::m:nw::x"
+#define ARPT_OPTSTRING OPTSTRING_COMMON "h::l:nx" /* "m:" */
#define EBT_OPTSTRING OPTSTRING_COMMON "h"
/* define invflags which won't collide with IPT ones.
@@ -262,6 +264,7 @@ struct xtables_args {
uint16_t invflags;
char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+ char bri_iniface[IFNAMSIZ], bri_outiface[IFNAMSIZ];
bool goto_set;
const char *shostnetworkmask, *dhostnetworkmask;
const char *pcnt, *bcnt;
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index a2ab318cff251..fbeff74f7fbb0 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -21,61 +21,10 @@
#include "nft-bridge.h"
#include "nft.h"
#include "nft-shared.h"
-/*
- * From include/ebtables_u.h
- */
-#define ebt_check_option2(flags, mask) EBT_CHECK_OPTION(flags, mask)
-extern int ebt_invert;
-
-static int ebt_check_inverse2(const char option[], int argc, char **argv)
-{
- if (!option)
- return ebt_invert;
- if (strcmp(option, "!") == 0) {
- if (ebt_invert == 1)
- xtables_error(PARAMETER_PROBLEM,
- "Double use of '!' not allowed");
- if (optind >= argc)
- optarg = NULL;
- else
- optarg = argv[optind];
- optind++;
- ebt_invert = 1;
- return 1;
- }
- return ebt_invert;
-}
-
-/*
- * Glue code to use libxtables
- */
-static int parse_rule_number(const char *rule)
-{
- unsigned int rule_nr;
-
- if (!xtables_strtoui(rule, NULL, &rule_nr, 1, INT_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid rule number `%s'", rule);
-
- return rule_nr;
-}
-
-/*
- * The original ebtables parser
- */
-
-/* Checks whether a command has already been specified */
-#define OPT_COMMANDS (flags & OPT_COMMAND || flags & OPT_ZERO)
-
-/* Default command line options. Do not mess around with the already
- * assigned numbers unless you know what you are doing */
-extern struct option ebt_original_options[];
-#define opts ebtables_globals.opts
#define prog_name ebtables_globals.program_name
-#define prog_vers ebtables_globals.program_version
-static void print_help(void)
+static void print_help(struct iptables_command_state *cs)
{
fprintf(stderr, "%s: Translate ebtables command to nft syntax\n"
"no side effects occur, the translated command is written "
@@ -85,46 +34,6 @@ static void print_help(void)
exit(0);
}
-static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
-{
- char *colon = strchr(argv, ':'), *buffer;
-
- if (colon) {
- *colon = '\0';
- if (*(colon + 1) == '\0')
- *rule_nr_end = -1; /* Until the last rule */
- else {
- *rule_nr_end = strtol(colon + 1, &buffer, 10);
- if (*buffer != '\0' || *rule_nr_end == 0)
- return -1;
- }
- }
- if (colon == argv)
- *rule_nr = 1; /* Beginning with the first rule */
- else {
- *rule_nr = strtol(argv, &buffer, 10);
- if (*buffer != '\0' || *rule_nr == 0)
- return -1;
- }
- if (!colon)
- *rule_nr_end = *rule_nr;
- return 0;
-}
-
-static void ebtables_parse_interface(const char *arg, char *vianame)
-{
- unsigned char mask[IFNAMSIZ];
- char *c;
-
- xtables_parse_interface(arg, vianame, mask);
-
- if ((c = strchr(vianame, '+'))) {
- if (*(c + 1) != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Spurious characters after '+' wildcard");
- }
-}
-
static void print_ebt_cmd(int argc, char *argv[])
{
int i;
@@ -158,347 +67,35 @@ static int nft_rule_eb_xlate_add(struct nft_handle *h, const struct xt_cmd_parse
static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char **table)
{
- char *buffer;
- int c, i;
- int rule_nr = 0;
- int rule_nr_end = 0;
- int ret = 0;
- unsigned int flags = 0;
struct iptables_command_state cs = {
.argv = argv,
+ .jumpto = "",
.eb.bitmask = EBT_NOPROTO,
};
- char command = 'h';
- const char *chain = NULL;
- int selected_chain = -1;
- struct xtables_rule_match *xtrm_i;
- struct ebt_match *match;
struct xt_cmd_parse p = {
.table = *table,
+ .rule_ranges = true,
+ .ops = &h->ops->cmd_parse,
};
- bool table_set = false;
-
- /* prevent getopt to spoil our error reporting */
- opterr = false;
-
- printf("nft ");
- /* Getopt saves the day */
- while ((c = getopt_long(argc, argv,
- "-:A:D:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) {
- cs.c = c;
- switch (c) {
- case 'A': /* Add a rule */
- case 'D': /* Delete a rule */
- case 'P': /* Define policy */
- case 'I': /* Insert a rule */
- case 'N': /* Make a user defined chain */
- case 'E': /* Rename chain */
- case 'X': /* Delete chain */
- /* We allow -N chainname -P policy */
- /* XXX: Not in ebtables-compat */
- if (command == 'N' && c == 'P') {
- command = c;
- optind--; /* No table specified */
- break;
- }
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- command = c;
- chain = optarg;
- selected_chain = ebt_get_current_chain(chain);
- p.chain = chain;
- flags |= OPT_COMMAND;
-
- if (c == 'N') {
- printf("add chain bridge %s %s\n", p.table, p.chain);
- ret = 1;
- break;
- } else if (c == 'X') {
- printf("delete chain bridge %s %s\n", p.table, p.chain);
- ret = 1;
- break;
- }
-
- if (c == 'E') {
- break;
- } else if (c == 'D' && optind < argc && (argv[optind][0] != '-' || (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
- if (optind != argc - 1)
- xtables_error(PARAMETER_PROBLEM,
- "No extra options allowed with -D start_nr[:end_nr]");
- if (parse_rule_range(argv[optind], &rule_nr, &rule_nr_end))
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified rule number(s) '%s'", argv[optind]);
- optind++;
- } else if (c == 'I') {
- if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
- rule_nr = 1;
- else {
- rule_nr = parse_rule_number(argv[optind]);
- optind++;
- }
- p.rulenum = rule_nr;
- } else if (c == 'P') {
- break;
- }
- break;
- case 'L': /* List */
- printf("list table bridge %s\n", p.table);
- ret = 1;
- break;
- case 'F': /* Flush */
- case 'Z': /* Zero counters */
- if (c == 'Z') {
- if ((flags & OPT_ZERO) || (flags & OPT_COMMAND && command != 'L'))
-print_zero:
- xtables_error(PARAMETER_PROBLEM,
- "Command -Z only allowed together with command -L");
- flags |= OPT_ZERO;
- } else {
- if (flags & OPT_COMMAND)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- command = c;
- flags |= OPT_COMMAND;
- if (flags & OPT_ZERO && c != 'L')
- goto print_zero;
- }
- break;
- case 'V': /* Version */
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- printf("%s %s\n", prog_name, prog_vers);
- exit(0);
- case 'h':
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- print_help();
- break;
- case 't': /* Table */
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Please put the -t option first");
- if (table_set)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple use of same option not allowed");
- if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1)
- xtables_error(PARAMETER_PROBLEM,
- "Table name length cannot exceed %d characters",
- EBT_TABLE_MAXNAMELEN - 1);
- *table = optarg;
- p.table = optarg;
- table_set = true;
- break;
- case 'i': /* Input interface */
- case 15 : /* Logical input interface */
- case 'o': /* Output interface */
- case 16 : /* Logical output interface */
- case 'j': /* Target */
- case 'p': /* Net family protocol */
- case 's': /* Source mac */
- case 'd': /* Destination mac */
- case 'c': /* Set counters */
- if (!OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "No command specified");
- if (command != 'A' && command != 'D' && command != 'I')
- xtables_error(PARAMETER_PROBLEM,
- "Command and option do not match");
- if (c == 'i') {
- ebt_check_option2(&flags, OPT_VIANAMEIN);
- if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use -i only in INPUT, FORWARD, PREROUTING and BROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IIN;
-
- ebtables_parse_interface(optarg, cs.eb.in);
- break;
- } else if (c == 15) {
- ebt_check_option2(&flags, OPT_LOGICALIN);
- if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use --logical-in only in INPUT, FORWARD, PREROUTING and BROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALIN;
-
- ebtables_parse_interface(optarg, cs.eb.logical_in);
- break;
- } else if (c == 'o') {
- ebt_check_option2(&flags, OPT_VIANAMEOUT);
- if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use -o only in OUTPUT, FORWARD and POSTROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IOUT;
-
- ebtables_parse_interface(optarg, cs.eb.out);
- break;
- } else if (c == 16) {
- ebt_check_option2(&flags, OPT_LOGICALOUT);
- if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use --logical-out only in OUTPUT, FORWARD and POSTROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALOUT;
-
- ebtables_parse_interface(optarg, cs.eb.logical_out);
- break;
- } else if (c == 'j') {
- ebt_check_option2(&flags, OPT_JUMP);
- if (strcmp(optarg, "CONTINUE") != 0) {
- command_jump(&cs, optarg);
- }
- break;
- } else if (c == 's') {
- ebt_check_option2(&flags, OPT_SOURCE);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ISOURCE;
-
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.sourcemac,
- cs.eb.sourcemsk))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
- cs.eb.bitmask |= EBT_SOURCEMAC;
- break;
- } else if (c == 'd') {
- ebt_check_option2(&flags, OPT_DESTINATION);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IDEST;
-
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.destmac,
- cs.eb.destmsk))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
- cs.eb.bitmask |= EBT_DESTMAC;
- break;
- } else if (c == 'c') {
- ebt_check_option2(&flags, OPT_COUNTERS);
- if (ebt_check_inverse2(optarg, argc, argv))
- xtables_error(PARAMETER_PROBLEM,
- "Unexpected '!' after -c");
- if (optind >= argc || optarg[0] == '-' || argv[optind][0] == '-')
- xtables_error(PARAMETER_PROBLEM,
- "Option -c needs 2 arguments");
-
- cs.counters.pcnt = strtoull(optarg, &buffer, 10);
- if (*buffer != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid",
- optarg);
- cs.counters.bcnt = strtoull(argv[optind], &buffer, 10);
- if (*buffer != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid",
- argv[optind]);
- optind++;
- break;
- }
- ebt_check_option2(&flags, OPT_PROTOCOL);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IPROTO;
+ struct xtables_args args = {
+ .family = h->family,
+ };
+ int ret = 0;
- cs.eb.bitmask &= ~((unsigned int)EBT_NOPROTO);
- i = strtol(optarg, &buffer, 16);
- if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified protocol");
- if (*buffer != '\0') {
- struct xt_ethertypeent *ent;
+ p.ops->print_help = print_help;
- if (!strcasecmp(optarg, "LENGTH")) {
- cs.eb.bitmask |= EBT_802_3;
- break;
- }
- ent = xtables_getethertypebyname(optarg);
- if (!ent)
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
- cs.eb.ethproto = ent->e_ethertype;
- } else
- cs.eb.ethproto = i;
+ do_parse(argc, argv, &p, &cs, &args);
- if (cs.eb.ethproto < 0x0600)
- xtables_error(PARAMETER_PROBLEM,
- "Sorry, protocols have values above or equal to 0x0600");
- break;
- case 17 : /* Lc */
- ebt_check_option2(&flags, LIST_C);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lc with -L");
- flags |= LIST_C;
- break;
- case 18 : /* Ln */
- ebt_check_option2(&flags, LIST_N);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Ln with -L");
- if (flags & LIST_X)
- xtables_error(PARAMETER_PROBLEM,
- "--Lx is not compatible with --Ln");
- flags |= LIST_N;
- break;
- case 19 : /* Lx */
- ebt_check_option2(&flags, LIST_X);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lx with -L");
- if (flags & LIST_N)
- xtables_error(PARAMETER_PROBLEM,
- "--Lx is not compatible with --Ln");
- flags |= LIST_X;
- break;
- case 12 : /* Lmac2 */
- ebt_check_option2(&flags, LIST_MAC2);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lmac2 with -L");
- flags |= LIST_MAC2;
- break;
- case 1 :
- if (!strcmp(optarg, "!"))
- ebt_check_inverse2(optarg, argc, argv);
- else
- xtables_error(PARAMETER_PROBLEM,
- "Bad argument : '%s'", optarg);
- /* ebt_ebt_check_inverse2() did optind++ */
- optind--;
- continue;
- default:
- ebt_check_inverse2(optarg, argc, argv);
- ebt_command_default(&cs);
-
- if (command != 'A' && command != 'I' &&
- command != 'D')
- xtables_error(PARAMETER_PROBLEM,
- "Extensions only for -A, -I, -D");
- }
- ebt_invert = 0;
- }
+ h->verbose = p.verbose;
/* Do the final checks */
- if (command == 'A' || command == 'I' || command == 'D') {
- for (xtrm_i = cs.matches; xtrm_i; xtrm_i = xtrm_i->next)
- xtables_option_mfcall(xtrm_i->match);
-
- for (match = cs.match_list; match; match = match->next) {
- if (match->ismatch)
- continue;
+ if (!nft_table_builtin_find(h, p.table))
+ xtables_error(VERSION_PROBLEM,
+ "table '%s' does not exist", p.table);
- xtables_option_tfcall(match->u.watcher);
- }
-
- if (cs.target != NULL)
- xtables_option_tfcall(cs.target);
- }
-
- cs.eb.ethproto = htons(cs.eb.ethproto);
-
- switch (command) {
- case 'F':
+ printf("nft ");
+ switch (p.command) {
+ case CMD_FLUSH:
if (p.chain) {
printf("flush chain bridge %s %s\n", p.table, p.chain);
} else {
@@ -506,16 +103,52 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
}
ret = 1;
break;
- case 'A':
+ case CMD_APPEND:
ret = nft_rule_eb_xlate_add(h, &p, &cs, true);
if (!ret)
print_ebt_cmd(argc, argv);
break;
- case 'I':
+ case CMD_INSERT:
ret = nft_rule_eb_xlate_add(h, &p, &cs, false);
if (!ret)
print_ebt_cmd(argc, argv);
break;
+ case CMD_LIST:
+ printf("list table bridge %s\n", p.table);
+ ret = 1;
+ break;
+ case CMD_NEW_CHAIN:
+ printf("add chain bridge %s %s\n", p.table, p.chain);
+ ret = 1;
+ break;
+ case CMD_DELETE_CHAIN:
+ printf("delete chain bridge %s %s\n", p.table, p.chain);
+ ret = 1;
+ break;
+ case CMD_INIT_TABLE:
+ printf("flush table bridge %s\n", p.table);
+ ret = 1;
+ break;
+ case CMD_DELETE:
+ case CMD_DELETE_NUM:
+ case CMD_CHECK:
+ case CMD_REPLACE:
+ case CMD_ZERO:
+ case CMD_ZERO_NUM:
+ case CMD_LIST|CMD_ZERO:
+ case CMD_LIST|CMD_ZERO_NUM:
+ case CMD_LIST_RULES:
+ case CMD_LIST_RULES|CMD_ZERO:
+ case CMD_LIST_RULES|CMD_ZERO_NUM:
+ case CMD_NEW_CHAIN|CMD_SET_POLICY:
+ case CMD_SET_POLICY:
+ case CMD_RENAME_CHAIN:
+ case CMD_CHANGE_COUNTERS:
+ break;
+ default:
+ /* We should never reach this... */
+ printf("Unsupported command?\n");
+ exit(1);
}
ebt_cs_clean(&cs);
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index e03b2b2510eda..c3cf1c2c74104 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -42,76 +42,6 @@
#include "nft.h"
#include "nft-bridge.h"
-/* from linux/netfilter_bridge/ebtables.h */
-#define EBT_TABLE_MAXNAMELEN 32
-#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-
-/*
- * From include/ebtables_u.h
- */
-#define ebt_check_option2(flags, mask) EBT_CHECK_OPTION(flags, mask)
-
-/*
- * From useful_functions.c
- */
-
-/* 0: default
- * 1: the inverse '!' of the option has already been specified */
-int ebt_invert = 0;
-
-static int ebt_check_inverse2(const char option[], int argc, char **argv)
-{
- if (!option)
- return ebt_invert;
- if (strcmp(option, "!") == 0) {
- if (ebt_invert == 1)
- xtables_error(PARAMETER_PROBLEM,
- "Double use of '!' not allowed");
- if (optind >= argc)
- optarg = NULL;
- else
- optarg = argv[optind];
- optind++;
- ebt_invert = 1;
- return 1;
- }
- return ebt_invert;
-}
-
-/* XXX: merge with assert_valid_chain_name()? */
-static void ebt_assert_valid_chain_name(const char *chainname)
-{
- if (strlen(chainname) >= EBT_CHAIN_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "Chain name length can't exceed %d",
- EBT_CHAIN_MAXNAMELEN - 1);
-
- if (*chainname == '-' || *chainname == '!')
- xtables_error(PARAMETER_PROBLEM, "No chain name specified");
-
- if (xtables_find_target(chainname, XTF_TRY_LOAD))
- xtables_error(PARAMETER_PROBLEM,
- "Target with name %s exists", chainname);
-
- if (strchr(chainname, ' ') != NULL)
- xtables_error(PARAMETER_PROBLEM,
- "Use of ' ' not allowed in chain names");
-}
-
-/*
- * Glue code to use libxtables
- */
-static int parse_rule_number(const char *rule)
-{
- unsigned int rule_nr;
-
- if (!xtables_strtoui(rule, NULL, &rule_nr, 1, INT_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid rule number `%s'", rule);
-
- return rule_nr;
-}
-
static int
delete_entry(struct nft_handle *h,
const char *chain,
@@ -159,35 +89,6 @@ change_entry_counters(struct nft_handle *h,
return ret;
}
-int ebt_get_current_chain(const char *chain)
-{
- if (!chain)
- return -1;
-
- if (strcmp(chain, "PREROUTING") == 0)
- return NF_BR_PRE_ROUTING;
- else if (strcmp(chain, "INPUT") == 0)
- return NF_BR_LOCAL_IN;
- else if (strcmp(chain, "FORWARD") == 0)
- return NF_BR_FORWARD;
- else if (strcmp(chain, "OUTPUT") == 0)
- return NF_BR_LOCAL_OUT;
- else if (strcmp(chain, "POSTROUTING") == 0)
- return NF_BR_POST_ROUTING;
- else if (strcmp(chain, "BROUTING") == 0)
- return NF_BR_BROUTING;
-
- /* placeholder for user defined chain */
- return NF_BR_NUMHOOKS;
-}
-
-/*
- * The original ebtables parser
- */
-
-/* Checks whether a command has already been specified */
-#define OPT_COMMANDS (flags & OPT_COMMAND || flags & OPT_ZERO)
-
/* Default command line options. Do not mess around with the already
* assigned numbers unless you know what you are doing */
struct option ebt_original_options[] =
@@ -244,10 +145,6 @@ struct xtables_globals ebtables_globals = {
#define prog_name ebtables_globals.program_name
#define prog_vers ebtables_globals.program_version
-/*
- * From libebtc.c
- */
-
/* Prints all registered extensions */
static void ebt_list_extensions(const struct xtables_target *t,
const struct xtables_rule_match *m)
@@ -303,7 +200,7 @@ static struct option *merge_options(struct option *oldopts,
return merge;
}
-static void print_help(struct iptables_command_state *cs)
+void nft_bridge_print_help(struct iptables_command_state *cs)
{
const struct xtables_rule_match *m = cs->matches;
struct xtables_target *t = cs->target;
@@ -411,107 +308,6 @@ static int list_rules(struct nft_handle *h, const char *chain, const char *table
return nft_cmd_rule_list(h, chain, table, rule_nr, format);
}
-static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
-{
- char *colon = strchr(argv, ':'), *buffer;
-
- if (colon) {
- *colon = '\0';
- if (*(colon + 1) == '\0')
- *rule_nr_end = -1; /* Until the last rule */
- else {
- *rule_nr_end = strtol(colon + 1, &buffer, 10);
- if (*buffer != '\0' || *rule_nr_end == 0)
- return -1;
- }
- }
- if (colon == argv)
- *rule_nr = 1; /* Beginning with the first rule */
- else {
- *rule_nr = strtol(argv, &buffer, 10);
- if (*buffer != '\0' || *rule_nr == 0)
- return -1;
- }
- if (!colon)
- *rule_nr_end = *rule_nr;
- return 0;
-}
-
-/* Incrementing or decrementing rules in daemon mode is not supported as the
- * involved code overload is not worth it (too annoying to take the increased
- * counters in the kernel into account). */
-static uint8_t parse_change_counters_rule(int argc, char **argv,
- int *rule_nr, int *rule_nr_end,
- struct iptables_command_state *cs)
-{
- uint8_t ret = 0;
- char *buffer;
-
- if (optind + 1 >= argc ||
- (argv[optind][0] == '-' && !isdigit(argv[optind][1])) ||
- (argv[optind + 1][0] == '-' && !isdigit(argv[optind + 1][1])))
- xtables_error(PARAMETER_PROBLEM,
- "The command -C needs at least 2 arguments");
- if (optind + 2 < argc &&
- (argv[optind + 2][0] != '-' || isdigit(argv[optind + 2][1]))) {
- if (optind + 3 != argc)
- xtables_error(PARAMETER_PROBLEM,
- "No extra options allowed with -C start_nr[:end_nr] pcnt bcnt");
- if (parse_rule_range(argv[optind], rule_nr, rule_nr_end))
- xtables_error(PARAMETER_PROBLEM,
- "Something is wrong with the rule number specification '%s'",
- argv[optind]);
- optind++;
- }
-
- if (argv[optind][0] == '+') {
- ret |= CTR_OP_INC_PKTS;
- cs->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
- } else if (argv[optind][0] == '-') {
- ret |= CTR_OP_DEC_PKTS;
- cs->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
- } else {
- cs->counters.pcnt = strtoull(argv[optind], &buffer, 10);
- }
- if (*buffer != '\0')
- goto invalid;
-
- optind++;
-
- if (argv[optind][0] == '+') {
- ret |= CTR_OP_INC_BYTES;
- cs->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
- } else if (argv[optind][0] == '-') {
- ret |= CTR_OP_DEC_BYTES;
- cs->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
- } else {
- cs->counters.bcnt = strtoull(argv[optind], &buffer, 10);
- }
- if (*buffer != '\0')
- goto invalid;
-
- optind++;
-
- return ret;
-invalid:
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid", argv[optind]);
-}
-
-static void ebtables_parse_interface(const char *arg, char *vianame)
-{
- unsigned char mask[IFNAMSIZ];
- char *c;
-
- xtables_parse_interface(arg, vianame, mask);
-
- if ((c = strchr(vianame, '+'))) {
- if (*(c + 1) != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Spurious characters after '+' wildcard");
- }
-}
-
/* This code is very similar to iptables/xtables.c:command_match() */
static void ebt_load_match(const char *name)
{
@@ -580,6 +376,10 @@ static void ebt_load_match_extensions(void)
ebt_load_watcher("log");
ebt_load_watcher("nflog");
+
+ /* assign them back so do_parse() may
+ * reset opts to orig_opts upon each call */
+ xt_params->orig_opts = opts;
}
void ebt_add_match(struct xtables_match *m,
@@ -642,7 +442,8 @@ void ebt_add_watcher(struct xtables_target *watcher,
*matchp = newnode;
}
-int ebt_command_default(struct iptables_command_state *cs)
+int ebt_command_default(struct iptables_command_state *cs,
+ struct xtables_globals *unused, bool ebt_invert)
{
struct xtables_target *t = cs->target;
struct xtables_match *m;
@@ -753,431 +554,43 @@ void nft_fini_eb(struct nft_handle *h)
int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
bool restore)
{
- char *buffer;
- int c, i;
- uint8_t chcounter = 0; /* Needed for -C */
- int rule_nr = 0;
- int rule_nr_end = 0;
- int ret = 0;
- unsigned int flags = 0;
- struct xtables_target *t;
struct iptables_command_state cs = {
.argc = argc,
.argv = argv,
.jumpto = "",
.eb.bitmask = EBT_NOPROTO,
};
+ const struct builtin_table *t;
+ struct xtables_args args = {
+ .family = h->family,
+ };
struct xt_cmd_parse p = {
+ .table = *table,
+ .restore = restore,
+ .line = line,
+ .rule_ranges = true,
+ .ops = &h->ops->cmd_parse,
};
- char command = 'h';
- const char *chain = NULL;
- const char *policy = NULL;
- int selected_chain = -1;
- struct xtables_rule_match *xtrm_i;
- struct ebt_match *match;
- bool table_set = false;
+ int ret = 0;
- /* avoid cumulating verbosity with ebtables-restore */
- h->verbose = 0;
+ do_parse(argc, argv, &p, &cs, &args);
- /* prevent getopt to spoil our error reporting */
- optind = 0;
- opterr = false;
+ h->verbose = p.verbose;
- for (t = xtables_targets; t; t = t->next) {
- t->tflags = 0;
- t->used = 0;
- }
+ t = nft_table_builtin_find(h, p.table);
+ if (!t)
+ xtables_error(VERSION_PROBLEM,
+ "table '%s' does not exist", p.table);
- /* Getopt saves the day */
- while ((c = getopt_long(argc, argv, EBT_OPTSTRING,
- opts, NULL)) != -1) {
- cs.c = c;
- switch (c) {
-
- case 'A': /* Add a rule */
- case 'D': /* Delete a rule */
- case 'C': /* Change counters */
- case 'P': /* Define policy */
- case 'I': /* Insert a rule */
- case 'N': /* Make a user defined chain */
- case 'E': /* Rename chain */
- case 'X': /* Delete chain */
- case 14: /* check a rule */
- /* We allow -N chainname -P policy */
- if (command == 'N' && c == 'P') {
- command = c;
- optind--; /* No table specified */
- goto handle_P;
- }
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
-
- command = c;
- if (optarg && (optarg[0] == '-' || !strcmp(optarg, "!")))
- xtables_error(PARAMETER_PROBLEM, "No chain name specified");
- chain = optarg;
- selected_chain = ebt_get_current_chain(chain);
- flags |= OPT_COMMAND;
-
- if (c == 'N') {
- ebt_assert_valid_chain_name(chain);
- ret = nft_cmd_chain_user_add(h, chain, *table);
- break;
- } else if (c == 'X') {
- /* X arg is optional, optarg is NULL */
- if (!chain && optind < argc && argv[optind][0] != '-') {
- chain = argv[optind];
- optind++;
- }
- ret = nft_cmd_chain_del(h, chain, *table, 0);
- break;
- }
-
- if (c == 'E') {
- if (!xs_has_arg(argc, argv))
- xtables_error(PARAMETER_PROBLEM, "No new chain name specified");
- else if (optind < argc - 1)
- xtables_error(PARAMETER_PROBLEM, "No extra options allowed with -E");
-
- ebt_assert_valid_chain_name(argv[optind]);
-
- errno = 0;
- ret = nft_cmd_chain_user_rename(h, chain, *table,
- argv[optind]);
- if (ret != 0 && errno == ENOENT)
- xtables_error(PARAMETER_PROBLEM, "Chain '%s' doesn't exists", chain);
-
- optind++;
- break;
- } else if (c == 'D' && optind < argc && (argv[optind][0] != '-' || (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
- if (optind != argc - 1)
- xtables_error(PARAMETER_PROBLEM,
- "No extra options allowed with -D start_nr[:end_nr]");
- if (parse_rule_range(argv[optind], &rule_nr, &rule_nr_end))
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified rule number(s) '%s'", argv[optind]);
- optind++;
- } else if (c == 'C') {
- if ((chcounter = parse_change_counters_rule(argc, argv, &rule_nr, &rule_nr_end, &cs)) == -1)
- return -1;
- } else if (c == 'I') {
- if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
- rule_nr = 1;
- else {
- rule_nr = parse_rule_number(argv[optind]);
- optind++;
- }
- } else if (c == 'P') {
-handle_P:
- if (optind >= argc)
- xtables_error(PARAMETER_PROBLEM,
- "No policy specified");
- for (i = 0; i < NUM_STANDARD_TARGETS; i++)
- if (!strcmp(argv[optind], nft_ebt_standard_target(i))) {
- policy = argv[optind];
- if (-i-1 == EBT_CONTINUE)
- xtables_error(PARAMETER_PROBLEM,
- "Wrong policy '%s'",
- argv[optind]);
- break;
- }
- if (i == NUM_STANDARD_TARGETS)
- xtables_error(PARAMETER_PROBLEM,
- "Unknown policy '%s'", argv[optind]);
- optind++;
- }
- break;
- case 'L': /* List */
- case 'F': /* Flush */
- case 'Z': /* Zero counters */
- if (c == 'Z') {
- if ((flags & OPT_ZERO) || (flags & OPT_COMMAND && command != 'L'))
-print_zero:
- xtables_error(PARAMETER_PROBLEM,
- "Command -Z only allowed together with command -L");
- flags |= OPT_ZERO;
- } else {
- if (flags & OPT_COMMAND)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- command = c;
- flags |= OPT_COMMAND;
- if (flags & OPT_ZERO && c != 'L')
- goto print_zero;
- }
-
- if (optind < argc && argv[optind][0] != '-') {
- chain = argv[optind];
- optind++;
- }
- break;
- case 'v': /* verbose */
- flags |= OPT_VERBOSE;
- h->verbose++;
- break;
- case 'V': /* Version */
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- printf("%s %s\n", prog_name, prog_vers);
- exit(0);
- case 'h': /* Help */
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- print_help(&cs);
- exit(0);
- case 't': /* Table */
- if (restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option cannot be used in %s.",
- xt_params->program_name);
- else if (table_set)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple use of same option not allowed");
- if (!nft_table_builtin_find(h, optarg))
- xtables_error(VERSION_PROBLEM,
- "table '%s' does not exist",
- optarg);
- *table = optarg;
- table_set = true;
+ switch (p.command) {
+ case CMD_NEW_CHAIN:
+ case CMD_NEW_CHAIN | CMD_SET_POLICY:
+ ret = nft_cmd_chain_user_add(h, p.chain, p.table);
+ if (!ret || !(p.command & CMD_SET_POLICY))
break;
- case 'i': /* Input interface */
- case 15 : /* Logical input interface */
- case 'o': /* Output interface */
- case 16 : /* Logical output interface */
- case 'j': /* Target */
- case 'p': /* Net family protocol */
- case 's': /* Source mac */
- case 'd': /* Destination mac */
- case 'c': /* Set counters */
- if (!OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "No command specified");
- if (command != 'A' && command != 'D' &&
- command != 'I' && command != 'C' && command != 14)
- xtables_error(PARAMETER_PROBLEM,
- "Command and option do not match");
- if (c == 'i') {
- ebt_check_option2(&flags, OPT_VIANAMEIN);
- if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use -i only in INPUT, FORWARD, PREROUTING and BROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IIN;
-
- ebtables_parse_interface(optarg, cs.eb.in);
- break;
- } else if (c == 15) {
- ebt_check_option2(&flags, OPT_LOGICALIN);
- if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use --logical-in only in INPUT, FORWARD, PREROUTING and BROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALIN;
-
- ebtables_parse_interface(optarg, cs.eb.logical_in);
- break;
- } else if (c == 'o') {
- ebt_check_option2(&flags, OPT_VIANAMEOUT);
- if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use -o only in OUTPUT, FORWARD and POSTROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IOUT;
-
- ebtables_parse_interface(optarg, cs.eb.out);
- break;
- } else if (c == 16) {
- ebt_check_option2(&flags, OPT_LOGICALOUT);
- if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use --logical-out only in OUTPUT, FORWARD and POSTROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALOUT;
-
- ebtables_parse_interface(optarg, cs.eb.logical_out);
- break;
- } else if (c == 'j') {
- ebt_check_option2(&flags, OPT_JUMP);
- if (strcmp(optarg, "CONTINUE") != 0) {
- command_jump(&cs, optarg);
- }
- break;
- } else if (c == 's') {
- ebt_check_option2(&flags, OPT_SOURCE);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ISOURCE;
-
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.sourcemac,
- cs.eb.sourcemsk))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
- cs.eb.bitmask |= EBT_SOURCEMAC;
- break;
- } else if (c == 'd') {
- ebt_check_option2(&flags, OPT_DESTINATION);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IDEST;
-
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.destmac,
- cs.eb.destmsk))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
- cs.eb.bitmask |= EBT_DESTMAC;
- break;
- } else if (c == 'c') {
- ebt_check_option2(&flags, OPT_COUNTERS);
- if (ebt_check_inverse2(optarg, argc, argv))
- xtables_error(PARAMETER_PROBLEM,
- "Unexpected '!' after -c");
- if (optind >= argc || optarg[0] == '-' || argv[optind][0] == '-')
- xtables_error(PARAMETER_PROBLEM,
- "Option -c needs 2 arguments");
-
- cs.counters.pcnt = strtoull(optarg, &buffer, 10);
- if (*buffer != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid",
- optarg);
- cs.counters.bcnt = strtoull(argv[optind], &buffer, 10);
- if (*buffer != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid",
- argv[optind]);
- optind++;
- break;
- }
- ebt_check_option2(&flags, OPT_PROTOCOL);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IPROTO;
-
- cs.eb.bitmask &= ~((unsigned int)EBT_NOPROTO);
- i = strtol(optarg, &buffer, 16);
- if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified protocol");
- if (*buffer != '\0') {
- struct xt_ethertypeent *ent;
-
- if (!strcasecmp(optarg, "LENGTH")) {
- cs.eb.bitmask |= EBT_802_3;
- break;
- }
- ent = xtables_getethertypebyname(optarg);
- if (!ent)
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
- cs.eb.ethproto = ent->e_ethertype;
- } else
- cs.eb.ethproto = i;
-
- if (cs.eb.ethproto < 0x0600)
- xtables_error(PARAMETER_PROBLEM,
- "Sorry, protocols have values above or equal to 0x0600");
- break;
- case 17 : /* Lc */
- ebt_check_option2(&flags, LIST_C);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lc with -L");
- flags |= LIST_C;
- break;
- case 18 : /* Ln */
- ebt_check_option2(&flags, LIST_N);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Ln with -L");
- if (flags & LIST_X)
- xtables_error(PARAMETER_PROBLEM,
- "--Lx is not compatible with --Ln");
- flags |= LIST_N;
- break;
- case 19 : /* Lx */
- ebt_check_option2(&flags, LIST_X);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lx with -L");
- if (flags & LIST_N)
- xtables_error(PARAMETER_PROBLEM,
- "--Lx is not compatible with --Ln");
- flags |= LIST_X;
- break;
- case 12 : /* Lmac2 */
- ebt_check_option2(&flags, LIST_MAC2);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lmac2 with -L");
- flags |= LIST_MAC2;
- break;
- case 11: /* init-table */
- if (restore)
- xtables_error(PARAMETER_PROBLEM,
- "--init-table is not supported in daemon mode");
- nft_cmd_table_flush(h, *table, false);
- return 1;
- case 13 :
- break;
- case 1 :
- if (!strcmp(optarg, "!"))
- ebt_check_inverse2(optarg, argc, argv);
- else
- xtables_error(PARAMETER_PROBLEM,
- "Bad argument : '%s'", optarg);
- /* ebt_ebt_check_inverse2() did optind++ */
- optind--;
- continue;
- default:
- ebt_check_inverse2(optarg, argc, argv);
- ebt_command_default(&cs);
-
- if (command != 'A' && command != 'I' &&
- command != 'D' && command != 'C' && command != 14)
- xtables_error(PARAMETER_PROBLEM,
- "Extensions only for -A, -I, -D and -C");
- }
- ebt_invert = 0;
- }
-
- /* Just in case we didn't catch an error */
- /*if (ebt_errormsg[0] != '\0')
- return -1;
-
- if (!(table = ebt_find_table(replace->name)))
- ebt_print_error2("Bad table name");*/
-
- /* Do the final checks */
- if (command == 'A' || command == 'I' ||
- command == 'D' || command == 'C' || command == 14) {
- for (xtrm_i = cs.matches; xtrm_i; xtrm_i = xtrm_i->next)
- xtables_option_mfcall(xtrm_i->match);
-
- for (match = cs.match_list; match; match = match->next) {
- if (match->ismatch)
- continue;
-
- xtables_option_tfcall(match->u.watcher);
- }
-
- if (cs.target != NULL)
- xtables_option_tfcall(cs.target);
- }
- /* So, the extensions can work with the host endian.
- * The kernel does not have to do this of course */
- cs.eb.ethproto = htons(cs.eb.ethproto);
-
- p.table = *table;
- p.chain = chain;
- p.policy = policy;
- p.rulenum = rule_nr;
- p.rulenum_end = rule_nr_end;
- cs.options = flags;
-
- switch (command) {
- case 'P':
- if (selected_chain >= NF_BR_NUMHOOKS) {
+ /* fall through */
+ case CMD_SET_POLICY:
+ if (!nft_chain_builtin_find(t, p.chain)) {
ret = ebt_cmd_user_chain_policy(h, p.table, p.chain,
p.policy);
break;
@@ -1190,46 +603,83 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy");
break;
- case 'L':
- ret = list_rules(h, p.chain, p.table, p.rulenum,
- cs.options & OPT_VERBOSE,
- 0,
- /*cs.options&OPT_EXPANDED*/0,
- cs.options&LIST_N,
- cs.options&LIST_C);
- if (!(cs.options & OPT_ZERO))
- break;
- case 'Z':
+ case CMD_LIST:
+ case CMD_LIST | CMD_ZERO:
+ case CMD_LIST | CMD_ZERO_NUM:
+ case CMD_LIST_RULES:
+ case CMD_LIST_RULES | CMD_ZERO:
+ case CMD_LIST_RULES | CMD_ZERO_NUM:
+ if (p.command & CMD_LIST)
+ ret = list_rules(h, p.chain, p.table, p.rulenum,
+ cs.options & OPT_VERBOSE,
+ 0,
+ /*cs.options&OPT_EXPANDED*/0,
+ cs.options&OPT_LINENUMBERS,
+ cs.options&OPT_LIST_C);
+ else if (p.command & CMD_LIST_RULES)
+ ret = nft_cmd_rule_list_save(h, p.chain, p.table,
+ p.rulenum - 1,
+ cs.options & OPT_VERBOSE);
+ if (ret && (p.command & CMD_ZERO))
+ ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
+ cs.options & OPT_VERBOSE);
+ if (ret && (p.command & CMD_ZERO_NUM))
+ ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
+ p.rulenum - 1);
+ break;
+ case CMD_ZERO:
ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
cs.options & OPT_VERBOSE);
break;
- case 'F':
+ case CMD_ZERO_NUM:
+ ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
+ p.rulenum - 1);
+ break;
+ case CMD_FLUSH:
ret = nft_cmd_rule_flush(h, p.chain, p.table,
cs.options & OPT_VERBOSE);
break;
- case 'A':
+ case CMD_APPEND:
ret = nft_cmd_rule_append(h, p.chain, p.table, &cs,
cs.options & OPT_VERBOSE);
break;
- case 'I':
+ case CMD_INSERT:
ret = nft_cmd_rule_insert(h, p.chain, p.table, &cs,
p.rulenum - 1,
cs.options & OPT_VERBOSE);
break;
- case 'D':
+ case CMD_DELETE:
+ case CMD_DELETE_NUM:
ret = delete_entry(h, p.chain, p.table, &cs, p.rulenum - 1,
p.rulenum_end, cs.options & OPT_VERBOSE);
break;
- case 14:
+ case CMD_DELETE_CHAIN:
+ ret = nft_cmd_chain_del(h, p.chain, p.table, 0);
+ break;
+ case CMD_RENAME_CHAIN:
+ ret = nft_cmd_chain_user_rename(h, p.chain, p.table, p.newname);
+ break;
+ case CMD_INIT_TABLE:
+ ret = nft_cmd_table_flush(h, p.table, false);
+ break;
+ case CMD_CHECK:
ret = nft_cmd_rule_check(h, p.chain, p.table,
&cs, cs.options & OPT_VERBOSE);
break;
- case 'C':
+ case CMD_CHANGE_COUNTERS:
ret = change_entry_counters(h, p.chain, p.table, &cs,
p.rulenum - 1, p.rulenum_end,
- chcounter,
+ args.counter_op,
cs.options & OPT_VERBOSE);
break;
+ case CMD_REPLACE:
+ ret = nft_cmd_rule_replace(h, p.chain, p.table, &cs,
+ p.rulenum - 1,
+ cs.options & OPT_VERBOSE);
+ break;
+ default:
+ /* We should never reach this... */
+ exit_tryhelp(2, line);
}
ebt_cs_clean(&cs);
--
2.41.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [iptables PATCH 00/13] ebtables: Use the shared commandline parser
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
` (12 preceding siblings ...)
2023-11-29 13:28 ` [iptables PATCH 13/13] ebtables: Use do_parse() from xshared Phil Sutter
@ 2023-12-05 16:25 ` Phil Sutter
13 siblings, 0 replies; 15+ messages in thread
From: Phil Sutter @ 2023-12-05 16:25 UTC (permalink / raw)
To: netfilter-devel
On Wed, Nov 29, 2023 at 02:28:14PM +0100, Phil Sutter wrote:
> This series converts do_commandeb() and do_commandeb_xlate() to call
> do_parse() from xshared.c instead of iterating over argv themselves.
>
> Patches 1-6 prepare the shared (parser) code for use by ebtables.
> Patches 7-11 prepare ebtables code for the following integration in
> patch 13. Patch 12 is a minor refactoring in xshared but fits fine right
> before the merge as the introduced helper function is called two more
> times by it.
>
> Phil Sutter (13):
> xshared: do_parse: Skip option checking for CMD_DELETE_NUM
> xshared: Perform protocol value parsing in callback
> xshared: Turn command_default() into a callback
> xshared: Introduce print_help callback (again)
> xshared: Support rule range deletion in do_parse()
> xshared: Support for ebtables' --change-counters command
> ebtables{,-translate}: Convert if-clause to switch()
> ebtables: Change option values to avoid clashes
> ebtables: Pass struct iptables_command_state to print_help()
> ebtables: Make 'h' case just a call to print_help()
> ebtables: Use struct xt_cmd_parse
> xshared: Introduce option_test_and_reject()
> ebtables: Use do_parse() from xshared
Series applied.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2023-12-05 16:25 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-29 13:28 [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 01/13] xshared: do_parse: Skip option checking for CMD_DELETE_NUM Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 02/13] xshared: Perform protocol value parsing in callback Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 03/13] xshared: Turn command_default() into a callback Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 04/13] xshared: Introduce print_help callback (again) Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 05/13] xshared: Support rule range deletion in do_parse() Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 06/13] xshared: Support for ebtables' --change-counters command Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 07/13] ebtables{,-translate}: Convert if-clause to switch() Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 08/13] ebtables: Change option values to avoid clashes Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 09/13] ebtables: Pass struct iptables_command_state to print_help() Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 10/13] ebtables: Make 'h' case just a call " Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 11/13] ebtables: Use struct xt_cmd_parse Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 12/13] xshared: Introduce option_test_and_reject() Phil Sutter
2023-11-29 13:28 ` [iptables PATCH 13/13] ebtables: Use do_parse() from xshared Phil Sutter
2023-12-05 16:25 ` [iptables PATCH 00/13] ebtables: Use the shared commandline parser Phil Sutter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).