}
        }
        mutex_unlock(&xt[af].mutex);
+
+       if (af != NFPROTO_UNSPEC)
+               /* Try searching again in the family-independent list */
+               return xt_find_match(NFPROTO_UNSPEC, name, revision);
+
        return ERR_PTR(err);
 }
 EXPORT_SYMBOL(xt_find_match);
                }
        }
        mutex_unlock(&xt[af].mutex);
+
+       if (af != NFPROTO_UNSPEC)
+               /* Try searching again in the family-independent list */
+               return xt_find_target(NFPROTO_UNSPEC, name, revision);
+
        return ERR_PTR(err);
 }
 EXPORT_SYMBOL(xt_find_target);
 
        return XT_CONTINUE;
 }
 
-static struct xt_target classify_tg_reg[] __read_mostly = {
-       {
-               .family         = NFPROTO_IPV4,
-               .name           = "CLASSIFY",
-               .target         = classify_tg,
-               .targetsize     = sizeof(struct xt_classify_target_info),
-               .table          = "mangle",
-               .hooks          = (1 << NF_INET_LOCAL_OUT) |
-                                 (1 << NF_INET_FORWARD) |
-                                 (1 << NF_INET_POST_ROUTING),
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "CLASSIFY",
-               .family         = NFPROTO_IPV6,
-               .target         = classify_tg,
-               .targetsize     = sizeof(struct xt_classify_target_info),
-               .table          = "mangle",
-               .hooks          = (1 << NF_INET_LOCAL_OUT) |
-                                 (1 << NF_INET_FORWARD) |
-                                 (1 << NF_INET_POST_ROUTING),
-               .me             = THIS_MODULE,
-       },
+static struct xt_target classify_tg_reg __read_mostly = {
+       .name       = "CLASSIFY",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .table      = "mangle",
+       .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,
 };
 
 static int __init classify_tg_init(void)
 {
-       return xt_register_targets(classify_tg_reg,
-              ARRAY_SIZE(classify_tg_reg));
+       return xt_register_target(&classify_tg_reg);
 }
 
 static void __exit classify_tg_exit(void)
 {
-       xt_unregister_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg));
+       xt_unregister_target(&classify_tg_reg);
 }
 
 module_init(classify_tg_init);
 
        {
                .name           = "MARK",
                .revision       = 2,
-               .family         = NFPROTO_IPV4,
-               .target         = mark_tg,
-               .targetsize     = sizeof(struct xt_mark_tginfo2),
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "MARK",
-               .revision       = 2,
-               .family         = NFPROTO_IPV6,
+               .family         = NFPROTO_UNSPEC,
                .target         = mark_tg,
                .targetsize     = sizeof(struct xt_mark_tginfo2),
                .me             = THIS_MODULE,
 
        xt_rateest_put(info->est);
 }
 
-static struct xt_target xt_rateest_target[] __read_mostly = {
-       {
-               .family         = NFPROTO_IPV4,
-               .name           = "RATEEST",
-               .target         = xt_rateest_tg,
-               .checkentry     = xt_rateest_tg_checkentry,
-               .destroy        = xt_rateest_tg_destroy,
-               .targetsize     = sizeof(struct xt_rateest_target_info),
-               .me             = THIS_MODULE,
-       },
-       {
-               .family         = NFPROTO_IPV6,
-               .name           = "RATEEST",
-               .target         = xt_rateest_tg,
-               .checkentry     = xt_rateest_tg_checkentry,
-               .destroy        = xt_rateest_tg_destroy,
-               .targetsize     = sizeof(struct xt_rateest_target_info),
-               .me             = THIS_MODULE,
-       },
+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),
+       .me         = THIS_MODULE,
 };
 
 static int __init xt_rateest_tg_init(void)
                INIT_HLIST_HEAD(&rateest_hash[i]);
 
        get_random_bytes(&jhash_rnd, sizeof(jhash_rnd));
-       return xt_register_targets(xt_rateest_target,
-                                  ARRAY_SIZE(xt_rateest_target));
+       return xt_register_target(&xt_rateest_tg_reg);
 }
 
 static void __exit xt_rateest_tg_fini(void)
 {
-       xt_unregister_targets(xt_rateest_target, ARRAY_SIZE(xt_rateest_target));
+       xt_unregister_target(&xt_rateest_tg_reg);
 }
 
 
 
        }
 }
 
-static struct xt_target secmark_tg_reg[] __read_mostly = {
-       {
-               .name           = "SECMARK",
-               .family         = NFPROTO_IPV4,
-               .checkentry     = secmark_tg_check,
-               .destroy        = secmark_tg_destroy,
-               .target         = secmark_tg,
-               .targetsize     = sizeof(struct xt_secmark_target_info),
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "SECMARK",
-               .family         = NFPROTO_IPV6,
-               .checkentry     = secmark_tg_check,
-               .destroy        = secmark_tg_destroy,
-               .target         = secmark_tg,
-               .targetsize     = sizeof(struct xt_secmark_target_info),
-               .me             = THIS_MODULE,
-       },
+static struct xt_target secmark_tg_reg __read_mostly = {
+       .name       = "SECMARK",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .checkentry = secmark_tg_check,
+       .destroy    = secmark_tg_destroy,
+       .target     = secmark_tg,
+       .targetsize = sizeof(struct xt_secmark_target_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init secmark_tg_init(void)
 {
-       return xt_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
+       return xt_register_target(&secmark_tg_reg);
 }
 
 static void __exit secmark_tg_exit(void)
 {
-       xt_unregister_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
+       xt_unregister_target(&secmark_tg_reg);
 }
 
 module_init(secmark_tg_init);
 
        return XT_CONTINUE;
 }
 
-static struct xt_target trace_tg_reg[] __read_mostly = {
-       {
-               .name           = "TRACE",
-               .family         = NFPROTO_IPV4,
-               .target         = trace_tg,
-               .table          = "raw",
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "TRACE",
-               .family         = NFPROTO_IPV6,
-               .target         = trace_tg,
-               .table          = "raw",
-               .me             = THIS_MODULE,
-       },
+static struct xt_target trace_tg_reg __read_mostly = {
+       .name       = "TRACE",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .table      = "raw",
+       .target     = trace_tg,
+       .me         = THIS_MODULE,
 };
 
 static int __init trace_tg_init(void)
 {
-       return xt_register_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
+       return xt_register_target(&trace_tg_reg);
 }
 
 static void __exit trace_tg_exit(void)
 {
-       xt_unregister_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
+       xt_unregister_target(&trace_tg_reg);
 }
 
 module_init(trace_tg_init);
 
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match limit_mt_reg[] __read_mostly = {
-       {
-               .name           = "limit",
-               .family         = NFPROTO_IPV4,
-               .checkentry     = limit_mt_check,
-               .match          = limit_mt,
-               .matchsize      = sizeof(struct xt_rateinfo),
+static struct xt_match limit_mt_reg __read_mostly = {
+       .name             = "limit",
+       .revision         = 0,
+       .family           = NFPROTO_UNSPEC,
+       .match            = limit_mt,
+       .checkentry       = limit_mt_check,
+       .matchsize        = sizeof(struct xt_rateinfo),
 #ifdef CONFIG_COMPAT
-               .compatsize     = sizeof(struct compat_xt_rateinfo),
-               .compat_from_user = limit_mt_compat_from_user,
-               .compat_to_user = limit_mt_compat_to_user,
+       .compatsize       = sizeof(struct compat_xt_rateinfo),
+       .compat_from_user = limit_mt_compat_from_user,
+       .compat_to_user   = limit_mt_compat_to_user,
 #endif
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "limit",
-               .family         = NFPROTO_IPV6,
-               .checkentry     = limit_mt_check,
-               .match          = limit_mt,
-               .matchsize      = sizeof(struct xt_rateinfo),
-#ifdef CONFIG_COMPAT
-               .compatsize     = sizeof(struct compat_xt_rateinfo),
-               .compat_from_user = limit_mt_compat_from_user,
-               .compat_to_user = limit_mt_compat_to_user,
-#endif
-               .me             = THIS_MODULE,
-       },
+       .me               = THIS_MODULE,
 };
 
 static int __init limit_mt_init(void)
 {
-       return xt_register_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg));
+       return xt_register_match(&limit_mt_reg);
 }
 
 static void __exit limit_mt_exit(void)
 {
-       xt_unregister_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg));
+       xt_unregister_match(&limit_mt_reg);
 }
 
 module_init(limit_mt_init);
 
        {
                .name           = "mark",
                .revision       = 0,
-               .family         = NFPROTO_IPV4,
+               .family         = NFPROTO_UNSPEC,
                .checkentry     = mark_mt_check_v0,
                .match          = mark_mt_v0,
                .matchsize      = sizeof(struct xt_mark_info),
 #endif
                .me             = THIS_MODULE,
        },
-       {
-               .name           = "mark",
-               .revision       = 0,
-               .family         = NFPROTO_IPV6,
-               .checkentry     = mark_mt_check_v0,
-               .match          = mark_mt_v0,
-               .matchsize      = sizeof(struct xt_mark_info),
-#ifdef CONFIG_COMPAT
-               .compatsize     = sizeof(struct compat_xt_mark_info),
-               .compat_from_user = mark_mt_compat_from_user_v0,
-               .compat_to_user = mark_mt_compat_to_user_v0,
-#endif
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "mark",
-               .revision       = 1,
-               .family         = NFPROTO_IPV4,
-               .match          = mark_mt,
-               .matchsize      = sizeof(struct xt_mark_mtinfo1),
-               .me             = THIS_MODULE,
-       },
        {
                .name           = "mark",
                .revision       = 1,
-               .family         = NFPROTO_IPV6,
+               .family         = NFPROTO_UNSPEC,
                .match          = mark_mt,
                .matchsize      = sizeof(struct xt_mark_mtinfo1),
                .me             = THIS_MODULE,
 
        return true;
 }
 
-static struct xt_match quota_mt_reg[] __read_mostly = {
-       {
-               .name           = "quota",
-               .family         = NFPROTO_IPV4,
-               .checkentry     = quota_mt_check,
-               .match          = quota_mt,
-               .matchsize      = sizeof(struct xt_quota_info),
-               .me             = THIS_MODULE
-       },
-       {
-               .name           = "quota",
-               .family         = NFPROTO_IPV6,
-               .checkentry     = quota_mt_check,
-               .match          = quota_mt,
-               .matchsize      = sizeof(struct xt_quota_info),
-               .me             = THIS_MODULE
-       },
+static struct xt_match quota_mt_reg __read_mostly = {
+       .name       = "quota",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .match      = quota_mt,
+       .checkentry = quota_mt_check,
+       .matchsize  = sizeof(struct xt_quota_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init quota_mt_init(void)
 {
-       return xt_register_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg));
+       return xt_register_match("a_mt_reg);
 }
 
 static void __exit quota_mt_exit(void)
 {
-       xt_unregister_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg));
+       xt_unregister_match("a_mt_reg);
 }
 
 module_init(quota_mt_init);
 
                xt_rateest_put(info->est2);
 }
 
-static struct xt_match xt_rateest_match[] __read_mostly = {
-       {
-               .family         = NFPROTO_IPV4,
-               .name           = "rateest",
-               .match          = xt_rateest_mt,
-               .checkentry     = xt_rateest_mt_checkentry,
-               .destroy        = xt_rateest_mt_destroy,
-               .matchsize      = sizeof(struct xt_rateest_match_info),
-               .me             = THIS_MODULE,
-       },
-       {
-               .family         = NFPROTO_IPV6,
-               .name           = "rateest",
-               .match          = xt_rateest_mt,
-               .checkentry     = xt_rateest_mt_checkentry,
-               .destroy        = xt_rateest_mt_destroy,
-               .matchsize      = sizeof(struct xt_rateest_match_info),
-               .me             = THIS_MODULE,
-       },
+static struct xt_match xt_rateest_mt_reg __read_mostly = {
+       .name       = "rateest",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .match      = xt_rateest_mt,
+       .checkentry = xt_rateest_mt_checkentry,
+       .destroy    = xt_rateest_mt_destroy,
+       .matchsize  = sizeof(struct xt_rateest_match_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init xt_rateest_mt_init(void)
 {
-       return xt_register_matches(xt_rateest_match,
-                                  ARRAY_SIZE(xt_rateest_match));
+       return xt_register_match(&xt_rateest_mt_reg);
 }
 
 static void __exit xt_rateest_mt_fini(void)
 {
-       xt_unregister_matches(xt_rateest_match, ARRAY_SIZE(xt_rateest_match));
+       xt_unregister_match(&xt_rateest_mt_reg);
 }
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 
        return true;
 }
 
-static struct xt_match statistic_mt_reg[] __read_mostly = {
-       {
-               .name           = "statistic",
-               .family         = NFPROTO_IPV4,
-               .checkentry     = statistic_mt_check,
-               .match          = statistic_mt,
-               .matchsize      = sizeof(struct xt_statistic_info),
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "statistic",
-               .family         = NFPROTO_IPV6,
-               .checkentry     = statistic_mt_check,
-               .match          = statistic_mt,
-               .matchsize      = sizeof(struct xt_statistic_info),
-               .me             = THIS_MODULE,
-       },
+static struct xt_match xt_statistic_mt_reg __read_mostly = {
+       .name       = "statistic",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .match      = statistic_mt,
+       .checkentry = statistic_mt_check,
+       .matchsize  = sizeof(struct xt_statistic_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init statistic_mt_init(void)
 {
-       return xt_register_matches(statistic_mt_reg,
-              ARRAY_SIZE(statistic_mt_reg));
+       return xt_register_match(&xt_statistic_mt_reg);
 }
 
 static void __exit statistic_mt_exit(void)
 {
-       xt_unregister_matches(statistic_mt_reg,
-                             ARRAY_SIZE(statistic_mt_reg));
+       xt_unregister_match(&xt_statistic_mt_reg);
 }
 
 module_init(statistic_mt_init);
 
        textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
 }
 
-static struct xt_match string_mt_reg[] __read_mostly = {
+static struct xt_match xt_string_mt_reg[] __read_mostly = {
        {
                .name           = "string",
                .revision       = 0,
-               .family         = NFPROTO_IPV4,
+               .family         = NFPROTO_UNSPEC,
                .checkentry     = string_mt_check,
                .match          = string_mt,
                .destroy        = string_mt_destroy,
        {
                .name           = "string",
                .revision       = 1,
-               .family         = NFPROTO_IPV4,
-               .checkentry     = string_mt_check,
-               .match          = string_mt,
-               .destroy        = string_mt_destroy,
-               .matchsize      = sizeof(struct xt_string_info),
-               .me             = THIS_MODULE
-       },
-       {
-               .name           = "string",
-               .revision       = 0,
-               .family         = NFPROTO_IPV6,
-               .checkentry     = string_mt_check,
-               .match          = string_mt,
-               .destroy        = string_mt_destroy,
-               .matchsize      = sizeof(struct xt_string_info),
-               .me             = THIS_MODULE
-       },
-       {
-               .name           = "string",
-               .revision       = 1,
-               .family         = NFPROTO_IPV6,
+               .family         = NFPROTO_UNSPEC,
                .checkentry     = string_mt_check,
                .match          = string_mt,
                .destroy        = string_mt_destroy,
 
 static int __init string_mt_init(void)
 {
-       return xt_register_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg));
+       return xt_register_matches(xt_string_mt_reg,
+                                  ARRAY_SIZE(xt_string_mt_reg));
 }
 
 static void __exit string_mt_exit(void)
 {
-       xt_unregister_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg));
+       xt_unregister_matches(xt_string_mt_reg, ARRAY_SIZE(xt_string_mt_reg));
 }
 
 module_init(string_mt_init);
 
        return true;
 }
 
-static struct xt_match time_mt_reg[] __read_mostly = {
-       {
-               .name       = "time",
-               .family     = NFPROTO_IPV4,
-               .match      = time_mt,
-               .matchsize  = sizeof(struct xt_time_info),
-               .checkentry = time_mt_check,
-               .me         = THIS_MODULE,
-       },
-       {
-               .name       = "time",
-               .family     = NFPROTO_IPV6,
-               .match      = time_mt,
-               .matchsize  = sizeof(struct xt_time_info),
-               .checkentry = time_mt_check,
-               .me         = THIS_MODULE,
-       },
+static struct xt_match xt_time_mt_reg __read_mostly = {
+       .name       = "time",
+       .family     = NFPROTO_UNSPEC,
+       .match      = time_mt,
+       .checkentry = time_mt_check,
+       .matchsize  = sizeof(struct xt_time_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init time_mt_init(void)
 {
-       return xt_register_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg));
+       return xt_register_match(&xt_time_mt_reg);
 }
 
 static void __exit time_mt_exit(void)
 {
-       xt_unregister_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg));
+       xt_unregister_match(&xt_time_mt_reg);
 }
 
 module_init(time_mt_init);
 
        return ret ^ data->invert;
 }
 
-static struct xt_match u32_mt_reg[] __read_mostly = {
-       {
-               .name       = "u32",
-               .family     = NFPROTO_IPV4,
-               .match      = u32_mt,
-               .matchsize  = sizeof(struct xt_u32),
-               .me         = THIS_MODULE,
-       },
-       {
-               .name       = "u32",
-               .family     = NFPROTO_IPV6,
-               .match      = u32_mt,
-               .matchsize  = sizeof(struct xt_u32),
-               .me         = THIS_MODULE,
-       },
+static struct xt_match xt_u32_mt_reg __read_mostly = {
+       .name       = "u32",
+       .revision   = 0,
+       .family     = NFPROTO_UNSPEC,
+       .match      = u32_mt,
+       .matchsize  = sizeof(struct xt_u32),
+       .me         = THIS_MODULE,
 };
 
 static int __init u32_mt_init(void)
 {
-       return xt_register_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg));
+       return xt_register_match(&xt_u32_mt_reg);
 }
 
 static void __exit u32_mt_exit(void)
 {
-       xt_unregister_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg));
+       xt_unregister_match(&xt_u32_mt_reg);
 }
 
 module_init(u32_mt_init);