aboutsummaryrefslogtreecommitdiff
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2019-03-18 14:00:19 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2019-03-18 14:00:19 +0000
commitd6369c2d18afbf23d8fa0038d2974cab7f82a976 (patch)
treea67506c34f46cd96cf461860e4c92a36eb07b296 /sbin/ipfw
parentd7a1cf06f3fd3d54182b60b4336267ad95148502 (diff)
downloadsrc-d6369c2d18afbf23d8fa0038d2974cab7f82a976.tar.gz
src-d6369c2d18afbf23d8fa0038d2974cab7f82a976.zip
Revert r345274. It appears that not all 32-bit architectures have
necessary CK primitives.
Notes
Notes: svn path=/head/; revision=345275
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw.828
-rw-r--r--sbin/ipfw/ipfw2.h1
-rw-r--r--sbin/ipfw/nat64lsn.c124
3 files changed, 81 insertions, 72 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index dbe3515164a7..31448aff92bb 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -3300,7 +3300,6 @@ See
.Sx SYSCTL VARIABLES
for more info.
.Sh IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
-.Ss Stateful translation
.Nm
supports in-kernel IPv6/IPv4 network address and protocol translation.
Stateful NAT64 translation allows IPv6-only clients to contact IPv4 servers
@@ -3318,8 +3317,7 @@ to be able use stateful NAT64 translator.
Stateful NAT64 uses a bunch of memory for several types of objects.
When IPv6 client initiates connection, NAT64 translator creates a host entry
in the states table.
-Each host entry uses preallocated IPv4 alias entry.
-Each alias entry has a number of ports group entries allocated on demand.
+Each host entry has a number of ports group entries allocated on demand.
Ports group entries contains connection state entries.
There are several options to control limits and lifetime for these objects.
.Pp
@@ -3339,11 +3337,6 @@ First time an original packet is handled and consumed by translator,
and then it is handled again as translated packet.
This behavior can be changed by sysctl variable
.Va net.inet.ip.fw.nat64_direct_output .
-Also translated packet can be tagged using
-.Cm tag
-rule action, and then matched by
-.Cm tagged
-opcode to avoid loops and extra overhead.
.Pp
The stateful NAT64 configuration command is the following:
.Bd -ragged -offset indent
@@ -3371,16 +3364,15 @@ to represent IPv4 addresses. This IPv6 prefix should be configured in DNS64.
The translator implementation follows RFC6052, that restricts the length of
prefixes to one of following: 32, 40, 48, 56, 64, or 96.
The Well-Known IPv6 Prefix 64:ff9b:: must be 96 bits long.
-The special
-.Ar ::/length
-prefix can be used to handle several IPv6 prefixes with one NAT64 instance.
-The NAT64 instance will determine a destination IPv4 address from prefix
-.Ar length .
-.It Cm states_chunks Ar number
-The number of states chunks in single ports group.
-Each ports group by default can keep 64 state entries in single chunk.
-The above value affects the maximum number of states that can be associated with single IPv4 alias address and port.
-The value must be power of 2, and up to 128.
+.It Cm max_ports Ar number
+Maximum number of ports reserved for upper level protocols to one IPv6 client.
+All reserved ports are divided into chunks between supported protocols.
+The number of connections from one IPv6 client is limited by this option.
+Note that closed TCP connections still remain in the list of connections until
+.Cm tcp_close_age
+interval will not expire.
+Default value is
+.Ar 2048 .
.It Cm host_del_age Ar seconds
The number of seconds until the host entry for a IPv6 client will be deleted
and all its resources will be released due to inactivity.
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index 2b562734d15f..ff6990ae1c06 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -278,7 +278,6 @@ enum tokens {
TOK_AGG_LEN,
TOK_AGG_COUNT,
TOK_MAX_PORTS,
- TOK_STATES_CHUNKS,
TOK_JMAXLEN,
TOK_PORT_RANGE,
TOK_HOST_DEL_AGE,
diff --git a/sbin/ipfw/nat64lsn.c b/sbin/ipfw/nat64lsn.c
index 4a6d7a7914c3..c6a892572818 100644
--- a/sbin/ipfw/nat64lsn.c
+++ b/sbin/ipfw/nat64lsn.c
@@ -87,70 +87,68 @@ nat64lsn_print_states(void *buf)
char sflags[4], *sf, *proto;
ipfw_obj_header *oh;
ipfw_obj_data *od;
- ipfw_nat64lsn_stg_v1 *stg;
- ipfw_nat64lsn_state_v1 *ste;
+ ipfw_nat64lsn_stg *stg;
+ ipfw_nat64lsn_state *ste;
uint64_t next_idx;
int i, sz;
oh = (ipfw_obj_header *)buf;
od = (ipfw_obj_data *)(oh + 1);
- stg = (ipfw_nat64lsn_stg_v1 *)(od + 1);
+ stg = (ipfw_nat64lsn_stg *)(od + 1);
sz = od->head.length - sizeof(*od);
next_idx = 0;
while (sz > 0 && next_idx != 0xFF) {
- next_idx = stg->next.index;
+ next_idx = stg->next_idx;
sz -= sizeof(*stg);
if (stg->count == 0) {
stg++;
continue;
}
- /*
- * NOTE: addresses are in network byte order,
- * ports are in host byte order.
- */
+ switch (stg->proto) {
+ case IPPROTO_TCP:
+ proto = "TCP";
+ break;
+ case IPPROTO_UDP:
+ proto = "UDP";
+ break;
+ case IPPROTO_ICMPV6:
+ proto = "ICMPv6";
+ break;
+ }
+ inet_ntop(AF_INET6, &stg->host6, s, sizeof(s));
inet_ntop(AF_INET, &stg->alias4, a, sizeof(a));
- ste = (ipfw_nat64lsn_state_v1 *)(stg + 1);
+ ste = (ipfw_nat64lsn_state *)(stg + 1);
for (i = 0; i < stg->count && sz > 0; i++) {
sf = sflags;
- inet_ntop(AF_INET6, &ste->host6, s, sizeof(s));
inet_ntop(AF_INET, &ste->daddr, f, sizeof(f));
- switch (ste->proto) {
- case IPPROTO_TCP:
- proto = "TCP";
+ if (stg->proto == IPPROTO_TCP) {
if (ste->flags & 0x02)
*sf++ = 'S';
if (ste->flags & 0x04)
*sf++ = 'E';
if (ste->flags & 0x01)
*sf++ = 'F';
- break;
- case IPPROTO_UDP:
- proto = "UDP";
- break;
- case IPPROTO_ICMP:
- proto = "ICMPv6";
- break;
}
*sf = '\0';
- switch (ste->proto) {
+ switch (stg->proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
printf("%s:%d\t%s:%d\t%s\t%s\t%d\t%s:%d\n",
s, ste->sport, a, ste->aport, proto,
sflags, ste->idle, f, ste->dport);
break;
- case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
printf("%s\t%s\t%s\t\t%d\t%s\n",
s, a, proto, ste->idle, f);
break;
default:
printf("%s\t%s\t%d\t\t%d\t%s\n",
- s, a, ste->proto, ste->idle, f);
+ s, a, stg->proto, ste->idle, f);
}
ste++;
sz -= sizeof(*ste);
}
- stg = (ipfw_nat64lsn_stg_v1 *)ste;
+ stg = (ipfw_nat64lsn_stg *)ste;
}
return (next_idx);
}
@@ -176,7 +174,6 @@ nat64lsn_states_cb(ipfw_nat64lsn_cfg *cfg, const char *name, uint8_t set)
err(EX_OSERR, NULL);
do {
oh = (ipfw_obj_header *)buf;
- oh->opheader.version = 1; /* Force using ov new API */
od = (ipfw_obj_data *)(oh + 1);
nat64lsn_fill_ntlv(&oh->ntlv, cfg->name, set);
od->head.type = IPFW_TLV_OBJDATA;
@@ -366,8 +363,12 @@ nat64lsn_parse_int(const char *arg, const char *desc)
static struct _s_x nat64newcmds[] = {
{ "prefix6", TOK_PREFIX6 },
+ { "agg_len", TOK_AGG_LEN }, /* not yet */
+ { "agg_count", TOK_AGG_COUNT }, /* not yet */
+ { "port_range", TOK_PORT_RANGE }, /* not yet */
{ "jmaxlen", TOK_JMAXLEN },
{ "prefix4", TOK_PREFIX4 },
+ { "max_ports", TOK_MAX_PORTS },
{ "host_del_age", TOK_HOST_DEL_AGE },
{ "pg_del_age", TOK_PG_DEL_AGE },
{ "tcp_syn_age", TOK_TCP_SYN_AGE },
@@ -375,13 +376,10 @@ static struct _s_x nat64newcmds[] = {
{ "tcp_est_age", TOK_TCP_EST_AGE },
{ "udp_age", TOK_UDP_AGE },
{ "icmp_age", TOK_ICMP_AGE },
- { "states_chunks",TOK_STATES_CHUNKS },
{ "log", TOK_LOG },
{ "-log", TOK_LOGOFF },
{ "allow_private", TOK_PRIVATE },
{ "-allow_private", TOK_PRIVATEOFF },
- /* for compatibility with old configurations */
- { "max_ports", TOK_MAX_PORTS }, /* unused */
{ NULL, 0 }
};
@@ -438,17 +436,42 @@ nat64lsn_create(const char *name, uint8_t set, int ac, char **av)
nat64lsn_parse_prefix(*av, AF_INET6, &cfg->prefix6,
&cfg->plen6);
if (ipfw_check_nat64prefix(&cfg->prefix6,
- cfg->plen6) != 0 &&
- !IN6_IS_ADDR_UNSPECIFIED(&cfg->prefix6))
+ cfg->plen6) != 0)
errx(EX_USAGE, "Bad prefix6 %s", *av);
ac--; av++;
break;
+#if 0
+ case TOK_AGG_LEN:
+ NEED1("Aggregation prefix len required");
+ cfg->agg_prefix_len = nat64lsn_parse_int(*av, opt);
+ ac--; av++;
+ break;
+ case TOK_AGG_COUNT:
+ NEED1("Max per-prefix count required");
+ cfg->agg_prefix_max = nat64lsn_parse_int(*av, opt);
+ ac--; av++;
+ break;
+ case TOK_PORT_RANGE:
+ NEED1("port range x[:y] required");
+ if ((p = strchr(*av, ':')) == NULL)
+ cfg->min_port = (uint16_t)nat64lsn_parse_int(
+ *av, opt);
+ else {
+ *p++ = '\0';
+ cfg->min_port = (uint16_t)nat64lsn_parse_int(
+ *av, opt);
+ cfg->max_port = (uint16_t)nat64lsn_parse_int(
+ p, opt);
+ }
+ ac--; av++;
+ break;
case TOK_JMAXLEN:
NEED1("job queue length required");
cfg->jmaxlen = nat64lsn_parse_int(*av, opt);
ac--; av++;
break;
+#endif
case TOK_MAX_PORTS:
NEED1("Max per-user ports required");
cfg->max_ports = nat64lsn_parse_int(*av, opt);
@@ -496,12 +519,6 @@ nat64lsn_create(const char *name, uint8_t set, int ac, char **av)
*av, opt);
ac--; av++;
break;
- case TOK_STATES_CHUNKS:
- NEED1("number of chunks required");
- cfg->states_chunks = (uint8_t)nat64lsn_parse_int(
- *av, opt);
- ac--; av++;
- break;
case TOK_LOG:
cfg->flags |= NAT64_LOG;
break;
@@ -613,12 +630,6 @@ nat64lsn_config(const char *name, uint8_t set, int ac, char **av)
*av, opt);
ac--; av++;
break;
- case TOK_STATES_CHUNKS:
- NEED1("number of chunks required");
- cfg->states_chunks = (uint8_t)nat64lsn_parse_int(
- *av, opt);
- ac--; av++;
- break;
case TOK_LOG:
cfg->flags |= NAT64_LOG;
break;
@@ -778,24 +789,31 @@ nat64lsn_show_cb(ipfw_nat64lsn_cfg *cfg, const char *name, uint8_t set)
printf("nat64lsn %s prefix4 %s/%u", cfg->name, abuf, cfg->plen4);
inet_ntop(AF_INET6, &cfg->prefix6, abuf, sizeof(abuf));
printf(" prefix6 %s/%u", abuf, cfg->plen6);
- if (co.verbose || cfg->states_chunks > 1)
- printf(" states_chunks %u", cfg->states_chunks);
- if (co.verbose || cfg->nh_delete_delay != NAT64LSN_HOST_AGE)
+#if 0
+ printf("agg_len %u agg_count %u ", cfg->agg_prefix_len,
+ cfg->agg_prefix_max);
+ if (cfg->min_port != NAT64LSN_PORT_MIN ||
+ cfg->max_port != NAT64LSN_PORT_MAX)
+ printf(" port_range %u:%u", cfg->min_port, cfg->max_port);
+ if (cfg->jmaxlen != NAT64LSN_JMAXLEN)
+ printf(" jmaxlen %u ", cfg->jmaxlen);
+#endif
+ if (cfg->max_ports != NAT64LSN_MAX_PORTS)
+ printf(" max_ports %u", cfg->max_ports);
+ if (cfg->nh_delete_delay != NAT64LSN_HOST_AGE)
printf(" host_del_age %u", cfg->nh_delete_delay);
- if (co.verbose || cfg->pg_delete_delay != NAT64LSN_PG_AGE)
+ if (cfg->pg_delete_delay != NAT64LSN_PG_AGE)
printf(" pg_del_age %u ", cfg->pg_delete_delay);
- if (co.verbose || cfg->st_syn_ttl != NAT64LSN_TCP_SYN_AGE)
+ if (cfg->st_syn_ttl != NAT64LSN_TCP_SYN_AGE)
printf(" tcp_syn_age %u", cfg->st_syn_ttl);
- if (co.verbose || cfg->st_close_ttl != NAT64LSN_TCP_FIN_AGE)
+ if (cfg->st_close_ttl != NAT64LSN_TCP_FIN_AGE)
printf(" tcp_close_age %u", cfg->st_close_ttl);
- if (co.verbose || cfg->st_estab_ttl != NAT64LSN_TCP_EST_AGE)
+ if (cfg->st_estab_ttl != NAT64LSN_TCP_EST_AGE)
printf(" tcp_est_age %u", cfg->st_estab_ttl);
- if (co.verbose || cfg->st_udp_ttl != NAT64LSN_UDP_AGE)
+ if (cfg->st_udp_ttl != NAT64LSN_UDP_AGE)
printf(" udp_age %u", cfg->st_udp_ttl);
- if (co.verbose || cfg->st_icmp_ttl != NAT64LSN_ICMP_AGE)
+ if (cfg->st_icmp_ttl != NAT64LSN_ICMP_AGE)
printf(" icmp_age %u", cfg->st_icmp_ttl);
- if (co.verbose || cfg->jmaxlen != NAT64LSN_JMAXLEN)
- printf(" jmaxlen %u ", cfg->jmaxlen);
if (cfg->flags & NAT64_LOG)
printf(" log");
if (cfg->flags & NAT64_ALLOW_PRIVATE)