Code

libiptc: Updated from version 1.4.0 to 1.4.1.1.
authorSebastian Harl <sh@tokkee.org>
Thu, 2 Oct 2008 12:56:12 +0000 (14:56 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Fri, 3 Oct 2008 20:12:36 +0000 (22:12 +0200)
This brings the library in sync with the latest stable upstream release. Now,
libiptc.c:standard_target_map() is declared static in the upstream sources, so
we no longer need to modify that ourselves.

The update includes, amongst others, fixes for a build failure with glibc 2.8,
some compiler warnings, an incorrect ruleset dump (netfilter issue #104) and a
scalability issue for chain list "name" searching.

Signed-off-by: Sebastian Harl <sh@tokkee.org>
Signed-off-by: Florian Forster <octo@huhu.verplant.org>
src/libiptc/Makefile.am
src/libiptc/libip6tc.c
src/libiptc/libip6tc.h
src/libiptc/libiptc.c
src/libiptc/libiptc.h

index 338aecb9a16358c7fae974e9148d81d1e642a554..01657327413b7978fea3a748df36bd7f78ba09f2 100644 (file)
@@ -8,7 +8,7 @@ endif
 
 noinst_LTLIBRARIES = libiptc.la
 
-libiptc_la_CFLAGS = -DIPTABLES_VERSION=\"1.4.0\" -I$(KERNEL_DIR)/include
+libiptc_la_CFLAGS = -I$(KERNEL_DIR)/include
 libiptc_la_SOURCES = libip4tc.c libip6tc.c \
                ipt_kernel_headers.h libip6tc.h libiptc.h linux_list.h
 
index b30bb28b90f2bef0c0143410537ba9b84115cc18..276b7af8fa3769eee00157277d3f887e1e7628d0 100644 (file)
@@ -131,7 +131,7 @@ typedef unsigned int socklen_t;
 #include "libiptc.c"
 
 #define BIT6(a, l) \
- ((ntohl(a->in6_u.u6_addr32[(l) / 32]) >> (31 - ((l) & 31))) & 1)
+ ((ntohl(a->s6_addr32[(l) / 32]) >> (31 - ((l) & 31))) & 1)
 
 int
 ipv6_prefix_length(const struct in6_addr *a)
index 103267b7007e22edff845732ab0d292ed2688ce3..9253e11fa32bd5d569e88930f5e1f3a4ba3dba5d 100644 (file)
@@ -162,7 +162,7 @@ int ip6tc_set_counter(const ip6t_chainlabel chain,
 int ip6tc_commit(ip6tc_handle_t *handle);
 
 /* Get raw socket. */
-int ip6tc_get_raw_socket();
+int ip6tc_get_raw_socket(void);
 
 /* Translates errno numbers into more human-readable form than strerror. */
 const char *ip6tc_strerror(int err);
@@ -170,4 +170,6 @@ const char *ip6tc_strerror(int err);
 /* Return prefix length, or -1 if not contiguous */
 int ipv6_prefix_length(const struct in6_addr *a);
 
+extern void dump_entries6(const ip6tc_handle_t);
+
 #endif /* _LIBIP6TC_H */
index f8e88b2818c13be8d219d132c29db5f9c11166ab..11f73c378cf5c721ec93345a2c42f97aac4e9587 100644 (file)
@@ -44,6 +44,7 @@
  */
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <xtables.h>
 
 #include "linux_list.h"
 
 #define DEBUGP_C(x, args...)
 #endif
 
-#ifndef IPT_LIB_DIR
-#define IPT_LIB_DIR "/usr/local/lib/iptables"
+#ifdef DEBUG
+#define debug(x, args...)      fprintf(stderr, x, ## args)
+#else
+#define debug(x, args...)
 #endif
 
 static int sockfd = -1;
@@ -150,6 +153,11 @@ STRUCT_TC_HANDLE
        struct chain_head *chain_iterator_cur;
        struct rule_head *rule_iterator_cur;
 
+       unsigned int num_chains;         /* number of user defined chains */
+
+       struct chain_head **chain_index;   /* array for fast chain list access*/
+       unsigned int        chain_index_sz;/* size of chain index array */
+
        STRUCT_GETINFO info;
        STRUCT_GET_ENTRIES *entries;
 };
@@ -184,7 +192,7 @@ static struct rule_head *iptcc_alloc_rule(struct chain_head *c, unsigned int siz
 }
 
 /* notify us that the ruleset has been modified by the user */
-static void
+static inline void
 set_changed(TC_HANDLE_T h)
 {
        h->changed = 1;
@@ -281,12 +289,308 @@ iptcb_ent_is_hook_entry(STRUCT_ENTRY *e, TC_HANDLE_T h)
 }
 
 
+/**********************************************************************
+ * Chain index (cache utility) functions
+ **********************************************************************
+ * The chain index is an array with pointers into the chain list, with
+ * CHAIN_INDEX_BUCKET_LEN spacing.  This facilitates the ability to
+ * speedup chain list searching, by find a more optimal starting
+ * points when searching the linked list.
+ *
+ * The starting point can be found fast by using a binary search of
+ * the chain index. Thus, reducing the previous search complexity of
+ * O(n) to O(log(n/k) + k) where k is CHAIN_INDEX_BUCKET_LEN.
+ *
+ * A nice property of the chain index, is that the "bucket" list
+ * length is max CHAIN_INDEX_BUCKET_LEN (when just build, inserts will
+ * change this). Oppose to hashing, where the "bucket" list length can
+ * vary a lot.
+ */
+#ifndef CHAIN_INDEX_BUCKET_LEN
+#define CHAIN_INDEX_BUCKET_LEN 40
+#endif
+
+/* Another nice property of the chain index is that inserting/creating
+ * chains in chain list don't change the correctness of the chain
+ * index, it only causes longer lists in the buckets.
+ *
+ * To mitigate the performance penalty of longer bucket lists and the
+ * penalty of rebuilding, the chain index is rebuild only when
+ * CHAIN_INDEX_INSERT_MAX chains has been added.
+ */
+#ifndef CHAIN_INDEX_INSERT_MAX
+#define CHAIN_INDEX_INSERT_MAX 355
+#endif
+
+static inline unsigned int iptcc_is_builtin(struct chain_head *c);
+
+
+/* Use binary search in the chain index array, to find a chain_head
+ * pointer closest to the place of the searched name element.
+ *
+ * Notes that, binary search (obviously) requires that the chain list
+ * is sorted by name.
+ */
+static struct list_head *
+iptcc_bsearch_chain_index(const char *name, unsigned int *idx, TC_HANDLE_T handle)
+{
+       unsigned int pos, end;
+       int res;
+
+       struct list_head *list_pos;
+       list_pos=&handle->chains;
+
+       /* Check for empty array, e.g. no user defined chains */
+       if (handle->chain_index_sz == 0) {
+               debug("WARNING: handle->chain_index_sz == 0\n");
+               return list_pos;
+       }
+
+       /* Init */
+       end = handle->chain_index_sz;
+       pos = end / 2;
+
+       debug("bsearch Find chain:%s (pos:%d end:%d)\n", name, pos, end);
+
+       /* Loop */
+ loop:
+       if (!handle->chain_index[pos]) {
+               fprintf(stderr, "ERROR: NULL pointer chain_index[%d]\n", pos);
+               return &handle->chains; /* Be safe, return orig start pos */
+       }
+
+       res = strcmp(name, handle->chain_index[pos]->name);
+       list_pos = &handle->chain_index[pos]->list;
+       *idx = pos;
+
+       debug("bsearch Index[%d] name:%s res:%d ",
+             pos, handle->chain_index[pos]->name, res);
+
+       if (res == 0) { /* Found element, by direct hit */
+               debug("[found] Direct hit pos:%d end:%d\n", pos, end);
+               return list_pos;
+       } else if (res < 0) { /* Too far, jump back */
+               end = pos;
+               pos = pos / 2;
+
+               /* Exit case: First element of array */
+               if (end == 0) {
+                       debug("[found] Reached first array elem (end%d)\n",end);
+                       return list_pos;
+               }
+               debug("jump back to pos:%d (end:%d)\n", pos, end);
+               goto loop;
+       } else if (res > 0 ){ /* Not far enough, jump forward */
+
+               /* Exit case: Last element of array */
+               if (pos == handle->chain_index_sz-1) {
+                       debug("[found] Last array elem (end:%d)\n", end);
+                       return list_pos;
+               }
+
+               /* Exit case: Next index less, thus elem in this list section */
+               res = strcmp(name, handle->chain_index[pos+1]->name);
+               if (res < 0) {
+                       debug("[found] closest list (end:%d)\n", end);
+                       return list_pos;
+               }
+
+               pos = (pos+end)/2;
+               debug("jump forward to pos:%d (end:%d)\n", pos, end);
+               goto loop;
+       }
+
+       return list_pos;
+}
+
+#ifdef DEBUG
+/* Trivial linear search of chain index. Function used for verifying
+   the output of bsearch function */
+static struct list_head *
+iptcc_linearly_search_chain_index(const char *name, TC_HANDLE_T handle)
+{
+       unsigned int i=0;
+       int res=0;
+
+       struct list_head *list_pos;
+       list_pos = &handle->chains;
+
+       if (handle->chain_index_sz)
+               list_pos = &handle->chain_index[0]->list;
+
+       /* Linearly walk of chain index array */
+
+       for (i=0; i < handle->chain_index_sz; i++) {
+               if (handle->chain_index[i]) {
+                       res = strcmp(handle->chain_index[i]->name, name);
+                       if (res > 0)
+                               break; // One step too far
+                       list_pos = &handle->chain_index[i]->list;
+                       if (res == 0)
+                               break; // Direct hit
+               }
+       }
+
+       return list_pos;
+}
+#endif
+
+static int iptcc_chain_index_alloc(TC_HANDLE_T h)
+{
+       unsigned int list_length = CHAIN_INDEX_BUCKET_LEN;
+       unsigned int array_elems;
+       unsigned int array_mem;
+
+       /* Allocate memory for the chain index array */
+       array_elems = (h->num_chains / list_length) +
+                      (h->num_chains % list_length ? 1 : 0);
+       array_mem   = sizeof(h->chain_index) * array_elems;
+
+       debug("Alloc Chain index, elems:%d mem:%d bytes\n",
+             array_elems, array_mem);
+
+       h->chain_index = malloc(array_mem);
+       if (!h->chain_index) {
+               h->chain_index_sz = 0;
+               return -ENOMEM;
+       }
+       memset(h->chain_index, 0, array_mem);
+       h->chain_index_sz = array_elems;
+
+       return 1;
+}
+
+static void iptcc_chain_index_free(TC_HANDLE_T h)
+{
+       h->chain_index_sz = 0;
+       free(h->chain_index);
+}
+
+
+#ifdef DEBUG
+static void iptcc_chain_index_dump(TC_HANDLE_T h)
+{
+       unsigned int i = 0;
+
+       /* Dump: contents of chain index array */
+       for (i=0; i < h->chain_index_sz; i++) {
+               if (h->chain_index[i]) {
+                       fprintf(stderr, "Chain index[%d].name: %s\n",
+                               i, h->chain_index[i]->name);
+               }
+       }
+}
+#endif
+
+/* Build the chain index */
+static int iptcc_chain_index_build(TC_HANDLE_T h)
+{
+       unsigned int list_length = CHAIN_INDEX_BUCKET_LEN;
+       unsigned int chains = 0;
+       unsigned int cindex = 0;
+       struct chain_head *c;
+
+       /* Build up the chain index array here */
+       debug("Building chain index\n");
+
+       debug("Number of user defined chains:%d bucket_sz:%d array_sz:%d\n",
+               h->num_chains, list_length, h->chain_index_sz);
+
+       if (h->chain_index_sz == 0)
+               return 0;
+
+       list_for_each_entry(c, &h->chains, list) {
+
+               /* Issue: The index array needs to start after the
+                * builtin chains, as they are not sorted */
+               if (!iptcc_is_builtin(c)) {
+                       cindex=chains / list_length;
+
+                       /* Safe guard, break out on array limit, this
+                        * is useful if chains are added and array is
+                        * rebuild, without realloc of memory. */
+                       if (cindex >= h->chain_index_sz)
+                               break;
+
+                       if ((chains % list_length)== 0) {
+                               debug("\nIndex[%d] Chains:", cindex);
+                               h->chain_index[cindex] = c;
+                       }
+                       chains++;
+               }
+               debug("%s, ", c->name);
+       }
+       debug("\n");
+
+       return 1;
+}
+
+static int iptcc_chain_index_rebuild(TC_HANDLE_T h)
+{
+       debug("REBUILD chain index array\n");
+       iptcc_chain_index_free(h);
+       if ((iptcc_chain_index_alloc(h)) < 0)
+               return -ENOMEM;
+       iptcc_chain_index_build(h);
+       return 1;
+}
+
+/* Delete chain (pointer) from index array.  Removing an element from
+ * the chain list only affects the chain index array, if the chain
+ * index points-to/uses that list pointer.
+ *
+ * There are different strategies, the simple and safe is to rebuild
+ * the chain index every time.  The more advanced is to update the
+ * array index to point to the next element, but that requires some
+ * house keeping and boundry checks.  The advanced is implemented, as
+ * the simple approach behaves badly when all chains are deleted
+ * because list_for_each processing will always hit the first chain
+ * index, thus causing a rebuild for every chain.
+ */
+static int iptcc_chain_index_delete_chain(struct chain_head *c, TC_HANDLE_T h)
+{
+       struct list_head *index_ptr, *index_ptr2, *next;
+       struct chain_head *c2;
+       unsigned int idx, idx2;
+
+       index_ptr = iptcc_bsearch_chain_index(c->name, &idx, h);
+
+       debug("Del chain[%s] c->list:%p index_ptr:%p\n",
+             c->name, &c->list, index_ptr);
+
+       /* Save the next pointer */
+       next = c->list.next;
+       list_del(&c->list);
+
+       if (index_ptr == &c->list) { /* Chain used as index ptr */
+
+               /* See if its possible to avoid a rebuild, by shifting
+                * to next pointer.  Its possible if the next pointer
+                * is located in the same index bucket.
+                */
+               c2         = list_entry(next, struct chain_head, list);
+               index_ptr2 = iptcc_bsearch_chain_index(c2->name, &idx2, h);
+               if (idx != idx2) {
+                       /* Rebuild needed */
+                       return iptcc_chain_index_rebuild(h);
+               } else {
+                       /* Avoiding rebuild */
+                       debug("Update cindex[%d] with next ptr name:[%s]\n",
+                             idx, c2->name);
+                       h->chain_index[idx]=c2;
+                       return 0;
+               }
+       }
+       return 0;
+}
+
+
 /**********************************************************************
  * iptc cache utility functions (iptcc_*)
  **********************************************************************/
 
 /* Is the given chain builtin (1) or user-defined (0) */
-static unsigned int iptcc_is_builtin(struct chain_head *c)
+static inline unsigned int iptcc_is_builtin(struct chain_head *c)
 {
        return (c->hooknum ? 1 : 0);
 }
@@ -338,21 +642,81 @@ iptcc_find_chain_by_offset(TC_HANDLE_T handle, unsigned int offset)
 
        return NULL;
 }
+
 /* Returns chain head if found, otherwise NULL. */
 static struct chain_head *
 iptcc_find_label(const char *name, TC_HANDLE_T handle)
 {
        struct list_head *pos;
+       struct list_head *list_start_pos;
+       unsigned int i=0;
+       int res;
 
        if (list_empty(&handle->chains))
                return NULL;
 
+       /* First look at builtin chains */
        list_for_each(pos, &handle->chains) {
                struct chain_head *c = list_entry(pos, struct chain_head, list);
+               if (!iptcc_is_builtin(c))
+                       break;
                if (!strcmp(c->name, name))
                        return c;
        }
 
+       /* Find a smart place to start the search via chain index */
+       //list_start_pos = iptcc_linearly_search_chain_index(name, handle);
+       list_start_pos = iptcc_bsearch_chain_index(name, &i, handle);
+
+       /* Handel if bsearch bails out early */
+       if (list_start_pos == &handle->chains) {
+               list_start_pos = pos;
+       }
+#ifdef DEBUG
+       else {
+               /* Verify result of bsearch against linearly index search */
+               struct list_head *test_pos;
+               struct chain_head *test_c, *tmp_c;
+               test_pos = iptcc_linearly_search_chain_index(name, handle);
+               if (list_start_pos != test_pos) {
+                       debug("BUG in chain_index search\n");
+                       test_c=list_entry(test_pos,      struct chain_head,list);
+                       tmp_c =list_entry(list_start_pos,struct chain_head,list);
+                       debug("Verify search found:\n");
+                       debug(" Chain:%s\n", test_c->name);
+                       debug("BSearch found:\n");
+                       debug(" Chain:%s\n", tmp_c->name);
+                       exit(42);
+               }
+       }
+#endif
+
+       /* Initial/special case, no user defined chains */
+       if (handle->num_chains == 0)
+               return NULL;
+
+       /* Start searching through the chain list */
+       list_for_each(pos, list_start_pos->prev) {
+               struct chain_head *c = list_entry(pos, struct chain_head, list);
+               res = strcmp(c->name, name);
+               debug("List search name:%s == %s res:%d\n", name, c->name, res);
+               if (res==0)
+                       return c;
+
+               /* We can stop earlier as we know list is sorted */
+               if (res>0 && !iptcc_is_builtin(c)) { /* Walked too far*/
+                       debug(" Not in list, walked too far, sorted list\n");
+                       return NULL;
+               }
+
+               /* Stop on wrap around, if list head is reached */
+               if (pos == &handle->chains) {
+                       debug("Stop, list head reached\n");
+                       return NULL;
+               }
+       }
+
+       debug("List search NOT found name:%s\n", name);
        return NULL;
 }
 
@@ -413,14 +777,37 @@ static int __iptcc_p_del_policy(TC_HANDLE_T h, unsigned int num)
 static inline void iptc_insert_chain(TC_HANDLE_T h, struct chain_head *c)
 {
        struct chain_head *tmp;
+       struct list_head  *list_start_pos;
+       unsigned int i=1;
+
+       /* Find a smart place to start the insert search */
+       list_start_pos = iptcc_bsearch_chain_index(c->name, &i, h);
+
+       /* Handle the case, where chain.name is smaller than index[0] */
+       if (i==0 && strcmp(c->name, h->chain_index[0]->name) <= 0) {
+               h->chain_index[0] = c; /* Update chain index head */
+               list_start_pos = h->chains.next;
+               debug("Update chain_index[0] with %s\n", c->name);
+       }
+
+       /* Handel if bsearch bails out early */
+       if (list_start_pos == &h->chains) {
+               list_start_pos = h->chains.next;
+       }
 
        /* sort only user defined chains */
        if (!c->hooknum) {
-               list_for_each_entry(tmp, &h->chains, list) {
+               list_for_each_entry(tmp, list_start_pos->prev, list) {
                        if (!tmp->hooknum && strcmp(c->name, tmp->name) <= 0) {
                                list_add(&c->list, tmp->list.prev);
                                return;
                        }
+
+                       /* Stop if list head is reached */
+                       if (&tmp->list == &h->chains) {
+                               debug("Insert, list head reached add to tail\n");
+                               break;
+                       }
                }
        }
 
@@ -493,6 +880,7 @@ static int cache_add_entry(STRUCT_ENTRY *e,
                        errno = -ENOMEM;
                        return -1;
                }
+               h->num_chains++; /* New user defined chain */
 
                __iptcc_p_add_chain(h, c, offset, num);
 
@@ -580,22 +968,27 @@ static int parse_table(TC_HANDLE_T h)
        ENTRY_ITERATE(h->entries->entrytable, h->entries->size,
                        cache_add_entry, h, &prev, &num);
 
+       /* Build the chain index, used for chain list search speedup */
+       if ((iptcc_chain_index_alloc(h)) < 0)
+               return -ENOMEM;
+       iptcc_chain_index_build(h);
+
        /* Second pass: fixup parsed data from first pass */
        list_for_each_entry(c, &h->chains, list) {
                struct rule_head *r;
                list_for_each_entry(r, &c->rules, list) {
-                       struct chain_head *c;
+                       struct chain_head *lc;
                        STRUCT_STANDARD_TARGET *t;
 
                        if (r->type != IPTCC_R_JUMP)
                                continue;
 
                        t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
-                       c = iptcc_find_chain_by_offset(h, t->verdict);
-                       if (!c)
+                       lc = iptcc_find_chain_by_offset(h, t->verdict);
+                       if (!lc)
                                return -1;
-                       r->jump = c;
-                       c->references++;
+                       r->jump = lc;
+                       lc->references++;
                }
        }
 
@@ -848,7 +1241,7 @@ TC_INIT(const char *tablename)
                        return NULL;
        }
        sockfd_use++;
-
+retry:
        s = sizeof(info);
 
        strcpy(info.name, tablename);
@@ -901,6 +1294,9 @@ TC_INIT(const char *tablename)
        return h;
 error:
        TC_FREE(&h);
+       /* A different process changed the ruleset size, retry */
+       if (errno == EAGAIN)
+               goto retry;
        return NULL;
 }
 
@@ -925,6 +1321,8 @@ TC_FREE(TC_HANDLE_T *h)
                free(c);
        }
 
+       iptcc_chain_index_free(*h);
+
        free((*h)->entries);
        free(*h);
 
@@ -947,7 +1345,7 @@ TC_DUMP_ENTRIES(const TC_HANDLE_T handle)
        CHECK(handle);
 
        printf("libiptc v%s. %u bytes.\n",
-              IPTABLES_VERSION, handle->entries->size);
+              XTABLES_VERSION, handle->entries->size);
        printf("Table `%s'\n", handle->info.name);
        printf("Hooks: pre/in/fwd/out/post = %u/%u/%u/%u/%u\n",
               handle->info.hook_entry[HOOK_PRE_ROUTING],
@@ -1091,7 +1489,7 @@ TC_NEXT_RULE(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
 }
 
 /* How many rules in this chain? */
-unsigned int
+static unsigned int
 TC_NUM_RULES(const char *chain, TC_HANDLE_T *handle)
 {
        struct chain_head *c;
@@ -1107,9 +1505,8 @@ TC_NUM_RULES(const char *chain, TC_HANDLE_T *handle)
        return c->num_rules;
 }
 
-const STRUCT_ENTRY *TC_GET_RULE(const char *chain,
-                               unsigned int n,
-                               TC_HANDLE_T *handle)
+static const STRUCT_ENTRY *
+TC_GET_RULE(const char *chain, unsigned int n, TC_HANDLE_T *handle)
 {
        struct chain_head *c;
        struct rule_head *r;
@@ -1791,6 +2188,8 @@ int
 TC_CREATE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
 {
        static struct chain_head *c;
+       int capacity;
+       int exceeded;
 
        iptc_fn = TC_CREATE_CHAIN;
 
@@ -1819,10 +2218,25 @@ TC_CREATE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
                return 0;
 
        }
+       (*handle)->num_chains++; /* New user defined chain */
 
        DEBUGP("Creating chain `%s'\n", chain);
        iptc_insert_chain(*handle, c); /* Insert sorted */
 
+       /* Inserting chains don't change the correctness of the chain
+        * index (except if its smaller than index[0], but that
+        * handled by iptc_insert_chain).  It only causes longer lists
+        * in the buckets. Thus, only rebuild chain index when the
+        * capacity is exceed with CHAIN_INDEX_INSERT_MAX chains.
+        */
+       capacity = (*handle)->chain_index_sz * CHAIN_INDEX_BUCKET_LEN;
+       exceeded = ((((*handle)->num_chains)-capacity));
+       if (exceeded > CHAIN_INDEX_INSERT_MAX) {
+               debug("Capacity(%d) exceeded(%d) rebuild (chains:%d)\n",
+                     capacity, exceeded, (*handle)->num_chains);
+               iptcc_chain_index_rebuild(*handle);
+       }
+
        set_changed(*handle);
 
        return 1;
@@ -1885,11 +2299,14 @@ TC_DELETE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
        }
 
        /* If we are about to delete the chain that is the current
-        * iterator, move chain iterator firward. */
+        * iterator, move chain iterator forward. */
        if (c == (*handle)->chain_iterator_cur)
                iptcc_chain_iterator_advance(*handle);
 
-       list_del(&c->list);
+       (*handle)->num_chains--; /* One user defined chain deleted */
+
+       //list_del(&c->list); /* Done in iptcc_chain_index_delete_chain() */
+       iptcc_chain_index_delete_chain(c, *handle);
        free(c);
 
        DEBUGP("chain `%s' deleted\n", chain);
@@ -1997,16 +2414,14 @@ subtract_counters(STRUCT_COUNTERS *answer,
 }
 
 
-static void counters_nomap(STRUCT_COUNTERS_INFO *newcounters,
-                          unsigned int index)
+static void counters_nomap(STRUCT_COUNTERS_INFO *newcounters, unsigned int idx)
 {
-       newcounters->counters[index] = ((STRUCT_COUNTERS) { 0, 0});
+       newcounters->counters[idx] = ((STRUCT_COUNTERS) { 0, 0});
        DEBUGP_C("NOMAP => zero\n");
 }
 
 static void counters_normal_map(STRUCT_COUNTERS_INFO *newcounters,
-                               STRUCT_REPLACE *repl,
-                               unsigned int index,
+                               STRUCT_REPLACE *repl, unsigned int idx,
                                unsigned int mappos)
 {
        /* Original read: X.
@@ -2016,15 +2431,13 @@ static void counters_normal_map(STRUCT_COUNTERS_INFO *newcounters,
         * => Add in X + Y
         * => Add in replacement read.
         */
-       newcounters->counters[index] = repl->counters[mappos];
+       newcounters->counters[idx] = repl->counters[mappos];
        DEBUGP_C("NORMAL_MAP => mappos %u \n", mappos);
 }
 
 static void counters_map_zeroed(STRUCT_COUNTERS_INFO *newcounters,
-                               STRUCT_REPLACE *repl,
-                               unsigned int index,
-                               unsigned int mappos,
-                               STRUCT_COUNTERS *counters)
+                               STRUCT_REPLACE *repl, unsigned int idx,
+                               unsigned int mappos, STRUCT_COUNTERS *counters)
 {
        /* Original read: X.
         * Atomic read on replacement: X + Y.
@@ -2033,19 +2446,18 @@ static void counters_map_zeroed(STRUCT_COUNTERS_INFO *newcounters,
         * => Add in Y.
         * => Add in (replacement read - original read).
         */
-       subtract_counters(&newcounters->counters[index],
+       subtract_counters(&newcounters->counters[idx],
                          &repl->counters[mappos],
                          counters);
        DEBUGP_C("ZEROED => mappos %u\n", mappos);
 }
 
 static void counters_map_set(STRUCT_COUNTERS_INFO *newcounters,
-                            unsigned int index,
-                            STRUCT_COUNTERS *counters)
+                             unsigned int idx, STRUCT_COUNTERS *counters)
 {
        /* Want to set counter (iptables-restore) */
 
-       memcpy(&newcounters->counters[index], counters,
+       memcpy(&newcounters->counters[idx], counters,
                sizeof(STRUCT_COUNTERS));
 
        DEBUGP_C("SET\n");
index d9f7423c69d4ffef49b34da69d59f9d03251d8ea..3fc25b6fb01608117f44ebc88e772f1b1aef43fc 100644 (file)
@@ -172,11 +172,13 @@ int iptc_set_counter(const ipt_chainlabel chain,
 int iptc_commit(iptc_handle_t *handle);
 
 /* Get raw socket. */
-int iptc_get_raw_socket();
+int iptc_get_raw_socket(void);
 
 /* Translates errno numbers into more human-readable form than strerror. */
 const char *iptc_strerror(int err);
 
+extern void dump_entries(const iptc_handle_t);
+
 #ifdef __cplusplus
 }
 #endif