summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2013-03-11 12:46:32 +0100
committerJo-Philipp Wich <jow@openwrt.org>2013-03-11 21:41:24 +0100
commit16037f5d804ef952d61f93d09d7f9f0060072401 (patch)
tree70eab3b5d5d15b9c4cb9e34d50b5ee3f841e9e66
parenta4b710143626b399783865a3ea31bdb25aa1bac9 (diff)
downloadfirewall3-16037f5d804ef952d61f93d09d7f9f0060072401.tar.gz
Rework zone flush logic
-rw-r--r--defaults.c67
-rw-r--r--defaults.h9
-rw-r--r--forwards.c4
-rw-r--r--ipsets.c4
-rw-r--r--main.c29
-rw-r--r--options.h20
-rw-r--r--redirects.c12
-rw-r--r--rules.c8
-rw-r--r--utils.c36
-rw-r--r--utils.h9
-rw-r--r--zones.c167
-rw-r--r--zones.h4
12 files changed, 189 insertions, 180 deletions
diff --git a/defaults.c b/defaults.c
index 7c04f10..8bf1aa3 100644
--- a/defaults.c
+++ b/defaults.c
@@ -33,10 +33,10 @@ static const struct chain default_chains[] = {
C(ANY, FILTER, UNSPEC, "delegate_input"),
C(ANY, FILTER, UNSPEC, "delegate_output"),
C(ANY, FILTER, UNSPEC, "delegate_forward"),
+ C(ANY, FILTER, UNSPEC, "reject"),
C(ANY, FILTER, CUSTOM_CHAINS, "input_rule"),
C(ANY, FILTER, CUSTOM_CHAINS, "output_rule"),
C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_rule"),
- C(ANY, FILTER, UNSPEC, "reject"),
C(ANY, FILTER, SYN_FLOOD, "syn_flood"),
C(V4, NAT, UNSPEC, "delegate_prerouting"),
@@ -88,11 +88,15 @@ const struct fw3_option fw3_default_opts[] = {
static bool
print_chains(enum fw3_table table, enum fw3_family family,
- const char *fmt, uint32_t flags,
+ const char *fmt, uint32_t *flags, uint32_t mask,
const struct chain *chains, int n)
{
bool rv = false;
const struct chain *c;
+ uint32_t f = flags ? flags[family == FW3_FAMILY_V6] : 0;
+
+ if (mask)
+ f &= mask;
for (c = chains; n > 0; c++, n--)
{
@@ -102,7 +106,7 @@ print_chains(enum fw3_table table, enum fw3_family family,
if (c->table != table)
continue;
- if ((c->flag != FW3_DEFAULT_UNSPEC) && !hasbit(flags, c->flag))
+ if ((c->flag != FW3_DEFAULT_UNSPEC) && !hasbit(f, c->flag))
continue;
fw3_pr(fmt, c->name);
@@ -143,8 +147,6 @@ fw3_load_defaults(struct fw3_state *state, struct uci_package *p)
defs->tcp_window_scaling = true;
defs->custom_chains = true;
- setbit(defs->flags, FW3_FAMILY_V4);
-
uci_foreach_element(&p->sections, e)
{
s = uci_to_section(e);
@@ -163,28 +165,23 @@ fw3_load_defaults(struct fw3_state *state, struct uci_package *p)
check_policy(e, &defs->policy_input, "input");
check_policy(e, &defs->policy_output, "output");
check_policy(e, &defs->policy_forward, "forward");
-
- if (!defs->disable_ipv6)
- setbit(defs->flags, FW3_FAMILY_V6);
-
- if (defs->custom_chains)
- setbit(defs->flags, FW3_DEFAULT_CUSTOM_CHAINS);
-
- if (defs->syn_flood)
- setbit(defs->flags, FW3_DEFAULT_SYN_FLOOD);
}
}
void
fw3_print_default_chains(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state)
+ bool reload, struct fw3_state *state)
{
+ bool rv;
struct fw3_defaults *defs = &state->defaults;
uint32_t custom_mask = ~0;
#define policy(t) \
((t == FW3_TARGET_REJECT) ? "DROP" : fw3_flag_names[t])
+ if (family == FW3_FAMILY_V6 && defs->disable_ipv6)
+ return;
+
if (table == FW3_TABLE_FILTER)
{
fw3_pr(":INPUT %s [0:0]\n", policy(defs->policy_input));
@@ -192,17 +189,26 @@ fw3_print_default_chains(enum fw3_table table, enum fw3_family family,
fw3_pr(":OUTPUT %s [0:0]\n", policy(defs->policy_output));
}
- /* user chains already loaded, don't create again */
- if (hasbit(state->defaults.running_flags, FW3_DEFAULT_CUSTOM_CHAINS))
+ /* Don't touch user chains on reload */
+ if (reload)
delbit(custom_mask, FW3_DEFAULT_CUSTOM_CHAINS);
- print_chains(table, family, ":%s - [0:0]\n", defs->flags & custom_mask,
- default_chains, ARRAY_SIZE(default_chains));
+ if (defs->custom_chains)
+ set(defs->flags, family, FW3_DEFAULT_CUSTOM_CHAINS);
+
+ if (defs->syn_flood)
+ set(defs->flags, family, FW3_DEFAULT_SYN_FLOOD);
+
+ rv = print_chains(table, family, ":%s - [0:0]\n", defs->flags, custom_mask,
+ default_chains, ARRAY_SIZE(default_chains));
+
+ if (rv)
+ set(defs->flags, family, table);
}
void
fw3_print_default_head_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state)
+ bool reload, struct fw3_state *state)
{
int i;
struct fw3_defaults *defs = &state->defaults;
@@ -212,7 +218,7 @@ fw3_print_default_head_rules(enum fw3_table table, enum fw3_family family,
"forward", "forwarding",
};
- print_chains(table, family, "-A %s\n", 0,
+ print_chains(table, family, "-A %s\n", NULL, 0,
toplevel_rules, ARRAY_SIZE(toplevel_rules));
switch (table)
@@ -278,7 +284,7 @@ fw3_print_default_head_rules(enum fw3_table table, enum fw3_family family,
void
fw3_print_default_tail_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state)
+ bool reload, struct fw3_state *state)
{
struct fw3_defaults *defs = &state->defaults;
@@ -336,36 +342,37 @@ reset_policy(enum fw3_table table, enum fw3_target policy)
void
fw3_flush_rules(enum fw3_table table, enum fw3_family family,
- bool pass2, struct fw3_state *state, enum fw3_target policy)
+ bool pass2, bool reload, struct fw3_state *state)
{
struct fw3_defaults *defs = &state->defaults;
uint32_t custom_mask = ~0;
- if (!hasbit(defs->running_flags, family))
+ if (!has(defs->flags, family, table))
return;
/* don't touch user chains on selective stop */
- delbit(custom_mask, FW3_DEFAULT_CUSTOM_CHAINS);
+ if (reload)
+ delbit(custom_mask, FW3_DEFAULT_CUSTOM_CHAINS);
if (!pass2)
{
- reset_policy(table, policy);
+ reset_policy(table, reload ? FW3_TARGET_DROP : FW3_TARGET_ACCEPT);
print_chains(table, family, "-D %s\n",
- defs->running_flags & custom_mask,
+ defs->flags, custom_mask,
toplevel_rules, ARRAY_SIZE(toplevel_rules));
print_chains(table, family, "-F %s\n",
- defs->running_flags & custom_mask,
+ defs->flags, custom_mask,
default_chains, ARRAY_SIZE(default_chains));
}
else
{
print_chains(table, family, "-X %s\n",
- defs->running_flags & custom_mask,
+ defs->flags, custom_mask,
default_chains, ARRAY_SIZE(default_chains));
- delbit(defs->flags, family);
+ del(defs->flags, family, table);
}
}
diff --git a/defaults.h b/defaults.h
index 9547ace..00144db 100644
--- a/defaults.h
+++ b/defaults.h
@@ -26,19 +26,18 @@ extern const struct fw3_option fw3_default_opts[];
void fw3_load_defaults(struct fw3_state *state, struct uci_package *p);
void fw3_print_default_chains(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state);
+ bool reload, struct fw3_state *state);
void fw3_print_default_head_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state);
+ bool reload, struct fw3_state *state);
void fw3_print_default_tail_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state);
+ bool reload, struct fw3_state *state);
void fw3_set_defaults(struct fw3_state *state);
void fw3_flush_rules(enum fw3_table table, enum fw3_family family,
- bool pass2, struct fw3_state *state,
- enum fw3_target policy);
+ bool pass2, bool reload, struct fw3_state *state);
void fw3_flush_all(enum fw3_table table);
diff --git a/forwards.c b/forwards.c
index babf5e8..b7e056f 100644
--- a/forwards.c
+++ b/forwards.c
@@ -86,9 +86,11 @@ fw3_load_forwards(struct fw3_state *state, struct uci_package *p)
continue;
}
+ /* NB: forward family... */
if (forward->_dest)
{
- setbit(forward->_dest->flags, FW3_TARGET_ACCEPT);
+ setbit(forward->_dest->flags[0], FW3_TARGET_ACCEPT);
+ setbit(forward->_dest->flags[1], FW3_TARGET_ACCEPT);
if (forward->_src &&
(forward->_src->conntrack || forward->_dest->conntrack))
diff --git a/ipsets.c b/ipsets.c
index 74706ff..48aaa9c 100644
--- a/ipsets.c
+++ b/ipsets.c
@@ -379,9 +379,9 @@ fw3_destroy_ipsets(struct fw3_state *state, enum fw3_family family)
list_for_each_entry_safe(s, tmp, &state->running_ipsets, running_list)
{
- delbit(s->running_flags, family);
+ del(s->flags, family, family);
- if (fw3_no_family(s->running_flags))
+ if (fw3_no_family(s->flags[family == FW3_FAMILY_V6]))
{
info(" * Deleting ipset %s", s->name);
diff --git a/main.c b/main.c
index 47951e6..c1f6505 100644
--- a/main.c
+++ b/main.c
@@ -135,7 +135,7 @@ restore_pipe(enum fw3_family family, bool silent)
static bool
family_running(struct fw3_state *state, enum fw3_family family)
{
- return hasbit(state->defaults.running_flags, family);
+ return has(state->defaults.flags, family, family);
}
static bool
@@ -144,19 +144,13 @@ family_used(enum fw3_family family)
return (use_family == FW3_FAMILY_ANY) || (use_family == family);
}
-static bool
-family_loaded(struct fw3_state *state, enum fw3_family family)
-{
- return hasbit(state->defaults.flags, family);
-}
-
static void
family_set(struct fw3_state *state, enum fw3_family family, bool set)
{
if (set)
- setbit(state->defaults.flags, family);
+ set(state->defaults.flags, family, family);
else
- delbit(state->defaults.flags, family);
+ del(state->defaults.flags, family, family);
}
static int
@@ -167,7 +161,6 @@ stop(struct fw3_state *state, bool complete, bool reload)
int rv = 1;
enum fw3_family family;
enum fw3_table table;
- enum fw3_target policy = reload ? FW3_TARGET_DROP : FW3_TARGET_ACCEPT;
if (!complete && !state->statefile)
{
@@ -203,11 +196,11 @@ stop(struct fw3_state *state, bool complete, bool reload)
else
{
/* pass 1 */
- fw3_flush_rules(table, family, false, state, policy);
+ fw3_flush_rules(table, family, false, reload, state);
fw3_flush_zones(table, family, false, reload, state);
/* pass 2 */
- fw3_flush_rules(table, family, true, state, policy);
+ fw3_flush_rules(table, family, true, reload, state);
fw3_flush_zones(table, family, true, reload, state);
}
@@ -274,7 +267,7 @@ start(struct fw3_state *state, bool reload)
continue;
}
- if (!family_loaded(state, family) || !restore_pipe(family, false))
+ if (!restore_pipe(family, false))
continue;
for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
@@ -286,14 +279,14 @@ start(struct fw3_state *state, bool reload)
fw3_flag_names[family], fw3_flag_names[table]);
fw3_pr("*%s\n", fw3_flag_names[table]);
- fw3_print_default_chains(table, family, state);
- fw3_print_zone_chains(table, family, state);
- fw3_print_default_head_rules(table, family, state);
+ fw3_print_default_chains(table, family, reload, state);
+ fw3_print_zone_chains(table, family, reload, state);
+ fw3_print_default_head_rules(table, family, reload, state);
fw3_print_rules(table, family, state);
fw3_print_redirects(table, family, state);
fw3_print_forwards(table, family, state);
- fw3_print_zone_rules(table, family, state);
- fw3_print_default_tail_rules(table, family, state);
+ fw3_print_zone_rules(table, family, reload, state);
+ fw3_print_default_tail_rules(table, family, reload, state);
fw3_pr("COMMIT\n");
}
diff --git a/options.h b/options.h
index 0bfb3e8..9422f81 100644
--- a/options.h
+++ b/options.h
@@ -73,17 +73,16 @@ enum fw3_target
FW3_TARGET_SRC_ACCEPT = 12,
FW3_TARGET_SRC_REJECT = 13,
FW3_TARGET_SRC_DROP = 14,
- FW3_TARGET_CUSTOM_CNS_V4 = 15,
- FW3_TARGET_CUSTOM_CNS_V6 = 16,
+ FW3_TARGET_CUSTOM_CHAINS = 15,
};
enum fw3_default
{
FW3_DEFAULT_UNSPEC = 0,
- FW3_DEFAULT_CUSTOM_CHAINS = 17,
- FW3_DEFAULT_SYN_FLOOD = 18,
- FW3_DEFAULT_MTU_FIX = 19,
- FW3_DEFAULT_DROP_INVALID = 20,
+ FW3_DEFAULT_CUSTOM_CHAINS = 16,
+ FW3_DEFAULT_SYN_FLOOD = 17,
+ FW3_DEFAULT_MTU_FIX = 18,
+ FW3_DEFAULT_DROP_INVALID = 19,
};
extern const char *fw3_flag_names[FW3_DEFAULT_DROP_INVALID + 1];
@@ -242,8 +241,7 @@ struct fw3_defaults
bool disable_ipv6;
- uint32_t flags;
- uint32_t running_flags;
+ uint32_t flags[2];
};
struct fw3_zone
@@ -279,8 +277,7 @@ struct fw3_zone
bool custom_chains;
- uint32_t flags;
- uint32_t running_flags;
+ uint32_t flags[2];
};
struct fw3_rule
@@ -398,8 +395,7 @@ struct fw3_ipset
const char *external;
- uint32_t flags;
- uint32_t running_flags;
+ uint32_t flags[2];
};
struct fw3_include
diff --git a/redirects.c b/redirects.c
index 23dc034..7cd26c8 100644
--- a/redirects.c
+++ b/redirects.c
@@ -203,16 +203,16 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p)
warn_elem(e, "has no source specified");
else
{
- setbit(redir->_src->flags, redir->target);
+ set(redir->_src->flags, FW3_FAMILY_V4, redir->target);
redir->_src->conntrack = true;
valid = true;
}
if (redir->reflection && redir->_dest && redir->_src->masq)
{
- setbit(redir->_dest->flags, FW3_TARGET_ACCEPT);
- setbit(redir->_dest->flags, FW3_TARGET_DNAT);
- setbit(redir->_dest->flags, FW3_TARGET_SNAT);
+ set(redir->_dest->flags, FW3_FAMILY_V4, FW3_TARGET_ACCEPT);
+ set(redir->_dest->flags, FW3_FAMILY_V4, FW3_TARGET_DNAT);
+ set(redir->_dest->flags, FW3_FAMILY_V4, FW3_TARGET_SNAT);
}
}
else
@@ -225,7 +225,7 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p)
warn_elem(e, "has no src_dip option specified");
else
{
- setbit(redir->_dest->flags, redir->target);
+ set(redir->_dest->flags, FW3_FAMILY_V4, redir->target);
redir->_dest->conntrack = true;
valid = true;
}
@@ -357,7 +357,7 @@ print_redirect(enum fw3_table table, enum fw3_family family,
return;
}
- setbit(redir->_ipset->flags, family);
+ set(redir->_ipset->flags, family, family);
}
fw3_foreach(proto, &redir->proto)
diff --git a/rules.c b/rules.c
index 77fe998..de6ddc9 100644
--- a/rules.c
+++ b/rules.c
@@ -161,8 +161,12 @@ fw3_load_rules(struct fw3_state *state, struct uci_package *p)
rule->target = FW3_TARGET_REJECT;
}
+ /* NB: rule family... */
if (rule->_dest)
- setbit(rule->_dest->flags, rule->target);
+ {
+ setbit(rule->_dest->flags[0], rule->target);
+ setbit(rule->_dest->flags[1], rule->target);
+ }
list_add_tail(&rule->list, &state->rules);
continue;
@@ -312,7 +316,7 @@ expand_rule(enum fw3_table table, enum fw3_family family,
return;
}
- setbit(rule->_ipset->flags, family);
+ set(rule->_ipset->flags, family, family);
}
list_for_each_entry(proto, &rule->proto, list)
diff --git a/utils.c b/utils.c
index ab1d68b..7f2dd64 100644
--- a/utils.c
+++ b/utils.c
@@ -356,7 +356,7 @@ fw3_read_statefile(void *state)
char line[128];
const char *p, *name;
- uint32_t flags;
+ uint32_t flags[2];
struct fw3_state *s = state;
struct fw3_zone *zone;
@@ -380,17 +380,21 @@ fw3_read_statefile(void *state)
if (!name)
continue;
- p = strtok(NULL, " \t\n");
+ if (!(p = strtok(NULL, " \t\n")))
+ continue;
- if (!p)
+ flags[0] = strtoul(p, NULL, 16);
+
+ if (!(p = strtok(NULL, " \t\n")))
continue;
- flags = strtoul(p, NULL, 16);
+ flags[1] = strtoul(p, NULL, 16);
switch (type)
{
case FW3_TYPE_DEFAULTS:
- s->defaults.running_flags = flags;
+ s->defaults.flags[0] = flags[0];
+ s->defaults.flags[1] = flags[1];
break;
case FW3_TYPE_ZONE:
@@ -405,7 +409,8 @@ fw3_read_statefile(void *state)
list_add_tail(&zone->list, &s->zones);
}
- zone->running_flags = flags;
+ zone->flags[0] = flags[0];
+ zone->flags[1] = flags[1];
list_add_tail(&zone->running_list, &s->running_zones);
break;
@@ -421,7 +426,8 @@ fw3_read_statefile(void *state)
list_add_tail(&ipset->list, &s->ipsets);
}
- ipset->running_flags = flags;
+ ipset->flags[0] = flags[0];
+ ipset->flags[1] = flags[1];
list_add_tail(&ipset->running_list, &s->running_ipsets);
break;
}
@@ -441,7 +447,7 @@ fw3_write_statefile(void *state)
struct fw3_zone *z;
struct fw3_ipset *i;
- if (fw3_no_family(d->flags))
+ if (fw3_no_table(d->flags[0]) && fw3_no_table(d->flags[1]))
{
if (unlink(FW3_STATEFILE))
warn("Unable to remove state %s: %s",
@@ -458,16 +464,24 @@ fw3_write_statefile(void *state)
return;
}
- fprintf(sf, "%x - %x\n", FW3_TYPE_DEFAULTS, d->flags);
+ fprintf(sf, "%x - %x %x\n", FW3_TYPE_DEFAULTS, d->flags[0], d->flags[1]);
list_for_each_entry(z, &s->running_zones, running_list)
{
- fprintf(sf, "%x %s %x\n", FW3_TYPE_ZONE, z->name, z->flags);
+ if (!fw3_no_table(z->flags[0]) || !fw3_no_table(z->flags[1]))
+ {
+ fprintf(sf, "%x %s %x %x\n",
+ FW3_TYPE_ZONE, z->name, z->flags[0], z->flags[1]);
+ }
}
list_for_each_entry(i, &s->running_ipsets, running_list)
{
- fprintf(sf, "%x %s %x\n", FW3_TYPE_IPSET, i->name, i->flags);
+ if (!fw3_no_family(i->flags[0]) || !fw3_no_family(i->flags[1]))
+ {
+ fprintf(sf, "%x %s %x %x\n",
+ FW3_TYPE_IPSET, i->name, i->flags[0], i->flags[1]);
+ }
}
fclose(sf);
diff --git a/utils.h b/utils.h
index c3dc974..77d0d73 100644
--- a/utils.h
+++ b/utils.h
@@ -46,6 +46,10 @@ void info(const char *format, ...);
#define delbit(field, flag) field &= ~(1 << (flag))
#define hasbit(field, flag) (field & (1 << (flag)))
+#define set(field, family, flag) setbit(field[family == FW3_FAMILY_V6], flag)
+#define del(field, family, flag) delbit(field[family == FW3_FAMILY_V6], flag)
+#define has(field, family, flag) hasbit(field[family == FW3_FAMILY_V6], flag)
+
#define fw3_foreach(p, h) \
for (p = list_empty(h) ? NULL : list_first_entry(h, typeof(*p), list); \
list_empty(h) ? (p == NULL) : (&p->list != (h)); \
@@ -58,6 +62,11 @@ void info(const char *format, ...);
#define fw3_no_family(flags) \
(!(flags & ((1 << FW3_FAMILY_V4) | (1 << FW3_FAMILY_V6))))
+#define fw3_no_table(flags) \
+ (!(flags & ((1<<FW3_TABLE_FILTER)|(1<<FW3_TABLE_NAT)| \
+ (1<<FW3_TABLE_MANGLE)|(1<<FW3_TABLE_RAW))))
+
+
const char * fw3_find_command(const char *cmd);
bool fw3_stdout_pipe(void);
diff --git a/zones.c b/zones.c
index 4bf7df4..f41cb0f 100644
--- a/zones.c
+++ b/zones.c
@@ -30,33 +30,28 @@ struct chain {
const char *name;
};
-static const struct chain src_chains[] = {
- C(ANY, FILTER, UNSPEC, "zone_%1$s_input"),
- C(ANY, FILTER, UNSPEC, "zone_%1$s_output"),
- C(ANY, FILTER, UNSPEC, "zone_%1$s_forward"),
-
- C(ANY, FILTER, SRC_ACCEPT, "zone_%1$s_src_ACCEPT"),
- C(ANY, FILTER, SRC_REJECT, "zone_%1$s_src_REJECT"),
- C(ANY, FILTER, SRC_DROP, "zone_%1$s_src_DROP"),
-};
+static const struct chain zone_chains[] = {
+ C(ANY, FILTER, UNSPEC, "zone_%1$s_input"),
+ C(ANY, FILTER, UNSPEC, "zone_%1$s_output"),
+ C(ANY, FILTER, UNSPEC, "zone_%1$s_forward"),
+
+ C(ANY, FILTER, SRC_ACCEPT, "zone_%1$s_src_ACCEPT"),
+ C(ANY, FILTER, SRC_REJECT, "zone_%1$s_src_REJECT"),
+ C(ANY, FILTER, SRC_DROP, "zone_%1$s_src_DROP"),
-static const struct chain dst_chains[] = {
- C(ANY, FILTER, ACCEPT, "zone_%1$s_dest_ACCEPT"),
- C(ANY, FILTER, REJECT, "zone_%1$s_dest_REJECT"),
- C(ANY, FILTER, DROP, "zone_%1$s_dest_DROP"),
+ C(ANY, FILTER, ACCEPT, "zone_%1$s_dest_ACCEPT"),
+ C(ANY, FILTER, REJECT, "zone_%1$s_dest_REJECT"),
+ C(ANY, FILTER, DROP, "zone_%1$s_dest_DROP"),
- C(V4, NAT, SNAT, "zone_%1$s_postrouting"),
- C(V4, NAT, DNAT, "zone_%1$s_prerouting"),
+ C(V4, NAT, SNAT, "zone_%1$s_postrouting"),
+ C(V4, NAT, DNAT, "zone_%1$s_prerouting"),
- C(ANY, FILTER, CUSTOM_CNS_V4, "input_%1$s_rule"),
- C(ANY, FILTER, CUSTOM_CNS_V4, "output_%1$s_rule"),
- C(ANY, FILTER, CUSTOM_CNS_V4, "forwarding_%1$s_rule"),
- C(ANY, FILTER, CUSTOM_CNS_V6, "input_%1$s_rule"),
- C(ANY, FILTER, CUSTOM_CNS_V6, "output_%1$s_rule"),
- C(ANY, FILTER, CUSTOM_CNS_V6, "forwarding_%1$s_rule"),
+ C(ANY, FILTER, CUSTOM_CHAINS, "input_%1$s_rule"),
+ C(ANY, FILTER, CUSTOM_CHAINS, "output_%1$s_rule"),
+ C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_%1$s_rule"),
- C(V4, NAT, CUSTOM_CNS_V4, "prerouting_%1$s_rule"),
- C(V4, NAT, CUSTOM_CNS_V4, "postrouting_%1$s_rule"),
+ C(V4, NAT, CUSTOM_CHAINS, "prerouting_%1$s_rule"),
+ C(V4, NAT, CUSTOM_CHAINS, "postrouting_%1$s_rule"),
};
@@ -64,16 +59,13 @@ static const struct chain dst_chains[] = {
"zone_%1$s_" #dir1 " -m comment --comment \"user chain for %1$s " \
#dir2 "\" -j " #dir2 "_%1$s_rule"
-static const struct chain def_rules[] = {
- C(ANY, FILTER, CUSTOM_CNS_V4, R(input, input)),
- C(ANY, FILTER, CUSTOM_CNS_V4, R(output, output)),
- C(ANY, FILTER, CUSTOM_CNS_V4, R(forward, forwarding)),
- C(ANY, FILTER, CUSTOM_CNS_V6, R(input, input)),
- C(ANY, FILTER, CUSTOM_CNS_V6, R(output, output)),
- C(ANY, FILTER, CUSTOM_CNS_V6, R(forward, forwarding)),
+static const struct chain zone_rules[] = {
+ C(ANY, FILTER, CUSTOM_CHAINS, R(input, input)),
+ C(ANY, FILTER, CUSTOM_CHAINS, R(output, output)),
+ C(ANY, FILTER, CUSTOM_CHAINS, R(forward, forwarding)),
- C(V4, NAT, CUSTOM_CNS_V4, R(prerouting, prerouting)),
- C(V4, NAT, CUSTOM_CNS_V4, R(postrouting, postrouting)),
+ C(V4, NAT, CUSTOM_CHAINS, R(prerouting, prerouting)),
+ C(V4, NAT, CUSTOM_CHAINS, R(postrouting, postrouting)),
};
const struct fw3_option fw3_zone_opts[] = {
@@ -111,12 +103,16 @@ const struct fw3_option fw3_zone_opts[] = {
static bool
print_chains(enum fw3_table table, enum fw3_family family,
- const char *fmt, const char *name, uint32_t targets,
+ const char *fmt, const char *name, uint32_t *targets, uint32_t mask,
const struct chain *chains, int n)
{
bool rv = false;
char cn[256] = { 0 };
const struct chain *c;
+ uint32_t t = targets ? targets[family == FW3_FAMILY_V6] : 0;
+
+ if (mask)
+ t &= mask;
for (c = chains; n > 0; c++, n--)
{
@@ -126,7 +122,7 @@ print_chains(enum fw3_table table, enum fw3_family family,
if (c->table != table)
continue;
- if ((c->target != FW3_TARGET_UNSPEC) && !hasbit(targets, c->target))
+ if ((c->target != FW3_TARGET_UNSPEC) && !hasbit(t, c->target))
continue;
snprintf(cn, sizeof(cn), c->name, name);
@@ -255,19 +251,23 @@ fw3_load_zones(struct fw3_state *state, struct uci_package *p)
if (zone->masq)
{
- setbit(zone->flags, FW3_TARGET_SNAT);
+ setbit(zone->flags[0], FW3_TARGET_SNAT);
zone->conntrack = true;
}
if (zone->custom_chains)
{
- setbit(zone->flags, FW3_TARGET_SNAT);
- setbit(zone->flags, FW3_TARGET_DNAT);
+ setbit(zone->flags[0], FW3_TARGET_SNAT);
+ setbit(zone->flags[0], FW3_TARGET_DNAT);
}
- setbit(zone->flags, fw3_to_src_target(zone->policy_input));
- setbit(zone->flags, zone->policy_output);
- setbit(zone->flags, zone->policy_forward);
+ setbit(zone->flags[0], fw3_to_src_target(zone->policy_input));
+ setbit(zone->flags[0], zone->policy_output);
+ setbit(zone->flags[0], zone->policy_forward);
+
+ setbit(zone->flags[1], fw3_to_src_target(zone->policy_input));
+ setbit(zone->flags[1], zone->policy_output);
+ setbit(zone->flags[1], zone->policy_forward);
list_add_tail(&zone->list, &state->zones);
}
@@ -276,52 +276,47 @@ fw3_load_zones(struct fw3_state *state, struct uci_package *p)
static void
print_zone_chain(enum fw3_table table, enum fw3_family family,
- struct fw3_zone *zone, struct fw3_state *state)
+ struct fw3_zone *zone, bool reload, struct fw3_state *state)
{
- bool s, d, r;
- enum fw3_target f;
+ bool c, r;
uint32_t custom_mask = ~0;
if (!fw3_is_family(zone, family))
return;
- setbit(zone->flags, family);
+ set(zone->flags, family, table);
- /* user chains already loaded, don't create again */
- for (f = FW3_TARGET_CUSTOM_CNS_V4; f <= FW3_TARGET_CUSTOM_CNS_V6; f++)
- if (hasbit(zone->running_flags, f))
- delbit(custom_mask, f);
+ /* Don't touch user chains on reload */
+ if (reload)
+ delbit(custom_mask, FW3_TARGET_CUSTOM_CHAINS);
if (zone->custom_chains)
- setbit(zone->flags, (family == FW3_FAMILY_V4) ?
- FW3_TARGET_CUSTOM_CNS_V4 : FW3_TARGET_CUSTOM_CNS_V6);
+ set(zone->flags, family, FW3_TARGET_CUSTOM_CHAINS);
if (!zone->conntrack && !state->defaults.drop_invalid)
- setbit(zone->flags, FW3_TARGET_NOTRACK);
-
- s = print_chains(table, family, ":%s - [0:0]\n", zone->name,
- zone->flags,
- src_chains, ARRAY_SIZE(src_chains));
+ set(zone->flags, family, FW3_TARGET_NOTRACK);
- d = print_chains(table, family, ":%s - [0:0]\n", zone->name,
- zone->flags & custom_mask,
- dst_chains, ARRAY_SIZE(dst_chains));
+ c = print_chains(table, family, ":%s - [0:0]\n", zone->name,
+ zone->flags, custom_mask,
+ zone_chains, ARRAY_SIZE(zone_chains));
r = print_chains(table, family, "-A %s\n", zone->name,
- zone->flags,
- def_rules, ARRAY_SIZE(def_rules));
+ zone->flags, 0,
+ zone_rules, ARRAY_SIZE(zone_rules));
- if (s || d || r)
+ if (c || r)
{
info(" * Zone '%s'", zone->name);
fw3_set_running(zone, &state->running_zones);
+
+ set(zone->flags, family, table);
}
}
static void
print_interface_rule(enum fw3_table table, enum fw3_family family,
struct fw3_zone *zone, struct fw3_device *dev,
- struct fw3_address *sub, bool disable_notrack)
+ struct fw3_address *sub, bool reload, bool disable_notrack)
{
enum fw3_target t;
@@ -332,7 +327,7 @@ print_interface_rule(enum fw3_table table, enum fw3_family family,
{
for (t = FW3_TARGET_ACCEPT; t <= FW3_TARGET_DROP; t++)
{
- if (hasbit(zone->flags, fw3_to_src_target(t)))
+ if (has(zone->flags, family, fw3_to_src_target(t)))
{
fw3_pr("-A zone_%s_src_%s", zone->name, fw3_flag_names[t]);
fw3_format_in_out(dev, NULL);
@@ -341,7 +336,7 @@ print_interface_rule(enum fw3_table table, enum fw3_family family,
fw3_pr(" -j %s\n", jump_target(t));
}
- if (hasbit(zone->flags, t))
+ if (has(zone->flags, family, t))
{
fw3_pr("-A zone_%s_dest_%s", zone->name, fw3_flag_names[t]);
fw3_format_in_out(NULL, dev);
@@ -371,7 +366,7 @@ print_interface_rule(enum fw3_table table, enum fw3_family family,
}
else if (table == FW3_TABLE_NAT)
{
- if (hasbit(zone->flags, FW3_TARGET_DNAT))
+ if (has(zone->flags, family, FW3_TARGET_DNAT))
{
fw3_pr("-A delegate_prerouting");
fw3_format_in_out(dev, NULL);
@@ -380,7 +375,7 @@ print_interface_rule(enum fw3_table table, enum fw3_family family,
fw3_pr(" -j zone_%s_prerouting\n", zone->name);
}
- if (hasbit(zone->flags, FW3_TARGET_SNAT))
+ if (has(zone->flags, family, FW3_TARGET_SNAT))
{
fw3_pr("-A delegate_postrouting");
fw3_format_in_out(NULL, dev);
@@ -428,7 +423,7 @@ print_interface_rule(enum fw3_table table, enum fw3_family family,
static void
print_interface_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_zone *zone, bool disable_notrack)
+ struct fw3_zone *zone, bool reload, bool disable_notrack)
{
struct fw3_device *dev;
struct fw3_address *sub;
@@ -442,13 +437,13 @@ print_interface_rules(enum fw3_table table, enum fw3_family family,
if (!dev && !sub)
continue;
- print_interface_rule(table, family, zone, dev, sub, disable_notrack);
+ print_interface_rule(table, family, zone, dev, sub, reload, disable_notrack);
}
}
static void
print_zone_rule(enum fw3_table table, enum fw3_family family,
- struct fw3_zone *zone, bool disable_notrack)
+ struct fw3_zone *zone, bool reload, bool disable_notrack)
{
struct fw3_address *msrc;
struct fw3_address *mdest;
@@ -474,7 +469,7 @@ print_zone_rule(enum fw3_table table, enum fw3_family family,
{
for (t = FW3_TARGET_REJECT; t <= FW3_TARGET_DROP; t++)
{
- if (hasbit(zone->flags, fw3_to_src_target(t)))
+ if (has(zone->flags, family, fw3_to_src_target(t)))
{
fw3_pr("-A zone_%s_src_%s", zone->name, fw3_flag_names[t]);
fw3_format_limit(&zone->log_limit);
@@ -482,7 +477,7 @@ print_zone_rule(enum fw3_table table, enum fw3_family family,
fw3_flag_names[t], zone->name);
}
- if (hasbit(zone->flags, t))
+ if (has(zone->flags, family, t))
{
fw3_pr("-A zone_%s_dest_%s", zone->name, fw3_flag_names[t]);
fw3_format_limit(&zone->log_limit);
@@ -511,27 +506,27 @@ print_zone_rule(enum fw3_table table, enum fw3_family family,
break;
}
- print_interface_rules(table, family, zone, disable_notrack);
+ print_interface_rules(table, family, zone, reload, disable_notrack);
}
void
fw3_print_zone_chains(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state)
+ bool reload, struct fw3_state *state)
{
struct fw3_zone *zone;
list_for_each_entry(zone, &state->zones, list)
- print_zone_chain(table, family, zone, state);
+ print_zone_chain(table, family, zone, reload, state);
}
void
fw3_print_zone_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state)
+ bool reload, struct fw3_state *state)
{
struct fw3_zone *zone;
list_for_each_entry(zone, &state->zones, list)
- print_zone_rule(table, family, zone, state->defaults.drop_invalid);
+ print_zone_rule(table, family, zone, reload, state->defaults.drop_invalid);
}
void
@@ -543,30 +538,20 @@ fw3_flush_zones(enum fw3_table table, enum fw3_family family,
/* don't touch user chains on selective stop */
if (reload)
- {
- delbit(custom_mask, FW3_TARGET_CUSTOM_CNS_V4);
- delbit(custom_mask, FW3_TARGET_CUSTOM_CNS_V6);
- }
+ delbit(custom_mask, FW3_TARGET_CUSTOM_CHAINS);
list_for_each_entry_safe(z, tmp, &state->running_zones, running_list)
{
- if (!hasbit(z->flags, family))
+ if (!has(z->flags, family, table))
continue;
print_chains(table, family, pass2 ? "-X %s\n" : "-F %s\n",
- z->name, z->running_flags,
- src_chains, ARRAY_SIZE(src_chains));
-
- print_chains(table, family, pass2 ? "-X %s\n" : "-F %s\n",
- z->name, z->running_flags & custom_mask,
- dst_chains, ARRAY_SIZE(dst_chains));
+ z->name, z->flags, custom_mask,
+ zone_chains, ARRAY_SIZE(zone_chains));
if (pass2)
{
- delbit(z->running_flags, family);
-
- if (fw3_no_family(z->running_flags))
- fw3_set_running(z, NULL);
+ del(z->flags, family, table);
}
}
}
diff --git a/zones.h b/zones.h
index 7fd8e4c..c84897b 100644
--- a/zones.h
+++ b/zones.h
@@ -28,10 +28,10 @@ struct fw3_zone * fw3_alloc_zone(void);
void fw3_load_zones(struct fw3_state *state, struct uci_package *p);
void fw3_print_zone_chains(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state);
+ bool reload, struct fw3_state *state);
void fw3_print_zone_rules(enum fw3_table table, enum fw3_family family,
- struct fw3_state *state);
+ bool reload, struct fw3_state *state);
void fw3_flush_zones(enum fw3_table table, enum fw3_family family,
bool pass2, bool reload, struct fw3_state *state);