diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/cls_flow.c | 21 | ||||
-rw-r--r-- | net/sched/em_meta.c | 17 |
2 files changed, 34 insertions, 4 deletions
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 5a7f6a3060f..971b867e048 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -19,6 +19,7 @@ #include <linux/in.h> #include <linux/ip.h> #include <linux/ipv6.h> +#include <linux/if_vlan.h> #include <net/pkt_cls.h> #include <net/ip.h> @@ -270,6 +271,15 @@ static u32 flow_get_skgid(const struct sk_buff *skb) return 0; } +static u32 flow_get_vlan_tag(const struct sk_buff *skb) +{ + u16 uninitialized_var(tag); + + if (vlan_get_tag(skb, &tag) < 0) + return 0; + return tag & VLAN_VID_MASK; +} + static u32 flow_key_get(const struct sk_buff *skb, int key) { switch (key) { @@ -305,6 +315,8 @@ static u32 flow_key_get(const struct sk_buff *skb, int key) return flow_get_skuid(skb); case FLOW_KEY_SKGID: return flow_get_skgid(skb); + case FLOW_KEY_VLAN_TAG: + return flow_get_vlan_tag(skb); default: WARN_ON(1); return 0; @@ -402,12 +414,13 @@ static int flow_change(struct tcf_proto *tp, unsigned long base, if (tb[TCA_FLOW_KEYS]) { keymask = nla_get_u32(tb[TCA_FLOW_KEYS]); - if (fls(keymask) - 1 > FLOW_KEY_MAX) - return -EOPNOTSUPP; nkeys = hweight32(keymask); if (nkeys == 0) return -EINVAL; + + if (fls(keymask) - 1 > FLOW_KEY_MAX) + return -EOPNOTSUPP; } err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); @@ -594,11 +607,11 @@ static int flow_dump(struct tcf_proto *tp, unsigned long fh, if (tcf_exts_dump(skb, &f->exts, &flow_ext_map) < 0) goto nla_put_failure; - +#ifdef CONFIG_NET_EMATCH if (f->ematches.hdr.nmatches && tcf_em_tree_dump(skb, &f->ematches, TCA_FLOW_EMATCHES) < 0) goto nla_put_failure; - +#endif nla_nest_end(skb, nest); if (tcf_exts_dump_stats(skb, &f->exts, &flow_ext_map) < 0) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index a1e5619b187..2a7e648fbcf 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -65,6 +65,7 @@ #include <linux/string.h> #include <linux/skbuff.h> #include <linux/random.h> +#include <linux/if_vlan.h> #include <linux/tc_ematch/tc_em_meta.h> #include <net/dst.h> #include <net/route.h> @@ -170,6 +171,21 @@ META_COLLECTOR(var_dev) } /************************************************************************** + * vlan tag + **************************************************************************/ + +META_COLLECTOR(int_vlan_tag) +{ + unsigned short uninitialized_var(tag); + if (vlan_get_tag(skb, &tag) < 0) + *err = -1; + else + dst->value = tag; +} + + + +/************************************************************************** * skb attributes **************************************************************************/ @@ -520,6 +536,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo), [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), + [META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag), } }; |