Root/target/linux/generic/patches-3.0/621-sched_act_connmark.patch

1--- /dev/null
2+++ b/net/sched/act_connmark.c
3@@ -0,0 +1,137 @@
4+/*
5+ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms and conditions of the GNU General Public License,
9+ * version 2, as published by the Free Software Foundation.
10+ *
11+ * This program is distributed in the hope it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+ * more details.
15+ *
16+ * You should have received a copy of the GNU General Public License along with
17+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18+ * Place - Suite 330, Boston, MA 02111-1307 USA.
19+ */
20+
21+#include <linux/module.h>
22+#include <linux/init.h>
23+#include <linux/kernel.h>
24+#include <linux/skbuff.h>
25+#include <linux/rtnetlink.h>
26+#include <linux/pkt_cls.h>
27+#include <linux/ip.h>
28+#include <linux/ipv6.h>
29+#include <net/netlink.h>
30+#include <net/pkt_sched.h>
31+#include <net/act_api.h>
32+
33+#include <net/netfilter/nf_conntrack.h>
34+#include <net/netfilter/nf_conntrack_core.h>
35+
36+#define TCA_ACT_CONNMARK 20
37+
38+#define CONNMARK_TAB_MASK 3
39+static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1];
40+static u32 connmark_idx_gen;
41+static DEFINE_RWLOCK(connmark_lock);
42+
43+static struct tcf_hashinfo connmark_hash_info = {
44+ .htab = tcf_connmark_ht,
45+ .hmask = CONNMARK_TAB_MASK,
46+ .lock = &connmark_lock,
47+};
48+
49+static int tcf_connmark(struct sk_buff *skb, struct tc_action *a,
50+ struct tcf_result *res)
51+{
52+ struct nf_conn *c;
53+ enum ip_conntrack_info ctinfo;
54+ int proto;
55+ int r;
56+
57+ if (skb->protocol == htons(ETH_P_IP)) {
58+ if (skb->len < sizeof(struct iphdr))
59+ goto out;
60+ proto = PF_INET;
61+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
62+ if (skb->len < sizeof(struct ipv6hdr))
63+ goto out;
64+ proto = PF_INET6;
65+ } else
66+ goto out;
67+
68+ r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb);
69+ if (r != NF_ACCEPT)
70+ goto out;
71+
72+ c = nf_ct_get(skb, &ctinfo);
73+ if (!c)
74+ goto out;
75+
76+ skb->mark = c->mark;
77+ nf_conntrack_put(skb->nfct);
78+ skb->nfct = NULL;
79+
80+out:
81+ return TC_ACT_PIPE;
82+}
83+
84+static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est,
85+ struct tc_action *a, int ovr, int bind)
86+{
87+ struct tcf_common *pc;
88+
89+ pc = tcf_hash_create(0, est, a, sizeof(*pc), bind,
90+ &connmark_idx_gen, &connmark_hash_info);
91+ if (IS_ERR(pc))
92+ return PTR_ERR(pc);
93+
94+ tcf_hash_insert(pc, &connmark_hash_info);
95+
96+ return ACT_P_CREATED;
97+}
98+
99+static inline int tcf_connmark_cleanup(struct tc_action *a, int bind)
100+{
101+ if (a->priv)
102+ return tcf_hash_release(a->priv, bind, &connmark_hash_info);
103+ return 0;
104+}
105+
106+static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
107+ int bind, int ref)
108+{
109+ return skb->len;
110+}
111+
112+static struct tc_action_ops act_connmark_ops = {
113+ .kind = "connmark",
114+ .hinfo = &connmark_hash_info,
115+ .type = TCA_ACT_CONNMARK,
116+ .capab = TCA_CAP_NONE,
117+ .owner = THIS_MODULE,
118+ .act = tcf_connmark,
119+ .dump = tcf_connmark_dump,
120+ .cleanup = tcf_connmark_cleanup,
121+ .init = tcf_connmark_init,
122+ .walk = tcf_generic_walker,
123+};
124+
125+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
126+MODULE_DESCRIPTION("Connection tracking mark restoring");
127+MODULE_LICENSE("GPL");
128+
129+static int __init connmark_init_module(void)
130+{
131+ return tcf_register_action(&act_connmark_ops);
132+}
133+
134+static void __exit connmark_cleanup_module(void)
135+{
136+ tcf_unregister_action(&act_connmark_ops);
137+}
138+
139+module_init(connmark_init_module);
140+module_exit(connmark_cleanup_module);
141--- a/net/sched/Kconfig
142+++ b/net/sched/Kconfig
143@@ -602,6 +602,19 @@ config NET_ACT_CSUM
144       To compile this code as a module, choose M here: the
145       module will be called act_csum.
146 
147+config NET_ACT_CONNMARK
148+ tristate "Connection Tracking Marking"
149+ depends on NET_CLS_ACT
150+ depends on NF_CONNTRACK
151+ depends on NF_CONNTRACK_MARK
152+ ---help---
153+ Say Y here to restore the connmark from a scheduler action
154+
155+ If unsure, say N.
156+
157+ To compile this code as a module, choose M here: the
158+ module will be called act_connmark.
159+
160 config NET_CLS_IND
161     bool "Incoming device classification"
162     depends on NET_CLS_U32 || NET_CLS_FW
163--- a/net/sched/Makefile
164+++ b/net/sched/Makefile
165@@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit
166 obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
167 obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
168 obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o
169+obj-$(CONFIG_NET_ACT_CONNMARK) += act_connmark.o
170 obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
171 obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
172 obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
173

Archive Download this file



interactive