--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -51,6 +51,7 @@ header-y += xt_ecn.h
 header-y += xt_esp.h
 header-y += xt_hashlimit.h
 header-y += xt_helper.h
+header-y += xt_id.h
 header-y += xt_iprange.h
 header-y += xt_ipvs.h
 header-y += xt_layer7.h
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_id.h
@@ -0,0 +1,8 @@
+#ifndef _XT_ID_H
+#define _XT_ID_H
+
+struct xt_id_info {
+	u32 id;
+};
+
+#endif /* XT_ID_H */
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -989,6 +989,13 @@ config NETFILTER_XT_MATCH_HL
 	in the IPv6 header, or the time-to-live field in the IPv4
 	header of the packet.
 
+config NETFILTER_XT_MATCH_ID
+	tristate '"id" match support'
+	depends on NETFILTER_ADVANCED
+	---help---
+	This option adds a `id' dummy-match, which allows you to put
+	numeric IDs into your iptables ruleset.
+
 config NETFILTER_XT_MATCH_IPRANGE
 	tristate '"iprange" address range match support'
 	depends on NETFILTER_ADVANCED
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += 
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_ID) += xt_id.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
--- /dev/null
+++ b/net/netfilter/xt_id.c
@@ -0,0 +1,45 @@
+/*
+ * Implements a dummy match to allow attaching IDs to rules
+ *
+ * 2014-08-01 Jo-Philipp Wich <jow@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_id.h>
+
+MODULE_AUTHOR("Jo-Philipp Wich <jow@openwrt.org>");
+MODULE_DESCRIPTION("Xtables: No-op match which can be tagged with a 32bit ID");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_id");
+MODULE_ALIAS("ip6t_id");
+
+static bool
+id_mt(const struct sk_buff *skb, struct xt_action_param *par)
+{
+	/* We always match */
+	return true;
+}
+
+static struct xt_match id_mt_reg __read_mostly = {
+	.name      = "id",
+	.revision  = 0,
+	.family    = NFPROTO_UNSPEC,
+	.match     = id_mt,
+	.matchsize = sizeof(struct xt_id_info),
+	.me        = THIS_MODULE,
+};
+
+static int __init id_mt_init(void)
+{
+	return xt_register_match(&id_mt_reg);
+}
+
+static void __exit id_mt_exit(void)
+{
+	xt_unregister_match(&id_mt_reg);
+}
+
+module_init(id_mt_init);
+module_exit(id_mt_exit);
