[iptables PATCH 06/13] xshared: Support for ebtables' --change-counters command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxx>
---
 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





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux