]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xshared: Introduce xt_cmd_parse_ops::option_invert
authorPhil Sutter <phil@nwl.cc>
Tue, 14 Nov 2023 19:18:12 +0000 (20:18 +0100)
committerPhil Sutter <phil@nwl.cc>
Wed, 29 Nov 2023 01:33:02 +0000 (02:33 +0100)
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>
iptables/ip6tables.c
iptables/iptables.c
iptables/nft-arp.c
iptables/nft-ipv4.c
iptables/nft-ipv6.c
iptables/xshared.c
iptables/xshared.h

index 85cb211d2ec121792a343ec25847e7743d3a58b5..08da04b4567870bae1526d8a3f98f2180634c2fd 100644 (file)
@@ -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,
index 4bfce62dd5d86aafa1069ddb9c18d853d2467f91..a73e8eed9028a286fc6ee83d02f1752731779980 100644 (file)
@@ -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,
index 6f8e1952db3b8a524b11eb33ed3dd465b63654b8..c009dd83e26cf774d07b99c6552f807db05b7164 100644 (file)
@@ -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,
index 166680b3eb07c14b2cd6b19c6fecb21a8fe4b7aa..7fb71ed4a8056f40e75ba1222662c01903c6e7f6 100644 (file)
@@ -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,
index 2cc45944f6c0454fae8587eaa2090ee15a9174e9..bb417356629a9bcc54d4abbe2864cc4fa52afa6a 100644 (file)
@@ -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,
index 31a3019592317ec2fcbda4cbee30546642ad223d..f939a988fa59decb9ac3658aaeba94b0402740b7 100644 (file)
@@ -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;
        }
 }
 
index 2470acbb46b7dfbfc479f585705f69eab1aa691f..28efd73cf470a64cfc2f6a330bdb4b4d995aee31 100644 (file)
@@ -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,