FW3_OPT("module", string, cthelper, module),
FW3_OPT("description", string, cthelper, description),
FW3_OPT("family", family, cthelper, family),
- FW3_OPT("proto", protocol, cthelper, proto),
+ FW3_LIST("proto", protocol, cthelper, proto),
FW3_OPT("port", port, cthelper, port),
{ }
return true;
}
+static bool
+check_cthelper_proto(const struct fw3_cthelper *helper)
+{
+ struct fw3_protocol *proto;
+
+ if (list_empty(&helper->proto))
+ return false;
+
+ list_for_each_entry(proto, &helper->proto, list)
+ {
+ if (!proto->protocol || proto->any || proto->invert)
+ return false;
+ }
+
+ return true;
+}
+
static bool
check_cthelper(struct fw3_state *state, struct fw3_cthelper *helper, struct uci_element *e)
{
{
warn_section("helper", helper, e, "must have a module assigned");
}
- else if (!helper->proto.protocol || helper->proto.any || helper->proto.invert)
+ else if (!check_cthelper_proto(helper))
{
warn_section("helper", helper, e, "must specify a protocol");
}
helper->enabled = true;
helper->family = FW3_FAMILY_ANY;
+ INIT_LIST_HEAD(&helper->proto);
list_add_tail(&helper->list, &state->cthelpers);
return NULL;
}
+bool
+fw3_cthelper_check_proto(const struct fw3_cthelper *h, const struct fw3_protocol *proto)
+{
+ struct fw3_protocol *p;
+
+ list_for_each_entry(p, &h->proto, list)
+ {
+ if (p->protocol == proto->protocol)
+ return true;
+ }
+
+ return false;
+}
+
struct fw3_cthelper *
fw3_lookup_cthelper_by_proto_port(struct fw3_state *state,
struct fw3_protocol *proto,
if (!h->enabled)
continue;
- if (h->proto.protocol != proto->protocol)
+ if (!fw3_cthelper_check_proto(h, proto))
continue;
if (h->port.set && (!port || !port->set))
static void
print_helper_rule(struct fw3_ipt_handle *handle, struct fw3_cthelper *helper,
- struct fw3_zone *zone)
+ struct fw3_zone *zone, struct fw3_protocol *proto)
{
struct fw3_ipt_rule *r;
- r = fw3_ipt_rule_create(handle, &helper->proto, NULL, NULL, NULL, NULL);
+ r = fw3_ipt_rule_create(handle, proto, NULL, NULL, NULL, NULL);
if (helper->description && *helper->description)
fw3_ipt_rule_comment(r, helper->description);
fw3_ipt_rule_replace(r, "zone_%s_helper", zone->name);
}
+static void
+expand_helper_rule(struct fw3_ipt_handle *handle, struct fw3_cthelper *helper,
+ struct fw3_zone *zone)
+{
+ struct fw3_protocol *proto;
+
+ list_for_each_entry(proto, &helper->proto, list)
+ print_helper_rule(handle, helper, zone, proto);
+}
+
void
fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state,
struct fw3_zone *zone)
if (!test_module(helper))
continue;
- print_helper_rule(handle, helper, zone);
+ expand_helper_rule(handle, helper, zone);
}
}
else
continue;
}
- print_helper_rule(handle, helper, zone);
+ expand_helper_rule(handle, helper, zone);
}
}
}