This commit was manufactured by cvs2svn to create branch
[iptables.git] / libiptc2 / foo.diff
diff --git a/libiptc2/foo.diff b/libiptc2/foo.diff
new file mode 100644 (file)
index 0000000..af69eb5
--- /dev/null
@@ -0,0 +1,391 @@
+--- libiptc.c  2003-06-30 18:26:59.000000000 +0200
++++ libiptc.c  2003-06-30 18:27:24.000000000 +0200
+@@ -64,19 +61,35 @@
+       char error[TABLE_MAXNAMELEN];
+ };
+-struct chain_cache
++struct rule_head
+ {
++      struct list_head list;
++      
++      struct chain_head *chain;
++
++      unsigned int size;
++      STRUCT_ENTRY entry[0];
++}
++
++struct chain_head
++{
++      struct list_head list;
++
+       char name[TABLE_MAXNAMELEN];
+-      /* This is the first rule in chain. */
+-      unsigned int start_off;
+-      /* Last rule in chain */
+-      unsigned int end_off;
++      unsigned int hooknum;
++      struct list_head rules;
+ };
+ STRUCT_TC_HANDLE
+ {
+       /* Have changes been made? */
+       int changed;
++
++      struct list_head chains;
++      
++      struct chain_head *chain_iterator_cur;
++
++#if 0
+       /* Size in here reflects original state. */
+       STRUCT_GETINFO info;
+@@ -98,6 +111,7 @@
+       /* Number in here reflects current state. */
+       unsigned int new_number;
+       STRUCT_GET_ENTRIES entries;
++#endif
+ };
+ static void
+@@ -375,173 +389,25 @@
+       }
+       return 0;
+ }
+-
+-static inline int
+-add_chain(STRUCT_ENTRY *e, TC_HANDLE_T h, STRUCT_ENTRY **prev)
+-{
+-      unsigned int builtin;
+-
+-      /* Last entry.  End it. */
+-      if (entry2offset(h, e) + e->next_offset == h->entries.size) {
+-              /* This is the ERROR node at end of the table */
+-              h->cache_chain_heads[h->cache_num_chains-1].end_off = 
+-                      entry2offset(h, *prev);
+-              return 0;
+-      }
+-
+-      /* We know this is the start of a new chain if it's an ERROR
+-         target, or a hook entry point */
+-      if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) == 0) {
+-              /* prev was last entry in previous chain */
+-              h->cache_chain_heads[h->cache_num_chains-1].end_off
+-                      = entry2offset(h, *prev);
+-
+-              strcpy(h->cache_chain_heads[h->cache_num_chains].name,
+-                     (const char *)GET_TARGET(e)->data);
+-              h->cache_chain_heads[h->cache_num_chains].start_off
+-                      = entry2offset(h, (void *)e + e->next_offset);
+-              h->cache_num_chains++;
+-      } else if ((builtin = is_hook_entry(e, h)) != 0) {
+-              if (h->cache_num_chains > 0)
+-                      /* prev was last entry in previous chain */
+-                      h->cache_chain_heads[h->cache_num_chains-1].end_off
+-                              = entry2offset(h, *prev);
+-
+-              strcpy(h->cache_chain_heads[h->cache_num_chains].name,
+-                     h->hooknames[builtin-1]);
+-              h->cache_chain_heads[h->cache_num_chains].start_off
+-                      = entry2offset(h, (void *)e);
+-              h->cache_num_chains++;
+-      }
+-
+-      *prev = e;
+-      return 0;
+-}
+-
+ static int alphasort(const void *a, const void *b)
+ {
+       return strcmp(((struct chain_cache *)a)->name,
+                     ((struct chain_cache *)b)->name);
+ }
+-static int populate_cache(TC_HANDLE_T h)
+-{
+-      unsigned int i;
+-      STRUCT_ENTRY *prev;
+-
+-      /* # chains < # rules / 2 + num builtins - 1 */
+-      h->cache_chain_heads = malloc((h->new_number / 2 + 4)
+-                                    * sizeof(struct chain_cache));
+-      if (!h->cache_chain_heads) {
+-              errno = ENOMEM;
+-              return 0;
+-      }
+-
+-      h->cache_num_chains = 0;
+-      h->cache_num_builtins = 0;
+-
+-      /* Count builtins */
+-      for (i = 0; i < NUMHOOKS; i++) {
+-              if (h->info.valid_hooks & (1 << i))
+-                      h->cache_num_builtins++;
+-      }
+-
+-      prev = NULL;
+-      ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
+-                    add_chain, h, &prev);
+-
+-      qsort(h->cache_chain_heads + h->cache_num_builtins,
+-            h->cache_num_chains - h->cache_num_builtins,
+-            sizeof(struct chain_cache), alphasort);
+-
+-      return 1;
+-}
+-
+-static int 
+-correct_cache(TC_HANDLE_T h, unsigned int offset, int delta)
+-{
+-      int i;          /* needs to be signed because deleting first
+-                         chain can make it drop to -1 */
+-
+-      if (!delta)
+-              return 1;
+-
+-      for (i = 0; i < h->cache_num_chains; i++) {
+-              struct chain_cache *cc = &h->cache_chain_heads[i];
+-
+-              if (delta < 0) {
+-                      /* take care about deleted chains */
+-                      if (cc->start_off >= offset+delta
+-                          && cc->end_off <= offset) {
+-                              /* this chain is within the deleted range,
+-                               * let's remove it from the cache */
+-                              void *start;
+-                              unsigned int size;
+-
+-                              h->cache_num_chains--;
+-                              if (i+1 >= h->cache_num_chains)
+-                                      continue;
+-                              start = &h->cache_chain_heads[i+1];
+-                              size = (h->cache_num_chains-i)
+-                                      * sizeof(struct chain_cache);
+-                              memmove(cc, start, size);
+-
+-                              /* iterate over same index again, since
+-                               * it is now a different chain */
+-                              i--;
+-                              continue;
+-                      }
+-              }
+-
+-              if (cc->start_off > offset)
+-                      cc->start_off += delta;
+-
+-              if (cc->end_off >= offset)
+-                      cc->end_off += delta;
+-      }
+-      /* HW_FIXME: sorting might be needed, but just in case a new chain was
+-       * added */
+-
+-      return 1;
+-}
+-
+-static int
+-add_chain_cache(TC_HANDLE_T h, const char *name, unsigned int start_off,
+-              unsigned int end_off)
+-{
+-      struct chain_cache *ccs = realloc(h->cache_chain_heads, 
+-                                        (h->new_number / 2 + 4 + 1)
+-                                         * sizeof(struct chain_cache));
+-      struct chain_cache *newcc;
+-      
+-      if (!ccs)
+-              return 0;
+-
+-      h->cache_chain_heads = ccs;
+-      newcc = &h->cache_chain_heads[h->cache_num_chains];
+-      h->cache_num_chains++;
+-
+-      strncpy(newcc->name, name, TABLE_MAXNAMELEN-1);
+-      newcc->start_off = start_off;
+-      newcc->end_off = end_off;
+-
+-      return 1;
+-}
+-
+-/* Returns cache ptr if found, otherwise NULL. */
+-static struct chain_cache *
++/* Returns chain head if found, otherwise NULL. */
++static struct chain_head *
+ find_label(const char *name, TC_HANDLE_T handle)
+ {
+-      unsigned int i;
++      struct list_head *pos;
+-      if (handle->cache_chain_heads == NULL
+-          && !populate_cache(handle))
++      if (!handle->chains)
+               return NULL;
+-      /* FIXME: Linear search through builtins, then binary --RR */
+-      for (i = 0; i < handle->cache_num_chains; i++) {
+-              if (strcmp(handle->cache_chain_heads[i].name, name) == 0)
+-                      return &handle->cache_chain_heads[i];
++      list_for_each(pos, &handle->chains) {
++              struct chain_head *c = list_entry(pos, struct chain_head, list);
++              if (!strcmp(c->name, name))
++                      return c;
+       }
+       return NULL;
+@@ -594,34 +460,30 @@
+ const char *
+ TC_FIRST_CHAIN(TC_HANDLE_T *handle)
+ {
+-      if ((*handle)->cache_chain_heads == NULL
+-          && !populate_cache(*handle))
+-              return NULL;
++      (*handle)->chain_iterator_cur = (*handle)->chains;
+-      (*handle)->cache_chain_iteration
+-              = &(*handle)->cache_chain_heads[0];
+-
+-      return (*handle)->cache_chain_iteration->name;
++      return (*handle)->chains.name;
+ }
+ /* Iterator functions to run through the chains.  Returns NULL at end. */
+ const char *
+ TC_NEXT_CHAIN(TC_HANDLE_T *handle)
+ {
+-      (*handle)->cache_chain_iteration++;
++      struct chain_head *next = list_entry(&(*handle)->chain_iterator_cur->list.next, struct chain_head, list);
++      (*handle)->chain_iterator_cur = next;
+-      if ((*handle)->cache_chain_iteration - (*handle)->cache_chain_heads
+-          == (*handle)->cache_num_chains)
++      if (next == (*handle)->chains)
+               return NULL;
+-      return (*handle)->cache_chain_iteration->name;
++      return next->name;
+ }
+ /* Get first rule in the given chain: NULL for empty chain. */
+ const STRUCT_ENTRY *
+ TC_FIRST_RULE(const char *chain, TC_HANDLE_T *handle)
+ {
+-      struct chain_cache *c;
++      struct chain_head *c;
++      struct rule_head *r;
+       c = find_label(chain, *handle);
+       if (!c) {
+@@ -630,22 +492,26 @@
+       }
+       /* Empty chain: single return/policy rule */
+-      if (c->start_off == c->end_off)
++      if (list_empty(c->rules))
+               return NULL;
+-      (*handle)->cache_rule_end = offset2entry(*handle, c->end_off);
+-      return offset2entry(*handle, c->start_off);
++      r = list_entry(&c->rules.next, struct rule_head, list);
++      (*handle)->rule_iterator_cur = r;
++
++      return r->entry;
+ }
+ /* Returns NULL when rules run out. */
+ const STRUCT_ENTRY *
+ TC_NEXT_RULE(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
+ {
+-      if ((void *)prev + prev->next_offset
+-          == (void *)(*handle)->cache_rule_end)
++      struct rule_head *r = list_entry((*handle)->rule_iterator_cur->list.next, struct rule_head, list);
++
++      if (r == r->chain)
+               return NULL;
+-      return (void *)prev + prev->next_offset;
++      /* NOTE: prev is without any influence ! */
++      return r->entry;
+ }
+ #if 0
+@@ -773,7 +639,7 @@
+       return target_name(*handle, e);
+ }
+-static inline int
++static int
+ correct_verdict(STRUCT_ENTRY *e,
+               char *base,
+               unsigned int offset, int delta_offset)
+@@ -874,16 +740,8 @@
+       newh->entries.size = (*handle)->entries.size + rules_size;
+       newh->hooknames = (*handle)->hooknames;
+-      newh->cache_chain_heads = (*handle)->cache_chain_heads;
+-      newh->cache_num_builtins = (*handle)->cache_num_builtins;
+-      newh->cache_num_chains = (*handle)->cache_num_chains;
+-      newh->cache_rule_end = (*handle)->cache_rule_end;
+-      newh->cache_chain_iteration = (*handle)->cache_chain_iteration;
+-      if (!correct_cache(newh, offset, rules_size)) {
+-              free(newh);
+-              return 0;
+-      }
+-
++      if ((*handle)->cache_chain_heads)
++              free((*handle)->cache_chain_heads);
+       free(*handle);
+       *handle = newh;
+@@ -942,10 +800,6 @@
+       (*handle)->new_number -= num_rules;
+       (*handle)->entries.size -= rules_size;
+-      /* Fix the chain cache */
+-      if (!correct_cache(*handle, offset, -(int)rules_size))
+-              return 0;
+-
+       return set_verdict(offset, -(int)rules_size, handle);
+ }
+@@ -1449,7 +1303,6 @@
+               STRUCT_ENTRY ret;
+               STRUCT_STANDARD_TARGET target;
+       } newc;
+-      unsigned int destination;
+       iptc_fn = TC_CREATE_CHAIN;
+@@ -1487,21 +1340,11 @@
+               = ALIGN(sizeof(STRUCT_STANDARD_TARGET));
+       newc.target.verdict = RETURN;
+-      destination = index2offset(*handle, (*handle)->new_number -1);
+-
+       /* Add just before terminal entry */
+       ret = insert_rules(2, sizeof(newc), &newc.head,
+-                         destination,
++                         index2offset(*handle, (*handle)->new_number - 1),
+                          (*handle)->new_number - 1,
+                          0, handle);
+-
+-      set_changed(*handle);
+-
+-      /* add chain cache info for this chain */
+-      add_chain_cache(*handle, chain, 
+-                      destination+newc.head.next_offset, 
+-                      destination+newc.head.next_offset);
+-
+       return ret;
+ }
+@@ -1629,11 +1472,6 @@
+       memset(t->error, 0, sizeof(t->error));
+       strcpy(t->error, newname);
+-
+-      /* update chain cache */
+-      memset(c->name, 0, sizeof(c->name));
+-      strcpy(c->name, newname);
+-
+       set_changed(*handle);
+       return 1;