]> err.no Git - linux-2.6/blobdiff - net/sched/em_meta.c
mxser/mxser_new: first pass over termios reporting for the mxser cards
[linux-2.6] / net / sched / em_meta.c
index d9f487d813c4cca7711c5df819336d1ce7f19383..2a7e648fbcf44edd7ce7944fee7627f3590d434a 100644 (file)
@@ -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>
@@ -169,6 +170,21 @@ META_COLLECTOR(var_dev)
        *err = var_dev(skb->dev, dst);
 }
 
+/**************************************************************************
+ * 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),
        }
 };
 
@@ -745,6 +762,10 @@ static inline int meta_is_supported(struct meta_value *val)
        return (!meta_id(val) || meta_ops(val)->get);
 }
 
+static const struct nla_policy meta_policy[TCA_EM_META_MAX + 1] = {
+       [TCA_EM_META_HDR]       = { .len = sizeof(struct tcf_meta_hdr) },
+};
+
 static int em_meta_change(struct tcf_proto *tp, void *data, int len,
                          struct tcf_ematch *m)
 {
@@ -753,13 +774,12 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len,
        struct tcf_meta_hdr *hdr;
        struct meta_match *meta = NULL;
 
-       err = nla_parse(tb, TCA_EM_META_MAX, data, len, NULL);
+       err = nla_parse(tb, TCA_EM_META_MAX, data, len, meta_policy);
        if (err < 0)
                goto errout;
 
        err = -EINVAL;
-       if (tb[TCA_EM_META_HDR] == NULL ||
-           nla_len(tb[TCA_EM_META_HDR]) < sizeof(*hdr))
+       if (tb[TCA_EM_META_HDR] == NULL)
                goto errout;
        hdr = nla_data(tb[TCA_EM_META_HDR]);