This allows hlist_unhashed() to be used to find out if a flow has been
removed from the flow tables.  Both nodes need to be checked, though.

Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 datapath/flow_table.c |    5 ++++-
 datapath/flow_table.h |    7 +++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/datapath/flow_table.c b/datapath/flow_table.c
index a680895..8724520 100644
--- a/datapath/flow_table.c
+++ b/datapath/flow_table.c
@@ -505,7 +505,10 @@ void ovs_flow_tbl_remove(struct flow_table *table, struct 
sw_flow *flow)
        struct table_instance *ti = ovsl_dereference(table->ti);
 
        BUG_ON(table->count == 0);
-       hlist_del_rcu(&flow->hash_node[ti->node_ver]);
+       hlist_del_init_rcu(&flow->hash_node[ti->node_ver]);
+       /* Clear both nodes, so that hlist_unhashed() can be used to check
+        * if the flow has been removed from the table(s). */
+       INIT_HLIST_NODE(&flow->hash_node[!ti->node_ver]);
        table->count--;
 
        /* RCU delete the mask. 'flow->mask' is not NULLed, as it should be
diff --git a/datapath/flow_table.h b/datapath/flow_table.h
index ca8a582..7067c66 100644
--- a/datapath/flow_table.h
+++ b/datapath/flow_table.h
@@ -82,4 +82,11 @@ bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow,
 
 void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
                       const struct sw_flow_mask *mask);
+
+/* Return true if flow has been removed from the flow table. */
+static inline bool ovs_flow_removed(const struct sw_flow *flow)
+{
+       return hlist_unhashed(&flow->hash_node[0])
+               && hlist_unhashed(&flow->hash_node[1]);
+}
 #endif /* flow_table.h */
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to