struct rcu_head                 tcfa_rcu;
        struct gnet_stats_basic_cpu __percpu *cpu_bstats;
        struct gnet_stats_queue __percpu *cpu_qstats;
+       struct tc_cookie        *act_cookie;
 };
 #define tcf_head       common.tcfa_head
 #define tcf_index      common.tcfa_index
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/sch_generic.h>
+#include <net/pkt_cls.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 
 
        free_percpu(p->cpu_bstats);
        free_percpu(p->cpu_qstats);
+
+       if (p->act_cookie) {
+               kfree(p->act_cookie->data);
+               kfree(p->act_cookie);
+       }
+
        kfree(p);
 }
 
                goto nla_put_failure;
        if (tcf_action_copy_stats(skb, a, 0))
                goto nla_put_failure;
+       if (a->act_cookie) {
+               if (nla_put(skb, TCA_ACT_COOKIE, a->act_cookie->len,
+                           a->act_cookie->data))
+                       goto nla_put_failure;
+       }
+
        nest = nla_nest_start(skb, TCA_OPTIONS);
        if (nest == NULL)
                goto nla_put_failure;
        return err;
 }
 
+int nla_memdup_cookie(struct tc_action *a, struct nlattr **tb)
+{
+       a->act_cookie = kzalloc(sizeof(*a->act_cookie), GFP_KERNEL);
+       if (!a->act_cookie)
+               return -ENOMEM;
+
+       a->act_cookie->data = nla_memdup(tb[TCA_ACT_COOKIE], GFP_KERNEL);
+       if (!a->act_cookie->data) {
+               kfree(a->act_cookie);
+               return -ENOMEM;
+       }
+       a->act_cookie->len = nla_len(tb[TCA_ACT_COOKIE]);
+
+       return 0;
+}
+
 struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
                                    struct nlattr *est, char *name, int ovr,
                                    int bind)
        if (err < 0)
                goto err_mod;
 
+       if (tb[TCA_ACT_COOKIE]) {
+               int cklen = nla_len(tb[TCA_ACT_COOKIE]);
+
+               if (cklen > TC_COOKIE_MAX_SIZE) {
+                       err = -EINVAL;
+                       tcf_hash_release(a, bind);
+                       goto err_mod;
+               }
+
+               err = nla_memdup_cookie(a, tb);
+               if (err < 0) {
+                       tcf_hash_release(a, bind);
+                       goto err_mod;
+               }
+       }
+
        /* module count goes up only when brand new policy is created
         * if it exists and is only bound to in a_o->init() then
         * ACT_P_CREATED is not returned (a zero is).