1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2015-2019 Yandex LLC 5 * Copyright (c) 2015 Alexander V. Chernikov <melifaro@FreeBSD.org> 6 * Copyright (c) 2015-2019 Andrey V. Elsukov <ae@FreeBSD.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _IP_FW_NAT64LSN_H_ 33 #define _IP_FW_NAT64LSN_H_ 34 35 #include "ip_fw_nat64.h" 36 #include "nat64_translate.h" 37 38 #define NAT64_MIN_PORT 1024 39 struct nat64lsn_host; 40 struct nat64lsn_alias; 41 42 struct nat64lsn_state { 43 /* IPv6 host entry keeps hash table to speedup state lookup */ 44 CK_SLIST_ENTRY(nat64lsn_state) entries; 45 struct nat64lsn_host *host; 46 47 struct in6_addr ip6_dst; /* Destination IPv6 address */ 48 49 in_addr_t ip_src; /* Alias IPv4 address */ 50 in_addr_t ip_dst; /* Destination IPv4 address */ 51 uint16_t dport; /* Destination port */ 52 uint16_t sport; /* Source port */ 53 54 uint32_t hval; 55 uint32_t flags; /* Internal flags */ 56 uint16_t aport; 57 uint16_t timestamp; /* last used */ 58 uint8_t proto; 59 uint8_t _spare[7]; 60 }; 61 62 struct nat64lsn_states_chunk { 63 struct nat64lsn_state state[64]; 64 }; 65 66 #define ISSET64(mask, bit) ((mask) & ((uint64_t)1 << (bit))) 67 #define ISSET32(mask, bit) ((mask) & ((uint32_t)1 << (bit))) 68 struct nat64lsn_pg { 69 CK_SLIST_ENTRY(nat64lsn_pg) entries; 70 71 uint16_t base_port; 72 uint16_t timestamp; 73 uint8_t proto; 74 uint8_t chunks_count; 75 uint8_t spare[2]; 76 77 union { 78 uint64_t freemask64; 79 uint32_t freemask32[2]; 80 uint64_t *freemask64_chunk; 81 uint32_t *freemask32_chunk; 82 void *freemask_chunk; 83 }; 84 union { 85 struct nat64lsn_states_chunk *states; 86 struct nat64lsn_states_chunk **states_chunk; 87 }; 88 }; 89 90 #define CHUNK_BY_FADDR(p, a) ((a) & ((p)->chunks_count - 1)) 91 92 #ifdef __LP64__ 93 #define FREEMASK_CHUNK(p, v) \ 94 ((p)->chunks_count == 1 ? &(p)->freemask64 : \ 95 &(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)]) 96 #define FREEMASK_BITCOUNT(pg, faddr) \ 97 bitcount64(*FREEMASK_CHUNK((pg), (faddr))) 98 #else 99 #define FREEMASK_CHUNK(p, v) \ 100 ((p)->chunks_count == 1 ? &(p)->freemask32[0] : \ 101 &(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2]) 102 #define FREEMASK_BITCOUNT(pg, faddr) \ 103 bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr))) 104 #endif /* !__LP64__ */ 105 106 struct nat64lsn_pgchunk { 107 struct nat64lsn_pg *pgptr[32]; 108 }; 109 110 struct nat64lsn_aliaslink { 111 CK_SLIST_ENTRY(nat64lsn_aliaslink) alias_entries; 112 CK_SLIST_ENTRY(nat64lsn_aliaslink) host_entries; 113 struct nat64lsn_alias *alias; 114 }; 115 116 CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink); 117 CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state); 118 CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host); 119 CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg); 120 121 struct nat64lsn_alias { 122 struct nat64lsn_aliaslink_slist hosts; 123 struct nat64lsn_pg_slist portgroups; 124 125 struct mtx lock; 126 in_addr_t addr; /* host byte order */ 127 uint32_t hosts_count; 128 uint32_t portgroups_count; 129 uint32_t tcp_chunkmask; 130 uint32_t udp_chunkmask; 131 uint32_t icmp_chunkmask; 132 133 uint32_t tcp_pgidx; 134 uint32_t udp_pgidx; 135 uint32_t icmp_pgidx; 136 uint16_t timestamp; 137 uint16_t spare; 138 139 uint32_t tcp_pgmask[32]; 140 uint32_t udp_pgmask[32]; 141 uint32_t icmp_pgmask[32]; 142 struct nat64lsn_pgchunk *tcp[32]; 143 struct nat64lsn_pgchunk *udp[32]; 144 struct nat64lsn_pgchunk *icmp[32]; 145 146 /* pointer to PG that can be used for faster state allocation */ 147 struct nat64lsn_pg *tcp_pg; 148 struct nat64lsn_pg *udp_pg; 149 struct nat64lsn_pg *icmp_pg; 150 }; 151 #define ALIAS_LOCK_INIT(p) \ 152 mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF) 153 #define ALIAS_LOCK_DESTROY(p) mtx_destroy(&(p)->lock) 154 #define ALIAS_LOCK(p) mtx_lock(&(p)->lock) 155 #define ALIAS_UNLOCK(p) mtx_unlock(&(p)->lock) 156 157 #define NAT64LSN_HSIZE 256 158 #define NAT64LSN_MAX_HSIZE 4096 159 #define NAT64LSN_HOSTS_HSIZE 1024 160 161 struct nat64lsn_host { 162 struct in6_addr addr; 163 struct nat64lsn_aliaslink_slist aliases; 164 struct nat64lsn_states_slist *states_hash; 165 CK_SLIST_ENTRY(nat64lsn_host) entries; 166 uint32_t states_count; 167 uint32_t hval; 168 uint32_t flags; 169 #define NAT64LSN_DEADHOST 1 170 #define NAT64LSN_GROWHASH 2 171 uint16_t states_hashsize; 172 uint16_t timestamp; 173 struct mtx lock; 174 }; 175 176 #define HOST_LOCK_INIT(p) \ 177 mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW) 178 #define HOST_LOCK_DESTROY(p) mtx_destroy(&(p)->lock) 179 #define HOST_LOCK(p) mtx_lock(&(p)->lock) 180 #define HOST_UNLOCK(p) mtx_unlock(&(p)->lock) 181 182 VNET_DECLARE(uint16_t, nat64lsn_eid); 183 #define V_nat64lsn_eid VNET(nat64lsn_eid) 184 #define IPFW_TLV_NAT64LSN_NAME IPFW_TLV_EACTION_NAME(V_nat64lsn_eid) 185 186 /* Timestamp macro */ 187 #define _CT ((int)time_uptime % 65536) 188 #define SET_AGE(x) (x) = _CT 189 #define GET_AGE(x) ((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x)) 190 191 STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item); 192 193 struct nat64lsn_cfg { 194 struct named_object no; 195 196 struct nat64lsn_hosts_slist *hosts_hash; 197 struct nat64lsn_alias *aliases; /* array of aliases */ 198 199 struct mtx lock; 200 uint32_t hosts_hashsize; 201 uint32_t hash_seed; 202 203 uint32_t prefix4; /* IPv4 prefix */ 204 uint32_t pmask4; /* IPv4 prefix mask */ 205 uint8_t plen4; 206 uint8_t nomatch_verdict;/* Return value on no-match */ 207 208 uint32_t hosts_count; /* Number of items in host hash */ 209 uint32_t states_chunks; /* Number of states chunks per PG */ 210 uint32_t jmaxlen; /* Max jobqueue length */ 211 uint16_t host_delete_delay; /* Stale host delete delay */ 212 uint16_t pgchunk_delete_delay; 213 uint16_t pg_delete_delay; /* Stale portgroup del delay */ 214 uint16_t st_syn_ttl; /* TCP syn expire */ 215 uint16_t st_close_ttl; /* TCP fin expire */ 216 uint16_t st_estab_ttl; /* TCP established expire */ 217 uint16_t st_udp_ttl; /* UDP expire */ 218 uint16_t st_icmp_ttl; /* ICMP expire */ 219 220 struct nat64_config base; 221 #define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE) 222 #define NAT64LSN_ANYPREFIX 0x00000100 223 224 struct mtx periodic_lock; 225 struct callout periodic; 226 struct callout jcallout; 227 struct vnet *vp; 228 struct nat64lsn_job_head jhead; 229 int jlen; 230 char name[64]; /* Nat instance name */ 231 }; 232 233 /* CFG_LOCK protects cfg->hosts_hash from modification */ 234 #define CFG_LOCK_INIT(p) \ 235 mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF) 236 #define CFG_LOCK_DESTROY(p) mtx_destroy(&(p)->lock) 237 #define CFG_LOCK(p) mtx_lock(&(p)->lock) 238 #define CFG_UNLOCK(p) mtx_unlock(&(p)->lock) 239 240 #define CALLOUT_LOCK_INIT(p) \ 241 mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF) 242 #define CALLOUT_LOCK_DESTROY(p) mtx_destroy(&(p)->periodic_lock) 243 #define CALLOUT_LOCK(p) mtx_lock(&(p)->periodic_lock) 244 #define CALLOUT_UNLOCK(p) mtx_unlock(&(p)->periodic_lock) 245 246 struct nat64lsn_cfg *nat64lsn_init_instance(struct ip_fw_chain *ch, 247 in_addr_t prefix, int plen); 248 void nat64lsn_destroy_instance(struct nat64lsn_cfg *cfg); 249 void nat64lsn_start_instance(struct nat64lsn_cfg *cfg); 250 void nat64lsn_init_internal(void); 251 void nat64lsn_uninit_internal(void); 252 int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args, 253 ipfw_insn *cmd, int *done); 254 255 #endif /* _IP_FW_NAT64LSN_H_ */ 256