summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Boie <util@deuroconsult.ro>2004-11-17 00:08:01 -0800
committerDavid S. Miller <davem@nuts.davemloft.net>2004-11-17 00:08:01 -0800
commitfcf4a4369976cb355092c049e30916d9706fbae0 (patch)
treea54557209b5835aa0a5d1115df3367b9f3240e54
parent555983d64332ce0f98f68dbbd8706eabd045b992 (diff)
[PKT_SCHED]: Allow using nfmark as key in U32 classifier.
Signed-off-by: Catalin(ux aka Dino) BOIE <catab at umbrella.ro> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/pkt_cls.h1
-rw-r--r--net/sched/Kconfig12
-rw-r--r--net/sched/cls_u32.c39
3 files changed, 52 insertions, 0 deletions
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 45ac289f1bbf..45ed903d247c 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -192,6 +192,7 @@ enum
TCA_U32_ACT,
TCA_U32_INDEV,
TCA_U32_PCNT,
+ TCA_U32_MARK,
__TCA_U32_MAX
};
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 2fe4fd4e34cf..b04297f5ddf8 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -334,6 +334,18 @@ config NET_CLS_IND
Requires a new iproute2
You MUST NOT turn this on if you dont have an update iproute2.
+config CLS_U32_MARK
+ bool "Use nfmark as a key in U32 classifier"
+ depends on NET_CLS_U32 && NETFILTER
+ help
+ This allows you to match mark in a u32 filter.
+ Example:
+ tc filter add dev eth0 protocol ip parent 1:0 prio 5 u32 \
+ match mark 0x0090 0xffff \
+ match ip dst 4.4.4.4 \
+ flowid 1:90
+ You must use a new iproute2 to use this feature.
+
config NET_CLS_RSVP
tristate "Special RSVP classifier"
depends on NET_CLS && NET_QOS
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 0e8505bbbb38..984e1f27b1a6 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -27,6 +27,7 @@
* JHS: We should remove the CONFIG_NET_CLS_IND from here
* eventually when the meta match extension is made available
*
+ * nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
*/
#include <asm/uaccess.h>
@@ -58,6 +59,13 @@
#include <net/pkt_cls.h>
+struct tc_u32_mark
+{
+ __u32 val;
+ __u32 mask;
+ __u32 success;
+};
+
struct tc_u_knode
{
struct tc_u_knode *next;
@@ -79,6 +87,9 @@ struct tc_u_knode
#ifdef CONFIG_CLS_U32_PERF
struct tc_u32_pcnt *pf;
#endif
+#ifdef CONFIG_CLS_U32_MARK
+ struct tc_u32_mark mark;
+#endif
struct tc_u32_sel sel;
};
@@ -139,6 +150,16 @@ next_knode:
n->pf->rcnt +=1;
j = 0;
#endif
+
+#ifdef CONFIG_CLS_U32_MARK
+ if ((skb->nfmark & n->mark.mask) != n->mark.val) {
+ n = n->next;
+ goto next_knode;
+ } else {
+ n->mark.success++;
+ }
+#endif
+
for (i = n->sel.nkeys; i>0; i--, key++) {
if ((*(u32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) {
@@ -554,6 +575,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
struct tc_u_hnode *ht;
struct tc_u_knode *n;
struct tc_u32_sel *s;
+ struct tc_u32_mark *mark;
struct rtattr *opt = tca[TCA_OPTIONS-1];
struct rtattr *tb[TCA_U32_MAX];
u32 htid;
@@ -657,6 +679,17 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
}
n->fshift = i;
}
+
+#ifdef CONFIG_CLS_U32_MARK
+ if (tb[TCA_U32_MARK-1]) {
+ if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark))
+ return -EINVAL;
+ mark = RTA_DATA(tb[TCA_U32_MARK-1]);
+ memcpy(&n->mark, mark, sizeof(struct tc_u32_mark));
+ n->mark.success = 0;
+ }
+#endif
+
err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]);
if (err == 0) {
struct tc_u_knode **ins;
@@ -744,6 +777,12 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
RTA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid);
if (n->ht_down)
RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle);
+
+#ifdef CONFIG_CLS_U32_MARK
+ if (n->mark.val || n->mark.mask)
+ RTA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark);
+#endif
+
#ifdef CONFIG_NET_CLS_ACT
if (tcf_dump_act(skb, n->action, TCA_U32_ACT, TCA_U32_POLICE) < 0)
goto rtattr_failure;