Changeset View
Changeset View
Standalone View
Standalone View
sbin/ipfw/nat64lsn.c
/*- | /*- | ||||
* Copyright (c) 2015-2016 Yandex LLC | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | ||||
* | |||||
* Copyright (c) 2015-2019 Yandex LLC | |||||
* Copyright (c) 2015-2016 Alexander V. Chernikov <melifaro@FreeBSD.org> | * Copyright (c) 2015-2016 Alexander V. Chernikov <melifaro@FreeBSD.org> | ||||
* Copyright (c) 2015-2016 Andrey V. Elsukov <ae@FreeBSD.org> | * Copyright (c) 2015-2019 Andrey V. Elsukov <ae@FreeBSD.org> | ||||
* All rights reserved. | |||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* | * | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
static uint64_t | static uint64_t | ||||
nat64lsn_print_states(void *buf) | nat64lsn_print_states(void *buf) | ||||
{ | { | ||||
char s[INET6_ADDRSTRLEN], a[INET_ADDRSTRLEN], f[INET_ADDRSTRLEN]; | char s[INET6_ADDRSTRLEN], a[INET_ADDRSTRLEN], f[INET_ADDRSTRLEN]; | ||||
char sflags[4], *sf, *proto; | char sflags[4], *sf, *proto; | ||||
ipfw_obj_header *oh; | ipfw_obj_header *oh; | ||||
ipfw_obj_data *od; | ipfw_obj_data *od; | ||||
ipfw_nat64lsn_stg *stg; | ipfw_nat64lsn_stg_v1 *stg; | ||||
ipfw_nat64lsn_state *ste; | ipfw_nat64lsn_state_v1 *ste; | ||||
uint64_t next_idx; | uint64_t next_idx; | ||||
int i, sz; | int i, sz; | ||||
oh = (ipfw_obj_header *)buf; | oh = (ipfw_obj_header *)buf; | ||||
od = (ipfw_obj_data *)(oh + 1); | od = (ipfw_obj_data *)(oh + 1); | ||||
stg = (ipfw_nat64lsn_stg *)(od + 1); | stg = (ipfw_nat64lsn_stg_v1 *)(od + 1); | ||||
sz = od->head.length - sizeof(*od); | sz = od->head.length - sizeof(*od); | ||||
next_idx = 0; | next_idx = 0; | ||||
while (sz > 0 && next_idx != 0xFF) { | while (sz > 0 && next_idx != 0xFF) { | ||||
next_idx = stg->next_idx; | next_idx = stg->next.index; | ||||
sz -= sizeof(*stg); | sz -= sizeof(*stg); | ||||
if (stg->count == 0) { | if (stg->count == 0) { | ||||
stg++; | stg++; | ||||
continue; | continue; | ||||
} | } | ||||
switch (stg->proto) { | /* | ||||
case IPPROTO_TCP: | * NOTE: addresses are in network byte order, | ||||
proto = "TCP"; | * ports are in host byte order. | ||||
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)); | inet_ntop(AF_INET, &stg->alias4, a, sizeof(a)); | ||||
ste = (ipfw_nat64lsn_state *)(stg + 1); | ste = (ipfw_nat64lsn_state_v1 *)(stg + 1); | ||||
for (i = 0; i < stg->count && sz > 0; i++) { | for (i = 0; i < stg->count && sz > 0; i++) { | ||||
sf = sflags; | sf = sflags; | ||||
inet_ntop(AF_INET6, &ste->host6, s, sizeof(s)); | |||||
inet_ntop(AF_INET, &ste->daddr, f, sizeof(f)); | inet_ntop(AF_INET, &ste->daddr, f, sizeof(f)); | ||||
if (stg->proto == IPPROTO_TCP) { | switch (ste->proto) { | ||||
case IPPROTO_TCP: | |||||
proto = "TCP"; | |||||
if (ste->flags & 0x02) | if (ste->flags & 0x02) | ||||
*sf++ = 'S'; | *sf++ = 'S'; | ||||
if (ste->flags & 0x04) | if (ste->flags & 0x04) | ||||
*sf++ = 'E'; | *sf++ = 'E'; | ||||
if (ste->flags & 0x01) | if (ste->flags & 0x01) | ||||
*sf++ = 'F'; | *sf++ = 'F'; | ||||
break; | |||||
case IPPROTO_UDP: | |||||
proto = "UDP"; | |||||
break; | |||||
case IPPROTO_ICMP: | |||||
proto = "ICMPv6"; | |||||
break; | |||||
} | } | ||||
*sf = '\0'; | *sf = '\0'; | ||||
switch (stg->proto) { | switch (ste->proto) { | ||||
case IPPROTO_TCP: | case IPPROTO_TCP: | ||||
case IPPROTO_UDP: | case IPPROTO_UDP: | ||||
printf("%s:%d\t%s:%d\t%s\t%s\t%d\t%s:%d\n", | printf("%s:%d\t%s:%d\t%s\t%s\t%d\t%s:%d\n", | ||||
s, ste->sport, a, ste->aport, proto, | s, ste->sport, a, ste->aport, proto, | ||||
sflags, ste->idle, f, ste->dport); | sflags, ste->idle, f, ste->dport); | ||||
break; | break; | ||||
case IPPROTO_ICMPV6: | case IPPROTO_ICMP: | ||||
printf("%s\t%s\t%s\t\t%d\t%s\n", | printf("%s\t%s\t%s\t\t%d\t%s\n", | ||||
s, a, proto, ste->idle, f); | s, a, proto, ste->idle, f); | ||||
break; | break; | ||||
default: | default: | ||||
printf("%s\t%s\t%d\t\t%d\t%s\n", | printf("%s\t%s\t%d\t\t%d\t%s\n", | ||||
s, a, stg->proto, ste->idle, f); | s, a, ste->proto, ste->idle, f); | ||||
} | } | ||||
ste++; | ste++; | ||||
sz -= sizeof(*ste); | sz -= sizeof(*ste); | ||||
} | } | ||||
stg = (ipfw_nat64lsn_stg *)ste; | stg = (ipfw_nat64lsn_stg_v1 *)ste; | ||||
} | } | ||||
return (next_idx); | return (next_idx); | ||||
} | } | ||||
static int | static int | ||||
nat64lsn_states_cb(ipfw_nat64lsn_cfg *cfg, const char *name, uint8_t set) | nat64lsn_states_cb(ipfw_nat64lsn_cfg *cfg, const char *name, uint8_t set) | ||||
{ | { | ||||
ipfw_obj_header *oh; | ipfw_obj_header *oh; | ||||
Show All 9 Lines | if (set != 0 && cfg->set != set) | ||||
return (ESRCH); | return (ESRCH); | ||||
next_idx = 0; | next_idx = 0; | ||||
sz = 4096; | sz = 4096; | ||||
if ((buf = calloc(1, sz)) == NULL) | if ((buf = calloc(1, sz)) == NULL) | ||||
err(EX_OSERR, NULL); | err(EX_OSERR, NULL); | ||||
do { | do { | ||||
oh = (ipfw_obj_header *)buf; | oh = (ipfw_obj_header *)buf; | ||||
oh->opheader.version = 1; /* Force using ov new API */ | |||||
od = (ipfw_obj_data *)(oh + 1); | od = (ipfw_obj_data *)(oh + 1); | ||||
nat64lsn_fill_ntlv(&oh->ntlv, cfg->name, set); | nat64lsn_fill_ntlv(&oh->ntlv, cfg->name, set); | ||||
od->head.type = IPFW_TLV_OBJDATA; | od->head.type = IPFW_TLV_OBJDATA; | ||||
od->head.length = sizeof(*od) + sizeof(next_idx); | od->head.length = sizeof(*od) + sizeof(next_idx); | ||||
*((uint64_t *)(od + 1)) = next_idx; | *((uint64_t *)(od + 1)) = next_idx; | ||||
if (do_get3(IP_FW_NAT64LSN_LIST_STATES, &oh->opheader, &sz)) | if (do_get3(IP_FW_NAT64LSN_LIST_STATES, &oh->opheader, &sz)) | ||||
err(EX_OSERR, "Error reading nat64lsn states"); | err(EX_OSERR, "Error reading nat64lsn states"); | ||||
next_idx = nat64lsn_print_states(buf); | next_idx = nat64lsn_print_states(buf); | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | nat64lsn_parse_int(const char *arg, const char *desc) | ||||
val = (uint32_t)strtol(arg, &p, 10); | val = (uint32_t)strtol(arg, &p, 10); | ||||
if (*p != '\0') | if (*p != '\0') | ||||
errx(EX_USAGE, "Invalid %s value: %s\n", desc, arg); | errx(EX_USAGE, "Invalid %s value: %s\n", desc, arg); | ||||
return (val); | return (val); | ||||
} | } | ||||
static struct _s_x nat64newcmds[] = { | static struct _s_x nat64newcmds[] = { | ||||
{ "prefix6", TOK_PREFIX6 }, | { "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 }, | { "jmaxlen", TOK_JMAXLEN }, | ||||
{ "prefix4", TOK_PREFIX4 }, | { "prefix4", TOK_PREFIX4 }, | ||||
{ "max_ports", TOK_MAX_PORTS }, | |||||
{ "host_del_age", TOK_HOST_DEL_AGE }, | { "host_del_age", TOK_HOST_DEL_AGE }, | ||||
{ "pg_del_age", TOK_PG_DEL_AGE }, | { "pg_del_age", TOK_PG_DEL_AGE }, | ||||
{ "tcp_syn_age", TOK_TCP_SYN_AGE }, | { "tcp_syn_age", TOK_TCP_SYN_AGE }, | ||||
{ "tcp_close_age",TOK_TCP_CLOSE_AGE }, | { "tcp_close_age",TOK_TCP_CLOSE_AGE }, | ||||
{ "tcp_est_age", TOK_TCP_EST_AGE }, | { "tcp_est_age", TOK_TCP_EST_AGE }, | ||||
{ "udp_age", TOK_UDP_AGE }, | { "udp_age", TOK_UDP_AGE }, | ||||
{ "icmp_age", TOK_ICMP_AGE }, | { "icmp_age", TOK_ICMP_AGE }, | ||||
{ "states_chunks",TOK_STATES_CHUNKS }, | |||||
{ "log", TOK_LOG }, | { "log", TOK_LOG }, | ||||
{ "-log", TOK_LOGOFF }, | { "-log", TOK_LOGOFF }, | ||||
{ "allow_private", TOK_PRIVATE }, | |||||
{ "-allow_private", TOK_PRIVATEOFF }, | |||||
/* for compatibility with old configurations */ | |||||
{ "max_ports", TOK_MAX_PORTS }, /* unused */ | |||||
{ NULL, 0 } | { NULL, 0 } | ||||
}; | }; | ||||
/* | /* | ||||
* Creates new nat64lsn instance | * Creates new nat64lsn instance | ||||
* ipfw nat64lsn <NAME> create | * ipfw nat64lsn <NAME> create | ||||
* [ max_ports <N> ] | * [ max_ports <N> ] | ||||
* Request: [ ipfw_obj_lheader ipfw_nat64lsn_cfg ] | * Request: [ ipfw_obj_lheader ipfw_nat64lsn_cfg ] | ||||
Show All 40 Lines | case TOK_PREFIX4: | ||||
flags |= NAT64LSN_HAS_PREFIX4; | flags |= NAT64LSN_HAS_PREFIX4; | ||||
ac--; av++; | ac--; av++; | ||||
break; | break; | ||||
case TOK_PREFIX6: | case TOK_PREFIX6: | ||||
NEED1("IPv6 prefix required"); | NEED1("IPv6 prefix required"); | ||||
nat64lsn_parse_prefix(*av, AF_INET6, &cfg->prefix6, | nat64lsn_parse_prefix(*av, AF_INET6, &cfg->prefix6, | ||||
&cfg->plen6); | &cfg->plen6); | ||||
if (ipfw_check_nat64prefix(&cfg->prefix6, | if (ipfw_check_nat64prefix(&cfg->prefix6, | ||||
cfg->plen6) != 0) | cfg->plen6) != 0 && | ||||
!IN6_IS_ADDR_UNSPECIFIED(&cfg->prefix6)) | |||||
errx(EX_USAGE, "Bad prefix6 %s", *av); | errx(EX_USAGE, "Bad prefix6 %s", *av); | ||||
ac--; av++; | ac--; av++; | ||||
break; | 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: | case TOK_JMAXLEN: | ||||
NEED1("job queue length required"); | NEED1("job queue length required"); | ||||
cfg->jmaxlen = nat64lsn_parse_int(*av, opt); | cfg->jmaxlen = nat64lsn_parse_int(*av, opt); | ||||
ac--; av++; | ac--; av++; | ||||
break; | break; | ||||
#endif | |||||
case TOK_MAX_PORTS: | case TOK_MAX_PORTS: | ||||
NEED1("Max per-user ports required"); | NEED1("Max per-user ports required"); | ||||
cfg->max_ports = nat64lsn_parse_int(*av, opt); | cfg->max_ports = nat64lsn_parse_int(*av, opt); | ||||
ac--; av++; | ac--; av++; | ||||
break; | break; | ||||
case TOK_HOST_DEL_AGE: | case TOK_HOST_DEL_AGE: | ||||
NEED1("host delete delay required"); | NEED1("host delete delay required"); | ||||
cfg->nh_delete_delay = (uint16_t)nat64lsn_parse_int( | cfg->nh_delete_delay = (uint16_t)nat64lsn_parse_int( | ||||
Show All 31 Lines | case TOK_UDP_AGE: | ||||
ac--; av++; | ac--; av++; | ||||
break; | break; | ||||
case TOK_ICMP_AGE: | case TOK_ICMP_AGE: | ||||
NEED1("icmp age required"); | NEED1("icmp age required"); | ||||
cfg->st_icmp_ttl = (uint16_t)nat64lsn_parse_int( | cfg->st_icmp_ttl = (uint16_t)nat64lsn_parse_int( | ||||
*av, opt); | *av, opt); | ||||
ac--; av++; | ac--; av++; | ||||
break; | 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: | case TOK_LOG: | ||||
cfg->flags |= NAT64_LOG; | cfg->flags |= NAT64_LOG; | ||||
break; | break; | ||||
case TOK_LOGOFF: | case TOK_LOGOFF: | ||||
cfg->flags &= ~NAT64_LOG; | cfg->flags &= ~NAT64_LOG; | ||||
break; | break; | ||||
case TOK_PRIVATE: | |||||
cfg->flags |= NAT64_ALLOW_PRIVATE; | |||||
break; | |||||
case TOK_PRIVATEOFF: | |||||
cfg->flags &= ~NAT64_ALLOW_PRIVATE; | |||||
break; | |||||
} | } | ||||
} | } | ||||
/* Check validness */ | /* Check validness */ | ||||
if ((flags & NAT64LSN_HAS_PREFIX4) != NAT64LSN_HAS_PREFIX4) | if ((flags & NAT64LSN_HAS_PREFIX4) != NAT64LSN_HAS_PREFIX4) | ||||
errx(EX_USAGE, "prefix4 required"); | errx(EX_USAGE, "prefix4 required"); | ||||
olh->count = 1; | olh->count = 1; | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | case TOK_UDP_AGE: | ||||
ac--; av++; | ac--; av++; | ||||
break; | break; | ||||
case TOK_ICMP_AGE: | case TOK_ICMP_AGE: | ||||
NEED1("icmp age required"); | NEED1("icmp age required"); | ||||
cfg->st_icmp_ttl = (uint16_t)nat64lsn_parse_int( | cfg->st_icmp_ttl = (uint16_t)nat64lsn_parse_int( | ||||
*av, opt); | *av, opt); | ||||
ac--; av++; | ac--; av++; | ||||
break; | 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: | case TOK_LOG: | ||||
cfg->flags |= NAT64_LOG; | cfg->flags |= NAT64_LOG; | ||||
break; | break; | ||||
case TOK_LOGOFF: | case TOK_LOGOFF: | ||||
cfg->flags &= ~NAT64_LOG; | cfg->flags &= ~NAT64_LOG; | ||||
break; | break; | ||||
case TOK_PRIVATE: | |||||
cfg->flags |= NAT64_ALLOW_PRIVATE; | |||||
break; | |||||
case TOK_PRIVATEOFF: | |||||
cfg->flags &= ~NAT64_ALLOW_PRIVATE; | |||||
break; | |||||
default: | default: | ||||
errx(EX_USAGE, "Can't change %s option", opt); | errx(EX_USAGE, "Can't change %s option", opt); | ||||
} | } | ||||
} | } | ||||
if (do_set3(IP_FW_NAT64LSN_CONFIG, &oh->opheader, sizeof(buf)) != 0) | if (do_set3(IP_FW_NAT64LSN_CONFIG, &oh->opheader, sizeof(buf)) != 0) | ||||
err(EX_OSERR, "nat64lsn instance configuration failed"); | err(EX_OSERR, "nat64lsn instance configuration failed"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | if (co.use_set != 0 && cfg->set != set) | ||||
return (ESRCH); | return (ESRCH); | ||||
if (co.use_set != 0 || cfg->set != 0) | if (co.use_set != 0 || cfg->set != 0) | ||||
printf("set %u ", cfg->set); | printf("set %u ", cfg->set); | ||||
inet_ntop(AF_INET, &cfg->prefix4, abuf, sizeof(abuf)); | inet_ntop(AF_INET, &cfg->prefix4, abuf, sizeof(abuf)); | ||||
printf("nat64lsn %s prefix4 %s/%u", cfg->name, abuf, cfg->plen4); | printf("nat64lsn %s prefix4 %s/%u", cfg->name, abuf, cfg->plen4); | ||||
inet_ntop(AF_INET6, &cfg->prefix6, abuf, sizeof(abuf)); | inet_ntop(AF_INET6, &cfg->prefix6, abuf, sizeof(abuf)); | ||||
printf(" prefix6 %s/%u", abuf, cfg->plen6); | printf(" prefix6 %s/%u", abuf, cfg->plen6); | ||||
#if 0 | if (co.verbose || cfg->states_chunks > 1) | ||||
printf("agg_len %u agg_count %u ", cfg->agg_prefix_len, | printf(" states_chunks %u", cfg->states_chunks); | ||||
cfg->agg_prefix_max); | if (co.verbose || cfg->nh_delete_delay != NAT64LSN_HOST_AGE) | ||||
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); | printf(" host_del_age %u", cfg->nh_delete_delay); | ||||
if (cfg->pg_delete_delay != NAT64LSN_PG_AGE) | if (co.verbose || cfg->pg_delete_delay != NAT64LSN_PG_AGE) | ||||
printf(" pg_del_age %u ", cfg->pg_delete_delay); | printf(" pg_del_age %u ", cfg->pg_delete_delay); | ||||
if (cfg->st_syn_ttl != NAT64LSN_TCP_SYN_AGE) | if (co.verbose || cfg->st_syn_ttl != NAT64LSN_TCP_SYN_AGE) | ||||
printf(" tcp_syn_age %u", cfg->st_syn_ttl); | printf(" tcp_syn_age %u", cfg->st_syn_ttl); | ||||
if (cfg->st_close_ttl != NAT64LSN_TCP_FIN_AGE) | if (co.verbose || cfg->st_close_ttl != NAT64LSN_TCP_FIN_AGE) | ||||
printf(" tcp_close_age %u", cfg->st_close_ttl); | printf(" tcp_close_age %u", cfg->st_close_ttl); | ||||
if (cfg->st_estab_ttl != NAT64LSN_TCP_EST_AGE) | if (co.verbose || cfg->st_estab_ttl != NAT64LSN_TCP_EST_AGE) | ||||
printf(" tcp_est_age %u", cfg->st_estab_ttl); | printf(" tcp_est_age %u", cfg->st_estab_ttl); | ||||
if (cfg->st_udp_ttl != NAT64LSN_UDP_AGE) | if (co.verbose || cfg->st_udp_ttl != NAT64LSN_UDP_AGE) | ||||
printf(" udp_age %u", cfg->st_udp_ttl); | printf(" udp_age %u", cfg->st_udp_ttl); | ||||
if (cfg->st_icmp_ttl != NAT64LSN_ICMP_AGE) | if (co.verbose || cfg->st_icmp_ttl != NAT64LSN_ICMP_AGE) | ||||
printf(" icmp_age %u", cfg->st_icmp_ttl); | 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) | if (cfg->flags & NAT64_LOG) | ||||
printf(" log"); | printf(" log"); | ||||
if (cfg->flags & NAT64_ALLOW_PRIVATE) | |||||
printf(" allow_private"); | |||||
printf("\n"); | printf("\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
nat64lsn_destroy_cb(ipfw_nat64lsn_cfg *cfg, const char *name, uint8_t set) | nat64lsn_destroy_cb(ipfw_nat64lsn_cfg *cfg, const char *name, uint8_t set) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines |