| File: | netpfil/pf/pf_ioctl.c |
| Warning: | line 3624, column 11 Copies out a struct with a union element with different sizes |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /*- | |||
| 2 | * SPDX-License-Identifier: BSD-2-Clause | |||
| 3 | * | |||
| 4 | * Copyright (c) 2001 Daniel Hartmeier | |||
| 5 | * Copyright (c) 2002,2003 Henning Brauer | |||
| 6 | * Copyright (c) 2012 Gleb Smirnoff <[email protected]> | |||
| 7 | * All rights reserved. | |||
| 8 | * | |||
| 9 | * Redistribution and use in source and binary forms, with or without | |||
| 10 | * modification, are permitted provided that the following conditions | |||
| 11 | * are met: | |||
| 12 | * | |||
| 13 | * - Redistributions of source code must retain the above copyright | |||
| 14 | * notice, this list of conditions and the following disclaimer. | |||
| 15 | * - Redistributions in binary form must reproduce the above | |||
| 16 | * copyright notice, this list of conditions and the following | |||
| 17 | * disclaimer in the documentation and/or other materials provided | |||
| 18 | * with the distribution. | |||
| 19 | * | |||
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |||
| 23 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |||
| 24 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
| 25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |||
| 26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| 27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
| 28 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |||
| 30 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
| 31 | * POSSIBILITY OF SUCH DAMAGE. | |||
| 32 | * | |||
| 33 | * Effort sponsored in part by the Defense Advanced Research Projects | |||
| 34 | * Agency (DARPA) and Air Force Research Laboratory, Air Force | |||
| 35 | * Materiel Command, USAF, under agreement number F30602-01-2-0537. | |||
| 36 | * | |||
| 37 | * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $ | |||
| 38 | */ | |||
| 39 | ||||
| 40 | #include <sys/cdefs.h> | |||
| 41 | __FBSDID("$FreeBSD$")__asm__(".ident\t\"" "$FreeBSD$" "\""); | |||
| 42 | ||||
| 43 | #include "opt_inet.h" | |||
| 44 | #include "opt_inet6.h" | |||
| 45 | #include "opt_bpf.h" | |||
| 46 | #include "opt_pf.h" | |||
| 47 | ||||
| 48 | #include <sys/param.h> | |||
| 49 | #include <sys/bus.h> | |||
| 50 | #include <sys/conf.h> | |||
| 51 | #include <sys/endian.h> | |||
| 52 | #include <sys/fcntl.h> | |||
| 53 | #include <sys/filio.h> | |||
| 54 | #include <sys/interrupt.h> | |||
| 55 | #include <sys/jail.h> | |||
| 56 | #include <sys/kernel.h> | |||
| 57 | #include <sys/kthread.h> | |||
| 58 | #include <sys/lock.h> | |||
| 59 | #include <sys/mbuf.h> | |||
| 60 | #include <sys/module.h> | |||
| 61 | #include <sys/proc.h> | |||
| 62 | #include <sys/smp.h> | |||
| 63 | #include <sys/socket.h> | |||
| 64 | #include <sys/sysctl.h> | |||
| 65 | #include <sys/md5.h> | |||
| 66 | #include <sys/ucred.h> | |||
| 67 | ||||
| 68 | #include <net/if.h> | |||
| 69 | #include <net/if_var.h> | |||
| 70 | #include <net/vnet.h> | |||
| 71 | #include <net/route.h> | |||
| 72 | #include <net/pfil.h> | |||
| 73 | #include <net/pfvar.h> | |||
| 74 | #include <net/if_pfsync.h> | |||
| 75 | #include <net/if_pflog.h> | |||
| 76 | ||||
| 77 | #include <netinet/in.h> | |||
| 78 | #include <netinet/ip.h> | |||
| 79 | #include <netinet/ip_var.h> | |||
| 80 | #include <netinet6/ip6_var.h> | |||
| 81 | #include <netinet/ip_icmp.h> | |||
| 82 | ||||
| 83 | #ifdef INET61 | |||
| 84 | #include <netinet/ip6.h> | |||
| 85 | #endif /* INET6 */ | |||
| 86 | ||||
| 87 | #ifdef ALTQ | |||
| 88 | #include <net/altq/altq.h> | |||
| 89 | #endif | |||
| 90 | ||||
| 91 | static struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t, | |||
| 92 | u_int8_t, u_int8_t, u_int8_t); | |||
| 93 | ||||
| 94 | static void pf_mv_pool(struct pf_palist *, struct pf_palist *); | |||
| 95 | static void pf_empty_pool(struct pf_palist *); | |||
| 96 | static int pfioctl(struct cdev *, u_long, caddr_t, int, | |||
| 97 | struct thread *); | |||
| 98 | #ifdef ALTQ | |||
| 99 | static int pf_begin_altq(u_int32_t *); | |||
| 100 | static int pf_rollback_altq(u_int32_t); | |||
| 101 | static int pf_commit_altq(u_int32_t); | |||
| 102 | static int pf_enable_altq(struct pf_altqpf_kaltq *); | |||
| 103 | static int pf_disable_altq(struct pf_altqpf_kaltq *); | |||
| 104 | static u_int32_t pf_qname2qid(char *); | |||
| 105 | static void pf_qid_unref(u_int32_t); | |||
| 106 | #endif /* ALTQ */ | |||
| 107 | static int pf_begin_rules(u_int32_t *, int, const char *); | |||
| 108 | static int pf_rollback_rules(u_int32_t, int, char *); | |||
| 109 | static int pf_setup_pfsync_matching(struct pf_ruleset *); | |||
| 110 | static void pf_hash_rule(MD5_CTX *, struct pf_rule *); | |||
| 111 | static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); | |||
| 112 | static int pf_commit_rules(u_int32_t, int, char *); | |||
| 113 | static int pf_addr_setup(struct pf_ruleset *, | |||
| 114 | struct pf_addr_wrap *, sa_family_t); | |||
| 115 | static void pf_addr_copyout(struct pf_addr_wrap *); | |||
| 116 | #ifdef ALTQ | |||
| 117 | static int pf_export_kaltq(struct pf_altqpf_kaltq *, | |||
| 118 | struct pfioc_altq_v1 *, size_t); | |||
| 119 | static int pf_import_kaltq(struct pfioc_altq_v1 *, | |||
| 120 | struct pf_altqpf_kaltq *, size_t); | |||
| 121 | #endif /* ALTQ */ | |||
| 122 | ||||
| 123 | VNET_DEFINE(struct pf_rule, pf_default_rule)struct _hack; struct pf_rule vnet_entry_pf_default_rule __attribute__ ((__section__("set_vnet"))) __attribute__((__used__)); | |||
| 124 | ||||
| 125 | #ifdef ALTQ | |||
| 126 | VNET_DEFINE_STATIC(int, pf_altq_running)static int vnet_entry_pf_altq_running __attribute__((__section__ ("set_vnet"))) __attribute__((__used__)); | |||
| 127 | #define V_pf_altq_running VNET(pf_altq_running)(*(__typeof(vnet_entry_pf_altq_running)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altq_running )) | |||
| 128 | #endif | |||
| 129 | ||||
| 130 | #define TAGID_MAX50000 50000 | |||
| 131 | struct pf_tagname { | |||
| 132 | TAILQ_ENTRY(pf_tagname)struct { struct pf_tagname *tqe_next; struct pf_tagname **tqe_prev ; } entries; | |||
| 133 | char name[PF_TAG_NAME_SIZE64]; | |||
| 134 | uint16_t tag; | |||
| 135 | int ref; | |||
| 136 | }; | |||
| 137 | ||||
| 138 | TAILQ_HEAD(pf_tags, pf_tagname)struct pf_tags { struct pf_tagname *tqh_first; struct pf_tagname **tqh_last; }; | |||
| 139 | #define V_pf_tags(*(__typeof(vnet_entry_pf_tags)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags)) VNET(pf_tags)(*(__typeof(vnet_entry_pf_tags)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags)) | |||
| 140 | VNET_DEFINE(struct pf_tags, pf_tags)struct _hack; struct pf_tags vnet_entry_pf_tags __attribute__ ((__section__("set_vnet"))) __attribute__((__used__)); | |||
| 141 | #define V_pf_qids(*(__typeof(vnet_entry_pf_qids)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_qids)) VNET(pf_qids)(*(__typeof(vnet_entry_pf_qids)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_qids)) | |||
| 142 | VNET_DEFINE(struct pf_tags, pf_qids)struct _hack; struct pf_tags vnet_entry_pf_qids __attribute__ ((__section__("set_vnet"))) __attribute__((__used__)); | |||
| 143 | static MALLOC_DEFINE(M_PFTAG, "pf_tag", "pf(4) tag names")struct malloc_type M_PFTAG[1] = { { ((void *)0), 877983977, "pf_tag" , ((void *)0) } }; static struct sysinit M_PFTAG_init_sys_init = { SI_SUB_KMEM, SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t )malloc_init, ((void *)(M_PFTAG)) }; __asm__(".globl " "__start_set_sysinit_set" ); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_M_PFTAG_init_sys_init __attribute__( (__section__("set_" "sysinit_set"))) __attribute__((__used__) ) = &(M_PFTAG_init_sys_init); static struct sysinit M_PFTAG_uninit_sys_uninit = { SI_SUB_KMEM, SI_ORDER_ANY, (sysinit_cfunc_t)(sysinit_nfunc_t )malloc_uninit, ((void *)(M_PFTAG)) }; __asm__(".globl " "__start_set_sysuninit_set" ); __asm__(".globl " "__stop_set_sysuninit_set"); static void const * __set_sysuninit_set_sym_M_PFTAG_uninit_sys_uninit __attribute__ ((__section__("set_" "sysuninit_set"))) __attribute__((__used__ )) = &(M_PFTAG_uninit_sys_uninit); | |||
| 144 | static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db")struct malloc_type M_PFALTQ[1] = { { ((void *)0), 877983977, "pf_altq" , ((void *)0) } }; static struct sysinit M_PFALTQ_init_sys_init = { SI_SUB_KMEM, SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t )malloc_init, ((void *)(M_PFALTQ)) }; __asm__(".globl " "__start_set_sysinit_set" ); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_M_PFALTQ_init_sys_init __attribute__ ((__section__("set_" "sysinit_set"))) __attribute__((__used__ )) = &(M_PFALTQ_init_sys_init); static struct sysinit M_PFALTQ_uninit_sys_uninit = { SI_SUB_KMEM, SI_ORDER_ANY, (sysinit_cfunc_t)(sysinit_nfunc_t )malloc_uninit, ((void *)(M_PFALTQ)) }; __asm__(".globl " "__start_set_sysuninit_set" ); __asm__(".globl " "__stop_set_sysuninit_set"); static void const * __set_sysuninit_set_sym_M_PFALTQ_uninit_sys_uninit __attribute__ ((__section__("set_" "sysuninit_set"))) __attribute__((__used__ )) = &(M_PFALTQ_uninit_sys_uninit); | |||
| 145 | static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules")struct malloc_type M_PFRULE[1] = { { ((void *)0), 877983977, "pf_rule" , ((void *)0) } }; static struct sysinit M_PFRULE_init_sys_init = { SI_SUB_KMEM, SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t )malloc_init, ((void *)(M_PFRULE)) }; __asm__(".globl " "__start_set_sysinit_set" ); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_M_PFRULE_init_sys_init __attribute__ ((__section__("set_" "sysinit_set"))) __attribute__((__used__ )) = &(M_PFRULE_init_sys_init); static struct sysinit M_PFRULE_uninit_sys_uninit = { SI_SUB_KMEM, SI_ORDER_ANY, (sysinit_cfunc_t)(sysinit_nfunc_t )malloc_uninit, ((void *)(M_PFRULE)) }; __asm__(".globl " "__start_set_sysuninit_set" ); __asm__(".globl " "__stop_set_sysuninit_set"); static void const * __set_sysuninit_set_sym_M_PFRULE_uninit_sys_uninit __attribute__ ((__section__("set_" "sysuninit_set"))) __attribute__((__used__ )) = &(M_PFRULE_uninit_sys_uninit); | |||
| 146 | ||||
| 147 | #if (PF_QNAME_SIZE64 != PF_TAG_NAME_SIZE64) | |||
| 148 | #error PF_QNAME_SIZE64 must be equal to PF_TAG_NAME_SIZE64 | |||
| 149 | #endif | |||
| 150 | ||||
| 151 | static u_int16_t tagname2tag(struct pf_tags *, char *); | |||
| 152 | static u_int16_t pf_tagname2tag(char *); | |||
| 153 | static void tag_unref(struct pf_tags *, u_int16_t); | |||
| 154 | ||||
| 155 | #define DPFPRINTF(n, x)if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (n)) printf x if (V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (n)) printf x | |||
| 156 | ||||
| 157 | struct cdev *pf_dev; | |||
| 158 | ||||
| 159 | /* | |||
| 160 | * XXX - These are new and need to be checked when moveing to a new version | |||
| 161 | */ | |||
| 162 | static void pf_clear_states(void); | |||
| 163 | static int pf_clear_tables(void); | |||
| 164 | static void pf_clear_srcnodes(struct pf_src_node *); | |||
| 165 | static void pf_kill_srcnodes(struct pfioc_src_node_kill *); | |||
| 166 | static void pf_tbladdr_copyout(struct pf_addr_wrap *); | |||
| 167 | ||||
| 168 | /* | |||
| 169 | * Wrapper functions for pfil(9) hooks | |||
| 170 | */ | |||
| 171 | #ifdef INET1 | |||
| 172 | static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
| 173 | int dir, int flags, struct inpcb *inp); | |||
| 174 | static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
| 175 | int dir, int flags, struct inpcb *inp); | |||
| 176 | #endif | |||
| 177 | #ifdef INET61 | |||
| 178 | static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
| 179 | int dir, int flags, struct inpcb *inp); | |||
| 180 | static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
| 181 | int dir, int flags, struct inpcb *inp); | |||
| 182 | #endif | |||
| 183 | ||||
| 184 | static int hook_pf(void); | |||
| 185 | static int dehook_pf(void); | |||
| 186 | static int shutdown_pf(void); | |||
| 187 | static int pf_load(void); | |||
| 188 | static void pf_unload(void); | |||
| 189 | ||||
| 190 | static struct cdevsw pf_cdevsw = { | |||
| 191 | .d_ioctl = pfioctl, | |||
| 192 | .d_name = PF_NAME"pf", | |||
| 193 | .d_version = D_VERSION0x17122009, | |||
| 194 | }; | |||
| 195 | ||||
| 196 | volatile VNET_DEFINE_STATIC(int, pf_pfil_hooked)static int vnet_entry_pf_pfil_hooked __attribute__((__section__ ("set_vnet"))) __attribute__((__used__)); | |||
| 197 | #define V_pf_pfil_hooked(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked )) VNET(pf_pfil_hooked)(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked )) | |||
| 198 | ||||
| 199 | /* | |||
| 200 | * We need a flag that is neither hooked nor running to know when | |||
| 201 | * the VNET is "valid". We primarily need this to control (global) | |||
| 202 | * external event, e.g., eventhandlers. | |||
| 203 | */ | |||
| 204 | VNET_DEFINE(int, pf_vnet_active)struct _hack; int vnet_entry_pf_vnet_active __attribute__((__section__ ("set_vnet"))) __attribute__((__used__)); | |||
| 205 | #define V_pf_vnet_active(*(__typeof(vnet_entry_pf_vnet_active)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_vnet_active )) VNET(pf_vnet_active)(*(__typeof(vnet_entry_pf_vnet_active)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_vnet_active )) | |||
| 206 | ||||
| 207 | int pf_end_threads; | |||
| 208 | struct proc *pf_purge_proc; | |||
| 209 | ||||
| 210 | struct rmlock pf_rules_lock; | |||
| 211 | struct sx pf_ioctl_lock; | |||
| 212 | struct sx pf_end_lock; | |||
| 213 | ||||
| 214 | /* pfsync */ | |||
| 215 | VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr)struct _hack; pfsync_state_import_t * vnet_entry_pfsync_state_import_ptr __attribute__((__section__("set_vnet"))) __attribute__((__used__ )); | |||
| 216 | VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr)struct _hack; pfsync_insert_state_t * vnet_entry_pfsync_insert_state_ptr __attribute__((__section__("set_vnet"))) __attribute__((__used__ )); | |||
| 217 | VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr)struct _hack; pfsync_update_state_t * vnet_entry_pfsync_update_state_ptr __attribute__((__section__("set_vnet"))) __attribute__((__used__ )); | |||
| 218 | VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr)struct _hack; pfsync_delete_state_t * vnet_entry_pfsync_delete_state_ptr __attribute__((__section__("set_vnet"))) __attribute__((__used__ )); | |||
| 219 | VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr)struct _hack; pfsync_clear_states_t * vnet_entry_pfsync_clear_states_ptr __attribute__((__section__("set_vnet"))) __attribute__((__used__ )); | |||
| 220 | VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr)struct _hack; pfsync_defer_t * vnet_entry_pfsync_defer_ptr __attribute__ ((__section__("set_vnet"))) __attribute__((__used__)); | |||
| 221 | pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr; | |||
| 222 | ||||
| 223 | /* pflog */ | |||
| 224 | pflog_packet_t *pflog_packet_ptr = NULL((void *)0); | |||
| 225 | ||||
| 226 | extern u_long pf_ioctl_maxcount; | |||
| 227 | ||||
| 228 | static void | |||
| 229 | pfattach_vnet(void) | |||
| 230 | { | |||
| 231 | u_int32_t *my_timeout = V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).timeout; | |||
| 232 | ||||
| 233 | pf_initialize(); | |||
| 234 | pfr_initialize(); | |||
| 235 | pfi_initialize_vnet(); | |||
| 236 | pf_normalize_init(); | |||
| 237 | ||||
| 238 | V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[PF_LIMIT_STATES].limit = PFSTATE_HIWAT100000; | |||
| 239 | V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT10000; | |||
| 240 | ||||
| 241 | RB_INIT(&V_pf_anchors)do { (&(*(__typeof(vnet_entry_pf_anchors)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_anchors )))->rbh_root = ((void *)0); } while ( 0); | |||
| 242 | pf_init_ruleset(&pf_main_ruleset(*(__typeof(vnet_entry_pf_main_anchor)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_main_anchor )).ruleset); | |||
| 243 | ||||
| 244 | /* default rule should never be garbage collected */ | |||
| 245 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).entries.tqe_prev = &V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).entries.tqe_next; | |||
| 246 | #ifdef PF_DEFAULT_TO_DROP | |||
| 247 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).action = PF_DROP; | |||
| 248 | #else | |||
| 249 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).action = PF_PASS; | |||
| 250 | #endif | |||
| 251 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).nr = -1; | |||
| 252 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).rtableid = -1; | |||
| 253 | ||||
| 254 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).states_cur = counter_u64_alloc(M_WAITOK0x0002); | |||
| 255 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).states_tot = counter_u64_alloc(M_WAITOK0x0002); | |||
| 256 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).src_nodes = counter_u64_alloc(M_WAITOK0x0002); | |||
| 257 | ||||
| 258 | /* initialize default timeouts */ | |||
| 259 | my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL120; | |||
| 260 | my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL30; | |||
| 261 | my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL24*60*60; | |||
| 262 | my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL15 * 60; | |||
| 263 | my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL45; | |||
| 264 | my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL90; | |||
| 265 | my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL60; | |||
| 266 | my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL30; | |||
| 267 | my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL60; | |||
| 268 | my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL20; | |||
| 269 | my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL10; | |||
| 270 | my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL60; | |||
| 271 | my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL30; | |||
| 272 | my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL60; | |||
| 273 | my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL30; | |||
| 274 | my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL10; | |||
| 275 | my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL0; | |||
| 276 | my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL30; | |||
| 277 | my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START60000; | |||
| 278 | my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END120000; | |||
| 279 | ||||
| 280 | bzero(&V_pf_status, sizeof(V_pf_status))__builtin_memset((&(*(__typeof(vnet_entry_pf_status)*) (( (((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_status))), 0, (sizeof((*(__typeof(vnet_entry_pf_status )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_status))))); | |||
| 281 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug = PF_DEBUG_URGENT; | |||
| 282 | ||||
| 283 | V_pf_pfil_hooked(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked )) = 0; | |||
| 284 | ||||
| 285 | /* XXX do our best to avoid a conflict */ | |||
| 286 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).hostid = arc4random(); | |||
| 287 | ||||
| 288 | for (int i = 0; i < PFRES_MAX16; i++) | |||
| 289 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).counters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
| 290 | for (int i = 0; i < LCNT_MAX7; i++) | |||
| 291 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).lcounters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
| 292 | for (int i = 0; i < FCNT_MAX3; i++) | |||
| 293 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).fcounters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
| 294 | for (int i = 0; i < SCNT_MAX3; i++) | |||
| 295 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).scounters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
| 296 | ||||
| 297 | if (swi_add(NULL((void *)0), "pf send", pf_intr, curvnet(__curthread())->td_vnet, SWI_NET1, | |||
| 298 | INTR_MPSAFE, &V_pf_swi_cookie(*(__typeof(vnet_entry_pf_swi_cookie)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_swi_cookie ))) != 0) | |||
| 299 | /* XXXGL: leaked all above. */ | |||
| 300 | return; | |||
| 301 | } | |||
| 302 | ||||
| 303 | ||||
| 304 | static struct pf_pool * | |||
| 305 | pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action, | |||
| 306 | u_int32_t rule_number, u_int8_t r_last, u_int8_t active, | |||
| 307 | u_int8_t check_ticket) | |||
| 308 | { | |||
| 309 | struct pf_ruleset *ruleset; | |||
| 310 | struct pf_rule *rule; | |||
| 311 | int rs_num; | |||
| 312 | ||||
| 313 | ruleset = pf_find_ruleset(anchor); | |||
| 314 | if (ruleset == NULL((void *)0)) | |||
| 315 | return (NULL((void *)0)); | |||
| 316 | rs_num = pf_get_ruleset_number(rule_action); | |||
| 317 | if (rs_num >= PF_RULESET_MAX) | |||
| 318 | return (NULL((void *)0)); | |||
| 319 | if (active) { | |||
| 320 | if (check_ticket && ticket != | |||
| 321 | ruleset->rules[rs_num].active.ticket) | |||
| 322 | return (NULL((void *)0)); | |||
| 323 | if (r_last) | |||
| 324 | rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)) | |||
| 325 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)); | |||
| 326 | else | |||
| 327 | rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
| 328 | } else { | |||
| 329 | if (check_ticket && ticket != | |||
| 330 | ruleset->rules[rs_num].inactive.ticket) | |||
| 331 | return (NULL((void *)0)); | |||
| 332 | if (r_last) | |||
| 333 | rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)) | |||
| 334 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)); | |||
| 335 | else | |||
| 336 | rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr)((ruleset->rules[rs_num].inactive.ptr)->tqh_first); | |||
| 337 | } | |||
| 338 | if (!r_last) { | |||
| 339 | while ((rule != NULL((void *)0)) && (rule->nr != rule_number)) | |||
| 340 | rule = TAILQ_NEXT(rule, entries)((rule)->entries.tqe_next); | |||
| 341 | } | |||
| 342 | if (rule == NULL((void *)0)) | |||
| 343 | return (NULL((void *)0)); | |||
| 344 | ||||
| 345 | return (&rule->rpool); | |||
| 346 | } | |||
| 347 | ||||
| 348 | static void | |||
| 349 | pf_mv_pool(struct pf_palist *poola, struct pf_palist *poolb) | |||
| 350 | { | |||
| 351 | struct pf_pooladdr *mv_pool_pa; | |||
| 352 | ||||
| 353 | while ((mv_pool_pa = TAILQ_FIRST(poola)((poola)->tqh_first)) != NULL((void *)0)) { | |||
| 354 | TAILQ_REMOVE(poola, mv_pool_pa, entries)do { ; ; do { if ((((mv_pool_pa))->entries.tqe_next) != (( void *)0) && (((mv_pool_pa))->entries.tqe_next)-> entries.tqe_prev != &((mv_pool_pa)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm", (mv_pool_pa)); } while (0); do { if (*(mv_pool_pa)->entries.tqe_prev != ( mv_pool_pa)) panic("Bad link elm %p prev->next != elm", (mv_pool_pa )); } while (0); if (((((mv_pool_pa))->entries.tqe_next)) != ((void *)0)) (((mv_pool_pa))->entries.tqe_next)->entries .tqe_prev = (mv_pool_pa)->entries.tqe_prev; else { (poola) ->tqh_last = (mv_pool_pa)->entries.tqe_prev; ; } *(mv_pool_pa )->entries.tqe_prev = (((mv_pool_pa))->entries.tqe_next ); ; ; ; } while (0); | |||
| 355 | TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries)do { do { if (*(poolb)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (poolb)); } while (0); (((mv_pool_pa))->entries.tqe_next ) = ((void *)0); (mv_pool_pa)->entries.tqe_prev = (poolb)-> tqh_last; *(poolb)->tqh_last = (mv_pool_pa); (poolb)->tqh_last = &(((mv_pool_pa))->entries.tqe_next); ; ; } while (0 ); | |||
| 356 | } | |||
| 357 | } | |||
| 358 | ||||
| 359 | static void | |||
| 360 | pf_empty_pool(struct pf_palist *poola) | |||
| 361 | { | |||
| 362 | struct pf_pooladdr *pa; | |||
| 363 | ||||
| 364 | while ((pa = TAILQ_FIRST(poola)((poola)->tqh_first)) != NULL((void *)0)) { | |||
| 365 | switch (pa->addr.type) { | |||
| 366 | case PF_ADDR_DYNIFTL: | |||
| 367 | pfi_dynaddr_remove(pa->addr.p.dyn); | |||
| 368 | break; | |||
| 369 | case PF_ADDR_TABLE: | |||
| 370 | /* XXX: this could be unfinished pooladdr on pabuf */ | |||
| 371 | if (pa->addr.p.tbl != NULL((void *)0)) | |||
| 372 | pfr_detach_table(pa->addr.p.tbl); | |||
| 373 | break; | |||
| 374 | } | |||
| 375 | if (pa->kif) | |||
| 376 | pfi_kif_unref(pa->kif); | |||
| 377 | TAILQ_REMOVE(poola, pa, entries)do { ; ; do { if ((((pa))->entries.tqe_next) != ((void *)0 ) && (((pa))->entries.tqe_next)->entries.tqe_prev != &((pa)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (pa)); } while (0); do { if (*(pa)->entries.tqe_prev != ( pa)) panic("Bad link elm %p prev->next != elm", (pa)); } while (0); if (((((pa))->entries.tqe_next)) != ((void *)0)) ((( pa))->entries.tqe_next)->entries.tqe_prev = (pa)->entries .tqe_prev; else { (poola)->tqh_last = (pa)->entries.tqe_prev ; ; } *(pa)->entries.tqe_prev = (((pa))->entries.tqe_next ); ; ; ; } while (0); | |||
| 378 | free(pa, M_PFRULE); | |||
| 379 | } | |||
| 380 | } | |||
| 381 | ||||
| 382 | static void | |||
| 383 | pf_unlink_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) | |||
| 384 | { | |||
| 385 | ||||
| 386 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 386); | |||
| 387 | ||||
| 388 | TAILQ_REMOVE(rulequeue, rule, entries)do { ; ; do { if ((((rule))->entries.tqe_next) != ((void * )0) && (((rule))->entries.tqe_next)->entries.tqe_prev != &((rule)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (rule)); } while (0); do { if (*(rule)->entries.tqe_prev != (rule)) panic("Bad link elm %p prev->next != elm", (rule )); } while (0); if (((((rule))->entries.tqe_next)) != ((void *)0)) (((rule))->entries.tqe_next)->entries.tqe_prev = (rule)->entries.tqe_prev; else { (rulequeue)->tqh_last = (rule)->entries.tqe_prev; ; } *(rule)->entries.tqe_prev = (((rule))->entries.tqe_next); ; ; ; } while (0); | |||
| 389 | ||||
| 390 | PF_UNLNKDRULES_LOCK()__mtx_lock_flags(&((((&pf_unlnkdrules_mtx))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (390)); | |||
| 391 | rule->rule_flag |= PFRULE_REFS0x0080; | |||
| 392 | TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries)do { do { if (*(&(*(__typeof(vnet_entry_pf_unlinked_rules )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_unlinked_rules)))->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (&(*(__typeof(vnet_entry_pf_unlinked_rules)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_unlinked_rules )))); } while (0); (((rule))->entries.tqe_next) = ((void * )0); (rule)->entries.tqe_prev = (&(*(__typeof(vnet_entry_pf_unlinked_rules )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_unlinked_rules)))->tqh_last; * (&(*(__typeof(vnet_entry_pf_unlinked_rules)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_unlinked_rules )))->tqh_last = (rule); (&(*(__typeof(vnet_entry_pf_unlinked_rules )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_unlinked_rules)))->tqh_last = &(((rule))->entries.tqe_next); ; ; } while (0); | |||
| 393 | PF_UNLNKDRULES_UNLOCK()__mtx_unlock_flags(&((((&pf_unlnkdrules_mtx))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (393)); | |||
| 394 | } | |||
| 395 | ||||
| 396 | void | |||
| 397 | pf_free_rule(struct pf_rule *rule) | |||
| 398 | { | |||
| 399 | ||||
| 400 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 400); | |||
| 401 | ||||
| 402 | if (rule->tag) | |||
| 403 | tag_unref(&V_pf_tags(*(__typeof(vnet_entry_pf_tags)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags)), rule->tag); | |||
| 404 | if (rule->match_tag) | |||
| 405 | tag_unref(&V_pf_tags(*(__typeof(vnet_entry_pf_tags)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags)), rule->match_tag); | |||
| 406 | #ifdef ALTQ | |||
| 407 | if (rule->pqid != rule->qid) | |||
| 408 | pf_qid_unref(rule->pqid); | |||
| 409 | pf_qid_unref(rule->qid); | |||
| 410 | #endif | |||
| 411 | switch (rule->src.addr.type) { | |||
| 412 | case PF_ADDR_DYNIFTL: | |||
| 413 | pfi_dynaddr_remove(rule->src.addr.p.dyn); | |||
| 414 | break; | |||
| 415 | case PF_ADDR_TABLE: | |||
| 416 | pfr_detach_table(rule->src.addr.p.tbl); | |||
| 417 | break; | |||
| 418 | } | |||
| 419 | switch (rule->dst.addr.type) { | |||
| 420 | case PF_ADDR_DYNIFTL: | |||
| 421 | pfi_dynaddr_remove(rule->dst.addr.p.dyn); | |||
| 422 | break; | |||
| 423 | case PF_ADDR_TABLE: | |||
| 424 | pfr_detach_table(rule->dst.addr.p.tbl); | |||
| 425 | break; | |||
| 426 | } | |||
| 427 | if (rule->overload_tbl) | |||
| 428 | pfr_detach_table(rule->overload_tbl); | |||
| 429 | if (rule->kif) | |||
| 430 | pfi_kif_unref(rule->kif); | |||
| 431 | pf_anchor_remove(rule); | |||
| 432 | pf_empty_pool(&rule->rpool.list); | |||
| 433 | counter_u64_free(rule->states_cur); | |||
| 434 | counter_u64_free(rule->states_tot); | |||
| 435 | counter_u64_free(rule->src_nodes); | |||
| 436 | free(rule, M_PFRULE); | |||
| 437 | } | |||
| 438 | ||||
| 439 | static u_int16_t | |||
| 440 | tagname2tag(struct pf_tags *head, char *tagname) | |||
| 441 | { | |||
| 442 | struct pf_tagname *tag, *p = NULL((void *)0); | |||
| 443 | u_int16_t new_tagid = 1; | |||
| 444 | ||||
| 445 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 445); | |||
| 446 | ||||
| 447 | TAILQ_FOREACH(tag, head, entries)for ((tag) = (((head))->tqh_first); (tag); (tag) = (((tag) )->entries.tqe_next)) | |||
| 448 | if (strcmp(tagname, tag->name) == 0) { | |||
| 449 | tag->ref++; | |||
| 450 | return (tag->tag); | |||
| 451 | } | |||
| 452 | ||||
| 453 | /* | |||
| 454 | * to avoid fragmentation, we do a linear search from the beginning | |||
| 455 | * and take the first free slot we find. if there is none or the list | |||
| 456 | * is empty, append a new entry at the end. | |||
| 457 | */ | |||
| 458 | ||||
| 459 | /* new entry */ | |||
| 460 | if (!TAILQ_EMPTY(head)((head)->tqh_first == ((void *)0))) | |||
| 461 | for (p = TAILQ_FIRST(head)((head)->tqh_first); p != NULL((void *)0) && | |||
| 462 | p->tag == new_tagid; p = TAILQ_NEXT(p, entries)((p)->entries.tqe_next)) | |||
| 463 | new_tagid = p->tag + 1; | |||
| 464 | ||||
| 465 | if (new_tagid > TAGID_MAX50000) | |||
| 466 | return (0); | |||
| 467 | ||||
| 468 | /* allocate and fill new struct pf_tagname */ | |||
| 469 | tag = malloc(sizeof(*tag), M_PFTAG, M_NOWAIT0x0001|M_ZERO0x0100); | |||
| 470 | if (tag == NULL((void *)0)) | |||
| 471 | return (0); | |||
| 472 | strlcpy(tag->name, tagname, sizeof(tag->name)); | |||
| 473 | tag->tag = new_tagid; | |||
| 474 | tag->ref++; | |||
| 475 | ||||
| 476 | if (p != NULL((void *)0)) /* insert new entry before p */ | |||
| 477 | TAILQ_INSERT_BEFORE(p, tag, entries)do { do { if (*(p)->entries.tqe_prev != (p)) panic("Bad link elm %p prev->next != elm" , (p)); } while (0); (tag)->entries.tqe_prev = (p)->entries .tqe_prev; (((tag))->entries.tqe_next) = (p); *(p)->entries .tqe_prev = (tag); (p)->entries.tqe_prev = &(((tag))-> entries.tqe_next); ; ; } while (0); | |||
| 478 | else /* either list empty or no free slot in between */ | |||
| 479 | TAILQ_INSERT_TAIL(head, tag, entries)do { do { if (*(head)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (head)); } while (0); (((tag))->entries.tqe_next) = ((void *)0); (tag)->entries.tqe_prev = (head)->tqh_last; *(head )->tqh_last = (tag); (head)->tqh_last = &(((tag))-> entries.tqe_next); ; ; } while (0); | |||
| 480 | ||||
| 481 | return (tag->tag); | |||
| 482 | } | |||
| 483 | ||||
| 484 | static void | |||
| 485 | tag_unref(struct pf_tags *head, u_int16_t tag) | |||
| 486 | { | |||
| 487 | struct pf_tagname *p, *next; | |||
| 488 | ||||
| 489 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 489); | |||
| 490 | ||||
| 491 | for (p = TAILQ_FIRST(head)((head)->tqh_first); p != NULL((void *)0); p = next) { | |||
| 492 | next = TAILQ_NEXT(p, entries)((p)->entries.tqe_next); | |||
| 493 | if (tag == p->tag) { | |||
| 494 | if (--p->ref == 0) { | |||
| 495 | TAILQ_REMOVE(head, p, entries)do { ; ; do { if ((((p))->entries.tqe_next) != ((void *)0) && (((p))->entries.tqe_next)->entries.tqe_prev != &((p)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (p)); } while (0); do { if (*(p)->entries.tqe_prev != (p )) panic("Bad link elm %p prev->next != elm", (p)); } while (0); if (((((p))->entries.tqe_next)) != ((void *)0)) (((p ))->entries.tqe_next)->entries.tqe_prev = (p)->entries .tqe_prev; else { (head)->tqh_last = (p)->entries.tqe_prev ; ; } *(p)->entries.tqe_prev = (((p))->entries.tqe_next ); ; ; ; } while (0); | |||
| 496 | free(p, M_PFTAG); | |||
| 497 | } | |||
| 498 | break; | |||
| 499 | } | |||
| 500 | } | |||
| 501 | } | |||
| 502 | ||||
| 503 | static u_int16_t | |||
| 504 | pf_tagname2tag(char *tagname) | |||
| 505 | { | |||
| 506 | return (tagname2tag(&V_pf_tags(*(__typeof(vnet_entry_pf_tags)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags)), tagname)); | |||
| 507 | } | |||
| 508 | ||||
| 509 | #ifdef ALTQ | |||
| 510 | static u_int32_t | |||
| 511 | pf_qname2qid(char *qname) | |||
| 512 | { | |||
| 513 | return ((u_int32_t)tagname2tag(&V_pf_qids(*(__typeof(vnet_entry_pf_qids)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_qids)), qname)); | |||
| 514 | } | |||
| 515 | ||||
| 516 | static void | |||
| 517 | pf_qid_unref(u_int32_t qid) | |||
| 518 | { | |||
| 519 | tag_unref(&V_pf_qids(*(__typeof(vnet_entry_pf_qids)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_qids)), (u_int16_t)qid); | |||
| 520 | } | |||
| 521 | ||||
| 522 | static int | |||
| 523 | pf_begin_altq(u_int32_t *ticket) | |||
| 524 | { | |||
| 525 | struct pf_altqpf_kaltq *altq; | |||
| 526 | int error = 0; | |||
| 527 | ||||
| 528 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 528); | |||
| 529 | ||||
| 530 | /* Purge the old altq list */ | |||
| 531 | while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)(((*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))->tqh_first)) != NULL((void *)0)) { | |||
| 532 | TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries)do { ; ; do { if ((((altq))->entries.tqe_next) != ((void * )0) && (((altq))->entries.tqe_next)->entries.tqe_prev != &((altq)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (altq)); } while (0); do { if (*(altq)->entries.tqe_prev != (altq)) panic("Bad link elm %p prev->next != elm", (altq )); } while (0); if (((((altq))->entries.tqe_next)) != ((void *)0)) (((altq))->entries.tqe_next)->entries.tqe_prev = (altq)->entries.tqe_prev; else { ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last = (altq)->entries.tqe_prev; ; } *(altq)->entries.tqe_prev = (((altq))->entries.tqe_next); ; ; ; } while (0); | |||
| 533 | if (altq->qname[0] == 0 && | |||
| 534 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
| 535 | /* detach and destroy the discipline */ | |||
| 536 | error = altq_remove(altq); | |||
| 537 | } else | |||
| 538 | pf_qid_unref(altq->qid); | |||
| 539 | free(altq, M_PFALTQ); | |||
| 540 | } | |||
| 541 | if (error) | |||
| 542 | return (error); | |||
| 543 | *ticket = ++V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive )); | |||
| 544 | V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open )) = 1; | |||
| 545 | return (0); | |||
| 546 | } | |||
| 547 | ||||
| 548 | static int | |||
| 549 | pf_rollback_altq(u_int32_t ticket) | |||
| 550 | { | |||
| 551 | struct pf_altqpf_kaltq *altq; | |||
| 552 | int error = 0; | |||
| 553 | ||||
| 554 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 554); | |||
| 555 | ||||
| 556 | if (!V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open )) || ticket != V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive ))) | |||
| 557 | return (0); | |||
| 558 | /* Purge the old altq list */ | |||
| 559 | while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)(((*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))->tqh_first)) != NULL((void *)0)) { | |||
| 560 | TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries)do { ; ; do { if ((((altq))->entries.tqe_next) != ((void * )0) && (((altq))->entries.tqe_next)->entries.tqe_prev != &((altq)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (altq)); } while (0); do { if (*(altq)->entries.tqe_prev != (altq)) panic("Bad link elm %p prev->next != elm", (altq )); } while (0); if (((((altq))->entries.tqe_next)) != ((void *)0)) (((altq))->entries.tqe_next)->entries.tqe_prev = (altq)->entries.tqe_prev; else { ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last = (altq)->entries.tqe_prev; ; } *(altq)->entries.tqe_prev = (((altq))->entries.tqe_next); ; ; ; } while (0); | |||
| 561 | if (altq->qname[0] == 0 && | |||
| 562 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
| 563 | /* detach and destroy the discipline */ | |||
| 564 | error = altq_remove(altq); | |||
| 565 | } else | |||
| 566 | pf_qid_unref(altq->qid); | |||
| 567 | free(altq, M_PFALTQ); | |||
| 568 | } | |||
| 569 | V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open )) = 0; | |||
| 570 | return (error); | |||
| 571 | } | |||
| 572 | ||||
| 573 | static int | |||
| 574 | pf_commit_altq(u_int32_t ticket) | |||
| 575 | { | |||
| 576 | struct pf_altqqueue *old_altqs; | |||
| 577 | struct pf_altqpf_kaltq *altq; | |||
| 578 | int err, error = 0; | |||
| 579 | ||||
| 580 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 580); | |||
| 581 | ||||
| 582 | if (!V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open )) || ticket != V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive ))) | |||
| 583 | return (EBUSY16); | |||
| 584 | ||||
| 585 | /* swap altqs, keep the old. */ | |||
| 586 | old_altqs = V_pf_altqs_active(*(__typeof(vnet_entry_pf_altqs_active)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_active )); | |||
| 587 | V_pf_altqs_active(*(__typeof(vnet_entry_pf_altqs_active)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_active )) = V_pf_altqs_inactive(*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread( ))->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )); | |||
| 588 | V_pf_altqs_inactive(*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread( ))->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )) = old_altqs; | |||
| 589 | V_ticket_altqs_active(*(__typeof(vnet_entry_ticket_altqs_active)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_active )) = V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive )); | |||
| 590 | ||||
| 591 | /* Attach new disciplines */ | |||
| 592 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((*(__typeof(vnet_entry_pf_altqs_active)*) (( (((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_active))))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) { | |||
| 593 | if (altq->qname[0] == 0 && | |||
| 594 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
| 595 | /* attach the discipline */ | |||
| 596 | error = altq_pfattach(altq); | |||
| 597 | if (error == 0 && V_pf_altq_running) | |||
| 598 | error = pf_enable_altq(altq); | |||
| 599 | if (error != 0) | |||
| 600 | return (error); | |||
| 601 | } | |||
| 602 | } | |||
| 603 | ||||
| 604 | /* Purge the old altq list */ | |||
| 605 | while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)(((*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))->tqh_first)) != NULL((void *)0)) { | |||
| 606 | TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries)do { ; ; do { if ((((altq))->entries.tqe_next) != ((void * )0) && (((altq))->entries.tqe_next)->entries.tqe_prev != &((altq)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (altq)); } while (0); do { if (*(altq)->entries.tqe_prev != (altq)) panic("Bad link elm %p prev->next != elm", (altq )); } while (0); if (((((altq))->entries.tqe_next)) != ((void *)0)) (((altq))->entries.tqe_next)->entries.tqe_prev = (altq)->entries.tqe_prev; else { ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last = (altq)->entries.tqe_prev; ; } *(altq)->entries.tqe_prev = (((altq))->entries.tqe_next); ; ; ; } while (0); | |||
| 607 | if (altq->qname[0] == 0 && | |||
| 608 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
| 609 | /* detach and destroy the discipline */ | |||
| 610 | if (V_pf_altq_running) | |||
| 611 | error = pf_disable_altq(altq); | |||
| 612 | err = altq_pfdetach(altq); | |||
| 613 | if (err != 0 && error == 0) | |||
| 614 | error = err; | |||
| 615 | err = altq_remove(altq); | |||
| 616 | if (err != 0 && error == 0) | |||
| 617 | error = err; | |||
| 618 | } else | |||
| 619 | pf_qid_unref(altq->qid); | |||
| 620 | free(altq, M_PFALTQ); | |||
| 621 | } | |||
| 622 | ||||
| 623 | V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open )) = 0; | |||
| 624 | return (error); | |||
| 625 | } | |||
| 626 | ||||
| 627 | static int | |||
| 628 | pf_enable_altq(struct pf_altqpf_kaltq *altq) | |||
| 629 | { | |||
| 630 | struct ifnet *ifp; | |||
| 631 | struct tb_profile tb; | |||
| 632 | int error = 0; | |||
| 633 | ||||
| 634 | if ((ifp = ifunit(altq->ifname)) == NULL((void *)0)) | |||
| 635 | return (EINVAL22); | |||
| 636 | ||||
| 637 | if (ifp->if_snd.altq_type != ALTQT_NONE) | |||
| 638 | error = altq_enable(&ifp->if_snd); | |||
| 639 | ||||
| 640 | /* set tokenbucket regulator */ | |||
| 641 | if (error == 0 && ifp != NULL((void *)0) && ALTQ_IS_ENABLED(&ifp->if_snd)0) { | |||
| 642 | tb.rate = altq->ifbandwidth; | |||
| 643 | tb.depth = altq->tbrsize; | |||
| 644 | error = tbr_set(&ifp->if_snd, &tb); | |||
| 645 | } | |||
| 646 | ||||
| 647 | return (error); | |||
| 648 | } | |||
| 649 | ||||
| 650 | static int | |||
| 651 | pf_disable_altq(struct pf_altqpf_kaltq *altq) | |||
| 652 | { | |||
| 653 | struct ifnet *ifp; | |||
| 654 | struct tb_profile tb; | |||
| 655 | int error; | |||
| 656 | ||||
| 657 | if ((ifp = ifunit(altq->ifname)) == NULL((void *)0)) | |||
| 658 | return (EINVAL22); | |||
| 659 | ||||
| 660 | /* | |||
| 661 | * when the discipline is no longer referenced, it was overridden | |||
| 662 | * by a new one. if so, just return. | |||
| 663 | */ | |||
| 664 | if (altq->altq_disc != ifp->if_snd.altq_disc) | |||
| 665 | return (0); | |||
| 666 | ||||
| 667 | error = altq_disable(&ifp->if_snd); | |||
| 668 | ||||
| 669 | if (error == 0) { | |||
| 670 | /* clear tokenbucket regulator */ | |||
| 671 | tb.rate = 0; | |||
| 672 | error = tbr_set(&ifp->if_snd, &tb); | |||
| 673 | } | |||
| 674 | ||||
| 675 | return (error); | |||
| 676 | } | |||
| 677 | ||||
| 678 | void | |||
| 679 | pf_altq_ifnet_event(struct ifnet *ifp, int remove) | |||
| 680 | { | |||
| 681 | struct ifnet *ifp1; | |||
| 682 | struct pf_altqpf_kaltq *a1, *a2, *a3; | |||
| 683 | u_int32_t ticket; | |||
| 684 | int error = 0; | |||
| 685 | ||||
| 686 | /* Interrupt userland queue modifications */ | |||
| 687 | if (V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open ))) | |||
| 688 | pf_rollback_altq(V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive ))); | |||
| 689 | ||||
| 690 | /* Start new altq ruleset */ | |||
| 691 | if (pf_begin_altq(&ticket)) | |||
| 692 | return; | |||
| 693 | ||||
| 694 | /* Copy the current active set */ | |||
| 695 | TAILQ_FOREACH(a1, V_pf_altqs_active, entries)for ((a1) = ((((*(__typeof(vnet_entry_pf_altqs_active)*) (((( (__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_active))))->tqh_first); (a1); (a1 ) = (((a1))->entries.tqe_next)) { | |||
| 696 | a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT0x0001); | |||
| 697 | if (a2 == NULL((void *)0)) { | |||
| 698 | error = ENOMEM12; | |||
| 699 | break; | |||
| 700 | } | |||
| 701 | bcopy(a1, a2, sizeof(struct pf_altq))__builtin_memmove((a2), (a1), (sizeof(struct pf_kaltq))); | |||
| 702 | ||||
| 703 | if (a2->qname[0] != 0) { | |||
| 704 | if ((a2->qid = pf_qname2qid(a2->qname)) == 0) { | |||
| 705 | error = EBUSY16; | |||
| 706 | free(a2, M_PFALTQ); | |||
| 707 | break; | |||
| 708 | } | |||
| 709 | a2->altq_disc = NULL((void *)0); | |||
| 710 | TAILQ_FOREACH(a3, V_pf_altqs_inactive, entries)for ((a3) = ((((*(__typeof(vnet_entry_pf_altqs_inactive)*) (( (((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_inactive))))->tqh_first); (a3); ( a3) = (((a3))->entries.tqe_next)) { | |||
| 711 | if (strncmp(a3->ifname, a2->ifname, | |||
| 712 | IFNAMSIZ16) == 0 && a3->qname[0] == 0) { | |||
| 713 | a2->altq_disc = a3->altq_disc; | |||
| 714 | break; | |||
| 715 | } | |||
| 716 | } | |||
| 717 | } | |||
| 718 | /* Deactivate the interface in question */ | |||
| 719 | a2->local_flags &= ~PFALTQ_FLAG_IF_REMOVED0x01; | |||
| 720 | if ((ifp1 = ifunit(a2->ifname)) == NULL((void *)0) || | |||
| 721 | (remove && ifp1 == ifp)) { | |||
| 722 | a2->local_flags |= PFALTQ_FLAG_IF_REMOVED0x01; | |||
| 723 | } else { | |||
| 724 | error = altq_add(a2); | |||
| 725 | ||||
| 726 | if (ticket != V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive ))) | |||
| 727 | error = EBUSY16; | |||
| 728 | ||||
| 729 | if (error) { | |||
| 730 | free(a2, M_PFALTQ); | |||
| 731 | break; | |||
| 732 | } | |||
| 733 | } | |||
| 734 | ||||
| 735 | TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries)do { do { if (*((*(__typeof(vnet_entry_pf_altqs_inactive)*) ( ((((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_inactive)))->tqh_last != ((void * )0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL", ((*(__typeof (vnet_entry_pf_altqs_inactive)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))); } while (0); (((a2))->entries.tqe_next) = ((void *)0 ); (a2)->entries.tqe_prev = ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last; * ((*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))->tqh_last = (a2); ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last = &(((a2))->entries.tqe_next); ; ; } while (0); | |||
| 736 | } | |||
| 737 | ||||
| 738 | if (error != 0) | |||
| 739 | pf_rollback_altq(ticket); | |||
| 740 | else | |||
| 741 | pf_commit_altq(ticket); | |||
| 742 | } | |||
| 743 | #endif /* ALTQ */ | |||
| 744 | ||||
| 745 | static int | |||
| 746 | pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor) | |||
| 747 | { | |||
| 748 | struct pf_ruleset *rs; | |||
| 749 | struct pf_rule *rule; | |||
| 750 | ||||
| 751 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 751); | |||
| 752 | ||||
| 753 | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | |||
| 754 | return (EINVAL22); | |||
| 755 | rs = pf_find_or_create_ruleset(anchor); | |||
| 756 | if (rs == NULL((void *)0)) | |||
| 757 | return (EINVAL22); | |||
| 758 | while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)((rs->rules[rs_num].inactive.ptr)->tqh_first)) != NULL((void *)0)) { | |||
| 759 | pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule); | |||
| 760 | rs->rules[rs_num].inactive.rcount--; | |||
| 761 | } | |||
| 762 | *ticket = ++rs->rules[rs_num].inactive.ticket; | |||
| 763 | rs->rules[rs_num].inactive.open = 1; | |||
| 764 | return (0); | |||
| 765 | } | |||
| 766 | ||||
| 767 | static int | |||
| 768 | pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor) | |||
| 769 | { | |||
| 770 | struct pf_ruleset *rs; | |||
| 771 | struct pf_rule *rule; | |||
| 772 | ||||
| 773 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 773); | |||
| 774 | ||||
| 775 | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | |||
| 776 | return (EINVAL22); | |||
| 777 | rs = pf_find_ruleset(anchor); | |||
| 778 | if (rs == NULL((void *)0) || !rs->rules[rs_num].inactive.open || | |||
| 779 | rs->rules[rs_num].inactive.ticket != ticket) | |||
| 780 | return (0); | |||
| 781 | while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)((rs->rules[rs_num].inactive.ptr)->tqh_first)) != NULL((void *)0)) { | |||
| 782 | pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule); | |||
| 783 | rs->rules[rs_num].inactive.rcount--; | |||
| 784 | } | |||
| 785 | rs->rules[rs_num].inactive.open = 0; | |||
| 786 | return (0); | |||
| 787 | } | |||
| 788 | ||||
| 789 | #define PF_MD5_UPD(st, elm)MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)-> elm)) \ | |||
| 790 | MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm)) | |||
| 791 | ||||
| 792 | #define PF_MD5_UPD_STR(st, elm)MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm )) \ | |||
| 793 | MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm)) | |||
| 794 | ||||
| 795 | #define PF_MD5_UPD_HTONL(st, elm, stor)do { (stor) = (__builtin_constant_p((st)->elm) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)((st)->elm )) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(( st)->elm)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((st)->elm)) & 0xffff)) >> 8) : __bswap16_var(( (__uint32_t)((st)->elm)) & 0xffff))) << 16) | (( __uint16_t)(__builtin_constant_p(((__uint32_t)((st)->elm)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((st) ->elm)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t )((st)->elm)) >> 16)) >> 8) : __bswap16_var((( __uint32_t)((st)->elm)) >> 16)))) : __bswap32_var((st )->elm)); MD5Update(ctx, (u_int8_t *) &(stor), sizeof( u_int32_t));} while (0) do { \ | |||
| 796 | (stor) = htonl((st)->elm)(__builtin_constant_p((st)->elm) ? (((__uint32_t)((__uint16_t )(__builtin_constant_p(((__uint32_t)((st)->elm)) & 0xffff ) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((st)->elm)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((st)->elm )) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(( st)->elm)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p (((__uint32_t)((st)->elm)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((st)->elm)) >> 16)) << 8 | ((__uint16_t )(((__uint32_t)((st)->elm)) >> 16)) >> 8) : __bswap16_var (((__uint32_t)((st)->elm)) >> 16)))) : __bswap32_var ((st)->elm)); \ | |||
| 797 | MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\ | |||
| 798 | } while (0) | |||
| 799 | ||||
| 800 | #define PF_MD5_UPD_HTONS(st, elm, stor)do { (stor) = ((__uint16_t)(__builtin_constant_p((st)->elm ) ? (__uint16_t)(((__uint16_t)((st)->elm)) << 8 | (( __uint16_t)((st)->elm)) >> 8) : __bswap16_var((st)-> elm))); MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t ));} while (0) do { \ | |||
| 801 | (stor) = htons((st)->elm)((__uint16_t)(__builtin_constant_p((st)->elm) ? (__uint16_t )(((__uint16_t)((st)->elm)) << 8 | ((__uint16_t)((st )->elm)) >> 8) : __bswap16_var((st)->elm))); \ | |||
| 802 | MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\ | |||
| 803 | } while (0) | |||
| 804 | ||||
| 805 | static void | |||
| 806 | pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr) | |||
| 807 | { | |||
| 808 | PF_MD5_UPD(pfr, addr.type)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.type, sizeof( (pfr)->addr.type)); | |||
| 809 | switch (pfr->addr.type) { | |||
| 810 | case PF_ADDR_DYNIFTL: | |||
| 811 | PF_MD5_UPD(pfr, addr.v.ifname)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.v.ifname, sizeof ((pfr)->addr.v.ifname)); | |||
| 812 | PF_MD5_UPD(pfr, addr.iflags)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.iflags, sizeof ((pfr)->addr.iflags)); | |||
| 813 | break; | |||
| 814 | case PF_ADDR_TABLE: | |||
| 815 | PF_MD5_UPD(pfr, addr.v.tblname)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.v.tblname, sizeof ((pfr)->addr.v.tblname)); | |||
| 816 | break; | |||
| 817 | case PF_ADDR_ADDRMASK: | |||
| 818 | /* XXX ignore af? */ | |||
| 819 | PF_MD5_UPD(pfr, addr.v.a.addr.addr32)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.v.a.addr.pfa. addr32, sizeof((pfr)->addr.v.a.addr.pfa.addr32)); | |||
| 820 | PF_MD5_UPD(pfr, addr.v.a.mask.addr32)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.v.a.mask.pfa. addr32, sizeof((pfr)->addr.v.a.mask.pfa.addr32)); | |||
| 821 | break; | |||
| 822 | } | |||
| 823 | ||||
| 824 | PF_MD5_UPD(pfr, port[0])MD5Update(ctx, (u_int8_t *) &(pfr)->port[0], sizeof((pfr )->port[0])); | |||
| 825 | PF_MD5_UPD(pfr, port[1])MD5Update(ctx, (u_int8_t *) &(pfr)->port[1], sizeof((pfr )->port[1])); | |||
| 826 | PF_MD5_UPD(pfr, neg)MD5Update(ctx, (u_int8_t *) &(pfr)->neg, sizeof((pfr)-> neg)); | |||
| 827 | PF_MD5_UPD(pfr, port_op)MD5Update(ctx, (u_int8_t *) &(pfr)->port_op, sizeof((pfr )->port_op)); | |||
| 828 | } | |||
| 829 | ||||
| 830 | static void | |||
| 831 | pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule) | |||
| 832 | { | |||
| 833 | u_int16_t x; | |||
| 834 | u_int32_t y; | |||
| 835 | ||||
| 836 | pf_hash_rule_addr(ctx, &rule->src); | |||
| 837 | pf_hash_rule_addr(ctx, &rule->dst); | |||
| 838 | PF_MD5_UPD_STR(rule, label)MD5Update(ctx, (u_int8_t *) (rule)->label, strlen((rule)-> label)); | |||
| 839 | PF_MD5_UPD_STR(rule, ifname)MD5Update(ctx, (u_int8_t *) (rule)->ifname, strlen((rule)-> ifname)); | |||
| 840 | PF_MD5_UPD_STR(rule, match_tagname)MD5Update(ctx, (u_int8_t *) (rule)->match_tagname, strlen( (rule)->match_tagname)); | |||
| 841 | PF_MD5_UPD_HTONS(rule, match_tag, x)do { (x) = ((__uint16_t)(__builtin_constant_p((rule)->match_tag ) ? (__uint16_t)(((__uint16_t)((rule)->match_tag)) << 8 | ((__uint16_t)((rule)->match_tag)) >> 8) : __bswap16_var ((rule)->match_tag))); MD5Update(ctx, (u_int8_t *) &(x ), sizeof(u_int16_t));} while (0); /* dup? */ | |||
| 842 | PF_MD5_UPD_HTONL(rule, os_fingerprint, y)do { (y) = (__builtin_constant_p((rule)->os_fingerprint) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t )((rule)->os_fingerprint)) & 0xffff) ? (__uint16_t)((( __uint16_t)(((__uint32_t)((rule)->os_fingerprint)) & 0xffff )) << 8 | ((__uint16_t)(((__uint32_t)((rule)->os_fingerprint )) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(( rule)->os_fingerprint)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)((rule)->os_fingerprint )) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((rule )->os_fingerprint)) >> 16)) << 8 | ((__uint16_t )(((__uint32_t)((rule)->os_fingerprint)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((rule)->os_fingerprint)) >> 16)))) : __bswap32_var((rule)->os_fingerprint)); MD5Update(ctx, (u_int8_t *) &(y), sizeof(u_int32_t));} while (0); | |||
| 843 | PF_MD5_UPD_HTONL(rule, prob, y)do { (y) = (__builtin_constant_p((rule)->prob) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)((rule)-> prob)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t )((rule)->prob)) & 0xffff)) << 8 | ((__uint16_t) (((__uint32_t)((rule)->prob)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((rule)->prob)) & 0xffff)) ) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t )((rule)->prob)) >> 16) ? (__uint16_t)(((__uint16_t) (((__uint32_t)((rule)->prob)) >> 16)) << 8 | ( (__uint16_t)(((__uint32_t)((rule)->prob)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((rule)->prob)) >> 16 )))) : __bswap32_var((rule)->prob)); MD5Update(ctx, (u_int8_t *) &(y), sizeof(u_int32_t));} while (0); | |||
| 844 | PF_MD5_UPD_HTONL(rule, uid.uid[0], y)do { (y) = (__builtin_constant_p((rule)->uid.uid[0]) ? ((( __uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(( rule)->uid.uid[0])) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((rule)->uid.uid[0])) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->uid.uid[0])) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((rule)-> uid.uid[0])) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p (((__uint32_t)((rule)->uid.uid[0])) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)((rule)->uid.uid[0])) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->uid .uid[0])) >> 16)) >> 8) : __bswap16_var(((__uint32_t )((rule)->uid.uid[0])) >> 16)))) : __bswap32_var((rule )->uid.uid[0])); MD5Update(ctx, (u_int8_t *) &(y), sizeof (u_int32_t));} while (0); | |||
| 845 | PF_MD5_UPD_HTONL(rule, uid.uid[1], y)do { (y) = (__builtin_constant_p((rule)->uid.uid[1]) ? ((( __uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(( rule)->uid.uid[1])) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((rule)->uid.uid[1])) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->uid.uid[1])) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((rule)-> uid.uid[1])) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p (((__uint32_t)((rule)->uid.uid[1])) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)((rule)->uid.uid[1])) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->uid .uid[1])) >> 16)) >> 8) : __bswap16_var(((__uint32_t )((rule)->uid.uid[1])) >> 16)))) : __bswap32_var((rule )->uid.uid[1])); MD5Update(ctx, (u_int8_t *) &(y), sizeof (u_int32_t));} while (0); | |||
| 846 | PF_MD5_UPD(rule, uid.op)MD5Update(ctx, (u_int8_t *) &(rule)->uid.op, sizeof((rule )->uid.op)); | |||
| 847 | PF_MD5_UPD_HTONL(rule, gid.gid[0], y)do { (y) = (__builtin_constant_p((rule)->gid.gid[0]) ? ((( __uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(( rule)->gid.gid[0])) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((rule)->gid.gid[0])) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->gid.gid[0])) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((rule)-> gid.gid[0])) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p (((__uint32_t)((rule)->gid.gid[0])) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)((rule)->gid.gid[0])) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->gid .gid[0])) >> 16)) >> 8) : __bswap16_var(((__uint32_t )((rule)->gid.gid[0])) >> 16)))) : __bswap32_var((rule )->gid.gid[0])); MD5Update(ctx, (u_int8_t *) &(y), sizeof (u_int32_t));} while (0); | |||
| 848 | PF_MD5_UPD_HTONL(rule, gid.gid[1], y)do { (y) = (__builtin_constant_p((rule)->gid.gid[1]) ? ((( __uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(( rule)->gid.gid[1])) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((rule)->gid.gid[1])) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->gid.gid[1])) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((rule)-> gid.gid[1])) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p (((__uint32_t)((rule)->gid.gid[1])) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)((rule)->gid.gid[1])) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->gid .gid[1])) >> 16)) >> 8) : __bswap16_var(((__uint32_t )((rule)->gid.gid[1])) >> 16)))) : __bswap32_var((rule )->gid.gid[1])); MD5Update(ctx, (u_int8_t *) &(y), sizeof (u_int32_t));} while (0); | |||
| 849 | PF_MD5_UPD(rule, gid.op)MD5Update(ctx, (u_int8_t *) &(rule)->gid.op, sizeof((rule )->gid.op)); | |||
| 850 | PF_MD5_UPD_HTONL(rule, rule_flag, y)do { (y) = (__builtin_constant_p((rule)->rule_flag) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)((rule)-> rule_flag)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t )((rule)->rule_flag)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)((rule)->rule_flag)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((rule)->rule_flag)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p( ((__uint32_t)((rule)->rule_flag)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)((rule)->rule_flag)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((rule)->rule_flag )) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((rule )->rule_flag)) >> 16)))) : __bswap32_var((rule)-> rule_flag)); MD5Update(ctx, (u_int8_t *) &(y), sizeof(u_int32_t ));} while (0); | |||
| 851 | PF_MD5_UPD(rule, action)MD5Update(ctx, (u_int8_t *) &(rule)->action, sizeof((rule )->action)); | |||
| 852 | PF_MD5_UPD(rule, direction)MD5Update(ctx, (u_int8_t *) &(rule)->direction, sizeof ((rule)->direction)); | |||
| 853 | PF_MD5_UPD(rule, af)MD5Update(ctx, (u_int8_t *) &(rule)->af, sizeof((rule) ->af)); | |||
| 854 | PF_MD5_UPD(rule, quick)MD5Update(ctx, (u_int8_t *) &(rule)->quick, sizeof((rule )->quick)); | |||
| 855 | PF_MD5_UPD(rule, ifnot)MD5Update(ctx, (u_int8_t *) &(rule)->ifnot, sizeof((rule )->ifnot)); | |||
| 856 | PF_MD5_UPD(rule, match_tag_not)MD5Update(ctx, (u_int8_t *) &(rule)->match_tag_not, sizeof ((rule)->match_tag_not)); | |||
| 857 | PF_MD5_UPD(rule, natpass)MD5Update(ctx, (u_int8_t *) &(rule)->natpass, sizeof(( rule)->natpass)); | |||
| 858 | PF_MD5_UPD(rule, keep_state)MD5Update(ctx, (u_int8_t *) &(rule)->keep_state, sizeof ((rule)->keep_state)); | |||
| 859 | PF_MD5_UPD(rule, proto)MD5Update(ctx, (u_int8_t *) &(rule)->proto, sizeof((rule )->proto)); | |||
| 860 | PF_MD5_UPD(rule, type)MD5Update(ctx, (u_int8_t *) &(rule)->type, sizeof((rule )->type)); | |||
| 861 | PF_MD5_UPD(rule, code)MD5Update(ctx, (u_int8_t *) &(rule)->code, sizeof((rule )->code)); | |||
| 862 | PF_MD5_UPD(rule, flags)MD5Update(ctx, (u_int8_t *) &(rule)->flags, sizeof((rule )->flags)); | |||
| 863 | PF_MD5_UPD(rule, flagset)MD5Update(ctx, (u_int8_t *) &(rule)->flagset, sizeof(( rule)->flagset)); | |||
| 864 | PF_MD5_UPD(rule, allow_opts)MD5Update(ctx, (u_int8_t *) &(rule)->allow_opts, sizeof ((rule)->allow_opts)); | |||
| 865 | PF_MD5_UPD(rule, rt)MD5Update(ctx, (u_int8_t *) &(rule)->rt, sizeof((rule) ->rt)); | |||
| 866 | PF_MD5_UPD(rule, tos)MD5Update(ctx, (u_int8_t *) &(rule)->tos, sizeof((rule )->tos)); | |||
| 867 | } | |||
| 868 | ||||
| 869 | static int | |||
| 870 | pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) | |||
| 871 | { | |||
| 872 | struct pf_ruleset *rs; | |||
| 873 | struct pf_rule *rule, **old_array; | |||
| 874 | struct pf_rulequeue *old_rules; | |||
| 875 | int error; | |||
| 876 | u_int32_t old_rcount; | |||
| 877 | ||||
| 878 | PF_RULES_WASSERT()_rm_assert((&pf_rules_lock), (0x00000004), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 878); | |||
| 879 | ||||
| 880 | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | |||
| 881 | return (EINVAL22); | |||
| 882 | rs = pf_find_ruleset(anchor); | |||
| 883 | if (rs == NULL((void *)0) || !rs->rules[rs_num].inactive.open || | |||
| 884 | ticket != rs->rules[rs_num].inactive.ticket) | |||
| 885 | return (EBUSY16); | |||
| 886 | ||||
| 887 | /* Calculate checksum for the main ruleset */ | |||
| 888 | if (rs == &pf_main_ruleset(*(__typeof(vnet_entry_pf_main_anchor)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_main_anchor )).ruleset) { | |||
| 889 | error = pf_setup_pfsync_matching(rs); | |||
| 890 | if (error != 0) | |||
| 891 | return (error); | |||
| 892 | } | |||
| 893 | ||||
| 894 | /* Swap rules, keep the old. */ | |||
| 895 | old_rules = rs->rules[rs_num].active.ptr; | |||
| 896 | old_rcount = rs->rules[rs_num].active.rcount; | |||
| 897 | old_array = rs->rules[rs_num].active.ptr_array; | |||
| 898 | ||||
| 899 | rs->rules[rs_num].active.ptr = | |||
| 900 | rs->rules[rs_num].inactive.ptr; | |||
| 901 | rs->rules[rs_num].active.ptr_array = | |||
| 902 | rs->rules[rs_num].inactive.ptr_array; | |||
| 903 | rs->rules[rs_num].active.rcount = | |||
| 904 | rs->rules[rs_num].inactive.rcount; | |||
| 905 | rs->rules[rs_num].inactive.ptr = old_rules; | |||
| 906 | rs->rules[rs_num].inactive.ptr_array = old_array; | |||
| 907 | rs->rules[rs_num].inactive.rcount = old_rcount; | |||
| 908 | ||||
| 909 | rs->rules[rs_num].active.ticket = | |||
| 910 | rs->rules[rs_num].inactive.ticket; | |||
| 911 | pf_calc_skip_steps(rs->rules[rs_num].active.ptr); | |||
| 912 | ||||
| 913 | ||||
| 914 | /* Purge the old rule list. */ | |||
| 915 | while ((rule = TAILQ_FIRST(old_rules)((old_rules)->tqh_first)) != NULL((void *)0)) | |||
| 916 | pf_unlink_rule(old_rules, rule); | |||
| 917 | if (rs->rules[rs_num].inactive.ptr_array) | |||
| 918 | free(rs->rules[rs_num].inactive.ptr_array, M_TEMP); | |||
| 919 | rs->rules[rs_num].inactive.ptr_array = NULL((void *)0); | |||
| 920 | rs->rules[rs_num].inactive.rcount = 0; | |||
| 921 | rs->rules[rs_num].inactive.open = 0; | |||
| 922 | pf_remove_if_empty_ruleset(rs); | |||
| 923 | ||||
| 924 | return (0); | |||
| 925 | } | |||
| 926 | ||||
| 927 | static int | |||
| 928 | pf_setup_pfsync_matching(struct pf_ruleset *rs) | |||
| 929 | { | |||
| 930 | MD5_CTX ctx; | |||
| 931 | struct pf_rule *rule; | |||
| 932 | int rs_cnt; | |||
| 933 | u_int8_t digest[PF_MD5_DIGEST_LENGTH16]; | |||
| 934 | ||||
| 935 | MD5Init(&ctx); | |||
| 936 | for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) { | |||
| 937 | /* XXX PF_RULESET_SCRUB as well? */ | |||
| 938 | if (rs_cnt == PF_RULESET_SCRUB) | |||
| 939 | continue; | |||
| 940 | ||||
| 941 | if (rs->rules[rs_cnt].inactive.ptr_array) | |||
| 942 | free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP); | |||
| 943 | rs->rules[rs_cnt].inactive.ptr_array = NULL((void *)0); | |||
| 944 | ||||
| 945 | if (rs->rules[rs_cnt].inactive.rcount) { | |||
| 946 | rs->rules[rs_cnt].inactive.ptr_array = | |||
| 947 | malloc(sizeof(caddr_t) * | |||
| 948 | rs->rules[rs_cnt].inactive.rcount, | |||
| 949 | M_TEMP, M_NOWAIT0x0001); | |||
| 950 | ||||
| 951 | if (!rs->rules[rs_cnt].inactive.ptr_array) | |||
| 952 | return (ENOMEM12); | |||
| 953 | } | |||
| 954 | ||||
| 955 | TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,for ((rule) = (((rs->rules[rs_cnt].inactive.ptr))->tqh_first ); (rule); (rule) = (((rule))->entries.tqe_next)) | |||
| 956 | entries)for ((rule) = (((rs->rules[rs_cnt].inactive.ptr))->tqh_first ); (rule); (rule) = (((rule))->entries.tqe_next)) { | |||
| 957 | pf_hash_rule(&ctx, rule); | |||
| 958 | (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule; | |||
| 959 | } | |||
| 960 | } | |||
| 961 | ||||
| 962 | MD5Final(digest, &ctx); | |||
| 963 | memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum))__builtin_memcpy(((*(__typeof(vnet_entry_pf_status)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).pf_chksum), (digest), (sizeof((*(__typeof(vnet_entry_pf_status )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_status)).pf_chksum))); | |||
| 964 | return (0); | |||
| 965 | } | |||
| 966 | ||||
| 967 | static int | |||
| 968 | pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr, | |||
| 969 | sa_family_t af) | |||
| 970 | { | |||
| 971 | int error = 0; | |||
| 972 | ||||
| 973 | switch (addr->type) { | |||
| 974 | case PF_ADDR_TABLE: | |||
| 975 | addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname); | |||
| 976 | if (addr->p.tbl == NULL((void *)0)) | |||
| 977 | error = ENOMEM12; | |||
| 978 | break; | |||
| 979 | case PF_ADDR_DYNIFTL: | |||
| 980 | error = pfi_dynaddr_setup(addr, af); | |||
| 981 | break; | |||
| 982 | } | |||
| 983 | ||||
| 984 | return (error); | |||
| 985 | } | |||
| 986 | ||||
| 987 | static void | |||
| 988 | pf_addr_copyout(struct pf_addr_wrap *addr) | |||
| 989 | { | |||
| 990 | ||||
| 991 | switch (addr->type) { | |||
| 992 | case PF_ADDR_DYNIFTL: | |||
| 993 | pfi_dynaddr_copyout(addr); | |||
| 994 | break; | |||
| 995 | case PF_ADDR_TABLE: | |||
| 996 | pf_tbladdr_copyout(addr); | |||
| 997 | break; | |||
| 998 | } | |||
| 999 | } | |||
| 1000 | ||||
| 1001 | #ifdef ALTQ | |||
| 1002 | /* | |||
| 1003 | * Handle export of struct pf_kaltq to user binaries that may be using any | |||
| 1004 | * version of struct pf_altq. | |||
| 1005 | */ | |||
| 1006 | static int | |||
| 1007 | pf_export_kaltq(struct pf_altqpf_kaltq *q, struct pfioc_altq_v1 *pa, size_t ioc_size) | |||
| 1008 | { | |||
| 1009 | u_int32_t version; | |||
| 1010 | ||||
| 1011 | if (ioc_size == sizeof(struct pfioc_altq_v0)) | |||
| 1012 | version = 0; | |||
| 1013 | else | |||
| 1014 | version = pa->version; | |||
| 1015 | ||||
| 1016 | if (version > PFIOC_ALTQ_VERSION1) | |||
| 1017 | return (EINVAL22); | |||
| 1018 | ||||
| 1019 | #define ASSIGN(x) exported_q->x = q->x | |||
| 1020 | #define COPY(x) \ | |||
| 1021 | bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x)))__builtin_memmove((&exported_q->x), (&q->x), (min (sizeof(q->x), sizeof(exported_q->x)))) | |||
| 1022 | #define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX0xffff) | |||
| 1023 | #define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX0xffffffff) | |||
| 1024 | ||||
| 1025 | switch (version) { | |||
| 1026 | case 0: { | |||
| 1027 | struct pf_altq_v0 *exported_q = | |||
| 1028 | &((struct pfioc_altq_v0 *)pa)->altq; | |||
| 1029 | ||||
| 1030 | COPY(ifname); | |||
| 1031 | ||||
| 1032 | ASSIGN(scheduler); | |||
| 1033 | ASSIGN(tbrsize); | |||
| 1034 | exported_q->tbrsize = SATU16(q->tbrsize); | |||
| 1035 | exported_q->ifbandwidth = SATU32(q->ifbandwidth); | |||
| 1036 | ||||
| 1037 | COPY(qname); | |||
| 1038 | COPY(parent); | |||
| 1039 | ASSIGN(parent_qid); | |||
| 1040 | exported_q->bandwidth = SATU32(q->bandwidth); | |||
| 1041 | ASSIGN(priority); | |||
| 1042 | ASSIGN(local_flags); | |||
| 1043 | ||||
| 1044 | ASSIGN(qlimit); | |||
| 1045 | ASSIGN(flags); | |||
| 1046 | ||||
| 1047 | if (q->scheduler == ALTQT_HFSC) { | |||
| 1048 | #define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x | |||
| 1049 | #define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \ | |||
| 1050 | SATU32(q->pq_u.hfsc_opts.x) | |||
| 1051 | ||||
| 1052 | ASSIGN_OPT_SATU32(rtsc_m1); | |||
| 1053 | ASSIGN_OPT(rtsc_d); | |||
| 1054 | ASSIGN_OPT_SATU32(rtsc_m2); | |||
| 1055 | ||||
| 1056 | ASSIGN_OPT_SATU32(lssc_m1); | |||
| 1057 | ASSIGN_OPT(lssc_d); | |||
| 1058 | ASSIGN_OPT_SATU32(lssc_m2); | |||
| 1059 | ||||
| 1060 | ASSIGN_OPT_SATU32(ulsc_m1); | |||
| 1061 | ASSIGN_OPT(ulsc_d); | |||
| 1062 | ASSIGN_OPT_SATU32(ulsc_m2); | |||
| 1063 | ||||
| 1064 | ASSIGN_OPT(flags); | |||
| 1065 | ||||
| 1066 | #undef ASSIGN_OPT | |||
| 1067 | #undef ASSIGN_OPT_SATU32 | |||
| 1068 | } else | |||
| 1069 | COPY(pq_u); | |||
| 1070 | ||||
| 1071 | ASSIGN(qid); | |||
| 1072 | break; | |||
| 1073 | } | |||
| 1074 | case 1: { | |||
| 1075 | struct pf_altq_v1 *exported_q = | |||
| 1076 | &((struct pfioc_altq_v1 *)pa)->altq; | |||
| 1077 | ||||
| 1078 | COPY(ifname); | |||
| 1079 | ||||
| 1080 | ASSIGN(scheduler); | |||
| 1081 | ASSIGN(tbrsize); | |||
| 1082 | ASSIGN(ifbandwidth); | |||
| 1083 | ||||
| 1084 | COPY(qname); | |||
| 1085 | COPY(parent); | |||
| 1086 | ASSIGN(parent_qid); | |||
| 1087 | ASSIGN(bandwidth); | |||
| 1088 | ASSIGN(priority); | |||
| 1089 | ASSIGN(local_flags); | |||
| 1090 | ||||
| 1091 | ASSIGN(qlimit); | |||
| 1092 | ASSIGN(flags); | |||
| 1093 | COPY(pq_u); | |||
| 1094 | ||||
| 1095 | ASSIGN(qid); | |||
| 1096 | break; | |||
| 1097 | } | |||
| 1098 | default: | |||
| 1099 | panic("%s: unhandled struct pfioc_altq version", __func__); | |||
| 1100 | break; | |||
| 1101 | } | |||
| 1102 | ||||
| 1103 | #undef ASSIGN | |||
| 1104 | #undef COPY | |||
| 1105 | #undef SATU16 | |||
| 1106 | #undef SATU32 | |||
| 1107 | ||||
| 1108 | return (0); | |||
| 1109 | } | |||
| 1110 | ||||
| 1111 | /* | |||
| 1112 | * Handle import to struct pf_kaltq of struct pf_altq from user binaries | |||
| 1113 | * that may be using any version of it. | |||
| 1114 | */ | |||
| 1115 | static int | |||
| 1116 | pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altqpf_kaltq *q, size_t ioc_size) | |||
| 1117 | { | |||
| 1118 | u_int32_t version; | |||
| 1119 | ||||
| 1120 | if (ioc_size == sizeof(struct pfioc_altq_v0)) | |||
| 1121 | version = 0; | |||
| 1122 | else | |||
| 1123 | version = pa->version; | |||
| 1124 | ||||
| 1125 | if (version > PFIOC_ALTQ_VERSION1) | |||
| 1126 | return (EINVAL22); | |||
| 1127 | ||||
| 1128 | #define ASSIGN(x) q->x = imported_q->x | |||
| 1129 | #define COPY(x) \ | |||
| 1130 | bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x)))__builtin_memmove((&q->x), (&imported_q->x), (min (sizeof(imported_q->x), sizeof(q->x)))) | |||
| 1131 | ||||
| 1132 | switch (version) { | |||
| 1133 | case 0: { | |||
| 1134 | struct pf_altq_v0 *imported_q = | |||
| 1135 | &((struct pfioc_altq_v0 *)pa)->altq; | |||
| 1136 | ||||
| 1137 | COPY(ifname); | |||
| 1138 | ||||
| 1139 | ASSIGN(scheduler); | |||
| 1140 | ASSIGN(tbrsize); /* 16-bit -> 32-bit */ | |||
| 1141 | ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */ | |||
| 1142 | ||||
| 1143 | COPY(qname); | |||
| 1144 | COPY(parent); | |||
| 1145 | ASSIGN(parent_qid); | |||
| 1146 | ASSIGN(bandwidth); /* 32-bit -> 64-bit */ | |||
| 1147 | ASSIGN(priority); | |||
| 1148 | ASSIGN(local_flags); | |||
| 1149 | ||||
| 1150 | ASSIGN(qlimit); | |||
| 1151 | ASSIGN(flags); | |||
| 1152 | ||||
| 1153 | if (imported_q->scheduler == ALTQT_HFSC) { | |||
| 1154 | #define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x | |||
| 1155 | ||||
| 1156 | /* | |||
| 1157 | * The m1 and m2 parameters are being copied from | |||
| 1158 | * 32-bit to 64-bit. | |||
| 1159 | */ | |||
| 1160 | ASSIGN_OPT(rtsc_m1); | |||
| 1161 | ASSIGN_OPT(rtsc_d); | |||
| 1162 | ASSIGN_OPT(rtsc_m2); | |||
| 1163 | ||||
| 1164 | ASSIGN_OPT(lssc_m1); | |||
| 1165 | ASSIGN_OPT(lssc_d); | |||
| 1166 | ASSIGN_OPT(lssc_m2); | |||
| 1167 | ||||
| 1168 | ASSIGN_OPT(ulsc_m1); | |||
| 1169 | ASSIGN_OPT(ulsc_d); | |||
| 1170 | ASSIGN_OPT(ulsc_m2); | |||
| 1171 | ||||
| 1172 | ASSIGN_OPT(flags); | |||
| 1173 | ||||
| 1174 | #undef ASSIGN_OPT | |||
| 1175 | } else | |||
| 1176 | COPY(pq_u); | |||
| 1177 | ||||
| 1178 | ASSIGN(qid); | |||
| 1179 | break; | |||
| 1180 | } | |||
| 1181 | case 1: { | |||
| 1182 | struct pf_altq_v1 *imported_q = | |||
| 1183 | &((struct pfioc_altq_v1 *)pa)->altq; | |||
| 1184 | ||||
| 1185 | COPY(ifname); | |||
| 1186 | ||||
| 1187 | ASSIGN(scheduler); | |||
| 1188 | ASSIGN(tbrsize); | |||
| 1189 | ASSIGN(ifbandwidth); | |||
| 1190 | ||||
| 1191 | COPY(qname); | |||
| 1192 | COPY(parent); | |||
| 1193 | ASSIGN(parent_qid); | |||
| 1194 | ASSIGN(bandwidth); | |||
| 1195 | ASSIGN(priority); | |||
| 1196 | ASSIGN(local_flags); | |||
| 1197 | ||||
| 1198 | ASSIGN(qlimit); | |||
| 1199 | ASSIGN(flags); | |||
| 1200 | COPY(pq_u); | |||
| 1201 | ||||
| 1202 | ASSIGN(qid); | |||
| 1203 | break; | |||
| 1204 | } | |||
| 1205 | default: | |||
| 1206 | panic("%s: unhandled struct pfioc_altq version", __func__); | |||
| 1207 | break; | |||
| 1208 | } | |||
| 1209 | ||||
| 1210 | #undef ASSIGN | |||
| 1211 | #undef COPY | |||
| 1212 | ||||
| 1213 | return (0); | |||
| 1214 | } | |||
| 1215 | #endif /* ALTQ */ | |||
| 1216 | ||||
| 1217 | static int | |||
| 1218 | pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) | |||
| 1219 | { | |||
| 1220 | int error = 0; | |||
| 1221 | PF_RULES_RLOCK_TRACKERstruct rm_priotracker _pf_rules_tracker; | |||
| 1222 | ||||
| 1223 | /* XXX keep in sync with switch() below */ | |||
| 1224 | if (securelevel_gt(td->td_ucred, 2)) | |||
| ||||
| 1225 | switch (cmd) { | |||
| 1226 | case DIOCGETRULES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((6)))): | |||
| 1227 | case DIOCGETRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((7)))): | |||
| 1228 | case DIOCGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((53)))): | |||
| 1229 | case DIOCGETADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((54)))): | |||
| 1230 | case DIOCGETSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((19)))): | |||
| 1231 | case DIOCSETSTATUSIF((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_if)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((20)))): | |||
| 1232 | case DIOCGETSTATUS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_status)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((21)))): | |||
| 1233 | case DIOCCLRSTATUS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((22)))): | |||
| 1234 | case DIOCNATLOOK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_natlook)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((23)))): | |||
| 1235 | case DIOCSETDEBUG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(u_int32_t )) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((24)))): | |||
| 1236 | case DIOCGETSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_states)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((25)))): | |||
| 1237 | case DIOCGETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((30)))): | |||
| 1238 | case DIOCCLRRULECTRS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((38)))): | |||
| 1239 | case DIOCGETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((39)))): | |||
| 1240 | case DIOCGETALTQSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((47)))): | |||
| 1241 | case DIOCGETALTQSV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((47)))): | |||
| 1242 | case DIOCGETALTQV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((48)))): | |||
| 1243 | case DIOCGETALTQV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((48)))): | |||
| 1244 | case DIOCGETQSTATSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v0)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50)))): | |||
| 1245 | case DIOCGETQSTATSV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v1)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50)))): | |||
| 1246 | case DIOCGETRULESETS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((58)))): | |||
| 1247 | case DIOCGETRULESET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((59)))): | |||
| 1248 | case DIOCRGETTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((63)))): | |||
| 1249 | case DIOCRGETTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((64)))): | |||
| 1250 | case DIOCRCLRTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((65)))): | |||
| 1251 | case DIOCRCLRADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((66)))): | |||
| 1252 | case DIOCRADDADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((67)))): | |||
| 1253 | case DIOCRDELADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((68)))): | |||
| 1254 | case DIOCRSETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((69)))): | |||
| 1255 | case DIOCRGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((70)))): | |||
| 1256 | case DIOCRGETASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((71)))): | |||
| 1257 | case DIOCRCLRASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((72)))): | |||
| 1258 | case DIOCRTSTADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((73)))): | |||
| 1259 | case DIOCOSFPGET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((80)))): | |||
| 1260 | case DIOCGETSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_nodes)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((84)))): | |||
| 1261 | case DIOCCLRSRCNODES((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((85)))): | |||
| 1262 | case DIOCIGETIFACES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((87)))): | |||
| 1263 | case DIOCGIFSPEEDV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92)))): | |||
| 1264 | case DIOCGIFSPEEDV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92)))): | |||
| 1265 | case DIOCSETIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((89)))): | |||
| 1266 | case DIOCCLRIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((90)))): | |||
| 1267 | break; | |||
| 1268 | case DIOCRCLRTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((60)))): | |||
| 1269 | case DIOCRADDTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((61)))): | |||
| 1270 | case DIOCRDELTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((62)))): | |||
| 1271 | case DIOCRSETTFLAGS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((74)))): | |||
| 1272 | if (((struct pfioc_table *)addr)->pfrio_flags & | |||
| 1273 | PFR_FLAG_DUMMY0x00000002) | |||
| 1274 | break; /* dummy operation ok */ | |||
| 1275 | return (EPERM1); | |||
| 1276 | default: | |||
| 1277 | return (EPERM1); | |||
| 1278 | } | |||
| 1279 | ||||
| 1280 | if (!(flags & FWRITE0x0002)) | |||
| 1281 | switch (cmd) { | |||
| 1282 | case DIOCGETRULES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((6)))): | |||
| 1283 | case DIOCGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((53)))): | |||
| 1284 | case DIOCGETADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((54)))): | |||
| 1285 | case DIOCGETSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((19)))): | |||
| 1286 | case DIOCGETSTATUS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_status)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((21)))): | |||
| 1287 | case DIOCGETSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_states)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((25)))): | |||
| 1288 | case DIOCGETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((30)))): | |||
| 1289 | case DIOCGETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((39)))): | |||
| 1290 | case DIOCGETALTQSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((47)))): | |||
| 1291 | case DIOCGETALTQSV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((47)))): | |||
| 1292 | case DIOCGETALTQV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((48)))): | |||
| 1293 | case DIOCGETALTQV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((48)))): | |||
| 1294 | case DIOCGETQSTATSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v0)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50)))): | |||
| 1295 | case DIOCGETQSTATSV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v1)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50)))): | |||
| 1296 | case DIOCGETRULESETS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((58)))): | |||
| 1297 | case DIOCGETRULESET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((59)))): | |||
| 1298 | case DIOCNATLOOK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_natlook)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((23)))): | |||
| 1299 | case DIOCRGETTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((63)))): | |||
| 1300 | case DIOCRGETTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((64)))): | |||
| 1301 | case DIOCRGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((70)))): | |||
| 1302 | case DIOCRGETASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((71)))): | |||
| 1303 | case DIOCRTSTADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((73)))): | |||
| 1304 | case DIOCOSFPGET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((80)))): | |||
| 1305 | case DIOCGETSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_nodes)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((84)))): | |||
| 1306 | case DIOCIGETIFACES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((87)))): | |||
| 1307 | case DIOCGIFSPEEDV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92)))): | |||
| 1308 | case DIOCGIFSPEEDV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92)))): | |||
| 1309 | break; | |||
| 1310 | case DIOCRCLRTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((60)))): | |||
| 1311 | case DIOCRADDTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((61)))): | |||
| 1312 | case DIOCRDELTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((62)))): | |||
| 1313 | case DIOCRCLRTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((65)))): | |||
| 1314 | case DIOCRCLRADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((66)))): | |||
| 1315 | case DIOCRADDADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((67)))): | |||
| 1316 | case DIOCRDELADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((68)))): | |||
| 1317 | case DIOCRSETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((69)))): | |||
| 1318 | case DIOCRSETTFLAGS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((74)))): | |||
| 1319 | if (((struct pfioc_table *)addr)->pfrio_flags & | |||
| 1320 | PFR_FLAG_DUMMY0x00000002) { | |||
| 1321 | flags |= FWRITE0x0002; /* need write lock for dummy */ | |||
| 1322 | break; /* dummy operation ok */ | |||
| 1323 | } | |||
| 1324 | return (EACCES13); | |||
| 1325 | case DIOCGETRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((7)))): | |||
| 1326 | if (((struct pfioc_rule *)addr)->action == | |||
| 1327 | PF_GET_CLR_CNTR) | |||
| 1328 | return (EACCES13); | |||
| 1329 | break; | |||
| 1330 | default: | |||
| 1331 | return (EACCES13); | |||
| 1332 | } | |||
| 1333 | ||||
| 1334 | CURVNET_SET(TD_TO_VNET(td))do { if (!((((td)->td_ucred)->cr_prison->pr_vnet) != ((void *)0) && (((td)->td_ucred)->cr_prison-> pr_vnet)->vnet_magic_n == 0x3e0d8f29)) panic ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p" , "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 1334, __func__, ( __curthread())->td_vnet, (((td)->td_ucred)->cr_prison ->pr_vnet)); } while (0); struct vnet *saved_vnet = (__curthread ())->td_vnet; (__curthread())->td_vnet = ((td)->td_ucred )->cr_prison->pr_vnet;; | |||
| 1335 | ||||
| 1336 | switch (cmd) { | |||
| 1337 | case DIOCSTART((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((1)))): | |||
| 1338 | sx_xlock(&pf_ioctl_lock)(void)_sx_xlock(((&pf_ioctl_lock)), 0, ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c" ), (1338)); | |||
| 1339 | if (V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running) | |||
| 1340 | error = EEXIST17; | |||
| 1341 | else { | |||
| 1342 | int cpu; | |||
| 1343 | ||||
| 1344 | error = hook_pf(); | |||
| 1345 | if (error) { | |||
| 1346 | DPFPRINTF(PF_DEBUG_MISC,if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil registration failed\n" ) | |||
| 1347 | ("pf: pfil registration failed\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil registration failed\n" ); | |||
| 1348 | break; | |||
| 1349 | } | |||
| 1350 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running = 1; | |||
| 1351 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).since = time_second; | |||
| 1352 | ||||
| 1353 | CPU_FOREACH(cpu)for ((cpu) = 0; (cpu) <= mp_maxid; (cpu)++) if (!(!((((& all_cpus)->__bits[(((((((256)) + (((sizeof(long) * 8)) - 1 )) / ((sizeof(long) * 8)))) == 1) ? 0 : (((cpu)) / (sizeof(long ) * 8)))] & (1L << ((((((((256))) + (((sizeof(long) * 8)) - 1)) / ((sizeof(long) * 8)))) == 1) ? (__size_t)(((cpu ))) : ((((cpu))) % (sizeof(long) * 8))))) != 0)))) | |||
| 1354 | V_pf_stateid(*(__typeof(vnet_entry_pf_stateid)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_stateid ))[cpu] = time_second; | |||
| 1355 | ||||
| 1356 | DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pf: started\n"); | |||
| 1357 | } | |||
| 1358 | break; | |||
| 1359 | ||||
| 1360 | case DIOCSTOP((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((2)))): | |||
| 1361 | sx_xlock(&pf_ioctl_lock)(void)_sx_xlock(((&pf_ioctl_lock)), 0, ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c" ), (1361)); | |||
| 1362 | if (!V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running) | |||
| 1363 | error = ENOENT2; | |||
| 1364 | else { | |||
| 1365 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running = 0; | |||
| 1366 | error = dehook_pf(); | |||
| 1367 | if (error) { | |||
| 1368 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running = 1; | |||
| 1369 | DPFPRINTF(PF_DEBUG_MISC,if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil unregistration failed\n" ) | |||
| 1370 | ("pf: pfil unregistration failed\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil unregistration failed\n" ); | |||
| 1371 | } | |||
| 1372 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).since = time_second; | |||
| 1373 | DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pf: stopped\n"); | |||
| 1374 | } | |||
| 1375 | break; | |||
| 1376 | ||||
| 1377 | case DIOCADDRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((4)))): { | |||
| 1378 | struct pfioc_rule *pr = (struct pfioc_rule *)addr; | |||
| 1379 | struct pf_ruleset *ruleset; | |||
| 1380 | struct pf_rule *rule, *tail; | |||
| 1381 | struct pf_pooladdr *pa; | |||
| 1382 | struct pfi_kif *kif = NULL((void *)0); | |||
| 1383 | int rs_num; | |||
| 1384 | ||||
| 1385 | if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE40) { | |||
| 1386 | error = EINVAL22; | |||
| 1387 | break; | |||
| 1388 | } | |||
| 1389 | #ifndef INET1 | |||
| 1390 | if (pr->rule.af == AF_INET2) { | |||
| 1391 | error = EAFNOSUPPORT47; | |||
| 1392 | break; | |||
| 1393 | } | |||
| 1394 | #endif /* INET */ | |||
| 1395 | #ifndef INET61 | |||
| 1396 | if (pr->rule.af == AF_INET628) { | |||
| 1397 | error = EAFNOSUPPORT47; | |||
| 1398 | break; | |||
| 1399 | } | |||
| 1400 | #endif /* INET6 */ | |||
| 1401 | ||||
| 1402 | rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK0x0002); | |||
| 1403 | bcopy(&pr->rule, rule, sizeof(struct pf_rule))__builtin_memmove((rule), (&pr->rule), (sizeof(struct pf_rule ))); | |||
| 1404 | if (rule->ifname[0]) | |||
| 1405 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
| 1406 | rule->states_cur = counter_u64_alloc(M_WAITOK0x0002); | |||
| 1407 | rule->states_tot = counter_u64_alloc(M_WAITOK0x0002); | |||
| 1408 | rule->src_nodes = counter_u64_alloc(M_WAITOK0x0002); | |||
| 1409 | rule->cuid = td->td_ucred->cr_ruid; | |||
| 1410 | rule->cpid = td->td_proc ? td->td_proc->p_pid : 0; | |||
| 1411 | TAILQ_INIT(&rule->rpool.list)do { (((&rule->rpool.list))->tqh_first) = ((void *) 0); (&rule->rpool.list)->tqh_last = &(((&rule ->rpool.list))->tqh_first); ; } while (0); | |||
| 1412 | ||||
| 1413 | #define ERROUT(x) { error = (x); goto DIOCADDRULE_error; } | |||
| 1414 | ||||
| 1415 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1415); | |||
| 1416 | pr->anchor[sizeof(pr->anchor) - 1] = 0; | |||
| 1417 | ruleset = pf_find_ruleset(pr->anchor); | |||
| 1418 | if (ruleset == NULL((void *)0)) | |||
| 1419 | ERROUT(EINVAL22); | |||
| 1420 | rs_num = pf_get_ruleset_number(pr->rule.action); | |||
| 1421 | if (rs_num >= PF_RULESET_MAX) | |||
| 1422 | ERROUT(EINVAL22); | |||
| 1423 | if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) { | |||
| 1424 | DPFPRINTF(PF_DEBUG_MISC,if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("ticket: %d != [%d]%d\n" , pr->ticket, rs_num, ruleset->rules[rs_num].inactive.ticket ) | |||
| 1425 | ("ticket: %d != [%d]%d\n", pr->ticket, rs_num,if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("ticket: %d != [%d]%d\n" , pr->ticket, rs_num, ruleset->rules[rs_num].inactive.ticket ) | |||
| 1426 | ruleset->rules[rs_num].inactive.ticket))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("ticket: %d != [%d]%d\n" , pr->ticket, rs_num, ruleset->rules[rs_num].inactive.ticket ); | |||
| 1427 | ERROUT(EBUSY16); | |||
| 1428 | } | |||
| 1429 | if (pr->pool_ticket != V_ticket_pabuf(*(__typeof(vnet_entry_ticket_pabuf)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_pabuf ))) { | |||
| 1430 | DPFPRINTF(PF_DEBUG_MISC,if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pool_ticket: %d != %d\n" , pr->pool_ticket, (*(__typeof(vnet_entry_ticket_pabuf)*) ( ((((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_ticket_pabuf))) | |||
| 1431 | ("pool_ticket: %d != %d\n", pr->pool_ticket,if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pool_ticket: %d != %d\n" , pr->pool_ticket, (*(__typeof(vnet_entry_ticket_pabuf)*) ( ((((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_ticket_pabuf))) | |||
| 1432 | V_ticket_pabuf))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("pool_ticket: %d != %d\n" , pr->pool_ticket, (*(__typeof(vnet_entry_ticket_pabuf)*) ( ((((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_ticket_pabuf))); | |||
| 1433 | ERROUT(EBUSY16); | |||
| 1434 | } | |||
| 1435 | ||||
| 1436 | tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)) | |||
| 1437 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)); | |||
| 1438 | if (tail) | |||
| 1439 | rule->nr = tail->nr + 1; | |||
| 1440 | else | |||
| 1441 | rule->nr = 0; | |||
| 1442 | if (rule->ifname[0]) { | |||
| 1443 | rule->kif = pfi_kif_attach(kif, rule->ifname); | |||
| 1444 | pfi_kif_ref(rule->kif); | |||
| 1445 | } else | |||
| 1446 | rule->kif = NULL((void *)0); | |||
| 1447 | ||||
| 1448 | if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs) | |||
| 1449 | error = EBUSY16; | |||
| 1450 | ||||
| 1451 | #ifdef ALTQ | |||
| 1452 | /* set queue IDs */ | |||
| 1453 | if (rule->qname[0] != 0) { | |||
| 1454 | if ((rule->qid = pf_qname2qid(rule->qname)) == 0) | |||
| 1455 | error = EBUSY16; | |||
| 1456 | else if (rule->pqname[0] != 0) { | |||
| 1457 | if ((rule->pqid = | |||
| 1458 | pf_qname2qid(rule->pqname)) == 0) | |||
| 1459 | error = EBUSY16; | |||
| 1460 | } else | |||
| 1461 | rule->pqid = rule->qid; | |||
| 1462 | } | |||
| 1463 | #endif | |||
| 1464 | if (rule->tagname[0]) | |||
| 1465 | if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0) | |||
| 1466 | error = EBUSY16; | |||
| 1467 | if (rule->match_tagname[0]) | |||
| 1468 | if ((rule->match_tag = | |||
| 1469 | pf_tagname2tag(rule->match_tagname)) == 0) | |||
| 1470 | error = EBUSY16; | |||
| 1471 | if (rule->rt && !rule->direction) | |||
| 1472 | error = EINVAL22; | |||
| 1473 | if (!rule->log) | |||
| 1474 | rule->logif = 0; | |||
| 1475 | if (rule->logif >= PFLOGIFS_MAX16) | |||
| 1476 | error = EINVAL22; | |||
| 1477 | if (pf_addr_setup(ruleset, &rule->src.addr, rule->af)) | |||
| 1478 | error = ENOMEM12; | |||
| 1479 | if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af)) | |||
| 1480 | error = ENOMEM12; | |||
| 1481 | if (pf_anchor_setup(rule, ruleset, pr->anchor_call)) | |||
| 1482 | error = EINVAL22; | |||
| 1483 | if (rule->scrub_flags & PFSTATE_SETPRIO0x0200 && | |||
| 1484 | (rule->set_prio[0] > PF_PRIO_MAX7 || | |||
| 1485 | rule->set_prio[1] > PF_PRIO_MAX7)) | |||
| 1486 | error = EINVAL22; | |||
| 1487 | TAILQ_FOREACH(pa, &V_pf_pabuf, entries)for ((pa) = (((&(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf ))))->tqh_first); (pa); (pa) = (((pa))->entries.tqe_next )) | |||
| 1488 | if (pa->addr.type == PF_ADDR_TABLE) { | |||
| 1489 | pa->addr.p.tbl = pfr_attach_table(ruleset, | |||
| 1490 | pa->addr.v.tblname); | |||
| 1491 | if (pa->addr.p.tbl == NULL((void *)0)) | |||
| 1492 | error = ENOMEM12; | |||
| 1493 | } | |||
| 1494 | ||||
| 1495 | rule->overload_tbl = NULL((void *)0); | |||
| 1496 | if (rule->overload_tblname[0]) { | |||
| 1497 | if ((rule->overload_tbl = pfr_attach_table(ruleset, | |||
| 1498 | rule->overload_tblname)) == NULL((void *)0)) | |||
| 1499 | error = EINVAL22; | |||
| 1500 | else | |||
| 1501 | rule->overload_tbl->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags |= | |||
| 1502 | PFR_TFLAG_ACTIVE0x00000004; | |||
| 1503 | } | |||
| 1504 | ||||
| 1505 | pf_mv_pool(&V_pf_pabuf(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf) ), &rule->rpool.list); | |||
| 1506 | if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) || | |||
| 1507 | (rule->action == PF_BINAT)) && rule->anchor == NULL((void *)0)) || | |||
| 1508 | (rule->rt > PF_NOPFROUTE)) && | |||
| 1509 | (TAILQ_FIRST(&rule->rpool.list)((&rule->rpool.list)->tqh_first) == NULL((void *)0))) | |||
| 1510 | error = EINVAL22; | |||
| 1511 | ||||
| 1512 | if (error) { | |||
| 1513 | pf_free_rule(rule); | |||
| 1514 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1514); | |||
| 1515 | break; | |||
| 1516 | } | |||
| 1517 | ||||
| 1518 | rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list)((&rule->rpool.list)->tqh_first); | |||
| 1519 | rule->evaluations = rule->packets[0] = rule->packets[1] = | |||
| 1520 | rule->bytes[0] = rule->bytes[1] = 0; | |||
| 1521 | TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,do { do { if (*(ruleset->rules[rs_num].inactive.ptr)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (ruleset->rules[rs_num].inactive.ptr)); } while (0); ((( rule))->entries.tqe_next) = ((void *)0); (rule)->entries .tqe_prev = (ruleset->rules[rs_num].inactive.ptr)->tqh_last ; *(ruleset->rules[rs_num].inactive.ptr)->tqh_last = (rule ); (ruleset->rules[rs_num].inactive.ptr)->tqh_last = & (((rule))->entries.tqe_next); ; ; } while (0) | |||
| 1522 | rule, entries)do { do { if (*(ruleset->rules[rs_num].inactive.ptr)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (ruleset->rules[rs_num].inactive.ptr)); } while (0); ((( rule))->entries.tqe_next) = ((void *)0); (rule)->entries .tqe_prev = (ruleset->rules[rs_num].inactive.ptr)->tqh_last ; *(ruleset->rules[rs_num].inactive.ptr)->tqh_last = (rule ); (ruleset->rules[rs_num].inactive.ptr)->tqh_last = & (((rule))->entries.tqe_next); ; ; } while (0); | |||
| 1523 | ruleset->rules[rs_num].inactive.rcount++; | |||
| 1524 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1524); | |||
| 1525 | break; | |||
| 1526 | ||||
| 1527 | #undef ERROUT | |||
| 1528 | DIOCADDRULE_error: | |||
| 1529 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1529); | |||
| 1530 | counter_u64_free(rule->states_cur); | |||
| 1531 | counter_u64_free(rule->states_tot); | |||
| 1532 | counter_u64_free(rule->src_nodes); | |||
| 1533 | free(rule, M_PFRULE); | |||
| 1534 | if (kif) | |||
| 1535 | free(kif, PFI_MTYPE); | |||
| 1536 | break; | |||
| 1537 | } | |||
| 1538 | ||||
| 1539 | case DIOCGETRULES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((6)))): { | |||
| 1540 | struct pfioc_rule *pr = (struct pfioc_rule *)addr; | |||
| 1541 | struct pf_ruleset *ruleset; | |||
| 1542 | struct pf_rule *tail; | |||
| 1543 | int rs_num; | |||
| 1544 | ||||
| 1545 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1545); | |||
| 1546 | pr->anchor[sizeof(pr->anchor) - 1] = 0; | |||
| 1547 | ruleset = pf_find_ruleset(pr->anchor); | |||
| 1548 | if (ruleset == NULL((void *)0)) { | |||
| 1549 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1549); | |||
| 1550 | error = EINVAL22; | |||
| 1551 | break; | |||
| 1552 | } | |||
| 1553 | rs_num = pf_get_ruleset_number(pr->rule.action); | |||
| 1554 | if (rs_num >= PF_RULESET_MAX) { | |||
| 1555 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1555); | |||
| 1556 | error = EINVAL22; | |||
| 1557 | break; | |||
| 1558 | } | |||
| 1559 | tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)) | |||
| 1560 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)); | |||
| 1561 | if (tail) | |||
| 1562 | pr->nr = tail->nr + 1; | |||
| 1563 | else | |||
| 1564 | pr->nr = 0; | |||
| 1565 | pr->ticket = ruleset->rules[rs_num].active.ticket; | |||
| 1566 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1566); | |||
| 1567 | break; | |||
| 1568 | } | |||
| 1569 | ||||
| 1570 | case DIOCGETRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((7)))): { | |||
| 1571 | struct pfioc_rule *pr = (struct pfioc_rule *)addr; | |||
| 1572 | struct pf_ruleset *ruleset; | |||
| 1573 | struct pf_rule *rule; | |||
| 1574 | int rs_num, i; | |||
| 1575 | ||||
| 1576 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1576); | |||
| 1577 | pr->anchor[sizeof(pr->anchor) - 1] = 0; | |||
| 1578 | ruleset = pf_find_ruleset(pr->anchor); | |||
| 1579 | if (ruleset == NULL((void *)0)) { | |||
| 1580 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1580); | |||
| 1581 | error = EINVAL22; | |||
| 1582 | break; | |||
| 1583 | } | |||
| 1584 | rs_num = pf_get_ruleset_number(pr->rule.action); | |||
| 1585 | if (rs_num >= PF_RULESET_MAX) { | |||
| 1586 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1586); | |||
| 1587 | error = EINVAL22; | |||
| 1588 | break; | |||
| 1589 | } | |||
| 1590 | if (pr->ticket != ruleset->rules[rs_num].active.ticket) { | |||
| 1591 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1591); | |||
| 1592 | error = EBUSY16; | |||
| 1593 | break; | |||
| 1594 | } | |||
| 1595 | rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
| 1596 | while ((rule != NULL((void *)0)) && (rule->nr != pr->nr)) | |||
| 1597 | rule = TAILQ_NEXT(rule, entries)((rule)->entries.tqe_next); | |||
| 1598 | if (rule == NULL((void *)0)) { | |||
| 1599 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1599); | |||
| 1600 | error = EBUSY16; | |||
| 1601 | break; | |||
| 1602 | } | |||
| 1603 | bcopy(rule, &pr->rule, sizeof(struct pf_rule))__builtin_memmove((&pr->rule), (rule), (sizeof(struct pf_rule ))); | |||
| 1604 | pr->rule.u_states_cur = counter_u64_fetch(rule->states_cur); | |||
| 1605 | pr->rule.u_states_tot = counter_u64_fetch(rule->states_tot); | |||
| 1606 | pr->rule.u_src_nodes = counter_u64_fetch(rule->src_nodes); | |||
| 1607 | if (pf_anchor_copyout(ruleset, rule, pr)) { | |||
| 1608 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1608); | |||
| 1609 | error = EBUSY16; | |||
| 1610 | break; | |||
| 1611 | } | |||
| 1612 | pf_addr_copyout(&pr->rule.src.addr); | |||
| 1613 | pf_addr_copyout(&pr->rule.dst.addr); | |||
| 1614 | for (i = 0; i < PF_SKIP_COUNT8; ++i) | |||
| 1615 | if (rule->skip[i].ptr == NULL((void *)0)) | |||
| 1616 | pr->rule.skip[i].nr = -1; | |||
| 1617 | else | |||
| 1618 | pr->rule.skip[i].nr = | |||
| 1619 | rule->skip[i].ptr->nr; | |||
| 1620 | ||||
| 1621 | if (pr->action == PF_GET_CLR_CNTR) { | |||
| 1622 | rule->evaluations = 0; | |||
| 1623 | rule->packets[0] = rule->packets[1] = 0; | |||
| 1624 | rule->bytes[0] = rule->bytes[1] = 0; | |||
| 1625 | counter_u64_zero(rule->states_tot); | |||
| 1626 | } | |||
| 1627 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1627); | |||
| 1628 | break; | |||
| 1629 | } | |||
| 1630 | ||||
| 1631 | case DIOCCHANGERULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((26)))): { | |||
| 1632 | struct pfioc_rule *pcr = (struct pfioc_rule *)addr; | |||
| 1633 | struct pf_ruleset *ruleset; | |||
| 1634 | struct pf_rule *oldrule = NULL((void *)0), *newrule = NULL((void *)0); | |||
| 1635 | struct pfi_kif *kif = NULL((void *)0); | |||
| 1636 | struct pf_pooladdr *pa; | |||
| 1637 | u_int32_t nr = 0; | |||
| 1638 | int rs_num; | |||
| 1639 | ||||
| 1640 | if (pcr->action < PF_CHANGE_ADD_HEAD || | |||
| 1641 | pcr->action > PF_CHANGE_GET_TICKET) { | |||
| 1642 | error = EINVAL22; | |||
| 1643 | break; | |||
| 1644 | } | |||
| 1645 | if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE40) { | |||
| 1646 | error = EINVAL22; | |||
| 1647 | break; | |||
| 1648 | } | |||
| 1649 | ||||
| 1650 | if (pcr->action != PF_CHANGE_REMOVE) { | |||
| 1651 | #ifndef INET1 | |||
| 1652 | if (pcr->rule.af == AF_INET2) { | |||
| 1653 | error = EAFNOSUPPORT47; | |||
| 1654 | break; | |||
| 1655 | } | |||
| 1656 | #endif /* INET */ | |||
| 1657 | #ifndef INET61 | |||
| 1658 | if (pcr->rule.af == AF_INET628) { | |||
| 1659 | error = EAFNOSUPPORT47; | |||
| 1660 | break; | |||
| 1661 | } | |||
| 1662 | #endif /* INET6 */ | |||
| 1663 | newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK0x0002); | |||
| 1664 | bcopy(&pcr->rule, newrule, sizeof(struct pf_rule))__builtin_memmove((newrule), (&pcr->rule), (sizeof(struct pf_rule))); | |||
| 1665 | if (newrule->ifname[0]) | |||
| 1666 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
| 1667 | newrule->states_cur = counter_u64_alloc(M_WAITOK0x0002); | |||
| 1668 | newrule->states_tot = counter_u64_alloc(M_WAITOK0x0002); | |||
| 1669 | newrule->src_nodes = counter_u64_alloc(M_WAITOK0x0002); | |||
| 1670 | newrule->cuid = td->td_ucred->cr_ruid; | |||
| 1671 | newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0; | |||
| 1672 | TAILQ_INIT(&newrule->rpool.list)do { (((&newrule->rpool.list))->tqh_first) = ((void *)0); (&newrule->rpool.list)->tqh_last = &(((& newrule->rpool.list))->tqh_first); ; } while (0); | |||
| 1673 | } | |||
| 1674 | ||||
| 1675 | #define ERROUT(x) { error = (x); goto DIOCCHANGERULE_error; } | |||
| 1676 | ||||
| 1677 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1677); | |||
| 1678 | if (!(pcr->action == PF_CHANGE_REMOVE || | |||
| 1679 | pcr->action == PF_CHANGE_GET_TICKET) && | |||
| 1680 | pcr->pool_ticket != V_ticket_pabuf(*(__typeof(vnet_entry_ticket_pabuf)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_pabuf ))) | |||
| 1681 | ERROUT(EBUSY16); | |||
| 1682 | ||||
| 1683 | ruleset = pf_find_ruleset(pcr->anchor); | |||
| 1684 | if (ruleset == NULL((void *)0)) | |||
| 1685 | ERROUT(EINVAL22); | |||
| 1686 | ||||
| 1687 | rs_num = pf_get_ruleset_number(pcr->rule.action); | |||
| 1688 | if (rs_num >= PF_RULESET_MAX) | |||
| 1689 | ERROUT(EINVAL22); | |||
| 1690 | ||||
| 1691 | if (pcr->action == PF_CHANGE_GET_TICKET) { | |||
| 1692 | pcr->ticket = ++ruleset->rules[rs_num].active.ticket; | |||
| 1693 | ERROUT(0); | |||
| 1694 | } else if (pcr->ticket != | |||
| 1695 | ruleset->rules[rs_num].active.ticket) | |||
| 1696 | ERROUT(EINVAL22); | |||
| 1697 | ||||
| 1698 | if (pcr->action != PF_CHANGE_REMOVE) { | |||
| 1699 | if (newrule->ifname[0]) { | |||
| 1700 | newrule->kif = pfi_kif_attach(kif, | |||
| 1701 | newrule->ifname); | |||
| 1702 | pfi_kif_ref(newrule->kif); | |||
| 1703 | } else | |||
| 1704 | newrule->kif = NULL((void *)0); | |||
| 1705 | ||||
| 1706 | if (newrule->rtableid > 0 && | |||
| 1707 | newrule->rtableid >= rt_numfibs) | |||
| 1708 | error = EBUSY16; | |||
| 1709 | ||||
| 1710 | #ifdef ALTQ | |||
| 1711 | /* set queue IDs */ | |||
| 1712 | if (newrule->qname[0] != 0) { | |||
| 1713 | if ((newrule->qid = | |||
| 1714 | pf_qname2qid(newrule->qname)) == 0) | |||
| 1715 | error = EBUSY16; | |||
| 1716 | else if (newrule->pqname[0] != 0) { | |||
| 1717 | if ((newrule->pqid = | |||
| 1718 | pf_qname2qid(newrule->pqname)) == 0) | |||
| 1719 | error = EBUSY16; | |||
| 1720 | } else | |||
| 1721 | newrule->pqid = newrule->qid; | |||
| 1722 | } | |||
| 1723 | #endif /* ALTQ */ | |||
| 1724 | if (newrule->tagname[0]) | |||
| 1725 | if ((newrule->tag = | |||
| 1726 | pf_tagname2tag(newrule->tagname)) == 0) | |||
| 1727 | error = EBUSY16; | |||
| 1728 | if (newrule->match_tagname[0]) | |||
| 1729 | if ((newrule->match_tag = pf_tagname2tag( | |||
| 1730 | newrule->match_tagname)) == 0) | |||
| 1731 | error = EBUSY16; | |||
| 1732 | if (newrule->rt && !newrule->direction) | |||
| 1733 | error = EINVAL22; | |||
| 1734 | if (!newrule->log) | |||
| 1735 | newrule->logif = 0; | |||
| 1736 | if (newrule->logif >= PFLOGIFS_MAX16) | |||
| 1737 | error = EINVAL22; | |||
| 1738 | if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af)) | |||
| 1739 | error = ENOMEM12; | |||
| 1740 | if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af)) | |||
| 1741 | error = ENOMEM12; | |||
| 1742 | if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call)) | |||
| 1743 | error = EINVAL22; | |||
| 1744 | TAILQ_FOREACH(pa, &V_pf_pabuf, entries)for ((pa) = (((&(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf ))))->tqh_first); (pa); (pa) = (((pa))->entries.tqe_next )) | |||
| 1745 | if (pa->addr.type == PF_ADDR_TABLE) { | |||
| 1746 | pa->addr.p.tbl = | |||
| 1747 | pfr_attach_table(ruleset, | |||
| 1748 | pa->addr.v.tblname); | |||
| 1749 | if (pa->addr.p.tbl == NULL((void *)0)) | |||
| 1750 | error = ENOMEM12; | |||
| 1751 | } | |||
| 1752 | ||||
| 1753 | newrule->overload_tbl = NULL((void *)0); | |||
| 1754 | if (newrule->overload_tblname[0]) { | |||
| 1755 | if ((newrule->overload_tbl = pfr_attach_table( | |||
| 1756 | ruleset, newrule->overload_tblname)) == | |||
| 1757 | NULL((void *)0)) | |||
| 1758 | error = EINVAL22; | |||
| 1759 | else | |||
| 1760 | newrule->overload_tbl->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags |= | |||
| 1761 | PFR_TFLAG_ACTIVE0x00000004; | |||
| 1762 | } | |||
| 1763 | ||||
| 1764 | pf_mv_pool(&V_pf_pabuf(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf) ), &newrule->rpool.list); | |||
| 1765 | if (((((newrule->action == PF_NAT) || | |||
| 1766 | (newrule->action == PF_RDR) || | |||
| 1767 | (newrule->action == PF_BINAT) || | |||
| 1768 | (newrule->rt > PF_NOPFROUTE)) && | |||
| 1769 | !newrule->anchor)) && | |||
| 1770 | (TAILQ_FIRST(&newrule->rpool.list)((&newrule->rpool.list)->tqh_first) == NULL((void *)0))) | |||
| 1771 | error = EINVAL22; | |||
| 1772 | ||||
| 1773 | if (error) { | |||
| 1774 | pf_free_rule(newrule); | |||
| 1775 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1775); | |||
| 1776 | break; | |||
| 1777 | } | |||
| 1778 | ||||
| 1779 | newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list)((&newrule->rpool.list)->tqh_first); | |||
| 1780 | newrule->evaluations = 0; | |||
| 1781 | newrule->packets[0] = newrule->packets[1] = 0; | |||
| 1782 | newrule->bytes[0] = newrule->bytes[1] = 0; | |||
| 1783 | } | |||
| 1784 | pf_empty_pool(&V_pf_pabuf(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf) )); | |||
| 1785 | ||||
| 1786 | if (pcr->action == PF_CHANGE_ADD_HEAD) | |||
| 1787 | oldrule = TAILQ_FIRST(((ruleset->rules[rs_num].active.ptr)->tqh_first) | |||
| 1788 | ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
| 1789 | else if (pcr->action == PF_CHANGE_ADD_TAIL) | |||
| 1790 | oldrule = TAILQ_LAST((*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)) | |||
| 1791 | ruleset->rules[rs_num].active.ptr, pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)); | |||
| 1792 | else { | |||
| 1793 | oldrule = TAILQ_FIRST(((ruleset->rules[rs_num].active.ptr)->tqh_first) | |||
| 1794 | ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
| 1795 | while ((oldrule != NULL((void *)0)) && (oldrule->nr != pcr->nr)) | |||
| 1796 | oldrule = TAILQ_NEXT(oldrule, entries)((oldrule)->entries.tqe_next); | |||
| 1797 | if (oldrule == NULL((void *)0)) { | |||
| 1798 | if (newrule != NULL((void *)0)) | |||
| 1799 | pf_free_rule(newrule); | |||
| 1800 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1800); | |||
| 1801 | error = EINVAL22; | |||
| 1802 | break; | |||
| 1803 | } | |||
| 1804 | } | |||
| 1805 | ||||
| 1806 | if (pcr->action == PF_CHANGE_REMOVE) { | |||
| 1807 | pf_unlink_rule(ruleset->rules[rs_num].active.ptr, | |||
| 1808 | oldrule); | |||
| 1809 | ruleset->rules[rs_num].active.rcount--; | |||
| 1810 | } else { | |||
| 1811 | if (oldrule == NULL((void *)0)) | |||
| 1812 | TAILQ_INSERT_TAIL(do { do { if (*(ruleset->rules[rs_num].active.ptr)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (ruleset->rules[rs_num].active.ptr)); } while (0); (((newrule ))->entries.tqe_next) = ((void *)0); (newrule)->entries .tqe_prev = (ruleset->rules[rs_num].active.ptr)->tqh_last ; *(ruleset->rules[rs_num].active.ptr)->tqh_last = (newrule ); (ruleset->rules[rs_num].active.ptr)->tqh_last = & (((newrule))->entries.tqe_next); ; ; } while (0) | |||
| 1813 | ruleset->rules[rs_num].active.ptr,do { do { if (*(ruleset->rules[rs_num].active.ptr)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (ruleset->rules[rs_num].active.ptr)); } while (0); (((newrule ))->entries.tqe_next) = ((void *)0); (newrule)->entries .tqe_prev = (ruleset->rules[rs_num].active.ptr)->tqh_last ; *(ruleset->rules[rs_num].active.ptr)->tqh_last = (newrule ); (ruleset->rules[rs_num].active.ptr)->tqh_last = & (((newrule))->entries.tqe_next); ; ; } while (0) | |||
| 1814 | newrule, entries)do { do { if (*(ruleset->rules[rs_num].active.ptr)->tqh_last != ((void *)0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL" , (ruleset->rules[rs_num].active.ptr)); } while (0); (((newrule ))->entries.tqe_next) = ((void *)0); (newrule)->entries .tqe_prev = (ruleset->rules[rs_num].active.ptr)->tqh_last ; *(ruleset->rules[rs_num].active.ptr)->tqh_last = (newrule ); (ruleset->rules[rs_num].active.ptr)->tqh_last = & (((newrule))->entries.tqe_next); ; ; } while (0); | |||
| 1815 | else if (pcr->action == PF_CHANGE_ADD_HEAD || | |||
| 1816 | pcr->action == PF_CHANGE_ADD_BEFORE) | |||
| 1817 | TAILQ_INSERT_BEFORE(oldrule, newrule, entries)do { do { if (*(oldrule)->entries.tqe_prev != (oldrule)) panic ("Bad link elm %p prev->next != elm", (oldrule)); } while ( 0); (newrule)->entries.tqe_prev = (oldrule)->entries.tqe_prev ; (((newrule))->entries.tqe_next) = (oldrule); *(oldrule)-> entries.tqe_prev = (newrule); (oldrule)->entries.tqe_prev = &(((newrule))->entries.tqe_next); ; ; } while (0); | |||
| 1818 | else | |||
| 1819 | TAILQ_INSERT_AFTER(do { do { if ((((oldrule))->entries.tqe_next) != ((void *) 0) && (((oldrule))->entries.tqe_next)->entries. tqe_prev != &((oldrule)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (oldrule)); } while (0); if (((((newrule))->entries.tqe_next ) = (((oldrule))->entries.tqe_next)) != ((void *)0)) (((newrule ))->entries.tqe_next)->entries.tqe_prev = &(((newrule ))->entries.tqe_next); else { (ruleset->rules[rs_num].active .ptr)->tqh_last = &(((newrule))->entries.tqe_next); ; } (((oldrule))->entries.tqe_next) = (newrule); (newrule )->entries.tqe_prev = &(((oldrule))->entries.tqe_next ); ; ; } while (0) | |||
| 1820 | ruleset->rules[rs_num].active.ptr,do { do { if ((((oldrule))->entries.tqe_next) != ((void *) 0) && (((oldrule))->entries.tqe_next)->entries. tqe_prev != &((oldrule)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (oldrule)); } while (0); if (((((newrule))->entries.tqe_next ) = (((oldrule))->entries.tqe_next)) != ((void *)0)) (((newrule ))->entries.tqe_next)->entries.tqe_prev = &(((newrule ))->entries.tqe_next); else { (ruleset->rules[rs_num].active .ptr)->tqh_last = &(((newrule))->entries.tqe_next); ; } (((oldrule))->entries.tqe_next) = (newrule); (newrule )->entries.tqe_prev = &(((oldrule))->entries.tqe_next ); ; ; } while (0) | |||
| 1821 | oldrule, newrule, entries)do { do { if ((((oldrule))->entries.tqe_next) != ((void *) 0) && (((oldrule))->entries.tqe_next)->entries. tqe_prev != &((oldrule)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (oldrule)); } while (0); if (((((newrule))->entries.tqe_next ) = (((oldrule))->entries.tqe_next)) != ((void *)0)) (((newrule ))->entries.tqe_next)->entries.tqe_prev = &(((newrule ))->entries.tqe_next); else { (ruleset->rules[rs_num].active .ptr)->tqh_last = &(((newrule))->entries.tqe_next); ; } (((oldrule))->entries.tqe_next) = (newrule); (newrule )->entries.tqe_prev = &(((oldrule))->entries.tqe_next ); ; ; } while (0); | |||
| 1822 | ruleset->rules[rs_num].active.rcount++; | |||
| 1823 | } | |||
| 1824 | ||||
| 1825 | nr = 0; | |||
| 1826 | TAILQ_FOREACH(oldrule,for ((oldrule) = (((ruleset->rules[rs_num].active.ptr))-> tqh_first); (oldrule); (oldrule) = (((oldrule))->entries.tqe_next )) | |||
| 1827 | ruleset->rules[rs_num].active.ptr, entries)for ((oldrule) = (((ruleset->rules[rs_num].active.ptr))-> tqh_first); (oldrule); (oldrule) = (((oldrule))->entries.tqe_next )) | |||
| 1828 | oldrule->nr = nr++; | |||
| 1829 | ||||
| 1830 | ruleset->rules[rs_num].active.ticket++; | |||
| 1831 | ||||
| 1832 | pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr); | |||
| 1833 | pf_remove_if_empty_ruleset(ruleset); | |||
| 1834 | ||||
| 1835 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1835); | |||
| 1836 | break; | |||
| 1837 | ||||
| 1838 | #undef ERROUT | |||
| 1839 | DIOCCHANGERULE_error: | |||
| 1840 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 1840); | |||
| 1841 | if (newrule != NULL((void *)0)) { | |||
| 1842 | counter_u64_free(newrule->states_cur); | |||
| 1843 | counter_u64_free(newrule->states_tot); | |||
| 1844 | counter_u64_free(newrule->src_nodes); | |||
| 1845 | free(newrule, M_PFRULE); | |||
| 1846 | } | |||
| 1847 | if (kif != NULL((void *)0)) | |||
| 1848 | free(kif, PFI_MTYPE); | |||
| 1849 | break; | |||
| 1850 | } | |||
| 1851 | ||||
| 1852 | case DIOCCLRSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state_kill)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((18)))): { | |||
| 1853 | struct pf_state *s; | |||
| 1854 | struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; | |||
| 1855 | u_int i, killed = 0; | |||
| 1856 | ||||
| 1857 | for (i = 0; i <= pf_hashmask; i++) { | |||
| 1858 | struct pf_idhash *ih = &V_pf_idhash(*(__typeof(vnet_entry_pf_idhash)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_idhash ))[i]; | |||
| 1859 | ||||
| 1860 | relock_DIOCCLRSTATES: | |||
| 1861 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (1861)); | |||
| 1862 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) | |||
| 1863 | if (!psk->psk_ifname[0] || | |||
| 1864 | !strcmp(psk->psk_ifname, | |||
| 1865 | s->kif->pfik_name)) { | |||
| 1866 | /* | |||
| 1867 | * Don't send out individual | |||
| 1868 | * delete messages. | |||
| 1869 | */ | |||
| 1870 | s->state_flags |= PFSTATE_NOSYNC0x08; | |||
| 1871 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
| 1872 | killed++; | |||
| 1873 | goto relock_DIOCCLRSTATES; | |||
| 1874 | } | |||
| 1875 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (1875)); | |||
| 1876 | } | |||
| 1877 | psk->psk_killed = killed; | |||
| 1878 | if (V_pfsync_clear_states_ptr(*(__typeof(vnet_entry_pfsync_clear_states_ptr)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pfsync_clear_states_ptr )) != NULL((void *)0)) | |||
| 1879 | V_pfsync_clear_states_ptr(*(__typeof(vnet_entry_pfsync_clear_states_ptr)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pfsync_clear_states_ptr ))(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).hostid, psk->psk_ifname); | |||
| 1880 | break; | |||
| 1881 | } | |||
| 1882 | ||||
| 1883 | case DIOCKILLSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state_kill)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((41)))): { | |||
| 1884 | struct pf_state *s; | |||
| 1885 | struct pf_state_key *sk; | |||
| 1886 | struct pf_addr *srcaddr, *dstaddr; | |||
| 1887 | u_int16_t srcport, dstport; | |||
| 1888 | struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; | |||
| 1889 | u_int i, killed = 0; | |||
| 1890 | ||||
| 1891 | if (psk->psk_pfcmp.id) { | |||
| 1892 | if (psk->psk_pfcmp.creatorid == 0) | |||
| 1893 | psk->psk_pfcmp.creatorid = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).hostid; | |||
| 1894 | if ((s = pf_find_state_byid(psk->psk_pfcmp.id, | |||
| 1895 | psk->psk_pfcmp.creatorid))) { | |||
| 1896 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
| 1897 | psk->psk_killed = 1; | |||
| 1898 | } | |||
| 1899 | break; | |||
| 1900 | } | |||
| 1901 | ||||
| 1902 | for (i = 0; i <= pf_hashmask; i++) { | |||
| 1903 | struct pf_idhash *ih = &V_pf_idhash(*(__typeof(vnet_entry_pf_idhash)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_idhash ))[i]; | |||
| 1904 | ||||
| 1905 | relock_DIOCKILLSTATES: | |||
| 1906 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (1906)); | |||
| 1907 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
| 1908 | sk = s->key[PF_SK_WIRE]; | |||
| 1909 | if (s->direction == PF_OUT) { | |||
| 1910 | srcaddr = &sk->addr[1]; | |||
| 1911 | dstaddr = &sk->addr[0]; | |||
| 1912 | srcport = sk->port[1]; | |||
| 1913 | dstport = sk->port[0]; | |||
| 1914 | } else { | |||
| 1915 | srcaddr = &sk->addr[0]; | |||
| 1916 | dstaddr = &sk->addr[1]; | |||
| 1917 | srcport = sk->port[0]; | |||
| 1918 | dstport = sk->port[1]; | |||
| 1919 | } | |||
| 1920 | ||||
| 1921 | if ((!psk->psk_af || sk->af == psk->psk_af) | |||
| 1922 | && (!psk->psk_proto || psk->psk_proto == | |||
| 1923 | sk->proto) && | |||
| 1924 | PF_MATCHA(psk->psk_src.neg,pf_match_addr(psk->psk_src.neg, &psk->psk_src.addr. v.a.addr, &psk->psk_src.addr.v.a.mask, srcaddr, sk-> af) | |||
| 1925 | &psk->psk_src.addr.v.a.addr,pf_match_addr(psk->psk_src.neg, &psk->psk_src.addr. v.a.addr, &psk->psk_src.addr.v.a.mask, srcaddr, sk-> af) | |||
| 1926 | &psk->psk_src.addr.v.a.mask,pf_match_addr(psk->psk_src.neg, &psk->psk_src.addr. v.a.addr, &psk->psk_src.addr.v.a.mask, srcaddr, sk-> af) | |||
| 1927 | srcaddr, sk->af)pf_match_addr(psk->psk_src.neg, &psk->psk_src.addr. v.a.addr, &psk->psk_src.addr.v.a.mask, srcaddr, sk-> af) && | |||
| 1928 | PF_MATCHA(psk->psk_dst.neg,pf_match_addr(psk->psk_dst.neg, &psk->psk_dst.addr. v.a.addr, &psk->psk_dst.addr.v.a.mask, dstaddr, sk-> af) | |||
| 1929 | &psk->psk_dst.addr.v.a.addr,pf_match_addr(psk->psk_dst.neg, &psk->psk_dst.addr. v.a.addr, &psk->psk_dst.addr.v.a.mask, dstaddr, sk-> af) | |||
| 1930 | &psk->psk_dst.addr.v.a.mask,pf_match_addr(psk->psk_dst.neg, &psk->psk_dst.addr. v.a.addr, &psk->psk_dst.addr.v.a.mask, dstaddr, sk-> af) | |||
| 1931 | dstaddr, sk->af)pf_match_addr(psk->psk_dst.neg, &psk->psk_dst.addr. v.a.addr, &psk->psk_dst.addr.v.a.mask, dstaddr, sk-> af) && | |||
| 1932 | (psk->psk_src.port_op == 0 || | |||
| 1933 | pf_match_port(psk->psk_src.port_op, | |||
| 1934 | psk->psk_src.port[0], psk->psk_src.port[1], | |||
| 1935 | srcport)) && | |||
| 1936 | (psk->psk_dst.port_op == 0 || | |||
| 1937 | pf_match_port(psk->psk_dst.port_op, | |||
| 1938 | psk->psk_dst.port[0], psk->psk_dst.port[1], | |||
| 1939 | dstport)) && | |||
| 1940 | (!psk->psk_label[0] || | |||
| 1941 | (s->rule.ptr->label[0] && | |||
| 1942 | !strcmp(psk->psk_label, | |||
| 1943 | s->rule.ptr->label))) && | |||
| 1944 | (!psk->psk_ifname[0] || | |||
| 1945 | !strcmp(psk->psk_ifname, | |||
| 1946 | s->kif->pfik_name))) { | |||
| 1947 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
| 1948 | killed++; | |||
| 1949 | goto relock_DIOCKILLSTATES; | |||
| 1950 | } | |||
| 1951 | } | |||
| 1952 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (1952)); | |||
| 1953 | } | |||
| 1954 | psk->psk_killed = killed; | |||
| 1955 | break; | |||
| 1956 | } | |||
| 1957 | ||||
| 1958 | case DIOCADDSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((37)))): { | |||
| 1959 | struct pfioc_state *ps = (struct pfioc_state *)addr; | |||
| 1960 | struct pfsync_state *sp = &ps->state; | |||
| 1961 | ||||
| 1962 | if (sp->timeout >= PFTM_MAX) { | |||
| 1963 | error = EINVAL22; | |||
| 1964 | break; | |||
| 1965 | } | |||
| 1966 | if (V_pfsync_state_import_ptr(*(__typeof(vnet_entry_pfsync_state_import_ptr)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pfsync_state_import_ptr )) != NULL((void *)0)) { | |||
| 1967 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 1967 )); | |||
| 1968 | error = V_pfsync_state_import_ptr(*(__typeof(vnet_entry_pfsync_state_import_ptr)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pfsync_state_import_ptr ))(sp, PFSYNC_SI_IOCTL0x01); | |||
| 1969 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 1969 ); | |||
| 1970 | } else | |||
| 1971 | error = EOPNOTSUPP45; | |||
| 1972 | break; | |||
| 1973 | } | |||
| 1974 | ||||
| 1975 | case DIOCGETSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((19)))): { | |||
| 1976 | struct pfioc_state *ps = (struct pfioc_state *)addr; | |||
| 1977 | struct pf_state *s; | |||
| 1978 | ||||
| 1979 | s = pf_find_state_byid(ps->state.id, ps->state.creatorid); | |||
| 1980 | if (s == NULL((void *)0)) { | |||
| 1981 | error = ENOENT2; | |||
| 1982 | break; | |||
| 1983 | } | |||
| 1984 | ||||
| 1985 | pfsync_state_export(&ps->state, s); | |||
| 1986 | PF_STATE_UNLOCK(s)do { struct pf_idhash *_ih = &(*(__typeof(vnet_entry_pf_idhash )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_idhash))[((__builtin_constant_p( (((s))->id)) ? (((__uint64_t)(__builtin_constant_p(((__uint64_t )((((s))->id))) & 0xffffffff) ? (((__uint32_t)((__uint16_t )(__builtin_constant_p(((__uint32_t)(((__uint64_t)((((s))-> id))) & 0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(((__uint64_t)((((s))->id))) & 0xffffffff )) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((( __uint64_t)((((s))->id))) & 0xffffffff)) & 0xffff) ) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)(((( s))->id))) & 0xffffffff)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t )((((s))->id))) & 0xffffffff)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(((__uint64_t)((((s))->id))) & 0xffffffff)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t )(((__uint64_t)((((s))->id))) & 0xffffffff)) >> 16 )) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((( (s))->id))) & 0xffffffff)) >> 16)))) : __bswap32_var (((__uint64_t)((((s))->id))) & 0xffffffff)) << 32 ) | (__builtin_constant_p(((__uint64_t)((((s))->id))) >> 32) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t )(((__uint64_t)((((s))->id))) >> 32)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((((s) )->id))) >> 32)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)(((__uint64_t)((((s))->id))) >> 32)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t )((((s))->id))) >> 32)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t )((((s))->id))) >> 32)) >> 16) ? (__uint16_t)( ((__uint16_t)(((__uint32_t)(((__uint64_t)((((s))->id))) >> 32)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)( ((__uint64_t)((((s))->id))) >> 32)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((((s))->id ))) >> 32)) >> 16)))) : __bswap32_var(((__uint64_t )((((s))->id))) >> 32))) : __bswap64_var((((s))-> id))) % (pf_hashmask + 1))]; __mtx_unlock_flags(&((((& (_ih)->lock))))->mtx_lock, ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c" ), (1986)); } while (0); | |||
| 1987 | break; | |||
| 1988 | } | |||
| 1989 | ||||
| 1990 | case DIOCGETSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_states)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((25)))): { | |||
| 1991 | struct pfioc_states *ps = (struct pfioc_states *)addr; | |||
| 1992 | struct pf_state *s; | |||
| 1993 | struct pfsync_state *pstore, *p; | |||
| 1994 | int i, nr; | |||
| 1995 | ||||
| 1996 | if (ps->ps_len == 0) { | |||
| 1997 | nr = uma_zone_get_cur(V_pf_state_z(*(__typeof(vnet_entry_pf_state_z)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_state_z ))); | |||
| 1998 | ps->ps_len = sizeof(struct pfsync_state) * nr; | |||
| 1999 | break; | |||
| 2000 | } | |||
| 2001 | ||||
| 2002 | p = pstore = malloc(ps->ps_len, M_TEMP, M_WAITOK0x0002); | |||
| 2003 | nr = 0; | |||
| 2004 | ||||
| 2005 | for (i = 0; i <= pf_hashmask; i++) { | |||
| 2006 | struct pf_idhash *ih = &V_pf_idhash(*(__typeof(vnet_entry_pf_idhash)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_idhash ))[i]; | |||
| 2007 | ||||
| 2008 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (2008)); | |||
| 2009 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
| 2010 | ||||
| 2011 | if (s->timeout == PFTM_UNLINKED) | |||
| 2012 | continue; | |||
| 2013 | ||||
| 2014 | if ((nr+1) * sizeof(*p) > ps->ps_len) { | |||
| 2015 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (2015)); | |||
| 2016 | goto DIOCGETSTATES_full; | |||
| 2017 | } | |||
| 2018 | pfsync_state_export(p, s); | |||
| 2019 | p++; | |||
| 2020 | nr++; | |||
| 2021 | } | |||
| 2022 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (2022)); | |||
| 2023 | } | |||
| 2024 | DIOCGETSTATES_full: | |||
| 2025 | error = copyout(pstore, ps->ps_statesps_u.psu_states, | |||
| 2026 | sizeof(struct pfsync_state) * nr); | |||
| 2027 | if (error) { | |||
| 2028 | free(pstore, M_TEMP); | |||
| 2029 | break; | |||
| 2030 | } | |||
| 2031 | ps->ps_len = sizeof(struct pfsync_state) * nr; | |||
| 2032 | free(pstore, M_TEMP); | |||
| 2033 | ||||
| 2034 | break; | |||
| 2035 | } | |||
| 2036 | ||||
| 2037 | case DIOCGETSTATUS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_status)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((21)))): { | |||
| 2038 | struct pf_status *s = (struct pf_status *)addr; | |||
| 2039 | ||||
| 2040 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2040 )); | |||
| 2041 | s->running = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running; | |||
| 2042 | s->since = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).since; | |||
| 2043 | s->debug = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug; | |||
| 2044 | s->hostid = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).hostid; | |||
| 2045 | s->states = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).states; | |||
| 2046 | s->src_nodes = V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).src_nodes; | |||
| 2047 | ||||
| 2048 | for (int i = 0; i < PFRES_MAX16; i++) | |||
| 2049 | s->counters[i] = | |||
| 2050 | counter_u64_fetch(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).counters[i]); | |||
| 2051 | for (int i = 0; i < LCNT_MAX7; i++) | |||
| 2052 | s->lcounters[i] = | |||
| 2053 | counter_u64_fetch(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).lcounters[i]); | |||
| 2054 | for (int i = 0; i < FCNT_MAX3; i++) | |||
| 2055 | s->fcounters[i] = | |||
| 2056 | counter_u64_fetch(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).fcounters[i]); | |||
| 2057 | for (int i = 0; i < SCNT_MAX3; i++) | |||
| 2058 | s->scounters[i] = | |||
| 2059 | counter_u64_fetch(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).scounters[i]); | |||
| 2060 | ||||
| 2061 | bcopy(V_pf_status.ifname, s->ifname, IFNAMSIZ)__builtin_memmove((s->ifname), ((*(__typeof(vnet_entry_pf_status )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_status)).ifname), (16)); | |||
| 2062 | bcopy(V_pf_status.pf_chksum, s->pf_chksum,__builtin_memmove((s->pf_chksum), ((*(__typeof(vnet_entry_pf_status )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_status)).pf_chksum), (16)) | |||
| 2063 | PF_MD5_DIGEST_LENGTH)__builtin_memmove((s->pf_chksum), ((*(__typeof(vnet_entry_pf_status )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_status)).pf_chksum), (16)); | |||
| 2064 | ||||
| 2065 | pfi_update_status(s->ifname, s); | |||
| 2066 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2066 ); | |||
| 2067 | break; | |||
| 2068 | } | |||
| 2069 | ||||
| 2070 | case DIOCSETSTATUSIF((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_if)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((20)))): { | |||
| 2071 | struct pfioc_if *pi = (struct pfioc_if *)addr; | |||
| 2072 | ||||
| 2073 | if (pi->ifname[0] == 0) { | |||
| 2074 | bzero(V_pf_status.ifname, IFNAMSIZ)__builtin_memset(((*(__typeof(vnet_entry_pf_status)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).ifname), 0, (16)); | |||
| 2075 | break; | |||
| 2076 | } | |||
| 2077 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2077); | |||
| 2078 | strlcpy(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).ifname, pi->ifname, IFNAMSIZ16); | |||
| 2079 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2079); | |||
| 2080 | break; | |||
| 2081 | } | |||
| 2082 | ||||
| 2083 | case DIOCCLRSTATUS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((22)))): { | |||
| 2084 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2084); | |||
| 2085 | for (int i = 0; i < PFRES_MAX16; i++) | |||
| 2086 | counter_u64_zero(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).counters[i]); | |||
| 2087 | for (int i = 0; i < FCNT_MAX3; i++) | |||
| 2088 | counter_u64_zero(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).fcounters[i]); | |||
| 2089 | for (int i = 0; i < SCNT_MAX3; i++) | |||
| 2090 | counter_u64_zero(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).scounters[i]); | |||
| 2091 | for (int i = 0; i < LCNT_MAX7; i++) | |||
| 2092 | counter_u64_zero(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).lcounters[i]); | |||
| 2093 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).since = time_second; | |||
| 2094 | if (*V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).ifname) | |||
| 2095 | pfi_update_status(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).ifname, NULL((void *)0)); | |||
| 2096 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2096); | |||
| 2097 | break; | |||
| 2098 | } | |||
| 2099 | ||||
| 2100 | case DIOCNATLOOK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_natlook)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((23)))): { | |||
| 2101 | struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; | |||
| 2102 | struct pf_state_key *sk; | |||
| 2103 | struct pf_state *state; | |||
| 2104 | struct pf_state_key_cmp key; | |||
| 2105 | int m = 0, direction = pnl->direction; | |||
| 2106 | int sidx, didx; | |||
| 2107 | ||||
| 2108 | /* NATLOOK src and dst are reversed, so reverse sidx/didx */ | |||
| 2109 | sidx = (direction == PF_IN) ? 1 : 0; | |||
| 2110 | didx = (direction == PF_IN) ? 0 : 1; | |||
| 2111 | ||||
| 2112 | if (!pnl->proto || | |||
| 2113 | PF_AZERO(&pnl->saddr, pnl->af)((pnl->af == 2 && !(&pnl->saddr)->pfa.addr32 [0]) || (pnl->af == 28 && !(&pnl->saddr)-> pfa.addr32[0] && !(&pnl->saddr)->pfa.addr32 [1] && !(&pnl->saddr)->pfa.addr32[2] && !(&pnl->saddr)->pfa.addr32[3] )) || | |||
| 2114 | PF_AZERO(&pnl->daddr, pnl->af)((pnl->af == 2 && !(&pnl->daddr)->pfa.addr32 [0]) || (pnl->af == 28 && !(&pnl->daddr)-> pfa.addr32[0] && !(&pnl->daddr)->pfa.addr32 [1] && !(&pnl->daddr)->pfa.addr32[2] && !(&pnl->daddr)->pfa.addr32[3] )) || | |||
| 2115 | ((pnl->proto == IPPROTO_TCP6 || | |||
| 2116 | pnl->proto == IPPROTO_UDP17) && | |||
| 2117 | (!pnl->dport || !pnl->sport))) | |||
| 2118 | error = EINVAL22; | |||
| 2119 | else { | |||
| 2120 | bzero(&key, sizeof(key))__builtin_memset((&key), 0, (sizeof(key))); | |||
| 2121 | key.af = pnl->af; | |||
| 2122 | key.proto = pnl->proto; | |||
| 2123 | PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af)pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af ); | |||
| 2124 | key.port[sidx] = pnl->sport; | |||
| 2125 | PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af)pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af ); | |||
| 2126 | key.port[didx] = pnl->dport; | |||
| 2127 | ||||
| 2128 | state = pf_find_state_all(&key, direction, &m); | |||
| 2129 | ||||
| 2130 | if (m > 1) | |||
| 2131 | error = E2BIG7; /* more than one state */ | |||
| 2132 | else if (state != NULL((void *)0)) { | |||
| 2133 | /* XXXGL: not locked read */ | |||
| 2134 | sk = state->key[sidx]; | |||
| 2135 | PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af)pf_addrcpy(&pnl->rsaddr, &sk->addr[sidx], sk-> af); | |||
| 2136 | pnl->rsport = sk->port[sidx]; | |||
| 2137 | PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af)pf_addrcpy(&pnl->rdaddr, &sk->addr[didx], sk-> af); | |||
| 2138 | pnl->rdport = sk->port[didx]; | |||
| 2139 | } else | |||
| 2140 | error = ENOENT2; | |||
| 2141 | } | |||
| 2142 | break; | |||
| 2143 | } | |||
| 2144 | ||||
| 2145 | case DIOCSETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((29)))): { | |||
| 2146 | struct pfioc_tm *pt = (struct pfioc_tm *)addr; | |||
| 2147 | int old; | |||
| 2148 | ||||
| 2149 | if (pt->timeout < 0 || pt->timeout >= PFTM_MAX || | |||
| 2150 | pt->seconds < 0) { | |||
| 2151 | error = EINVAL22; | |||
| 2152 | break; | |||
| 2153 | } | |||
| 2154 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2154); | |||
| 2155 | old = V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).timeout[pt->timeout]; | |||
| 2156 | if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0) | |||
| 2157 | pt->seconds = 1; | |||
| 2158 | V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).timeout[pt->timeout] = pt->seconds; | |||
| 2159 | if (pt->timeout == PFTM_INTERVAL && pt->seconds < old) | |||
| 2160 | wakeup(pf_purge_thread); | |||
| 2161 | pt->seconds = old; | |||
| 2162 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2162); | |||
| 2163 | break; | |||
| 2164 | } | |||
| 2165 | ||||
| 2166 | case DIOCGETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((30)))): { | |||
| 2167 | struct pfioc_tm *pt = (struct pfioc_tm *)addr; | |||
| 2168 | ||||
| 2169 | if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) { | |||
| 2170 | error = EINVAL22; | |||
| 2171 | break; | |||
| 2172 | } | |||
| 2173 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2173 )); | |||
| 2174 | pt->seconds = V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).timeout[pt->timeout]; | |||
| 2175 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2175 ); | |||
| 2176 | break; | |||
| 2177 | } | |||
| 2178 | ||||
| 2179 | case DIOCGETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((39)))): { | |||
| 2180 | struct pfioc_limit *pl = (struct pfioc_limit *)addr; | |||
| 2181 | ||||
| 2182 | if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { | |||
| 2183 | error = EINVAL22; | |||
| 2184 | break; | |||
| 2185 | } | |||
| 2186 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2186 )); | |||
| 2187 | pl->limit = V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[pl->index].limit; | |||
| 2188 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2188 ); | |||
| 2189 | break; | |||
| 2190 | } | |||
| 2191 | ||||
| 2192 | case DIOCSETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((40)))): { | |||
| 2193 | struct pfioc_limit *pl = (struct pfioc_limit *)addr; | |||
| 2194 | int old_limit; | |||
| 2195 | ||||
| 2196 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2196); | |||
| 2197 | if (pl->index < 0 || pl->index >= PF_LIMIT_MAX || | |||
| 2198 | V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[pl->index].zone == NULL((void *)0)) { | |||
| 2199 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2199); | |||
| 2200 | error = EINVAL22; | |||
| 2201 | break; | |||
| 2202 | } | |||
| 2203 | uma_zone_set_max(V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[pl->index].zone, pl->limit); | |||
| 2204 | old_limit = V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[pl->index].limit; | |||
| 2205 | V_pf_limits(*(__typeof(vnet_entry_pf_limits)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_limits ))[pl->index].limit = pl->limit; | |||
| 2206 | pl->limit = old_limit; | |||
| 2207 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2207); | |||
| 2208 | break; | |||
| 2209 | } | |||
| 2210 | ||||
| 2211 | case DIOCSETDEBUG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(u_int32_t )) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((24)))): { | |||
| 2212 | u_int32_t *level = (u_int32_t *)addr; | |||
| 2213 | ||||
| 2214 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2214); | |||
| 2215 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug = *level; | |||
| 2216 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2216); | |||
| 2217 | break; | |||
| 2218 | } | |||
| 2219 | ||||
| 2220 | case DIOCCLRRULECTRS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((38)))): { | |||
| 2221 | /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */ | |||
| 2222 | struct pf_ruleset *ruleset = &pf_main_ruleset(*(__typeof(vnet_entry_pf_main_anchor)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_main_anchor )).ruleset; | |||
| 2223 | struct pf_rule *rule; | |||
| 2224 | ||||
| 2225 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2225); | |||
| 2226 | TAILQ_FOREACH(rule,for ((rule) = (((ruleset->rules[PF_RULESET_FILTER].active. ptr))->tqh_first); (rule); (rule) = (((rule))->entries. tqe_next)) | |||
| 2227 | ruleset->rules[PF_RULESET_FILTER].active.ptr, entries)for ((rule) = (((ruleset->rules[PF_RULESET_FILTER].active. ptr))->tqh_first); (rule); (rule) = (((rule))->entries. tqe_next)) { | |||
| 2228 | rule->evaluations = 0; | |||
| 2229 | rule->packets[0] = rule->packets[1] = 0; | |||
| 2230 | rule->bytes[0] = rule->bytes[1] = 0; | |||
| 2231 | } | |||
| 2232 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2232); | |||
| 2233 | break; | |||
| 2234 | } | |||
| 2235 | ||||
| 2236 | case DIOCGIFSPEEDV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92)))): | |||
| 2237 | case DIOCGIFSPEEDV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92)))): { | |||
| 2238 | struct pf_ifspeed_v1 *psp = (struct pf_ifspeed_v1 *)addr; | |||
| 2239 | struct pf_ifspeed_v1 ps; | |||
| 2240 | struct ifnet *ifp; | |||
| 2241 | ||||
| 2242 | if (psp->ifname[0] != 0) { | |||
| 2243 | /* Can we completely trust user-land? */ | |||
| 2244 | strlcpy(ps.ifname, psp->ifname, IFNAMSIZ16); | |||
| 2245 | ifp = ifunit(ps.ifname); | |||
| 2246 | if (ifp != NULL((void *)0)) { | |||
| 2247 | psp->baudrate32 = | |||
| 2248 | (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX0xffffffff); | |||
| 2249 | if (cmd == DIOCGIFSPEEDV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((92))))) | |||
| 2250 | psp->baudrate = ifp->if_baudrate; | |||
| 2251 | } else | |||
| 2252 | error = EINVAL22; | |||
| 2253 | } else | |||
| 2254 | error = EINVAL22; | |||
| 2255 | break; | |||
| 2256 | } | |||
| 2257 | ||||
| 2258 | #ifdef ALTQ | |||
| 2259 | case DIOCSTARTALTQ((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((42)))): { | |||
| 2260 | struct pf_altqpf_kaltq *altq; | |||
| 2261 | ||||
| 2262 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2262); | |||
| 2263 | /* enable all altq interfaces on active list */ | |||
| 2264 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((*(__typeof(vnet_entry_pf_altqs_active)*) (( (((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_active))))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) { | |||
| 2265 | if (altq->qname[0] == 0 && (altq->local_flags & | |||
| 2266 | PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
| 2267 | error = pf_enable_altq(altq); | |||
| 2268 | if (error != 0) | |||
| 2269 | break; | |||
| 2270 | } | |||
| 2271 | } | |||
| 2272 | if (error == 0) | |||
| 2273 | V_pf_altq_running = 1; | |||
| 2274 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2274); | |||
| 2275 | DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("altq: started\n"); | |||
| 2276 | break; | |||
| 2277 | } | |||
| 2278 | ||||
| 2279 | case DIOCSTOPALTQ((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((43)))): { | |||
| 2280 | struct pf_altqpf_kaltq *altq; | |||
| 2281 | ||||
| 2282 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2282); | |||
| 2283 | /* disable all altq interfaces on active list */ | |||
| 2284 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((*(__typeof(vnet_entry_pf_altqs_active)*) (( (((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_active))))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) { | |||
| 2285 | if (altq->qname[0] == 0 && (altq->local_flags & | |||
| 2286 | PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
| 2287 | error = pf_disable_altq(altq); | |||
| 2288 | if (error != 0) | |||
| 2289 | break; | |||
| 2290 | } | |||
| 2291 | } | |||
| 2292 | if (error == 0) | |||
| 2293 | V_pf_altq_running = 0; | |||
| 2294 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2294); | |||
| 2295 | DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("altq: stopped\n"); | |||
| 2296 | break; | |||
| 2297 | } | |||
| 2298 | ||||
| 2299 | case DIOCADDALTQV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((45)))): | |||
| 2300 | case DIOCADDALTQV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((45)))): { | |||
| 2301 | struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr; | |||
| 2302 | struct pf_altqpf_kaltq *altq, *a; | |||
| 2303 | struct ifnet *ifp; | |||
| 2304 | ||||
| 2305 | altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK0x0002 | M_ZERO0x0100); | |||
| 2306 | error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd)(((cmd) >> 16) & ((1 << 13) - 1))); | |||
| 2307 | if (error) | |||
| 2308 | break; | |||
| 2309 | altq->local_flags = 0; | |||
| 2310 | ||||
| 2311 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2311); | |||
| 2312 | if (pa->ticket != V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive ))) { | |||
| 2313 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2313); | |||
| 2314 | free(altq, M_PFALTQ); | |||
| 2315 | error = EBUSY16; | |||
| 2316 | break; | |||
| 2317 | } | |||
| 2318 | ||||
| 2319 | /* | |||
| 2320 | * if this is for a queue, find the discipline and | |||
| 2321 | * copy the necessary fields | |||
| 2322 | */ | |||
| 2323 | if (altq->qname[0] != 0) { | |||
| 2324 | if ((altq->qid = pf_qname2qid(altq->qname)) == 0) { | |||
| 2325 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2325); | |||
| 2326 | error = EBUSY16; | |||
| 2327 | free(altq, M_PFALTQ); | |||
| 2328 | break; | |||
| 2329 | } | |||
| 2330 | altq->altq_disc = NULL((void *)0); | |||
| 2331 | TAILQ_FOREACH(a, V_pf_altqs_inactive, entries)for ((a) = ((((*(__typeof(vnet_entry_pf_altqs_inactive)*) ((( ((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_inactive))))->tqh_first); (a); ( a) = (((a))->entries.tqe_next)) { | |||
| 2332 | if (strncmp(a->ifname, altq->ifname, | |||
| 2333 | IFNAMSIZ16) == 0 && a->qname[0] == 0) { | |||
| 2334 | altq->altq_disc = a->altq_disc; | |||
| 2335 | break; | |||
| 2336 | } | |||
| 2337 | } | |||
| 2338 | } | |||
| 2339 | ||||
| 2340 | if ((ifp = ifunit(altq->ifname)) == NULL((void *)0)) | |||
| 2341 | altq->local_flags |= PFALTQ_FLAG_IF_REMOVED0x01; | |||
| 2342 | else | |||
| 2343 | error = altq_add(altq); | |||
| 2344 | ||||
| 2345 | if (error) { | |||
| 2346 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2346); | |||
| 2347 | free(altq, M_PFALTQ); | |||
| 2348 | break; | |||
| 2349 | } | |||
| 2350 | ||||
| 2351 | TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries)do { do { if (*((*(__typeof(vnet_entry_pf_altqs_inactive)*) ( ((((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_inactive)))->tqh_last != ((void * )0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL", ((*(__typeof (vnet_entry_pf_altqs_inactive)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))); } while (0); (((altq))->entries.tqe_next) = ((void * )0); (altq)->entries.tqe_prev = ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last; * ((*(__typeof(vnet_entry_pf_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_inactive )))->tqh_last = (altq); ((*(__typeof(vnet_entry_pf_altqs_inactive )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_altqs_inactive)))->tqh_last = &(((altq))->entries.tqe_next); ; ; } while (0); | |||
| 2352 | /* version error check done on import above */ | |||
| 2353 | pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd)(((cmd) >> 16) & ((1 << 13) - 1))); | |||
| 2354 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2354); | |||
| 2355 | break; | |||
| 2356 | } | |||
| 2357 | ||||
| 2358 | case DIOCGETALTQSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((47)))): | |||
| 2359 | case DIOCGETALTQSV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((47)))): { | |||
| 2360 | struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr; | |||
| 2361 | struct pf_altqpf_kaltq *altq; | |||
| 2362 | ||||
| 2363 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2363 )); | |||
| 2364 | pa->nr = 0; | |||
| 2365 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((*(__typeof(vnet_entry_pf_altqs_active)*) (( (((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_altqs_active))))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) | |||
| 2366 | pa->nr++; | |||
| 2367 | pa->ticket = V_ticket_altqs_active(*(__typeof(vnet_entry_ticket_altqs_active)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_active )); | |||
| 2368 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2368 ); | |||
| 2369 | break; | |||
| 2370 | } | |||
| 2371 | ||||
| 2372 | case DIOCGETALTQV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((48)))): | |||
| 2373 | case DIOCGETALTQV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((48)))): { | |||
| 2374 | struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr; | |||
| 2375 | struct pf_altqpf_kaltq *altq; | |||
| 2376 | u_int32_t nr; | |||
| 2377 | ||||
| 2378 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2378 )); | |||
| 2379 | if (pa->ticket != V_ticket_altqs_active(*(__typeof(vnet_entry_ticket_altqs_active)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_active ))) { | |||
| 2380 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2380 ); | |||
| 2381 | error = EBUSY16; | |||
| 2382 | break; | |||
| 2383 | } | |||
| 2384 | nr = 0; | |||
| 2385 | altq = TAILQ_FIRST(V_pf_altqs_active)(((*(__typeof(vnet_entry_pf_altqs_active)*) (((((__curthread( ))->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_active )))->tqh_first); | |||
| 2386 | while ((altq != NULL((void *)0)) && (nr < pa->nr)) { | |||
| 2387 | altq = TAILQ_NEXT(altq, entries)((altq)->entries.tqe_next); | |||
| 2388 | nr++; | |||
| 2389 | } | |||
| 2390 | if (altq == NULL((void *)0)) { | |||
| 2391 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2391 ); | |||
| 2392 | error = EBUSY16; | |||
| 2393 | break; | |||
| 2394 | } | |||
| 2395 | pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd)(((cmd) >> 16) & ((1 << 13) - 1))); | |||
| 2396 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2396 ); | |||
| 2397 | break; | |||
| 2398 | } | |||
| 2399 | ||||
| 2400 | case DIOCCHANGEALTQV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v0)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((49)))): | |||
| 2401 | case DIOCCHANGEALTQV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq_v1)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((49)))): | |||
| 2402 | /* CHANGEALTQ not supported yet! */ | |||
| 2403 | error = ENODEV19; | |||
| 2404 | break; | |||
| 2405 | ||||
| 2406 | case DIOCGETQSTATSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v0)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50)))): | |||
| 2407 | case DIOCGETQSTATSV1((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v1)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50)))): { | |||
| 2408 | struct pfioc_qstats_v1 *pq = (struct pfioc_qstats_v1 *)addr; | |||
| 2409 | struct pf_altqpf_kaltq *altq; | |||
| 2410 | u_int32_t nr; | |||
| 2411 | int nbytes; | |||
| 2412 | u_int32_t version; | |||
| 2413 | ||||
| 2414 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2414 )); | |||
| 2415 | if (pq->ticket != V_ticket_altqs_active(*(__typeof(vnet_entry_ticket_altqs_active)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_active ))) { | |||
| 2416 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2416 ); | |||
| 2417 | error = EBUSY16; | |||
| 2418 | break; | |||
| 2419 | } | |||
| 2420 | nbytes = pq->nbytes; | |||
| 2421 | nr = 0; | |||
| 2422 | altq = TAILQ_FIRST(V_pf_altqs_active)(((*(__typeof(vnet_entry_pf_altqs_active)*) (((((__curthread( ))->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_altqs_active )))->tqh_first); | |||
| 2423 | while ((altq != NULL((void *)0)) && (nr < pq->nr)) { | |||
| 2424 | altq = TAILQ_NEXT(altq, entries)((altq)->entries.tqe_next); | |||
| 2425 | nr++; | |||
| 2426 | } | |||
| 2427 | if (altq == NULL((void *)0)) { | |||
| 2428 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2428 ); | |||
| 2429 | error = EBUSY16; | |||
| 2430 | break; | |||
| 2431 | } | |||
| 2432 | ||||
| 2433 | if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) != 0) { | |||
| 2434 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2434 ); | |||
| 2435 | error = ENXIO6; | |||
| 2436 | break; | |||
| 2437 | } | |||
| 2438 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2438 ); | |||
| 2439 | if (cmd == DIOCGETQSTATSV0((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats_v0)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((50))))) | |||
| 2440 | version = 0; /* DIOCGETQSTATSV0 means stats struct v0 */ | |||
| 2441 | else | |||
| 2442 | version = pq->version; | |||
| 2443 | error = altq_getqstats(altq, pq->buf, &nbytes, version); | |||
| 2444 | if (error == 0) { | |||
| 2445 | pq->scheduler = altq->scheduler; | |||
| 2446 | pq->nbytes = nbytes; | |||
| 2447 | } | |||
| 2448 | break; | |||
| 2449 | } | |||
| 2450 | #endif /* ALTQ */ | |||
| 2451 | ||||
| 2452 | case DIOCBEGINADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((51)))): { | |||
| 2453 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
| 2454 | ||||
| 2455 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2455); | |||
| 2456 | pf_empty_pool(&V_pf_pabuf(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf) )); | |||
| 2457 | pp->ticket = ++V_ticket_pabuf(*(__typeof(vnet_entry_ticket_pabuf)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_pabuf )); | |||
| 2458 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2458); | |||
| 2459 | break; | |||
| 2460 | } | |||
| 2461 | ||||
| 2462 | case DIOCADDADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((52)))): { | |||
| 2463 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
| 2464 | struct pf_pooladdr *pa; | |||
| 2465 | struct pfi_kif *kif = NULL((void *)0); | |||
| 2466 | ||||
| 2467 | #ifndef INET1 | |||
| 2468 | if (pp->af == AF_INET2) { | |||
| 2469 | error = EAFNOSUPPORT47; | |||
| 2470 | break; | |||
| 2471 | } | |||
| 2472 | #endif /* INET */ | |||
| 2473 | #ifndef INET61 | |||
| 2474 | if (pp->af == AF_INET628) { | |||
| 2475 | error = EAFNOSUPPORT47; | |||
| 2476 | break; | |||
| 2477 | } | |||
| 2478 | #endif /* INET6 */ | |||
| 2479 | if (pp->addr.addr.type != PF_ADDR_ADDRMASK && | |||
| 2480 | pp->addr.addr.type != PF_ADDR_DYNIFTL && | |||
| 2481 | pp->addr.addr.type != PF_ADDR_TABLE) { | |||
| 2482 | error = EINVAL22; | |||
| 2483 | break; | |||
| 2484 | } | |||
| 2485 | pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK0x0002); | |||
| 2486 | bcopy(&pp->addr, pa, sizeof(struct pf_pooladdr))__builtin_memmove((pa), (&pp->addr), (sizeof(struct pf_pooladdr ))); | |||
| 2487 | if (pa->ifname[0]) | |||
| 2488 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
| 2489 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2489); | |||
| 2490 | if (pp->ticket != V_ticket_pabuf(*(__typeof(vnet_entry_ticket_pabuf)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_pabuf ))) { | |||
| 2491 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2491); | |||
| 2492 | if (pa->ifname[0]) | |||
| 2493 | free(kif, PFI_MTYPE); | |||
| 2494 | free(pa, M_PFRULE); | |||
| 2495 | error = EBUSY16; | |||
| 2496 | break; | |||
| 2497 | } | |||
| 2498 | if (pa->ifname[0]) { | |||
| 2499 | pa->kif = pfi_kif_attach(kif, pa->ifname); | |||
| 2500 | pfi_kif_ref(pa->kif); | |||
| 2501 | } else | |||
| 2502 | pa->kif = NULL((void *)0); | |||
| 2503 | if (pa->addr.type == PF_ADDR_DYNIFTL && ((error = | |||
| 2504 | pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) { | |||
| 2505 | if (pa->ifname[0]) | |||
| 2506 | pfi_kif_unref(pa->kif); | |||
| 2507 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2507); | |||
| 2508 | free(pa, M_PFRULE); | |||
| 2509 | break; | |||
| 2510 | } | |||
| 2511 | TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries)do { do { if (*(&(*(__typeof(vnet_entry_pf_pabuf)*) ((((( __curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_pabuf)))->tqh_last != ((void *)0)) panic ("Bad tailq NEXT(%p->tqh_last) != NULL", (&(*(__typeof (vnet_entry_pf_pabuf)*) (((((__curthread())->td_vnet))-> vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf)))); } while (0); (((pa))->entries.tqe_next) = ((void *)0); (pa)->entries .tqe_prev = (&(*(__typeof(vnet_entry_pf_pabuf)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf )))->tqh_last; *(&(*(__typeof(vnet_entry_pf_pabuf)*) ( ((((__curthread())->td_vnet))->vnet_data_base) + (uintptr_t )&vnet_entry_pf_pabuf)))->tqh_last = (pa); (&(*(__typeof (vnet_entry_pf_pabuf)*) (((((__curthread())->td_vnet))-> vnet_data_base) + (uintptr_t)&vnet_entry_pf_pabuf)))-> tqh_last = &(((pa))->entries.tqe_next); ; ; } while (0 ); | |||
| 2512 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2512); | |||
| 2513 | break; | |||
| 2514 | } | |||
| 2515 | ||||
| 2516 | case DIOCGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((53)))): { | |||
| 2517 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
| 2518 | struct pf_pool *pool; | |||
| 2519 | struct pf_pooladdr *pa; | |||
| 2520 | ||||
| 2521 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2521 )); | |||
| 2522 | pp->nr = 0; | |||
| 2523 | pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action, | |||
| 2524 | pp->r_num, 0, 1, 0); | |||
| 2525 | if (pool == NULL((void *)0)) { | |||
| 2526 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2526 ); | |||
| 2527 | error = EBUSY16; | |||
| 2528 | break; | |||
| 2529 | } | |||
| 2530 | TAILQ_FOREACH(pa, &pool->list, entries)for ((pa) = (((&pool->list))->tqh_first); (pa); (pa ) = (((pa))->entries.tqe_next)) | |||
| 2531 | pp->nr++; | |||
| 2532 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2532 ); | |||
| 2533 | break; | |||
| 2534 | } | |||
| 2535 | ||||
| 2536 | case DIOCGETADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((54)))): { | |||
| 2537 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
| 2538 | struct pf_pool *pool; | |||
| 2539 | struct pf_pooladdr *pa; | |||
| 2540 | u_int32_t nr = 0; | |||
| 2541 | ||||
| 2542 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2542 )); | |||
| 2543 | pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action, | |||
| 2544 | pp->r_num, 0, 1, 1); | |||
| 2545 | if (pool == NULL((void *)0)) { | |||
| 2546 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2546 ); | |||
| 2547 | error = EBUSY16; | |||
| 2548 | break; | |||
| 2549 | } | |||
| 2550 | pa = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
| 2551 | while ((pa != NULL((void *)0)) && (nr < pp->nr)) { | |||
| 2552 | pa = TAILQ_NEXT(pa, entries)((pa)->entries.tqe_next); | |||
| 2553 | nr++; | |||
| 2554 | } | |||
| 2555 | if (pa == NULL((void *)0)) { | |||
| 2556 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2556 ); | |||
| 2557 | error = EBUSY16; | |||
| 2558 | break; | |||
| 2559 | } | |||
| 2560 | bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr))__builtin_memmove((&pp->addr), (pa), (sizeof(struct pf_pooladdr ))); | |||
| 2561 | pf_addr_copyout(&pp->addr.addr); | |||
| 2562 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2562 ); | |||
| 2563 | break; | |||
| 2564 | } | |||
| 2565 | ||||
| 2566 | case DIOCCHANGEADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((55)))): { | |||
| 2567 | struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr; | |||
| 2568 | struct pf_pool *pool; | |||
| 2569 | struct pf_pooladdr *oldpa = NULL((void *)0), *newpa = NULL((void *)0); | |||
| 2570 | struct pf_ruleset *ruleset; | |||
| 2571 | struct pfi_kif *kif = NULL((void *)0); | |||
| 2572 | ||||
| 2573 | if (pca->action < PF_CHANGE_ADD_HEAD || | |||
| 2574 | pca->action > PF_CHANGE_REMOVE) { | |||
| 2575 | error = EINVAL22; | |||
| 2576 | break; | |||
| 2577 | } | |||
| 2578 | if (pca->addr.addr.type != PF_ADDR_ADDRMASK && | |||
| 2579 | pca->addr.addr.type != PF_ADDR_DYNIFTL && | |||
| 2580 | pca->addr.addr.type != PF_ADDR_TABLE) { | |||
| 2581 | error = EINVAL22; | |||
| 2582 | break; | |||
| 2583 | } | |||
| 2584 | ||||
| 2585 | if (pca->action != PF_CHANGE_REMOVE) { | |||
| 2586 | #ifndef INET1 | |||
| 2587 | if (pca->af == AF_INET2) { | |||
| 2588 | error = EAFNOSUPPORT47; | |||
| 2589 | break; | |||
| 2590 | } | |||
| 2591 | #endif /* INET */ | |||
| 2592 | #ifndef INET61 | |||
| 2593 | if (pca->af == AF_INET628) { | |||
| 2594 | error = EAFNOSUPPORT47; | |||
| 2595 | break; | |||
| 2596 | } | |||
| 2597 | #endif /* INET6 */ | |||
| 2598 | newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK0x0002); | |||
| 2599 | bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr))__builtin_memmove((newpa), (&pca->addr), (sizeof(struct pf_pooladdr))); | |||
| 2600 | if (newpa->ifname[0]) | |||
| 2601 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
| 2602 | newpa->kif = NULL((void *)0); | |||
| 2603 | } | |||
| 2604 | ||||
| 2605 | #define ERROUT(x) { error = (x); goto DIOCCHANGEADDR_error; } | |||
| 2606 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2606); | |||
| 2607 | ruleset = pf_find_ruleset(pca->anchor); | |||
| 2608 | if (ruleset == NULL((void *)0)) | |||
| 2609 | ERROUT(EBUSY16); | |||
| 2610 | ||||
| 2611 | pool = pf_get_pool(pca->anchor, pca->ticket, pca->r_action, | |||
| 2612 | pca->r_num, pca->r_last, 1, 1); | |||
| 2613 | if (pool == NULL((void *)0)) | |||
| 2614 | ERROUT(EBUSY16); | |||
| 2615 | ||||
| 2616 | if (pca->action != PF_CHANGE_REMOVE) { | |||
| 2617 | if (newpa->ifname[0]) { | |||
| 2618 | newpa->kif = pfi_kif_attach(kif, newpa->ifname); | |||
| 2619 | pfi_kif_ref(newpa->kif); | |||
| 2620 | kif = NULL((void *)0); | |||
| 2621 | } | |||
| 2622 | ||||
| 2623 | switch (newpa->addr.type) { | |||
| 2624 | case PF_ADDR_DYNIFTL: | |||
| 2625 | error = pfi_dynaddr_setup(&newpa->addr, | |||
| 2626 | pca->af); | |||
| 2627 | break; | |||
| 2628 | case PF_ADDR_TABLE: | |||
| 2629 | newpa->addr.p.tbl = pfr_attach_table(ruleset, | |||
| 2630 | newpa->addr.v.tblname); | |||
| 2631 | if (newpa->addr.p.tbl == NULL((void *)0)) | |||
| 2632 | error = ENOMEM12; | |||
| 2633 | break; | |||
| 2634 | } | |||
| 2635 | if (error) | |||
| 2636 | goto DIOCCHANGEADDR_error; | |||
| 2637 | } | |||
| 2638 | ||||
| 2639 | switch (pca->action) { | |||
| 2640 | case PF_CHANGE_ADD_HEAD: | |||
| 2641 | oldpa = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
| 2642 | break; | |||
| 2643 | case PF_CHANGE_ADD_TAIL: | |||
| 2644 | oldpa = TAILQ_LAST(&pool->list, pf_palist)(*(((struct pf_palist *)((&pool->list)->tqh_last))-> tqh_last)); | |||
| 2645 | break; | |||
| 2646 | default: | |||
| 2647 | oldpa = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
| 2648 | for (int i = 0; oldpa && i < pca->nr; i++) | |||
| 2649 | oldpa = TAILQ_NEXT(oldpa, entries)((oldpa)->entries.tqe_next); | |||
| 2650 | ||||
| 2651 | if (oldpa == NULL((void *)0)) | |||
| 2652 | ERROUT(EINVAL22); | |||
| 2653 | } | |||
| 2654 | ||||
| 2655 | if (pca->action == PF_CHANGE_REMOVE) { | |||
| 2656 | TAILQ_REMOVE(&pool->list, oldpa, entries)do { ; ; do { if ((((oldpa))->entries.tqe_next) != ((void * )0) && (((oldpa))->entries.tqe_next)->entries.tqe_prev != &((oldpa)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (oldpa)); } while (0); do { if (*(oldpa)->entries.tqe_prev != (oldpa)) panic("Bad link elm %p prev->next != elm", (oldpa )); } while (0); if (((((oldpa))->entries.tqe_next)) != (( void *)0)) (((oldpa))->entries.tqe_next)->entries.tqe_prev = (oldpa)->entries.tqe_prev; else { (&pool->list)-> tqh_last = (oldpa)->entries.tqe_prev; ; } *(oldpa)->entries .tqe_prev = (((oldpa))->entries.tqe_next); ; ; ; } while ( 0); | |||
| 2657 | switch (oldpa->addr.type) { | |||
| 2658 | case PF_ADDR_DYNIFTL: | |||
| 2659 | pfi_dynaddr_remove(oldpa->addr.p.dyn); | |||
| 2660 | break; | |||
| 2661 | case PF_ADDR_TABLE: | |||
| 2662 | pfr_detach_table(oldpa->addr.p.tbl); | |||
| 2663 | break; | |||
| 2664 | } | |||
| 2665 | if (oldpa->kif) | |||
| 2666 | pfi_kif_unref(oldpa->kif); | |||
| 2667 | free(oldpa, M_PFRULE); | |||
| 2668 | } else { | |||
| 2669 | if (oldpa == NULL((void *)0)) | |||
| 2670 | TAILQ_INSERT_TAIL(&pool->list, newpa, entries)do { do { if (*(&pool->list)->tqh_last != ((void *) 0)) panic("Bad tailq NEXT(%p->tqh_last) != NULL", (&pool ->list)); } while (0); (((newpa))->entries.tqe_next) = ( (void *)0); (newpa)->entries.tqe_prev = (&pool->list )->tqh_last; *(&pool->list)->tqh_last = (newpa); (&pool->list)->tqh_last = &(((newpa))->entries .tqe_next); ; ; } while (0); | |||
| 2671 | else if (pca->action == PF_CHANGE_ADD_HEAD || | |||
| 2672 | pca->action == PF_CHANGE_ADD_BEFORE) | |||
| 2673 | TAILQ_INSERT_BEFORE(oldpa, newpa, entries)do { do { if (*(oldpa)->entries.tqe_prev != (oldpa)) panic ("Bad link elm %p prev->next != elm", (oldpa)); } while (0 ); (newpa)->entries.tqe_prev = (oldpa)->entries.tqe_prev ; (((newpa))->entries.tqe_next) = (oldpa); *(oldpa)->entries .tqe_prev = (newpa); (oldpa)->entries.tqe_prev = &(((newpa ))->entries.tqe_next); ; ; } while (0); | |||
| 2674 | else | |||
| 2675 | TAILQ_INSERT_AFTER(&pool->list, oldpa,do { do { if ((((oldpa))->entries.tqe_next) != ((void *)0) && (((oldpa))->entries.tqe_next)->entries.tqe_prev != &((oldpa)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (oldpa)); } while (0); if (((((newpa))->entries.tqe_next ) = (((oldpa))->entries.tqe_next)) != ((void *)0)) (((newpa ))->entries.tqe_next)->entries.tqe_prev = &(((newpa ))->entries.tqe_next); else { (&pool->list)->tqh_last = &(((newpa))->entries.tqe_next); ; } (((oldpa))-> entries.tqe_next) = (newpa); (newpa)->entries.tqe_prev = & (((oldpa))->entries.tqe_next); ; ; } while (0) | |||
| 2676 | newpa, entries)do { do { if ((((oldpa))->entries.tqe_next) != ((void *)0) && (((oldpa))->entries.tqe_next)->entries.tqe_prev != &((oldpa)->entries.tqe_next)) panic("Bad link elm %p next->prev != elm" , (oldpa)); } while (0); if (((((newpa))->entries.tqe_next ) = (((oldpa))->entries.tqe_next)) != ((void *)0)) (((newpa ))->entries.tqe_next)->entries.tqe_prev = &(((newpa ))->entries.tqe_next); else { (&pool->list)->tqh_last = &(((newpa))->entries.tqe_next); ; } (((oldpa))-> entries.tqe_next) = (newpa); (newpa)->entries.tqe_prev = & (((oldpa))->entries.tqe_next); ; ; } while (0); | |||
| 2677 | } | |||
| 2678 | ||||
| 2679 | pool->cur = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
| 2680 | PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af)pf_addrcpy(&pool->counter, &pool->cur->addr. v.a.addr, pca->af); | |||
| 2681 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2681); | |||
| 2682 | break; | |||
| 2683 | ||||
| 2684 | #undef ERROUT | |||
| 2685 | DIOCCHANGEADDR_error: | |||
| 2686 | if (newpa != NULL((void *)0)) { | |||
| 2687 | if (newpa->kif) | |||
| 2688 | pfi_kif_unref(newpa->kif); | |||
| 2689 | free(newpa, M_PFRULE); | |||
| 2690 | } | |||
| 2691 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2691); | |||
| 2692 | if (kif != NULL((void *)0)) | |||
| 2693 | free(kif, PFI_MTYPE); | |||
| 2694 | break; | |||
| 2695 | } | |||
| 2696 | ||||
| 2697 | case DIOCGETRULESETS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((58)))): { | |||
| 2698 | struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; | |||
| 2699 | struct pf_ruleset *ruleset; | |||
| 2700 | struct pf_anchor *anchor; | |||
| 2701 | ||||
| 2702 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2702 )); | |||
| 2703 | pr->path[sizeof(pr->path) - 1] = 0; | |||
| 2704 | if ((ruleset = pf_find_ruleset(pr->path)) == NULL((void *)0)) { | |||
| 2705 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2705 ); | |||
| 2706 | error = ENOENT2; | |||
| 2707 | break; | |||
| 2708 | } | |||
| 2709 | pr->nr = 0; | |||
| 2710 | if (ruleset->anchor == NULL((void *)0)) { | |||
| 2711 | /* XXX kludge for pf_main_ruleset */ | |||
| 2712 | RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)for ((anchor) = pf_anchor_global_RB_MINMAX(&(*(__typeof(vnet_entry_pf_anchors )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_anchors)), -1); (anchor) != ((void *)0); (anchor) = pf_anchor_global_RB_NEXT(anchor)) | |||
| 2713 | if (anchor->parent == NULL((void *)0)) | |||
| 2714 | pr->nr++; | |||
| 2715 | } else { | |||
| 2716 | RB_FOREACH(anchor, pf_anchor_node,for ((anchor) = pf_anchor_node_RB_MINMAX(&ruleset->anchor ->children, -1); (anchor) != ((void *)0); (anchor) = pf_anchor_node_RB_NEXT (anchor)) | |||
| 2717 | &ruleset->anchor->children)for ((anchor) = pf_anchor_node_RB_MINMAX(&ruleset->anchor ->children, -1); (anchor) != ((void *)0); (anchor) = pf_anchor_node_RB_NEXT (anchor)) | |||
| 2718 | pr->nr++; | |||
| 2719 | } | |||
| 2720 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2720 ); | |||
| 2721 | break; | |||
| 2722 | } | |||
| 2723 | ||||
| 2724 | case DIOCGETRULESET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((59)))): { | |||
| 2725 | struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; | |||
| 2726 | struct pf_ruleset *ruleset; | |||
| 2727 | struct pf_anchor *anchor; | |||
| 2728 | u_int32_t nr = 0; | |||
| 2729 | ||||
| 2730 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2730 )); | |||
| 2731 | pr->path[sizeof(pr->path) - 1] = 0; | |||
| 2732 | if ((ruleset = pf_find_ruleset(pr->path)) == NULL((void *)0)) { | |||
| 2733 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2733 ); | |||
| 2734 | error = ENOENT2; | |||
| 2735 | break; | |||
| 2736 | } | |||
| 2737 | pr->name[0] = 0; | |||
| 2738 | if (ruleset->anchor == NULL((void *)0)) { | |||
| 2739 | /* XXX kludge for pf_main_ruleset */ | |||
| 2740 | RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)for ((anchor) = pf_anchor_global_RB_MINMAX(&(*(__typeof(vnet_entry_pf_anchors )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_anchors)), -1); (anchor) != ((void *)0); (anchor) = pf_anchor_global_RB_NEXT(anchor)) | |||
| 2741 | if (anchor->parent == NULL((void *)0) && nr++ == pr->nr) { | |||
| 2742 | strlcpy(pr->name, anchor->name, | |||
| 2743 | sizeof(pr->name)); | |||
| 2744 | break; | |||
| 2745 | } | |||
| 2746 | } else { | |||
| 2747 | RB_FOREACH(anchor, pf_anchor_node,for ((anchor) = pf_anchor_node_RB_MINMAX(&ruleset->anchor ->children, -1); (anchor) != ((void *)0); (anchor) = pf_anchor_node_RB_NEXT (anchor)) | |||
| 2748 | &ruleset->anchor->children)for ((anchor) = pf_anchor_node_RB_MINMAX(&ruleset->anchor ->children, -1); (anchor) != ((void *)0); (anchor) = pf_anchor_node_RB_NEXT (anchor)) | |||
| 2749 | if (nr++ == pr->nr) { | |||
| 2750 | strlcpy(pr->name, anchor->name, | |||
| 2751 | sizeof(pr->name)); | |||
| 2752 | break; | |||
| 2753 | } | |||
| 2754 | } | |||
| 2755 | if (!pr->name[0]) | |||
| 2756 | error = EBUSY16; | |||
| 2757 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2757 ); | |||
| 2758 | break; | |||
| 2759 | } | |||
| 2760 | ||||
| 2761 | case DIOCRCLRTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((60)))): { | |||
| 2762 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2763 | ||||
| 2764 | if (io->pfrio_esize != 0) { | |||
| 2765 | error = ENODEV19; | |||
| 2766 | break; | |||
| 2767 | } | |||
| 2768 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2768); | |||
| 2769 | error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, | |||
| 2770 | io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2771 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2771); | |||
| 2772 | break; | |||
| 2773 | } | |||
| 2774 | ||||
| 2775 | case DIOCRADDTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((61)))): { | |||
| 2776 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2777 | struct pfr_table *pfrts; | |||
| 2778 | size_t totlen; | |||
| 2779 | ||||
| 2780 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
| 2781 | error = ENODEV19; | |||
| 2782 | break; | |||
| 2783 | } | |||
| 2784 | ||||
| 2785 | if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || | |||
| 2786 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { | |||
| 2787 | error = ENOMEM12; | |||
| 2788 | break; | |||
| 2789 | } | |||
| 2790 | ||||
| 2791 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
| 2792 | pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | |||
| 2793 | M_TEMP, M_WAITOK0x0002); | |||
| 2794 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
| 2795 | if (error) { | |||
| 2796 | free(pfrts, M_TEMP); | |||
| 2797 | break; | |||
| 2798 | } | |||
| 2799 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2799); | |||
| 2800 | error = pfr_add_tables(pfrts, io->pfrio_size, | |||
| 2801 | &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2802 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2802); | |||
| 2803 | free(pfrts, M_TEMP); | |||
| 2804 | break; | |||
| 2805 | } | |||
| 2806 | ||||
| 2807 | case DIOCRDELTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((62)))): { | |||
| 2808 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2809 | struct pfr_table *pfrts; | |||
| 2810 | size_t totlen; | |||
| 2811 | ||||
| 2812 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
| 2813 | error = ENODEV19; | |||
| 2814 | break; | |||
| 2815 | } | |||
| 2816 | ||||
| 2817 | if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || | |||
| 2818 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { | |||
| 2819 | error = ENOMEM12; | |||
| 2820 | break; | |||
| 2821 | } | |||
| 2822 | ||||
| 2823 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
| 2824 | pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | |||
| 2825 | M_TEMP, M_WAITOK0x0002); | |||
| 2826 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
| 2827 | if (error) { | |||
| 2828 | free(pfrts, M_TEMP); | |||
| 2829 | break; | |||
| 2830 | } | |||
| 2831 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2831); | |||
| 2832 | error = pfr_del_tables(pfrts, io->pfrio_size, | |||
| 2833 | &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2834 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2834); | |||
| 2835 | free(pfrts, M_TEMP); | |||
| 2836 | break; | |||
| 2837 | } | |||
| 2838 | ||||
| 2839 | case DIOCRGETTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((63)))): { | |||
| 2840 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2841 | struct pfr_table *pfrts; | |||
| 2842 | size_t totlen, n; | |||
| 2843 | ||||
| 2844 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
| 2845 | error = ENODEV19; | |||
| 2846 | break; | |||
| 2847 | } | |||
| 2848 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2848 )); | |||
| 2849 | n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | |||
| 2850 | io->pfrio_size = min(io->pfrio_size, n); | |||
| 2851 | ||||
| 2852 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
| 2853 | ||||
| 2854 | pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | |||
| 2855 | M_TEMP, M_NOWAIT0x0001); | |||
| 2856 | if (pfrts == NULL((void *)0)) { | |||
| 2857 | error = ENOMEM12; | |||
| 2858 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2858 ); | |||
| 2859 | break; | |||
| 2860 | } | |||
| 2861 | error = pfr_get_tables(&io->pfrio_table, pfrts, | |||
| 2862 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2863 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 2863 ); | |||
| 2864 | if (error == 0) | |||
| 2865 | error = copyout(pfrts, io->pfrio_buffer, totlen); | |||
| 2866 | free(pfrts, M_TEMP); | |||
| 2867 | break; | |||
| 2868 | } | |||
| 2869 | ||||
| 2870 | case DIOCRGETTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((64)))): { | |||
| 2871 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2872 | struct pfr_tstats *pfrtstats; | |||
| 2873 | size_t totlen, n; | |||
| 2874 | ||||
| 2875 | if (io->pfrio_esize != sizeof(struct pfr_tstats)) { | |||
| 2876 | error = ENODEV19; | |||
| 2877 | break; | |||
| 2878 | } | |||
| 2879 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2879); | |||
| 2880 | n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | |||
| 2881 | io->pfrio_size = min(io->pfrio_size, n); | |||
| 2882 | ||||
| 2883 | totlen = io->pfrio_size * sizeof(struct pfr_tstats); | |||
| 2884 | pfrtstats = mallocarray(io->pfrio_size, | |||
| 2885 | sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT0x0001); | |||
| 2886 | if (pfrtstats == NULL((void *)0)) { | |||
| 2887 | error = ENOMEM12; | |||
| 2888 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2888); | |||
| 2889 | break; | |||
| 2890 | } | |||
| 2891 | error = pfr_get_tstats(&io->pfrio_table, pfrtstats, | |||
| 2892 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2893 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2893); | |||
| 2894 | if (error == 0) | |||
| 2895 | error = copyout(pfrtstats, io->pfrio_buffer, totlen); | |||
| 2896 | free(pfrtstats, M_TEMP); | |||
| 2897 | break; | |||
| 2898 | } | |||
| 2899 | ||||
| 2900 | case DIOCRCLRTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((65)))): { | |||
| 2901 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2902 | struct pfr_table *pfrts; | |||
| 2903 | size_t totlen, n; | |||
| 2904 | ||||
| 2905 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
| 2906 | error = ENODEV19; | |||
| 2907 | break; | |||
| 2908 | } | |||
| 2909 | ||||
| 2910 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2910); | |||
| 2911 | n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | |||
| 2912 | io->pfrio_size = min(io->pfrio_size, n); | |||
| 2913 | ||||
| 2914 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
| 2915 | pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | |||
| 2916 | M_TEMP, M_NOWAIT0x0001); | |||
| 2917 | if (pfrts == NULL((void *)0)) { | |||
| 2918 | error = ENOMEM12; | |||
| 2919 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2919); | |||
| 2920 | break; | |||
| 2921 | } | |||
| 2922 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
| 2923 | if (error) { | |||
| 2924 | free(pfrts, M_TEMP); | |||
| 2925 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2925); | |||
| 2926 | break; | |||
| 2927 | } | |||
| 2928 | error = pfr_clr_tstats(pfrts, io->pfrio_size, | |||
| 2929 | &io->pfrio_nzeropfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2930 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2930); | |||
| 2931 | free(pfrts, M_TEMP); | |||
| 2932 | break; | |||
| 2933 | } | |||
| 2934 | ||||
| 2935 | case DIOCRSETTFLAGS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((74)))): { | |||
| 2936 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2937 | struct pfr_table *pfrts; | |||
| 2938 | size_t totlen, n; | |||
| 2939 | ||||
| 2940 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
| 2941 | error = ENODEV19; | |||
| 2942 | break; | |||
| 2943 | } | |||
| 2944 | ||||
| 2945 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2945); | |||
| 2946 | n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | |||
| 2947 | io->pfrio_size = min(io->pfrio_size, n); | |||
| 2948 | ||||
| 2949 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
| 2950 | pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | |||
| 2951 | M_TEMP, M_NOWAIT0x0001); | |||
| 2952 | if (pfrts == NULL((void *)0)) { | |||
| 2953 | error = ENOMEM12; | |||
| 2954 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2954); | |||
| 2955 | break; | |||
| 2956 | } | |||
| 2957 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
| 2958 | if (error) { | |||
| 2959 | free(pfrts, M_TEMP); | |||
| 2960 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2960); | |||
| 2961 | break; | |||
| 2962 | } | |||
| 2963 | error = pfr_set_tflags(pfrts, io->pfrio_size, | |||
| 2964 | io->pfrio_setflagpfrio_size2, io->pfrio_clrflagpfrio_nadd, &io->pfrio_nchange, | |||
| 2965 | &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2966 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2966); | |||
| 2967 | free(pfrts, M_TEMP); | |||
| 2968 | break; | |||
| 2969 | } | |||
| 2970 | ||||
| 2971 | case DIOCRCLRADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((66)))): { | |||
| 2972 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2973 | ||||
| 2974 | if (io->pfrio_esize != 0) { | |||
| 2975 | error = ENODEV19; | |||
| 2976 | break; | |||
| 2977 | } | |||
| 2978 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2978); | |||
| 2979 | error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel, | |||
| 2980 | io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 2981 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 2981); | |||
| 2982 | break; | |||
| 2983 | } | |||
| 2984 | ||||
| 2985 | case DIOCRADDADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((67)))): { | |||
| 2986 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 2987 | struct pfr_addr *pfras; | |||
| 2988 | size_t totlen; | |||
| 2989 | ||||
| 2990 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 2991 | error = ENODEV19; | |||
| 2992 | break; | |||
| 2993 | } | |||
| 2994 | if (io->pfrio_size < 0 || | |||
| 2995 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 2996 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | |||
| 2997 | error = EINVAL22; | |||
| 2998 | break; | |||
| 2999 | } | |||
| 3000 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
| 3001 | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | |||
| 3002 | M_TEMP, M_NOWAIT0x0001); | |||
| 3003 | if (! pfras) { | |||
| 3004 | error = ENOMEM12; | |||
| 3005 | break; | |||
| 3006 | } | |||
| 3007 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
| 3008 | if (error) { | |||
| 3009 | free(pfras, M_TEMP); | |||
| 3010 | break; | |||
| 3011 | } | |||
| 3012 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3012); | |||
| 3013 | error = pfr_add_addrs(&io->pfrio_table, pfras, | |||
| 3014 | io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags | | |||
| 3015 | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3016 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3016); | |||
| 3017 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
| 3018 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
| 3019 | free(pfras, M_TEMP); | |||
| 3020 | break; | |||
| 3021 | } | |||
| 3022 | ||||
| 3023 | case DIOCRDELADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((68)))): { | |||
| 3024 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3025 | struct pfr_addr *pfras; | |||
| 3026 | size_t totlen; | |||
| 3027 | ||||
| 3028 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 3029 | error = ENODEV19; | |||
| 3030 | break; | |||
| 3031 | } | |||
| 3032 | if (io->pfrio_size < 0 || | |||
| 3033 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 3034 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | |||
| 3035 | error = EINVAL22; | |||
| 3036 | break; | |||
| 3037 | } | |||
| 3038 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
| 3039 | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | |||
| 3040 | M_TEMP, M_NOWAIT0x0001); | |||
| 3041 | if (! pfras) { | |||
| 3042 | error = ENOMEM12; | |||
| 3043 | break; | |||
| 3044 | } | |||
| 3045 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
| 3046 | if (error) { | |||
| 3047 | free(pfras, M_TEMP); | |||
| 3048 | break; | |||
| 3049 | } | |||
| 3050 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3050); | |||
| 3051 | error = pfr_del_addrs(&io->pfrio_table, pfras, | |||
| 3052 | io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags | | |||
| 3053 | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3054 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3054); | |||
| 3055 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
| 3056 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
| 3057 | free(pfras, M_TEMP); | |||
| 3058 | break; | |||
| 3059 | } | |||
| 3060 | ||||
| 3061 | case DIOCRSETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((69)))): { | |||
| 3062 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3063 | struct pfr_addr *pfras; | |||
| 3064 | size_t totlen, count; | |||
| 3065 | ||||
| 3066 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 3067 | error = ENODEV19; | |||
| 3068 | break; | |||
| 3069 | } | |||
| 3070 | if (io->pfrio_size < 0 || io->pfrio_size2 < 0) { | |||
| 3071 | error = EINVAL22; | |||
| 3072 | break; | |||
| 3073 | } | |||
| 3074 | count = max(io->pfrio_size, io->pfrio_size2); | |||
| 3075 | if (count > pf_ioctl_maxcount || | |||
| 3076 | WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) { | |||
| 3077 | error = EINVAL22; | |||
| 3078 | break; | |||
| 3079 | } | |||
| 3080 | totlen = count * sizeof(struct pfr_addr); | |||
| 3081 | pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP, | |||
| 3082 | M_NOWAIT0x0001); | |||
| 3083 | if (! pfras) { | |||
| 3084 | error = ENOMEM12; | |||
| 3085 | break; | |||
| 3086 | } | |||
| 3087 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
| 3088 | if (error) { | |||
| 3089 | free(pfras, M_TEMP); | |||
| 3090 | break; | |||
| 3091 | } | |||
| 3092 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3092); | |||
| 3093 | error = pfr_set_addrs(&io->pfrio_table, pfras, | |||
| 3094 | io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd, | |||
| 3095 | &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags | | |||
| 3096 | PFR_FLAG_USERIOCTL0x10000000, 0); | |||
| 3097 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3097); | |||
| 3098 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
| 3099 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
| 3100 | free(pfras, M_TEMP); | |||
| 3101 | break; | |||
| 3102 | } | |||
| 3103 | ||||
| 3104 | case DIOCRGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((70)))): { | |||
| 3105 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3106 | struct pfr_addr *pfras; | |||
| 3107 | size_t totlen; | |||
| 3108 | ||||
| 3109 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 3110 | error = ENODEV19; | |||
| 3111 | break; | |||
| 3112 | } | |||
| 3113 | if (io->pfrio_size < 0 || | |||
| 3114 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 3115 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | |||
| 3116 | error = EINVAL22; | |||
| 3117 | break; | |||
| 3118 | } | |||
| 3119 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
| 3120 | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | |||
| 3121 | M_TEMP, M_NOWAIT0x0001); | |||
| 3122 | if (! pfras) { | |||
| 3123 | error = ENOMEM12; | |||
| 3124 | break; | |||
| 3125 | } | |||
| 3126 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3126 )); | |||
| 3127 | error = pfr_get_addrs(&io->pfrio_table, pfras, | |||
| 3128 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3129 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3129 ); | |||
| 3130 | if (error == 0) | |||
| 3131 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
| 3132 | free(pfras, M_TEMP); | |||
| 3133 | break; | |||
| 3134 | } | |||
| 3135 | ||||
| 3136 | case DIOCRGETASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((71)))): { | |||
| 3137 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3138 | struct pfr_astats *pfrastats; | |||
| 3139 | size_t totlen; | |||
| 3140 | ||||
| 3141 | if (io->pfrio_esize != sizeof(struct pfr_astats)) { | |||
| 3142 | error = ENODEV19; | |||
| 3143 | break; | |||
| 3144 | } | |||
| 3145 | if (io->pfrio_size < 0 || | |||
| 3146 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 3147 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) { | |||
| 3148 | error = EINVAL22; | |||
| 3149 | break; | |||
| 3150 | } | |||
| 3151 | totlen = io->pfrio_size * sizeof(struct pfr_astats); | |||
| 3152 | pfrastats = mallocarray(io->pfrio_size, | |||
| 3153 | sizeof(struct pfr_astats), M_TEMP, M_NOWAIT0x0001); | |||
| 3154 | if (! pfrastats) { | |||
| 3155 | error = ENOMEM12; | |||
| 3156 | break; | |||
| 3157 | } | |||
| 3158 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3158 )); | |||
| 3159 | error = pfr_get_astats(&io->pfrio_table, pfrastats, | |||
| 3160 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3161 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3161 ); | |||
| 3162 | if (error == 0) | |||
| 3163 | error = copyout(pfrastats, io->pfrio_buffer, totlen); | |||
| 3164 | free(pfrastats, M_TEMP); | |||
| 3165 | break; | |||
| 3166 | } | |||
| 3167 | ||||
| 3168 | case DIOCRCLRASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((72)))): { | |||
| 3169 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3170 | struct pfr_addr *pfras; | |||
| 3171 | size_t totlen; | |||
| 3172 | ||||
| 3173 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 3174 | error = ENODEV19; | |||
| 3175 | break; | |||
| 3176 | } | |||
| 3177 | if (io->pfrio_size < 0 || | |||
| 3178 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 3179 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | |||
| 3180 | error = EINVAL22; | |||
| 3181 | break; | |||
| 3182 | } | |||
| 3183 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
| 3184 | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | |||
| 3185 | M_TEMP, M_NOWAIT0x0001); | |||
| 3186 | if (! pfras) { | |||
| 3187 | error = ENOMEM12; | |||
| 3188 | break; | |||
| 3189 | } | |||
| 3190 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
| 3191 | if (error) { | |||
| 3192 | free(pfras, M_TEMP); | |||
| 3193 | break; | |||
| 3194 | } | |||
| 3195 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3195); | |||
| 3196 | error = pfr_clr_astats(&io->pfrio_table, pfras, | |||
| 3197 | io->pfrio_size, &io->pfrio_nzeropfrio_nadd, io->pfrio_flags | | |||
| 3198 | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3199 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3199); | |||
| 3200 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
| 3201 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
| 3202 | free(pfras, M_TEMP); | |||
| 3203 | break; | |||
| 3204 | } | |||
| 3205 | ||||
| 3206 | case DIOCRTSTADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((73)))): { | |||
| 3207 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3208 | struct pfr_addr *pfras; | |||
| 3209 | size_t totlen; | |||
| 3210 | ||||
| 3211 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 3212 | error = ENODEV19; | |||
| 3213 | break; | |||
| 3214 | } | |||
| 3215 | if (io->pfrio_size < 0 || | |||
| 3216 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 3217 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | |||
| 3218 | error = EINVAL22; | |||
| 3219 | break; | |||
| 3220 | } | |||
| 3221 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
| 3222 | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | |||
| 3223 | M_TEMP, M_NOWAIT0x0001); | |||
| 3224 | if (! pfras) { | |||
| 3225 | error = ENOMEM12; | |||
| 3226 | break; | |||
| 3227 | } | |||
| 3228 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
| 3229 | if (error) { | |||
| 3230 | free(pfras, M_TEMP); | |||
| 3231 | break; | |||
| 3232 | } | |||
| 3233 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3233 )); | |||
| 3234 | error = pfr_tst_addrs(&io->pfrio_table, pfras, | |||
| 3235 | io->pfrio_size, &io->pfrio_nmatchpfrio_nadd, io->pfrio_flags | | |||
| 3236 | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3237 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3237 ); | |||
| 3238 | if (error == 0) | |||
| 3239 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
| 3240 | free(pfras, M_TEMP); | |||
| 3241 | break; | |||
| 3242 | } | |||
| 3243 | ||||
| 3244 | case DIOCRINADEFINE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((77)))): { | |||
| 3245 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
| 3246 | struct pfr_addr *pfras; | |||
| 3247 | size_t totlen; | |||
| 3248 | ||||
| 3249 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
| 3250 | error = ENODEV19; | |||
| 3251 | break; | |||
| 3252 | } | |||
| 3253 | if (io->pfrio_size < 0 || | |||
| 3254 | io->pfrio_size > pf_ioctl_maxcount || | |||
| 3255 | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | |||
| 3256 | error = EINVAL22; | |||
| 3257 | break; | |||
| 3258 | } | |||
| 3259 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
| 3260 | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | |||
| 3261 | M_TEMP, M_NOWAIT0x0001); | |||
| 3262 | if (! pfras) { | |||
| 3263 | error = ENOMEM12; | |||
| 3264 | break; | |||
| 3265 | } | |||
| 3266 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
| 3267 | if (error) { | |||
| 3268 | free(pfras, M_TEMP); | |||
| 3269 | break; | |||
| 3270 | } | |||
| 3271 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3271); | |||
| 3272 | error = pfr_ina_define(&io->pfrio_table, pfras, | |||
| 3273 | io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddrpfrio_size2, | |||
| 3274 | io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
| 3275 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3275); | |||
| 3276 | free(pfras, M_TEMP); | |||
| 3277 | break; | |||
| 3278 | } | |||
| 3279 | ||||
| 3280 | case DIOCOSFPADD((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((79)))): { | |||
| 3281 | struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; | |||
| 3282 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3282); | |||
| 3283 | error = pf_osfp_add(io); | |||
| 3284 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3284); | |||
| 3285 | break; | |||
| 3286 | } | |||
| 3287 | ||||
| 3288 | case DIOCOSFPGET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((80)))): { | |||
| 3289 | struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; | |||
| 3290 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3290 )); | |||
| 3291 | error = pf_osfp_get(io); | |||
| 3292 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3292 ); | |||
| 3293 | break; | |||
| 3294 | } | |||
| 3295 | ||||
| 3296 | case DIOCXBEGIN((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_trans)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((81)))): { | |||
| 3297 | struct pfioc_trans *io = (struct pfioc_trans *)addr; | |||
| 3298 | struct pfioc_trans_e *ioes, *ioe; | |||
| 3299 | size_t totlen; | |||
| 3300 | int i; | |||
| 3301 | ||||
| 3302 | if (io->esize != sizeof(*ioe)) { | |||
| 3303 | error = ENODEV19; | |||
| 3304 | break; | |||
| 3305 | } | |||
| 3306 | if (io->size < 0 || | |||
| 3307 | io->size > pf_ioctl_maxcount || | |||
| 3308 | WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { | |||
| 3309 | error = EINVAL22; | |||
| 3310 | break; | |||
| 3311 | } | |||
| 3312 | totlen = sizeof(struct pfioc_trans_e) * io->size; | |||
| 3313 | ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), | |||
| 3314 | M_TEMP, M_NOWAIT0x0001); | |||
| 3315 | if (! ioes) { | |||
| 3316 | error = ENOMEM12; | |||
| 3317 | break; | |||
| 3318 | } | |||
| 3319 | error = copyin(io->array, ioes, totlen); | |||
| 3320 | if (error) { | |||
| 3321 | free(ioes, M_TEMP); | |||
| 3322 | break; | |||
| 3323 | } | |||
| 3324 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3324); | |||
| 3325 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
| 3326 | switch (ioe->rs_num) { | |||
| 3327 | #ifdef ALTQ | |||
| 3328 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
| 3329 | if (ioe->anchor[0]) { | |||
| 3330 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3330); | |||
| 3331 | free(ioes, M_TEMP); | |||
| 3332 | error = EINVAL22; | |||
| 3333 | goto fail; | |||
| 3334 | } | |||
| 3335 | if ((error = pf_begin_altq(&ioe->ticket))) { | |||
| 3336 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3336); | |||
| 3337 | free(ioes, M_TEMP); | |||
| 3338 | goto fail; | |||
| 3339 | } | |||
| 3340 | break; | |||
| 3341 | #endif /* ALTQ */ | |||
| 3342 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
| 3343 | { | |||
| 3344 | struct pfr_table table; | |||
| 3345 | ||||
| 3346 | bzero(&table, sizeof(table))__builtin_memset((&table), 0, (sizeof(table))); | |||
| 3347 | strlcpy(table.pfrt_anchor, ioe->anchor, | |||
| 3348 | sizeof(table.pfrt_anchor)); | |||
| 3349 | if ((error = pfr_ina_begin(&table, | |||
| 3350 | &ioe->ticket, NULL((void *)0), 0))) { | |||
| 3351 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3351); | |||
| 3352 | free(ioes, M_TEMP); | |||
| 3353 | goto fail; | |||
| 3354 | } | |||
| 3355 | break; | |||
| 3356 | } | |||
| 3357 | default: | |||
| 3358 | if ((error = pf_begin_rules(&ioe->ticket, | |||
| 3359 | ioe->rs_num, ioe->anchor))) { | |||
| 3360 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3360); | |||
| 3361 | free(ioes, M_TEMP); | |||
| 3362 | goto fail; | |||
| 3363 | } | |||
| 3364 | break; | |||
| 3365 | } | |||
| 3366 | } | |||
| 3367 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3367); | |||
| 3368 | error = copyout(ioes, io->array, totlen); | |||
| 3369 | free(ioes, M_TEMP); | |||
| 3370 | break; | |||
| 3371 | } | |||
| 3372 | ||||
| 3373 | case DIOCXROLLBACK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_trans)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((83)))): { | |||
| 3374 | struct pfioc_trans *io = (struct pfioc_trans *)addr; | |||
| 3375 | struct pfioc_trans_e *ioe, *ioes; | |||
| 3376 | size_t totlen; | |||
| 3377 | int i; | |||
| 3378 | ||||
| 3379 | if (io->esize != sizeof(*ioe)) { | |||
| 3380 | error = ENODEV19; | |||
| 3381 | break; | |||
| 3382 | } | |||
| 3383 | if (io->size < 0 || | |||
| 3384 | io->size > pf_ioctl_maxcount || | |||
| 3385 | WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { | |||
| 3386 | error = EINVAL22; | |||
| 3387 | break; | |||
| 3388 | } | |||
| 3389 | totlen = sizeof(struct pfioc_trans_e) * io->size; | |||
| 3390 | ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), | |||
| 3391 | M_TEMP, M_NOWAIT0x0001); | |||
| 3392 | if (! ioes) { | |||
| 3393 | error = ENOMEM12; | |||
| 3394 | break; | |||
| 3395 | } | |||
| 3396 | error = copyin(io->array, ioes, totlen); | |||
| 3397 | if (error) { | |||
| 3398 | free(ioes, M_TEMP); | |||
| 3399 | break; | |||
| 3400 | } | |||
| 3401 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3401); | |||
| 3402 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
| 3403 | switch (ioe->rs_num) { | |||
| 3404 | #ifdef ALTQ | |||
| 3405 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
| 3406 | if (ioe->anchor[0]) { | |||
| 3407 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3407); | |||
| 3408 | free(ioes, M_TEMP); | |||
| 3409 | error = EINVAL22; | |||
| 3410 | goto fail; | |||
| 3411 | } | |||
| 3412 | if ((error = pf_rollback_altq(ioe->ticket))) { | |||
| 3413 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3413); | |||
| 3414 | free(ioes, M_TEMP); | |||
| 3415 | goto fail; /* really bad */ | |||
| 3416 | } | |||
| 3417 | break; | |||
| 3418 | #endif /* ALTQ */ | |||
| 3419 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
| 3420 | { | |||
| 3421 | struct pfr_table table; | |||
| 3422 | ||||
| 3423 | bzero(&table, sizeof(table))__builtin_memset((&table), 0, (sizeof(table))); | |||
| 3424 | strlcpy(table.pfrt_anchor, ioe->anchor, | |||
| 3425 | sizeof(table.pfrt_anchor)); | |||
| 3426 | if ((error = pfr_ina_rollback(&table, | |||
| 3427 | ioe->ticket, NULL((void *)0), 0))) { | |||
| 3428 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3428); | |||
| 3429 | free(ioes, M_TEMP); | |||
| 3430 | goto fail; /* really bad */ | |||
| 3431 | } | |||
| 3432 | break; | |||
| 3433 | } | |||
| 3434 | default: | |||
| 3435 | if ((error = pf_rollback_rules(ioe->ticket, | |||
| 3436 | ioe->rs_num, ioe->anchor))) { | |||
| 3437 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3437); | |||
| 3438 | free(ioes, M_TEMP); | |||
| 3439 | goto fail; /* really bad */ | |||
| 3440 | } | |||
| 3441 | break; | |||
| 3442 | } | |||
| 3443 | } | |||
| 3444 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3444); | |||
| 3445 | free(ioes, M_TEMP); | |||
| 3446 | break; | |||
| 3447 | } | |||
| 3448 | ||||
| 3449 | case DIOCXCOMMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_trans)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((82)))): { | |||
| 3450 | struct pfioc_trans *io = (struct pfioc_trans *)addr; | |||
| 3451 | struct pfioc_trans_e *ioe, *ioes; | |||
| 3452 | struct pf_ruleset *rs; | |||
| 3453 | size_t totlen; | |||
| 3454 | int i; | |||
| 3455 | ||||
| 3456 | if (io->esize != sizeof(*ioe)) { | |||
| 3457 | error = ENODEV19; | |||
| 3458 | break; | |||
| 3459 | } | |||
| 3460 | ||||
| 3461 | if (io->size < 0 || | |||
| 3462 | io->size > pf_ioctl_maxcount || | |||
| 3463 | WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { | |||
| 3464 | error = EINVAL22; | |||
| 3465 | break; | |||
| 3466 | } | |||
| 3467 | ||||
| 3468 | totlen = sizeof(struct pfioc_trans_e) * io->size; | |||
| 3469 | ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), | |||
| 3470 | M_TEMP, M_NOWAIT0x0001); | |||
| 3471 | if (ioes == NULL((void *)0)) { | |||
| 3472 | error = ENOMEM12; | |||
| 3473 | break; | |||
| 3474 | } | |||
| 3475 | error = copyin(io->array, ioes, totlen); | |||
| 3476 | if (error) { | |||
| 3477 | free(ioes, M_TEMP); | |||
| 3478 | break; | |||
| 3479 | } | |||
| 3480 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3480); | |||
| 3481 | /* First makes sure everything will succeed. */ | |||
| 3482 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
| 3483 | switch (ioe->rs_num) { | |||
| 3484 | #ifdef ALTQ | |||
| 3485 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
| 3486 | if (ioe->anchor[0]) { | |||
| 3487 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3487); | |||
| 3488 | free(ioes, M_TEMP); | |||
| 3489 | error = EINVAL22; | |||
| 3490 | goto fail; | |||
| 3491 | } | |||
| 3492 | if (!V_altqs_inactive_open(*(__typeof(vnet_entry_altqs_inactive_open)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_altqs_inactive_open )) || ioe->ticket != | |||
| 3493 | V_ticket_altqs_inactive(*(__typeof(vnet_entry_ticket_altqs_inactive)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_ticket_altqs_inactive ))) { | |||
| 3494 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3494); | |||
| 3495 | free(ioes, M_TEMP); | |||
| 3496 | error = EBUSY16; | |||
| 3497 | goto fail; | |||
| 3498 | } | |||
| 3499 | break; | |||
| 3500 | #endif /* ALTQ */ | |||
| 3501 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
| 3502 | rs = pf_find_ruleset(ioe->anchor); | |||
| 3503 | if (rs == NULL((void *)0) || !rs->topen || ioe->ticket != | |||
| 3504 | rs->tticket) { | |||
| 3505 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3505); | |||
| 3506 | free(ioes, M_TEMP); | |||
| 3507 | error = EBUSY16; | |||
| 3508 | goto fail; | |||
| 3509 | } | |||
| 3510 | break; | |||
| 3511 | default: | |||
| 3512 | if (ioe->rs_num < 0 || ioe->rs_num >= | |||
| 3513 | PF_RULESET_MAX) { | |||
| 3514 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3514); | |||
| 3515 | free(ioes, M_TEMP); | |||
| 3516 | error = EINVAL22; | |||
| 3517 | goto fail; | |||
| 3518 | } | |||
| 3519 | rs = pf_find_ruleset(ioe->anchor); | |||
| 3520 | if (rs == NULL((void *)0) || | |||
| 3521 | !rs->rules[ioe->rs_num].inactive.open || | |||
| 3522 | rs->rules[ioe->rs_num].inactive.ticket != | |||
| 3523 | ioe->ticket) { | |||
| 3524 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3524); | |||
| 3525 | free(ioes, M_TEMP); | |||
| 3526 | error = EBUSY16; | |||
| 3527 | goto fail; | |||
| 3528 | } | |||
| 3529 | break; | |||
| 3530 | } | |||
| 3531 | } | |||
| 3532 | /* Now do the commit - no errors should happen here. */ | |||
| 3533 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
| 3534 | switch (ioe->rs_num) { | |||
| 3535 | #ifdef ALTQ | |||
| 3536 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
| 3537 | if ((error = pf_commit_altq(ioe->ticket))) { | |||
| 3538 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3538); | |||
| 3539 | free(ioes, M_TEMP); | |||
| 3540 | goto fail; /* really bad */ | |||
| 3541 | } | |||
| 3542 | break; | |||
| 3543 | #endif /* ALTQ */ | |||
| 3544 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
| 3545 | { | |||
| 3546 | struct pfr_table table; | |||
| 3547 | ||||
| 3548 | bzero(&table, sizeof(table))__builtin_memset((&table), 0, (sizeof(table))); | |||
| 3549 | strlcpy(table.pfrt_anchor, ioe->anchor, | |||
| 3550 | sizeof(table.pfrt_anchor)); | |||
| 3551 | if ((error = pfr_ina_commit(&table, | |||
| 3552 | ioe->ticket, NULL((void *)0), NULL((void *)0), 0))) { | |||
| 3553 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3553); | |||
| 3554 | free(ioes, M_TEMP); | |||
| 3555 | goto fail; /* really bad */ | |||
| 3556 | } | |||
| 3557 | break; | |||
| 3558 | } | |||
| 3559 | default: | |||
| 3560 | if ((error = pf_commit_rules(ioe->ticket, | |||
| 3561 | ioe->rs_num, ioe->anchor))) { | |||
| 3562 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3562); | |||
| 3563 | free(ioes, M_TEMP); | |||
| 3564 | goto fail; /* really bad */ | |||
| 3565 | } | |||
| 3566 | break; | |||
| 3567 | } | |||
| 3568 | } | |||
| 3569 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3569); | |||
| 3570 | free(ioes, M_TEMP); | |||
| 3571 | break; | |||
| 3572 | } | |||
| 3573 | ||||
| 3574 | case DIOCGETSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_nodes)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((84)))): { | |||
| 3575 | struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr; | |||
| 3576 | struct pf_srchash *sh; | |||
| 3577 | struct pf_src_node *n, *p, *pstore; | |||
| 3578 | uint32_t i, nr = 0; | |||
| 3579 | ||||
| 3580 | if (psn->psn_len == 0) { | |||
| 3581 | for (i = 0, sh = V_pf_srchash(*(__typeof(vnet_entry_pf_srchash)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_srchash )); i <= pf_srchashmask; | |||
| 3582 | i++, sh++) { | |||
| 3583 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3583)); | |||
| 3584 | LIST_FOREACH(n, &sh->nodes, entry)for ((n) = (((&sh->nodes))->lh_first); (n); (n) = ( ((n))->entry.le_next)) | |||
| 3585 | nr++; | |||
| 3586 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3586)); | |||
| 3587 | } | |||
| 3588 | psn->psn_len = sizeof(struct pf_src_node) * nr; | |||
| 3589 | break; | |||
| 3590 | } | |||
| 3591 | ||||
| 3592 | p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK0x0002); | |||
| 3593 | for (i = 0, sh = V_pf_srchash(*(__typeof(vnet_entry_pf_srchash)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_srchash )); i <= pf_srchashmask; | |||
| 3594 | i++, sh++) { | |||
| 3595 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3595)); | |||
| 3596 | LIST_FOREACH(n, &sh->nodes, entry)for ((n) = (((&sh->nodes))->lh_first); (n); (n) = ( ((n))->entry.le_next)) { | |||
| 3597 | int secs = time_uptime, diff; | |||
| 3598 | ||||
| 3599 | if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len) | |||
| 3600 | break; | |||
| 3601 | ||||
| 3602 | bcopy(n, p, sizeof(struct pf_src_node))__builtin_memmove((p), (n), (sizeof(struct pf_src_node))); | |||
| 3603 | if (n->rule.ptr != NULL((void *)0)) | |||
| 3604 | p->rule.nr = n->rule.ptr->nr; | |||
| 3605 | p->creation = secs - p->creation; | |||
| 3606 | if (p->expire > secs) | |||
| 3607 | p->expire -= secs; | |||
| 3608 | else | |||
| 3609 | p->expire = 0; | |||
| 3610 | ||||
| 3611 | /* Adjust the connection rate estimate. */ | |||
| 3612 | diff = secs - n->conn_rate.last; | |||
| 3613 | if (diff >= n->conn_rate.seconds) | |||
| 3614 | p->conn_rate.count = 0; | |||
| 3615 | else | |||
| 3616 | p->conn_rate.count -= | |||
| 3617 | n->conn_rate.count * diff / | |||
| 3618 | n->conn_rate.seconds; | |||
| 3619 | p++; | |||
| 3620 | nr++; | |||
| 3621 | } | |||
| 3622 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3622)); | |||
| 3623 | } | |||
| 3624 | error = copyout(pstore, psn->psn_src_nodespsn_u.psu_src_nodes, | |||
| ||||
| 3625 | sizeof(struct pf_src_node) * nr); | |||
| 3626 | if (error) { | |||
| 3627 | free(pstore, M_TEMP); | |||
| 3628 | break; | |||
| 3629 | } | |||
| 3630 | psn->psn_len = sizeof(struct pf_src_node) * nr; | |||
| 3631 | free(pstore, M_TEMP); | |||
| 3632 | break; | |||
| 3633 | } | |||
| 3634 | ||||
| 3635 | case DIOCCLRSRCNODES((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((85)))): { | |||
| 3636 | ||||
| 3637 | pf_clear_srcnodes(NULL((void *)0)); | |||
| 3638 | pf_purge_expired_src_nodes(); | |||
| 3639 | break; | |||
| 3640 | } | |||
| 3641 | ||||
| 3642 | case DIOCKILLSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_node_kill)) & ((1 << 13) - 1)) << 16 ) | ((('D')) << 8) | ((91)))): | |||
| 3643 | pf_kill_srcnodes((struct pfioc_src_node_kill *)addr); | |||
| 3644 | break; | |||
| 3645 | ||||
| 3646 | case DIOCSETHOSTID((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(u_int32_t )) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((86)))): { | |||
| 3647 | u_int32_t *hostid = (u_int32_t *)addr; | |||
| 3648 | ||||
| 3649 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3649); | |||
| 3650 | if (*hostid == 0) | |||
| 3651 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).hostid = arc4random(); | |||
| 3652 | else | |||
| 3653 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).hostid = *hostid; | |||
| 3654 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3654); | |||
| 3655 | break; | |||
| 3656 | } | |||
| 3657 | ||||
| 3658 | case DIOCOSFPFLUSH((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((78)))): | |||
| 3659 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3659); | |||
| 3660 | pf_osfp_flush(); | |||
| 3661 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3661); | |||
| 3662 | break; | |||
| 3663 | ||||
| 3664 | case DIOCIGETIFACES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((87)))): { | |||
| 3665 | struct pfioc_iface *io = (struct pfioc_iface *)addr; | |||
| 3666 | struct pfi_kif *ifstore; | |||
| 3667 | size_t bufsiz; | |||
| 3668 | ||||
| 3669 | if (io->pfiio_esize != sizeof(struct pfi_kif)) { | |||
| 3670 | error = ENODEV19; | |||
| 3671 | break; | |||
| 3672 | } | |||
| 3673 | ||||
| 3674 | if (io->pfiio_size < 0 || | |||
| 3675 | io->pfiio_size > pf_ioctl_maxcount || | |||
| 3676 | WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) { | |||
| 3677 | error = EINVAL22; | |||
| 3678 | break; | |||
| 3679 | } | |||
| 3680 | ||||
| 3681 | bufsiz = io->pfiio_size * sizeof(struct pfi_kif); | |||
| 3682 | ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif), | |||
| 3683 | M_TEMP, M_NOWAIT0x0001); | |||
| 3684 | if (ifstore == NULL((void *)0)) { | |||
| 3685 | error = ENOMEM12; | |||
| 3686 | break; | |||
| 3687 | } | |||
| 3688 | ||||
| 3689 | PF_RULES_RLOCK()((void)_rm_rlock_debug((&pf_rules_lock),(&_pf_rules_tracker ), 0, "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3689 )); | |||
| 3690 | pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size); | |||
| 3691 | PF_RULES_RUNLOCK()_rm_runlock_debug((&pf_rules_lock), (&_pf_rules_tracker ), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3691 ); | |||
| 3692 | error = copyout(ifstore, io->pfiio_buffer, bufsiz); | |||
| 3693 | free(ifstore, M_TEMP); | |||
| 3694 | break; | |||
| 3695 | } | |||
| 3696 | ||||
| 3697 | case DIOCSETIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((89)))): { | |||
| 3698 | struct pfioc_iface *io = (struct pfioc_iface *)addr; | |||
| 3699 | ||||
| 3700 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3700); | |||
| 3701 | error = pfi_set_flags(io->pfiio_name, io->pfiio_flags); | |||
| 3702 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3702); | |||
| 3703 | break; | |||
| 3704 | } | |||
| 3705 | ||||
| 3706 | case DIOCCLRIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((90)))): { | |||
| 3707 | struct pfioc_iface *io = (struct pfioc_iface *)addr; | |||
| 3708 | ||||
| 3709 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3709); | |||
| 3710 | error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags); | |||
| 3711 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 3711); | |||
| 3712 | break; | |||
| 3713 | } | |||
| 3714 | ||||
| 3715 | default: | |||
| 3716 | error = ENODEV19; | |||
| 3717 | break; | |||
| 3718 | } | |||
| 3719 | fail: | |||
| 3720 | if (sx_xlocked(&pf_ioctl_lock)(((&pf_ioctl_lock)->sx_lock & ~((0x01 | 0x02 | 0x04 | 0x10 | 0x08) & ~0x01)) == (uintptr_t)(__curthread()))) | |||
| 3721 | sx_xunlock(&pf_ioctl_lock)_sx_xunlock(((&pf_ioctl_lock)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c" ), (3721)); | |||
| 3722 | CURVNET_RESTORE()do { if (!((__curthread())->td_vnet != ((void *)0) && (saved_vnet == ((void *)0) || saved_vnet->vnet_magic_n == 0x3e0d8f29))) panic ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p" , "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 3722, __func__, ( __curthread())->td_vnet, saved_vnet); } while (0); (__curthread ())->td_vnet = saved_vnet;; | |||
| 3723 | ||||
| 3724 | return (error); | |||
| 3725 | } | |||
| 3726 | ||||
| 3727 | void | |||
| 3728 | pfsync_state_export(struct pfsync_state *sp, struct pf_state *st) | |||
| 3729 | { | |||
| 3730 | bzero(sp, sizeof(struct pfsync_state))__builtin_memset((sp), 0, (sizeof(struct pfsync_state))); | |||
| 3731 | ||||
| 3732 | /* copy from state key */ | |||
| 3733 | sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0]; | |||
| 3734 | sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1]; | |||
| 3735 | sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0]; | |||
| 3736 | sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1]; | |||
| 3737 | sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0]; | |||
| 3738 | sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1]; | |||
| 3739 | sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0]; | |||
| 3740 | sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1]; | |||
| 3741 | sp->proto = st->key[PF_SK_WIRE]->proto; | |||
| 3742 | sp->af = st->key[PF_SK_WIRE]->af; | |||
| 3743 | ||||
| 3744 | /* copy from state */ | |||
| 3745 | strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); | |||
| 3746 | bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr))__builtin_memmove((&sp->rt_addr), (&st->rt_addr ), (sizeof(sp->rt_addr))); | |||
| 3747 | sp->creation = htonl(time_uptime - st->creation)(__builtin_constant_p(time_uptime - st->creation) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)(time_uptime - st->creation)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(time_uptime - st->creation)) & 0xffff) ) << 8 | ((__uint16_t)(((__uint32_t)(time_uptime - st-> creation)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t )(time_uptime - st->creation)) & 0xffff))) << 16 ) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(time_uptime - st->creation)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(time_uptime - st->creation)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(time_uptime - st-> creation)) >> 16)) >> 8) : __bswap16_var(((__uint32_t )(time_uptime - st->creation)) >> 16)))) : __bswap32_var (time_uptime - st->creation)); | |||
| 3748 | sp->expire = pf_state_expires(st); | |||
| 3749 | if (sp->expire <= time_uptime) | |||
| 3750 | sp->expire = htonl(0)(__builtin_constant_p(0) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)(0)) & 0xffff) ? (__uint16_t)(((__uint16_t) (((__uint32_t)(0)) & 0xffff)) << 8 | ((__uint16_t)( ((__uint32_t)(0)) & 0xffff)) >> 8) : __bswap16_var( ((__uint32_t)(0)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)(0)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(0)) >> 16)) << 8 | ( (__uint16_t)(((__uint32_t)(0)) >> 16)) >> 8) : __bswap16_var (((__uint32_t)(0)) >> 16)))) : __bswap32_var(0)); | |||
| 3751 | else | |||
| 3752 | sp->expire = htonl(sp->expire - time_uptime)(__builtin_constant_p(sp->expire - time_uptime) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)(sp->expire - time_uptime)) & 0xffff) ? (__uint16_t)(((__uint16_t)(( (__uint32_t)(sp->expire - time_uptime)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(sp->expire - time_uptime) ) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(sp ->expire - time_uptime)) & 0xffff))) << 16) | (( __uint16_t)(__builtin_constant_p(((__uint32_t)(sp->expire - time_uptime)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t )(sp->expire - time_uptime)) >> 16)) << 8 | (( __uint16_t)(((__uint32_t)(sp->expire - time_uptime)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(sp->expire - time_uptime)) >> 16)))) : __bswap32_var(sp->expire - time_uptime)); | |||
| 3753 | ||||
| 3754 | sp->direction = st->direction; | |||
| 3755 | sp->log = st->log; | |||
| 3756 | sp->timeout = st->timeout; | |||
| 3757 | sp->state_flags = st->state_flags; | |||
| 3758 | if (st->src_node) | |||
| 3759 | sp->sync_flags |= PFSYNC_FLAG_SRCNODE0x04; | |||
| 3760 | if (st->nat_src_node) | |||
| 3761 | sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE0x08; | |||
| 3762 | ||||
| 3763 | sp->id = st->id; | |||
| 3764 | sp->creatorid = st->creatorid; | |||
| 3765 | pf_state_peer_hton(&st->src, &sp->src)do { (&sp->src)->seqlo = (__builtin_constant_p((& st->src)->seqlo) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)((&st->src)->seqlo)) & 0xffff) ? ( __uint16_t)(((__uint16_t)(((__uint32_t)((&st->src)-> seqlo)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((&st->src)->seqlo)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)((&st->src)->seqlo)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)((& st->src)->seqlo)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((&st->src)->seqlo)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((&st->src)->seqlo) ) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((& st->src)->seqlo)) >> 16)))) : __bswap32_var((& st->src)->seqlo)); (&sp->src)->seqhi = (__builtin_constant_p ((&st->src)->seqhi) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)((&st->src)->seqhi)) & 0xffff) ? ( __uint16_t)(((__uint16_t)(((__uint32_t)((&st->src)-> seqhi)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((&st->src)->seqhi)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)((&st->src)->seqhi)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)((& st->src)->seqhi)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((&st->src)->seqhi)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((&st->src)->seqhi) ) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((& st->src)->seqhi)) >> 16)))) : __bswap32_var((& st->src)->seqhi)); (&sp->src)->seqdiff = (__builtin_constant_p ((&st->src)->seqdiff) ? (((__uint32_t)((__uint16_t) (__builtin_constant_p(((__uint32_t)((&st->src)->seqdiff )) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(( &st->src)->seqdiff)) & 0xffff)) << 8 | (( __uint16_t)(((__uint32_t)((&st->src)->seqdiff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((&st-> src)->seqdiff)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)((&st->src)->seqdiff )) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((& st->src)->seqdiff)) >> 16)) << 8 | ((__uint16_t )(((__uint32_t)((&st->src)->seqdiff)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((&st->src)-> seqdiff)) >> 16)))) : __bswap32_var((&st->src)-> seqdiff)); (&sp->src)->max_win = ((__uint16_t)(__builtin_constant_p ((&st->src)->max_win) ? (__uint16_t)(((__uint16_t)( (&st->src)->max_win)) << 8 | ((__uint16_t)((& st->src)->max_win)) >> 8) : __bswap16_var((&st ->src)->max_win))); (&sp->src)->mss = ((__uint16_t )(__builtin_constant_p((&st->src)->mss) ? (__uint16_t )(((__uint16_t)((&st->src)->mss)) << 8 | ((__uint16_t )((&st->src)->mss)) >> 8) : __bswap16_var((& st->src)->mss))); (&sp->src)->state = (&st ->src)->state; (&sp->src)->wscale = (&st-> src)->wscale; if ((&st->src)->scrub) { (&sp-> src)->scrub.pfss_flags = ((__uint16_t)(__builtin_constant_p ((&st->src)->scrub->pfss_flags & 0x0001) ? ( __uint16_t)(((__uint16_t)((&st->src)->scrub->pfss_flags & 0x0001)) << 8 | ((__uint16_t)((&st->src)-> scrub->pfss_flags & 0x0001)) >> 8) : __bswap16_var ((&st->src)->scrub->pfss_flags & 0x0001))); ( &sp->src)->scrub.pfss_ttl = (&st->src)->scrub ->pfss_ttl; (&sp->src)->scrub.pfss_ts_mod = (__builtin_constant_p ((&st->src)->scrub->pfss_ts_mod) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)((&st-> src)->scrub->pfss_ts_mod)) & 0xffff) ? (__uint16_t) (((__uint16_t)(((__uint32_t)((&st->src)->scrub-> pfss_ts_mod)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((&st->src)->scrub->pfss_ts_mod)) & 0xffff) ) >> 8) : __bswap16_var(((__uint32_t)((&st->src) ->scrub->pfss_ts_mod)) & 0xffff))) << 16) | ( (__uint16_t)(__builtin_constant_p(((__uint32_t)((&st-> src)->scrub->pfss_ts_mod)) >> 16) ? (__uint16_t)( ((__uint16_t)(((__uint32_t)((&st->src)->scrub->pfss_ts_mod )) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((& st->src)->scrub->pfss_ts_mod)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((&st->src)->scrub ->pfss_ts_mod)) >> 16)))) : __bswap32_var((&st-> src)->scrub->pfss_ts_mod)); (&sp->src)->scrub .scrub_flag = 0x01; } } while (0); | |||
| 3766 | pf_state_peer_hton(&st->dst, &sp->dst)do { (&sp->dst)->seqlo = (__builtin_constant_p((& st->dst)->seqlo) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)((&st->dst)->seqlo)) & 0xffff) ? ( __uint16_t)(((__uint16_t)(((__uint32_t)((&st->dst)-> seqlo)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((&st->dst)->seqlo)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)((&st->dst)->seqlo)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)((& st->dst)->seqlo)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((&st->dst)->seqlo)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((&st->dst)->seqlo) ) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((& st->dst)->seqlo)) >> 16)))) : __bswap32_var((& st->dst)->seqlo)); (&sp->dst)->seqhi = (__builtin_constant_p ((&st->dst)->seqhi) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)((&st->dst)->seqhi)) & 0xffff) ? ( __uint16_t)(((__uint16_t)(((__uint32_t)((&st->dst)-> seqhi)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((&st->dst)->seqhi)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)((&st->dst)->seqhi)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)((& st->dst)->seqhi)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((&st->dst)->seqhi)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((&st->dst)->seqhi) ) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((& st->dst)->seqhi)) >> 16)))) : __bswap32_var((& st->dst)->seqhi)); (&sp->dst)->seqdiff = (__builtin_constant_p ((&st->dst)->seqdiff) ? (((__uint32_t)((__uint16_t) (__builtin_constant_p(((__uint32_t)((&st->dst)->seqdiff )) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(( &st->dst)->seqdiff)) & 0xffff)) << 8 | (( __uint16_t)(((__uint32_t)((&st->dst)->seqdiff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((&st-> dst)->seqdiff)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)((&st->dst)->seqdiff )) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((& st->dst)->seqdiff)) >> 16)) << 8 | ((__uint16_t )(((__uint32_t)((&st->dst)->seqdiff)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((&st->dst)-> seqdiff)) >> 16)))) : __bswap32_var((&st->dst)-> seqdiff)); (&sp->dst)->max_win = ((__uint16_t)(__builtin_constant_p ((&st->dst)->max_win) ? (__uint16_t)(((__uint16_t)( (&st->dst)->max_win)) << 8 | ((__uint16_t)((& st->dst)->max_win)) >> 8) : __bswap16_var((&st ->dst)->max_win))); (&sp->dst)->mss = ((__uint16_t )(__builtin_constant_p((&st->dst)->mss) ? (__uint16_t )(((__uint16_t)((&st->dst)->mss)) << 8 | ((__uint16_t )((&st->dst)->mss)) >> 8) : __bswap16_var((& st->dst)->mss))); (&sp->dst)->state = (&st ->dst)->state; (&sp->dst)->wscale = (&st-> dst)->wscale; if ((&st->dst)->scrub) { (&sp-> dst)->scrub.pfss_flags = ((__uint16_t)(__builtin_constant_p ((&st->dst)->scrub->pfss_flags & 0x0001) ? ( __uint16_t)(((__uint16_t)((&st->dst)->scrub->pfss_flags & 0x0001)) << 8 | ((__uint16_t)((&st->dst)-> scrub->pfss_flags & 0x0001)) >> 8) : __bswap16_var ((&st->dst)->scrub->pfss_flags & 0x0001))); ( &sp->dst)->scrub.pfss_ttl = (&st->dst)->scrub ->pfss_ttl; (&sp->dst)->scrub.pfss_ts_mod = (__builtin_constant_p ((&st->dst)->scrub->pfss_ts_mod) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)((&st-> dst)->scrub->pfss_ts_mod)) & 0xffff) ? (__uint16_t) (((__uint16_t)(((__uint32_t)((&st->dst)->scrub-> pfss_ts_mod)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t )((&st->dst)->scrub->pfss_ts_mod)) & 0xffff) ) >> 8) : __bswap16_var(((__uint32_t)((&st->dst) ->scrub->pfss_ts_mod)) & 0xffff))) << 16) | ( (__uint16_t)(__builtin_constant_p(((__uint32_t)((&st-> dst)->scrub->pfss_ts_mod)) >> 16) ? (__uint16_t)( ((__uint16_t)(((__uint32_t)((&st->dst)->scrub->pfss_ts_mod )) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((& st->dst)->scrub->pfss_ts_mod)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((&st->dst)->scrub ->pfss_ts_mod)) >> 16)))) : __bswap32_var((&st-> dst)->scrub->pfss_ts_mod)); (&sp->dst)->scrub .scrub_flag = 0x01; } } while (0); | |||
| 3767 | ||||
| 3768 | if (st->rule.ptr == NULL((void *)0)) | |||
| 3769 | sp->rule = htonl(-1)(__builtin_constant_p(-1) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)(-1)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(-1)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)(-1)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)(-1)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)(-1)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(-1)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(-1)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(-1)) >> 16)))) : __bswap32_var (-1)); | |||
| 3770 | else | |||
| 3771 | sp->rule = htonl(st->rule.ptr->nr)(__builtin_constant_p(st->rule.ptr->nr) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)(st->rule .ptr->nr)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t )(st->rule.ptr->nr)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)(st->rule.ptr->nr)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(st->rule.ptr->nr)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p( ((__uint32_t)(st->rule.ptr->nr)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->rule.ptr->nr)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(st->rule.ptr ->nr)) >> 16)) >> 8) : __bswap16_var(((__uint32_t )(st->rule.ptr->nr)) >> 16)))) : __bswap32_var(st ->rule.ptr->nr)); | |||
| 3772 | if (st->anchor.ptr == NULL((void *)0)) | |||
| 3773 | sp->anchor = htonl(-1)(__builtin_constant_p(-1) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)(-1)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(-1)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)(-1)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)(-1)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)(-1)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(-1)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(-1)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(-1)) >> 16)))) : __bswap32_var (-1)); | |||
| 3774 | else | |||
| 3775 | sp->anchor = htonl(st->anchor.ptr->nr)(__builtin_constant_p(st->anchor.ptr->nr) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)(st->anchor .ptr->nr)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t )(st->anchor.ptr->nr)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)(st->anchor.ptr->nr)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(st->anchor.ptr->nr)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p( ((__uint32_t)(st->anchor.ptr->nr)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->anchor.ptr->nr)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(st->anchor. ptr->nr)) >> 16)) >> 8) : __bswap16_var(((__uint32_t )(st->anchor.ptr->nr)) >> 16)))) : __bswap32_var( st->anchor.ptr->nr)); | |||
| 3776 | if (st->nat_rule.ptr == NULL((void *)0)) | |||
| 3777 | sp->nat_rule = htonl(-1)(__builtin_constant_p(-1) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p (((__uint32_t)(-1)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(-1)) & 0xffff)) << 8 | ((__uint16_t )(((__uint32_t)(-1)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)(-1)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)(-1)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(-1)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(-1)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(-1)) >> 16)))) : __bswap32_var (-1)); | |||
| 3778 | else | |||
| 3779 | sp->nat_rule = htonl(st->nat_rule.ptr->nr)(__builtin_constant_p(st->nat_rule.ptr->nr) ? (((__uint32_t )((__uint16_t)(__builtin_constant_p(((__uint32_t)(st->nat_rule .ptr->nr)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t )(st->nat_rule.ptr->nr)) & 0xffff)) << 8 | (( __uint16_t)(((__uint32_t)(st->nat_rule.ptr->nr)) & 0xffff )) >> 8) : __bswap16_var(((__uint32_t)(st->nat_rule. ptr->nr)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p (((__uint32_t)(st->nat_rule.ptr->nr)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->nat_rule.ptr->nr)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(st->nat_rule .ptr->nr)) >> 16)) >> 8) : __bswap16_var(((__uint32_t )(st->nat_rule.ptr->nr)) >> 16)))) : __bswap32_var (st->nat_rule.ptr->nr)); | |||
| 3780 | ||||
| 3781 | pf_state_counter_hton(st->packets[0], sp->packets[0])do { sp->packets[0][0] = (__builtin_constant_p((st->packets [0]>>32)&0xffffffff) ? (((__uint32_t)((__uint16_t)( __builtin_constant_p(((__uint32_t)((st->packets[0]>> 32)&0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((st->packets[0]>>32)&0xffffffff) ) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((st ->packets[0]>>32)&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((st->packets[0]>>32 )&0xffffffff)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)((st->packets[0]>> 32)&0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((st->packets[0]>>32)&0xffffffff) ) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((st-> packets[0]>>32)&0xffffffff)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((st->packets[0]>>32 )&0xffffffff)) >> 16)))) : __bswap32_var((st->packets [0]>>32)&0xffffffff)); sp->packets[0][1] = (__builtin_constant_p (st->packets[0]&0xffffffff) ? (((__uint32_t)((__uint16_t )(__builtin_constant_p(((__uint32_t)(st->packets[0]&0xffffffff )) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(st ->packets[0]&0xffffffff)) & 0xffff)) << 8 | ( (__uint16_t)(((__uint32_t)(st->packets[0]&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(st-> packets[0]&0xffffffff)) & 0xffff))) << 16) | (( __uint16_t)(__builtin_constant_p(((__uint32_t)(st->packets [0]&0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(st->packets[0]&0xffffffff)) >> 16 )) << 8 | ((__uint16_t)(((__uint32_t)(st->packets[0] &0xffffffff)) >> 16)) >> 8) : __bswap16_var(( (__uint32_t)(st->packets[0]&0xffffffff)) >> 16)) )) : __bswap32_var(st->packets[0]&0xffffffff)); } while (0); | |||
| 3782 | pf_state_counter_hton(st->packets[1], sp->packets[1])do { sp->packets[1][0] = (__builtin_constant_p((st->packets [1]>>32)&0xffffffff) ? (((__uint32_t)((__uint16_t)( __builtin_constant_p(((__uint32_t)((st->packets[1]>> 32)&0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((st->packets[1]>>32)&0xffffffff) ) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((st ->packets[1]>>32)&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)((st->packets[1]>>32 )&0xffffffff)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)((st->packets[1]>> 32)&0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)((st->packets[1]>>32)&0xffffffff) ) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)((st-> packets[1]>>32)&0xffffffff)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((st->packets[1]>>32 )&0xffffffff)) >> 16)))) : __bswap32_var((st->packets [1]>>32)&0xffffffff)); sp->packets[1][1] = (__builtin_constant_p (st->packets[1]&0xffffffff) ? (((__uint32_t)((__uint16_t )(__builtin_constant_p(((__uint32_t)(st->packets[1]&0xffffffff )) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(st ->packets[1]&0xffffffff)) & 0xffff)) << 8 | ( (__uint16_t)(((__uint32_t)(st->packets[1]&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(st-> packets[1]&0xffffffff)) & 0xffff))) << 16) | (( __uint16_t)(__builtin_constant_p(((__uint32_t)(st->packets [1]&0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t )(((__uint32_t)(st->packets[1]&0xffffffff)) >> 16 )) << 8 | ((__uint16_t)(((__uint32_t)(st->packets[1] &0xffffffff)) >> 16)) >> 8) : __bswap16_var(( (__uint32_t)(st->packets[1]&0xffffffff)) >> 16)) )) : __bswap32_var(st->packets[1]&0xffffffff)); } while (0); | |||
| 3783 | pf_state_counter_hton(st->bytes[0], sp->bytes[0])do { sp->bytes[0][0] = (__builtin_constant_p((st->bytes [0]>>32)&0xffffffff) ? (((__uint32_t)((__uint16_t)( __builtin_constant_p(((__uint32_t)((st->bytes[0]>>32 )&0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t) (((__uint32_t)((st->bytes[0]>>32)&0xffffffff)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((st->bytes [0]>>32)&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)((st->bytes[0]>>32)&0xffffffff)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p( ((__uint32_t)((st->bytes[0]>>32)&0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((st->bytes [0]>>32)&0xffffffff)) >> 16)) << 8 | (( __uint16_t)(((__uint32_t)((st->bytes[0]>>32)&0xffffffff )) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((st ->bytes[0]>>32)&0xffffffff)) >> 16)))) : __bswap32_var ((st->bytes[0]>>32)&0xffffffff)); sp->bytes[0 ][1] = (__builtin_constant_p(st->bytes[0]&0xffffffff) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t )(st->bytes[0]&0xffffffff)) & 0xffff) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->bytes[0]&0xffffffff) ) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(st-> bytes[0]&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)(st->bytes[0]&0xffffffff)) & 0xffff) )) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t )(st->bytes[0]&0xffffffff)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->bytes[0]&0xffffffff) ) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(st-> bytes[0]&0xffffffff)) >> 16)) >> 8) : __bswap16_var (((__uint32_t)(st->bytes[0]&0xffffffff)) >> 16)) )) : __bswap32_var(st->bytes[0]&0xffffffff)); } while ( 0); | |||
| 3784 | pf_state_counter_hton(st->bytes[1], sp->bytes[1])do { sp->bytes[1][0] = (__builtin_constant_p((st->bytes [1]>>32)&0xffffffff) ? (((__uint32_t)((__uint16_t)( __builtin_constant_p(((__uint32_t)((st->bytes[1]>>32 )&0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t) (((__uint32_t)((st->bytes[1]>>32)&0xffffffff)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)((st->bytes [1]>>32)&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)((st->bytes[1]>>32)&0xffffffff)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p( ((__uint32_t)((st->bytes[1]>>32)&0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)((st->bytes [1]>>32)&0xffffffff)) >> 16)) << 8 | (( __uint16_t)(((__uint32_t)((st->bytes[1]>>32)&0xffffffff )) >> 16)) >> 8) : __bswap16_var(((__uint32_t)((st ->bytes[1]>>32)&0xffffffff)) >> 16)))) : __bswap32_var ((st->bytes[1]>>32)&0xffffffff)); sp->bytes[1 ][1] = (__builtin_constant_p(st->bytes[1]&0xffffffff) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t )(st->bytes[1]&0xffffffff)) & 0xffff) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->bytes[1]&0xffffffff) ) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(st-> bytes[1]&0xffffffff)) & 0xffff)) >> 8) : __bswap16_var (((__uint32_t)(st->bytes[1]&0xffffffff)) & 0xffff) )) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t )(st->bytes[1]&0xffffffff)) >> 16) ? (__uint16_t )(((__uint16_t)(((__uint32_t)(st->bytes[1]&0xffffffff) ) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(st-> bytes[1]&0xffffffff)) >> 16)) >> 8) : __bswap16_var (((__uint32_t)(st->bytes[1]&0xffffffff)) >> 16)) )) : __bswap32_var(st->bytes[1]&0xffffffff)); } while ( 0); | |||
| 3785 | ||||
| 3786 | } | |||
| 3787 | ||||
| 3788 | static void | |||
| 3789 | pf_tbladdr_copyout(struct pf_addr_wrap *aw) | |||
| 3790 | { | |||
| 3791 | struct pfr_ktable *kt; | |||
| 3792 | ||||
| 3793 | KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type))do { if (__builtin_expect((!(aw->type == PF_ADDR_TABLE)), 0 )) panic ("%s: type %u", __func__, aw->type); } while (0); | |||
| 3794 | ||||
| 3795 | kt = aw->p.tbl; | |||
| 3796 | if (!(kt->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags & PFR_TFLAG_ACTIVE0x00000004) && kt->pfrkt_root != NULL((void *)0)) | |||
| 3797 | kt = kt->pfrkt_root; | |||
| 3798 | aw->p.tbl = NULL((void *)0); | |||
| 3799 | aw->p.tblcnt = (kt->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags & PFR_TFLAG_ACTIVE0x00000004) ? | |||
| 3800 | kt->pfrkt_cntpfrkt_ts.pfrts_cnt : -1; | |||
| 3801 | } | |||
| 3802 | ||||
| 3803 | /* | |||
| 3804 | * XXX - Check for version missmatch!!! | |||
| 3805 | */ | |||
| 3806 | static void | |||
| 3807 | pf_clear_states(void) | |||
| 3808 | { | |||
| 3809 | struct pf_state *s; | |||
| 3810 | u_int i; | |||
| 3811 | ||||
| 3812 | for (i = 0; i <= pf_hashmask; i++) { | |||
| 3813 | struct pf_idhash *ih = &V_pf_idhash(*(__typeof(vnet_entry_pf_idhash)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_idhash ))[i]; | |||
| 3814 | relock: | |||
| 3815 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3815)); | |||
| 3816 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
| 3817 | s->timeout = PFTM_PURGE; | |||
| 3818 | /* Don't send out individual delete messages. */ | |||
| 3819 | s->state_flags |= PFSTATE_NOSYNC0x08; | |||
| 3820 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
| 3821 | goto relock; | |||
| 3822 | } | |||
| 3823 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3823)); | |||
| 3824 | } | |||
| 3825 | } | |||
| 3826 | ||||
| 3827 | static int | |||
| 3828 | pf_clear_tables(void) | |||
| 3829 | { | |||
| 3830 | struct pfioc_table io; | |||
| 3831 | int error; | |||
| 3832 | ||||
| 3833 | bzero(&io, sizeof(io))__builtin_memset((&io), 0, (sizeof(io))); | |||
| 3834 | ||||
| 3835 | error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel, | |||
| 3836 | io.pfrio_flags); | |||
| 3837 | ||||
| 3838 | return (error); | |||
| 3839 | } | |||
| 3840 | ||||
| 3841 | static void | |||
| 3842 | pf_clear_srcnodes(struct pf_src_node *n) | |||
| 3843 | { | |||
| 3844 | struct pf_state *s; | |||
| 3845 | int i; | |||
| 3846 | ||||
| 3847 | for (i = 0; i <= pf_hashmask; i++) { | |||
| 3848 | struct pf_idhash *ih = &V_pf_idhash(*(__typeof(vnet_entry_pf_idhash)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_idhash ))[i]; | |||
| 3849 | ||||
| 3850 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3850)); | |||
| 3851 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
| 3852 | if (n == NULL((void *)0) || n == s->src_node) | |||
| 3853 | s->src_node = NULL((void *)0); | |||
| 3854 | if (n == NULL((void *)0) || n == s->nat_src_node) | |||
| 3855 | s->nat_src_node = NULL((void *)0); | |||
| 3856 | } | |||
| 3857 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3857)); | |||
| 3858 | } | |||
| 3859 | ||||
| 3860 | if (n == NULL((void *)0)) { | |||
| 3861 | struct pf_srchash *sh; | |||
| 3862 | ||||
| 3863 | for (i = 0, sh = V_pf_srchash(*(__typeof(vnet_entry_pf_srchash)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_srchash )); i <= pf_srchashmask; | |||
| 3864 | i++, sh++) { | |||
| 3865 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3865)); | |||
| 3866 | LIST_FOREACH(n, &sh->nodes, entry)for ((n) = (((&sh->nodes))->lh_first); (n); (n) = ( ((n))->entry.le_next)) { | |||
| 3867 | n->expire = 1; | |||
| 3868 | n->states = 0; | |||
| 3869 | } | |||
| 3870 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3870)); | |||
| 3871 | } | |||
| 3872 | } else { | |||
| 3873 | /* XXX: hash slot should already be locked here. */ | |||
| 3874 | n->expire = 1; | |||
| 3875 | n->states = 0; | |||
| 3876 | } | |||
| 3877 | } | |||
| 3878 | ||||
| 3879 | static void | |||
| 3880 | pf_kill_srcnodes(struct pfioc_src_node_kill *psnk) | |||
| 3881 | { | |||
| 3882 | struct pf_src_node_list kill; | |||
| 3883 | ||||
| 3884 | LIST_INIT(&kill)do { (((&kill))->lh_first) = ((void *)0); } while (0); | |||
| 3885 | for (int i = 0; i <= pf_srchashmask; i++) { | |||
| 3886 | struct pf_srchash *sh = &V_pf_srchash(*(__typeof(vnet_entry_pf_srchash)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_srchash ))[i]; | |||
| 3887 | struct pf_src_node *sn, *tmp; | |||
| 3888 | ||||
| 3889 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3889)); | |||
| 3890 | LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)for ((sn) = (((&sh->nodes))->lh_first); (sn) && ((tmp) = (((sn))->entry.le_next), 1); (sn) = (tmp)) | |||
| 3891 | if (PF_MATCHA(psnk->psnk_src.neg,pf_match_addr(psnk->psnk_src.neg, &psnk->psnk_src.addr .v.a.addr, &psnk->psnk_src.addr.v.a.mask, &sn-> addr, sn->af) | |||
| 3892 | &psnk->psnk_src.addr.v.a.addr,pf_match_addr(psnk->psnk_src.neg, &psnk->psnk_src.addr .v.a.addr, &psnk->psnk_src.addr.v.a.mask, &sn-> addr, sn->af) | |||
| 3893 | &psnk->psnk_src.addr.v.a.mask,pf_match_addr(psnk->psnk_src.neg, &psnk->psnk_src.addr .v.a.addr, &psnk->psnk_src.addr.v.a.mask, &sn-> addr, sn->af) | |||
| 3894 | &sn->addr, sn->af)pf_match_addr(psnk->psnk_src.neg, &psnk->psnk_src.addr .v.a.addr, &psnk->psnk_src.addr.v.a.mask, &sn-> addr, sn->af) && | |||
| 3895 | PF_MATCHA(psnk->psnk_dst.neg,pf_match_addr(psnk->psnk_dst.neg, &psnk->psnk_dst.addr .v.a.addr, &psnk->psnk_dst.addr.v.a.mask, &sn-> raddr, sn->af) | |||
| 3896 | &psnk->psnk_dst.addr.v.a.addr,pf_match_addr(psnk->psnk_dst.neg, &psnk->psnk_dst.addr .v.a.addr, &psnk->psnk_dst.addr.v.a.mask, &sn-> raddr, sn->af) | |||
| 3897 | &psnk->psnk_dst.addr.v.a.mask,pf_match_addr(psnk->psnk_dst.neg, &psnk->psnk_dst.addr .v.a.addr, &psnk->psnk_dst.addr.v.a.mask, &sn-> raddr, sn->af) | |||
| 3898 | &sn->raddr, sn->af)pf_match_addr(psnk->psnk_dst.neg, &psnk->psnk_dst.addr .v.a.addr, &psnk->psnk_dst.addr.v.a.mask, &sn-> raddr, sn->af)) { | |||
| 3899 | pf_unlink_src_node(sn); | |||
| 3900 | LIST_INSERT_HEAD(&kill, sn, entry)do { do { if (((((&kill)))->lh_first) != ((void *)0) && ((((&kill)))->lh_first)->entry.le_prev != &((( (&kill)))->lh_first)) panic("Bad list head %p first->prev != head" , ((&kill))); } while (0); if (((((sn))->entry.le_next ) = (((&kill))->lh_first)) != ((void *)0)) (((&kill ))->lh_first)->entry.le_prev = &(((sn))->entry.le_next ); (((&kill))->lh_first) = (sn); (sn)->entry.le_prev = &(((&kill))->lh_first); } while (0); | |||
| 3901 | sn->expire = 1; | |||
| 3902 | } | |||
| 3903 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3903)); | |||
| 3904 | } | |||
| 3905 | ||||
| 3906 | for (int i = 0; i <= pf_hashmask; i++) { | |||
| 3907 | struct pf_idhash *ih = &V_pf_idhash(*(__typeof(vnet_entry_pf_idhash)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_idhash ))[i]; | |||
| 3908 | struct pf_state *s; | |||
| 3909 | ||||
| 3910 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3910)); | |||
| 3911 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
| 3912 | if (s->src_node && s->src_node->expire == 1) | |||
| 3913 | s->src_node = NULL((void *)0); | |||
| 3914 | if (s->nat_src_node && s->nat_src_node->expire == 1) | |||
| 3915 | s->nat_src_node = NULL((void *)0); | |||
| 3916 | } | |||
| 3917 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c"), (3917)); | |||
| 3918 | } | |||
| 3919 | ||||
| 3920 | psnk->psnk_killed = pf_free_src_nodes(&kill); | |||
| 3921 | } | |||
| 3922 | ||||
| 3923 | /* | |||
| 3924 | * XXX - Check for version missmatch!!! | |||
| 3925 | */ | |||
| 3926 | ||||
| 3927 | /* | |||
| 3928 | * Duplicate pfctl -Fa operation to get rid of as much as we can. | |||
| 3929 | */ | |||
| 3930 | static int | |||
| 3931 | shutdown_pf(void) | |||
| 3932 | { | |||
| 3933 | int error = 0; | |||
| 3934 | u_int32_t t[5]; | |||
| 3935 | char nn = '\0'; | |||
| 3936 | ||||
| 3937 | do { | |||
| 3938 | if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn)) | |||
| 3939 | != 0) { | |||
| 3940 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: SCRUB\n" ); | |||
| 3941 | break; | |||
| 3942 | } | |||
| 3943 | if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn)) | |||
| 3944 | != 0) { | |||
| 3945 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: FILTER\n" ); | |||
| 3946 | break; /* XXX: rollback? */ | |||
| 3947 | } | |||
| 3948 | if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn)) | |||
| 3949 | != 0) { | |||
| 3950 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: NAT\n"); | |||
| 3951 | break; /* XXX: rollback? */ | |||
| 3952 | } | |||
| 3953 | if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn)) | |||
| 3954 | != 0) { | |||
| 3955 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: BINAT\n" ); | |||
| 3956 | break; /* XXX: rollback? */ | |||
| 3957 | } | |||
| 3958 | if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn)) | |||
| 3959 | != 0) { | |||
| 3960 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: RDR\n"); | |||
| 3961 | break; /* XXX: rollback? */ | |||
| 3962 | } | |||
| 3963 | ||||
| 3964 | /* XXX: these should always succeed here */ | |||
| 3965 | pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn); | |||
| 3966 | pf_commit_rules(t[1], PF_RULESET_FILTER, &nn); | |||
| 3967 | pf_commit_rules(t[2], PF_RULESET_NAT, &nn); | |||
| 3968 | pf_commit_rules(t[3], PF_RULESET_BINAT, &nn); | |||
| 3969 | pf_commit_rules(t[4], PF_RULESET_RDR, &nn); | |||
| 3970 | ||||
| 3971 | if ((error = pf_clear_tables()) != 0) | |||
| 3972 | break; | |||
| 3973 | ||||
| 3974 | #ifdef ALTQ | |||
| 3975 | if ((error = pf_begin_altq(&t[0])) != 0) { | |||
| 3976 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"))if ((*(__typeof(vnet_entry_pf_status)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: ALTQ\n" ); | |||
| 3977 | break; | |||
| 3978 | } | |||
| 3979 | pf_commit_altq(t[0]); | |||
| 3980 | #endif | |||
| 3981 | ||||
| 3982 | pf_clear_states(); | |||
| 3983 | ||||
| 3984 | pf_clear_srcnodes(NULL((void *)0)); | |||
| 3985 | ||||
| 3986 | /* status does not use malloced mem so no need to cleanup */ | |||
| 3987 | /* fingerprints and interfaces have their own cleanup code */ | |||
| 3988 | ||||
| 3989 | /* Free counters last as we updated them during shutdown. */ | |||
| 3990 | counter_u64_free(V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).states_cur); | |||
| 3991 | counter_u64_free(V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).states_tot); | |||
| 3992 | counter_u64_free(V_pf_default_rule(*(__typeof(vnet_entry_pf_default_rule)*) (((((__curthread()) ->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_default_rule )).src_nodes); | |||
| 3993 | ||||
| 3994 | for (int i = 0; i < PFRES_MAX16; i++) | |||
| 3995 | counter_u64_free(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).counters[i]); | |||
| 3996 | for (int i = 0; i < LCNT_MAX7; i++) | |||
| 3997 | counter_u64_free(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).lcounters[i]); | |||
| 3998 | for (int i = 0; i < FCNT_MAX3; i++) | |||
| 3999 | counter_u64_free(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).fcounters[i]); | |||
| 4000 | for (int i = 0; i < SCNT_MAX3; i++) | |||
| 4001 | counter_u64_free(V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).scounters[i]); | |||
| 4002 | } while(0); | |||
| 4003 | ||||
| 4004 | return (error); | |||
| 4005 | } | |||
| 4006 | ||||
| 4007 | #ifdef INET1 | |||
| 4008 | static int | |||
| 4009 | pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags, | |||
| 4010 | struct inpcb *inp) | |||
| 4011 | { | |||
| 4012 | int chk; | |||
| 4013 | ||||
| 4014 | chk = pf_test(PF_IN, flags, ifp, m, inp); | |||
| 4015 | if (chk && *m) { | |||
| 4016 | m_freem(*m); | |||
| 4017 | *m = NULL((void *)0); | |||
| 4018 | } | |||
| 4019 | ||||
| 4020 | if (chk != PF_PASS) | |||
| 4021 | return (EACCES13); | |||
| 4022 | return (0); | |||
| 4023 | } | |||
| 4024 | ||||
| 4025 | static int | |||
| 4026 | pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags, | |||
| 4027 | struct inpcb *inp) | |||
| 4028 | { | |||
| 4029 | int chk; | |||
| 4030 | ||||
| 4031 | chk = pf_test(PF_OUT, flags, ifp, m, inp); | |||
| 4032 | if (chk && *m) { | |||
| 4033 | m_freem(*m); | |||
| 4034 | *m = NULL((void *)0); | |||
| 4035 | } | |||
| 4036 | ||||
| 4037 | if (chk != PF_PASS) | |||
| 4038 | return (EACCES13); | |||
| 4039 | return (0); | |||
| 4040 | } | |||
| 4041 | #endif | |||
| 4042 | ||||
| 4043 | #ifdef INET61 | |||
| 4044 | static int | |||
| 4045 | pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags, | |||
| 4046 | struct inpcb *inp) | |||
| 4047 | { | |||
| 4048 | int chk; | |||
| 4049 | ||||
| 4050 | /* | |||
| 4051 | * In case of loopback traffic IPv6 uses the real interface in | |||
| 4052 | * order to support scoped addresses. In order to support stateful | |||
| 4053 | * filtering we have change this to lo0 as it is the case in IPv4. | |||
| 4054 | */ | |||
| 4055 | CURVNET_SET(ifp->if_vnet)do { if (!((ifp->if_vnet) != ((void *)0) && (ifp-> if_vnet)->vnet_magic_n == 0x3e0d8f29)) panic ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p" , "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 4055, __func__, ( __curthread())->td_vnet, (ifp->if_vnet)); } while (0); struct vnet *saved_vnet = (__curthread())->td_vnet; (__curthread ())->td_vnet = ifp->if_vnet;; | |||
| 4056 | chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP0x00020000 ? V_loif(*(__typeof(vnet_entry_loif)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_loif)) : ifp, m, inp); | |||
| 4057 | CURVNET_RESTORE()do { if (!((__curthread())->td_vnet != ((void *)0) && (saved_vnet == ((void *)0) || saved_vnet->vnet_magic_n == 0x3e0d8f29))) panic ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p" , "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 4057, __func__, ( __curthread())->td_vnet, saved_vnet); } while (0); (__curthread ())->td_vnet = saved_vnet;; | |||
| 4058 | if (chk && *m) { | |||
| 4059 | m_freem(*m); | |||
| 4060 | *m = NULL((void *)0); | |||
| 4061 | } | |||
| 4062 | if (chk != PF_PASS) | |||
| 4063 | return (EACCES13); | |||
| 4064 | return (0); | |||
| 4065 | } | |||
| 4066 | ||||
| 4067 | static int | |||
| 4068 | pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags, | |||
| 4069 | struct inpcb *inp) | |||
| 4070 | { | |||
| 4071 | int chk; | |||
| 4072 | ||||
| 4073 | CURVNET_SET(ifp->if_vnet)do { if (!((ifp->if_vnet) != ((void *)0) && (ifp-> if_vnet)->vnet_magic_n == 0x3e0d8f29)) panic ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p" , "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 4073, __func__, ( __curthread())->td_vnet, (ifp->if_vnet)); } while (0); struct vnet *saved_vnet = (__curthread())->td_vnet; (__curthread ())->td_vnet = ifp->if_vnet;; | |||
| 4074 | chk = pf_test6(PF_OUT, flags, ifp, m, inp); | |||
| 4075 | CURVNET_RESTORE()do { if (!((__curthread())->td_vnet != ((void *)0) && (saved_vnet == ((void *)0) || saved_vnet->vnet_magic_n == 0x3e0d8f29))) panic ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p" , "/root/freebsd/sys/netpfil/pf/pf_ioctl.c", 4075, __func__, ( __curthread())->td_vnet, saved_vnet); } while (0); (__curthread ())->td_vnet = saved_vnet;; | |||
| 4076 | if (chk && *m) { | |||
| 4077 | m_freem(*m); | |||
| 4078 | *m = NULL((void *)0); | |||
| 4079 | } | |||
| 4080 | if (chk != PF_PASS) | |||
| 4081 | return (EACCES13); | |||
| 4082 | return (0); | |||
| 4083 | } | |||
| 4084 | #endif /* INET6 */ | |||
| 4085 | ||||
| 4086 | static int | |||
| 4087 | hook_pf(void) | |||
| 4088 | { | |||
| 4089 | #ifdef INET1 | |||
| 4090 | struct pfil_head *pfh_inet; | |||
| 4091 | #endif | |||
| 4092 | #ifdef INET61 | |||
| 4093 | struct pfil_head *pfh_inet6; | |||
| 4094 | #endif | |||
| 4095 | ||||
| 4096 | if (V_pf_pfil_hooked(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked ))) | |||
| 4097 | return (0); | |||
| 4098 | ||||
| 4099 | #ifdef INET1 | |||
| 4100 | pfh_inet = pfil_head_get(PFIL_TYPE_AF1, AF_INET2); | |||
| 4101 | if (pfh_inet == NULL((void *)0)) | |||
| 4102 | return (ESRCH3); /* XXX */ | |||
| 4103 | pfil_add_hook_flags(pf_check_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, pfh_inet); | |||
| 4104 | pfil_add_hook_flags(pf_check_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, pfh_inet); | |||
| 4105 | #endif | |||
| 4106 | #ifdef INET61 | |||
| 4107 | pfh_inet6 = pfil_head_get(PFIL_TYPE_AF1, AF_INET628); | |||
| 4108 | if (pfh_inet6 == NULL((void *)0)) { | |||
| 4109 | #ifdef INET1 | |||
| 4110 | pfil_remove_hook_flags(pf_check_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, | |||
| 4111 | pfh_inet); | |||
| 4112 | pfil_remove_hook_flags(pf_check_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, | |||
| 4113 | pfh_inet); | |||
| 4114 | #endif | |||
| 4115 | return (ESRCH3); /* XXX */ | |||
| 4116 | } | |||
| 4117 | pfil_add_hook_flags(pf_check6_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, pfh_inet6); | |||
| 4118 | pfil_add_hook_flags(pf_check6_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, pfh_inet6); | |||
| 4119 | #endif | |||
| 4120 | ||||
| 4121 | V_pf_pfil_hooked(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked )) = 1; | |||
| 4122 | return (0); | |||
| 4123 | } | |||
| 4124 | ||||
| 4125 | static int | |||
| 4126 | dehook_pf(void) | |||
| 4127 | { | |||
| 4128 | #ifdef INET1 | |||
| 4129 | struct pfil_head *pfh_inet; | |||
| 4130 | #endif | |||
| 4131 | #ifdef INET61 | |||
| 4132 | struct pfil_head *pfh_inet6; | |||
| 4133 | #endif | |||
| 4134 | ||||
| 4135 | if (V_pf_pfil_hooked(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked )) == 0) | |||
| 4136 | return (0); | |||
| 4137 | ||||
| 4138 | #ifdef INET1 | |||
| 4139 | pfh_inet = pfil_head_get(PFIL_TYPE_AF1, AF_INET2); | |||
| 4140 | if (pfh_inet == NULL((void *)0)) | |||
| 4141 | return (ESRCH3); /* XXX */ | |||
| 4142 | pfil_remove_hook_flags(pf_check_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, | |||
| 4143 | pfh_inet); | |||
| 4144 | pfil_remove_hook_flags(pf_check_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, | |||
| 4145 | pfh_inet); | |||
| 4146 | #endif | |||
| 4147 | #ifdef INET61 | |||
| 4148 | pfh_inet6 = pfil_head_get(PFIL_TYPE_AF1, AF_INET628); | |||
| 4149 | if (pfh_inet6 == NULL((void *)0)) | |||
| 4150 | return (ESRCH3); /* XXX */ | |||
| 4151 | pfil_remove_hook_flags(pf_check6_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, | |||
| 4152 | pfh_inet6); | |||
| 4153 | pfil_remove_hook_flags(pf_check6_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, | |||
| 4154 | pfh_inet6); | |||
| 4155 | #endif | |||
| 4156 | ||||
| 4157 | V_pf_pfil_hooked(*(__typeof(vnet_entry_pf_pfil_hooked)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_pfil_hooked )) = 0; | |||
| 4158 | return (0); | |||
| 4159 | } | |||
| 4160 | ||||
| 4161 | static void | |||
| 4162 | pf_load_vnet(void) | |||
| 4163 | { | |||
| 4164 | TAILQ_INIT(&V_pf_tags)do { (((&(*(__typeof(vnet_entry_pf_tags)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags ))))->tqh_first) = ((void *)0); (&(*(__typeof(vnet_entry_pf_tags )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_tags)))->tqh_last = &(((& (*(__typeof(vnet_entry_pf_tags)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_tags)) ))->tqh_first); ; } while (0); | |||
| 4165 | TAILQ_INIT(&V_pf_qids)do { (((&(*(__typeof(vnet_entry_pf_qids)*) (((((__curthread ())->td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_qids ))))->tqh_first) = ((void *)0); (&(*(__typeof(vnet_entry_pf_qids )*) (((((__curthread())->td_vnet))->vnet_data_base) + ( uintptr_t)&vnet_entry_pf_qids)))->tqh_last = &(((& (*(__typeof(vnet_entry_pf_qids)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_qids)) ))->tqh_first); ; } while (0); | |||
| 4166 | ||||
| 4167 | pfattach_vnet(); | |||
| 4168 | V_pf_vnet_active(*(__typeof(vnet_entry_pf_vnet_active)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_vnet_active )) = 1; | |||
| 4169 | } | |||
| 4170 | ||||
| 4171 | static int | |||
| 4172 | pf_load(void) | |||
| 4173 | { | |||
| 4174 | int error; | |||
| 4175 | ||||
| 4176 | rm_init(&pf_rules_lock, "pf rulesets"); | |||
| 4177 | sx_init(&pf_ioctl_lock, "pf ioctl")sx_init_flags((&pf_ioctl_lock), ("pf ioctl"), 0); | |||
| 4178 | sx_init(&pf_end_lock, "pf end thread")sx_init_flags((&pf_end_lock), ("pf end thread"), 0); | |||
| 4179 | ||||
| 4180 | pf_mtag_initialize(); | |||
| 4181 | ||||
| 4182 | pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME"pf"); | |||
| 4183 | if (pf_dev == NULL((void *)0)) | |||
| 4184 | return (ENOMEM12); | |||
| 4185 | ||||
| 4186 | pf_end_threads = 0; | |||
| 4187 | error = kproc_create(pf_purge_thread, NULL((void *)0), &pf_purge_proc, 0, 0, "pf purge"); | |||
| 4188 | if (error != 0) | |||
| 4189 | return (error); | |||
| 4190 | ||||
| 4191 | pfi_initialize(); | |||
| 4192 | ||||
| 4193 | return (0); | |||
| 4194 | } | |||
| 4195 | ||||
| 4196 | static void | |||
| 4197 | pf_unload_vnet(void) | |||
| 4198 | { | |||
| 4199 | int error; | |||
| 4200 | ||||
| 4201 | V_pf_vnet_active(*(__typeof(vnet_entry_pf_vnet_active)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_vnet_active )) = 0; | |||
| 4202 | V_pf_status(*(__typeof(vnet_entry_pf_status)*) (((((__curthread())->td_vnet ))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_status )).running = 0; | |||
| 4203 | error = dehook_pf(); | |||
| 4204 | if (error) { | |||
| 4205 | /* | |||
| 4206 | * Should not happen! | |||
| 4207 | * XXX Due to error code ESRCH, kldunload will show | |||
| 4208 | * a message like 'No such process'. | |||
| 4209 | */ | |||
| 4210 | printf("%s : pfil unregisteration fail\n", __FUNCTION__); | |||
| 4211 | return; | |||
| 4212 | } | |||
| 4213 | ||||
| 4214 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 4214); | |||
| 4215 | shutdown_pf(); | |||
| 4216 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 4216); | |||
| 4217 | ||||
| 4218 | swi_remove(V_pf_swi_cookie(*(__typeof(vnet_entry_pf_swi_cookie)*) (((((__curthread())-> td_vnet))->vnet_data_base) + (uintptr_t)&vnet_entry_pf_swi_cookie ))); | |||
| 4219 | ||||
| 4220 | pf_unload_vnet_purge(); | |||
| 4221 | ||||
| 4222 | pf_normalize_cleanup(); | |||
| 4223 | PF_RULES_WLOCK()_rm_wlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 4223); | |||
| 4224 | pfi_cleanup_vnet(); | |||
| 4225 | PF_RULES_WUNLOCK()_rm_wunlock_debug((&pf_rules_lock), "/root/freebsd/sys/netpfil/pf/pf_ioctl.c" , 4225); | |||
| 4226 | pfr_cleanup(); | |||
| 4227 | pf_osfp_flush(); | |||
| 4228 | pf_cleanup(); | |||
| 4229 | if (IS_DEFAULT_VNET(curvnet)(((__curthread())->td_vnet) == vnet0)) | |||
| 4230 | pf_mtag_cleanup(); | |||
| 4231 | } | |||
| 4232 | ||||
| 4233 | static void | |||
| 4234 | pf_unload(void) | |||
| 4235 | { | |||
| 4236 | ||||
| 4237 | sx_xlock(&pf_end_lock)(void)_sx_xlock(((&pf_end_lock)), 0, ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c" ), (4237)); | |||
| 4238 | pf_end_threads = 1; | |||
| 4239 | while (pf_end_threads < 2) { | |||
| 4240 | wakeup_one(pf_purge_thread); | |||
| 4241 | sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0)_sleep((pf_purge_proc), &(&pf_end_lock)->lock_object , (0), ("pftmo"), tick_sbt * (0), 0, 0x0100); | |||
| 4242 | } | |||
| 4243 | sx_xunlock(&pf_end_lock)_sx_xunlock(((&pf_end_lock)), ("/root/freebsd/sys/netpfil/pf/pf_ioctl.c" ), (4243)); | |||
| 4244 | ||||
| 4245 | if (pf_dev != NULL((void *)0)) | |||
| 4246 | destroy_dev(pf_dev); | |||
| 4247 | ||||
| 4248 | pfi_cleanup(); | |||
| 4249 | ||||
| 4250 | rm_destroy(&pf_rules_lock); | |||
| 4251 | sx_destroy(&pf_ioctl_lock); | |||
| 4252 | sx_destroy(&pf_end_lock); | |||
| 4253 | } | |||
| 4254 | ||||
| 4255 | static void | |||
| 4256 | vnet_pf_init(void *unused __unused__attribute__((__unused__))) | |||
| 4257 | { | |||
| 4258 | ||||
| 4259 | pf_load_vnet(); | |||
| 4260 | } | |||
| 4261 | VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,static struct vnet_sysinit vnet_pf_init_vnet_init = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_init , (((void *)0)) }; static struct sysinit vnet_init_vnet_pf_init_sys_init = { SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, (sysinit_cfunc_t) (sysinit_nfunc_t)vnet_register_sysinit, ((void *)(&vnet_pf_init_vnet_init )) }; __asm__(".globl " "__start_set_sysinit_set"); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_vnet_init_vnet_pf_init_sys_init __attribute__((__section__("set_" "sysinit_set"))) __attribute__ ((__used__)) = &(vnet_init_vnet_pf_init_sys_init); static struct sysinit vnet_init_vnet_pf_init_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_deregister_sysinit , ((void *)(&vnet_pf_init_vnet_init)) }; __asm__(".globl " "__start_set_sysuninit_set"); __asm__(".globl " "__stop_set_sysuninit_set" ); static void const * __set_sysuninit_set_sym_vnet_init_vnet_pf_init_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(vnet_init_vnet_pf_init_sys_uninit) | |||
| 4262 | vnet_pf_init, NULL)static struct vnet_sysinit vnet_pf_init_vnet_init = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_init , (((void *)0)) }; static struct sysinit vnet_init_vnet_pf_init_sys_init = { SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, (sysinit_cfunc_t) (sysinit_nfunc_t)vnet_register_sysinit, ((void *)(&vnet_pf_init_vnet_init )) }; __asm__(".globl " "__start_set_sysinit_set"); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_vnet_init_vnet_pf_init_sys_init __attribute__((__section__("set_" "sysinit_set"))) __attribute__ ((__used__)) = &(vnet_init_vnet_pf_init_sys_init); static struct sysinit vnet_init_vnet_pf_init_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_deregister_sysinit , ((void *)(&vnet_pf_init_vnet_init)) }; __asm__(".globl " "__start_set_sysuninit_set"); __asm__(".globl " "__stop_set_sysuninit_set" ); static void const * __set_sysuninit_set_sym_vnet_init_vnet_pf_init_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(vnet_init_vnet_pf_init_sys_uninit); | |||
| 4263 | ||||
| 4264 | static void | |||
| 4265 | vnet_pf_uninit(const void *unused __unused__attribute__((__unused__))) | |||
| 4266 | { | |||
| 4267 | ||||
| 4268 | pf_unload_vnet(); | |||
| 4269 | } | |||
| 4270 | SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL)static struct sysinit pf_unload_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_SECOND, (sysinit_cfunc_t)(sysinit_nfunc_t)pf_unload , ((void *)(((void *)0))) }; __asm__(".globl " "__start_set_sysuninit_set" ); __asm__(".globl " "__stop_set_sysuninit_set"); static void const * __set_sysuninit_set_sym_pf_unload_sys_uninit __attribute__ ((__section__("set_" "sysuninit_set"))) __attribute__((__used__ )) = &(pf_unload_sys_uninit); | |||
| 4271 | VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,static struct vnet_sysinit vnet_pf_uninit_vnet_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_uninit , (((void *)0)) }; static struct sysinit vnet_uninit_vnet_pf_uninit_sys_init = { SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, (sysinit_cfunc_t) (sysinit_nfunc_t)vnet_register_sysuninit, ((void *)(&vnet_pf_uninit_vnet_uninit )) }; __asm__(".globl " "__start_set_sysinit_set"); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_vnet_uninit_vnet_pf_uninit_sys_init __attribute__((__section__("set_" "sysinit_set"))) __attribute__ ((__used__)) = &(vnet_uninit_vnet_pf_uninit_sys_init); static struct sysinit vnet_uninit_vnet_pf_uninit_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_deregister_sysuninit , ((void *)(&vnet_pf_uninit_vnet_uninit)) }; __asm__(".globl " "__start_set_sysuninit_set"); __asm__(".globl " "__stop_set_sysuninit_set" ); static void const * __set_sysuninit_set_sym_vnet_uninit_vnet_pf_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(vnet_uninit_vnet_pf_uninit_sys_uninit) | |||
| 4272 | vnet_pf_uninit, NULL)static struct vnet_sysinit vnet_pf_uninit_vnet_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_uninit , (((void *)0)) }; static struct sysinit vnet_uninit_vnet_pf_uninit_sys_init = { SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, (sysinit_cfunc_t) (sysinit_nfunc_t)vnet_register_sysuninit, ((void *)(&vnet_pf_uninit_vnet_uninit )) }; __asm__(".globl " "__start_set_sysinit_set"); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_vnet_uninit_vnet_pf_uninit_sys_init __attribute__((__section__("set_" "sysinit_set"))) __attribute__ ((__used__)) = &(vnet_uninit_vnet_pf_uninit_sys_init); static struct sysinit vnet_uninit_vnet_pf_uninit_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_deregister_sysuninit , ((void *)(&vnet_pf_uninit_vnet_uninit)) }; __asm__(".globl " "__start_set_sysuninit_set"); __asm__(".globl " "__stop_set_sysuninit_set" ); static void const * __set_sysuninit_set_sym_vnet_uninit_vnet_pf_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(vnet_uninit_vnet_pf_uninit_sys_uninit); | |||
| 4273 | ||||
| 4274 | ||||
| 4275 | static int | |||
| 4276 | pf_modevent(module_t mod, int type, void *data) | |||
| 4277 | { | |||
| 4278 | int error = 0; | |||
| 4279 | ||||
| 4280 | switch(type) { | |||
| 4281 | case MOD_LOAD: | |||
| 4282 | error = pf_load(); | |||
| 4283 | break; | |||
| 4284 | case MOD_UNLOAD: | |||
| 4285 | /* Handled in SYSUNINIT(pf_unload) to ensure it's done after | |||
| 4286 | * the vnet_pf_uninit()s */ | |||
| 4287 | break; | |||
| 4288 | default: | |||
| 4289 | error = EINVAL22; | |||
| 4290 | break; | |||
| 4291 | } | |||
| 4292 | ||||
| 4293 | return (error); | |||
| 4294 | } | |||
| 4295 | ||||
| 4296 | static moduledata_t pf_mod = { | |||
| 4297 | "pf", | |||
| 4298 | pf_modevent, | |||
| 4299 | 0 | |||
| 4300 | }; | |||
| 4301 | ||||
| 4302 | DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND)static struct mod_depend _pf_depend_on_kernel __attribute__(( __section__(".data"))) = { 1300006, 1300006, 1300006 }; static struct mod_metadata _mod_metadata_md_pf_on_kernel = { 1, 1, & _pf_depend_on_kernel, "kernel" }; __asm__(".globl " "__start_set_modmetadata_set" ); __asm__(".globl " "__stop_set_modmetadata_set"); static void const * const __set_modmetadata_set_sym__mod_metadata_md_pf_on_kernel __attribute__((__section__("set_" "modmetadata_set"))) __attribute__ ((__used__)) = &(_mod_metadata_md_pf_on_kernel); static struct mod_metadata _mod_metadata_md_pf = { 1, 2, &pf_mod, "pf" }; __asm__(".globl " "__start_set_modmetadata_set"); __asm__ (".globl " "__stop_set_modmetadata_set"); static void const * const __set_modmetadata_set_sym__mod_metadata_md_pf __attribute__ ((__section__("set_" "modmetadata_set"))) __attribute__((__used__ )) = &(_mod_metadata_md_pf); static struct sysinit pfmodule_sys_init = { SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, (sysinit_cfunc_t )(sysinit_nfunc_t)module_register_init, ((void *)(&pf_mod )) }; __asm__(".globl " "__start_set_sysinit_set"); __asm__(".globl " "__stop_set_sysinit_set"); static void const * __set_sysinit_set_sym_pfmodule_sys_init __attribute__((__section__("set_" "sysinit_set"))) __attribute__ ((__used__)) = &(pfmodule_sys_init); struct __hack; | |||
| 4303 | MODULE_VERSION(pf, PF_MODVER)static struct mod_version _pf_version __attribute__((__section__ (".data"))) = { 1 }; static struct mod_metadata _mod_metadata_pf_version = { 1, 3, &_pf_version, "pf" }; __asm__(".globl " "__start_set_modmetadata_set" ); __asm__(".globl " "__stop_set_modmetadata_set"); static void const * const __set_modmetadata_set_sym__mod_metadata_pf_version __attribute__((__section__("set_" "modmetadata_set"))) __attribute__ ((__used__)) = &(_mod_metadata_pf_version); |