Index: sbin/ipfw/ipfw.8 =================================================================== --- sbin/ipfw/ipfw.8 +++ sbin/ipfw/ipfw.8 @@ -3571,6 +3571,13 @@ Turn off private address handling in .Nm nat64clat instance. +.It Cm local +Create UE (client) instance for packets originating from the local node. +.It Cm -local +Create external (router) instance for packets originating from network. +This is the default behavior for +.Nm nat64clat +instance. .El .Pp Note that the behavior of CLAT translator with respect to not matched Index: sbin/ipfw/ipfw2.h =================================================================== --- sbin/ipfw/ipfw2.h +++ sbin/ipfw/ipfw2.h @@ -295,6 +295,8 @@ TOK_LOGOFF, TOK_PRIVATE, TOK_PRIVATEOFF, + TOK_LOCAL, + TOK_LOCALOFF, /* NAT64 CLAT tokens */ TOK_NAT64CLAT, Index: sbin/ipfw/nat64clat.c =================================================================== --- sbin/ipfw/nat64clat.c +++ sbin/ipfw/nat64clat.c @@ -166,6 +166,8 @@ { "-log", TOK_LOGOFF }, { "allow_private", TOK_PRIVATE }, { "-allow_private", TOK_PRIVATEOFF }, + { "local", TOK_LOCAL }, + { "-local", TOK_LOCALOFF }, { NULL, 0 } }; @@ -241,6 +243,12 @@ case TOK_PRIVATEOFF: cfg->flags &= ~NAT64_ALLOW_PRIVATE; break; + case TOK_LOCAL: + cfg->flags |= NAT64_LOCAL; + break; + case TOK_LOCALOFF: + cfg->flags &= ~NAT64_LOCAL; + break; } } @@ -331,6 +339,12 @@ case TOK_PRIVATEOFF: cfg->flags &= ~NAT64_ALLOW_PRIVATE; break; + case TOK_LOCAL: + cfg->flags |= NAT64_LOCAL; + break; + case TOK_LOCALOFF: + cfg->flags &= ~NAT64_LOCAL; + break; default: errx(EX_USAGE, "Can't change %s option", opt); } @@ -452,6 +466,8 @@ printf(" log"); if (cfg->flags & NAT64_ALLOW_PRIVATE) printf(" allow_private"); + if (cfg->flags & NAT64_LOCAL) + printf(" local"); printf("\n"); return (0); } Index: sys/netinet6/ip_fw_nat64.h =================================================================== --- sys/netinet6/ip_fw_nat64.h +++ sys/netinet6/ip_fw_nat64.h @@ -97,6 +97,7 @@ #define NAT64_ALLOW_PRIVATE 0x0002 /* Allow private IPv4 address * translation */ +#define NAT64_LOCAL 0x0004 /* Compute full checksum */ typedef struct _ipfw_nat64stl_cfg { char name[64]; /* NAT name */ ipfw_obj_ntlv ntlv6; /* object name tlv */ Index: sys/netpfil/ipfw/nat64/nat64_translate.h =================================================================== --- sys/netpfil/ipfw/nat64/nat64_translate.h +++ sys/netpfil/ipfw/nat64/nat64_translate.h @@ -149,6 +149,7 @@ uint16_t aport, struct nat64_config *cfg, void *logdata); void nat64_embed_ip4(struct in6_addr *ip6, int plen, in_addr_t ia); in_addr_t nat64_extract_ip4(const struct in6_addr *ip6, int plen); +void nat64_local_csum(struct mbuf *m); void nat64_set_output_method(int); int nat64_get_output_method(void); Index: sys/netpfil/ipfw/nat64/nat64_translate.c =================================================================== --- sys/netpfil/ipfw/nat64/nat64_translate.c +++ sys/netpfil/ipfw/nat64/nat64_translate.c @@ -1298,6 +1298,8 @@ switch (proto) { case IPPROTO_TCP: csum = &TCP(mtodo(m, hlen))->th_sum; + if (cfg->flags & NAT64_LOCAL) + nat64_local_csum(m); if (lport != 0) { struct tcphdr *tcp = TCP(mtodo(m, hlen)); *csum = cksum_adjust(*csum, tcp->th_dport, lport); @@ -1307,6 +1309,8 @@ break; case IPPROTO_UDP: csum = &UDP(mtodo(m, hlen))->uh_sum; + if (cfg->flags & NAT64_LOCAL) + nat64_local_csum(m); if (lport != 0) { struct udphdr *udp = UDP(mtodo(m, hlen)); *csum = cksum_adjust(*csum, udp->uh_dport, lport); @@ -1331,6 +1335,16 @@ } mbufq_drain(&mq); return (NAT64RETURN); +} + +void +nat64_local_csum(struct mbuf *m) +{ + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) + m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + + in_delayed_cksum(m); + m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } int Index: sys/netpfil/ipfw/nat64/nat64clat.h =================================================================== --- sys/netpfil/ipfw/nat64/nat64clat.h +++ sys/netpfil/ipfw/nat64/nat64clat.h @@ -39,8 +39,9 @@ struct named_object no; struct nat64_config base; + /* flags to pass to userland */ #define NAT64CLAT_FLAGSMASK \ - (NAT64_LOG | NAT64_ALLOW_PRIVATE) /* flags to pass to userland */ + (NAT64_LOG | NAT64_ALLOW_PRIVATE | NAT64_LOCAL) char name[64]; }; Index: sys/netpfil/ipfw/nat64/nat64lsn.h =================================================================== --- sys/netpfil/ipfw/nat64/nat64lsn.h +++ sys/netpfil/ipfw/nat64/nat64lsn.h @@ -218,7 +218,7 @@ uint16_t st_icmp_ttl; /* ICMP expire */ struct nat64_config base; -#define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE) +#define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE | NAT64_LOCAL) #define NAT64LSN_ANYPREFIX 0x00000100 struct mtx periodic_lock; Index: sys/netpfil/ipfw/nat64/nat64stl.h =================================================================== --- sys/netpfil/ipfw/nat64/nat64stl.h +++ sys/netpfil/ipfw/nat64/nat64stl.h @@ -45,7 +45,7 @@ #define NAT64STL_46T 0x0200 #define NAT64STL_64T 0x0400 /* flags to pass to userland */ -#define NAT64STL_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE) +#define NAT64STL_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE | NAT64_LOCAL) char name[64]; };