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.