Added 'prev' field to make double-linked list.

Signed-off-by: Vadim Kochan <[email protected]>
---
 flowtop.c | 68 +++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 38 insertions(+), 30 deletions(-)

diff --git a/flowtop.c b/flowtop.c
index 6fd3c6a..cf9ac6f 100644
--- a/flowtop.c
+++ b/flowtop.c
@@ -65,7 +65,7 @@ struct flow_entry {
        char city_src[128], city_dst[128];
        char rev_dns_src[256], rev_dns_dst[256];
        char procname[256];
-       struct flow_entry *next;
+       struct flow_entry *next, *prev;
        int inode;
        unsigned int procnum;
        bool is_visible;
@@ -343,6 +343,26 @@ static inline bool nfct_is_dns(const struct nf_conntrack 
*ct)
        return ntohs(port_src) == 53 || ntohs(port_dst) == 53;
 }
 
+static void flow_list_insert_entry(struct flow_list *fl,
+                                  struct flow_entry *head, struct flow_entry 
*n)
+{
+       struct flow_entry *next = NULL;
+
+       if (head) {
+               next = rcu_dereference(head->next);
+               rcu_assign_pointer(head->next, n);
+       } else {
+               next = rcu_dereference(fl->head);
+               rcu_assign_pointer(fl->head, n);
+       }
+
+       if (next)
+               rcu_assign_pointer(next->prev, n);
+
+       rcu_assign_pointer(n->prev, head);
+       rcu_assign_pointer(n->next, next);
+}
+
 static void flow_list_new_entry(struct flow_list *fl, const struct 
nf_conntrack *ct)
 {
        struct flow_entry *n;
@@ -361,8 +381,7 @@ static void flow_list_new_entry(struct flow_list *fl, const 
struct nf_conntrack
        flow_entry_from_ct(n, ct);
        flow_entry_get_extended(n);
 
-       rcu_assign_pointer(n->next, fl->head);
-       rcu_assign_pointer(fl->head, n);
+       flow_list_insert_entry(fl, NULL, n);
 }
 
 static struct flow_entry *flow_list_find_id(struct flow_list *fl,
@@ -380,22 +399,21 @@ static struct flow_entry *flow_list_find_id(struct 
flow_list *fl,
        return NULL;
 }
 
-static struct flow_entry *flow_list_find_prev_id(const struct flow_list *fl,
-                                                uint32_t id)
+static void flow_list_remove_entry(struct flow_list *fl, struct flow_entry *n)
 {
-       struct flow_entry *prev = rcu_dereference(fl->head), *next;
-
-       if (prev->flow_id == id)
-               return NULL;
+       struct flow_entry *prev = rcu_dereference(n->prev);
+       struct flow_entry *next = rcu_dereference(n->next);
 
-       while ((next = rcu_dereference(prev->next)) != NULL) {
-               if (next->flow_id == id)
-                       return prev;
+       if (!prev && !next)
+               return;
 
-               prev = next;
-       }
+       if (prev)
+               rcu_assign_pointer(prev->next, next);
+       else
+               rcu_assign_pointer(fl->head, next);
 
-       return NULL;
+       if (next)
+               rcu_assign_pointer(next->prev, prev);
 }
 
 static void flow_list_update_entry(struct flow_list *fl,
@@ -415,23 +433,13 @@ static void flow_list_update_entry(struct flow_list *fl,
 static void flow_list_destroy_entry(struct flow_list *fl,
                                    const struct nf_conntrack *ct)
 {
-       struct flow_entry *n1, *n2;
+       struct flow_entry *n;
        uint32_t id = nfct_get_attr_u32(ct, ATTR_ID);
 
-       n1 = flow_list_find_id(fl, id);
-       if (n1) {
-               n2 = flow_list_find_prev_id(fl, id);
-               if (n2) {
-                       rcu_assign_pointer(n2->next, n1->next);
-                       n1->next = NULL;
-
-                       flow_entry_xfree(n1);
-               } else {
-                       struct flow_entry *next = fl->head->next;
-
-                       flow_entry_xfree(fl->head);
-                       fl->head = next;
-               }
+       n = flow_list_find_id(fl, id);
+       if (n) {
+               flow_list_remove_entry(fl, n);
+               flow_entry_xfree(n);
        }
 }
 
-- 
2.6.1

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to