Skip to content

Commit 08b2c61

Browse files
pticonblogic
authored andcommitted
helpers: make the proto field as a list rather than one option
The field proto in the struct fw3_cthelper should be implemented as a list in order to support multiple protocols. For example, the helper for SIP should be able to support both TCP and UDP within only one entry in the config file. config helper option name 'sip' option description 'SIP VoIP connection tracking' option module 'nf_conntrack_sip' option family 'any' option proto 'tcpudp' option port '5060' Signed-off-by: Pierre Lebleu <[email protected]>
1 parent 35b3e74 commit 08b2c61

File tree

5 files changed

+56
-11
lines changed

5 files changed

+56
-11
lines changed

helpers.c

+49-7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const struct fw3_option fw3_cthelper_opts[] = {
2525
FW3_OPT("module", string, cthelper, module),
2626
FW3_OPT("description", string, cthelper, description),
2727
FW3_OPT("family", family, cthelper, family),
28-
FW3_OPT("proto", protocol, cthelper, proto),
28+
FW3_LIST("proto", protocol, cthelper, proto),
2929
FW3_OPT("port", port, cthelper, port),
3030

3131
{ }
@@ -46,6 +46,23 @@ test_module(struct fw3_cthelper *helper)
4646
return true;
4747
}
4848

49+
static bool
50+
check_cthelper_proto(const struct fw3_cthelper *helper)
51+
{
52+
struct fw3_protocol *proto;
53+
54+
if (list_empty(&helper->proto))
55+
return false;
56+
57+
list_for_each_entry(proto, &helper->proto, list)
58+
{
59+
if (!proto->protocol || proto->any || proto->invert)
60+
return false;
61+
}
62+
63+
return true;
64+
}
65+
4966
static bool
5067
check_cthelper(struct fw3_state *state, struct fw3_cthelper *helper, struct uci_element *e)
5168
{
@@ -57,7 +74,7 @@ check_cthelper(struct fw3_state *state, struct fw3_cthelper *helper, struct uci_
5774
{
5875
warn_section("helper", helper, e, "must have a module assigned");
5976
}
60-
else if (!helper->proto.protocol || helper->proto.any || helper->proto.invert)
77+
else if (!check_cthelper_proto(helper))
6178
{
6279
warn_section("helper", helper, e, "must specify a protocol");
6380
}
@@ -84,6 +101,7 @@ fw3_alloc_cthelper(struct fw3_state *state)
84101

85102
helper->enabled = true;
86103
helper->family = FW3_FAMILY_ANY;
104+
INIT_LIST_HEAD(&helper->proto);
87105

88106
list_add_tail(&helper->list, &state->cthelpers);
89107

@@ -157,6 +175,20 @@ fw3_lookup_cthelper(struct fw3_state *state, const char *name)
157175
return NULL;
158176
}
159177

178+
bool
179+
fw3_cthelper_check_proto(const struct fw3_cthelper *h, const struct fw3_protocol *proto)
180+
{
181+
struct fw3_protocol *p;
182+
183+
list_for_each_entry(p, &h->proto, list)
184+
{
185+
if (p->protocol == proto->protocol)
186+
return true;
187+
}
188+
189+
return false;
190+
}
191+
160192
struct fw3_cthelper *
161193
fw3_lookup_cthelper_by_proto_port(struct fw3_state *state,
162194
struct fw3_protocol *proto,
@@ -178,7 +210,7 @@ fw3_lookup_cthelper_by_proto_port(struct fw3_state *state,
178210
if (!h->enabled)
179211
continue;
180212

181-
if (h->proto.protocol != proto->protocol)
213+
if (!fw3_cthelper_check_proto(h, proto))
182214
continue;
183215

184216
if (h->port.set && (!port || !port->set))
@@ -198,11 +230,11 @@ fw3_lookup_cthelper_by_proto_port(struct fw3_state *state,
198230

199231
static void
200232
print_helper_rule(struct fw3_ipt_handle *handle, struct fw3_cthelper *helper,
201-
struct fw3_zone *zone)
233+
struct fw3_zone *zone, struct fw3_protocol *proto)
202234
{
203235
struct fw3_ipt_rule *r;
204236

205-
r = fw3_ipt_rule_create(handle, &helper->proto, NULL, NULL, NULL, NULL);
237+
r = fw3_ipt_rule_create(handle, proto, NULL, NULL, NULL, NULL);
206238

207239
if (helper->description && *helper->description)
208240
fw3_ipt_rule_comment(r, helper->description);
@@ -215,6 +247,16 @@ print_helper_rule(struct fw3_ipt_handle *handle, struct fw3_cthelper *helper,
215247
fw3_ipt_rule_replace(r, "zone_%s_helper", zone->name);
216248
}
217249

250+
static void
251+
expand_helper_rule(struct fw3_ipt_handle *handle, struct fw3_cthelper *helper,
252+
struct fw3_zone *zone)
253+
{
254+
struct fw3_protocol *proto;
255+
256+
list_for_each_entry(proto, &helper->proto, list)
257+
print_helper_rule(handle, helper, zone, proto);
258+
}
259+
218260
void
219261
fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state,
220262
struct fw3_zone *zone)
@@ -249,7 +291,7 @@ fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state,
249291
if (!test_module(helper))
250292
continue;
251293

252-
print_helper_rule(handle, helper, zone);
294+
expand_helper_rule(handle, helper, zone);
253295
}
254296
}
255297
else
@@ -271,7 +313,7 @@ fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state,
271313
continue;
272314
}
273315

274-
print_helper_rule(handle, helper, zone);
316+
expand_helper_rule(handle, helper, zone);
275317
}
276318
}
277319
}

helpers.h

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ void
4141
fw3_print_cthelpers(struct fw3_ipt_handle *handle, struct fw3_state *state,
4242
struct fw3_zone *zone);
4343

44+
bool
45+
fw3_cthelper_check_proto(const struct fw3_cthelper *h, const struct fw3_protocol *proto);
46+
4447
static inline void fw3_free_cthelper(struct fw3_cthelper *helper)
4548
{
4649
list_del(&helper->list);

options.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ struct fw3_cthelper
526526
const char *module;
527527
const char *description;
528528
enum fw3_family family;
529-
struct fw3_protocol proto;
529+
struct list_head proto;
530530
struct fw3_port port;
531531
};
532532

redirects.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ print_redirect(struct fw3_ipt_handle *h, struct fw3_state *state,
576576
case FW3_TABLE_RAW:
577577
if (redir->target == FW3_FLAG_DNAT && redir->helper.ptr)
578578
{
579-
if (redir->helper.ptr->proto.protocol != proto->protocol)
579+
if (!fw3_cthelper_check_proto(redir->helper.ptr, proto))
580580
{
581581
info(" ! Skipping protocol %s since helper '%s' does not support it",
582582
fw3_protoname(proto), redir->helper.ptr->name);

rules.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -436,15 +436,15 @@ print_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
436436
}
437437

438438
if (rule->helper.ptr &&
439-
rule->helper.ptr->proto.protocol != proto->protocol)
439+
!fw3_cthelper_check_proto(rule->helper.ptr, proto))
440440
{
441441
info(" ! Skipping protocol %s since helper '%s' does not support it",
442442
fw3_protoname(proto), rule->helper.ptr->name);
443443
return;
444444
}
445445

446446
if (rule->set_helper.ptr &&
447-
rule->set_helper.ptr->proto.protocol != proto->protocol)
447+
!fw3_cthelper_check_proto(rule->set_helper.ptr, proto))
448448
{
449449
info(" ! Skipping protocol %s since helper '%s' does not support it",
450450
fw3_protoname(proto), rule->helper.ptr->name);

0 commit comments

Comments
 (0)