svn commit: r333403 - in head: sbin/ipfw sys/modules/ipfw_nat64 sys/netpfil/ipfw/nat64
Andrey V. Elsukov
ae at FreeBSD.org
Wed May 9 11:59:26 UTC 2018
Author: ae
Date: Wed May 9 11:59:24 2018
New Revision: 333403
URL: https://svnweb.freebsd.org/changeset/base/333403
Log:
Bring in some last changes in NAT64 implementation:
o Modify ipfw(8) to be able set any prefix6 not just Well-Known,
and also show configured prefix6;
o relocate some definitions and macros into proper place;
o convert nat64_debug and nat64_allow_private variables to be
VNET-compatible;
o add struct nat64_config that keeps generic configuration needed
to NAT64 code;
o add nat64_check_prefix6() function to check validness of specified
by user IPv6 prefix according to RFC6052;
o use nat64_check_private_ip4() and nat64_embed_ip4() functions
instead of nat64_get_ip4() and nat64_set_ip4() macros. This allows
to use any configured IPv6 prefixes that are allowed by RFC6052;
o introduce NAT64_WKPFX flag, that is set when IPv6 prefix is
Well-Known IPv6 prefix. It is used to reduce overhead to check this;
o modify nat64lsn_cfg and nat64stl_cfg structures to use nat64_config
structure. And respectivelly modify the rest of code;
o remove now unused ro argument from nat64_output() function;
o remove __FreeBSD_version ifdef, NAT64 was not merged to older versions;
o add commented -DIPFIREWALL_NAT64_DIRECT_OUTPUT flag to module's Makefile
as example.
Obtained from: Yandex LLC
MFC after: 1 month
Sponsored by: Yandex LLC
Modified:
head/sbin/ipfw/ipfw2.h
head/sbin/ipfw/nat64lsn.c
head/sbin/ipfw/nat64stl.c
head/sys/modules/ipfw_nat64/Makefile
head/sys/netpfil/ipfw/nat64/ip_fw_nat64.c
head/sys/netpfil/ipfw/nat64/ip_fw_nat64.h
head/sys/netpfil/ipfw/nat64/nat64_translate.c
head/sys/netpfil/ipfw/nat64/nat64_translate.h
head/sys/netpfil/ipfw/nat64/nat64lsn.c
head/sys/netpfil/ipfw/nat64/nat64lsn.h
head/sys/netpfil/ipfw/nat64/nat64lsn_control.c
head/sys/netpfil/ipfw/nat64/nat64stl.c
head/sys/netpfil/ipfw/nat64/nat64stl.h
head/sys/netpfil/ipfw/nat64/nat64stl_control.c
Modified: head/sbin/ipfw/ipfw2.h
==============================================================================
--- head/sbin/ipfw/ipfw2.h Wed May 9 11:47:05 2018 (r333402)
+++ head/sbin/ipfw/ipfw2.h Wed May 9 11:59:24 2018 (r333403)
@@ -384,6 +384,7 @@ void ipfw_nat64lsn_handler(int ac, char *av[]);
void ipfw_nat64stl_handler(int ac, char *av[]);
void ipfw_nptv6_handler(int ac, char *av[]);
int ipfw_check_object_name(const char *name);
+int ipfw_check_nat64prefix(const struct in6_addr *prefix, int length);
#ifdef PF
/* altq.c */
Modified: head/sbin/ipfw/nat64lsn.c
==============================================================================
--- head/sbin/ipfw/nat64lsn.c Wed May 9 11:47:05 2018 (r333402)
+++ head/sbin/ipfw/nat64lsn.c Wed May 9 11:59:24 2018 (r333403)
@@ -428,13 +428,17 @@ nat64lsn_create(const char *name, uint8_t set, int ac,
flags |= NAT64LSN_HAS_PREFIX4;
ac--; av++;
break;
-#if 0
case TOK_PREFIX6:
NEED1("IPv6 prefix required");
nat64lsn_parse_prefix(*av, AF_INET6, &cfg->prefix6,
&cfg->plen6);
+ if (ipfw_check_nat64prefix(&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);
@@ -767,10 +771,10 @@ nat64lsn_show_cb(ipfw_nat64lsn_cfg *cfg, const char *n
if (co.use_set != 0 || cfg->set != 0)
printf("set %u ", cfg->set);
inet_ntop(AF_INET, &cfg->prefix4, abuf, sizeof(abuf));
- printf("nat64lsn %s prefix4 %s/%u ", cfg->name, abuf, cfg->plen4);
-#if 0
+ 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);
+ printf(" prefix6 %s/%u", abuf, cfg->plen6);
+#if 0
printf("agg_len %u agg_count %u ", cfg->agg_prefix_len,
cfg->agg_prefix_max);
if (cfg->min_port != NAT64LSN_PORT_MIN ||
Modified: head/sbin/ipfw/nat64stl.c
==============================================================================
--- head/sbin/ipfw/nat64stl.c Wed May 9 11:47:05 2018 (r333402)
+++ head/sbin/ipfw/nat64stl.c Wed May 9 11:59:24 2018 (r333403)
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip_fw_nat64.h>
#include <arpa/inet.h>
-static int nat64stl_check_prefix(struct in6_addr *prefix, int length);
typedef int (nat64stl_cb_t)(ipfw_nat64stl_cfg *i, const char *name,
uint8_t set);
static int nat64stl_foreach(nat64stl_cb_t *f, const char *name, uint8_t set,
@@ -80,13 +79,10 @@ static struct _s_x nat64cmds[] = {
((a)->__u6_addr.__u6_addr32[0] == IPV6_ADDR_INT32_WKPFX && \
(a)->__u6_addr.__u6_addr32[1] == 0 && \
(a)->__u6_addr.__u6_addr32[2] == 0)
-static int
-nat64stl_check_prefix(struct in6_addr *prefix, int length)
+int
+ipfw_check_nat64prefix(const struct in6_addr *prefix, int length)
{
- if (IN6_IS_ADDR_WKPFX(prefix) && length == 96)
- return (0);
-#if 0
switch (length) {
case 32:
case 40:
@@ -95,21 +91,20 @@ nat64stl_check_prefix(struct in6_addr *prefix, int len
case 64:
/* Well-known prefix has 96 prefix length */
if (IN6_IS_ADDR_WKPFX(prefix))
- return (1);
+ return (EINVAL);
/* FALLTHROUGH */
case 96:
/* Bits 64 to 71 must be set to zero */
if (prefix->__u6_addr.__u6_addr8[8] != 0)
- return (1);
+ return (EINVAL);
/* XXX: looks incorrect */
if (IN6_IS_ADDR_MULTICAST(prefix) ||
IN6_IS_ADDR_UNSPECIFIED(prefix) ||
IN6_IS_ADDR_LOOPBACK(prefix))
- return (1);
+ return (EINVAL);
return (0);
}
-#endif
- return (1);
+ return (EINVAL);
}
static struct _s_x nat64statscmds[] = {
@@ -255,7 +250,7 @@ nat64stl_create(const char *name, uint8_t set, int ac,
errx(EX_USAGE,
"Bad prefix: %s", *av);
cfg->plen6 = strtol(p, NULL, 10);
- if (nat64stl_check_prefix(&cfg->prefix6,
+ if (ipfw_check_nat64prefix(&cfg->prefix6,
cfg->plen6) != 0)
errx(EX_USAGE,
"Bad prefix length: %s", p);
@@ -439,6 +434,7 @@ nat64stl_reset_stats(const char *name, uint8_t set)
static int
nat64stl_show_cb(ipfw_nat64stl_cfg *cfg, const char *name, uint8_t set)
{
+ char abuf[INET6_ADDRSTRLEN];
if (name != NULL && strcmp(cfg->name, name) != 0)
return (ESRCH);
@@ -448,8 +444,11 @@ nat64stl_show_cb(ipfw_nat64stl_cfg *cfg, const char *n
if (co.use_set != 0 || cfg->set != 0)
printf("set %u ", cfg->set);
+
printf("nat64stl %s table4 %s table6 %s",
cfg->name, cfg->ntlv4.name, cfg->ntlv6.name);
+ inet_ntop(AF_INET6, &cfg->prefix6, abuf, sizeof(abuf));
+ printf(" prefix6 %s/%u", abuf, cfg->plen6);
if (cfg->flags & NAT64_LOG)
printf(" log");
printf("\n");
Modified: head/sys/modules/ipfw_nat64/Makefile
==============================================================================
--- head/sys/modules/ipfw_nat64/Makefile Wed May 9 11:47:05 2018 (r333402)
+++ head/sys/modules/ipfw_nat64/Makefile Wed May 9 11:59:24 2018 (r333403)
@@ -8,4 +8,6 @@ SRCS+= nat64lsn.c nat64lsn_control.c
SRCS+= nat64stl.c nat64stl_control.c
SRCS+= opt_ipfw.h
+#CFLAGS+= -DIPFIREWALL_NAT64_DIRECT_OUTPUT
+
.include <bsd.kmod.mk>
Modified: head/sys/netpfil/ipfw/nat64/ip_fw_nat64.c
==============================================================================
--- head/sys/netpfil/ipfw/nat64/ip_fw_nat64.c Wed May 9 11:47:05 2018 (r333402)
+++ head/sys/netpfil/ipfw/nat64/ip_fw_nat64.c Wed May 9 11:59:24 2018 (r333403)
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 2015-2016 Yandex LLC
- * Copyright (c) 2015-2016 Andrey V. Elsukov <ae at FreeBSD.org>
+ * Copyright (c) 2015-2018 Yandex LLC
+ * Copyright (c) 2015-2018 Andrey V. Elsukov <ae at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -46,18 +46,17 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_fw.h>
#include <netpfil/ipfw/ip_fw_private.h>
-#include <netpfil/ipfw/nat64/ip_fw_nat64.h>
-#include <netpfil/ipfw/nat64/nat64_translate.h>
+#include "ip_fw_nat64.h"
-int nat64_debug = 0;
-SYSCTL_DECL(_net_inet_ip_fw);
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, nat64_debug, CTLFLAG_RW,
- &nat64_debug, 0, "Debug level for NAT64 module");
+VNET_DEFINE(int, nat64_debug) = 0;
+VNET_DEFINE(int, nat64_allow_private) = 0;
-int nat64_allow_private = 0;
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, nat64_allow_private, CTLFLAG_RW,
- &nat64_allow_private, 0,
+SYSCTL_DECL(_net_inet_ip_fw);
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, nat64_debug, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(nat64_debug), 0, "Debug level for NAT64 module");
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, nat64_allow_private,
+ CTLFLAG_VNET |CTLFLAG_RW, &VNET_NAME(nat64_allow_private), 0,
"Allow use of non-global IPv4 addresses with NAT64");
static int
Modified: head/sys/netpfil/ipfw/nat64/ip_fw_nat64.h
==============================================================================
--- head/sys/netpfil/ipfw/nat64/ip_fw_nat64.h Wed May 9 11:47:05 2018 (r333402)
+++ head/sys/netpfil/ipfw/nat64/ip_fw_nat64.h Wed May 9 11:59:24 2018 (r333403)
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 2015-2016 Yandex LLC
- * Copyright (c) 2015-2016 Andrey V. Elsukov <ae at FreeBSD.org>
+ * Copyright (c) 2015-2018 Yandex LLC
+ * Copyright (c) 2015-2018 Andrey V. Elsukov <ae at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define _IP_FW_NAT64_H_
#define DPRINTF(mask, fmt, ...) \
- if (nat64_debug & (mask)) \
+ if (V_nat64_debug & (mask)) \
printf("NAT64: %s: " fmt "\n", __func__, ## __VA_ARGS__)
#define DP_GENERIC 0x0001
#define DP_OBJ 0x0002
@@ -39,79 +39,21 @@
#define DP_STATE 0x0008
#define DP_DROPS 0x0010
#define DP_ALL 0xFFFF
-extern int nat64_debug;
+VNET_DECLARE(int, nat64_debug);
+VNET_DECLARE(int, nat64_allow_private);
+#define V_nat64_debug VNET(nat64_debug)
+#define V_nat64_allow_private VNET(nat64_allow_private)
+
#if 0
#define NAT64NOINLINE __noinline
#else
#define NAT64NOINLINE
#endif
-int nat64stl_init(struct ip_fw_chain *ch, int first);
-void nat64stl_uninit(struct ip_fw_chain *ch, int last);
-int nat64lsn_init(struct ip_fw_chain *ch, int first);
-void nat64lsn_uninit(struct ip_fw_chain *ch, int last);
+int nat64stl_init(struct ip_fw_chain *ch, int first);
+void nat64stl_uninit(struct ip_fw_chain *ch, int last);
+int nat64lsn_init(struct ip_fw_chain *ch, int first);
+void nat64lsn_uninit(struct ip_fw_chain *ch, int last);
-struct ip_fw_nat64_stats {
- counter_u64_t opcnt64; /* 6to4 of packets translated */
- counter_u64_t opcnt46; /* 4to6 of packets translated */
- counter_u64_t ofrags; /* number of fragments generated */
- counter_u64_t ifrags; /* number of fragments received */
- counter_u64_t oerrors; /* number of output errors */
- counter_u64_t noroute4;
- counter_u64_t noroute6;
- counter_u64_t nomatch4; /* No addr/port match */
- counter_u64_t noproto; /* Protocol not supported */
- counter_u64_t nomem; /* mbufs allocation failed */
- counter_u64_t dropped; /* number of packets silently
- * dropped due to some errors/
- * unsupported/etc.
- */
-
- counter_u64_t jrequests; /* number of jobs requests queued */
- counter_u64_t jcalls; /* number of jobs handler calls */
- counter_u64_t jhostsreq; /* number of hosts requests */
- counter_u64_t jportreq;
- counter_u64_t jhostfails;
- counter_u64_t jportfails;
- counter_u64_t jmaxlen;
- counter_u64_t jnomem;
- counter_u64_t jreinjected;
-
- counter_u64_t screated;
- counter_u64_t sdeleted;
- counter_u64_t spgcreated;
- counter_u64_t spgdeleted;
-};
-
-#define IPFW_NAT64_VERSION 1
-#define NAT64STATS (sizeof(struct ip_fw_nat64_stats) / sizeof(uint64_t))
-typedef struct _nat64_stats_block {
- counter_u64_t stats[NAT64STATS];
-} nat64_stats_block;
-#define NAT64STAT_ADD(s, f, v) \
- counter_u64_add((s)->stats[ \
- offsetof(struct ip_fw_nat64_stats, f) / sizeof(uint64_t)], (v))
-#define NAT64STAT_INC(s, f) NAT64STAT_ADD(s, f, 1)
-#define NAT64STAT_FETCH(s, f) \
- counter_u64_fetch((s)->stats[ \
- offsetof(struct ip_fw_nat64_stats, f) / sizeof(uint64_t)])
-
-#define L3HDR(_ip, _t) ((_t)((u_int32_t *)(_ip) + (_ip)->ip_hl))
-#define TCP(p) ((struct tcphdr *)(p))
-#define UDP(p) ((struct udphdr *)(p))
-#define ICMP(p) ((struct icmphdr *)(p))
-#define ICMP6(p) ((struct icmp6_hdr *)(p))
-
-#define NAT64SKIP 0
-#define NAT64RETURN 1
-#define NAT64MFREE -1
-
-/* Well-known prefix 64:ff9b::/96 */
-#define IPV6_ADDR_INT32_WKPFX htonl(0x64ff9b)
-#define IN6_IS_ADDR_WKPFX(a) \
- ((a)->s6_addr32[0] == IPV6_ADDR_INT32_WKPFX && \
- (a)->s6_addr32[1] == 0 && (a)->s6_addr32[2] == 0)
-
-#endif
-
+#endif /* _IP_FW_NAT64_H_ */
Modified: head/sys/netpfil/ipfw/nat64/nat64_translate.c
==============================================================================
--- head/sys/netpfil/ipfw/nat64/nat64_translate.c Wed May 9 11:47:05 2018 (r333402)
+++ head/sys/netpfil/ipfw/nat64/nat64_translate.c Wed May 9 11:59:24 2018 (r333403)
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 2015-2016 Yandex LLC
- * Copyright (c) 2015-2016 Andrey V. Elsukov <ae at FreeBSD.org>
+ * Copyright (c) 2015-2018 Yandex LLC
+ * Copyright (c) 2015-2018 Andrey V. Elsukov <ae at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,10 +66,11 @@ __FBSDID("$FreeBSD$");
#include <netpfil/pf/pf.h>
#include <netpfil/ipfw/ip_fw_private.h>
-#include <netpfil/ipfw/nat64/ip_fw_nat64.h>
-#include <netpfil/ipfw/nat64/nat64_translate.h>
#include <machine/in_cksum.h>
+#include "ip_fw_nat64.h"
+#include "nat64_translate.h"
+
static void
nat64_log(struct pfloghdr *logdata, struct mbuf *m, sa_family_t family)
{
@@ -86,22 +87,21 @@ static NAT64NOINLINE int nat64_find_route6(struct nhop
struct sockaddr_in6 *, struct mbuf *);
static NAT64NOINLINE int
-nat64_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro, nat64_stats_block *stats,
- void *logdata)
+nat64_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+ struct nat64_counters *stats, void *logdata)
{
int error;
if (logdata != NULL)
nat64_log(logdata, m, dst->sa_family);
- error = (*ifp->if_output)(ifp, m, dst, ro);
+ error = (*ifp->if_output)(ifp, m, dst, NULL);
if (error != 0)
NAT64STAT_INC(stats, oerrors);
return (error);
}
static NAT64NOINLINE int
-nat64_output_one(struct mbuf *m, nat64_stats_block *stats, void *logdata)
+nat64_output_one(struct mbuf *m, struct nat64_counters *stats, void *logdata)
{
struct nhop6_basic nh6;
struct nhop4_basic nh4;
@@ -155,9 +155,8 @@ nat64_output_one(struct mbuf *m, nat64_stats_block *st
}
#else /* !IPFIREWALL_NAT64_DIRECT_OUTPUT */
static NAT64NOINLINE int
-nat64_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro, nat64_stats_block *stats,
- void *logdata)
+nat64_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+ struct nat64_counters *stats, void *logdata)
{
struct ip *ip4;
int ret, af;
@@ -187,50 +186,103 @@ nat64_output(struct ifnet *ifp, struct mbuf *m,
}
static NAT64NOINLINE int
-nat64_output_one(struct mbuf *m, nat64_stats_block *stats, void *logdata)
+nat64_output_one(struct mbuf *m, struct nat64_counters *stats, void *logdata)
{
- return (nat64_output(NULL, m, NULL, NULL, stats, logdata));
+ return (nat64_output(NULL, m, NULL, stats, logdata));
}
#endif /* !IPFIREWALL_NAT64_DIRECT_OUTPUT */
+/*
+ * Check the given IPv6 prefix and length according to RFC6052:
+ * The prefixes can only have one of the following lengths:
+ * 32, 40, 48, 56, 64, or 96 (The Well-Known Prefix is 96 bits long).
+ * Returns zero on success, otherwise EINVAL.
+ */
+int
+nat64_check_prefix6(const struct in6_addr *prefix, int length)
+{
-#if 0
-void print_ipv6_header(struct ip6_hdr *ip6, char *buf, size_t bufsize);
+ switch (length) {
+ case 32:
+ case 40:
+ case 48:
+ case 56:
+ case 64:
+ /* Well-known prefix has 96 prefix length */
+ if (IN6_IS_ADDR_WKPFX(prefix))
+ return (EINVAL);
+ /* FALLTHROUGH */
+ case 96:
+ /* Bits 64 to 71 must be set to zero */
+ if (prefix->__u6_addr.__u6_addr8[8] != 0)
+ return (EINVAL);
+ /* Some extra checks */
+ if (IN6_IS_ADDR_MULTICAST(prefix) ||
+ IN6_IS_ADDR_UNSPECIFIED(prefix) ||
+ IN6_IS_ADDR_LOOPBACK(prefix))
+ return (EINVAL);
+ return (0);
+ }
+ return (EINVAL);
+}
-void
-print_ipv6_header(struct ip6_hdr *ip6, char *buf, size_t bufsize)
+int
+nat64_check_private_ip4(const struct nat64_config *cfg, in_addr_t ia)
{
- char sbuf[INET6_ADDRSTRLEN], dbuf[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &ip6->ip6_src, sbuf, sizeof(sbuf));
- inet_ntop(AF_INET6, &ip6->ip6_dst, dbuf, sizeof(dbuf));
- snprintf(buf, bufsize, "%s -> %s %d", sbuf, dbuf, ip6->ip6_nxt);
+ if (V_nat64_allow_private)
+ return (0);
+
+ /* WKPFX must not be used to represent non-global IPv4 addresses */
+ if (cfg->flags & NAT64_WKPFX) {
+ /* IN_PRIVATE */
+ if ((ia & htonl(0xff000000)) == htonl(0x0a000000) ||
+ (ia & htonl(0xfff00000)) == htonl(0xac100000) ||
+ (ia & htonl(0xffff0000)) == htonl(0xc0a80000))
+ return (1);
+ /*
+ * RFC 5735:
+ * 192.0.0.0/24 - reserved for IETF protocol assignments
+ * 192.88.99.0/24 - for use as 6to4 relay anycast addresses
+ * 198.18.0.0/15 - for use in benchmark tests
+ * 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 - for use
+ * in documentation and example code
+ */
+ if ((ia & htonl(0xffffff00)) == htonl(0xc0000000) ||
+ (ia & htonl(0xffffff00)) == htonl(0xc0586300) ||
+ (ia & htonl(0xfffffe00)) == htonl(0xc6120000) ||
+ (ia & htonl(0xffffff00)) == htonl(0xc0000200) ||
+ (ia & htonl(0xfffffe00)) == htonl(0xc6336400) ||
+ (ia & htonl(0xffffff00)) == htonl(0xcb007100))
+ return (1);
+ }
+ return (0);
}
-
-static NAT64NOINLINE int
-nat64_embed_ip4(struct nat64_cfg *cfg, in_addr_t ia, struct in6_addr *ip6)
+void
+nat64_embed_ip4(const struct nat64_config *cfg, in_addr_t ia,
+ struct in6_addr *ip6)
{
- /* assume the prefix is properly filled with zeros */
- bcopy(&cfg->prefix, ip6, sizeof(*ip6));
- switch (cfg->plen) {
+ /* assume the prefix6 is properly filled with zeros */
+ bcopy(&cfg->prefix6, ip6, sizeof(*ip6));
+ switch (cfg->plen6) {
case 32:
case 96:
- ip6->s6_addr32[cfg->plen / 32] = ia;
+ ip6->s6_addr32[cfg->plen6 / 32] = ia;
break;
case 40:
case 48:
case 56:
#if BYTE_ORDER == BIG_ENDIAN
- ip6->s6_addr32[1] = cfg->prefix.s6_addr32[1] |
- (ia >> (cfg->plen % 32));
- ip6->s6_addr32[2] = ia << (24 - cfg->plen % 32);
+ ip6->s6_addr32[1] = cfg->prefix6.s6_addr32[1] |
+ (ia >> (cfg->plen6 % 32));
+ ip6->s6_addr32[2] = ia << (24 - cfg->plen6 % 32);
#elif BYTE_ORDER == LITTLE_ENDIAN
- ip6->s6_addr32[1] = cfg->prefix.s6_addr32[1] |
- (ia << (cfg->plen % 32));
- ip6->s6_addr32[2] = ia >> (24 - cfg->plen % 32);
+ ip6->s6_addr32[1] = cfg->prefix6.s6_addr32[1] |
+ (ia << (cfg->plen6 % 32));
+ ip6->s6_addr32[2] = ia >> (24 - cfg->plen6 % 32);
#endif
break;
case 64:
@@ -243,14 +295,13 @@ nat64_embed_ip4(struct nat64_cfg *cfg, in_addr_t ia, s
#endif
break;
default:
- return (0);
+ panic("Wrong plen6");
};
ip6->s6_addr8[8] = 0;
- return (1);
}
-static NAT64NOINLINE in_addr_t
-nat64_extract_ip4(struct in6_addr *ip6, int plen)
+in_addr_t
+nat64_extract_ip4(const struct nat64_config *cfg, const struct in6_addr *ip6)
{
in_addr_t ia;
@@ -261,7 +312,7 @@ nat64_extract_ip4(struct in6_addr *ip6, int plen)
* The suffix bits are reserved for future extensions and SHOULD
* be set to zero.
*/
- switch (plen) {
+ switch (cfg->plen6) {
case 32:
if (ip6->s6_addr32[3] != 0 || ip6->s6_addr32[2] != 0)
goto badip6;
@@ -285,20 +336,20 @@ nat64_extract_ip4(struct in6_addr *ip6, int plen)
(ip6->s6_addr32[3] & htonl(0x00ffffff)) != 0)
goto badip6;
};
- switch (plen) {
+ switch (cfg->plen6) {
case 32:
case 96:
- ia = ip6->s6_addr32[plen / 32];
+ ia = ip6->s6_addr32[cfg->plen6 / 32];
break;
case 40:
case 48:
case 56:
#if BYTE_ORDER == BIG_ENDIAN
- ia = (ip6->s6_addr32[1] << (plen % 32)) |
- (ip6->s6_addr32[2] >> (24 - plen % 32));
+ ia = (ip6->s6_addr32[1] << (cfg->plen6 % 32)) |
+ (ip6->s6_addr32[2] >> (24 - cfg->plen6 % 32));
#elif BYTE_ORDER == LITTLE_ENDIAN
- ia = (ip6->s6_addr32[1] >> (plen % 32)) |
- (ip6->s6_addr32[2] << (24 - plen % 32));
+ ia = (ip6->s6_addr32[1] >> (cfg->plen6 % 32)) |
+ (ip6->s6_addr32[2] << (24 - cfg->plen6 % 32));
#endif
break;
case 64:
@@ -312,18 +363,18 @@ nat64_extract_ip4(struct in6_addr *ip6, int plen)
return (0);
};
if (nat64_check_ip4(ia) != 0 ||
- nat64_check_private_ip4(ia) != 0)
+ nat64_check_private_ip4(cfg, ia) != 0)
goto badip4;
return (ia);
badip4:
- DPRINTF(DP_GENERIC, "invalid destination address: %08x", ia);
+ DPRINTF(DP_GENERIC | DP_DROPS,
+ "invalid destination address: %08x", ia);
return (0);
badip6:
- DPRINTF(DP_GENERIC, "invalid IPv4-embedded IPv6 address");
+ DPRINTF(DP_GENERIC | DP_DROPS, "invalid IPv4-embedded IPv6 address");
return (0);
}
-#endif
/*
* According to RFC 1624 the equation for incremental checksum update is:
@@ -363,9 +414,6 @@ nat64_cksum_convert(struct ip6_hdr *ip6, struct ip *ip
return (sum);
}
-#if __FreeBSD_version < 1100000
-#define ip_fillid(ip) (ip)->ip_id = ip_newid()
-#endif
static NAT64NOINLINE void
nat64_init_ip4hdr(const struct ip6_hdr *ip6, const struct ip6_frag *frag,
uint16_t plen, uint8_t proto, struct ip *ip)
@@ -397,8 +445,9 @@ nat64_init_ip4hdr(const struct ip6_hdr *ip6, const str
#define FRAGSZ(mtu) ((mtu) - sizeof(struct ip6_hdr) - sizeof(struct ip6_frag))
static NAT64NOINLINE int
-nat64_fragment6(nat64_stats_block *stats, struct ip6_hdr *ip6, struct mbufq *mq,
- struct mbuf *m, uint32_t mtu, uint16_t ip_id, uint16_t ip_off)
+nat64_fragment6(struct nat64_counters *stats, struct ip6_hdr *ip6,
+ struct mbufq *mq, struct mbuf *m, uint32_t mtu, uint16_t ip_id,
+ uint16_t ip_off)
{
struct ip6_frag ip6f;
struct mbuf *n;
@@ -510,7 +559,7 @@ nat64_find_route6(struct nhop6_basic *pnh, struct sock
#define NAT64_ICMP6_PLEN 64
static NAT64NOINLINE void
nat64_icmp6_reflect(struct mbuf *m, uint8_t type, uint8_t code, uint32_t mtu,
- nat64_stats_block *stats, void *logdata)
+ struct nat64_counters *stats, void *logdata)
{
struct icmp6_hdr *icmp6;
struct ip6_hdr *ip6, *oip6;
@@ -625,7 +674,7 @@ nat64_find_route4(struct nhop4_basic *pnh, struct sock
#define NAT64_ICMP_PLEN 64
static NAT64NOINLINE void
nat64_icmp_reflect(struct mbuf *m, uint8_t type,
- uint8_t code, uint16_t mtu, nat64_stats_block *stats, void *logdata)
+ uint8_t code, uint16_t mtu, struct nat64_counters *stats, void *logdata)
{
struct icmp *icmp;
struct ip *ip, *oip;
@@ -734,7 +783,7 @@ nat64_icmp_handle_echo(struct ip6_hdr *ip6, struct icm
static NAT64NOINLINE struct mbuf *
nat64_icmp_translate(struct mbuf *m, struct ip6_hdr *ip6, uint16_t icmpid,
- int offset, nat64_stats_block *stats)
+ int offset, struct nat64_config *cfg)
{
struct ip ip;
struct icmp *icmp;
@@ -749,7 +798,7 @@ nat64_icmp_translate(struct mbuf *m, struct ip6_hdr *i
if (m->m_len < offset + ICMP_MINLEN)
m = m_pullup(m, offset + ICMP_MINLEN);
if (m == NULL) {
- NAT64STAT_INC(stats, nomem);
+ NAT64STAT_INC(&cfg->stats, nomem);
return (m);
}
mtu = 0;
@@ -889,8 +938,8 @@ nat64_icmp_translate(struct mbuf *m, struct ip6_hdr *i
hlen += ip.ip_hl << 2; /* Skip inner IP header */
if (nat64_check_ip4(ip.ip_src.s_addr) != 0 ||
nat64_check_ip4(ip.ip_dst.s_addr) != 0 ||
- nat64_check_private_ip4(ip.ip_src.s_addr) != 0 ||
- nat64_check_private_ip4(ip.ip_dst.s_addr) != 0) {
+ nat64_check_private_ip4(cfg, ip.ip_src.s_addr) != 0 ||
+ nat64_check_private_ip4(cfg, ip.ip_dst.s_addr) != 0) {
DPRINTF(DP_DROPS, "IP addresses checks failed %04x -> %04x",
ntohl(ip.ip_src.s_addr), ntohl(ip.ip_dst.s_addr));
goto freeit;
@@ -925,7 +974,7 @@ nat64_icmp_translate(struct mbuf *m, struct ip6_hdr *i
plen = sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr) + len;
n = m_get2(offset + plen + max_hdr, M_NOWAIT, MT_HEADER, M_PKTHDR);
if (n == NULL) {
- NAT64STAT_INC(stats, nomem);
+ NAT64STAT_INC(&cfg->stats, nomem);
m_freem(m);
return (NULL);
}
@@ -939,7 +988,7 @@ nat64_icmp_translate(struct mbuf *m, struct ip6_hdr *i
eip6->ip6_src = ip6->ip6_dst;
/* Use the fact that we have single /96 prefix for IPv4 map */
eip6->ip6_dst = ip6->ip6_src;
- nat64_set_ip4(&eip6->ip6_dst, ip.ip_dst.s_addr);
+ nat64_embed_ip4(cfg, ip.ip_dst.s_addr, &eip6->ip6_dst);
eip6->ip6_flow = htonl(ip.ip_tos << 20);
eip6->ip6_vfc |= IPV6_VERSION;
@@ -1009,7 +1058,7 @@ nat64_icmp_translate(struct mbuf *m, struct ip6_hdr *i
return (n);
freeit:
m_freem(m);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NULL);
}
@@ -1057,7 +1106,7 @@ nat64_getlasthdr(struct mbuf *m, int *offset)
int
nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *saddr,
- struct in6_addr *daddr, uint16_t lport, nat64_stats_block *stats,
+ struct in6_addr *daddr, uint16_t lport, struct nat64_config *cfg,
void *logdata)
{
struct nhop6_basic nh;
@@ -1074,7 +1123,7 @@ nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *s
if (ip->ip_ttl <= IPTTLDEC) {
nat64_icmp_reflect(m, ICMP_TIMXCEED,
- ICMP_TIMXCEED_INTRANS, 0, stats, logdata);
+ ICMP_TIMXCEED_INTRANS, 0, &cfg->stats, logdata);
return (NAT64RETURN);
}
@@ -1092,27 +1141,27 @@ nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *s
/* Fragment length must be multiple of 8 octets */
if ((ip->ip_off & htons(IP_MF)) != 0 && (plen & 0x7) != 0) {
nat64_icmp_reflect(m, ICMP_PARAMPROB,
- ICMP_PARAMPROB_LENGTH, 0, stats, logdata);
+ ICMP_PARAMPROB_LENGTH, 0, &cfg->stats, logdata);
return (NAT64RETURN);
}
/* Fragmented ICMP is unsupported */
if (proto == IPPROTO_ICMP && ip_off != 0) {
DPRINTF(DP_DROPS, "dropped due to fragmented ICMP");
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
dst.sin6_addr = ip6.ip6_dst;
if (nat64_find_route6(&nh, &dst, m) != 0) {
- NAT64STAT_INC(stats, noroute6);
+ NAT64STAT_INC(&cfg->stats, noroute6);
nat64_icmp_reflect(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0,
- stats, logdata);
+ &cfg->stats, logdata);
return (NAT64RETURN);
}
if (nh.nh_mtu < plen + sizeof(ip6) &&
(ip->ip_off & htons(IP_DF)) != 0) {
nat64_icmp_reflect(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
- FRAGSZ(nh.nh_mtu) + sizeof(struct ip), stats, logdata);
+ FRAGSZ(nh.nh_mtu) + sizeof(struct ip), &cfg->stats, logdata);
return (NAT64RETURN);
}
@@ -1147,19 +1196,19 @@ nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *s
*csum = cksum_add(*csum, ~nat64_cksum_convert(&ip6, ip));
break;
case IPPROTO_ICMP:
- m = nat64_icmp_translate(m, &ip6, lport, hlen, stats);
+ m = nat64_icmp_translate(m, &ip6, lport, hlen, cfg);
if (m == NULL) /* stats already accounted */
return (NAT64RETURN);
}
m_adj(m, hlen);
mbufq_init(&mq, 255);
- nat64_fragment6(stats, &ip6, &mq, m, nh.nh_mtu, ip_id, ip_off);
+ nat64_fragment6(&cfg->stats, &ip6, &mq, m, nh.nh_mtu, ip_id, ip_off);
while ((m = mbufq_dequeue(&mq)) != NULL) {
if (nat64_output(nh.nh_ifp, m, (struct sockaddr *)&dst,
- NULL, stats, logdata) != 0)
+ &cfg->stats, logdata) != 0)
break;
- NAT64STAT_INC(stats, opcnt46);
+ NAT64STAT_INC(&cfg->stats, opcnt46);
}
mbufq_drain(&mq);
return (NAT64RETURN);
@@ -1167,7 +1216,7 @@ nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *s
int
nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t aaddr, uint16_t aport,
- nat64_stats_block *stats, void *logdata)
+ struct nat64_config *cfg, void *logdata)
{
struct ip ip;
struct icmp6_hdr *icmp6;
@@ -1187,7 +1236,7 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
if (proto != IPPROTO_ICMPV6) {
DPRINTF(DP_DROPS,
"dropped due to mbuf isn't contigious");
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
}
@@ -1217,7 +1266,7 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
DPRINTF(DP_DROPS, "Unsupported ICMPv6 type %d,"
" code %d", icmp6->icmp6_type,
icmp6->icmp6_code);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
break;
@@ -1229,7 +1278,7 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
DPRINTF(DP_DROPS, "Wrong MTU %d in ICMPv6 type %d,"
" code %d", mtu, icmp6->icmp6_type,
icmp6->icmp6_code);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
/*
@@ -1274,7 +1323,7 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
DPRINTF(DP_DROPS, "Unsupported ICMPv6 type %d,"
" code %d, pptr %d", icmp6->icmp6_type,
icmp6->icmp6_code, mtu);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
case ICMP6_PARAMPROB_NEXTHEADER:
@@ -1285,20 +1334,20 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
DPRINTF(DP_DROPS, "Unsupported ICMPv6 type %d,"
" code %d, pptr %d", icmp6->icmp6_type,
icmp6->icmp6_code, ntohl(icmp6->icmp6_pptr));
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
break;
default:
DPRINTF(DP_DROPS, "Unsupported ICMPv6 type %d, code %d",
icmp6->icmp6_type, icmp6->icmp6_code);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
hlen += sizeof(struct icmp6_hdr);
if (m->m_pkthdr.len < hlen + sizeof(struct ip6_hdr) + ICMP_MINLEN) {
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
DPRINTF(DP_DROPS, "Message is too short %d",
m->m_pkthdr.len);
return (NAT64MFREE);
@@ -1325,7 +1374,7 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
if (m->m_len < hlen + sizeof(struct ip6_hdr) + ICMP_MINLEN)
m = m_pullup(m, hlen + sizeof(struct ip6_hdr) + ICMP_MINLEN);
if (m == NULL) {
- NAT64STAT_INC(stats, nomem);
+ NAT64STAT_INC(&cfg->stats, nomem);
return (NAT64RETURN);
}
ip6 = mtod(m, struct ip6_hdr *);
@@ -1364,7 +1413,7 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
/* Now we need to make a fake IPv4 packet to generate ICMP message */
ip.ip_dst.s_addr = aaddr;
- ip.ip_src.s_addr = nat64_get_ip4(&ip6i->ip6_src);
+ ip.ip_src.s_addr = nat64_extract_ip4(cfg, &ip6i->ip6_src);
/* XXX: Make fake ulp header */
#ifdef IPFIREWALL_NAT64_DIRECT_OUTPUT
ip6i->ip6_hlim += IPV6_HLIMDEC; /* init_ip4hdr will decrement it */
@@ -1372,7 +1421,8 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t
nat64_init_ip4hdr(ip6i, ip6f, plen, proto, &ip);
m_adj(m, hlen - sizeof(struct ip));
bcopy(&ip, mtod(m, void *), sizeof(ip));
- nat64_icmp_reflect(m, type, code, (uint16_t)mtu, stats, logdata);
+ nat64_icmp_reflect(m, type, code, (uint16_t)mtu, &cfg->stats,
+ logdata);
return (NAT64RETURN);
fail:
/*
@@ -1380,13 +1430,13 @@ fail:
* changed with m_pullup().
*/
m_freem(m);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64RETURN);
}
int
nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, uint16_t aport,
- nat64_stats_block *stats, void *logdata)
+ struct nat64_config *cfg, void *logdata)
{
struct ip ip;
struct nhop4_basic nh;
@@ -1411,21 +1461,21 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
/* Starting from this point we must not return zero */
ip.ip_src.s_addr = aaddr;
if (nat64_check_ip4(ip.ip_src.s_addr) != 0) {
- DPRINTF(DP_GENERIC, "invalid source address: %08x",
+ DPRINTF(DP_GENERIC | DP_DROPS, "invalid source address: %08x",
ip.ip_src.s_addr);
- /* XXX: stats? */
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
- ip.ip_dst.s_addr = nat64_get_ip4(&ip6->ip6_dst);
+ ip.ip_dst.s_addr = nat64_extract_ip4(cfg, &ip6->ip6_dst);
if (ip.ip_dst.s_addr == 0) {
- /* XXX: stats? */
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
nat64_icmp6_reflect(m, ICMP6_TIME_EXCEEDED,
- ICMP6_TIME_EXCEED_TRANSIT, 0, stats, logdata);
+ ICMP6_TIME_EXCEED_TRANSIT, 0, &cfg->stats, logdata);
return (NAT64RETURN);
}
@@ -1434,7 +1484,7 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
proto = nat64_getlasthdr(m, &hlen);
if (proto < 0) {
DPRINTF(DP_DROPS, "dropped due to mbuf isn't contigious");
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
frag = NULL;
@@ -1443,7 +1493,7 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
if (m->m_len < hlen + sizeof(*frag)) {
DPRINTF(DP_DROPS,
"dropped due to mbuf isn't contigious");
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
frag = mtodo(m, hlen);
@@ -1452,7 +1502,7 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
/* Fragmented ICMPv6 is unsupported */
if (proto == IPPROTO_ICMPV6) {
DPRINTF(DP_DROPS, "dropped due to fragmented ICMPv6");
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
/* Fragment length must be multiple of 8 octets */
@@ -1460,7 +1510,7 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
((plen + sizeof(struct ip6_hdr) - hlen) & 0x7) != 0) {
nat64_icmp6_reflect(m, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
- offsetof(struct ip6_hdr, ip6_plen), stats,
+ offsetof(struct ip6_hdr, ip6_plen), &cfg->stats,
logdata);
return (NAT64RETURN);
}
@@ -1469,7 +1519,7 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
if (plen < 0 || m->m_pkthdr.len < plen + hlen) {
DPRINTF(DP_DROPS, "plen %d, pkthdr.len %d, hlen %d",
plen, m->m_pkthdr.len, hlen);
- NAT64STAT_INC(stats, dropped);
+ NAT64STAT_INC(&cfg->stats, dropped);
return (NAT64MFREE);
}
@@ -1479,18 +1529,18 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
if (icmp6->icmp6_type != ICMP6_ECHO_REQUEST &&
icmp6->icmp6_type != ICMP6_ECHO_REPLY)
return (nat64_handle_icmp6(m, hlen, aaddr, aport,
- stats, logdata));
+ cfg, logdata));
}
dst.sin_addr.s_addr = ip.ip_dst.s_addr;
if (nat64_find_route4(&nh, &dst, m) != 0) {
- NAT64STAT_INC(stats, noroute4);
+ NAT64STAT_INC(&cfg->stats, noroute4);
nat64_icmp6_reflect(m, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_NOROUTE, 0, stats, logdata);
+ ICMP6_DST_UNREACH_NOROUTE, 0, &cfg->stats, logdata);
return (NAT64RETURN);
}
if (nh.nh_mtu < plen + sizeof(ip)) {
nat64_icmp6_reflect(m, ICMP6_PACKET_TOO_BIG, 0, nh.nh_mtu,
- stats, logdata);
+ &cfg->stats, logdata);
return (NAT64RETURN);
}
nat64_init_ip4hdr(ip6, frag, plen, proto, &ip);
@@ -1537,9 +1587,9 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, ui
m_adj(m, hlen - sizeof(ip));
bcopy(&ip, mtod(m, void *), sizeof(ip));
- if (nat64_output(nh.nh_ifp, m, (struct sockaddr *)&dst, NULL,
- stats, logdata) == 0)
- NAT64STAT_INC(stats, opcnt64);
+ if (nat64_output(nh.nh_ifp, m, (struct sockaddr *)&dst,
+ &cfg->stats, logdata) == 0)
+ NAT64STAT_INC(&cfg->stats, opcnt64);
return (NAT64RETURN);
}
Modified: head/sys/netpfil/ipfw/nat64/nat64_translate.h
==============================================================================
--- head/sys/netpfil/ipfw/nat64/nat64_translate.h Wed May 9 11:47:05 2018 (r333402)
+++ head/sys/netpfil/ipfw/nat64/nat64_translate.h Wed May 9 11:59:24 2018 (r333403)
@@ -30,6 +30,70 @@
#ifndef _IP_FW_NAT64_TRANSLATE_H_
#define _IP_FW_NAT64_TRANSLATE_H_
+struct nat64_stats {
+ uint64_t opcnt64; /* 6to4 of packets translated */
+ uint64_t opcnt46; /* 4to6 of packets translated */
+ uint64_t ofrags; /* number of fragments generated */
+ uint64_t ifrags; /* number of fragments received */
+ uint64_t oerrors; /* number of output errors */
+ uint64_t noroute4;
+ uint64_t noroute6;
+ uint64_t nomatch4; /* No addr/port match */
+ uint64_t noproto; /* Protocol not supported */
+ uint64_t nomem; /* mbufs allocation failed */
+ uint64_t dropped; /* number of packets silently
+ * dropped due to some errors/
+ * unsupported/etc.
+ */
+
+ uint64_t jrequests; /* number of jobs requests queued */
+ uint64_t jcalls; /* number of jobs handler calls */
+ uint64_t jhostsreq; /* number of hosts requests */
+ uint64_t jportreq;
+ uint64_t jhostfails;
+ uint64_t jportfails;
+ uint64_t jmaxlen;
+ uint64_t jnomem;
+ uint64_t jreinjected;
+
+ uint64_t screated;
+ uint64_t sdeleted;
+ uint64_t spgcreated;
+ uint64_t spgdeleted;
+};
+
+#define IPFW_NAT64_VERSION 1
+#define NAT64STATS (sizeof(struct nat64_stats) / sizeof(uint64_t))
+struct nat64_counters {
+ counter_u64_t cnt[NAT64STATS];
+};
+#define NAT64STAT_ADD(s, f, v) \
+ counter_u64_add((s)->cnt[ \
+ offsetof(struct nat64_stats, f) / sizeof(uint64_t)], (v))
+#define NAT64STAT_INC(s, f) NAT64STAT_ADD(s, f, 1)
+#define NAT64STAT_FETCH(s, f) \
+ counter_u64_fetch((s)->cnt[ \
+ offsetof(struct nat64_stats, f) / sizeof(uint64_t)])
+
+#define L3HDR(_ip, _t) ((_t)((uint32_t *)(_ip) + (_ip)->ip_hl))
+#define TCP(p) ((struct tcphdr *)(p))
+#define UDP(p) ((struct udphdr *)(p))
+#define ICMP(p) ((struct icmphdr *)(p))
+#define ICMP6(p) ((struct icmp6_hdr *)(p))
+
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-head
mailing list