summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2023-11-14 20:18:12 +0100
committerPhil Sutter <phil@nwl.cc>2023-11-29 02:33:02 +0100
commit90f84108cf61891f6bc60d2f93cb25e05a47a661 (patch)
tree054db6afb719630aaa1185e909d9d07b94f8fc48
parent20e95a4ec5cec14d9e03ba562fa65f015d49dc14 (diff)
xshared: Introduce xt_cmd_parse_ops::option_invert
Replace the awkward inverse_for_options array with basically a few switch() statements clearly identifying the relation between option and inverse values and relieve callers from having to find the option flag bit's position. Signed-off-by: Phil Sutter <phil@nwl.cc>
-rw-r--r--iptables/ip6tables.c1
-rw-r--r--iptables/iptables.c1
-rw-r--r--iptables/nft-arp.c14
-rw-r--r--iptables/nft-ipv4.c1
-rw-r--r--iptables/nft-ipv6.c1
-rw-r--r--iptables/xshared.c38
-rw-r--r--iptables/xshared.h2
7 files changed, 34 insertions, 24 deletions
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 85cb211d..08da04b4 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -670,6 +670,7 @@ int do_command6(int argc, char *argv[], char **table,
.proto_parse = ipv6_proto_parse,
.post_parse = ipv6_post_parse,
.option_name = ip46t_option_name,
+ .option_invert = ip46t_option_invert,
};
struct xt_cmd_parse p = {
.table = *table,
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 4bfce62d..a73e8eed 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -664,6 +664,7 @@ int do_command4(int argc, char *argv[], char **table,
.proto_parse = ipv4_proto_parse,
.post_parse = ipv4_post_parse,
.option_name = ip46t_option_name,
+ .option_invert = ip46t_option_invert,
};
struct xt_cmd_parse p = {
.table = *table,
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index 6f8e1952..c009dd83 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -832,6 +832,19 @@ static const char *nft_arp_option_name(int option)
}
}
+static int nft_arp_option_invert(int option)
+{
+ switch (option) {
+ case OPT_S_MAC: return IPT_INV_SRCDEVADDR;
+ case OPT_D_MAC: return IPT_INV_TGTDEVADDR;
+ case OPT_H_LENGTH: return IPT_INV_ARPHLN;
+ case OPT_OPCODE: return IPT_INV_ARPOP;
+ case OPT_H_TYPE: return IPT_INV_ARPHRD;
+ case OPT_P_TYPE: return IPT_INV_PROTO;
+ default: return ip46t_option_invert(option);
+ }
+}
+
struct nft_family_ops nft_family_ops_arp = {
.add = nft_arp_add,
.is_same = nft_arp_is_same,
@@ -844,6 +857,7 @@ struct nft_family_ops nft_family_ops_arp = {
.cmd_parse = {
.post_parse = nft_arp_post_parse,
.option_name = nft_arp_option_name,
+ .option_invert = nft_arp_option_invert,
},
.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 166680b3..7fb71ed4 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -354,6 +354,7 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.proto_parse = ipv4_proto_parse,
.post_parse = ipv4_post_parse,
.option_name = ip46t_option_name,
+ .option_invert = ip46t_option_invert,
},
.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 2cc45944..bb417356 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -345,6 +345,7 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.proto_parse = ipv6_proto_parse,
.post_parse = ipv6_post_parse,
.option_name = ip46t_option_name,
+ .option_invert = ip46t_option_invert,
},
.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 31a30195..f939a988 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1003,27 +1003,18 @@ const char *ip46t_option_name(int option)
}
}
-static const int inverse_for_options[NUMBER_OF_OPT] =
+int ip46t_option_invert(int option)
{
-/* -n */ 0,
-/* -s */ IPT_INV_SRCIP,
-/* -d */ IPT_INV_DSTIP,
-/* -p */ XT_INV_PROTO,
-/* -j */ 0,
-/* -v */ 0,
-/* -x */ 0,
-/* -i */ IPT_INV_VIA_IN,
-/* -o */ IPT_INV_VIA_OUT,
-/*--line*/ 0,
-/* -c */ 0,
-/* -f */ IPT_INV_FRAG,
-/* 2 */ IPT_INV_SRCDEVADDR,
-/* 3 */ IPT_INV_TGTDEVADDR,
-/* -l */ IPT_INV_ARPHLN,
-/* 4 */ IPT_INV_ARPOP,
-/* 5 */ IPT_INV_ARPHRD,
-/* 6 */ IPT_INV_PROTO,
-};
+ switch (option) {
+ case OPT_SOURCE: return IPT_INV_SRCIP;
+ case OPT_DESTINATION: return IPT_INV_DSTIP;
+ case OPT_PROTOCOL: return XT_INV_PROTO;
+ case OPT_VIANAMEIN: return IPT_INV_VIA_IN;
+ case OPT_VIANAMEOUT: return IPT_INV_VIA_OUT;
+ case OPT_FRAGMENT: return IPT_INV_FRAG;
+ default: return -1;
+ }
+}
static void
set_option(struct xt_cmd_parse_ops *ops,
@@ -1037,14 +1028,13 @@ set_option(struct xt_cmd_parse_ops *ops,
*options |= option;
if (invert) {
- unsigned int i;
- for (i = 0; 1 << i != option; i++);
+ int invopt = ops->option_invert(option);
- if (!inverse_for_options[i])
+ if (invopt < 0)
xtables_error(PARAMETER_PROBLEM,
"cannot have ! before %s",
ops->option_name(option));
- *invflg |= inverse_for_options[i];
+ *invflg |= invopt;
}
}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 2470acbb..28efd73c 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -274,6 +274,7 @@ struct xt_cmd_parse_ops {
struct iptables_command_state *cs,
struct xtables_args *args);
const char *(*option_name)(int option);
+ int (*option_invert)(int option);
};
struct xt_cmd_parse {
@@ -290,6 +291,7 @@ struct xt_cmd_parse {
};
const char *ip46t_option_name(int option);
+int ip46t_option_invert(int option);
void do_parse(int argc, char *argv[],
struct xt_cmd_parse *p, struct iptables_command_state *cs,