Path: blob/main/sys/netpfil/ipfw/nat64/nat64lsn.h
108818 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2015-2020 Yandex LLC4* Copyright (c) 2015 Alexander V. Chernikov <[email protected]>5* Copyright (c) 2015-2020 Andrey V. Elsukov <[email protected]>6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10*11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR18* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES19* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.20* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,21* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT22* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF26* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.27*/2829#ifndef _IP_FW_NAT64LSN_H_30#define _IP_FW_NAT64LSN_H_3132#include "ip_fw_nat64.h"33#include "nat64_translate.h"3435#define NAT64_MIN_PORT 102436struct nat64lsn_host;37struct nat64lsn_alias;3839struct nat64lsn_state {40/* IPv6 host entry keeps hash table to speedup state lookup */41CK_SLIST_ENTRY(nat64lsn_state) entries;42struct nat64lsn_host *host;4344struct in6_addr ip6_dst; /* Destination IPv6 address */4546in_addr_t ip_src; /* Alias IPv4 address */47in_addr_t ip_dst; /* Destination IPv4 address */48uint16_t dport; /* Destination port */49uint16_t sport; /* Source port */5051uint32_t hval;52uint32_t flags; /* Internal flags */53uint16_t aport;54uint16_t timestamp; /* last used */55uint8_t proto;56uint8_t _spare[7];57};5859struct nat64lsn_states_chunk {60struct nat64lsn_state state[64];61};6263#define ISSET64(mask, bit) ((mask) & ((uint64_t)1 << (bit)))64#define ISSET32(mask, bit) ((mask) & ((uint32_t)1 << (bit)))65struct nat64lsn_pg {66uint16_t base_port;67uint16_t timestamp;68uint8_t proto;69uint8_t chunks_count;70uint16_t flags;71#define NAT64LSN_DEADPG 17273union {74uint64_t freemask64;75uint32_t freemask32[2];76uint64_t *freemask64_chunk;77uint32_t *freemask32_chunk;78void *freemask_chunk;79};80union {81struct nat64lsn_states_chunk *states;82struct nat64lsn_states_chunk **states_chunk;83};84/*85* An alias object holds chain of all allocated PGs.86* The chain is used mostly by expiration code.87*/88CK_SLIST_ENTRY(nat64lsn_pg) entries;89};9091#define CHUNK_BY_FADDR(p, a) ((a) & ((p)->chunks_count - 1))9293#ifdef __LP64__94#define FREEMASK_CHUNK(p, v) \95((p)->chunks_count == 1 ? &(p)->freemask64 : \96&(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)])97#define FREEMASK_BITCOUNT(pg, faddr) \98bitcount64(*FREEMASK_CHUNK((pg), (faddr)))99#else100#define FREEMASK_CHUNK(p, v) \101((p)->chunks_count == 1 ? &(p)->freemask32[0] : \102&(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2])103#define FREEMASK_BITCOUNT(pg, faddr) \104bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr)))105#endif /* !__LP64__ */106107struct nat64lsn_pgchunk {108struct nat64lsn_pg *pgptr[32];109};110111struct nat64lsn_aliaslink {112CK_SLIST_ENTRY(nat64lsn_aliaslink) alias_entries;113CK_SLIST_ENTRY(nat64lsn_aliaslink) host_entries;114struct nat64lsn_alias *alias;115};116117CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink);118CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state);119CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host);120CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg);121122struct nat64lsn_alias {123struct nat64lsn_aliaslink_slist hosts;124struct nat64lsn_pg_slist portgroups;125126struct mtx lock;127in_addr_t addr; /* host byte order */128uint32_t hosts_count;129130uint16_t timestamp;131uint16_t tcp_pgcount;132uint16_t udp_pgcount;133uint16_t icmp_pgcount;134/*135* We keep PGs in chunks by 32 PGs in each.136* Each chunk allocated by demand, and then corresponding bit137* is set in chunkmask.138*139* Also we keep last used PG's index for each protocol.140* pgidx / 32 = index of pgchunk;141* pgidx % 32 = index of pgptr in pgchunk.142*/143uint32_t tcp_chunkmask;144uint32_t tcp_pgidx;145146uint32_t udp_chunkmask;147uint32_t udp_pgidx;148149uint32_t icmp_chunkmask;150uint32_t icmp_pgidx;151/*152* Each pgchunk keeps 32 pointers to PGs. If pgptr pointer is153* valid, we have corresponding bit set in the pgmask.154*/155uint32_t tcp_pgmask[32];156uint32_t udp_pgmask[32];157uint32_t icmp_pgmask[32];158159struct nat64lsn_pgchunk *tcp[32];160struct nat64lsn_pgchunk *udp[32];161struct nat64lsn_pgchunk *icmp[32];162};163#define ALIAS_LOCK_INIT(p) \164mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF)165#define ALIAS_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)166#define ALIAS_LOCK(p) mtx_lock(&(p)->lock)167#define ALIAS_UNLOCK(p) mtx_unlock(&(p)->lock)168169#define NAT64LSN_HSIZE 256170#define NAT64LSN_MAX_HSIZE 4096171#define NAT64LSN_HOSTS_HSIZE 1024172173struct nat64lsn_host {174struct in6_addr addr;175struct nat64lsn_aliaslink_slist aliases;176struct nat64lsn_states_slist *states_hash;177CK_SLIST_ENTRY(nat64lsn_host) entries;178uint32_t states_count;179uint32_t hval;180uint32_t flags;181#define NAT64LSN_DEADHOST 1182#define NAT64LSN_GROWHASH 2183uint16_t states_hashsize;184uint16_t timestamp;185struct mtx lock;186};187188#define HOST_LOCK_INIT(p) \189mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW)190#define HOST_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)191#define HOST_LOCK(p) mtx_lock(&(p)->lock)192#define HOST_UNLOCK(p) mtx_unlock(&(p)->lock)193194VNET_DECLARE(uint32_t, nat64lsn_eid);195#define V_nat64lsn_eid VNET(nat64lsn_eid)196#define IPFW_TLV_NAT64LSN_NAME IPFW_TLV_EACTION_NAME(V_nat64lsn_eid)197198/* Timestamp macro */199#define _CT ((int)time_uptime % 65536)200#define SET_AGE(x) (x) = _CT201#define GET_AGE(x) ((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x))202203STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item);204205struct nat64lsn_cfg {206struct nat64lsn_hosts_slist *hosts_hash;207struct nat64lsn_alias *aliases; /* array of aliases */208209struct mtx lock;210uint32_t hosts_hashsize;211uint32_t hash_seed;212213uint32_t prefix4; /* IPv4 prefix */214uint32_t pmask4; /* IPv4 prefix mask */215uint8_t plen4;216uint8_t nomatch_verdict;/* Return value on no-match */217218uint32_t hosts_count; /* Number of items in host hash */219uint32_t states_chunks; /* Number of states chunks per PG */220uint32_t jmaxlen; /* Max jobqueue length */221uint16_t host_delete_delay; /* Stale host delete delay */222uint16_t pgchunk_delete_delay;223uint16_t pg_delete_delay; /* Stale portgroup del delay */224uint16_t st_syn_ttl; /* TCP syn expire */225uint16_t st_close_ttl; /* TCP fin expire */226uint16_t st_estab_ttl; /* TCP established expire */227uint16_t st_udp_ttl; /* UDP expire */228uint16_t st_icmp_ttl; /* ICMP expire */229230struct nat64_config base;231#define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE | \232NAT64LSN_ALLOW_SWAPCONF)233#define NAT64LSN_ANYPREFIX 0x00000100234235struct mtx periodic_lock;236struct callout periodic;237struct callout jcallout;238struct vnet *vp;239struct nat64lsn_job_head jhead;240int jlen;241char name[64]; /* Nat instance name */242};243244struct nat64lsn_instance {245struct named_object no;246struct nat64lsn_cfg *cfg;247char name[64]; /* Nat instance name */248};249250/* CFG_LOCK protects cfg->hosts_hash from modification */251#define CFG_LOCK_INIT(p) \252mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF)253#define CFG_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)254#define CFG_LOCK(p) mtx_lock(&(p)->lock)255#define CFG_UNLOCK(p) mtx_unlock(&(p)->lock)256257#define CALLOUT_LOCK_INIT(p) \258mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF)259#define CALLOUT_LOCK_DESTROY(p) mtx_destroy(&(p)->periodic_lock)260#define CALLOUT_LOCK(p) mtx_lock(&(p)->periodic_lock)261#define CALLOUT_UNLOCK(p) mtx_unlock(&(p)->periodic_lock)262263MALLOC_DECLARE(M_NAT64LSN);264265struct nat64lsn_cfg *nat64lsn_init_config(struct ip_fw_chain *ch,266in_addr_t prefix, int plen);267void nat64lsn_destroy_config(struct nat64lsn_cfg *cfg);268void nat64lsn_start_instance(struct nat64lsn_cfg *cfg);269void nat64lsn_init_internal(void);270void nat64lsn_uninit_internal(void);271int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args,272ipfw_insn *cmd, int *done);273274#endif /* _IP_FW_NAT64LSN_H_ */275276277