Commit fcf4a436 authored by Catalin Boie's avatar Catalin Boie Committed by David S. Miller

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent 555983d6
...@@ -192,6 +192,7 @@ enum ...@@ -192,6 +192,7 @@ enum
TCA_U32_ACT, TCA_U32_ACT,
TCA_U32_INDEV, TCA_U32_INDEV,
TCA_U32_PCNT, TCA_U32_PCNT,
TCA_U32_MARK,
__TCA_U32_MAX __TCA_U32_MAX
}; };
......
...@@ -334,6 +334,18 @@ config NET_CLS_IND ...@@ -334,6 +334,18 @@ config NET_CLS_IND
Requires a new iproute2 Requires a new iproute2
You MUST NOT turn this on if you dont have an update 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 config NET_CLS_RSVP
tristate "Special RSVP classifier" tristate "Special RSVP classifier"
depends on NET_CLS && NET_QOS depends on NET_CLS && NET_QOS
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* JHS: We should remove the CONFIG_NET_CLS_IND from here * JHS: We should remove the CONFIG_NET_CLS_IND from here
* eventually when the meta match extension is made available * 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> #include <asm/uaccess.h>
...@@ -58,6 +59,13 @@ ...@@ -58,6 +59,13 @@
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
struct tc_u32_mark
{
__u32 val;
__u32 mask;
__u32 success;
};
struct tc_u_knode struct tc_u_knode
{ {
struct tc_u_knode *next; struct tc_u_knode *next;
...@@ -78,6 +86,9 @@ struct tc_u_knode ...@@ -78,6 +86,9 @@ struct tc_u_knode
struct tc_u_hnode *ht_down; struct tc_u_hnode *ht_down;
#ifdef CONFIG_CLS_U32_PERF #ifdef CONFIG_CLS_U32_PERF
struct tc_u32_pcnt *pf; struct tc_u32_pcnt *pf;
#endif
#ifdef CONFIG_CLS_U32_MARK
struct tc_u32_mark mark;
#endif #endif
struct tc_u32_sel sel; struct tc_u32_sel sel;
}; };
...@@ -139,6 +150,16 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re ...@@ -139,6 +150,16 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
n->pf->rcnt +=1; n->pf->rcnt +=1;
j = 0; j = 0;
#endif #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++) { for (i = n->sel.nkeys; i>0; i--, key++) {
if ((*(u32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { 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, ...@@ -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_hnode *ht;
struct tc_u_knode *n; struct tc_u_knode *n;
struct tc_u32_sel *s; struct tc_u32_sel *s;
struct tc_u32_mark *mark;
struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *opt = tca[TCA_OPTIONS-1];
struct rtattr *tb[TCA_U32_MAX]; struct rtattr *tb[TCA_U32_MAX];
u32 htid; u32 htid;
...@@ -657,6 +679,17 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, ...@@ -657,6 +679,17 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
} }
n->fshift = i; 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]); err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]);
if (err == 0) { if (err == 0) {
struct tc_u_knode **ins; struct tc_u_knode **ins;
...@@ -744,6 +777,12 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, ...@@ -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); RTA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid);
if (n->ht_down) if (n->ht_down)
RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle); 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 #ifdef CONFIG_NET_CLS_ACT
if (tcf_dump_act(skb, n->action, TCA_U32_ACT, TCA_U32_POLICE) < 0) if (tcf_dump_act(skb, n->action, TCA_U32_ACT, TCA_U32_POLICE) < 0)
goto rtattr_failure; goto rtattr_failure;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment