bool wildcard;
                bool transparent = true;
 
-               /* Ignore sockets listening on INADDR_ANY */
-               wildcard = (sk->sk_state != TCP_TIME_WAIT &&
+               /* Ignore sockets listening on INADDR_ANY,
+                * unless XT_SOCKET_NOWILDCARD is set
+                */
+               wildcard = (!(info->flags & XT_SOCKET_NOWILDCARD) &&
+                           sk->sk_state != TCP_TIME_WAIT &&
                            inet_sk(sk)->inet_rcv_saddr == 0);
 
                /* Ignore non-transparent sockets,
 }
 
 static bool
-socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par)
+socket_mt4_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
 {
        return socket_match(skb, par, par->matchinfo);
 }
 }
 
 static bool
-socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
+socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
        struct udphdr _hdr, *hp = NULL;
                bool wildcard;
                bool transparent = true;
 
-               /* Ignore sockets listening on INADDR_ANY */
-               wildcard = (sk->sk_state != TCP_TIME_WAIT &&
+               /* Ignore sockets listening on INADDR_ANY
+                * unless XT_SOCKET_NOWILDCARD is set
+                */
+               wildcard = (!(info->flags & XT_SOCKET_NOWILDCARD) &&
+                           sk->sk_state != TCP_TIME_WAIT &&
                            ipv6_addr_any(&inet6_sk(sk)->rcv_saddr));
 
                /* Ignore non-transparent sockets,
 }
 #endif
 
+static int socket_mt_v1_check(const struct xt_mtchk_param *par)
+{
+       const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
+
+       if (info->flags & ~XT_SOCKET_FLAGS_V1) {
+               pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V1);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int socket_mt_v2_check(const struct xt_mtchk_param *par)
+{
+       const struct xt_socket_mtinfo2 *info = (struct xt_socket_mtinfo2 *) par->matchinfo;
+
+       if (info->flags & ~XT_SOCKET_FLAGS_V2) {
+               pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V2);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static struct xt_match socket_mt_reg[] __read_mostly = {
        {
                .name           = "socket",
                .name           = "socket",
                .revision       = 1,
                .family         = NFPROTO_IPV4,
-               .match          = socket_mt4_v1,
+               .match          = socket_mt4_v1_v2,
+               .checkentry     = socket_mt_v1_check,
                .matchsize      = sizeof(struct xt_socket_mtinfo1),
                .hooks          = (1 << NF_INET_PRE_ROUTING) |
                                  (1 << NF_INET_LOCAL_IN),
                .name           = "socket",
                .revision       = 1,
                .family         = NFPROTO_IPV6,
-               .match          = socket_mt6_v1,
+               .match          = socket_mt6_v1_v2,
+               .checkentry     = socket_mt_v1_check,
+               .matchsize      = sizeof(struct xt_socket_mtinfo1),
+               .hooks          = (1 << NF_INET_PRE_ROUTING) |
+                                 (1 << NF_INET_LOCAL_IN),
+               .me             = THIS_MODULE,
+       },
+#endif
+       {
+               .name           = "socket",
+               .revision       = 2,
+               .family         = NFPROTO_IPV4,
+               .match          = socket_mt4_v1_v2,
+               .checkentry     = socket_mt_v2_check,
+               .matchsize      = sizeof(struct xt_socket_mtinfo1),
+               .hooks          = (1 << NF_INET_PRE_ROUTING) |
+                                 (1 << NF_INET_LOCAL_IN),
+               .me             = THIS_MODULE,
+       },
+#ifdef XT_SOCKET_HAVE_IPV6
+       {
+               .name           = "socket",
+               .revision       = 2,
+               .family         = NFPROTO_IPV6,
+               .match          = socket_mt6_v1_v2,
+               .checkentry     = socket_mt_v2_check,
                .matchsize      = sizeof(struct xt_socket_mtinfo1),
                .hooks          = (1 << NF_INET_PRE_ROUTING) |
                                  (1 << NF_INET_LOCAL_IN),