]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xshared: Merge invflags handling code
authorPhil Sutter <phil@nwl.cc>
Mon, 16 Nov 2020 16:20:57 +0000 (17:20 +0100)
committerPhil Sutter <phil@nwl.cc>
Mon, 17 May 2021 13:07:02 +0000 (15:07 +0200)
Join invflags handling between iptables, ip6tables, xtables and
arptables. Ebtables still has its own code which differs quite a bit.

In order to use a shared set_option() routine, iptables and ip6tables
need to provide a local 'invflags' variable which is 16bits wide.

Signed-off-by: Phil Sutter <phil@nwl.cc>
iptables/ip6tables.c
iptables/iptables.c
iptables/nft-arp.h
iptables/xshared.c
iptables/xshared.h
iptables/xtables-arp.c
iptables/xtables.c

index 60db11b7131e58b43edf637e6e57c34d9d9e9bf4..044d9a33a0266846c4df29f7885115d14ae557db 100644 (file)
@@ -96,21 +96,6 @@ struct xtables_globals ip6tables_globals = {
        .compat_rev = xtables_compatible_revision,
 };
 
-static const unsigned int inverse_for_options[NUMBER_OF_OPT] =
-{
-/* -n */ 0,
-/* -s */ IP6T_INV_SRCIP,
-/* -d */ IP6T_INV_DSTIP,
-/* -p */ XT_INV_PROTO,
-/* -j */ 0,
-/* -v */ 0,
-/* -x */ 0,
-/* -i */ IP6T_INV_VIA_IN,
-/* -o */ IP6T_INV_VIA_OUT,
-/*--line*/ 0,
-/* -c */ 0,
-};
-
 #define opts ip6tables_globals.opts
 #define prog_name ip6tables_globals.program_name
 #define prog_vers ip6tables_globals.program_version
@@ -274,28 +259,6 @@ parse_chain(const char *chainname)
                                   "Invalid chain name `%s'", chainname);
 }
 
-static void
-set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
-          int invert)
-{
-       if (*options & option)
-               xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
-                          opt2char(option));
-       *options |= option;
-
-       if (invert) {
-               unsigned int i;
-               for (i = 0; 1 << i != option; i++);
-
-               if (!inverse_for_options[i])
-                       xtables_error(PARAMETER_PROBLEM,
-                                  "cannot have ! before -%c",
-                                  opt2char(option));
-               *invflg |= inverse_for_options[i];
-       }
-}
-
-
 static void
 print_header(unsigned int format, const char *chain, struct xtc_handle *handle)
 {
@@ -1083,6 +1046,7 @@ int do_command6(int argc, char *argv[], char **table,
        struct xtables_target *t;
        unsigned long long cnt;
        bool table_set = false;
+       uint16_t invflags = 0;
        bool invert = false;
 
        /* re-set optind to 0 in case do_command6 gets called
@@ -1242,7 +1206,7 @@ int do_command6(int argc, char *argv[], char **table,
                         * Option selection
                         */
                case 'p':
-                       set_option(&cs.options, OPT_PROTOCOL, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_PROTOCOL, &invflags,
                                   invert);
 
                        /* Canonicalize into lower case */
@@ -1253,13 +1217,12 @@ int do_command6(int argc, char *argv[], char **table,
                        cs.fw6.ipv6.proto = xtables_parse_protocol(cs.protocol);
                        cs.fw6.ipv6.flags |= IP6T_F_PROTO;
 
-                       if (cs.fw6.ipv6.proto == 0
-                           && (cs.fw6.ipv6.invflags & XT_INV_PROTO))
+                       if (cs.fw6.ipv6.proto == 0 && (invflags & XT_INV_PROTO))
                                xtables_error(PARAMETER_PROBLEM,
                                           "rule would never match protocol");
 
                        if (is_exthdr(cs.fw6.ipv6.proto)
-                           && (cs.fw6.ipv6.invflags & XT_INV_PROTO) == 0)
+                           && (invflags & XT_INV_PROTO) == 0)
                                fprintf(stderr,
                                        "Warning: never matched protocol: %s. "
                                        "use extension match instead.\n",
@@ -1267,29 +1230,26 @@ int do_command6(int argc, char *argv[], char **table,
                        break;
 
                case 's':
-                       set_option(&cs.options, OPT_SOURCE, &cs.fw6.ipv6.invflags,
-                                  invert);
+                       set_option(&cs.options, OPT_SOURCE, &invflags, invert);
                        shostnetworkmask = optarg;
                        break;
 
                case 'd':
-                       set_option(&cs.options, OPT_DESTINATION, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_DESTINATION, &invflags,
                                   invert);
                        dhostnetworkmask = optarg;
                        break;
 
 #ifdef IP6T_F_GOTO
                case 'g':
-                       set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
-                                       invert);
+                       set_option(&cs.options, OPT_JUMP, &invflags, invert);
                        cs.fw6.ipv6.flags |= IP6T_F_GOTO;
                        cs.jumpto = xt_parse_target(optarg);
                        break;
 #endif
 
                case 'j':
-                       set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
-                                       invert);
+                       set_option(&cs.options, OPT_JUMP, &invflags, invert);
                        command_jump(&cs, optarg);
                        break;
 
@@ -1299,7 +1259,7 @@ int do_command6(int argc, char *argv[], char **table,
                                xtables_error(PARAMETER_PROBLEM,
                                        "Empty interface is likely to be "
                                        "undesired");
-                       set_option(&cs.options, OPT_VIANAMEIN, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_VIANAMEIN, &invflags,
                                   invert);
                        xtables_parse_interface(optarg,
                                        cs.fw6.ipv6.iniface,
@@ -1311,7 +1271,7 @@ int do_command6(int argc, char *argv[], char **table,
                                xtables_error(PARAMETER_PROBLEM,
                                        "Empty interface is likely to be "
                                        "undesired");
-                       set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_VIANAMEOUT, &invflags,
                                   invert);
                        xtables_parse_interface(optarg,
                                        cs.fw6.ipv6.outiface,
@@ -1321,7 +1281,7 @@ int do_command6(int argc, char *argv[], char **table,
                case 'v':
                        if (!verbose)
                                set_option(&cs.options, OPT_VERBOSE,
-                                          &cs.fw6.ipv6.invflags, invert);
+                                          &invflags, invert);
                        verbose++;
                        break;
 
@@ -1349,8 +1309,7 @@ int do_command6(int argc, char *argv[], char **table,
                        break;
 
                case 'n':
-                       set_option(&cs.options, OPT_NUMERIC, &cs.fw6.ipv6.invflags,
-                                  invert);
+                       set_option(&cs.options, OPT_NUMERIC, &invflags, invert);
                        break;
 
                case 't':
@@ -1366,7 +1325,7 @@ int do_command6(int argc, char *argv[], char **table,
                        break;
 
                case 'x':
-                       set_option(&cs.options, OPT_EXPANDED, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_EXPANDED, &invflags,
                                   invert);
                        break;
 
@@ -1379,7 +1338,7 @@ int do_command6(int argc, char *argv[], char **table,
                        exit(0);
 
                case '0':
-                       set_option(&cs.options, OPT_LINENUMBERS, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_LINENUMBERS, &invflags,
                                   invert);
                        break;
 
@@ -1389,7 +1348,7 @@ int do_command6(int argc, char *argv[], char **table,
 
                case 'c':
 
-                       set_option(&cs.options, OPT_COUNTERS, &cs.fw6.ipv6.invflags,
+                       set_option(&cs.options, OPT_COUNTERS, &invflags,
                                   invert);
                        pcnt = optarg;
                        bcnt = strchr(pcnt + 1, ',');
@@ -1479,6 +1438,8 @@ int do_command6(int argc, char *argv[], char **table,
                xtables_error(PARAMETER_PROBLEM,
                           "nothing appropriate following !");
 
+       cs.fw6.ipv6.invflags = invflags;
+
        if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
                if (!(cs.options & OPT_DESTINATION))
                        dhostnetworkmask = "::0/0";
index 0976017383b4d81ebc894b30196a608b6424cec0..da67dd2e1e9970ccf6508b12434d7d82be1a65ce 100644 (file)
@@ -94,22 +94,6 @@ struct xtables_globals iptables_globals = {
        .compat_rev = xtables_compatible_revision,
 };
 
-static const int inverse_for_options[NUMBER_OF_OPT] =
-{
-/* -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,
-};
-
 #define opts iptables_globals.opts
 #define prog_name iptables_globals.program_name
 #define prog_vers iptables_globals.program_version
@@ -265,27 +249,6 @@ parse_chain(const char *chainname)
                                   "Invalid chain name `%s'", chainname);
 }
 
-static void
-set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
-          int invert)
-{
-       if (*options & option)
-               xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
-                          opt2char(option));
-       *options |= option;
-
-       if (invert) {
-               unsigned int i;
-               for (i = 0; 1 << i != option; i++);
-
-               if (!inverse_for_options[i])
-                       xtables_error(PARAMETER_PROBLEM,
-                                  "cannot have ! before -%c",
-                                  opt2char(option));
-               *invflg |= inverse_for_options[i];
-       }
-}
-
 static void
 print_header(unsigned int format, const char *chain, struct xtc_handle *handle)
 {
@@ -1078,6 +1041,7 @@ int do_command4(int argc, char *argv[], char **table,
        struct xtables_target *t;
        unsigned long long cnt;
        bool table_set = false;
+       uint16_t invflags = 0;
        bool invert = false;
 
        /* re-set optind to 0 in case do_command4 gets called
@@ -1236,7 +1200,7 @@ int do_command4(int argc, char *argv[], char **table,
                         * Option selection
                         */
                case 'p':
-                       set_option(&cs.options, OPT_PROTOCOL, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_PROTOCOL, &invflags,
                                   invert);
 
                        /* Canonicalize into lower case */
@@ -1246,36 +1210,32 @@ int do_command4(int argc, char *argv[], char **table,
                        cs.protocol = optarg;
                        cs.fw.ip.proto = xtables_parse_protocol(cs.protocol);
 
-                       if (cs.fw.ip.proto == 0
-                           && (cs.fw.ip.invflags & XT_INV_PROTO))
+                       if (cs.fw.ip.proto == 0 && (invflags & XT_INV_PROTO))
                                xtables_error(PARAMETER_PROBLEM,
                                           "rule would never match protocol");
                        break;
 
                case 's':
-                       set_option(&cs.options, OPT_SOURCE, &cs.fw.ip.invflags,
-                                  invert);
+                       set_option(&cs.options, OPT_SOURCE, &invflags, invert);
                        shostnetworkmask = optarg;
                        break;
 
                case 'd':
-                       set_option(&cs.options, OPT_DESTINATION, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_DESTINATION, &invflags,
                                   invert);
                        dhostnetworkmask = optarg;
                        break;
 
 #ifdef IPT_F_GOTO
                case 'g':
-                       set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
-                                  invert);
+                       set_option(&cs.options, OPT_JUMP, &invflags, invert);
                        cs.fw.ip.flags |= IPT_F_GOTO;
                        cs.jumpto = xt_parse_target(optarg);
                        break;
 #endif
 
                case 'j':
-                       set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
-                                  invert);
+                       set_option(&cs.options, OPT_JUMP, &invflags, invert);
                        command_jump(&cs, optarg);
                        break;
 
@@ -1285,7 +1245,7 @@ int do_command4(int argc, char *argv[], char **table,
                                xtables_error(PARAMETER_PROBLEM,
                                        "Empty interface is likely to be "
                                        "undesired");
-                       set_option(&cs.options, OPT_VIANAMEIN, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_VIANAMEIN, &invflags,
                                   invert);
                        xtables_parse_interface(optarg,
                                        cs.fw.ip.iniface,
@@ -1297,7 +1257,7 @@ int do_command4(int argc, char *argv[], char **table,
                                xtables_error(PARAMETER_PROBLEM,
                                        "Empty interface is likely to be "
                                        "undesired");
-                       set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_VIANAMEOUT, &invflags,
                                   invert);
                        xtables_parse_interface(optarg,
                                        cs.fw.ip.outiface,
@@ -1305,7 +1265,7 @@ int do_command4(int argc, char *argv[], char **table,
                        break;
 
                case 'f':
-                       set_option(&cs.options, OPT_FRAGMENT, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_FRAGMENT, &invflags,
                                   invert);
                        cs.fw.ip.flags |= IPT_F_FRAG;
                        break;
@@ -1313,7 +1273,7 @@ int do_command4(int argc, char *argv[], char **table,
                case 'v':
                        if (!verbose)
                                set_option(&cs.options, OPT_VERBOSE,
-                                          &cs.fw.ip.invflags, invert);
+                                          &invflags, invert);
                        verbose++;
                        break;
 
@@ -1341,7 +1301,7 @@ int do_command4(int argc, char *argv[], char **table,
                        break;
 
                case 'n':
-                       set_option(&cs.options, OPT_NUMERIC, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_NUMERIC, &invflags,
                                   invert);
                        break;
 
@@ -1358,7 +1318,7 @@ int do_command4(int argc, char *argv[], char **table,
                        break;
 
                case 'x':
-                       set_option(&cs.options, OPT_EXPANDED, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_EXPANDED, &invflags,
                                   invert);
                        break;
 
@@ -1371,7 +1331,7 @@ int do_command4(int argc, char *argv[], char **table,
                        exit(0);
 
                case '0':
-                       set_option(&cs.options, OPT_LINENUMBERS, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_LINENUMBERS, &invflags,
                                   invert);
                        break;
 
@@ -1381,7 +1341,7 @@ int do_command4(int argc, char *argv[], char **table,
 
                case 'c':
 
-                       set_option(&cs.options, OPT_COUNTERS, &cs.fw.ip.invflags,
+                       set_option(&cs.options, OPT_COUNTERS, &invflags,
                                   invert);
                        pcnt = optarg;
                        bcnt = strchr(pcnt + 1, ',');
@@ -1467,6 +1427,8 @@ int do_command4(int argc, char *argv[], char **table,
                xtables_error(PARAMETER_PROBLEM,
                           "nothing appropriate following !");
 
+       cs.fw.ip.invflags = invflags;
+
        if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
                if (!(cs.options & OPT_DESTINATION))
                        dhostnetworkmask = "0.0.0.0/0";
index 0d93a31f563b199afcb0cf062bafbee83d90ee66..3411fc3d7c7b336732f5a842fb1279d07c465f92 100644 (file)
@@ -4,11 +4,4 @@
 extern char *arp_opcodes[];
 #define NUMOPCODES 9
 
-/* define invflags which won't collide with IPT ones */
-#define IPT_INV_SRCDEVADDR     0x0080
-#define IPT_INV_TGTDEVADDR     0x0100
-#define IPT_INV_ARPHLN         0x0200
-#define IPT_INV_ARPOP          0x0400
-#define IPT_INV_ARPHRD         0x0800
-
 #endif
index afd7a9d6aad2661804ed43d279b7ba521a166e82..a3f473ea607c864989224baa80339d34b7bacf9d 100644 (file)
@@ -853,3 +853,46 @@ char opt2char(int option)
 
        return *ptr;
 }
+
+static const int inverse_for_options[NUMBER_OF_OPT] =
+{
+/* -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,
+};
+
+void
+set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
+          bool invert)
+{
+       if (*options & option)
+               xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
+                          opt2char(option));
+       *options |= option;
+
+       if (invert) {
+               unsigned int i;
+               for (i = 0; 1 << i != option; i++);
+
+               if (!inverse_for_options[i])
+                       xtables_error(PARAMETER_PROBLEM,
+                                  "cannot have ! before -%c",
+                                  opt2char(option));
+               *invflg |= inverse_for_options[i];
+       }
+}
index af2a5adbe169ce312933bf41f67724ce23246338..dace221bbd962f39585a9310ec809ebfb1495e97 100644 (file)
@@ -68,6 +68,17 @@ struct xtables_globals;
 struct xtables_rule_match;
 struct xtables_target;
 
+/* define invflags which won't collide with IPT ones */
+#define IPT_INV_SRCDEVADDR     0x0080
+#define IPT_INV_TGTDEVADDR     0x0100
+#define IPT_INV_ARPHLN         0x0200
+#define IPT_INV_ARPOP          0x0400
+#define IPT_INV_ARPHRD         0x0800
+
+void
+set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
+          bool invert);
+
 /**
  * xtables_afinfo - protocol family dependent information
  * @kmod:              kernel module basename (e.g. "ip_tables")
index 4a89ae95070511b476ce3cc2671494857d768d4f..4a351f0cab4a7ff8be94fe0216a52ede9f2e9c1d 100644 (file)
@@ -105,29 +105,6 @@ struct xtables_globals arptables_globals = {
        .compat_rev             = nft_compatible_revision,
 };
 
-/* index relates to bit of each OPT_* value */
-static int inverse_for_options[] =
-{
-/* -n */ 0,
-/* -s */ IPT_INV_SRCIP,
-/* -d */ IPT_INV_DSTIP,
-/* -p */ 0,
-/* -j */ 0,
-/* -v */ 0,
-/* -x */ 0,
-/* -i */ IPT_INV_VIA_IN,
-/* -o */ IPT_INV_VIA_OUT,
-/*--line*/ 0,
-/* -c */ 0,
-/* -f */ 0,
-/* 2 */ IPT_INV_SRCDEVADDR,
-/* 3 */ IPT_INV_TGTDEVADDR,
-/* -l */ IPT_INV_ARPHLN,
-/* 4 */ IPT_INV_ARPOP,
-/* 5 */ IPT_INV_ARPHRD,
-/* 6 */ IPT_INV_PROTO,
-};
-
 /***********************************************/
 /* ARPTABLES SPECIFIC NEW FUNCTIONS ADDED HERE */
 /***********************************************/
@@ -298,27 +275,6 @@ check_inverse(const char option[], int *invert, int *optidx, int argc)
        return false;
 }
 
-static void
-set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
-          int invert)
-{
-       if (*options & option)
-               xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
-                             opt2char(option));
-       *options |= option;
-
-       if (invert) {
-               unsigned int i;
-               for (i = 0; 1 << i != option; i++);
-
-               if (!inverse_for_options[i])
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "cannot have ! before -%c",
-                                     opt2char(option));
-               *invflg |= inverse_for_options[i];
-       }
-}
-
 static int
 list_entries(struct nft_handle *h, const char *chain, const char *table,
             int rulenum, int verbose, int numeric, int expanded,
index 73531ca88b5171ef1841a2742fb02b73fa5c0d56..daa9b137b5fa4846a90f91591bbdbcd8a8f2ba91 100644 (file)
@@ -94,22 +94,6 @@ struct xtables_globals xtables_globals = {
        .compat_rev = nft_compatible_revision,
 };
 
-static const int inverse_for_options[NUMBER_OF_OPT] =
-{
-/* -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,
-};
-
 #define opts xt_params->opts
 #define prog_name xt_params->program_name
 #define prog_vers xt_params->program_version
@@ -238,27 +222,6 @@ xtables_exit_error(enum xtables_exittype status, const char *msg, ...)
 
 /* Christophe Burki wants `-p 6' to imply `-m tcp'.  */
 
-static void
-set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
-          bool invert)
-{
-       if (*options & option)
-               xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
-                          opt2char(option));
-       *options |= option;
-
-       if (invert) {
-               unsigned int i;
-               for (i = 0; 1 << i != option; i++);
-
-               if (!inverse_for_options[i])
-                       xtables_error(PARAMETER_PROBLEM,
-                                  "cannot have ! before -%c",
-                                  opt2char(option));
-               *invflg |= inverse_for_options[i];
-       }
-}
-
 static int
 add_entry(const char *chain,
          const char *table,