]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
netfilter: xtables: avoid NFPROTO_UNSPEC where needed
authorFlorian Westphal <fw@strlen.de>
Mon, 7 Oct 2024 09:28:16 +0000 (11:28 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 9 Oct 2024 21:20:46 +0000 (23:20 +0200)
syzbot managed to call xt_cluster match via ebtables:

 WARNING: CPU: 0 PID: 11 at net/netfilter/xt_cluster.c:72 xt_cluster_mt+0x196/0x780
 [..]
 ebt_do_table+0x174b/0x2a40

Module registers to NFPROTO_UNSPEC, but it assumes ipv4/ipv6 packet
processing.  As this is only useful to restrict locally terminating
TCP/UDP traffic, register this for ipv4 and ipv6 family only.

Pablo points out that this is a general issue, direct users of the
set/getsockopt interface can call into targets/matches that were only
intended for use with ip(6)tables.

Check all UNSPEC matches and targets for similar issues:

- matches and targets are fine except if they assume skb_network_header()
  is valid -- this is only true when called from inet layer: ip(6) stack
  pulls the ip/ipv6 header into linear data area.
- targets that return XT_CONTINUE or other xtables verdicts must be
  restricted too, they are incompatbile with the ebtables traverser, e.g.
  EBT_CONTINUE is a completely different value than XT_CONTINUE.

Most matches/targets are changed to register for NFPROTO_IPV4/IPV6, as
they are provided for use by ip(6)tables.

The MARK target is also used by arptables, so register for NFPROTO_ARP too.

While at it, bail out if connbytes fails to enable the corresponding
conntrack family.

This change passes the selftests in iptables.git.

Reported-by: syzbot+256c348558aa5cf611a9@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netfilter-devel/66fec2e2.050a0220.9ec68.0047.GAE@google.com/
Fixes: 0269ea493734 ("netfilter: xtables: add cluster match")
Signed-off-by: Florian Westphal <fw@strlen.de>
Co-developed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
16 files changed:
net/netfilter/xt_CHECKSUM.c
net/netfilter/xt_CLASSIFY.c
net/netfilter/xt_CONNSECMARK.c
net/netfilter/xt_CT.c
net/netfilter/xt_IDLETIMER.c
net/netfilter/xt_LED.c
net/netfilter/xt_NFLOG.c
net/netfilter/xt_RATEEST.c
net/netfilter/xt_SECMARK.c
net/netfilter/xt_TRACE.c
net/netfilter/xt_addrtype.c
net/netfilter/xt_cluster.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_connmark.c
net/netfilter/xt_mark.c

index c8a639f561684107cdab4332b6c3aff30e81fdb1..9d99f5a3d1764bd84e3e04d2aca739840b0b51da 100644 (file)
@@ -63,24 +63,37 @@ static int checksum_tg_check(const struct xt_tgchk_param *par)
        return 0;
 }
 
-static struct xt_target checksum_tg_reg __read_mostly = {
-       .name           = "CHECKSUM",
-       .family         = NFPROTO_UNSPEC,
-       .target         = checksum_tg,
-       .targetsize     = sizeof(struct xt_CHECKSUM_info),
-       .table          = "mangle",
-       .checkentry     = checksum_tg_check,
-       .me             = THIS_MODULE,
+static struct xt_target checksum_tg_reg[] __read_mostly = {
+       {
+               .name           = "CHECKSUM",
+               .family         = NFPROTO_IPV4,
+               .target         = checksum_tg,
+               .targetsize     = sizeof(struct xt_CHECKSUM_info),
+               .table          = "mangle",
+               .checkentry     = checksum_tg_check,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "CHECKSUM",
+               .family         = NFPROTO_IPV6,
+               .target         = checksum_tg,
+               .targetsize     = sizeof(struct xt_CHECKSUM_info),
+               .table          = "mangle",
+               .checkentry     = checksum_tg_check,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init checksum_tg_init(void)
 {
-       return xt_register_target(&checksum_tg_reg);
+       return xt_register_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
 }
 
 static void __exit checksum_tg_exit(void)
 {
-       xt_unregister_target(&checksum_tg_reg);
+       xt_unregister_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
 }
 
 module_init(checksum_tg_init);
index 0accac98dea784d48d764794b872669019721dfb..0ae8d8a1216e1921c6e8bfa91cd6a8246c48f337 100644 (file)
@@ -38,9 +38,9 @@ static struct xt_target classify_tg_reg[] __read_mostly = {
        {
                .name       = "CLASSIFY",
                .revision   = 0,
-               .family     = NFPROTO_UNSPEC,
+               .family     = NFPROTO_IPV4,
                .hooks      = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
-                             (1 << NF_INET_POST_ROUTING),
+                             (1 << NF_INET_POST_ROUTING),
                .target     = classify_tg,
                .targetsize = sizeof(struct xt_classify_target_info),
                .me         = THIS_MODULE,
@@ -54,6 +54,18 @@ static struct xt_target classify_tg_reg[] __read_mostly = {
                .targetsize = sizeof(struct xt_classify_target_info),
                .me         = THIS_MODULE,
        },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "CLASSIFY",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .hooks      = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
+                             (1 << NF_INET_POST_ROUTING),
+               .target     = classify_tg,
+               .targetsize = sizeof(struct xt_classify_target_info),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init classify_tg_init(void)
index 76acecf3e757a0fe4687f06ea2781661defac396..1494b3ee30e11e46b7abc5761c44a787c9dfd7bc 100644 (file)
@@ -114,25 +114,39 @@ static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
        nf_ct_netns_put(par->net, par->family);
 }
 
-static struct xt_target connsecmark_tg_reg __read_mostly = {
-       .name       = "CONNSECMARK",
-       .revision   = 0,
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = connsecmark_tg_check,
-       .destroy    = connsecmark_tg_destroy,
-       .target     = connsecmark_tg,
-       .targetsize = sizeof(struct xt_connsecmark_target_info),
-       .me         = THIS_MODULE,
+static struct xt_target connsecmark_tg_reg[] __read_mostly = {
+       {
+               .name       = "CONNSECMARK",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .checkentry = connsecmark_tg_check,
+               .destroy    = connsecmark_tg_destroy,
+               .target     = connsecmark_tg,
+               .targetsize = sizeof(struct xt_connsecmark_target_info),
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "CONNSECMARK",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .checkentry = connsecmark_tg_check,
+               .destroy    = connsecmark_tg_destroy,
+               .target     = connsecmark_tg,
+               .targetsize = sizeof(struct xt_connsecmark_target_info),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init connsecmark_tg_init(void)
 {
-       return xt_register_target(&connsecmark_tg_reg);
+       return xt_register_targets(connsecmark_tg_reg, ARRAY_SIZE(connsecmark_tg_reg));
 }
 
 static void __exit connsecmark_tg_exit(void)
 {
-       xt_unregister_target(&connsecmark_tg_reg);
+       xt_unregister_targets(connsecmark_tg_reg, ARRAY_SIZE(connsecmark_tg_reg));
 }
 
 module_init(connsecmark_tg_init);
index 2be2f7a7b60f4ec1d5bd5dfa4fc3a656825321ef..3ba94c34297cf5e24bfd7bcbce6b6977bd7204c2 100644 (file)
@@ -313,10 +313,30 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
        xt_ct_tg_destroy(par, par->targinfo);
 }
 
+static unsigned int
+notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
+{
+       /* Previously seen (loopback)? Ignore. */
+       if (skb->_nfct != 0)
+               return XT_CONTINUE;
+
+       nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
+
+       return XT_CONTINUE;
+}
+
 static struct xt_target xt_ct_tg_reg[] __read_mostly = {
+       {
+               .name           = "NOTRACK",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .target         = notrack_tg,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
        {
                .name           = "CT",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .targetsize     = sizeof(struct xt_ct_target_info),
                .usersize       = offsetof(struct xt_ct_target_info, ct),
                .checkentry     = xt_ct_tg_check_v0,
@@ -327,7 +347,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
        },
        {
                .name           = "CT",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .revision       = 1,
                .targetsize     = sizeof(struct xt_ct_target_info_v1),
                .usersize       = offsetof(struct xt_ct_target_info, ct),
@@ -339,7 +359,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
        },
        {
                .name           = "CT",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .revision       = 2,
                .targetsize     = sizeof(struct xt_ct_target_info_v1),
                .usersize       = offsetof(struct xt_ct_target_info, ct),
@@ -349,49 +369,61 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
                .table          = "raw",
                .me             = THIS_MODULE,
        },
-};
-
-static unsigned int
-notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
-{
-       /* Previously seen (loopback)? Ignore. */
-       if (skb->_nfct != 0)
-               return XT_CONTINUE;
-
-       nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
-
-       return XT_CONTINUE;
-}
-
-static struct xt_target notrack_tg_reg __read_mostly = {
-       .name           = "NOTRACK",
-       .revision       = 0,
-       .family         = NFPROTO_UNSPEC,
-       .target         = notrack_tg,
-       .table          = "raw",
-       .me             = THIS_MODULE,
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "NOTRACK",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .target         = notrack_tg,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CT",
+               .family         = NFPROTO_IPV6,
+               .targetsize     = sizeof(struct xt_ct_target_info),
+               .usersize       = offsetof(struct xt_ct_target_info, ct),
+               .checkentry     = xt_ct_tg_check_v0,
+               .destroy        = xt_ct_tg_destroy_v0,
+               .target         = xt_ct_target_v0,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CT",
+               .family         = NFPROTO_IPV6,
+               .revision       = 1,
+               .targetsize     = sizeof(struct xt_ct_target_info_v1),
+               .usersize       = offsetof(struct xt_ct_target_info, ct),
+               .checkentry     = xt_ct_tg_check_v1,
+               .destroy        = xt_ct_tg_destroy_v1,
+               .target         = xt_ct_target_v1,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CT",
+               .family         = NFPROTO_IPV6,
+               .revision       = 2,
+               .targetsize     = sizeof(struct xt_ct_target_info_v1),
+               .usersize       = offsetof(struct xt_ct_target_info, ct),
+               .checkentry     = xt_ct_tg_check_v2,
+               .destroy        = xt_ct_tg_destroy_v1,
+               .target         = xt_ct_target_v1,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init xt_ct_tg_init(void)
 {
-       int ret;
-
-       ret = xt_register_target(&notrack_tg_reg);
-       if (ret < 0)
-               return ret;
-
-       ret = xt_register_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
-       if (ret < 0) {
-               xt_unregister_target(&notrack_tg_reg);
-               return ret;
-       }
-       return 0;
+       return xt_register_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
 }
 
 static void __exit xt_ct_tg_exit(void)
 {
        xt_unregister_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
-       xt_unregister_target(&notrack_tg_reg);
 }
 
 module_init(xt_ct_tg_init);
index db720efa811d58cb4dffa14fe0dccfa8dcb152c8..f8b25b6f5da7367d93b44a2fce4e9b32e1eeb1b5 100644 (file)
@@ -458,28 +458,49 @@ static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
 
 static struct xt_target idletimer_tg[] __read_mostly = {
        {
-       .name           = "IDLETIMER",
-       .family         = NFPROTO_UNSPEC,
-       .target         = idletimer_tg_target,
-       .targetsize     = sizeof(struct idletimer_tg_info),
-       .usersize       = offsetof(struct idletimer_tg_info, timer),
-       .checkentry     = idletimer_tg_checkentry,
-       .destroy        = idletimer_tg_destroy,
-       .me             = THIS_MODULE,
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV4,
+               .target         = idletimer_tg_target,
+               .targetsize     = sizeof(struct idletimer_tg_info),
+               .usersize       = offsetof(struct idletimer_tg_info, timer),
+               .checkentry     = idletimer_tg_checkentry,
+               .destroy        = idletimer_tg_destroy,
+               .me             = THIS_MODULE,
        },
        {
-       .name           = "IDLETIMER",
-       .family         = NFPROTO_UNSPEC,
-       .revision       = 1,
-       .target         = idletimer_tg_target_v1,
-       .targetsize     = sizeof(struct idletimer_tg_info_v1),
-       .usersize       = offsetof(struct idletimer_tg_info_v1, timer),
-       .checkentry     = idletimer_tg_checkentry_v1,
-       .destroy        = idletimer_tg_destroy_v1,
-       .me             = THIS_MODULE,
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV4,
+               .revision       = 1,
+               .target         = idletimer_tg_target_v1,
+               .targetsize     = sizeof(struct idletimer_tg_info_v1),
+               .usersize       = offsetof(struct idletimer_tg_info_v1, timer),
+               .checkentry     = idletimer_tg_checkentry_v1,
+               .destroy        = idletimer_tg_destroy_v1,
+               .me             = THIS_MODULE,
        },
-
-
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV6,
+               .target         = idletimer_tg_target,
+               .targetsize     = sizeof(struct idletimer_tg_info),
+               .usersize       = offsetof(struct idletimer_tg_info, timer),
+               .checkentry     = idletimer_tg_checkentry,
+               .destroy        = idletimer_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV6,
+               .revision       = 1,
+               .target         = idletimer_tg_target_v1,
+               .targetsize     = sizeof(struct idletimer_tg_info_v1),
+               .usersize       = offsetof(struct idletimer_tg_info_v1, timer),
+               .checkentry     = idletimer_tg_checkentry_v1,
+               .destroy        = idletimer_tg_destroy_v1,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static struct class *idletimer_tg_class;
index 36c9720ad8d6d4360960d5de495a626d0f73dbfe..f7b0286d106ac1368baceb7809348213c266f34f 100644 (file)
@@ -175,26 +175,41 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par)
        kfree(ledinternal);
 }
 
-static struct xt_target led_tg_reg __read_mostly = {
-       .name           = "LED",
-       .revision       = 0,
-       .family         = NFPROTO_UNSPEC,
-       .target         = led_tg,
-       .targetsize     = sizeof(struct xt_led_info),
-       .usersize       = offsetof(struct xt_led_info, internal_data),
-       .checkentry     = led_tg_check,
-       .destroy        = led_tg_destroy,
-       .me             = THIS_MODULE,
+static struct xt_target led_tg_reg[] __read_mostly = {
+       {
+               .name           = "LED",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .target         = led_tg,
+               .targetsize     = sizeof(struct xt_led_info),
+               .usersize       = offsetof(struct xt_led_info, internal_data),
+               .checkentry     = led_tg_check,
+               .destroy        = led_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "LED",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .target         = led_tg,
+               .targetsize     = sizeof(struct xt_led_info),
+               .usersize       = offsetof(struct xt_led_info, internal_data),
+               .checkentry     = led_tg_check,
+               .destroy        = led_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init led_tg_init(void)
 {
-       return xt_register_target(&led_tg_reg);
+       return xt_register_targets(led_tg_reg, ARRAY_SIZE(led_tg_reg));
 }
 
 static void __exit led_tg_exit(void)
 {
-       xt_unregister_target(&led_tg_reg);
+       xt_unregister_targets(led_tg_reg, ARRAY_SIZE(led_tg_reg));
 }
 
 module_init(led_tg_init);
index e660c3710a10968909b98b5236536996cbb8462b..d80abd6ccaf8f71fa70605fef7edada827a19ceb 100644 (file)
@@ -64,25 +64,39 @@ static void nflog_tg_destroy(const struct xt_tgdtor_param *par)
        nf_logger_put(par->family, NF_LOG_TYPE_ULOG);
 }
 
-static struct xt_target nflog_tg_reg __read_mostly = {
-       .name       = "NFLOG",
-       .revision   = 0,
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = nflog_tg_check,
-       .destroy    = nflog_tg_destroy,
-       .target     = nflog_tg,
-       .targetsize = sizeof(struct xt_nflog_info),
-       .me         = THIS_MODULE,
+static struct xt_target nflog_tg_reg[] __read_mostly = {
+       {
+               .name       = "NFLOG",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .checkentry = nflog_tg_check,
+               .destroy    = nflog_tg_destroy,
+               .target     = nflog_tg,
+               .targetsize = sizeof(struct xt_nflog_info),
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "NFLOG",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .checkentry = nflog_tg_check,
+               .destroy    = nflog_tg_destroy,
+               .target     = nflog_tg,
+               .targetsize = sizeof(struct xt_nflog_info),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init nflog_tg_init(void)
 {
-       return xt_register_target(&nflog_tg_reg);
+       return xt_register_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg));
 }
 
 static void __exit nflog_tg_exit(void)
 {
-       xt_unregister_target(&nflog_tg_reg);
+       xt_unregister_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg));
 }
 
 module_init(nflog_tg_init);
index 80f6624e23554b30090b4a86b763ad279f5e44ac..4f49cfc27831204b3ce05b6fa1fd724b9ce86e2f 100644 (file)
@@ -179,16 +179,31 @@ static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par)
        xt_rateest_put(par->net, info->est);
 }
 
-static struct xt_target xt_rateest_tg_reg __read_mostly = {
-       .name       = "RATEEST",
-       .revision   = 0,
-       .family     = NFPROTO_UNSPEC,
-       .target     = xt_rateest_tg,
-       .checkentry = xt_rateest_tg_checkentry,
-       .destroy    = xt_rateest_tg_destroy,
-       .targetsize = sizeof(struct xt_rateest_target_info),
-       .usersize   = offsetof(struct xt_rateest_target_info, est),
-       .me         = THIS_MODULE,
+static struct xt_target xt_rateest_tg_reg[] __read_mostly = {
+       {
+               .name       = "RATEEST",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .target     = xt_rateest_tg,
+               .checkentry = xt_rateest_tg_checkentry,
+               .destroy    = xt_rateest_tg_destroy,
+               .targetsize = sizeof(struct xt_rateest_target_info),
+               .usersize   = offsetof(struct xt_rateest_target_info, est),
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "RATEEST",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .target     = xt_rateest_tg,
+               .checkentry = xt_rateest_tg_checkentry,
+               .destroy    = xt_rateest_tg_destroy,
+               .targetsize = sizeof(struct xt_rateest_target_info),
+               .usersize   = offsetof(struct xt_rateest_target_info, est),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static __net_init int xt_rateest_net_init(struct net *net)
@@ -214,12 +229,12 @@ static int __init xt_rateest_tg_init(void)
 
        if (err)
                return err;
-       return xt_register_target(&xt_rateest_tg_reg);
+       return xt_register_targets(xt_rateest_tg_reg, ARRAY_SIZE(xt_rateest_tg_reg));
 }
 
 static void __exit xt_rateest_tg_fini(void)
 {
-       xt_unregister_target(&xt_rateest_tg_reg);
+       xt_unregister_targets(xt_rateest_tg_reg, ARRAY_SIZE(xt_rateest_tg_reg));
        unregister_pernet_subsys(&xt_rateest_net_ops);
 }
 
index 498a0bf6f0444a80dd88f05299bf0a7b505dd587..5bc5ea505eb9e02e95d1175e8f2094f2cd5ea3b8 100644 (file)
@@ -157,7 +157,7 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
        {
                .name           = "SECMARK",
                .revision       = 0,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = secmark_tg_check_v0,
                .destroy        = secmark_tg_destroy,
                .target         = secmark_tg_v0,
@@ -167,7 +167,7 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
        {
                .name           = "SECMARK",
                .revision       = 1,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = secmark_tg_check_v1,
                .destroy        = secmark_tg_destroy,
                .target         = secmark_tg_v1,
@@ -175,6 +175,29 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
                .usersize       = offsetof(struct xt_secmark_target_info_v1, secid),
                .me             = THIS_MODULE,
        },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "SECMARK",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = secmark_tg_check_v0,
+               .destroy        = secmark_tg_destroy,
+               .target         = secmark_tg_v0,
+               .targetsize     = sizeof(struct xt_secmark_target_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "SECMARK",
+               .revision       = 1,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = secmark_tg_check_v1,
+               .destroy        = secmark_tg_destroy,
+               .target         = secmark_tg_v1,
+               .targetsize     = sizeof(struct xt_secmark_target_info_v1),
+               .usersize       = offsetof(struct xt_secmark_target_info_v1, secid),
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init secmark_tg_init(void)
index 5582dce98cae7d0796988d30e4b4e8e6832d6452..f3fa4f11348cd8ad796ce94f012cd48aa7a9020f 100644 (file)
@@ -29,25 +29,38 @@ trace_tg(struct sk_buff *skb, const struct xt_action_param *par)
        return XT_CONTINUE;
 }
 
-static struct xt_target trace_tg_reg __read_mostly = {
-       .name           = "TRACE",
-       .revision       = 0,
-       .family         = NFPROTO_UNSPEC,
-       .table          = "raw",
-       .target         = trace_tg,
-       .checkentry     = trace_tg_check,
-       .destroy        = trace_tg_destroy,
-       .me             = THIS_MODULE,
+static struct xt_target trace_tg_reg[] __read_mostly = {
+       {
+               .name           = "TRACE",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .table          = "raw",
+               .target         = trace_tg,
+               .checkentry     = trace_tg_check,
+               .destroy        = trace_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "TRACE",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .table          = "raw",
+               .target         = trace_tg,
+               .checkentry     = trace_tg_check,
+               .destroy        = trace_tg_destroy,
+       },
+#endif
 };
 
 static int __init trace_tg_init(void)
 {
-       return xt_register_target(&trace_tg_reg);
+       return xt_register_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
 }
 
 static void __exit trace_tg_exit(void)
 {
-       xt_unregister_target(&trace_tg_reg);
+       xt_unregister_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
 }
 
 module_init(trace_tg_init);
index e9b2181e8c425f24ab580ad6ff6856b8e7fd98f3..a7708894310716f154d6c66da5ce30a909d509eb 100644 (file)
@@ -208,13 +208,24 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = {
        },
        {
                .name           = "addrtype",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .revision       = 1,
                .match          = addrtype_mt_v1,
                .checkentry     = addrtype_mt_checkentry_v1,
                .matchsize      = sizeof(struct xt_addrtype_info_v1),
                .me             = THIS_MODULE
-       }
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "addrtype",
+               .family         = NFPROTO_IPV6,
+               .revision       = 1,
+               .match          = addrtype_mt_v1,
+               .checkentry     = addrtype_mt_checkentry_v1,
+               .matchsize      = sizeof(struct xt_addrtype_info_v1),
+               .me             = THIS_MODULE
+       },
+#endif
 };
 
 static int __init addrtype_mt_init(void)
index a047a545371e18cbfa17a182ec3457a4ade2fd75..908fd5f2c3c84814a35390cd96e53a43e3759468 100644 (file)
@@ -146,24 +146,37 @@ static void xt_cluster_mt_destroy(const struct xt_mtdtor_param *par)
        nf_ct_netns_put(par->net, par->family);
 }
 
-static struct xt_match xt_cluster_match __read_mostly = {
-       .name           = "cluster",
-       .family         = NFPROTO_UNSPEC,
-       .match          = xt_cluster_mt,
-       .checkentry     = xt_cluster_mt_checkentry,
-       .matchsize      = sizeof(struct xt_cluster_match_info),
-       .destroy        = xt_cluster_mt_destroy,
-       .me             = THIS_MODULE,
+static struct xt_match xt_cluster_match[] __read_mostly = {
+       {
+               .name           = "cluster",
+               .family         = NFPROTO_IPV4,
+               .match          = xt_cluster_mt,
+               .checkentry     = xt_cluster_mt_checkentry,
+               .matchsize      = sizeof(struct xt_cluster_match_info),
+               .destroy        = xt_cluster_mt_destroy,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "cluster",
+               .family         = NFPROTO_IPV6,
+               .match          = xt_cluster_mt,
+               .checkentry     = xt_cluster_mt_checkentry,
+               .matchsize      = sizeof(struct xt_cluster_match_info),
+               .destroy        = xt_cluster_mt_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init xt_cluster_mt_init(void)
 {
-       return xt_register_match(&xt_cluster_match);
+       return xt_register_matches(xt_cluster_match, ARRAY_SIZE(xt_cluster_match));
 }
 
 static void __exit xt_cluster_mt_fini(void)
 {
-       xt_unregister_match(&xt_cluster_match);
+       xt_unregister_matches(xt_cluster_match, ARRAY_SIZE(xt_cluster_match));
 }
 
 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
index 93cb018c3055f8fb660a2558fd86cac07285d47b..2aabdcea8707236244984357c0d079acc5ffcb39 100644 (file)
@@ -111,9 +111,11 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par)
                return -EINVAL;
 
        ret = nf_ct_netns_get(par->net, par->family);
-       if (ret < 0)
+       if (ret < 0) {
                pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
                                    par->family);
+               return ret;
+       }
 
        /*
         * This filter cannot function correctly unless connection tracking
index 0e762277bcf8f95ec0c9e35ec645f6e7af048609..0189f8b6b0bd15e7b0714de41359964b6e6990aa 100644 (file)
@@ -117,26 +117,41 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
        nf_ct_netns_put(par->net, par->family);
 }
 
-static struct xt_match connlimit_mt_reg __read_mostly = {
-       .name       = "connlimit",
-       .revision   = 1,
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = connlimit_mt_check,
-       .match      = connlimit_mt,
-       .matchsize  = sizeof(struct xt_connlimit_info),
-       .usersize   = offsetof(struct xt_connlimit_info, data),
-       .destroy    = connlimit_mt_destroy,
-       .me         = THIS_MODULE,
+static struct xt_match connlimit_mt_reg[] __read_mostly = {
+       {
+               .name       = "connlimit",
+               .revision   = 1,
+               .family     = NFPROTO_IPV4,
+               .checkentry = connlimit_mt_check,
+               .match      = connlimit_mt,
+               .matchsize  = sizeof(struct xt_connlimit_info),
+               .usersize   = offsetof(struct xt_connlimit_info, data),
+               .destroy    = connlimit_mt_destroy,
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "connlimit",
+               .revision   = 1,
+               .family     = NFPROTO_IPV6,
+               .checkentry = connlimit_mt_check,
+               .match      = connlimit_mt,
+               .matchsize  = sizeof(struct xt_connlimit_info),
+               .usersize   = offsetof(struct xt_connlimit_info, data),
+               .destroy    = connlimit_mt_destroy,
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init connlimit_mt_init(void)
 {
-       return xt_register_match(&connlimit_mt_reg);
+       return xt_register_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
 }
 
 static void __exit connlimit_mt_exit(void)
 {
-       xt_unregister_match(&connlimit_mt_reg);
+       xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
 }
 
 module_init(connlimit_mt_init);
index ad3c033db64e70dd642a63e9b48914fc0ac12cb9..4277084de2e70c995f49cadd411cab70473b3ad9 100644 (file)
@@ -151,7 +151,7 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
        {
                .name           = "CONNMARK",
                .revision       = 1,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = connmark_tg_check,
                .target         = connmark_tg,
                .targetsize     = sizeof(struct xt_connmark_tginfo1),
@@ -161,13 +161,35 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
        {
                .name           = "CONNMARK",
                .revision       = 2,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = connmark_tg_check,
                .target         = connmark_tg_v2,
                .targetsize     = sizeof(struct xt_connmark_tginfo2),
                .destroy        = connmark_tg_destroy,
                .me             = THIS_MODULE,
-       }
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "CONNMARK",
+               .revision       = 1,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = connmark_tg_check,
+               .target         = connmark_tg,
+               .targetsize     = sizeof(struct xt_connmark_tginfo1),
+               .destroy        = connmark_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CONNMARK",
+               .revision       = 2,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = connmark_tg_check,
+               .target         = connmark_tg_v2,
+               .targetsize     = sizeof(struct xt_connmark_tginfo2),
+               .destroy        = connmark_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static struct xt_match connmark_mt_reg __read_mostly = {
index 1ad74b5920b533abb1a1814b1fd0c86511433022..f76fe04fc9a4e19f18ac323349ba6f22a00eafd7 100644 (file)
@@ -39,13 +39,35 @@ mark_mt(const struct sk_buff *skb, struct xt_action_param *par)
        return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static struct xt_target mark_tg_reg __read_mostly = {
-       .name           = "MARK",
-       .revision       = 2,
-       .family         = NFPROTO_UNSPEC,
-       .target         = mark_tg,
-       .targetsize     = sizeof(struct xt_mark_tginfo2),
-       .me             = THIS_MODULE,
+static struct xt_target mark_tg_reg[] __read_mostly = {
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = NFPROTO_IPV4,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP_NF_ARPTABLES)
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = NFPROTO_ARP,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+#endif
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = NFPROTO_IPV4,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static struct xt_match mark_mt_reg __read_mostly = {
@@ -61,12 +83,12 @@ static int __init mark_mt_init(void)
 {
        int ret;
 
-       ret = xt_register_target(&mark_tg_reg);
+       ret = xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
        if (ret < 0)
                return ret;
        ret = xt_register_match(&mark_mt_reg);
        if (ret < 0) {
-               xt_unregister_target(&mark_tg_reg);
+               xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
                return ret;
        }
        return 0;
@@ -75,7 +97,7 @@ static int __init mark_mt_init(void)
 static void __exit mark_mt_exit(void)
 {
        xt_unregister_match(&mark_mt_reg);
-       xt_unregister_target(&mark_tg_reg);
+       xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
 }
 
 module_init(mark_mt_init);