+static bool
+check_forward(struct fw3_state *state, struct fw3_forward *forward, struct uci_element *e)
+{
+ if (!forward->enabled)
+ return false;
+
+ if (forward->src.invert || forward->dest.invert)
+ {
+ warn_section("forward", forward, e, "must not have inverted 'src' or 'dest' options");
+ return false;
+ }
+ else if (forward->src.set && !forward->src.any &&
+ !(forward->_src = fw3_lookup_zone(state, forward->src.name)))
+ {
+ warn_section("forward", forward, e, "refers to not existing zone '%s'",
+ forward->src.name);
+ return false;
+ }
+ else if (forward->dest.set && !forward->dest.any &&
+ !(forward->_dest = fw3_lookup_zone(state, forward->dest.name)))
+ {
+ warn_section("forward", forward, e, "refers to not existing zone '%s'",
+ forward->dest.name);
+ return false;
+ }
+
+ /* NB: forward family... */
+ if (forward->_dest)
+ {
+ fw3_setbit(forward->_dest->flags[0], FW3_FLAG_ACCEPT);
+ fw3_setbit(forward->_dest->flags[1], FW3_FLAG_ACCEPT);
+ }
+
+ return true;
+}
+
+static struct fw3_forward *
+fw3_alloc_forward(struct fw3_state *state)
+{
+ struct fw3_forward *forward;
+
+ forward = calloc(1, sizeof(*forward));
+ if (!forward)
+ return NULL;
+
+ forward->enabled = true;
+
+ list_add_tail(&forward->list, &state->forwards);
+
+ return forward;
+}