diff options
-rw-r--r-- | helpers.c | 56 | ||||
-rw-r--r-- | helpers.h | 3 | ||||
-rw-r--r-- | options.h | 2 | ||||
-rw-r--r-- | redirects.c | 2 | ||||
-rw-r--r-- | rules.c | 4 |
5 files changed, 56 insertions, 11 deletions
@@ -25,7 +25,7 @@ const struct fw3_option fw3_cthelper_opts[] = { 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), { } @@ -47,6 +47,23 @@ test_module(struct fw3_cthelper *helper) } 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) { if (!helper->name || !*helper->name) @@ -57,7 +74,7 @@ check_cthelper(struct fw3_state *state, struct fw3_cthelper *helper, struct uci_ { 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"); } @@ -84,6 +101,7 @@ fw3_alloc_cthelper(struct fw3_state *state) helper->enabled = true; helper->family = FW3_FAMILY_ANY; + INIT_LIST_HEAD(&helper->proto); list_add_tail(&helper->list, &state->cthelpers); @@ -157,6 +175,20 @@ fw3_lookup_cthelper(struct fw3_state *state, const char *name) 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, @@ -178,7 +210,7 @@ fw3_lookup_cthelper_by_proto_port(struct fw3_state *state, 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)) @@ -198,11 +230,11 @@ fw3_lookup_cthelper_by_proto_port(struct fw3_state *state, 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); @@ -215,6 +247,16 @@ print_helper_rule(struct fw3_ipt_handle *handle, struct fw3_cthelper *helper, 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) @@ -249,7 +291,7 @@ fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state, if (!test_module(helper)) continue; - print_helper_rule(handle, helper, zone); + expand_helper_rule(handle, helper, zone); } } else @@ -271,7 +313,7 @@ fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state, continue; } - print_helper_rule(handle, helper, zone); + expand_helper_rule(handle, helper, zone); } } } @@ -41,6 +41,9 @@ void fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state, struct fw3_zone *zone); +bool +fw3_cthelper_check_proto(const struct fw3_cthelper *h, const struct fw3_protocol *proto); + static inline void fw3_free_cthelper(struct fw3_cthelper *helper) { list_del(&helper->list); @@ -526,7 +526,7 @@ struct fw3_cthelper const char *module; const char *description; enum fw3_family family; - struct fw3_protocol proto; + struct list_head proto; struct fw3_port port; }; diff --git a/redirects.c b/redirects.c index 660cdd2..7f9948c 100644 --- a/redirects.c +++ b/redirects.c @@ -576,7 +576,7 @@ print_redirect(struct fw3_ipt_handle *h, struct fw3_state *state, case FW3_TABLE_RAW: if (redir->target == FW3_FLAG_DNAT && redir->helper.ptr) { - if (redir->helper.ptr->proto.protocol != proto->protocol) + if (!fw3_cthelper_check_proto(redir->helper.ptr, proto)) { info(" ! Skipping protocol %s since helper '%s' does not support it", fw3_protoname(proto), redir->helper.ptr->name); @@ -436,7 +436,7 @@ print_rule(struct fw3_ipt_handle *handle, struct fw3_state *state, } if (rule->helper.ptr && - rule->helper.ptr->proto.protocol != proto->protocol) + !fw3_cthelper_check_proto(rule->helper.ptr, proto)) { info(" ! Skipping protocol %s since helper '%s' does not support it", fw3_protoname(proto), rule->helper.ptr->name); @@ -444,7 +444,7 @@ print_rule(struct fw3_ipt_handle *handle, struct fw3_state *state, } if (rule->set_helper.ptr && - rule->set_helper.ptr->proto.protocol != proto->protocol) + !fw3_cthelper_check_proto(rule->set_helper.ptr, proto)) { info(" ! Skipping protocol %s since helper '%s' does not support it", fw3_protoname(proto), rule->helper.ptr->name); |