diff options
8 files changed, 1111 insertions, 0 deletions
| diff --git a/package/iproute2/patches/200-act_connmark.patch b/package/iproute2/patches/200-act_connmark.patch new file mode 100644 index 000000000..561041f0a --- /dev/null +++ b/package/iproute2/patches/200-act_connmark.patch @@ -0,0 +1,84 @@ +--- a/tc/Makefile ++++ b/tc/Makefile +@@ -36,6 +36,7 @@ TCMODULES += m_mirred.o + TCMODULES += m_nat.o + TCMODULES += m_pedit.o + TCMODULES += m_skbedit.o ++TCMODULES += m_connmark.o + TCMODULES += p_ip.o + TCMODULES += p_icmp.o + TCMODULES += p_tcp.o +--- /dev/null ++++ b/tc/m_connmark.c +@@ -0,0 +1,71 @@ ++/* ++ * m_connmark.c		Connection tracking marking import ++ * ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <string.h> ++#include "utils.h" ++#include "tc_util.h" ++ ++static void ++explain(void) ++{ ++	fprintf(stderr, "Usage: ... connmark\n"); ++} ++ ++static void ++usage(void) ++{ ++	explain(); ++	exit(-1); ++} ++ ++static int ++parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, ++	      struct nlmsghdr *n) ++{ ++	int argc = *argc_p; ++	char **argv = *argv_p; ++ ++	if (matches(*argv, "connmark") != 0) ++		return -1; ++ ++	NEXT_ARG(); ++ ++	*argc_p = argc; ++	*argv_p = argv; ++	return 0; ++} ++ ++static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg) ++{ ++	if (arg == NULL) ++		return -1; ++ ++	fprintf(f, " connmark"); ++ ++	return 0; ++} ++ ++struct action_util connmark_action_util = { ++	.id = "connmark", ++	.parse_aopt = parse_connmark, ++	.print_aopt = print_connmark, ++}; diff --git a/package/kernel/modules/netsupport.mk b/package/kernel/modules/netsupport.mk index e0e423893..c86003417 100644 --- a/package/kernel/modules/netsupport.mk +++ b/package/kernel/modules/netsupport.mk @@ -551,6 +551,7 @@ define KernelPackage/sched  	CONFIG_NET_ACT_MIRRED \  	CONFIG_NET_ACT_IPT \  	CONFIG_NET_ACT_POLICE \ +	CONFIG_NET_ACT_CONNMARK \  	CONFIG_NET_EMATCH=y \  	CONFIG_NET_EMATCH_CMP \  	CONFIG_NET_EMATCH_NBYTE \ diff --git a/target/linux/generic/patches-2.6.32/280-sched_act_connmark.patch b/target/linux/generic/patches-2.6.32/280-sched_act_connmark.patch new file mode 100644 index 000000000..734fd1cd1 --- /dev/null +++ b/target/linux/generic/patches-2.6.32/280-sched_act_connmark.patch @@ -0,0 +1,171 @@ +--- /dev/null ++++ b/net/sched/act_connmark.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <linux/rtnetlink.h> ++#include <linux/pkt_cls.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/netlink.h> ++#include <net/pkt_sched.h> ++#include <net/act_api.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_core.h> ++ ++#define TCA_ACT_CONNMARK	20 ++ ++#define CONNMARK_TAB_MASK     3 ++static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; ++static u32 connmark_idx_gen; ++static DEFINE_RWLOCK(connmark_lock); ++ ++static struct tcf_hashinfo connmark_hash_info = { ++	.htab	=	tcf_connmark_ht, ++	.hmask	=	CONNMARK_TAB_MASK, ++	.lock	=	&connmark_lock, ++}; ++ ++static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, ++		       struct tcf_result *res) ++{ ++	struct nf_conn *c; ++	enum ip_conntrack_info ctinfo; ++	int proto; ++	int r; ++ ++	if (skb->protocol == htons(ETH_P_IP)) { ++		if (skb->len < sizeof(struct iphdr)) ++			goto out; ++		proto = PF_INET; ++	} else if (skb->protocol == htons(ETH_P_IPV6)) { ++		if (skb->len < sizeof(struct ipv6hdr)) ++			goto out; ++		proto = PF_INET6; ++	} else ++		goto out; ++ ++	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); ++	if (r != NF_ACCEPT) ++		goto out; ++ ++	c = nf_ct_get(skb, &ctinfo); ++	if (!c) ++		goto out; ++ ++	skb->mark = c->mark; ++	nf_conntrack_put(skb->nfct); ++	skb->nfct = NULL; ++ ++out: ++	return TC_ACT_PIPE; ++} ++ ++static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, ++			 struct tc_action *a, int ovr, int bind) ++{ ++	struct tcf_common *pc; ++ ++	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, ++			     &connmark_idx_gen, &connmark_hash_info); ++	if (IS_ERR(pc)) ++	    return PTR_ERR(pc); ++ ++	tcf_hash_insert(pc, &connmark_hash_info); ++ ++	return ACT_P_CREATED; ++} ++ ++static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) ++{ ++	if (a->priv) ++		return tcf_hash_release(a->priv, bind, &connmark_hash_info); ++	return 0; ++} ++ ++static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ++				int bind, int ref) ++{ ++	return skb->len; ++} ++ ++static struct tc_action_ops act_connmark_ops = { ++	.kind		=	"connmark", ++	.hinfo		=	&connmark_hash_info, ++	.type		=	TCA_ACT_CONNMARK, ++	.capab		=	TCA_CAP_NONE, ++	.owner		=	THIS_MODULE, ++	.act		=	tcf_connmark, ++	.dump		=	tcf_connmark_dump, ++	.cleanup	=	tcf_connmark_cleanup, ++	.init		=	tcf_connmark_init, ++	.walk		=	tcf_generic_walker, ++}; ++ ++MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); ++MODULE_DESCRIPTION("Connection tracking mark restoring"); ++MODULE_LICENSE("GPL"); ++ ++static int __init connmark_init_module(void) ++{ ++	return tcf_register_action(&act_connmark_ops); ++} ++ ++static void __exit connmark_cleanup_module(void) ++{ ++	tcf_unregister_action(&act_connmark_ops); ++} ++ ++module_init(connmark_init_module); ++module_exit(connmark_cleanup_module); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -546,6 +546,18 @@ config NET_ACT_SKBEDIT + 	  To compile this code as a module, choose M here: the + 	  module will be called skbedit. +  ++config NET_ACT_CONNMARK ++        tristate "Connection Tracking Marking" ++        depends on NET_CLS_ACT ++        depends on NF_CONNTRACK ++        ---help--- ++	  Say Y here to restore the connmark from a scheduler action ++ ++	  If unsure, say N. ++ ++	  To compile this code as a module, choose M here: the ++	  module will be called act_connmark. ++ + config NET_CLS_IND + 	bool "Incoming device classification" + 	depends on NET_CLS_U32 || NET_CLS_FW +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT)	+= act_nat.o + obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o + obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o + obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o ++obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o + obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o + obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o + obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o diff --git a/target/linux/generic/patches-2.6.34/280-sched_act_connmark.patch b/target/linux/generic/patches-2.6.34/280-sched_act_connmark.patch new file mode 100644 index 000000000..e02d1bc31 --- /dev/null +++ b/target/linux/generic/patches-2.6.34/280-sched_act_connmark.patch @@ -0,0 +1,171 @@ +--- /dev/null ++++ b/net/sched/act_connmark.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <linux/rtnetlink.h> ++#include <linux/pkt_cls.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/netlink.h> ++#include <net/pkt_sched.h> ++#include <net/act_api.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_core.h> ++ ++#define TCA_ACT_CONNMARK	20 ++ ++#define CONNMARK_TAB_MASK     3 ++static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; ++static u32 connmark_idx_gen; ++static DEFINE_RWLOCK(connmark_lock); ++ ++static struct tcf_hashinfo connmark_hash_info = { ++	.htab	=	tcf_connmark_ht, ++	.hmask	=	CONNMARK_TAB_MASK, ++	.lock	=	&connmark_lock, ++}; ++ ++static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, ++		       struct tcf_result *res) ++{ ++	struct nf_conn *c; ++	enum ip_conntrack_info ctinfo; ++	int proto; ++	int r; ++ ++	if (skb->protocol == htons(ETH_P_IP)) { ++		if (skb->len < sizeof(struct iphdr)) ++			goto out; ++		proto = PF_INET; ++	} else if (skb->protocol == htons(ETH_P_IPV6)) { ++		if (skb->len < sizeof(struct ipv6hdr)) ++			goto out; ++		proto = PF_INET6; ++	} else ++		goto out; ++ ++	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); ++	if (r != NF_ACCEPT) ++		goto out; ++ ++	c = nf_ct_get(skb, &ctinfo); ++	if (!c) ++		goto out; ++ ++	skb->mark = c->mark; ++	nf_conntrack_put(skb->nfct); ++	skb->nfct = NULL; ++ ++out: ++	return TC_ACT_PIPE; ++} ++ ++static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, ++			 struct tc_action *a, int ovr, int bind) ++{ ++	struct tcf_common *pc; ++ ++	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, ++			     &connmark_idx_gen, &connmark_hash_info); ++	if (IS_ERR(pc)) ++	    return PTR_ERR(pc); ++ ++	tcf_hash_insert(pc, &connmark_hash_info); ++ ++	return ACT_P_CREATED; ++} ++ ++static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) ++{ ++	if (a->priv) ++		return tcf_hash_release(a->priv, bind, &connmark_hash_info); ++	return 0; ++} ++ ++static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ++				int bind, int ref) ++{ ++	return skb->len; ++} ++ ++static struct tc_action_ops act_connmark_ops = { ++	.kind		=	"connmark", ++	.hinfo		=	&connmark_hash_info, ++	.type		=	TCA_ACT_CONNMARK, ++	.capab		=	TCA_CAP_NONE, ++	.owner		=	THIS_MODULE, ++	.act		=	tcf_connmark, ++	.dump		=	tcf_connmark_dump, ++	.cleanup	=	tcf_connmark_cleanup, ++	.init		=	tcf_connmark_init, ++	.walk		=	tcf_generic_walker, ++}; ++ ++MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); ++MODULE_DESCRIPTION("Connection tracking mark restoring"); ++MODULE_LICENSE("GPL"); ++ ++static int __init connmark_init_module(void) ++{ ++	return tcf_register_action(&act_connmark_ops); ++} ++ ++static void __exit connmark_cleanup_module(void) ++{ ++	tcf_unregister_action(&act_connmark_ops); ++} ++ ++module_init(connmark_init_module); ++module_exit(connmark_cleanup_module); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -549,6 +549,18 @@ + 	  To compile this code as a module, choose M here: the + 	  module will be called act_skbedit. +  ++config NET_ACT_CONNMARK ++        tristate "Connection Tracking Marking" ++        depends on NET_CLS_ACT ++        depends on NF_CONNTRACK ++        ---help--- ++	  Say Y here to restore the connmark from a scheduler action ++ ++	  If unsure, say N. ++ ++	  To compile this code as a module, choose M here: the ++	  module will be called act_connmark. ++ + config NET_CLS_IND + 	bool "Incoming device classification" + 	depends on NET_CLS_U32 || NET_CLS_FW +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -15,6 +15,7 @@ + obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o + obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o + obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o ++obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o + obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o + obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o + obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o diff --git a/target/linux/generic/patches-2.6.35/290-sched_act_connmark.patch b/target/linux/generic/patches-2.6.35/290-sched_act_connmark.patch new file mode 100644 index 000000000..e02d1bc31 --- /dev/null +++ b/target/linux/generic/patches-2.6.35/290-sched_act_connmark.patch @@ -0,0 +1,171 @@ +--- /dev/null ++++ b/net/sched/act_connmark.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <linux/rtnetlink.h> ++#include <linux/pkt_cls.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/netlink.h> ++#include <net/pkt_sched.h> ++#include <net/act_api.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_core.h> ++ ++#define TCA_ACT_CONNMARK	20 ++ ++#define CONNMARK_TAB_MASK     3 ++static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; ++static u32 connmark_idx_gen; ++static DEFINE_RWLOCK(connmark_lock); ++ ++static struct tcf_hashinfo connmark_hash_info = { ++	.htab	=	tcf_connmark_ht, ++	.hmask	=	CONNMARK_TAB_MASK, ++	.lock	=	&connmark_lock, ++}; ++ ++static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, ++		       struct tcf_result *res) ++{ ++	struct nf_conn *c; ++	enum ip_conntrack_info ctinfo; ++	int proto; ++	int r; ++ ++	if (skb->protocol == htons(ETH_P_IP)) { ++		if (skb->len < sizeof(struct iphdr)) ++			goto out; ++		proto = PF_INET; ++	} else if (skb->protocol == htons(ETH_P_IPV6)) { ++		if (skb->len < sizeof(struct ipv6hdr)) ++			goto out; ++		proto = PF_INET6; ++	} else ++		goto out; ++ ++	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); ++	if (r != NF_ACCEPT) ++		goto out; ++ ++	c = nf_ct_get(skb, &ctinfo); ++	if (!c) ++		goto out; ++ ++	skb->mark = c->mark; ++	nf_conntrack_put(skb->nfct); ++	skb->nfct = NULL; ++ ++out: ++	return TC_ACT_PIPE; ++} ++ ++static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, ++			 struct tc_action *a, int ovr, int bind) ++{ ++	struct tcf_common *pc; ++ ++	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, ++			     &connmark_idx_gen, &connmark_hash_info); ++	if (IS_ERR(pc)) ++	    return PTR_ERR(pc); ++ ++	tcf_hash_insert(pc, &connmark_hash_info); ++ ++	return ACT_P_CREATED; ++} ++ ++static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) ++{ ++	if (a->priv) ++		return tcf_hash_release(a->priv, bind, &connmark_hash_info); ++	return 0; ++} ++ ++static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ++				int bind, int ref) ++{ ++	return skb->len; ++} ++ ++static struct tc_action_ops act_connmark_ops = { ++	.kind		=	"connmark", ++	.hinfo		=	&connmark_hash_info, ++	.type		=	TCA_ACT_CONNMARK, ++	.capab		=	TCA_CAP_NONE, ++	.owner		=	THIS_MODULE, ++	.act		=	tcf_connmark, ++	.dump		=	tcf_connmark_dump, ++	.cleanup	=	tcf_connmark_cleanup, ++	.init		=	tcf_connmark_init, ++	.walk		=	tcf_generic_walker, ++}; ++ ++MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); ++MODULE_DESCRIPTION("Connection tracking mark restoring"); ++MODULE_LICENSE("GPL"); ++ ++static int __init connmark_init_module(void) ++{ ++	return tcf_register_action(&act_connmark_ops); ++} ++ ++static void __exit connmark_cleanup_module(void) ++{ ++	tcf_unregister_action(&act_connmark_ops); ++} ++ ++module_init(connmark_init_module); ++module_exit(connmark_cleanup_module); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -549,6 +549,18 @@ + 	  To compile this code as a module, choose M here: the + 	  module will be called act_skbedit. +  ++config NET_ACT_CONNMARK ++        tristate "Connection Tracking Marking" ++        depends on NET_CLS_ACT ++        depends on NF_CONNTRACK ++        ---help--- ++	  Say Y here to restore the connmark from a scheduler action ++ ++	  If unsure, say N. ++ ++	  To compile this code as a module, choose M here: the ++	  module will be called act_connmark. ++ + config NET_CLS_IND + 	bool "Incoming device classification" + 	depends on NET_CLS_U32 || NET_CLS_FW +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -15,6 +15,7 @@ + obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o + obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o + obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o ++obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o + obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o + obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o + obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o diff --git a/target/linux/generic/patches-2.6.36/290-sched_act_connmark.patch b/target/linux/generic/patches-2.6.36/290-sched_act_connmark.patch new file mode 100644 index 000000000..e02d1bc31 --- /dev/null +++ b/target/linux/generic/patches-2.6.36/290-sched_act_connmark.patch @@ -0,0 +1,171 @@ +--- /dev/null ++++ b/net/sched/act_connmark.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <linux/rtnetlink.h> ++#include <linux/pkt_cls.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/netlink.h> ++#include <net/pkt_sched.h> ++#include <net/act_api.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_core.h> ++ ++#define TCA_ACT_CONNMARK	20 ++ ++#define CONNMARK_TAB_MASK     3 ++static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; ++static u32 connmark_idx_gen; ++static DEFINE_RWLOCK(connmark_lock); ++ ++static struct tcf_hashinfo connmark_hash_info = { ++	.htab	=	tcf_connmark_ht, ++	.hmask	=	CONNMARK_TAB_MASK, ++	.lock	=	&connmark_lock, ++}; ++ ++static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, ++		       struct tcf_result *res) ++{ ++	struct nf_conn *c; ++	enum ip_conntrack_info ctinfo; ++	int proto; ++	int r; ++ ++	if (skb->protocol == htons(ETH_P_IP)) { ++		if (skb->len < sizeof(struct iphdr)) ++			goto out; ++		proto = PF_INET; ++	} else if (skb->protocol == htons(ETH_P_IPV6)) { ++		if (skb->len < sizeof(struct ipv6hdr)) ++			goto out; ++		proto = PF_INET6; ++	} else ++		goto out; ++ ++	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); ++	if (r != NF_ACCEPT) ++		goto out; ++ ++	c = nf_ct_get(skb, &ctinfo); ++	if (!c) ++		goto out; ++ ++	skb->mark = c->mark; ++	nf_conntrack_put(skb->nfct); ++	skb->nfct = NULL; ++ ++out: ++	return TC_ACT_PIPE; ++} ++ ++static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, ++			 struct tc_action *a, int ovr, int bind) ++{ ++	struct tcf_common *pc; ++ ++	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, ++			     &connmark_idx_gen, &connmark_hash_info); ++	if (IS_ERR(pc)) ++	    return PTR_ERR(pc); ++ ++	tcf_hash_insert(pc, &connmark_hash_info); ++ ++	return ACT_P_CREATED; ++} ++ ++static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) ++{ ++	if (a->priv) ++		return tcf_hash_release(a->priv, bind, &connmark_hash_info); ++	return 0; ++} ++ ++static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ++				int bind, int ref) ++{ ++	return skb->len; ++} ++ ++static struct tc_action_ops act_connmark_ops = { ++	.kind		=	"connmark", ++	.hinfo		=	&connmark_hash_info, ++	.type		=	TCA_ACT_CONNMARK, ++	.capab		=	TCA_CAP_NONE, ++	.owner		=	THIS_MODULE, ++	.act		=	tcf_connmark, ++	.dump		=	tcf_connmark_dump, ++	.cleanup	=	tcf_connmark_cleanup, ++	.init		=	tcf_connmark_init, ++	.walk		=	tcf_generic_walker, ++}; ++ ++MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); ++MODULE_DESCRIPTION("Connection tracking mark restoring"); ++MODULE_LICENSE("GPL"); ++ ++static int __init connmark_init_module(void) ++{ ++	return tcf_register_action(&act_connmark_ops); ++} ++ ++static void __exit connmark_cleanup_module(void) ++{ ++	tcf_unregister_action(&act_connmark_ops); ++} ++ ++module_init(connmark_init_module); ++module_exit(connmark_cleanup_module); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -549,6 +549,18 @@ + 	  To compile this code as a module, choose M here: the + 	  module will be called act_skbedit. +  ++config NET_ACT_CONNMARK ++        tristate "Connection Tracking Marking" ++        depends on NET_CLS_ACT ++        depends on NF_CONNTRACK ++        ---help--- ++	  Say Y here to restore the connmark from a scheduler action ++ ++	  If unsure, say N. ++ ++	  To compile this code as a module, choose M here: the ++	  module will be called act_connmark. ++ + config NET_CLS_IND + 	bool "Incoming device classification" + 	depends on NET_CLS_U32 || NET_CLS_FW +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -15,6 +15,7 @@ + obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o + obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o + obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o ++obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o + obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o + obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o + obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o diff --git a/target/linux/generic/patches-2.6.37/290-sched_act_connmark.patch b/target/linux/generic/patches-2.6.37/290-sched_act_connmark.patch new file mode 100644 index 000000000..013c116c4 --- /dev/null +++ b/target/linux/generic/patches-2.6.37/290-sched_act_connmark.patch @@ -0,0 +1,171 @@ +--- /dev/null ++++ b/net/sched/act_connmark.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <linux/rtnetlink.h> ++#include <linux/pkt_cls.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/netlink.h> ++#include <net/pkt_sched.h> ++#include <net/act_api.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_core.h> ++ ++#define TCA_ACT_CONNMARK	20 ++ ++#define CONNMARK_TAB_MASK     3 ++static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; ++static u32 connmark_idx_gen; ++static DEFINE_RWLOCK(connmark_lock); ++ ++static struct tcf_hashinfo connmark_hash_info = { ++	.htab	=	tcf_connmark_ht, ++	.hmask	=	CONNMARK_TAB_MASK, ++	.lock	=	&connmark_lock, ++}; ++ ++static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, ++		       struct tcf_result *res) ++{ ++	struct nf_conn *c; ++	enum ip_conntrack_info ctinfo; ++	int proto; ++	int r; ++ ++	if (skb->protocol == htons(ETH_P_IP)) { ++		if (skb->len < sizeof(struct iphdr)) ++			goto out; ++		proto = PF_INET; ++	} else if (skb->protocol == htons(ETH_P_IPV6)) { ++		if (skb->len < sizeof(struct ipv6hdr)) ++			goto out; ++		proto = PF_INET6; ++	} else ++		goto out; ++ ++	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); ++	if (r != NF_ACCEPT) ++		goto out; ++ ++	c = nf_ct_get(skb, &ctinfo); ++	if (!c) ++		goto out; ++ ++	skb->mark = c->mark; ++	nf_conntrack_put(skb->nfct); ++	skb->nfct = NULL; ++ ++out: ++	return TC_ACT_PIPE; ++} ++ ++static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, ++			 struct tc_action *a, int ovr, int bind) ++{ ++	struct tcf_common *pc; ++ ++	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, ++			     &connmark_idx_gen, &connmark_hash_info); ++	if (IS_ERR(pc)) ++	    return PTR_ERR(pc); ++ ++	tcf_hash_insert(pc, &connmark_hash_info); ++ ++	return ACT_P_CREATED; ++} ++ ++static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) ++{ ++	if (a->priv) ++		return tcf_hash_release(a->priv, bind, &connmark_hash_info); ++	return 0; ++} ++ ++static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ++				int bind, int ref) ++{ ++	return skb->len; ++} ++ ++static struct tc_action_ops act_connmark_ops = { ++	.kind		=	"connmark", ++	.hinfo		=	&connmark_hash_info, ++	.type		=	TCA_ACT_CONNMARK, ++	.capab		=	TCA_CAP_NONE, ++	.owner		=	THIS_MODULE, ++	.act		=	tcf_connmark, ++	.dump		=	tcf_connmark_dump, ++	.cleanup	=	tcf_connmark_cleanup, ++	.init		=	tcf_connmark_init, ++	.walk		=	tcf_generic_walker, ++}; ++ ++MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); ++MODULE_DESCRIPTION("Connection tracking mark restoring"); ++MODULE_LICENSE("GPL"); ++ ++static int __init connmark_init_module(void) ++{ ++	return tcf_register_action(&act_connmark_ops); ++} ++ ++static void __exit connmark_cleanup_module(void) ++{ ++	tcf_unregister_action(&act_connmark_ops); ++} ++ ++module_init(connmark_init_module); ++module_exit(connmark_cleanup_module); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -559,6 +559,18 @@ + 	  To compile this code as a module, choose M here: the + 	  module will be called act_csum. +  ++config NET_ACT_CONNMARK ++        tristate "Connection Tracking Marking" ++        depends on NET_CLS_ACT ++        depends on NF_CONNTRACK ++        ---help--- ++	  Say Y here to restore the connmark from a scheduler action ++ ++	  If unsure, say N. ++ ++	  To compile this code as a module, choose M here: the ++	  module will be called act_connmark. ++ + config NET_CLS_IND + 	bool "Incoming device classification" + 	depends on NET_CLS_U32 || NET_CLS_FW +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -16,6 +16,7 @@ + obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o + obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o + obj-$(CONFIG_NET_ACT_CSUM)	+= act_csum.o ++obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o + obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o + obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o + obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o diff --git a/target/linux/generic/patches-2.6.38/290-sched_act_connmark.patch b/target/linux/generic/patches-2.6.38/290-sched_act_connmark.patch new file mode 100644 index 000000000..013c116c4 --- /dev/null +++ b/target/linux/generic/patches-2.6.38/290-sched_act_connmark.patch @@ -0,0 +1,171 @@ +--- /dev/null ++++ b/net/sched/act_connmark.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <linux/rtnetlink.h> ++#include <linux/pkt_cls.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/netlink.h> ++#include <net/pkt_sched.h> ++#include <net/act_api.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_core.h> ++ ++#define TCA_ACT_CONNMARK	20 ++ ++#define CONNMARK_TAB_MASK     3 ++static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; ++static u32 connmark_idx_gen; ++static DEFINE_RWLOCK(connmark_lock); ++ ++static struct tcf_hashinfo connmark_hash_info = { ++	.htab	=	tcf_connmark_ht, ++	.hmask	=	CONNMARK_TAB_MASK, ++	.lock	=	&connmark_lock, ++}; ++ ++static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, ++		       struct tcf_result *res) ++{ ++	struct nf_conn *c; ++	enum ip_conntrack_info ctinfo; ++	int proto; ++	int r; ++ ++	if (skb->protocol == htons(ETH_P_IP)) { ++		if (skb->len < sizeof(struct iphdr)) ++			goto out; ++		proto = PF_INET; ++	} else if (skb->protocol == htons(ETH_P_IPV6)) { ++		if (skb->len < sizeof(struct ipv6hdr)) ++			goto out; ++		proto = PF_INET6; ++	} else ++		goto out; ++ ++	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); ++	if (r != NF_ACCEPT) ++		goto out; ++ ++	c = nf_ct_get(skb, &ctinfo); ++	if (!c) ++		goto out; ++ ++	skb->mark = c->mark; ++	nf_conntrack_put(skb->nfct); ++	skb->nfct = NULL; ++ ++out: ++	return TC_ACT_PIPE; ++} ++ ++static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, ++			 struct tc_action *a, int ovr, int bind) ++{ ++	struct tcf_common *pc; ++ ++	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, ++			     &connmark_idx_gen, &connmark_hash_info); ++	if (IS_ERR(pc)) ++	    return PTR_ERR(pc); ++ ++	tcf_hash_insert(pc, &connmark_hash_info); ++ ++	return ACT_P_CREATED; ++} ++ ++static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) ++{ ++	if (a->priv) ++		return tcf_hash_release(a->priv, bind, &connmark_hash_info); ++	return 0; ++} ++ ++static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ++				int bind, int ref) ++{ ++	return skb->len; ++} ++ ++static struct tc_action_ops act_connmark_ops = { ++	.kind		=	"connmark", ++	.hinfo		=	&connmark_hash_info, ++	.type		=	TCA_ACT_CONNMARK, ++	.capab		=	TCA_CAP_NONE, ++	.owner		=	THIS_MODULE, ++	.act		=	tcf_connmark, ++	.dump		=	tcf_connmark_dump, ++	.cleanup	=	tcf_connmark_cleanup, ++	.init		=	tcf_connmark_init, ++	.walk		=	tcf_generic_walker, ++}; ++ ++MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); ++MODULE_DESCRIPTION("Connection tracking mark restoring"); ++MODULE_LICENSE("GPL"); ++ ++static int __init connmark_init_module(void) ++{ ++	return tcf_register_action(&act_connmark_ops); ++} ++ ++static void __exit connmark_cleanup_module(void) ++{ ++	tcf_unregister_action(&act_connmark_ops); ++} ++ ++module_init(connmark_init_module); ++module_exit(connmark_cleanup_module); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -559,6 +559,18 @@ + 	  To compile this code as a module, choose M here: the + 	  module will be called act_csum. +  ++config NET_ACT_CONNMARK ++        tristate "Connection Tracking Marking" ++        depends on NET_CLS_ACT ++        depends on NF_CONNTRACK ++        ---help--- ++	  Say Y here to restore the connmark from a scheduler action ++ ++	  If unsure, say N. ++ ++	  To compile this code as a module, choose M here: the ++	  module will be called act_connmark. ++ + config NET_CLS_IND + 	bool "Incoming device classification" + 	depends on NET_CLS_U32 || NET_CLS_FW +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -16,6 +16,7 @@ + obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o + obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o + obj-$(CONFIG_NET_ACT_CSUM)	+= act_csum.o ++obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o + obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o + obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o + obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o | 
