diff --git a/include/net/act_api.h b/include/net/act_api.h index 1d71644..f299ed3 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -41,6 +41,7 @@ struct tc_action { struct rcu_head tcfa_rcu; struct gnet_stats_basic_cpu __percpu *cpu_bstats; struct gnet_stats_queue __percpu *cpu_qstats; + u64 cookie; }; #define tcf_head common.tcfa_head #define tcf_index common.tcfa_index diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index cb4bcdc..2e968ee 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -67,6 +67,7 @@ enum { TCA_ACT_INDEX, TCA_ACT_STATS, TCA_ACT_PAD, + TCA_ACT_COOKIE, __TCA_ACT_MAX }; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 2095c83..97eae6b 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -26,6 +26,7 @@ #include #include #include +#include static void free_tcf(struct rcu_head *head) { @@ -467,17 +468,21 @@ int tcf_action_destroy(struct list_head *actions, int bind) return a->ops->dump(skb, a, bind, ref); } -int -tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) +int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, + int ref) { int err = -EINVAL; unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; + u64 cookie = a->cookie; if (nla_put_string(skb, TCA_KIND, a->ops->kind)) goto nla_put_failure; if (tcf_action_copy_stats(skb, a, 0)) goto nla_put_failure; + if (nla_put_u64_64bit(skb, TCA_ACT_COOKIE, cookie, TCA_ACT_PAD)) + goto nla_put_failure; + nest = nla_nest_start(skb, TCA_OPTIONS); if (nest == NULL) goto nla_put_failure; @@ -578,6 +583,11 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, if (err < 0) goto err_mod; + if (tb[TCA_ACT_COOKIE]) + a->cookie = nla_get_u64(tb[TCA_ACT_COOKIE]); + else + a->cookie = 0; /* kernel uses 0 */ + /* 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).