1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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 30 #ifndef _IP_FW_NAT64LSN_H_ 31 #define _IP_FW_NAT64LSN_H_ 32 33 #include "ip_fw_nat64.h" 34 #include "nat64_translate.h" 35 36 #define NAT64_MIN_PORT 1024 37 struct nat64lsn_host; 38 struct nat64lsn_alias; 39 40 struct nat64lsn_state { 41 /* IPv6 host entry keeps hash table to speedup state lookup */ 42 CK_SLIST_ENTRY(nat64lsn_state) entries; 43 struct nat64lsn_host *host; 44 45 struct in6_addr ip6_dst; /* Destination IPv6 address */ 46 47 in_addr_t ip_src; /* Alias IPv4 address */ 48 in_addr_t ip_dst; /* Destination IPv4 address */ 49 uint16_t dport; /* Destination port */ 50 uint16_t sport; /* Source port */ 51 52 uint32_t hval; 53 uint32_t flags; /* Internal flags */ 54 uint16_t aport; 55 uint16_t timestamp; /* last used */ 56 uint8_t proto; 57 uint8_t _spare[7]; 58 }; 59 60 struct nat64lsn_states_chunk { 61 struct nat64lsn_state state[64]; 62 }; 63 64 #define ISSET64(mask, bit) ((mask) & ((uint64_t)1 << (bit))) 65 #define ISSET32(mask, bit) ((mask) & ((uint32_t)1 << (bit))) 66 struct nat64lsn_pg { 67 CK_SLIST_ENTRY(nat64lsn_pg) entries; 68 69 uint16_t base_port; 70 uint16_t timestamp; 71 uint8_t proto; 72 uint8_t chunks_count; 73 uint8_t spare[2]; 74 75 union { 76 uint64_t freemask64; 77 uint32_t freemask32[2]; 78 uint64_t *freemask64_chunk; 79 uint32_t *freemask32_chunk; 80 void *freemask_chunk; 81 }; 82 union { 83 struct nat64lsn_states_chunk *states; 84 struct nat64lsn_states_chunk **states_chunk; 85 }; 86 }; 87 88 #define CHUNK_BY_FADDR(p, a) ((a) & ((p)->chunks_count - 1)) 89 90 #ifdef __LP64__ 91 #define FREEMASK_CHUNK(p, v) \ 92 ((p)->chunks_count == 1 ? &(p)->freemask64 : \ 93 &(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)]) 94 #define FREEMASK_BITCOUNT(pg, faddr) \ 95 bitcount64(*FREEMASK_CHUNK((pg), (faddr))) 96 #else 97 #define FREEMASK_CHUNK(p, v) \ 98 ((p)->chunks_count == 1 ? &(p)->freemask32[0] : \ 99 &(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2]) 100 #define FREEMASK_BITCOUNT(pg, faddr) \ 101 bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr))) 102 #endif /* !__LP64__ */ 103 104 struct nat64lsn_pgchunk { 105 struct nat64lsn_pg *pgptr[32]; 106 }; 107 108 struct nat64lsn_aliaslink { 109 CK_SLIST_ENTRY(nat64lsn_aliaslink) alias_entries; 110 CK_SLIST_ENTRY(nat64lsn_aliaslink) host_entries; 111 struct nat64lsn_alias *alias; 112 }; 113 114 CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink); 115 CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state); 116 CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host); 117 CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg); 118 119 struct nat64lsn_alias { 120 struct nat64lsn_aliaslink_slist hosts; 121 struct nat64lsn_pg_slist portgroups; 122 123 struct mtx lock; 124 in_addr_t addr; /* host byte order */ 125 uint32_t hosts_count; 126 uint32_t portgroups_count; 127 uint32_t tcp_chunkmask; 128 uint32_t udp_chunkmask; 129 uint32_t icmp_chunkmask; 130 131 uint32_t tcp_pgidx; 132 uint32_t udp_pgidx; 133 uint32_t icmp_pgidx; 134 uint16_t timestamp; 135 uint16_t spare; 136 137 uint32_t tcp_pgmask[32]; 138 uint32_t udp_pgmask[32]; 139 uint32_t icmp_pgmask[32]; 140 struct nat64lsn_pgchunk *tcp[32]; 141 struct nat64lsn_pgchunk *udp[32]; 142 struct nat64lsn_pgchunk *icmp[32]; 143 144 /* pointer to PG that can be used for faster state allocation */ 145 struct nat64lsn_pg *tcp_pg; 146 struct nat64lsn_pg *udp_pg; 147 struct nat64lsn_pg *icmp_pg; 148 }; 149 #define ALIAS_LOCK_INIT(p) \ 150 mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF) 151 #define ALIAS_LOCK_DESTROY(p) mtx_destroy(&(p)->lock) 152 #define ALIAS_LOCK(p) mtx_lock(&(p)->lock) 153 #define ALIAS_UNLOCK(p) mtx_unlock(&(p)->lock) 154 155 #define NAT64LSN_HSIZE 256 156 #define NAT64LSN_MAX_HSIZE 4096 157 #define NAT64LSN_HOSTS_HSIZE 1024 158 159 struct nat64lsn_host { 160 struct in6_addr addr; 161 struct nat64lsn_aliaslink_slist aliases; 162 struct nat64lsn_states_slist *states_hash; 163 CK_SLIST_ENTRY(nat64lsn_host) entries; 164 uint32_t states_count; 165 uint32_t hval; 166 uint32_t flags; 167 #define NAT64LSN_DEADHOST 1 168 #define NAT64LSN_GROWHASH 2 169 uint16_t states_hashsize; 170 uint16_t timestamp; 171 struct mtx lock; 172 }; 173 174 #define HOST_LOCK_INIT(p) \ 175 mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW) 176 #define HOST_LOCK_DESTROY(p) mtx_destroy(&(p)->lock) 177 #define HOST_LOCK(p) mtx_lock(&(p)->lock) 178 #define HOST_UNLOCK(p) mtx_unlock(&(p)->lock) 179 180 VNET_DECLARE(uint16_t, nat64lsn_eid); 181 #define V_nat64lsn_eid VNET(nat64lsn_eid) 182 #define IPFW_TLV_NAT64LSN_NAME IPFW_TLV_EACTION_NAME(V_nat64lsn_eid) 183 184 /* Timestamp macro */ 185 #define _CT ((int)time_uptime % 65536) 186 #define SET_AGE(x) (x) = _CT 187 #define GET_AGE(x) ((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x)) 188 189 STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item); 190 191 struct nat64lsn_cfg { 192 struct named_object no; 193 194 struct nat64lsn_hosts_slist *hosts_hash; 195 struct nat64lsn_alias *aliases; /* array of aliases */ 196 197 struct mtx lock; 198 uint32_t hosts_hashsize; 199 uint32_t hash_seed; 200 201 uint32_t prefix4; /* IPv4 prefix */ 202 uint32_t pmask4; /* IPv4 prefix mask */ 203 uint8_t plen4; 204 uint8_t nomatch_verdict;/* Return value on no-match */ 205 206 uint32_t hosts_count; /* Number of items in host hash */ 207 uint32_t states_chunks; /* Number of states chunks per PG */ 208 uint32_t jmaxlen; /* Max jobqueue length */ 209 uint16_t host_delete_delay; /* Stale host delete delay */ 210 uint16_t pgchunk_delete_delay; 211 uint16_t pg_delete_delay; /* Stale portgroup del delay */ 212 uint16_t st_syn_ttl; /* TCP syn expire */ 213 uint16_t st_close_ttl; /* TCP fin expire */ 214 uint16_t st_estab_ttl; /* TCP established expire */ 215 uint16_t st_udp_ttl; /* UDP expire */ 216 uint16_t st_icmp_ttl; /* ICMP expire */ 217 218 struct nat64_config base; 219 #define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE) 220 #define NAT64LSN_ANYPREFIX 0x00000100 221 222 struct mtx periodic_lock; 223 struct callout periodic; 224 struct callout jcallout; 225 struct vnet *vp; 226 struct nat64lsn_job_head jhead; 227 int jlen; 228 char name[64]; /* Nat instance name */ 229 }; 230 231 /* CFG_LOCK protects cfg->hosts_hash from modification */ 232 #define CFG_LOCK_INIT(p) \ 233 mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF) 234 #define CFG_LOCK_DESTROY(p) mtx_destroy(&(p)->lock) 235 #define CFG_LOCK(p) mtx_lock(&(p)->lock) 236 #define CFG_UNLOCK(p) mtx_unlock(&(p)->lock) 237 238 #define CALLOUT_LOCK_INIT(p) \ 239 mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF) 240 #define CALLOUT_LOCK_DESTROY(p) mtx_destroy(&(p)->periodic_lock) 241 #define CALLOUT_LOCK(p) mtx_lock(&(p)->periodic_lock) 242 #define CALLOUT_UNLOCK(p) mtx_unlock(&(p)->periodic_lock) 243 244 struct nat64lsn_cfg *nat64lsn_init_instance(struct ip_fw_chain *ch, 245 in_addr_t prefix, int plen); 246 void nat64lsn_destroy_instance(struct nat64lsn_cfg *cfg); 247 void nat64lsn_start_instance(struct nat64lsn_cfg *cfg); 248 void nat64lsn_init_internal(void); 249 void nat64lsn_uninit_internal(void); 250 int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args, 251 ipfw_insn *cmd, int *done); 252 253 #endif /* _IP_FW_NAT64LSN_H_ */ 254