]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xshared: Do not populate interface masks per default
authorPhil Sutter <phil@nwl.cc>
Sat, 18 Nov 2023 03:28:25 +0000 (04:28 +0100)
committerPhil Sutter <phil@nwl.cc>
Wed, 29 Nov 2023 01:33:04 +0000 (02:33 +0100)
These are needed by legacy variants only, so introduce a simplified
xtables_parse_interface() replacement which does not deal with them and
a small function which sets the mask based on given interface name for
use by legacy tools.

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

index 21cd8018926414cb3975d3d0c945403661414699..53eeb6e90bbb74ea93d7d334cac76eaefe4a17c8 100644 (file)
@@ -713,6 +713,9 @@ int do_command6(int argc, char *argv[], char **table,
        smasks          = args.s.mask.v6;
        dmasks          = args.d.mask.v6;
 
+       iface_to_mask(cs.fw6.ipv6.iniface, cs.fw6.ipv6.iniface_mask);
+       iface_to_mask(cs.fw6.ipv6.outiface, cs.fw6.ipv6.outiface_mask);
+
        /* Attempt to acquire the xtables lock */
        if (!restore)
                xtables_lock_or_exit(wait);
index ce65c30ad0b15d9cba12951f53dd5b7c28619747..69dd2890605288e66d75d116173f9b68766d4220 100644 (file)
@@ -706,6 +706,9 @@ int do_command4(int argc, char *argv[], char **table,
        smasks          = args.s.mask.v4;
        dmasks          = args.d.mask.v4;
 
+       iface_to_mask(cs.fw.ip.iniface, cs.fw.ip.iniface_mask);
+       iface_to_mask(cs.fw.ip.outiface, cs.fw.ip.outiface_mask);
+
        /* Attempt to acquire the xtables lock */
        if (!restore)
                xtables_lock_or_exit(wait);
index 839a5bb68776c5f2c2253a829794abcb01071e37..dca744773d773bb798aa5a6defd8332ee2b07ec6 100644 (file)
@@ -1322,6 +1322,44 @@ void xtables_clear_iptables_command_state(struct iptables_command_state *cs)
        }
 }
 
+void iface_to_mask(const char *iface, unsigned char *mask)
+{
+       unsigned int len = strlen(iface);
+
+       memset(mask, 0, IFNAMSIZ);
+
+       if (!len) {
+               return;
+       } else if (iface[len - 1] == '+') {
+               memset(mask, 0xff, len - 1);
+               /* Don't remove `+' here! -HW */
+       } else {
+               /* Include nul-terminator in match */
+               memset(mask, 0xff, len + 1);
+       }
+}
+
+static void parse_interface(const char *arg, char *iface)
+{
+       unsigned int len = strlen(arg);
+
+       memset(iface, 0, IFNAMSIZ);
+
+       if (!len)
+               return;
+       if (len >= IFNAMSIZ)
+               xtables_error(PARAMETER_PROBLEM,
+                             "interface name `%s' must be shorter than %d characters",
+                             arg, IFNAMSIZ);
+
+       if (strchr(arg, '/') || strchr(arg, ' '))
+               fprintf(stderr,
+                       "Warning: weird character in interface `%s' ('/' and ' ' are not allowed by the kernel).\n",
+                       arg);
+
+       strcpy(iface, arg);
+}
+
 void do_parse(int argc, char *argv[],
              struct xt_cmd_parse *p, struct iptables_command_state *cs,
              struct xtables_args *args)
@@ -1600,9 +1638,7 @@ void do_parse(int argc, char *argv[],
                        check_inverse(args, optarg, &invert, argc, argv);
                        set_option(p->ops, &cs->options, OPT_VIANAMEIN,
                                   &args->invflags, invert);
-                       xtables_parse_interface(optarg,
-                                               args->iniface,
-                                               args->iniface_mask);
+                       parse_interface(optarg, args->iniface);
                        break;
 
                case 'o':
@@ -1610,9 +1646,7 @@ void do_parse(int argc, char *argv[],
                        check_inverse(args, optarg, &invert, argc, argv);
                        set_option(p->ops, &cs->options, OPT_VIANAMEOUT,
                                   &args->invflags, invert);
-                       xtables_parse_interface(optarg,
-                                               args->outiface,
-                                               args->outiface_mask);
+                       parse_interface(optarg, args->outiface);
                        break;
 
                case 'f':
@@ -1873,12 +1907,7 @@ void ipv4_post_parse(int command, struct iptables_command_state *cs,
        cs->fw.ip.invflags = args->invflags;
 
        memcpy(cs->fw.ip.iniface, args->iniface, IFNAMSIZ);
-       memcpy(cs->fw.ip.iniface_mask,
-              args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
-
        memcpy(cs->fw.ip.outiface, args->outiface, IFNAMSIZ);
-       memcpy(cs->fw.ip.outiface_mask,
-              args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
 
        if (args->goto_set)
                cs->fw.ip.flags |= IPT_F_GOTO;
index 952fa8ab95fec481ade32e273ee16fb6d0377861..d2ce72e90824a1cfd20487aa4d08b4ba71543f7a 100644 (file)
@@ -311,4 +311,6 @@ unsigned char *make_delete_mask(const struct xtables_rule_match *matches,
                                const struct xtables_target *target,
                                size_t entry_size);
 
+void iface_to_mask(const char *ifname, unsigned char *mask);
+
 #endif /* IPTABLES_XSHARED_H */