File: | netpfil/pf/pf_ioctl.c |
Warning: | line 3624, column 11 Copies out a struct with uncleared padding (>= 6 bytes) |
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); |