This API is used to replace the old action in hash table
with the new one. It is used by the following patch.

Cc: Jamal Hadi Salim <j...@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangc...@gmail.com>
---
 include/net/act_api.h |  2 ++
 net/sched/act_api.c   | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 82f3c91..a374bab 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -164,6 +164,8 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, 
struct nlattr *est,
                    bool cpustats);
 void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);
 void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);
+void tcf_hash_replace(struct tc_action_net *tn, struct tc_action **old,
+                     struct tc_action *new, int bind);
 
 int __tcf_hash_release(struct tc_action *a, bool bind, bool strict);
 
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 06111aa..db907e5 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -306,6 +306,26 @@ void tcf_hash_insert(struct tc_action_net *tn, struct 
tc_action *a)
 }
 EXPORT_SYMBOL(tcf_hash_insert);
 
+void tcf_hash_replace(struct tc_action_net *tn, struct tc_action **old,
+                     struct tc_action *new, int bind)
+{
+       struct tcf_hashinfo *hinfo = tn->hinfo;
+       unsigned int h = tcf_hash(new->tcfa_index, hinfo->hmask);
+
+       spin_lock_bh(&hinfo->lock);
+       if (*old)
+               hlist_replace_rcu(&(*old)->tcfa_head, &new->tcfa_head);
+       else
+               hlist_add_head_rcu(&new->tcfa_head, &hinfo->htab[h]);
+       spin_unlock_bh(&hinfo->lock);
+
+       if (*old)
+               tcf_hash_release(*old, bind);
+
+       rcu_assign_pointer(*old, new);
+}
+EXPORT_SYMBOL(tcf_hash_replace);
+
 void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
                          struct tcf_hashinfo *hinfo)
 {
-- 
2.1.0

Reply via email to