1 /* $NetBSD: npf_impl.h,v 1.70 2017/12/10 01:18:21 rmind Exp $ */ 2 3 /*- 4 * Copyright (c) 2009-2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This material is based upon work partially supported by The 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Private NPF structures and interfaces. 34 * For internal use within NPF core only. 35 */ 36 37 #ifndef _NPF_IMPL_H_ 38 #define _NPF_IMPL_H_ 39 40 #if !defined(_KERNEL) && !defined(_NPF_STANDALONE) 41 #error "Kernel-level header only" 42 #endif 43 44 #ifdef _KERNEL_OPT 45 /* For INET/INET6 definitions. */ 46 #include "opt_inet.h" 47 #include "opt_inet6.h" 48 #endif 49 50 #ifdef _KERNEL 51 #include <sys/types.h> 52 #include <sys/queue.h> 53 #include <sys/rbtree.h> 54 55 #include <net/bpf.h> 56 #include <net/bpfjit.h> 57 #include <net/if.h> 58 #endif 59 60 #include "npf.h" 61 #include "npfkern.h" 62 63 #ifdef _NPF_DEBUG 64 #define NPF_PRINTF(x) printf x 65 #else 66 #define NPF_PRINTF(x) 67 #endif 68 69 /* 70 * STRUCTURE DECLARATIONS. 71 */ 72 73 struct npf_ruleset; 74 struct npf_rule; 75 struct npf_rprocset; 76 struct npf_nat; 77 struct npf_conn; 78 struct npf_config; 79 80 typedef struct npf_ruleset npf_ruleset_t; 81 typedef struct npf_rule npf_rule_t; 82 typedef struct npf_nat npf_nat_t; 83 typedef struct npf_rprocset npf_rprocset_t; 84 typedef struct npf_alg npf_alg_t; 85 typedef struct npf_natpolicy npf_natpolicy_t; 86 typedef struct npf_conn npf_conn_t; 87 typedef struct npf_config npf_config_t; 88 89 struct npf_conndb; 90 struct npf_table; 91 struct npf_tableset; 92 struct npf_algset; 93 struct npf_ifmap; 94 95 typedef struct npf_conndb npf_conndb_t; 96 typedef struct npf_table npf_table_t; 97 typedef struct npf_tableset npf_tableset_t; 98 typedef struct npf_algset npf_algset_t; 99 100 /* 101 * DEFINITIONS. 102 */ 103 104 typedef void (*npf_workfunc_t)(npf_t *); 105 106 /* 107 * Some artificial limits. 108 * Note: very unlikely to have many ALGs. 109 */ 110 #define NPF_MAX_RULES (1024 * 1024) 111 #define NPF_MAX_TABLES 128 112 #define NPF_MAX_RPROCS 128 113 #define NPF_MAX_IFMAP 64 114 #define NPF_MAX_ALGS 4 115 #define NPF_MAX_WORKS 4 116 117 /* 118 * CONNECTION STATE STRUCTURES 119 */ 120 121 #define NPF_FLOW_FORW 0 122 #define NPF_FLOW_BACK 1 123 124 typedef struct { 125 uint32_t nst_end; 126 uint32_t nst_maxend; 127 uint32_t nst_maxwin; 128 int nst_wscale; 129 } npf_tcpstate_t; 130 131 typedef struct { 132 u_int nst_state; 133 npf_tcpstate_t nst_tcpst[2]; 134 } npf_state_t; 135 136 /* 137 * ALG FUNCTIONS. 138 */ 139 140 typedef struct { 141 bool (*match)(npf_cache_t *, npf_nat_t *, int); 142 bool (*translate)(npf_cache_t *, npf_nat_t *, bool); 143 npf_conn_t * (*inspect)(npf_cache_t *, int); 144 } npfa_funcs_t; 145 146 /* 147 * NBUF STRUCTURE. 148 */ 149 150 struct nbuf { 151 struct mbuf * nb_mbuf0; 152 struct mbuf * nb_mbuf; 153 void * nb_nptr; 154 const ifnet_t * nb_ifp; 155 unsigned nb_ifid; 156 int nb_flags; 157 const npf_mbufops_t *nb_mops; 158 }; 159 160 /* 161 * NPF INSTANCE (CONTEXT) STRUCTURE AND AUXILIARY OPERATIONS. 162 */ 163 164 struct npf { 165 /* Active NPF configuration. */ 166 kmutex_t config_lock; 167 pserialize_t qsbr; 168 npf_config_t * config; 169 170 /* BPF byte-code context. */ 171 bpf_ctx_t * bpfctx; 172 const npf_mbufops_t * mbufops; 173 174 /* 175 * Connection tracking state: disabled (off) or enabled (on). 176 * Connection tracking database, connection cache and the lock. 177 */ 178 volatile int conn_tracking; 179 kmutex_t conn_lock; 180 npf_conndb_t * conn_db; 181 pool_cache_t conn_cache; 182 183 /* ALGs. */ 184 npf_algset_t * algset; 185 186 /* Interface mapping. */ 187 const npf_ifops_t * ifops; 188 struct npf_ifmap * ifmap; 189 unsigned ifmap_cnt; 190 191 /* Associated worker thread. */ 192 unsigned worker_id; 193 void * worker_entry; 194 195 /* List of extensions and its lock. */ 196 LIST_HEAD(, npf_ext) ext_list; 197 kmutex_t ext_lock; 198 199 /* Statistics. */ 200 percpu_t * stats_percpu; 201 }; 202 203 /* 204 * INTERFACES. 205 */ 206 207 /* NPF config, statistics, etc. */ 208 void npf_config_init(npf_t *); 209 void npf_config_fini(npf_t *); 210 211 void npf_config_enter(npf_t *); 212 void npf_config_exit(npf_t *); 213 void npf_config_sync(npf_t *); 214 bool npf_config_locked_p(npf_t *); 215 int npf_config_read_enter(void); 216 void npf_config_read_exit(int s); 217 218 void npf_config_load(npf_t *, npf_ruleset_t *, npf_tableset_t *, 219 npf_ruleset_t *, npf_rprocset_t *, npf_conndb_t *, bool); 220 npf_ruleset_t * npf_config_ruleset(npf_t *npf); 221 npf_ruleset_t * npf_config_natset(npf_t *npf); 222 npf_tableset_t *npf_config_tableset(npf_t *npf); 223 npf_rprocset_t *npf_config_rprocs(npf_t *); 224 bool npf_default_pass(npf_t *); 225 226 int npf_worker_sysinit(unsigned); 227 void npf_worker_sysfini(void); 228 void npf_worker_signal(npf_t *); 229 void npf_worker_register(npf_t *, npf_workfunc_t); 230 void npf_worker_unregister(npf_t *, npf_workfunc_t); 231 232 int npfctl_switch(void *); 233 int npfctl_reload(u_long, void *); 234 int npfctl_save(npf_t *, u_long, void *); 235 int npfctl_load(npf_t *, u_long, void *); 236 int npfctl_rule(npf_t *, u_long, void *); 237 int npfctl_conn_lookup(npf_t *, u_long, void *); 238 int npfctl_table(npf_t *, void *); 239 240 void npf_stats_inc(npf_t *, npf_stats_t); 241 void npf_stats_dec(npf_t *, npf_stats_t); 242 243 void npf_ifmap_init(npf_t *, const npf_ifops_t *); 244 void npf_ifmap_fini(npf_t *); 245 u_int npf_ifmap_register(npf_t *, const char *); 246 void npf_ifmap_flush(npf_t *); 247 u_int npf_ifmap_getid(npf_t *, const ifnet_t *); 248 const char * npf_ifmap_getname(npf_t *, const u_int); 249 void npf_ifmap_copyname(npf_t *, u_int, char *, size_t); 250 251 void npf_ifaddr_sync(npf_t *, ifnet_t *); 252 void npf_ifaddr_flush(npf_t *, ifnet_t *); 253 void npf_ifaddr_syncall(npf_t *); 254 255 /* Packet filter hooks. */ 256 int npf_pfil_register(bool); 257 void npf_pfil_unregister(bool); 258 bool npf_pfil_registered_p(void); 259 260 /* Protocol helpers. */ 261 int npf_cache_all(npf_cache_t *); 262 void npf_recache(npf_cache_t *); 263 264 bool npf_rwrip(const npf_cache_t *, u_int, const npf_addr_t *); 265 bool npf_rwrport(const npf_cache_t *, u_int, const in_port_t); 266 bool npf_rwrcksum(const npf_cache_t *, u_int, 267 const npf_addr_t *, const in_port_t); 268 int npf_napt_rwr(const npf_cache_t *, u_int, const npf_addr_t *, 269 const in_addr_t); 270 int npf_npt66_rwr(const npf_cache_t *, u_int, const npf_addr_t *, 271 npf_netmask_t, uint16_t); 272 273 uint16_t npf_fixup16_cksum(uint16_t, uint16_t, uint16_t); 274 uint16_t npf_fixup32_cksum(uint16_t, uint32_t, uint32_t); 275 uint16_t npf_addr_cksum(uint16_t, int, const npf_addr_t *, 276 const npf_addr_t *); 277 uint32_t npf_addr_mix(const int, const npf_addr_t *, const npf_addr_t *); 278 int npf_addr_cmp(const npf_addr_t *, const npf_netmask_t, 279 const npf_addr_t *, const npf_netmask_t, const int); 280 void npf_addr_mask(const npf_addr_t *, const npf_netmask_t, 281 const int, npf_addr_t *); 282 283 int npf_tcpsaw(const npf_cache_t *, tcp_seq *, tcp_seq *, 284 uint32_t *); 285 bool npf_fetch_tcpopts(npf_cache_t *, uint16_t *, int *); 286 bool npf_return_block(npf_cache_t *, const int); 287 288 /* BPF interface. */ 289 void npf_bpf_sysinit(void); 290 void npf_bpf_sysfini(void); 291 void npf_bpf_prepare(npf_cache_t *, bpf_args_t *, uint32_t *); 292 int npf_bpf_filter(bpf_args_t *, const void *, bpfjit_func_t); 293 void * npf_bpf_compile(void *, size_t); 294 bool npf_bpf_validate(const void *, size_t); 295 296 /* Tableset interface. */ 297 void npf_tableset_sysinit(void); 298 void npf_tableset_sysfini(void); 299 300 npf_tableset_t *npf_tableset_create(u_int); 301 void npf_tableset_destroy(npf_tableset_t *); 302 int npf_tableset_insert(npf_tableset_t *, npf_table_t *); 303 npf_table_t * npf_tableset_getbyname(npf_tableset_t *, const char *); 304 npf_table_t * npf_tableset_getbyid(npf_tableset_t *, u_int); 305 npf_table_t * npf_tableset_swap(npf_tableset_t *, npf_table_t *); 306 void npf_tableset_reload(npf_t *, npf_tableset_t *, npf_tableset_t *); 307 int npf_tableset_export(npf_t *, const npf_tableset_t *, prop_array_t); 308 309 npf_table_t * npf_table_create(const char *, u_int, int, void *, size_t); 310 void npf_table_destroy(npf_table_t *); 311 312 u_int npf_table_getid(npf_table_t *); 313 int npf_table_check(npf_tableset_t *, const char *, u_int, int); 314 int npf_table_insert(npf_table_t *, const int, 315 const npf_addr_t *, const npf_netmask_t); 316 int npf_table_remove(npf_table_t *, const int, 317 const npf_addr_t *, const npf_netmask_t); 318 int npf_table_lookup(npf_table_t *, const int, const npf_addr_t *); 319 int npf_table_list(npf_table_t *, void *, size_t); 320 int npf_table_flush(npf_table_t *); 321 322 /* Ruleset interface. */ 323 npf_ruleset_t * npf_ruleset_create(size_t); 324 void npf_ruleset_destroy(npf_ruleset_t *); 325 void npf_ruleset_insert(npf_ruleset_t *, npf_rule_t *); 326 void npf_ruleset_reload(npf_t *, npf_ruleset_t *, 327 npf_ruleset_t *, bool); 328 npf_rule_t * npf_ruleset_sharepm(npf_ruleset_t *, npf_natpolicy_t *); 329 npf_natpolicy_t *npf_ruleset_findnat(npf_ruleset_t *, uint64_t); 330 void npf_ruleset_freealg(npf_ruleset_t *, npf_alg_t *); 331 int npf_ruleset_export(npf_t *, const npf_ruleset_t *, prop_array_t); 332 333 npf_rule_t * npf_ruleset_lookup(npf_ruleset_t *, const char *); 334 int npf_ruleset_add(npf_ruleset_t *, const char *, npf_rule_t *); 335 int npf_ruleset_remove(npf_ruleset_t *, const char *, uint64_t); 336 int npf_ruleset_remkey(npf_ruleset_t *, const char *, 337 const void *, size_t); 338 prop_dictionary_t npf_ruleset_list(npf_t *, npf_ruleset_t *, const char *); 339 int npf_ruleset_flush(npf_ruleset_t *, const char *); 340 void npf_ruleset_gc(npf_ruleset_t *); 341 342 npf_rule_t * npf_ruleset_inspect(npf_cache_t *, const npf_ruleset_t *, 343 const int, const int); 344 int npf_rule_conclude(const npf_rule_t *, npf_match_info_t *); 345 346 /* Rule interface. */ 347 npf_rule_t * npf_rule_alloc(npf_t *, prop_dictionary_t); 348 void npf_rule_setcode(npf_rule_t *, int, void *, size_t); 349 void npf_rule_setrproc(npf_rule_t *, npf_rproc_t *); 350 void npf_rule_free(npf_rule_t *); 351 uint64_t npf_rule_getid(const npf_rule_t *); 352 npf_natpolicy_t *npf_rule_getnat(const npf_rule_t *); 353 void npf_rule_setnat(npf_rule_t *, npf_natpolicy_t *); 354 npf_rproc_t * npf_rule_getrproc(const npf_rule_t *); 355 356 void npf_ext_init(npf_t *); 357 void npf_ext_fini(npf_t *); 358 int npf_ext_construct(npf_t *, const char *, 359 npf_rproc_t *, prop_dictionary_t); 360 361 npf_rprocset_t *npf_rprocset_create(void); 362 void npf_rprocset_destroy(npf_rprocset_t *); 363 npf_rproc_t * npf_rprocset_lookup(npf_rprocset_t *, const char *); 364 void npf_rprocset_insert(npf_rprocset_t *, npf_rproc_t *); 365 int npf_rprocset_export(const npf_rprocset_t *, prop_array_t); 366 367 npf_rproc_t * npf_rproc_create(prop_dictionary_t); 368 void npf_rproc_acquire(npf_rproc_t *); 369 void npf_rproc_release(npf_rproc_t *); 370 const char * npf_rproc_getname(const npf_rproc_t *); 371 bool npf_rproc_run(npf_cache_t *, npf_rproc_t *, 372 const npf_match_info_t *, int *); 373 374 /* State handling. */ 375 bool npf_state_init(npf_cache_t *, npf_state_t *); 376 bool npf_state_inspect(npf_cache_t *, npf_state_t *, const bool); 377 int npf_state_etime(const npf_state_t *, const int); 378 void npf_state_destroy(npf_state_t *); 379 380 bool npf_state_tcp(npf_cache_t *, npf_state_t *, int); 381 int npf_state_tcp_timeout(const npf_state_t *); 382 383 /* NAT. */ 384 void npf_nat_sysinit(void); 385 void npf_nat_sysfini(void); 386 npf_natpolicy_t *npf_nat_newpolicy(npf_t *, prop_dictionary_t, npf_ruleset_t *); 387 int npf_nat_policyexport(const npf_natpolicy_t *, prop_dictionary_t); 388 void npf_nat_freepolicy(npf_natpolicy_t *); 389 bool npf_nat_cmppolicy(npf_natpolicy_t *, npf_natpolicy_t *); 390 bool npf_nat_sharepm(npf_natpolicy_t *, npf_natpolicy_t *); 391 void npf_nat_setid(npf_natpolicy_t *, uint64_t); 392 uint64_t npf_nat_getid(const npf_natpolicy_t *); 393 void npf_nat_freealg(npf_natpolicy_t *, npf_alg_t *); 394 395 int npf_do_nat(npf_cache_t *, npf_conn_t *, const int); 396 void npf_nat_destroy(npf_nat_t *); 397 void npf_nat_getorig(npf_nat_t *, npf_addr_t **, in_port_t *); 398 void npf_nat_gettrans(npf_nat_t *, npf_addr_t **, in_port_t *); 399 void npf_nat_setalg(npf_nat_t *, npf_alg_t *, uintptr_t); 400 401 void npf_nat_export(prop_dictionary_t, npf_nat_t *); 402 npf_nat_t * npf_nat_import(npf_t *, prop_dictionary_t, npf_ruleset_t *, 403 npf_conn_t *); 404 405 /* ALG interface. */ 406 void npf_alg_init(npf_t *); 407 void npf_alg_fini(npf_t *); 408 npf_alg_t * npf_alg_register(npf_t *, const char *, const npfa_funcs_t *); 409 int npf_alg_unregister(npf_t *, npf_alg_t *); 410 npf_alg_t * npf_alg_construct(npf_t *, const char *); 411 bool npf_alg_match(npf_cache_t *, npf_nat_t *, int); 412 void npf_alg_exec(npf_cache_t *, npf_nat_t *, bool); 413 npf_conn_t * npf_alg_conn(npf_cache_t *, int); 414 prop_array_t npf_alg_export(npf_t *); 415 416 /* Debugging routines. */ 417 const char * npf_addr_dump(const npf_addr_t *, int); 418 void npf_state_dump(const npf_state_t *); 419 void npf_nat_dump(const npf_nat_t *); 420 void npf_ruleset_dump(npf_t *, const char *); 421 void npf_state_setsampler(void (*)(npf_state_t *, bool)); 422 423 /* In-kernel routines. */ 424 void npf_setkernctx(npf_t *); 425 npf_t * npf_getkernctx(void); 426 427 #ifdef __NetBSD__ 428 #define pserialize_register(x) 429 #define pserialize_checkpoint(x) 430 #endif 431 432 #endif /* _NPF_IMPL_H_ */ 433