summaryrefslogtreecommitdiffstats
path: root/libiptc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2003-06-23 18:25:59 +0000
committerHarald Welte <laforge@gnumonks.org>2003-06-23 18:25:59 +0000
commit3ea8f40262386e6b1445a617841f28702fe74d9d (patch)
tree95dcd643afa1b57ff9bacaaf5d9172a2b4ca06f4 /libiptc
parent766113ac7457f4e14014d2accd5344a03bb6854f (diff)
implement chain cache ussing relative offsets instead of absolute entry
pointers. This is needed for my current libiptc optimization work, since it needs the chain cache to still be correct after it has been reallocated to a different address.
Diffstat (limited to 'libiptc')
-rw-r--r--libiptc/libiptc.c123
1 files changed, 73 insertions, 50 deletions
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index 0dad6f48..73a3cac0 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -1,4 +1,4 @@
-/* Library which manipulates firewall rules. Version $Revision: 1.37 $ */
+/* Library which manipulates firewall rules. Version $Revision: 1.38 $ */
/* Architecture of firewall rules is as follows:
*
@@ -8,8 +8,14 @@
* and a POLICY for built-ins.
*/
-/* (C)1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
- COPYING for details). */
+/* (C) 1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
+ * COPYING for details).
+ * (C) 2000-2003 by the Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * 2003-Jun-20: Harald Welte <laforge@netfilter.org:
+ * - Reimplementation of chain cache to use offsets instead of entries
+ *
+ */
#ifndef IPT_LIB_DIR
#define IPT_LIB_DIR "/usr/local/lib/iptables"
@@ -59,9 +65,9 @@ struct chain_cache
{
char name[TABLE_MAXNAMELEN];
/* This is the first rule in chain. */
- STRUCT_ENTRY *start;
+ unsigned int start_off;
/* Last rule in chain */
- STRUCT_ENTRY *end;
+ unsigned int end_off;
};
STRUCT_TC_HANDLE
@@ -171,15 +177,28 @@ get_entry(TC_HANDLE_T h, unsigned int offset)
static inline unsigned long
entry2offset(const TC_HANDLE_T h, const STRUCT_ENTRY *e)
{
- return (char *)e - (char *)h->entries.entrytable;
+ return (void *)e - (void *)h->entries.entrytable;
}
-static unsigned long
+static inline unsigned long
index2offset(TC_HANDLE_T h, unsigned int index)
{
return entry2offset(h, index2entry(h, index));
}
+static inline STRUCT_ENTRY *
+offset2entry(TC_HANDLE_T h, unsigned int offset)
+{
+ return (STRUCT_ENTRY *) ((void *)h->entries.entrytable+offset);
+}
+
+static inline unsigned int
+offset2index(const TC_HANDLE_T h, unsigned int offset)
+{
+ return entry2index(h, offset2entry(h, offset));
+}
+
+
static const char *
get_errorlabel(TC_HANDLE_T h, unsigned int offset)
{
@@ -369,7 +388,8 @@ add_chain(STRUCT_ENTRY *e, TC_HANDLE_T h, STRUCT_ENTRY **prev)
/* 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 = *prev;
+ h->cache_chain_heads[h->cache_num_chains-1].end_off =
+ entry2offset(h, *prev);
return 0;
}
@@ -377,24 +397,24 @@ add_chain(STRUCT_ENTRY *e, TC_HANDLE_T h, STRUCT_ENTRY **prev)
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
- = *prev;
+ 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
- = (void *)e + e->next_offset;
+ 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
- = *prev;
+ 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
- = (void *)e;
+ h->cache_chain_heads[h->cache_num_chains].start_off
+ = entry2offset(h, (void *)e);
h->cache_num_chains++;
}
@@ -543,11 +563,11 @@ TC_FIRST_RULE(const char *chain, TC_HANDLE_T *handle)
}
/* Empty chain: single return/policy rule */
- if (c->start == c->end)
+ if (c->start_off == c->end_off)
return NULL;
- (*handle)->cache_rule_end = c->end;
- return c->start;
+ (*handle)->cache_rule_end = offset2entry(*handle, c->end_off);
+ return offset2entry(*handle, c->start_off);
}
/* Returns NULL when rules run out. */
@@ -904,7 +924,7 @@ map_target(const TC_HANDLE_T handle,
c = find_label(t->u.user.name, handle);
if (c)
- return standard_map(e, entry2offset(handle, c->start));
+ return standard_map(e, c->start_off);
}
/* Must be a module? If not, kernel will reject... */
@@ -944,10 +964,10 @@ TC_INSERT_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
- chainindex = entry2index(*handle, c->start);
+ chainindex = offset2index(*handle, c->start_off);
tmp = index2entry(*handle, chainindex + rulenum);
- if (!tmp || tmp > c->end) {
+ if (!tmp || tmp > offset2entry(*handle, c->end_off)) {
errno = E2BIG;
return 0;
}
@@ -984,10 +1004,10 @@ TC_REPLACE_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
- chainindex = entry2index(*handle, c->start);
+ chainindex = offset2index(*handle, c->start_off);
tmp = index2entry(*handle, chainindex + rulenum);
- if (!tmp || tmp >= c->end) {
+ if (!tmp || tmp >= offset2entry(*handle, c->end_off)) {
errno = E2BIG;
return 0;
}
@@ -1025,13 +1045,11 @@ TC_APPEND_ENTRY(const IPT_CHAINLABEL chain,
}
if (!map_target(*handle, (STRUCT_ENTRY *)e,
- entry2offset(*handle, c->end), &old))
+ c->end_off, &old))
return 0;
- ret = insert_rules(1, e->next_offset, e,
- entry2offset(*handle, c->end),
- entry2index(*handle, c->end),
- 0, handle);
+ ret = insert_rules(1, e->next_offset, e, c->end_off,
+ offset2index(*handle, c->end_off), 0, handle);
unmap_target((STRUCT_ENTRY *)e, &old);
return ret;
}
@@ -1105,8 +1123,7 @@ TC_DELETE_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
- for (offset = entry2offset(*handle, c->start);
- offset < entry2offset(*handle, c->end);
+ for (offset = c->start_off; offset < c->end_off;
offset += e->next_offset) {
STRUCT_ENTRY_TARGET discard;
@@ -1155,9 +1172,9 @@ TC_DELETE_NUM_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
- index = entry2index(*handle, c->start) + rulenum;
+ index = offset2index(*handle, c->start_off) + rulenum;
- if (index >= entry2index(*handle, c->end)) {
+ if (index >= offset2index(*handle, c->end_off)) {
errno = E2BIG;
return 0;
}
@@ -1189,6 +1206,7 @@ int
TC_FLUSH_ENTRIES(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
{
unsigned int startindex, endindex;
+ STRUCT_ENTRY *startentry, *endentry;
struct chain_cache *c;
int ret;
@@ -1197,12 +1215,14 @@ TC_FLUSH_ENTRIES(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
errno = ENOENT;
return 0;
}
- startindex = entry2index(*handle, c->start);
- endindex = entry2index(*handle, c->end);
+ startindex = offset2index(*handle, c->start_off);
+ endindex = offset2index(*handle, c->end_off);
+ startentry = offset2entry(*handle, c->start_off);
+ endentry = offset2entry(*handle, c->end_off);
ret = delete_rules(endindex - startindex,
- (char *)c->end - (char *)c->start,
- entry2offset(*handle, c->start), startindex,
+ (char *)endentry - (char *)startentry,
+ c->start_off, startindex,
handle);
return ret;
}
@@ -1219,8 +1239,8 @@ TC_ZERO_ENTRIES(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
return 0;
}
- i = entry2index(*handle, c->start);
- end = entry2index(*handle, c->end);
+ i = offset2index(*handle, c->start_off);
+ end = offset2index(*handle, c->end_off);
for (; i <= end; i++) {
if ((*handle)->counter_map[i].maptype ==COUNTER_MAP_NORMAL_MAP)
@@ -1248,8 +1268,8 @@ TC_READ_COUNTER(const IPT_CHAINLABEL chain,
return NULL;
}
- chainindex = entry2index(*handle, c->start);
- end = entry2index(*handle, c->end);
+ chainindex = offset2index(*handle, c->start_off);
+ end = offset2index(*handle, c->end_off);
if (chainindex + rulenum > end) {
errno = E2BIG;
@@ -1278,8 +1298,8 @@ TC_ZERO_COUNTER(const IPT_CHAINLABEL chain,
return 0;
}
- chainindex = entry2index(*handle, c->start);
- end = entry2index(*handle, c->end);
+ chainindex = offset2index(*handle, c->start_off);
+ end = offset2index(*handle, c->end_off);
if (chainindex + rulenum > end) {
errno = E2BIG;
@@ -1317,8 +1337,8 @@ TC_SET_COUNTER(const IPT_CHAINLABEL chain,
return 0;
}
- chainindex = entry2index(*handle, c->start);
- end = entry2index(*handle, c->end);
+ chainindex = offset2index(*handle, c->start_off);
+ end = offset2index(*handle, c->end_off);
if (chainindex + rulenum > end) {
errno = E2BIG;
@@ -1425,7 +1445,7 @@ TC_GET_REFERENCES(unsigned int *ref, const IPT_CHAINLABEL chain,
*ref = 0;
ENTRY_ITERATE((*handle)->entries.entrytable,
(*handle)->entries.size,
- count_ref, entry2offset(*handle, c->start), ref);
+ count_ref, c->start_off, ref);
return 1;
}
@@ -1437,6 +1457,7 @@ TC_DELETE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
unsigned int references;
struct chain_cache *c;
int ret;
+ STRUCT_ENTRY *start;
if (!TC_GET_REFERENCES(&references, chain, handle))
return 0;
@@ -1458,18 +1479,20 @@ TC_DELETE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
return 0;
}
- if ((void *)c->start != c->end) {
+ if (c->start_off != c->end_off) {
errno = ENOTEMPTY;
return 0;
}
/* Need label index: preceeds chain start */
- labelidx = entry2index(*handle, c->start) - 1;
+ labelidx = offset2index(*handle, c->start_off) - 1;
labeloff = index2offset(*handle, labelidx);
+ start = offset2entry(*handle, c->start_off);
+
ret = delete_rules(2,
get_entry(*handle, labeloff)->next_offset
- + c->start->next_offset,
+ + start->next_offset,
labeloff, labelidx, handle);
return ret;
}
@@ -1508,7 +1531,7 @@ int TC_RENAME_CHAIN(const IPT_CHAINLABEL oldname,
}
/* Need label index: preceeds chain start */
- labelidx = entry2index(*handle, c->start) - 1;
+ labelidx = offset2index(*handle, c->start_off) - 1;
labeloff = index2offset(*handle, labelidx);
t = (struct ipt_error_target *)