Skip to content

Commit c2e4c28

Browse files
committed
firewall3: enable nat6
Make ipv6 nat managed by firewall3. Add masq6 option in zone for nat6 masquerading. Signed-off-by: Yanlong Wang <[email protected]>
1 parent fe9602c commit c2e4c28

File tree

7 files changed

+153
-16
lines changed

7 files changed

+153
-16
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ ENDIF()
1919

2020
IF (NOT DISABLE_IPV6)
2121
LIST(APPEND iptc_libs ip6tc)
22+
IF (ENABLE_NAT6)
23+
ADD_DEFINITIONS(-DENABLE_NAT6)
24+
ENDIF()
2225
ELSE()
2326
ADD_DEFINITIONS(-DDISABLE_IPV6)
2427
ENDIF()

defaults.c

+5
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ static const struct fw3_chain_spec default_chains[] = {
2929
C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_rule"),
3030
C(ANY, FILTER, SYN_FLOOD, "syn_flood"),
3131

32+
#ifdef ENABLE_NAT6
33+
C(ANY, NAT, CUSTOM_CHAINS, "prerouting_rule"),
34+
C(ANY, NAT, CUSTOM_CHAINS, "postrouting_rule"),
35+
#else
3236
C(V4, NAT, CUSTOM_CHAINS, "prerouting_rule"),
3337
C(V4, NAT, CUSTOM_CHAINS, "postrouting_rule"),
38+
#endif
3439

3540
{ }
3641
};

options.h

+4
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ struct fw3_time
263263

264264
struct fw3_mark
265265
{
266+
struct list_head list;
267+
266268
bool set;
267269
bool invert;
268270
uint32_t mark;
@@ -341,6 +343,8 @@ struct fw3_zone
341343
struct list_head masq_src;
342344
struct list_head masq_dest;
343345

346+
bool masq6;
347+
344348
bool mtu_fix;
345349

346350
struct list_head cthelpers;

redirects.c

+84-13
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,27 @@ check_families(struct uci_element *e, struct fw3_redirect *r)
124124
static bool
125125
compare_addr(struct fw3_address *a, struct fw3_address *b)
126126
{
127-
if (a->family != FW3_FAMILY_V4 || b->family != FW3_FAMILY_V4)
128-
return false;
129-
130-
return ((a->address.v4.s_addr & a->mask.v4.s_addr) ==
127+
if (a->family == FW3_FAMILY_V4) {
128+
if (b->family != FW3_FAMILY_V4) {
129+
return false;
130+
}
131+
return ((a->address.v4.s_addr & a->mask.v4.s_addr) ==
131132
(b->address.v4.s_addr & a->mask.v4.s_addr));
133+
}
134+
135+
if (a->family == FW3_FAMILY_V6) {
136+
if (b->family != FW3_FAMILY_V6) {
137+
return false;
138+
}
139+
bool r = true;
140+
int i;
141+
for (i = 0; i < 4; i++)
142+
r = r && ((a->address.v6.s6_addr32[i] & a->mask.v6.s6_addr32[i]) ==
143+
(b->address.v6.s6_addr32[i] & a->mask.v6.s6_addr32[i]));
144+
return r;
145+
}
146+
147+
return false;
132148
}
133149

134150
static bool
@@ -223,6 +239,11 @@ select_helper(struct fw3_state *state, struct fw3_redirect *redir)
223239
redir->helper.ptr = helper;
224240

225241
set(redir->_src->flags, FW3_FAMILY_V4, FW3_FLAG_HELPER);
242+
243+
#ifdef ENABLE_NAT6
244+
set(redir->_src->flags, FW3_FAMILY_V6, FW3_FLAG_HELPER);
245+
#endif
246+
226247
}
227248

228249
static bool
@@ -297,8 +318,14 @@ check_redirect(struct fw3_state *state, struct fw3_redirect *redir, struct uci_e
297318
else if (redir->helper.invert)
298319
warn_section("redirect", redir, e, "must not use a negated helper match");
299320
else
300-
{
301-
set(redir->_src->flags, FW3_FAMILY_V4, redir->target);
321+
{
322+
#ifdef ENABLE_NAT6
323+
if (fw3_is_family(redir, FW3_FAMILY_V6))
324+
set(redir->_src->flags, FW3_FAMILY_V6, redir->target);
325+
if (fw3_is_family(redir, FW3_FAMILY_V4))
326+
#endif
327+
set(redir->_src->flags, FW3_FAMILY_V4, redir->target);
328+
302329
valid = true;
303330

304331
if (!check_local(e, redir, state) && !redir->dest.set &&
@@ -309,15 +336,32 @@ check_redirect(struct fw3_state *state, struct fw3_redirect *redir, struct uci_e
309336
redir->dest.name);
310337
}
311338

312-
if (redir->reflection && redir->_dest && redir->_src->masq)
339+
if (redir->reflection && redir->_dest)
313340
{
314-
set(redir->_dest->flags, FW3_FAMILY_V4, FW3_FLAG_ACCEPT);
315-
set(redir->_dest->flags, FW3_FAMILY_V4, FW3_FLAG_DNAT);
316-
set(redir->_dest->flags, FW3_FAMILY_V4, FW3_FLAG_SNAT);
341+
if (redir->_src->masq && fw3_is_family(redir->_dest, FW3_FAMILY_V4)) {
342+
set(redir->_dest->flags, FW3_FAMILY_V4, FW3_FLAG_ACCEPT);
343+
set(redir->_dest->flags, FW3_FAMILY_V4, FW3_FLAG_DNAT);
344+
set(redir->_dest->flags, FW3_FAMILY_V4, FW3_FLAG_SNAT);
345+
}
346+
#ifdef ENABLE_NAT6
347+
if (redir->_src->masq6 && fw3_is_family(redir->_dest, FW3_FAMILY_V6)) {
348+
set(redir->_dest->flags, FW3_FAMILY_V6, FW3_FLAG_ACCEPT);
349+
set(redir->_dest->flags, FW3_FAMILY_V6, FW3_FLAG_DNAT);
350+
set(redir->_dest->flags, FW3_FAMILY_V6, FW3_FLAG_SNAT);
351+
}
352+
#endif
317353
}
318354

319355
if (redir->helper.ptr)
356+
{
320357
set(redir->_src->flags, FW3_FAMILY_V4, FW3_FLAG_HELPER);
358+
359+
#ifdef ENABLE_NAT6
360+
set(redir->_src->flags, FW3_FAMILY_V6, FW3_FLAG_HELPER);
361+
#endif
362+
363+
}
364+
321365
}
322366
}
323367
else
@@ -336,6 +380,11 @@ check_redirect(struct fw3_state *state, struct fw3_redirect *redir, struct uci_e
336380
else
337381
{
338382
set(redir->_dest->flags, FW3_FAMILY_V4, redir->target);
383+
384+
#ifdef ENABLE_NAT6
385+
set(redir->_dest->flags, FW3_FAMILY_V6, redir->target);
386+
#endif
387+
339388
valid = true;
340389
}
341390
}
@@ -475,13 +524,22 @@ static void
475524
set_snat_dnat(struct fw3_ipt_rule *r, enum fw3_flag target,
476525
struct fw3_address *addr, struct fw3_port *port)
477526
{
527+
#ifdef ENABLE_NAT6
528+
char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:65535-65535\0")];
529+
#else
478530
char buf[sizeof("255.255.255.255:65535-65535\0")];
531+
#endif
479532

480533
buf[0] = '\0';
481534

482535
if (addr && addr->set)
483536
{
484-
inet_ntop(AF_INET, &addr->address.v4, buf, sizeof(buf));
537+
#ifdef ENABLE_NAT6
538+
if (addr->family == FW3_FAMILY_V6)
539+
inet_ntop(AF_INET6, &addr->address.v6, buf, sizeof(buf));
540+
else
541+
#endif
542+
inet_ntop(AF_INET, &addr->address.v4, buf, sizeof(buf));
485543
}
486544

487545
if (port && port->set)
@@ -729,8 +787,19 @@ expand_redirect(struct fw3_ipt_handle *handle, struct fw3_state *state,
729787
else
730788
ref_addr = *ext_addr;
731789

732-
ref_addr.mask.v4.s_addr = 0xFFFFFFFF;
733-
ext_addr->mask.v4.s_addr = 0xFFFFFFFF;
790+
#ifdef ENABLE_NAT6
791+
if (ref_addr.family == FW3_FAMILY_V6)
792+
memset(ref_addr.mask.v6.s6_addr, 0xFF, 16);
793+
else
794+
#endif
795+
ref_addr.mask.v4.s_addr = 0xFFFFFFFF;
796+
797+
#ifdef ENABLE_NAT6
798+
if (ext_addr->family == FW3_FAMILY_V6)
799+
memset(ext_addr->mask.v6.s6_addr, 0xFF, 16);
800+
else
801+
#endif
802+
ext_addr->mask.v4.s_addr = 0xFFFFFFFF;
734803

735804
print_reflection(handle, state, redir, num, proto,
736805
&ref_addr, int_addr, ext_addr);
@@ -749,8 +818,10 @@ fw3_print_redirects(struct fw3_ipt_handle *handle, struct fw3_state *state)
749818
int num = 0;
750819
struct fw3_redirect *redir;
751820

821+
#ifndef ENABLE_NAT6
752822
if (handle->family == FW3_FAMILY_V6)
753823
return;
824+
#endif
754825

755826
if (handle->table != FW3_TABLE_FILTER &&
756827
handle->table != FW3_TABLE_NAT &&

snats.c

+21-3
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,15 @@ check_snat(struct fw3_state *state, struct fw3_snat *snat, struct uci_element *e
186186
fw3_parse_protocol(&snat->proto, "all", true);
187187
}
188188

189-
if (snat->_src)
190-
set(snat->_src->flags, FW3_FAMILY_V4, FW3_FLAG_SNAT);
189+
if (snat->_src) {
190+
191+
#ifdef ENABLE_NAT6
192+
if (fw3_is_family(snat->_src, FW3_FAMILY_V6))
193+
set(snat->_src->flags, FW3_FAMILY_V6, FW3_FLAG_SNAT);
194+
if (fw3_is_family(snat->_src, FW3_FAMILY_V4))
195+
#endif
196+
set(snat->_src->flags, FW3_FAMILY_V4, FW3_FLAG_SNAT);
197+
}
191198

192199
return true;
193200
}
@@ -265,15 +272,24 @@ static void
265272
set_target(struct fw3_ipt_rule *r, struct fw3_snat *snat,
266273
struct fw3_protocol *proto)
267274
{
275+
#ifdef ENABLE_NAT6
276+
char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:65535-65535\0")];
277+
#else
268278
char buf[sizeof("255.255.255.255:65535-65535\0")];
279+
#endif
269280

270281
if (snat->target == FW3_FLAG_SNAT)
271282
{
272283
buf[0] = '\0';
273284

274285
if (snat->ip_snat.set)
275286
{
276-
inet_ntop(AF_INET, &snat->ip_snat.address.v4, buf, sizeof(buf));
287+
#ifdef ENABLE_NAT6
288+
if (snat->ip_snat.family == FW3_FAMILY_V6)
289+
inet_ntop(AF_INET6, &snat->ip_snat.address.v6, buf, sizeof(buf));
290+
else
291+
#endif
292+
inet_ntop(AF_INET, &snat->ip_snat.address.v4, buf, sizeof(buf));
277293
}
278294

279295
if (snat->port_snat.set && proto && !proto->any &&
@@ -410,8 +426,10 @@ fw3_print_snats(struct fw3_ipt_handle *handle, struct fw3_state *state)
410426
int num = 0;
411427
struct fw3_snat *snat;
412428

429+
#ifndef ENABLE_NAT6
413430
if (handle->family == FW3_FAMILY_V6)
414431
return;
432+
#endif
415433

416434
if (handle->table != FW3_TABLE_NAT)
417435
return;

utils.c

+5
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,11 @@ write_zone_uci(struct uci_context *ctx, struct fw3_zone *z,
512512
ptr.value = z->masq ? "1" : "0";
513513
uci_set(ctx, &ptr);
514514

515+
ptr.o = NULL;
516+
ptr.option = "masq6";
517+
ptr.value = z->masq6 ? "1" : "0";
518+
uci_set(ctx, &ptr);
519+
515520
ptr.o = NULL;
516521
ptr.option = "mtu_fix";
517522
ptr.value = z->mtu_fix ? "1" : "0";

zones.c

+31
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@ static const struct fw3_chain_spec zone_chains[] = {
3737
C(ANY, FILTER, REJECT, "zone_%s_dest_REJECT"),
3838
C(ANY, FILTER, DROP, "zone_%s_dest_DROP"),
3939

40+
#ifdef ENABLE_NAT6
41+
C(ANY, NAT, SNAT, "zone_%s_postrouting"),
42+
C(ANY, NAT, DNAT, "zone_%s_prerouting"),
43+
#else
4044
C(V4, NAT, SNAT, "zone_%s_postrouting"),
4145
C(V4, NAT, DNAT, "zone_%s_prerouting"),
46+
#endif
4247

4348
C(ANY, RAW, HELPER, "zone_%s_helper"),
4449
C(ANY, RAW, NOTRACK, "zone_%s_notrack"),
@@ -47,8 +52,13 @@ static const struct fw3_chain_spec zone_chains[] = {
4752
C(ANY, FILTER, CUSTOM_CHAINS, "output_%s_rule"),
4853
C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_%s_rule"),
4954

55+
#ifdef ENABLE_NAT6
56+
C(ANY, NAT, CUSTOM_CHAINS, "prerouting_%s_rule"),
57+
C(ANY, NAT, CUSTOM_CHAINS, "postrouting_%s_rule"),
58+
#else
5059
C(V4, NAT, CUSTOM_CHAINS, "prerouting_%s_rule"),
5160
C(V4, NAT, CUSTOM_CHAINS, "postrouting_%s_rule"),
61+
#endif
5262

5363
{ }
5464
};
@@ -77,6 +87,8 @@ const struct fw3_option fw3_zone_opts[] = {
7787
FW3_LIST("masq_src", network, zone, masq_src),
7888
FW3_LIST("masq_dest", network, zone, masq_dest),
7989

90+
FW3_OPT("masq6", bool, zone, masq6),
91+
8092
FW3_OPT("extra", string, zone, extra_src),
8193
FW3_OPT("extra_src", string, zone, extra_src),
8294
FW3_OPT("extra_dest", string, zone, extra_dest),
@@ -306,10 +318,22 @@ fw3_load_zones(struct fw3_state *state, struct uci_package *p)
306318
fw3_setbit(zone->flags[0], FW3_FLAG_SNAT);
307319
}
308320

321+
#ifdef ENABLE_NAT6
322+
if (zone->masq6)
323+
{
324+
fw3_setbit(zone->flags[1], FW3_FLAG_SNAT);
325+
}
326+
#endif
327+
309328
if (zone->custom_chains)
310329
{
311330
fw3_setbit(zone->flags[0], FW3_FLAG_SNAT);
312331
fw3_setbit(zone->flags[0], FW3_FLAG_DNAT);
332+
333+
#ifdef ENABLE_NAT6
334+
fw3_setbit(zone->flags[1], FW3_FLAG_SNAT);
335+
fw3_setbit(zone->flags[1], FW3_FLAG_DNAT);
336+
#endif
313337
}
314338

315339
resolve_cthelpers(state, e, zone);
@@ -318,9 +342,11 @@ fw3_load_zones(struct fw3_state *state, struct uci_package *p)
318342
fw3_setbit(zone->flags[0], zone->policy_forward);
319343
fw3_setbit(zone->flags[0], zone->policy_output);
320344

345+
#ifdef ENABLE_NAT6
321346
fw3_setbit(zone->flags[1], fw3_to_src_target(zone->policy_input));
322347
fw3_setbit(zone->flags[1], zone->policy_forward);
323348
fw3_setbit(zone->flags[1], zone->policy_output);
349+
#endif
324350

325351
list_add_tail(&zone->list, &state->zones);
326352
}
@@ -669,7 +695,11 @@ print_zone_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
669695
break;
670696

671697
case FW3_TABLE_NAT:
698+
#ifdef ENABLE_NAT6
699+
if ((zone->masq && handle->family == FW3_FAMILY_V4) || (zone->masq6 && handle->family == FW3_FAMILY_V6))
700+
#else
672701
if (zone->masq && handle->family == FW3_FAMILY_V4)
702+
#endif
673703
{
674704
/* for any negated masq_src ip, emit -s addr -j RETURN rules */
675705
for (msrc = NULL;
@@ -716,6 +746,7 @@ print_zone_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
716746
fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
717747
}
718748
}
749+
719750
}
720751
break;
721752

0 commit comments

Comments
 (0)