From: Daniel Wagner <[email protected]>

Move the hook update part into its own function, so we have
one function for updating the hooks when inserting a rule
and one for updating the hoooks when removing a rule.

Add some comments to explain what's happening.
---
 src/iptables.c | 73 ++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 28 deletions(-)

diff --git a/src/iptables.c b/src/iptables.c
index 65327df..5349562 100644
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -761,6 +761,26 @@ static void insert_update_hooks(struct connman_iptables 
*table, GList *chain_hea
        }
 }
 
+static void delete_update_hooks(struct connman_iptables *table, GList 
*chain_tail,
+                               int removed)
+{
+       struct connman_iptables_entry *e;
+       GList *list;
+
+       e = chain_tail->data;
+       table->underflow[e->builtin] -= removed;
+
+       for (list = chain_tail->next; list; list = list->next) {
+               e = list->data;
+
+               if (e->builtin < 0)
+                       continue;
+
+               table->hook_entry[e->builtin] -= removed;
+               table->underflow[e->builtin] -= removed;
+       }
+}
+
 static struct ipt_entry *prepare_rule_inclusion(struct connman_iptables *table,
                                struct ipt_ip *ip, const char *chain_name,
                                const char *target_name,
@@ -1040,43 +1060,40 @@ static int iptables_delete_rule(struct connman_iptables 
*table,
 
        list = find_existing_rule(table, ip, chain_name, target_name,
                                                        xt_t, xt_m, xt_rm);
-       if (list == NULL)
+       if (list == NULL || list->data == NULL)
                return -EINVAL;
 
-       entry = chain_head->data;
-       builtin = entry->builtin;
+       if (list == chain_head) {
+               /*
+                * In case the chain head is removed, move the
+                * built in marker to the new chain head
+                */
+               entry = chain_head->data;
+               builtin = entry->builtin;
 
-       entry = list->data;
-       if (entry == NULL)
-               return -EINVAL;
+               chain_head = chain_head->next;
+
+               entry = chain_head->data;
+               entry->builtin = builtin;
+       }
 
-       /* We have deleted a rule,
-        * all references should be bumped accordingly */
+       /*
+        * We have deleted a rule, all references should be bumped
+        * accordingly
+        */
        if (list->next != NULL)
                update_targets_reference(table, list->next->data,
                                                list->data, TRUE);
 
-       removed += remove_table_entry(table, entry);
-
-       if (builtin >= 0) {
-               list = list->next;
-               if (list) {
-                       entry = list->data;
-                       entry->builtin = builtin;
-               }
-
-               table->underflow[builtin] -= removed;
-               for (list = chain_tail; list; list = list->next) {
-                       entry = list->data;
-
-                       builtin = entry->builtin;
-                       if (builtin < 0)
-                               continue;
+       removed += remove_table_entry(table, list->data);
 
-                       table->hook_entry[builtin] -= removed;
-                       table->underflow[builtin] -= removed;
-               }
-       }
+       /*
+        * We need to update the hooks if the rule was part of a built
+        * in chain.
+        */
+       entry = chain_head->data;
+       if (entry->builtin >= 0)
+               delete_update_hooks(table, chain_head, removed);
 
        update_offsets(table);
 
-- 
1.8.1.3.566.gaa39828

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to