1 --- libiptc.c 2003-06-30 18:26:59.000000000 +0200
2 +++ libiptc.c 2003-06-30 18:27:24.000000000 +0200
4 char error[TABLE_MAXNAMELEN];
10 + struct list_head list;
12 + struct chain_head *chain;
15 + STRUCT_ENTRY entry[0];
20 + struct list_head list;
22 char name[TABLE_MAXNAMELEN];
23 - /* This is the first rule in chain. */
24 - unsigned int start_off;
25 - /* Last rule in chain */
26 - unsigned int end_off;
27 + unsigned int hooknum;
28 + struct list_head rules;
33 /* Have changes been made? */
36 + struct list_head chains;
38 + struct chain_head *chain_iterator_cur;
41 /* Size in here reflects original state. */
45 /* Number in here reflects current state. */
46 unsigned int new_number;
47 STRUCT_GET_ENTRIES entries;
52 @@ -375,173 +389,25 @@
58 -add_chain(STRUCT_ENTRY *e, TC_HANDLE_T h, STRUCT_ENTRY **prev)
60 - unsigned int builtin;
62 - /* Last entry. End it. */
63 - if (entry2offset(h, e) + e->next_offset == h->entries.size) {
64 - /* This is the ERROR node at end of the table */
65 - h->cache_chain_heads[h->cache_num_chains-1].end_off =
66 - entry2offset(h, *prev);
70 - /* We know this is the start of a new chain if it's an ERROR
71 - target, or a hook entry point */
72 - if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) == 0) {
73 - /* prev was last entry in previous chain */
74 - h->cache_chain_heads[h->cache_num_chains-1].end_off
75 - = entry2offset(h, *prev);
77 - strcpy(h->cache_chain_heads[h->cache_num_chains].name,
78 - (const char *)GET_TARGET(e)->data);
79 - h->cache_chain_heads[h->cache_num_chains].start_off
80 - = entry2offset(h, (void *)e + e->next_offset);
81 - h->cache_num_chains++;
82 - } else if ((builtin = is_hook_entry(e, h)) != 0) {
83 - if (h->cache_num_chains > 0)
84 - /* prev was last entry in previous chain */
85 - h->cache_chain_heads[h->cache_num_chains-1].end_off
86 - = entry2offset(h, *prev);
88 - strcpy(h->cache_chain_heads[h->cache_num_chains].name,
89 - h->hooknames[builtin-1]);
90 - h->cache_chain_heads[h->cache_num_chains].start_off
91 - = entry2offset(h, (void *)e);
92 - h->cache_num_chains++;
99 static int alphasort(const void *a, const void *b)
101 return strcmp(((struct chain_cache *)a)->name,
102 ((struct chain_cache *)b)->name);
105 -static int populate_cache(TC_HANDLE_T h)
108 - STRUCT_ENTRY *prev;
110 - /* # chains < # rules / 2 + num builtins - 1 */
111 - h->cache_chain_heads = malloc((h->new_number / 2 + 4)
112 - * sizeof(struct chain_cache));
113 - if (!h->cache_chain_heads) {
118 - h->cache_num_chains = 0;
119 - h->cache_num_builtins = 0;
121 - /* Count builtins */
122 - for (i = 0; i < NUMHOOKS; i++) {
123 - if (h->info.valid_hooks & (1 << i))
124 - h->cache_num_builtins++;
128 - ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
129 - add_chain, h, &prev);
131 - qsort(h->cache_chain_heads + h->cache_num_builtins,
132 - h->cache_num_chains - h->cache_num_builtins,
133 - sizeof(struct chain_cache), alphasort);
139 -correct_cache(TC_HANDLE_T h, unsigned int offset, int delta)
141 - int i; /* needs to be signed because deleting first
142 - chain can make it drop to -1 */
147 - for (i = 0; i < h->cache_num_chains; i++) {
148 - struct chain_cache *cc = &h->cache_chain_heads[i];
151 - /* take care about deleted chains */
152 - if (cc->start_off >= offset+delta
153 - && cc->end_off <= offset) {
154 - /* this chain is within the deleted range,
155 - * let's remove it from the cache */
159 - h->cache_num_chains--;
160 - if (i+1 >= h->cache_num_chains)
162 - start = &h->cache_chain_heads[i+1];
163 - size = (h->cache_num_chains-i)
164 - * sizeof(struct chain_cache);
165 - memmove(cc, start, size);
167 - /* iterate over same index again, since
168 - * it is now a different chain */
174 - if (cc->start_off > offset)
175 - cc->start_off += delta;
177 - if (cc->end_off >= offset)
178 - cc->end_off += delta;
180 - /* HW_FIXME: sorting might be needed, but just in case a new chain was
187 -add_chain_cache(TC_HANDLE_T h, const char *name, unsigned int start_off,
188 - unsigned int end_off)
190 - struct chain_cache *ccs = realloc(h->cache_chain_heads,
191 - (h->new_number / 2 + 4 + 1)
192 - * sizeof(struct chain_cache));
193 - struct chain_cache *newcc;
198 - h->cache_chain_heads = ccs;
199 - newcc = &h->cache_chain_heads[h->cache_num_chains];
200 - h->cache_num_chains++;
202 - strncpy(newcc->name, name, TABLE_MAXNAMELEN-1);
203 - newcc->start_off = start_off;
204 - newcc->end_off = end_off;
209 -/* Returns cache ptr if found, otherwise NULL. */
210 -static struct chain_cache *
211 +/* Returns chain head if found, otherwise NULL. */
212 +static struct chain_head *
213 find_label(const char *name, TC_HANDLE_T handle)
216 + struct list_head *pos;
218 - if (handle->cache_chain_heads == NULL
219 - && !populate_cache(handle))
220 + if (!handle->chains)
223 - /* FIXME: Linear search through builtins, then binary --RR */
224 - for (i = 0; i < handle->cache_num_chains; i++) {
225 - if (strcmp(handle->cache_chain_heads[i].name, name) == 0)
226 - return &handle->cache_chain_heads[i];
227 + list_for_each(pos, &handle->chains) {
228 + struct chain_head *c = list_entry(pos, struct chain_head, list);
229 + if (!strcmp(c->name, name))
234 @@ -594,34 +460,30 @@
236 TC_FIRST_CHAIN(TC_HANDLE_T *handle)
238 - if ((*handle)->cache_chain_heads == NULL
239 - && !populate_cache(*handle))
241 + (*handle)->chain_iterator_cur = (*handle)->chains;
243 - (*handle)->cache_chain_iteration
244 - = &(*handle)->cache_chain_heads[0];
246 - return (*handle)->cache_chain_iteration->name;
247 + return (*handle)->chains.name;
250 /* Iterator functions to run through the chains. Returns NULL at end. */
252 TC_NEXT_CHAIN(TC_HANDLE_T *handle)
254 - (*handle)->cache_chain_iteration++;
255 + struct chain_head *next = list_entry(&(*handle)->chain_iterator_cur->list.next, struct chain_head, list);
256 + (*handle)->chain_iterator_cur = next;
258 - if ((*handle)->cache_chain_iteration - (*handle)->cache_chain_heads
259 - == (*handle)->cache_num_chains)
260 + if (next == (*handle)->chains)
263 - return (*handle)->cache_chain_iteration->name;
267 /* Get first rule in the given chain: NULL for empty chain. */
269 TC_FIRST_RULE(const char *chain, TC_HANDLE_T *handle)
271 - struct chain_cache *c;
272 + struct chain_head *c;
273 + struct rule_head *r;
275 c = find_label(chain, *handle);
277 @@ -630,22 +492,26 @@
280 /* Empty chain: single return/policy rule */
281 - if (c->start_off == c->end_off)
282 + if (list_empty(c->rules))
285 - (*handle)->cache_rule_end = offset2entry(*handle, c->end_off);
286 - return offset2entry(*handle, c->start_off);
287 + r = list_entry(&c->rules.next, struct rule_head, list);
288 + (*handle)->rule_iterator_cur = r;
293 /* Returns NULL when rules run out. */
295 TC_NEXT_RULE(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
297 - if ((void *)prev + prev->next_offset
298 - == (void *)(*handle)->cache_rule_end)
299 + struct rule_head *r = list_entry((*handle)->rule_iterator_cur->list.next, struct rule_head, list);
304 - return (void *)prev + prev->next_offset;
305 + /* NOTE: prev is without any influence ! */
311 return target_name(*handle, e);
316 correct_verdict(STRUCT_ENTRY *e,
318 unsigned int offset, int delta_offset)
320 newh->entries.size = (*handle)->entries.size + rules_size;
321 newh->hooknames = (*handle)->hooknames;
323 - newh->cache_chain_heads = (*handle)->cache_chain_heads;
324 - newh->cache_num_builtins = (*handle)->cache_num_builtins;
325 - newh->cache_num_chains = (*handle)->cache_num_chains;
326 - newh->cache_rule_end = (*handle)->cache_rule_end;
327 - newh->cache_chain_iteration = (*handle)->cache_chain_iteration;
328 - if (!correct_cache(newh, offset, rules_size)) {
333 + if ((*handle)->cache_chain_heads)
334 + free((*handle)->cache_chain_heads);
339 (*handle)->new_number -= num_rules;
340 (*handle)->entries.size -= rules_size;
342 - /* Fix the chain cache */
343 - if (!correct_cache(*handle, offset, -(int)rules_size))
346 return set_verdict(offset, -(int)rules_size, handle);
349 @@ -1449,7 +1303,6 @@
351 STRUCT_STANDARD_TARGET target;
353 - unsigned int destination;
355 iptc_fn = TC_CREATE_CHAIN;
357 @@ -1487,21 +1340,11 @@
358 = ALIGN(sizeof(STRUCT_STANDARD_TARGET));
359 newc.target.verdict = RETURN;
361 - destination = index2offset(*handle, (*handle)->new_number -1);
363 /* Add just before terminal entry */
364 ret = insert_rules(2, sizeof(newc), &newc.head,
366 + index2offset(*handle, (*handle)->new_number - 1),
367 (*handle)->new_number - 1,
370 - set_changed(*handle);
372 - /* add chain cache info for this chain */
373 - add_chain_cache(*handle, chain,
374 - destination+newc.head.next_offset,
375 - destination+newc.head.next_offset);
380 @@ -1629,11 +1472,6 @@
382 memset(t->error, 0, sizeof(t->error));
383 strcpy(t->error, newname);
385 - /* update chain cache */
386 - memset(c->name, 0, sizeof(c->name));
387 - strcpy(c->name, newname);
389 set_changed(*handle);