File: | modules/pf/../../netpfil/pf/pf_ioctl.c |
Warning: | line 3238, column 11 Copies out a struct with uncleared padding (>= 4 bytes) |
1 | /*- | |||
2 | * Copyright (c) 2001 Daniel Hartmeier | |||
3 | * Copyright (c) 2002,2003 Henning Brauer | |||
4 | * Copyright (c) 2012 Gleb Smirnoff <[email protected]> | |||
5 | * All rights reserved. | |||
6 | * | |||
7 | * Redistribution and use in source and binary forms, with or without | |||
8 | * modification, are permitted provided that the following conditions | |||
9 | * are met: | |||
10 | * | |||
11 | * - Redistributions of source code must retain the above copyright | |||
12 | * notice, this list of conditions and the following disclaimer. | |||
13 | * - Redistributions in binary form must reproduce the above | |||
14 | * copyright notice, this list of conditions and the following | |||
15 | * disclaimer in the documentation and/or other materials provided | |||
16 | * with the distribution. | |||
17 | * | |||
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |||
21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |||
22 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |||
24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |||
28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
29 | * POSSIBILITY OF SUCH DAMAGE. | |||
30 | * | |||
31 | * Effort sponsored in part by the Defense Advanced Research Projects | |||
32 | * Agency (DARPA) and Air Force Research Laboratory, Air Force | |||
33 | * Materiel Command, USAF, under agreement number F30602-01-2-0537. | |||
34 | * | |||
35 | * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $ | |||
36 | */ | |||
37 | ||||
38 | #include <sys/cdefs.h> | |||
39 | __FBSDID("$FreeBSD: releng/11.0/sys/netpfil/pf/pf_ioctl.c 302173 2016-06-24 11:53:12Z bz $")__asm__(".ident\t\"" "$FreeBSD: releng/11.0/sys/netpfil/pf/pf_ioctl.c 302173 2016-06-24 11:53:12Z bz $" "\""); | |||
40 | ||||
41 | #include "opt_inet.h" | |||
42 | #include "opt_inet6.h" | |||
43 | #include "opt_bpf.h" | |||
44 | #include "opt_pf.h" | |||
45 | ||||
46 | #include <sys/param.h> | |||
47 | #include <sys/bus.h> | |||
48 | #include <sys/conf.h> | |||
49 | #include <sys/endian.h> | |||
50 | #include <sys/fcntl.h> | |||
51 | #include <sys/filio.h> | |||
52 | #include <sys/interrupt.h> | |||
53 | #include <sys/jail.h> | |||
54 | #include <sys/kernel.h> | |||
55 | #include <sys/kthread.h> | |||
56 | #include <sys/lock.h> | |||
57 | #include <sys/mbuf.h> | |||
58 | #include <sys/module.h> | |||
59 | #include <sys/proc.h> | |||
60 | #include <sys/rwlock.h> | |||
61 | #include <sys/smp.h> | |||
62 | #include <sys/socket.h> | |||
63 | #include <sys/sysctl.h> | |||
64 | #include <sys/md5.h> | |||
65 | #include <sys/ucred.h> | |||
66 | ||||
67 | #include <net/if.h> | |||
68 | #include <net/if_var.h> | |||
69 | #include <net/vnet.h> | |||
70 | #include <net/route.h> | |||
71 | #include <net/pfil.h> | |||
72 | #include <net/pfvar.h> | |||
73 | #include <net/if_pfsync.h> | |||
74 | #include <net/if_pflog.h> | |||
75 | ||||
76 | #include <netinet/in.h> | |||
77 | #include <netinet/ip.h> | |||
78 | #include <netinet/ip_var.h> | |||
79 | #include <netinet6/ip6_var.h> | |||
80 | #include <netinet/ip_icmp.h> | |||
81 | ||||
82 | #ifdef INET61 | |||
83 | #include <netinet/ip6.h> | |||
84 | #endif /* INET6 */ | |||
85 | ||||
86 | #ifdef ALTQ | |||
87 | #include <net/altq/altq.h> | |||
88 | #endif | |||
89 | ||||
90 | static struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t, | |||
91 | u_int8_t, u_int8_t, u_int8_t); | |||
92 | ||||
93 | static void pf_mv_pool(struct pf_palist *, struct pf_palist *); | |||
94 | static void pf_empty_pool(struct pf_palist *); | |||
95 | static int pfioctl(struct cdev *, u_long, caddr_t, int, | |||
96 | struct thread *); | |||
97 | #ifdef ALTQ | |||
98 | static int pf_begin_altq(u_int32_t *); | |||
99 | static int pf_rollback_altq(u_int32_t); | |||
100 | static int pf_commit_altq(u_int32_t); | |||
101 | static int pf_enable_altq(struct pf_altq *); | |||
102 | static int pf_disable_altq(struct pf_altq *); | |||
103 | static u_int32_t pf_qname2qid(char *); | |||
104 | static void pf_qid_unref(u_int32_t); | |||
105 | #endif /* ALTQ */ | |||
106 | static int pf_begin_rules(u_int32_t *, int, const char *); | |||
107 | static int pf_rollback_rules(u_int32_t, int, char *); | |||
108 | static int pf_setup_pfsync_matching(struct pf_ruleset *); | |||
109 | static void pf_hash_rule(MD5_CTX *, struct pf_rule *); | |||
110 | static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); | |||
111 | static int pf_commit_rules(u_int32_t, int, char *); | |||
112 | static int pf_addr_setup(struct pf_ruleset *, | |||
113 | struct pf_addr_wrap *, sa_family_t); | |||
114 | static void pf_addr_copyout(struct pf_addr_wrap *); | |||
115 | ||||
116 | VNET_DEFINE(struct pf_rule, pf_default_rule)struct pf_rule pf_default_rule; | |||
117 | ||||
118 | #ifdef ALTQ | |||
119 | static VNET_DEFINE(int, pf_altq_running)int pf_altq_running; | |||
120 | #define V_pf_altq_running VNET(pf_altq_running)(pf_altq_running) | |||
121 | #endif | |||
122 | ||||
123 | #define TAGID_MAX50000 50000 | |||
124 | struct pf_tagname { | |||
125 | TAILQ_ENTRY(pf_tagname)struct { struct pf_tagname *tqe_next; struct pf_tagname **tqe_prev ; } entries; | |||
126 | char name[PF_TAG_NAME_SIZE64]; | |||
127 | uint16_t tag; | |||
128 | int ref; | |||
129 | }; | |||
130 | ||||
131 | TAILQ_HEAD(pf_tags, pf_tagname)struct pf_tags { struct pf_tagname *tqh_first; struct pf_tagname **tqh_last; }; | |||
132 | #define V_pf_tags(pf_tags) VNET(pf_tags)(pf_tags) | |||
133 | VNET_DEFINE(struct pf_tags, pf_tags)struct pf_tags pf_tags; | |||
134 | #define V_pf_qids(pf_qids) VNET(pf_qids)(pf_qids) | |||
135 | VNET_DEFINE(struct pf_tags, pf_qids)struct pf_tags pf_qids; | |||
136 | 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 * 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 * const __set_sysuninit_set_sym_M_PFTAG_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(M_PFTAG_uninit_sys_uninit); | |||
137 | 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 * 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 * const __set_sysuninit_set_sym_M_PFALTQ_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(M_PFALTQ_uninit_sys_uninit); | |||
138 | 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 * 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 * const __set_sysuninit_set_sym_M_PFRULE_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(M_PFRULE_uninit_sys_uninit); | |||
139 | ||||
140 | #if (PF_QNAME_SIZE64 != PF_TAG_NAME_SIZE64) | |||
141 | #error PF_QNAME_SIZE64 must be equal to PF_TAG_NAME_SIZE64 | |||
142 | #endif | |||
143 | ||||
144 | static u_int16_t tagname2tag(struct pf_tags *, char *); | |||
145 | static u_int16_t pf_tagname2tag(char *); | |||
146 | static void tag_unref(struct pf_tags *, u_int16_t); | |||
147 | ||||
148 | #define DPFPRINTF(n, x)if ((pf_status).debug >= (n)) printf x if (V_pf_status(pf_status).debug >= (n)) printf x | |||
149 | ||||
150 | struct cdev *pf_dev; | |||
151 | ||||
152 | /* | |||
153 | * XXX - These are new and need to be checked when moveing to a new version | |||
154 | */ | |||
155 | static void pf_clear_states(void); | |||
156 | static int pf_clear_tables(void); | |||
157 | static void pf_clear_srcnodes(struct pf_src_node *); | |||
158 | static void pf_kill_srcnodes(struct pfioc_src_node_kill *); | |||
159 | static void pf_tbladdr_copyout(struct pf_addr_wrap *); | |||
160 | ||||
161 | /* | |||
162 | * Wrapper functions for pfil(9) hooks | |||
163 | */ | |||
164 | #ifdef INET1 | |||
165 | static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
166 | int dir, struct inpcb *inp); | |||
167 | static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
168 | int dir, struct inpcb *inp); | |||
169 | #endif | |||
170 | #ifdef INET61 | |||
171 | static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
172 | int dir, struct inpcb *inp); | |||
173 | static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, | |||
174 | int dir, struct inpcb *inp); | |||
175 | #endif | |||
176 | ||||
177 | static int hook_pf(void); | |||
178 | static int dehook_pf(void); | |||
179 | static int shutdown_pf(void); | |||
180 | static int pf_load(void); | |||
181 | static int pf_unload(void); | |||
182 | ||||
183 | static struct cdevsw pf_cdevsw = { | |||
184 | .d_ioctl = pfioctl, | |||
185 | .d_name = PF_NAME"pf", | |||
186 | .d_version = D_VERSION0x17122009, | |||
187 | }; | |||
188 | ||||
189 | static volatile VNET_DEFINE(int, pf_pfil_hooked)int pf_pfil_hooked; | |||
190 | #define V_pf_pfil_hooked(pf_pfil_hooked) VNET(pf_pfil_hooked)(pf_pfil_hooked) | |||
191 | ||||
192 | /* | |||
193 | * We need a flag that is neither hooked nor running to know when | |||
194 | * the VNET is "valid". We primarily need this to control (global) | |||
195 | * external event, e.g., eventhandlers. | |||
196 | */ | |||
197 | VNET_DEFINE(int, pf_vnet_active)int pf_vnet_active; | |||
198 | #define V_pf_vnet_active(pf_vnet_active) VNET(pf_vnet_active)(pf_vnet_active) | |||
199 | ||||
200 | int pf_end_threads; | |||
201 | ||||
202 | struct rwlock pf_rules_lock; | |||
203 | struct sx pf_ioctl_lock; | |||
204 | ||||
205 | /* pfsync */ | |||
206 | pfsync_state_import_t *pfsync_state_import_ptr = NULL((void *)0); | |||
207 | pfsync_insert_state_t *pfsync_insert_state_ptr = NULL((void *)0); | |||
208 | pfsync_update_state_t *pfsync_update_state_ptr = NULL((void *)0); | |||
209 | pfsync_delete_state_t *pfsync_delete_state_ptr = NULL((void *)0); | |||
210 | pfsync_clear_states_t *pfsync_clear_states_ptr = NULL((void *)0); | |||
211 | pfsync_defer_t *pfsync_defer_ptr = NULL((void *)0); | |||
212 | /* pflog */ | |||
213 | pflog_packet_t *pflog_packet_ptr = NULL((void *)0); | |||
214 | ||||
215 | static void | |||
216 | pfattach_vnet(void) | |||
217 | { | |||
218 | u_int32_t *my_timeout = V_pf_default_rule(pf_default_rule).timeout; | |||
219 | ||||
220 | pf_initialize(); | |||
221 | pfr_initialize(); | |||
222 | pfi_initialize_vnet(); | |||
223 | pf_normalize_init(); | |||
224 | ||||
225 | V_pf_limits(pf_limits)[PF_LIMIT_STATES].limit = PFSTATE_HIWAT10000; | |||
226 | V_pf_limits(pf_limits)[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT10000; | |||
227 | ||||
228 | RB_INIT(&V_pf_anchors)do { (&(pf_anchors))->rbh_root = ((void *)0); } while ( 0); | |||
229 | pf_init_ruleset(&pf_main_ruleset(pf_main_anchor).ruleset); | |||
230 | ||||
231 | /* default rule should never be garbage collected */ | |||
232 | V_pf_default_rule(pf_default_rule).entries.tqe_prev = &V_pf_default_rule(pf_default_rule).entries.tqe_next; | |||
233 | #ifdef PF_DEFAULT_TO_DROP | |||
234 | V_pf_default_rule(pf_default_rule).action = PF_DROP; | |||
235 | #else | |||
236 | V_pf_default_rule(pf_default_rule).action = PF_PASS; | |||
237 | #endif | |||
238 | V_pf_default_rule(pf_default_rule).nr = -1; | |||
239 | V_pf_default_rule(pf_default_rule).rtableid = -1; | |||
240 | ||||
241 | V_pf_default_rule(pf_default_rule).states_cur = counter_u64_alloc(M_WAITOK0x0002); | |||
242 | V_pf_default_rule(pf_default_rule).states_tot = counter_u64_alloc(M_WAITOK0x0002); | |||
243 | V_pf_default_rule(pf_default_rule).src_nodes = counter_u64_alloc(M_WAITOK0x0002); | |||
244 | ||||
245 | /* initialize default timeouts */ | |||
246 | my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL120; | |||
247 | my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL30; | |||
248 | my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL24*60*60; | |||
249 | my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL15 * 60; | |||
250 | my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL45; | |||
251 | my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL90; | |||
252 | my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL60; | |||
253 | my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL30; | |||
254 | my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL60; | |||
255 | my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL20; | |||
256 | my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL10; | |||
257 | my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL60; | |||
258 | my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL30; | |||
259 | my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL60; | |||
260 | my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL30; | |||
261 | my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL10; | |||
262 | my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL0; | |||
263 | my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL30; | |||
264 | my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START6000; | |||
265 | my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END12000; | |||
266 | ||||
267 | bzero(&V_pf_status(pf_status), sizeof(V_pf_status(pf_status))); | |||
268 | V_pf_status(pf_status).debug = PF_DEBUG_URGENT; | |||
269 | ||||
270 | V_pf_pfil_hooked(pf_pfil_hooked) = 0; | |||
271 | ||||
272 | /* XXX do our best to avoid a conflict */ | |||
273 | V_pf_status(pf_status).hostid = arc4random(); | |||
274 | ||||
275 | for (int i = 0; i < PFRES_MAX16; i++) | |||
276 | V_pf_status(pf_status).counters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
277 | for (int i = 0; i < LCNT_MAX7; i++) | |||
278 | V_pf_status(pf_status).lcounters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
279 | for (int i = 0; i < FCNT_MAX3; i++) | |||
280 | V_pf_status(pf_status).fcounters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
281 | for (int i = 0; i < SCNT_MAX3; i++) | |||
282 | V_pf_status(pf_status).scounters[i] = counter_u64_alloc(M_WAITOK0x0002); | |||
283 | ||||
284 | if (swi_add(NULL((void *)0), "pf send", pf_intr, curvnet((void *)0), SWI_NET1, | |||
285 | INTR_MPSAFE, &V_pf_swi_cookie(pf_swi_cookie)) != 0) | |||
286 | /* XXXGL: leaked all above. */ | |||
287 | return; | |||
288 | } | |||
289 | ||||
290 | ||||
291 | static struct pf_pool * | |||
292 | pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action, | |||
293 | u_int32_t rule_number, u_int8_t r_last, u_int8_t active, | |||
294 | u_int8_t check_ticket) | |||
295 | { | |||
296 | struct pf_ruleset *ruleset; | |||
297 | struct pf_rule *rule; | |||
298 | int rs_num; | |||
299 | ||||
300 | ruleset = pf_find_ruleset(anchor); | |||
301 | if (ruleset == NULL((void *)0)) | |||
302 | return (NULL((void *)0)); | |||
303 | rs_num = pf_get_ruleset_number(rule_action); | |||
304 | if (rs_num >= PF_RULESET_MAX) | |||
305 | return (NULL((void *)0)); | |||
306 | if (active) { | |||
307 | if (check_ticket && ticket != | |||
308 | ruleset->rules[rs_num].active.ticket) | |||
309 | return (NULL((void *)0)); | |||
310 | if (r_last) | |||
311 | rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)) | |||
312 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)); | |||
313 | else | |||
314 | rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
315 | } else { | |||
316 | if (check_ticket && ticket != | |||
317 | ruleset->rules[rs_num].inactive.ticket) | |||
318 | return (NULL((void *)0)); | |||
319 | if (r_last) | |||
320 | rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)) | |||
321 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)); | |||
322 | else | |||
323 | rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr)((ruleset->rules[rs_num].inactive.ptr)->tqh_first); | |||
324 | } | |||
325 | if (!r_last) { | |||
326 | while ((rule != NULL((void *)0)) && (rule->nr != rule_number)) | |||
327 | rule = TAILQ_NEXT(rule, entries)((rule)->entries.tqe_next); | |||
328 | } | |||
329 | if (rule == NULL((void *)0)) | |||
330 | return (NULL((void *)0)); | |||
331 | ||||
332 | return (&rule->rpool); | |||
333 | } | |||
334 | ||||
335 | static void | |||
336 | pf_mv_pool(struct pf_palist *poola, struct pf_palist *poolb) | |||
337 | { | |||
338 | struct pf_pooladdr *mv_pool_pa; | |||
339 | ||||
340 | while ((mv_pool_pa = TAILQ_FIRST(poola)((poola)->tqh_first)) != NULL((void *)0)) { | |||
341 | TAILQ_REMOVE(poola, mv_pool_pa, entries)do { ; ; ; ; 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); | |||
342 | TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries)do { ; (((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); | |||
343 | } | |||
344 | } | |||
345 | ||||
346 | static void | |||
347 | pf_empty_pool(struct pf_palist *poola) | |||
348 | { | |||
349 | struct pf_pooladdr *pa; | |||
350 | ||||
351 | while ((pa = TAILQ_FIRST(poola)((poola)->tqh_first)) != NULL((void *)0)) { | |||
352 | switch (pa->addr.type) { | |||
353 | case PF_ADDR_DYNIFTL: | |||
354 | pfi_dynaddr_remove(pa->addr.p.dyn); | |||
355 | break; | |||
356 | case PF_ADDR_TABLE: | |||
357 | /* XXX: this could be unfinished pooladdr on pabuf */ | |||
358 | if (pa->addr.p.tbl != NULL((void *)0)) | |||
359 | pfr_detach_table(pa->addr.p.tbl); | |||
360 | break; | |||
361 | } | |||
362 | if (pa->kif) | |||
363 | pfi_kif_unref(pa->kif); | |||
364 | TAILQ_REMOVE(poola, pa, entries)do { ; ; ; ; 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); | |||
365 | free(pa, M_PFRULE); | |||
366 | } | |||
367 | } | |||
368 | ||||
369 | static void | |||
370 | pf_unlink_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) | |||
371 | { | |||
372 | ||||
373 | PF_RULES_WASSERT(); | |||
374 | ||||
375 | TAILQ_REMOVE(rulequeue, rule, entries)do { ; ; ; ; 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); | |||
376 | ||||
377 | PF_UNLNKDRULES_LOCK()__mtx_lock_flags(&((((&pf_unlnkdrules_mtx))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (377)); | |||
378 | rule->rule_flag |= PFRULE_REFS0x0080; | |||
379 | TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries)do { ; (((rule))->entries.tqe_next) = ((void *)0); (rule)-> entries.tqe_prev = (&(pf_unlinked_rules))->tqh_last; * (&(pf_unlinked_rules))->tqh_last = (rule); (&(pf_unlinked_rules ))->tqh_last = &(((rule))->entries.tqe_next); ; ; } while (0); | |||
380 | PF_UNLNKDRULES_UNLOCK()__mtx_unlock_flags(&((((&pf_unlnkdrules_mtx))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (380)); | |||
381 | } | |||
382 | ||||
383 | void | |||
384 | pf_free_rule(struct pf_rule *rule) | |||
385 | { | |||
386 | ||||
387 | PF_RULES_WASSERT(); | |||
388 | ||||
389 | if (rule->tag) | |||
390 | tag_unref(&V_pf_tags(pf_tags), rule->tag); | |||
391 | if (rule->match_tag) | |||
392 | tag_unref(&V_pf_tags(pf_tags), rule->match_tag); | |||
393 | #ifdef ALTQ | |||
394 | if (rule->pqid != rule->qid) | |||
395 | pf_qid_unref(rule->pqid); | |||
396 | pf_qid_unref(rule->qid); | |||
397 | #endif | |||
398 | switch (rule->src.addr.type) { | |||
399 | case PF_ADDR_DYNIFTL: | |||
400 | pfi_dynaddr_remove(rule->src.addr.p.dyn); | |||
401 | break; | |||
402 | case PF_ADDR_TABLE: | |||
403 | pfr_detach_table(rule->src.addr.p.tbl); | |||
404 | break; | |||
405 | } | |||
406 | switch (rule->dst.addr.type) { | |||
407 | case PF_ADDR_DYNIFTL: | |||
408 | pfi_dynaddr_remove(rule->dst.addr.p.dyn); | |||
409 | break; | |||
410 | case PF_ADDR_TABLE: | |||
411 | pfr_detach_table(rule->dst.addr.p.tbl); | |||
412 | break; | |||
413 | } | |||
414 | if (rule->overload_tbl) | |||
415 | pfr_detach_table(rule->overload_tbl); | |||
416 | if (rule->kif) | |||
417 | pfi_kif_unref(rule->kif); | |||
418 | pf_anchor_remove(rule); | |||
419 | pf_empty_pool(&rule->rpool.list); | |||
420 | counter_u64_free(rule->states_cur); | |||
421 | counter_u64_free(rule->states_tot); | |||
422 | counter_u64_free(rule->src_nodes); | |||
423 | free(rule, M_PFRULE); | |||
424 | } | |||
425 | ||||
426 | static u_int16_t | |||
427 | tagname2tag(struct pf_tags *head, char *tagname) | |||
428 | { | |||
429 | struct pf_tagname *tag, *p = NULL((void *)0); | |||
430 | u_int16_t new_tagid = 1; | |||
431 | ||||
432 | PF_RULES_WASSERT(); | |||
433 | ||||
434 | TAILQ_FOREACH(tag, head, entries)for ((tag) = (((head))->tqh_first); (tag); (tag) = (((tag) )->entries.tqe_next)) | |||
435 | if (strcmp(tagname, tag->name) == 0) { | |||
436 | tag->ref++; | |||
437 | return (tag->tag); | |||
438 | } | |||
439 | ||||
440 | /* | |||
441 | * to avoid fragmentation, we do a linear search from the beginning | |||
442 | * and take the first free slot we find. if there is none or the list | |||
443 | * is empty, append a new entry at the end. | |||
444 | */ | |||
445 | ||||
446 | /* new entry */ | |||
447 | if (!TAILQ_EMPTY(head)((head)->tqh_first == ((void *)0))) | |||
448 | for (p = TAILQ_FIRST(head)((head)->tqh_first); p != NULL((void *)0) && | |||
449 | p->tag == new_tagid; p = TAILQ_NEXT(p, entries)((p)->entries.tqe_next)) | |||
450 | new_tagid = p->tag + 1; | |||
451 | ||||
452 | if (new_tagid > TAGID_MAX50000) | |||
453 | return (0); | |||
454 | ||||
455 | /* allocate and fill new struct pf_tagname */ | |||
456 | tag = malloc(sizeof(*tag), M_PFTAG, M_NOWAIT0x0001|M_ZERO0x0100); | |||
457 | if (tag == NULL((void *)0)) | |||
458 | return (0); | |||
459 | strlcpy(tag->name, tagname, sizeof(tag->name)); | |||
460 | tag->tag = new_tagid; | |||
461 | tag->ref++; | |||
462 | ||||
463 | if (p != NULL((void *)0)) /* insert new entry before p */ | |||
464 | TAILQ_INSERT_BEFORE(p, tag, entries)do { ; (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); | |||
465 | else /* either list empty or no free slot in between */ | |||
466 | TAILQ_INSERT_TAIL(head, tag, entries)do { ; (((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); | |||
467 | ||||
468 | return (tag->tag); | |||
469 | } | |||
470 | ||||
471 | static void | |||
472 | tag_unref(struct pf_tags *head, u_int16_t tag) | |||
473 | { | |||
474 | struct pf_tagname *p, *next; | |||
475 | ||||
476 | PF_RULES_WASSERT(); | |||
477 | ||||
478 | for (p = TAILQ_FIRST(head)((head)->tqh_first); p != NULL((void *)0); p = next) { | |||
479 | next = TAILQ_NEXT(p, entries)((p)->entries.tqe_next); | |||
480 | if (tag == p->tag) { | |||
481 | if (--p->ref == 0) { | |||
482 | TAILQ_REMOVE(head, p, entries)do { ; ; ; ; 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); | |||
483 | free(p, M_PFTAG); | |||
484 | } | |||
485 | break; | |||
486 | } | |||
487 | } | |||
488 | } | |||
489 | ||||
490 | static u_int16_t | |||
491 | pf_tagname2tag(char *tagname) | |||
492 | { | |||
493 | return (tagname2tag(&V_pf_tags(pf_tags), tagname)); | |||
494 | } | |||
495 | ||||
496 | #ifdef ALTQ | |||
497 | static u_int32_t | |||
498 | pf_qname2qid(char *qname) | |||
499 | { | |||
500 | return ((u_int32_t)tagname2tag(&V_pf_qids(pf_qids), qname)); | |||
501 | } | |||
502 | ||||
503 | static void | |||
504 | pf_qid_unref(u_int32_t qid) | |||
505 | { | |||
506 | tag_unref(&V_pf_qids(pf_qids), (u_int16_t)qid); | |||
507 | } | |||
508 | ||||
509 | static int | |||
510 | pf_begin_altq(u_int32_t *ticket) | |||
511 | { | |||
512 | struct pf_altq *altq; | |||
513 | int error = 0; | |||
514 | ||||
515 | PF_RULES_WASSERT(); | |||
516 | ||||
517 | /* Purge the old altq list */ | |||
518 | while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)(((pf_altqs_inactive))->tqh_first)) != NULL((void *)0)) { | |||
519 | TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries)do { ; ; ; ; if (((((altq))->entries.tqe_next)) != ((void * )0)) (((altq))->entries.tqe_next)->entries.tqe_prev = ( altq)->entries.tqe_prev; else { ((pf_altqs_inactive))-> tqh_last = (altq)->entries.tqe_prev; ; } *(altq)->entries .tqe_prev = (((altq))->entries.tqe_next); ; ; ; } while (0 ); | |||
520 | if (altq->qname[0] == 0 && | |||
521 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
522 | /* detach and destroy the discipline */ | |||
523 | error = altq_remove(altq); | |||
524 | } else | |||
525 | pf_qid_unref(altq->qid); | |||
526 | free(altq, M_PFALTQ); | |||
527 | } | |||
528 | if (error) | |||
529 | return (error); | |||
530 | *ticket = ++V_ticket_altqs_inactive(ticket_altqs_inactive); | |||
531 | V_altqs_inactive_open(altqs_inactive_open) = 1; | |||
532 | return (0); | |||
533 | } | |||
534 | ||||
535 | static int | |||
536 | pf_rollback_altq(u_int32_t ticket) | |||
537 | { | |||
538 | struct pf_altq *altq; | |||
539 | int error = 0; | |||
540 | ||||
541 | PF_RULES_WASSERT(); | |||
542 | ||||
543 | if (!V_altqs_inactive_open(altqs_inactive_open) || ticket != V_ticket_altqs_inactive(ticket_altqs_inactive)) | |||
544 | return (0); | |||
545 | /* Purge the old altq list */ | |||
546 | while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)(((pf_altqs_inactive))->tqh_first)) != NULL((void *)0)) { | |||
547 | TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries)do { ; ; ; ; if (((((altq))->entries.tqe_next)) != ((void * )0)) (((altq))->entries.tqe_next)->entries.tqe_prev = ( altq)->entries.tqe_prev; else { ((pf_altqs_inactive))-> tqh_last = (altq)->entries.tqe_prev; ; } *(altq)->entries .tqe_prev = (((altq))->entries.tqe_next); ; ; ; } while (0 ); | |||
548 | if (altq->qname[0] == 0 && | |||
549 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
550 | /* detach and destroy the discipline */ | |||
551 | error = altq_remove(altq); | |||
552 | } else | |||
553 | pf_qid_unref(altq->qid); | |||
554 | free(altq, M_PFALTQ); | |||
555 | } | |||
556 | V_altqs_inactive_open(altqs_inactive_open) = 0; | |||
557 | return (error); | |||
558 | } | |||
559 | ||||
560 | static int | |||
561 | pf_commit_altq(u_int32_t ticket) | |||
562 | { | |||
563 | struct pf_altqqueue *old_altqs; | |||
564 | struct pf_altq *altq; | |||
565 | int err, error = 0; | |||
566 | ||||
567 | PF_RULES_WASSERT(); | |||
568 | ||||
569 | if (!V_altqs_inactive_open(altqs_inactive_open) || ticket != V_ticket_altqs_inactive(ticket_altqs_inactive)) | |||
570 | return (EBUSY16); | |||
571 | ||||
572 | /* swap altqs, keep the old. */ | |||
573 | old_altqs = V_pf_altqs_active(pf_altqs_active); | |||
574 | V_pf_altqs_active(pf_altqs_active) = V_pf_altqs_inactive(pf_altqs_inactive); | |||
575 | V_pf_altqs_inactive(pf_altqs_inactive) = old_altqs; | |||
576 | V_ticket_altqs_active(ticket_altqs_active) = V_ticket_altqs_inactive(ticket_altqs_inactive); | |||
577 | ||||
578 | /* Attach new disciplines */ | |||
579 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((pf_altqs_active)))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) { | |||
580 | if (altq->qname[0] == 0 && | |||
581 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
582 | /* attach the discipline */ | |||
583 | error = altq_pfattach(altq); | |||
584 | if (error == 0 && V_pf_altq_running) | |||
585 | error = pf_enable_altq(altq); | |||
586 | if (error != 0) | |||
587 | return (error); | |||
588 | } | |||
589 | } | |||
590 | ||||
591 | /* Purge the old altq list */ | |||
592 | while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)(((pf_altqs_inactive))->tqh_first)) != NULL((void *)0)) { | |||
593 | TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries)do { ; ; ; ; if (((((altq))->entries.tqe_next)) != ((void * )0)) (((altq))->entries.tqe_next)->entries.tqe_prev = ( altq)->entries.tqe_prev; else { ((pf_altqs_inactive))-> tqh_last = (altq)->entries.tqe_prev; ; } *(altq)->entries .tqe_prev = (((altq))->entries.tqe_next); ; ; ; } while (0 ); | |||
594 | if (altq->qname[0] == 0 && | |||
595 | (altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
596 | /* detach and destroy the discipline */ | |||
597 | if (V_pf_altq_running) | |||
598 | error = pf_disable_altq(altq); | |||
599 | err = altq_pfdetach(altq); | |||
600 | if (err != 0 && error == 0) | |||
601 | error = err; | |||
602 | err = altq_remove(altq); | |||
603 | if (err != 0 && error == 0) | |||
604 | error = err; | |||
605 | } else | |||
606 | pf_qid_unref(altq->qid); | |||
607 | free(altq, M_PFALTQ); | |||
608 | } | |||
609 | ||||
610 | V_altqs_inactive_open(altqs_inactive_open) = 0; | |||
611 | return (error); | |||
612 | } | |||
613 | ||||
614 | static int | |||
615 | pf_enable_altq(struct pf_altq *altq) | |||
616 | { | |||
617 | struct ifnet *ifp; | |||
618 | struct tb_profile tb; | |||
619 | int error = 0; | |||
620 | ||||
621 | if ((ifp = ifunit(altq->ifname)) == NULL((void *)0)) | |||
622 | return (EINVAL22); | |||
623 | ||||
624 | if (ifp->if_snd.altq_type != ALTQT_NONE) | |||
625 | error = altq_enable(&ifp->if_snd); | |||
626 | ||||
627 | /* set tokenbucket regulator */ | |||
628 | if (error == 0 && ifp != NULL((void *)0) && ALTQ_IS_ENABLED(&ifp->if_snd)((&ifp->if_snd)->altq_flags & 0x02)) { | |||
629 | tb.rate = altq->ifbandwidth; | |||
630 | tb.depth = altq->tbrsize; | |||
631 | error = tbr_set(&ifp->if_snd, &tb); | |||
632 | } | |||
633 | ||||
634 | return (error); | |||
635 | } | |||
636 | ||||
637 | static int | |||
638 | pf_disable_altq(struct pf_altq *altq) | |||
639 | { | |||
640 | struct ifnet *ifp; | |||
641 | struct tb_profile tb; | |||
642 | int error; | |||
643 | ||||
644 | if ((ifp = ifunit(altq->ifname)) == NULL((void *)0)) | |||
645 | return (EINVAL22); | |||
646 | ||||
647 | /* | |||
648 | * when the discipline is no longer referenced, it was overridden | |||
649 | * by a new one. if so, just return. | |||
650 | */ | |||
651 | if (altq->altq_disc != ifp->if_snd.altq_disc) | |||
652 | return (0); | |||
653 | ||||
654 | error = altq_disable(&ifp->if_snd); | |||
655 | ||||
656 | if (error == 0) { | |||
657 | /* clear tokenbucket regulator */ | |||
658 | tb.rate = 0; | |||
659 | error = tbr_set(&ifp->if_snd, &tb); | |||
660 | } | |||
661 | ||||
662 | return (error); | |||
663 | } | |||
664 | ||||
665 | void | |||
666 | pf_altq_ifnet_event(struct ifnet *ifp, int remove) | |||
667 | { | |||
668 | struct ifnet *ifp1; | |||
669 | struct pf_altq *a1, *a2, *a3; | |||
670 | u_int32_t ticket; | |||
671 | int error = 0; | |||
672 | ||||
673 | /* Interrupt userland queue modifications */ | |||
674 | if (V_altqs_inactive_open(altqs_inactive_open)) | |||
675 | pf_rollback_altq(V_ticket_altqs_inactive(ticket_altqs_inactive)); | |||
676 | ||||
677 | /* Start new altq ruleset */ | |||
678 | if (pf_begin_altq(&ticket)) | |||
679 | return; | |||
680 | ||||
681 | /* Copy the current active set */ | |||
682 | TAILQ_FOREACH(a1, V_pf_altqs_active, entries)for ((a1) = ((((pf_altqs_active)))->tqh_first); (a1); (a1) = (((a1))->entries.tqe_next)) { | |||
683 | a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT0x0001); | |||
684 | if (a2 == NULL((void *)0)) { | |||
685 | error = ENOMEM12; | |||
686 | break; | |||
687 | } | |||
688 | bcopy(a1, a2, sizeof(struct pf_altq)); | |||
689 | ||||
690 | if (a2->qname[0] != 0) { | |||
691 | if ((a2->qid = pf_qname2qid(a2->qname)) == 0) { | |||
692 | error = EBUSY16; | |||
693 | free(a2, M_PFALTQ); | |||
694 | break; | |||
695 | } | |||
696 | a2->altq_disc = NULL((void *)0); | |||
697 | TAILQ_FOREACH(a3, V_pf_altqs_inactive, entries)for ((a3) = ((((pf_altqs_inactive)))->tqh_first); (a3); (a3 ) = (((a3))->entries.tqe_next)) { | |||
698 | if (strncmp(a3->ifname, a2->ifname, | |||
699 | IFNAMSIZ16) == 0 && a3->qname[0] == 0) { | |||
700 | a2->altq_disc = a3->altq_disc; | |||
701 | break; | |||
702 | } | |||
703 | } | |||
704 | } | |||
705 | /* Deactivate the interface in question */ | |||
706 | a2->local_flags &= ~PFALTQ_FLAG_IF_REMOVED0x01; | |||
707 | if ((ifp1 = ifunit(a2->ifname)) == NULL((void *)0) || | |||
708 | (remove && ifp1 == ifp)) { | |||
709 | a2->local_flags |= PFALTQ_FLAG_IF_REMOVED0x01; | |||
710 | } else { | |||
711 | error = altq_add(a2); | |||
712 | ||||
713 | if (ticket != V_ticket_altqs_inactive(ticket_altqs_inactive)) | |||
714 | error = EBUSY16; | |||
715 | ||||
716 | if (error) { | |||
717 | free(a2, M_PFALTQ); | |||
718 | break; | |||
719 | } | |||
720 | } | |||
721 | ||||
722 | TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries)do { ; (((a2))->entries.tqe_next) = ((void *)0); (a2)-> entries.tqe_prev = ((pf_altqs_inactive))->tqh_last; *((pf_altqs_inactive ))->tqh_last = (a2); ((pf_altqs_inactive))->tqh_last = & (((a2))->entries.tqe_next); ; ; } while (0); | |||
723 | } | |||
724 | ||||
725 | if (error != 0) | |||
726 | pf_rollback_altq(ticket); | |||
727 | else | |||
728 | pf_commit_altq(ticket); | |||
729 | } | |||
730 | #endif /* ALTQ */ | |||
731 | ||||
732 | static int | |||
733 | pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor) | |||
734 | { | |||
735 | struct pf_ruleset *rs; | |||
736 | struct pf_rule *rule; | |||
737 | ||||
738 | PF_RULES_WASSERT(); | |||
739 | ||||
740 | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | |||
741 | return (EINVAL22); | |||
742 | rs = pf_find_or_create_ruleset(anchor); | |||
743 | if (rs == NULL((void *)0)) | |||
744 | return (EINVAL22); | |||
745 | while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)((rs->rules[rs_num].inactive.ptr)->tqh_first)) != NULL((void *)0)) { | |||
746 | pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule); | |||
747 | rs->rules[rs_num].inactive.rcount--; | |||
748 | } | |||
749 | *ticket = ++rs->rules[rs_num].inactive.ticket; | |||
750 | rs->rules[rs_num].inactive.open = 1; | |||
751 | return (0); | |||
752 | } | |||
753 | ||||
754 | static int | |||
755 | pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor) | |||
756 | { | |||
757 | struct pf_ruleset *rs; | |||
758 | struct pf_rule *rule; | |||
759 | ||||
760 | PF_RULES_WASSERT(); | |||
761 | ||||
762 | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | |||
763 | return (EINVAL22); | |||
764 | rs = pf_find_ruleset(anchor); | |||
765 | if (rs == NULL((void *)0) || !rs->rules[rs_num].inactive.open || | |||
766 | rs->rules[rs_num].inactive.ticket != ticket) | |||
767 | return (0); | |||
768 | while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)((rs->rules[rs_num].inactive.ptr)->tqh_first)) != NULL((void *)0)) { | |||
769 | pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule); | |||
770 | rs->rules[rs_num].inactive.rcount--; | |||
771 | } | |||
772 | rs->rules[rs_num].inactive.open = 0; | |||
773 | return (0); | |||
774 | } | |||
775 | ||||
776 | #define PF_MD5_UPD(st, elm)MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)-> elm)) \ | |||
777 | MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm)) | |||
778 | ||||
779 | #define PF_MD5_UPD_STR(st, elm)MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm )) \ | |||
780 | MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm)) | |||
781 | ||||
782 | #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 { \ | |||
783 | (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)); \ | |||
784 | MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\ | |||
785 | } while (0) | |||
786 | ||||
787 | #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 { \ | |||
788 | (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))); \ | |||
789 | MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\ | |||
790 | } while (0) | |||
791 | ||||
792 | static void | |||
793 | pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr) | |||
794 | { | |||
795 | PF_MD5_UPD(pfr, addr.type)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.type, sizeof( (pfr)->addr.type)); | |||
796 | switch (pfr->addr.type) { | |||
797 | case PF_ADDR_DYNIFTL: | |||
798 | PF_MD5_UPD(pfr, addr.v.ifname)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.v.ifname, sizeof ((pfr)->addr.v.ifname)); | |||
799 | PF_MD5_UPD(pfr, addr.iflags)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.iflags, sizeof ((pfr)->addr.iflags)); | |||
800 | break; | |||
801 | case PF_ADDR_TABLE: | |||
802 | PF_MD5_UPD(pfr, addr.v.tblname)MD5Update(ctx, (u_int8_t *) &(pfr)->addr.v.tblname, sizeof ((pfr)->addr.v.tblname)); | |||
803 | break; | |||
804 | case PF_ADDR_ADDRMASK: | |||
805 | /* XXX ignore af? */ | |||
806 | 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)); | |||
807 | 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)); | |||
808 | break; | |||
809 | } | |||
810 | ||||
811 | PF_MD5_UPD(pfr, port[0])MD5Update(ctx, (u_int8_t *) &(pfr)->port[0], sizeof((pfr )->port[0])); | |||
812 | PF_MD5_UPD(pfr, port[1])MD5Update(ctx, (u_int8_t *) &(pfr)->port[1], sizeof((pfr )->port[1])); | |||
813 | PF_MD5_UPD(pfr, neg)MD5Update(ctx, (u_int8_t *) &(pfr)->neg, sizeof((pfr)-> neg)); | |||
814 | PF_MD5_UPD(pfr, port_op)MD5Update(ctx, (u_int8_t *) &(pfr)->port_op, sizeof((pfr )->port_op)); | |||
815 | } | |||
816 | ||||
817 | static void | |||
818 | pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule) | |||
819 | { | |||
820 | u_int16_t x; | |||
821 | u_int32_t y; | |||
822 | ||||
823 | pf_hash_rule_addr(ctx, &rule->src); | |||
824 | pf_hash_rule_addr(ctx, &rule->dst); | |||
825 | PF_MD5_UPD_STR(rule, label)MD5Update(ctx, (u_int8_t *) (rule)->label, strlen((rule)-> label)); | |||
826 | PF_MD5_UPD_STR(rule, ifname)MD5Update(ctx, (u_int8_t *) (rule)->ifname, strlen((rule)-> ifname)); | |||
827 | PF_MD5_UPD_STR(rule, match_tagname)MD5Update(ctx, (u_int8_t *) (rule)->match_tagname, strlen( (rule)->match_tagname)); | |||
828 | 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? */ | |||
829 | 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); | |||
830 | 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); | |||
831 | 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); | |||
832 | 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); | |||
833 | PF_MD5_UPD(rule, uid.op)MD5Update(ctx, (u_int8_t *) &(rule)->uid.op, sizeof((rule )->uid.op)); | |||
834 | 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); | |||
835 | 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); | |||
836 | PF_MD5_UPD(rule, gid.op)MD5Update(ctx, (u_int8_t *) &(rule)->gid.op, sizeof((rule )->gid.op)); | |||
837 | 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); | |||
838 | PF_MD5_UPD(rule, action)MD5Update(ctx, (u_int8_t *) &(rule)->action, sizeof((rule )->action)); | |||
839 | PF_MD5_UPD(rule, direction)MD5Update(ctx, (u_int8_t *) &(rule)->direction, sizeof ((rule)->direction)); | |||
840 | PF_MD5_UPD(rule, af)MD5Update(ctx, (u_int8_t *) &(rule)->af, sizeof((rule) ->af)); | |||
841 | PF_MD5_UPD(rule, quick)MD5Update(ctx, (u_int8_t *) &(rule)->quick, sizeof((rule )->quick)); | |||
842 | PF_MD5_UPD(rule, ifnot)MD5Update(ctx, (u_int8_t *) &(rule)->ifnot, sizeof((rule )->ifnot)); | |||
843 | PF_MD5_UPD(rule, match_tag_not)MD5Update(ctx, (u_int8_t *) &(rule)->match_tag_not, sizeof ((rule)->match_tag_not)); | |||
844 | PF_MD5_UPD(rule, natpass)MD5Update(ctx, (u_int8_t *) &(rule)->natpass, sizeof(( rule)->natpass)); | |||
845 | PF_MD5_UPD(rule, keep_state)MD5Update(ctx, (u_int8_t *) &(rule)->keep_state, sizeof ((rule)->keep_state)); | |||
846 | PF_MD5_UPD(rule, proto)MD5Update(ctx, (u_int8_t *) &(rule)->proto, sizeof((rule )->proto)); | |||
847 | PF_MD5_UPD(rule, type)MD5Update(ctx, (u_int8_t *) &(rule)->type, sizeof((rule )->type)); | |||
848 | PF_MD5_UPD(rule, code)MD5Update(ctx, (u_int8_t *) &(rule)->code, sizeof((rule )->code)); | |||
849 | PF_MD5_UPD(rule, flags)MD5Update(ctx, (u_int8_t *) &(rule)->flags, sizeof((rule )->flags)); | |||
850 | PF_MD5_UPD(rule, flagset)MD5Update(ctx, (u_int8_t *) &(rule)->flagset, sizeof(( rule)->flagset)); | |||
851 | PF_MD5_UPD(rule, allow_opts)MD5Update(ctx, (u_int8_t *) &(rule)->allow_opts, sizeof ((rule)->allow_opts)); | |||
852 | PF_MD5_UPD(rule, rt)MD5Update(ctx, (u_int8_t *) &(rule)->rt, sizeof((rule) ->rt)); | |||
853 | PF_MD5_UPD(rule, tos)MD5Update(ctx, (u_int8_t *) &(rule)->tos, sizeof((rule )->tos)); | |||
854 | } | |||
855 | ||||
856 | static int | |||
857 | pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) | |||
858 | { | |||
859 | struct pf_ruleset *rs; | |||
860 | struct pf_rule *rule, **old_array; | |||
861 | struct pf_rulequeue *old_rules; | |||
862 | int error; | |||
863 | u_int32_t old_rcount; | |||
864 | ||||
865 | PF_RULES_WASSERT(); | |||
866 | ||||
867 | if (rs_num < 0 || rs_num >= PF_RULESET_MAX) | |||
868 | return (EINVAL22); | |||
869 | rs = pf_find_ruleset(anchor); | |||
870 | if (rs == NULL((void *)0) || !rs->rules[rs_num].inactive.open || | |||
871 | ticket != rs->rules[rs_num].inactive.ticket) | |||
872 | return (EBUSY16); | |||
873 | ||||
874 | /* Calculate checksum for the main ruleset */ | |||
875 | if (rs == &pf_main_ruleset(pf_main_anchor).ruleset) { | |||
876 | error = pf_setup_pfsync_matching(rs); | |||
877 | if (error != 0) | |||
878 | return (error); | |||
879 | } | |||
880 | ||||
881 | /* Swap rules, keep the old. */ | |||
882 | old_rules = rs->rules[rs_num].active.ptr; | |||
883 | old_rcount = rs->rules[rs_num].active.rcount; | |||
884 | old_array = rs->rules[rs_num].active.ptr_array; | |||
885 | ||||
886 | rs->rules[rs_num].active.ptr = | |||
887 | rs->rules[rs_num].inactive.ptr; | |||
888 | rs->rules[rs_num].active.ptr_array = | |||
889 | rs->rules[rs_num].inactive.ptr_array; | |||
890 | rs->rules[rs_num].active.rcount = | |||
891 | rs->rules[rs_num].inactive.rcount; | |||
892 | rs->rules[rs_num].inactive.ptr = old_rules; | |||
893 | rs->rules[rs_num].inactive.ptr_array = old_array; | |||
894 | rs->rules[rs_num].inactive.rcount = old_rcount; | |||
895 | ||||
896 | rs->rules[rs_num].active.ticket = | |||
897 | rs->rules[rs_num].inactive.ticket; | |||
898 | pf_calc_skip_steps(rs->rules[rs_num].active.ptr); | |||
899 | ||||
900 | ||||
901 | /* Purge the old rule list. */ | |||
902 | while ((rule = TAILQ_FIRST(old_rules)((old_rules)->tqh_first)) != NULL((void *)0)) | |||
903 | pf_unlink_rule(old_rules, rule); | |||
904 | if (rs->rules[rs_num].inactive.ptr_array) | |||
905 | free(rs->rules[rs_num].inactive.ptr_array, M_TEMP); | |||
906 | rs->rules[rs_num].inactive.ptr_array = NULL((void *)0); | |||
907 | rs->rules[rs_num].inactive.rcount = 0; | |||
908 | rs->rules[rs_num].inactive.open = 0; | |||
909 | pf_remove_if_empty_ruleset(rs); | |||
910 | ||||
911 | return (0); | |||
912 | } | |||
913 | ||||
914 | static int | |||
915 | pf_setup_pfsync_matching(struct pf_ruleset *rs) | |||
916 | { | |||
917 | MD5_CTX ctx; | |||
918 | struct pf_rule *rule; | |||
919 | int rs_cnt; | |||
920 | u_int8_t digest[PF_MD5_DIGEST_LENGTH16]; | |||
921 | ||||
922 | MD5Init(&ctx); | |||
923 | for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) { | |||
924 | /* XXX PF_RULESET_SCRUB as well? */ | |||
925 | if (rs_cnt == PF_RULESET_SCRUB) | |||
926 | continue; | |||
927 | ||||
928 | if (rs->rules[rs_cnt].inactive.ptr_array) | |||
929 | free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP); | |||
930 | rs->rules[rs_cnt].inactive.ptr_array = NULL((void *)0); | |||
931 | ||||
932 | if (rs->rules[rs_cnt].inactive.rcount) { | |||
933 | rs->rules[rs_cnt].inactive.ptr_array = | |||
934 | malloc(sizeof(caddr_t) * | |||
935 | rs->rules[rs_cnt].inactive.rcount, | |||
936 | M_TEMP, M_NOWAIT0x0001); | |||
937 | ||||
938 | if (!rs->rules[rs_cnt].inactive.ptr_array) | |||
939 | return (ENOMEM12); | |||
940 | } | |||
941 | ||||
942 | 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)) | |||
943 | entries)for ((rule) = (((rs->rules[rs_cnt].inactive.ptr))->tqh_first ); (rule); (rule) = (((rule))->entries.tqe_next)) { | |||
944 | pf_hash_rule(&ctx, rule); | |||
945 | (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule; | |||
946 | } | |||
947 | } | |||
948 | ||||
949 | MD5Final(digest, &ctx); | |||
950 | memcpy(V_pf_status(pf_status).pf_chksum, digest, sizeof(V_pf_status(pf_status).pf_chksum)); | |||
951 | return (0); | |||
952 | } | |||
953 | ||||
954 | static int | |||
955 | pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr, | |||
956 | sa_family_t af) | |||
957 | { | |||
958 | int error = 0; | |||
959 | ||||
960 | switch (addr->type) { | |||
961 | case PF_ADDR_TABLE: | |||
962 | addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname); | |||
963 | if (addr->p.tbl == NULL((void *)0)) | |||
964 | error = ENOMEM12; | |||
965 | break; | |||
966 | case PF_ADDR_DYNIFTL: | |||
967 | error = pfi_dynaddr_setup(addr, af); | |||
968 | break; | |||
969 | } | |||
970 | ||||
971 | return (error); | |||
972 | } | |||
973 | ||||
974 | static void | |||
975 | pf_addr_copyout(struct pf_addr_wrap *addr) | |||
976 | { | |||
977 | ||||
978 | switch (addr->type) { | |||
979 | case PF_ADDR_DYNIFTL: | |||
980 | pfi_dynaddr_copyout(addr); | |||
981 | break; | |||
982 | case PF_ADDR_TABLE: | |||
983 | pf_tbladdr_copyout(addr); | |||
984 | break; | |||
985 | } | |||
986 | } | |||
987 | ||||
988 | static int | |||
989 | pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) | |||
990 | { | |||
991 | int error = 0; | |||
992 | ||||
993 | /* XXX keep in sync with switch() below */ | |||
994 | if (securelevel_gt(td->td_ucred, 2)) | |||
| ||||
995 | switch (cmd) { | |||
996 | case DIOCGETRULES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((6)))): | |||
997 | case DIOCGETRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((7)))): | |||
998 | case DIOCGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((53)))): | |||
999 | case DIOCGETADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((54)))): | |||
1000 | case DIOCGETSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((19)))): | |||
1001 | case DIOCSETSTATUSIF((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_if)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((20)))): | |||
1002 | case DIOCGETSTATUS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_status)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((21)))): | |||
1003 | case DIOCCLRSTATUS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((22)))): | |||
1004 | case DIOCNATLOOK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_natlook)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((23)))): | |||
1005 | case DIOCSETDEBUG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(u_int32_t )) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((24)))): | |||
1006 | case DIOCGETSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_states)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((25)))): | |||
1007 | case DIOCGETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((30)))): | |||
1008 | case DIOCCLRRULECTRS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((38)))): | |||
1009 | case DIOCGETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((39)))): | |||
1010 | case DIOCGETALTQS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((47)))): | |||
1011 | case DIOCGETALTQ((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((48)))): | |||
1012 | case DIOCGETQSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((50)))): | |||
1013 | case DIOCGETRULESETS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((58)))): | |||
1014 | case DIOCGETRULESET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((59)))): | |||
1015 | case DIOCRGETTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((63)))): | |||
1016 | case DIOCRGETTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((64)))): | |||
1017 | case DIOCRCLRTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((65)))): | |||
1018 | case DIOCRCLRADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((66)))): | |||
1019 | case DIOCRADDADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((67)))): | |||
1020 | case DIOCRDELADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((68)))): | |||
1021 | case DIOCRSETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((69)))): | |||
1022 | case DIOCRGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((70)))): | |||
1023 | case DIOCRGETASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((71)))): | |||
1024 | case DIOCRCLRASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((72)))): | |||
1025 | case DIOCRTSTADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((73)))): | |||
1026 | case DIOCOSFPGET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((80)))): | |||
1027 | case DIOCGETSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_nodes)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((84)))): | |||
1028 | case DIOCCLRSRCNODES((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((85)))): | |||
1029 | case DIOCIGETIFACES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((87)))): | |||
1030 | case DIOCGIFSPEED((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((92)))): | |||
1031 | case DIOCSETIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((89)))): | |||
1032 | case DIOCCLRIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((90)))): | |||
1033 | break; | |||
1034 | case DIOCRCLRTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((60)))): | |||
1035 | case DIOCRADDTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((61)))): | |||
1036 | case DIOCRDELTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((62)))): | |||
1037 | case DIOCRSETTFLAGS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((74)))): | |||
1038 | if (((struct pfioc_table *)addr)->pfrio_flags & | |||
1039 | PFR_FLAG_DUMMY0x00000002) | |||
1040 | break; /* dummy operation ok */ | |||
1041 | return (EPERM1); | |||
1042 | default: | |||
1043 | return (EPERM1); | |||
1044 | } | |||
1045 | ||||
1046 | if (!(flags & FWRITE0x0002)) | |||
1047 | switch (cmd) { | |||
1048 | case DIOCGETRULES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((6)))): | |||
1049 | case DIOCGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((53)))): | |||
1050 | case DIOCGETADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((54)))): | |||
1051 | case DIOCGETSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((19)))): | |||
1052 | case DIOCGETSTATUS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_status)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((21)))): | |||
1053 | case DIOCGETSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_states)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((25)))): | |||
1054 | case DIOCGETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((30)))): | |||
1055 | case DIOCGETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((39)))): | |||
1056 | case DIOCGETALTQS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((47)))): | |||
1057 | case DIOCGETALTQ((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((48)))): | |||
1058 | case DIOCGETQSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((50)))): | |||
1059 | case DIOCGETRULESETS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((58)))): | |||
1060 | case DIOCGETRULESET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((59)))): | |||
1061 | case DIOCNATLOOK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_natlook)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((23)))): | |||
1062 | case DIOCRGETTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((63)))): | |||
1063 | case DIOCRGETTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((64)))): | |||
1064 | case DIOCRGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((70)))): | |||
1065 | case DIOCRGETASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((71)))): | |||
1066 | case DIOCRTSTADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((73)))): | |||
1067 | case DIOCOSFPGET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((80)))): | |||
1068 | case DIOCGETSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_nodes)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((84)))): | |||
1069 | case DIOCIGETIFACES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((87)))): | |||
1070 | case DIOCGIFSPEED((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((92)))): | |||
1071 | break; | |||
1072 | case DIOCRCLRTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((60)))): | |||
1073 | case DIOCRADDTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((61)))): | |||
1074 | case DIOCRDELTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((62)))): | |||
1075 | case DIOCRCLRTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((65)))): | |||
1076 | case DIOCRCLRADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((66)))): | |||
1077 | case DIOCRADDADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((67)))): | |||
1078 | case DIOCRDELADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((68)))): | |||
1079 | case DIOCRSETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((69)))): | |||
1080 | case DIOCRSETTFLAGS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((74)))): | |||
1081 | if (((struct pfioc_table *)addr)->pfrio_flags & | |||
1082 | PFR_FLAG_DUMMY0x00000002) { | |||
1083 | flags |= FWRITE0x0002; /* need write lock for dummy */ | |||
1084 | break; /* dummy operation ok */ | |||
1085 | } | |||
1086 | return (EACCES13); | |||
1087 | case DIOCGETRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((7)))): | |||
1088 | if (((struct pfioc_rule *)addr)->action == | |||
1089 | PF_GET_CLR_CNTR) | |||
1090 | return (EACCES13); | |||
1091 | break; | |||
1092 | default: | |||
1093 | return (EACCES13); | |||
1094 | } | |||
1095 | ||||
1096 | CURVNET_SET(TD_TO_VNET(td)); | |||
1097 | ||||
1098 | switch (cmd) { | |||
1099 | case DIOCSTART((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((1)))): | |||
1100 | sx_xlock(&pf_ioctl_lock)(void)_sx_xlock(((&pf_ioctl_lock)), 0, ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1100)); | |||
1101 | if (V_pf_status(pf_status).running) | |||
1102 | error = EEXIST17; | |||
1103 | else { | |||
1104 | int cpu; | |||
1105 | ||||
1106 | error = hook_pf(); | |||
1107 | if (error) { | |||
1108 | DPFPRINTF(PF_DEBUG_MISC,if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil registration failed\n" ) | |||
1109 | ("pf: pfil registration failed\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil registration failed\n" ); | |||
1110 | break; | |||
1111 | } | |||
1112 | V_pf_status(pf_status).running = 1; | |||
1113 | V_pf_status(pf_status).since = time_second; | |||
1114 | ||||
1115 | 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)))) | |||
1116 | V_pf_stateid(pf_stateid)[cpu] = time_second; | |||
1117 | ||||
1118 | DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pf: started\n" ); | |||
1119 | } | |||
1120 | break; | |||
1121 | ||||
1122 | case DIOCSTOP((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((2)))): | |||
1123 | sx_xlock(&pf_ioctl_lock)(void)_sx_xlock(((&pf_ioctl_lock)), 0, ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1123)); | |||
1124 | if (!V_pf_status(pf_status).running) | |||
1125 | error = ENOENT2; | |||
1126 | else { | |||
1127 | V_pf_status(pf_status).running = 0; | |||
1128 | error = dehook_pf(); | |||
1129 | if (error) { | |||
1130 | V_pf_status(pf_status).running = 1; | |||
1131 | DPFPRINTF(PF_DEBUG_MISC,if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil unregistration failed\n" ) | |||
1132 | ("pf: pfil unregistration failed\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pf: pfil unregistration failed\n" ); | |||
1133 | } | |||
1134 | V_pf_status(pf_status).since = time_second; | |||
1135 | DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pf: stopped\n" ); | |||
1136 | } | |||
1137 | break; | |||
1138 | ||||
1139 | case DIOCADDRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((4)))): { | |||
1140 | struct pfioc_rule *pr = (struct pfioc_rule *)addr; | |||
1141 | struct pf_ruleset *ruleset; | |||
1142 | struct pf_rule *rule, *tail; | |||
1143 | struct pf_pooladdr *pa; | |||
1144 | struct pfi_kif *kif = NULL((void *)0); | |||
1145 | int rs_num; | |||
1146 | ||||
1147 | if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE40) { | |||
1148 | error = EINVAL22; | |||
1149 | break; | |||
1150 | } | |||
1151 | #ifndef INET1 | |||
1152 | if (pr->rule.af == AF_INET2) { | |||
1153 | error = EAFNOSUPPORT47; | |||
1154 | break; | |||
1155 | } | |||
1156 | #endif /* INET */ | |||
1157 | #ifndef INET61 | |||
1158 | if (pr->rule.af == AF_INET628) { | |||
1159 | error = EAFNOSUPPORT47; | |||
1160 | break; | |||
1161 | } | |||
1162 | #endif /* INET6 */ | |||
1163 | ||||
1164 | rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK0x0002); | |||
1165 | bcopy(&pr->rule, rule, sizeof(struct pf_rule)); | |||
1166 | if (rule->ifname[0]) | |||
1167 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
1168 | rule->states_cur = counter_u64_alloc(M_WAITOK0x0002); | |||
1169 | rule->states_tot = counter_u64_alloc(M_WAITOK0x0002); | |||
1170 | rule->src_nodes = counter_u64_alloc(M_WAITOK0x0002); | |||
1171 | rule->cuid = td->td_ucred->cr_ruid; | |||
1172 | rule->cpid = td->td_proc ? td->td_proc->p_pid : 0; | |||
1173 | 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); | |||
1174 | ||||
1175 | #define ERROUT(x) { error = (x); goto DIOCADDRULE_error; } | |||
1176 | ||||
1177 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1177); | |||
1178 | pr->anchor[sizeof(pr->anchor) - 1] = 0; | |||
1179 | ruleset = pf_find_ruleset(pr->anchor); | |||
1180 | if (ruleset == NULL((void *)0)) | |||
1181 | ERROUT(EINVAL22); | |||
1182 | rs_num = pf_get_ruleset_number(pr->rule.action); | |||
1183 | if (rs_num >= PF_RULESET_MAX) | |||
1184 | ERROUT(EINVAL22); | |||
1185 | if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) { | |||
1186 | DPFPRINTF(PF_DEBUG_MISC,if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("ticket: %d != [%d]%d\n" , pr->ticket, rs_num, ruleset->rules[rs_num].inactive.ticket ) | |||
1187 | ("ticket: %d != [%d]%d\n", pr->ticket, rs_num,if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("ticket: %d != [%d]%d\n" , pr->ticket, rs_num, ruleset->rules[rs_num].inactive.ticket ) | |||
1188 | ruleset->rules[rs_num].inactive.ticket))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("ticket: %d != [%d]%d\n" , pr->ticket, rs_num, ruleset->rules[rs_num].inactive.ticket ); | |||
1189 | ERROUT(EBUSY16); | |||
1190 | } | |||
1191 | if (pr->pool_ticket != V_ticket_pabuf(ticket_pabuf)) { | |||
1192 | DPFPRINTF(PF_DEBUG_MISC,if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pool_ticket: %d != %d\n" , pr->pool_ticket, (ticket_pabuf)) | |||
1193 | ("pool_ticket: %d != %d\n", pr->pool_ticket,if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pool_ticket: %d != %d\n" , pr->pool_ticket, (ticket_pabuf)) | |||
1194 | V_ticket_pabuf))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("pool_ticket: %d != %d\n" , pr->pool_ticket, (ticket_pabuf)); | |||
1195 | ERROUT(EBUSY16); | |||
1196 | } | |||
1197 | ||||
1198 | tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)) | |||
1199 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].inactive .ptr)->tqh_last))->tqh_last)); | |||
1200 | if (tail) | |||
1201 | rule->nr = tail->nr + 1; | |||
1202 | else | |||
1203 | rule->nr = 0; | |||
1204 | if (rule->ifname[0]) { | |||
1205 | rule->kif = pfi_kif_attach(kif, rule->ifname); | |||
1206 | pfi_kif_ref(rule->kif); | |||
1207 | } else | |||
1208 | rule->kif = NULL((void *)0); | |||
1209 | ||||
1210 | if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs) | |||
1211 | error = EBUSY16; | |||
1212 | ||||
1213 | #ifdef ALTQ | |||
1214 | /* set queue IDs */ | |||
1215 | if (rule->qname[0] != 0) { | |||
1216 | if ((rule->qid = pf_qname2qid(rule->qname)) == 0) | |||
1217 | error = EBUSY16; | |||
1218 | else if (rule->pqname[0] != 0) { | |||
1219 | if ((rule->pqid = | |||
1220 | pf_qname2qid(rule->pqname)) == 0) | |||
1221 | error = EBUSY16; | |||
1222 | } else | |||
1223 | rule->pqid = rule->qid; | |||
1224 | } | |||
1225 | #endif | |||
1226 | if (rule->tagname[0]) | |||
1227 | if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0) | |||
1228 | error = EBUSY16; | |||
1229 | if (rule->match_tagname[0]) | |||
1230 | if ((rule->match_tag = | |||
1231 | pf_tagname2tag(rule->match_tagname)) == 0) | |||
1232 | error = EBUSY16; | |||
1233 | if (rule->rt && !rule->direction) | |||
1234 | error = EINVAL22; | |||
1235 | if (!rule->log) | |||
1236 | rule->logif = 0; | |||
1237 | if (rule->logif >= PFLOGIFS_MAX16) | |||
1238 | error = EINVAL22; | |||
1239 | if (pf_addr_setup(ruleset, &rule->src.addr, rule->af)) | |||
1240 | error = ENOMEM12; | |||
1241 | if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af)) | |||
1242 | error = ENOMEM12; | |||
1243 | if (pf_anchor_setup(rule, ruleset, pr->anchor_call)) | |||
1244 | error = EINVAL22; | |||
1245 | if (rule->scrub_flags & PFSTATE_SETPRIO0x0200 && | |||
1246 | (rule->set_prio[0] > PF_PRIO_MAX7 || | |||
1247 | rule->set_prio[1] > PF_PRIO_MAX7)) | |||
1248 | error = EINVAL22; | |||
1249 | TAILQ_FOREACH(pa, &V_pf_pabuf, entries)for ((pa) = (((&(pf_pabuf)))->tqh_first); (pa); (pa) = (((pa))->entries.tqe_next)) | |||
1250 | if (pa->addr.type == PF_ADDR_TABLE) { | |||
1251 | pa->addr.p.tbl = pfr_attach_table(ruleset, | |||
1252 | pa->addr.v.tblname); | |||
1253 | if (pa->addr.p.tbl == NULL((void *)0)) | |||
1254 | error = ENOMEM12; | |||
1255 | } | |||
1256 | ||||
1257 | rule->overload_tbl = NULL((void *)0); | |||
1258 | if (rule->overload_tblname[0]) { | |||
1259 | if ((rule->overload_tbl = pfr_attach_table(ruleset, | |||
1260 | rule->overload_tblname)) == NULL((void *)0)) | |||
1261 | error = EINVAL22; | |||
1262 | else | |||
1263 | rule->overload_tbl->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags |= | |||
1264 | PFR_TFLAG_ACTIVE0x00000004; | |||
1265 | } | |||
1266 | ||||
1267 | pf_mv_pool(&V_pf_pabuf(pf_pabuf), &rule->rpool.list); | |||
1268 | if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) || | |||
1269 | (rule->action == PF_BINAT)) && rule->anchor == NULL((void *)0)) || | |||
1270 | (rule->rt > PF_FASTROUTE)) && | |||
1271 | (TAILQ_FIRST(&rule->rpool.list)((&rule->rpool.list)->tqh_first) == NULL((void *)0))) | |||
1272 | error = EINVAL22; | |||
1273 | ||||
1274 | if (error) { | |||
1275 | pf_free_rule(rule); | |||
1276 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1276); | |||
1277 | break; | |||
1278 | } | |||
1279 | ||||
1280 | rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list)((&rule->rpool.list)->tqh_first); | |||
1281 | rule->evaluations = rule->packets[0] = rule->packets[1] = | |||
1282 | rule->bytes[0] = rule->bytes[1] = 0; | |||
1283 | TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,do { ; (((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) | |||
1284 | rule, entries)do { ; (((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); | |||
1285 | ruleset->rules[rs_num].inactive.rcount++; | |||
1286 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1286); | |||
1287 | break; | |||
1288 | ||||
1289 | #undef ERROUT | |||
1290 | DIOCADDRULE_error: | |||
1291 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1291); | |||
1292 | counter_u64_free(rule->states_cur); | |||
1293 | counter_u64_free(rule->states_tot); | |||
1294 | counter_u64_free(rule->src_nodes); | |||
1295 | free(rule, M_PFRULE); | |||
1296 | if (kif) | |||
1297 | free(kif, PFI_MTYPE); | |||
1298 | break; | |||
1299 | } | |||
1300 | ||||
1301 | case DIOCGETRULES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((6)))): { | |||
1302 | struct pfioc_rule *pr = (struct pfioc_rule *)addr; | |||
1303 | struct pf_ruleset *ruleset; | |||
1304 | struct pf_rule *tail; | |||
1305 | int rs_num; | |||
1306 | ||||
1307 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1307); | |||
1308 | pr->anchor[sizeof(pr->anchor) - 1] = 0; | |||
1309 | ruleset = pf_find_ruleset(pr->anchor); | |||
1310 | if (ruleset == NULL((void *)0)) { | |||
1311 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1311); | |||
1312 | error = EINVAL22; | |||
1313 | break; | |||
1314 | } | |||
1315 | rs_num = pf_get_ruleset_number(pr->rule.action); | |||
1316 | if (rs_num >= PF_RULESET_MAX) { | |||
1317 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1317); | |||
1318 | error = EINVAL22; | |||
1319 | break; | |||
1320 | } | |||
1321 | tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)) | |||
1322 | pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)); | |||
1323 | if (tail) | |||
1324 | pr->nr = tail->nr + 1; | |||
1325 | else | |||
1326 | pr->nr = 0; | |||
1327 | pr->ticket = ruleset->rules[rs_num].active.ticket; | |||
1328 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1328); | |||
1329 | break; | |||
1330 | } | |||
1331 | ||||
1332 | case DIOCGETRULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((7)))): { | |||
1333 | struct pfioc_rule *pr = (struct pfioc_rule *)addr; | |||
1334 | struct pf_ruleset *ruleset; | |||
1335 | struct pf_rule *rule; | |||
1336 | int rs_num, i; | |||
1337 | ||||
1338 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1338); | |||
1339 | pr->anchor[sizeof(pr->anchor) - 1] = 0; | |||
1340 | ruleset = pf_find_ruleset(pr->anchor); | |||
1341 | if (ruleset == NULL((void *)0)) { | |||
1342 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1342); | |||
1343 | error = EINVAL22; | |||
1344 | break; | |||
1345 | } | |||
1346 | rs_num = pf_get_ruleset_number(pr->rule.action); | |||
1347 | if (rs_num >= PF_RULESET_MAX) { | |||
1348 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1348); | |||
1349 | error = EINVAL22; | |||
1350 | break; | |||
1351 | } | |||
1352 | if (pr->ticket != ruleset->rules[rs_num].active.ticket) { | |||
1353 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1353); | |||
1354 | error = EBUSY16; | |||
1355 | break; | |||
1356 | } | |||
1357 | rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
1358 | while ((rule != NULL((void *)0)) && (rule->nr != pr->nr)) | |||
1359 | rule = TAILQ_NEXT(rule, entries)((rule)->entries.tqe_next); | |||
1360 | if (rule == NULL((void *)0)) { | |||
1361 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1361); | |||
1362 | error = EBUSY16; | |||
1363 | break; | |||
1364 | } | |||
1365 | bcopy(rule, &pr->rule, sizeof(struct pf_rule)); | |||
1366 | pr->rule.u_states_cur = counter_u64_fetch(rule->states_cur); | |||
1367 | pr->rule.u_states_tot = counter_u64_fetch(rule->states_tot); | |||
1368 | pr->rule.u_src_nodes = counter_u64_fetch(rule->src_nodes); | |||
1369 | if (pf_anchor_copyout(ruleset, rule, pr)) { | |||
1370 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1370); | |||
1371 | error = EBUSY16; | |||
1372 | break; | |||
1373 | } | |||
1374 | pf_addr_copyout(&pr->rule.src.addr); | |||
1375 | pf_addr_copyout(&pr->rule.dst.addr); | |||
1376 | for (i = 0; i < PF_SKIP_COUNT8; ++i) | |||
1377 | if (rule->skip[i].ptr == NULL((void *)0)) | |||
1378 | pr->rule.skip[i].nr = -1; | |||
1379 | else | |||
1380 | pr->rule.skip[i].nr = | |||
1381 | rule->skip[i].ptr->nr; | |||
1382 | ||||
1383 | if (pr->action == PF_GET_CLR_CNTR) { | |||
1384 | rule->evaluations = 0; | |||
1385 | rule->packets[0] = rule->packets[1] = 0; | |||
1386 | rule->bytes[0] = rule->bytes[1] = 0; | |||
1387 | counter_u64_zero(rule->states_tot); | |||
1388 | } | |||
1389 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1389); | |||
1390 | break; | |||
1391 | } | |||
1392 | ||||
1393 | case DIOCCHANGERULE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_rule)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((26)))): { | |||
1394 | struct pfioc_rule *pcr = (struct pfioc_rule *)addr; | |||
1395 | struct pf_ruleset *ruleset; | |||
1396 | struct pf_rule *oldrule = NULL((void *)0), *newrule = NULL((void *)0); | |||
1397 | struct pfi_kif *kif = NULL((void *)0); | |||
1398 | struct pf_pooladdr *pa; | |||
1399 | u_int32_t nr = 0; | |||
1400 | int rs_num; | |||
1401 | ||||
1402 | if (pcr->action < PF_CHANGE_ADD_HEAD || | |||
1403 | pcr->action > PF_CHANGE_GET_TICKET) { | |||
1404 | error = EINVAL22; | |||
1405 | break; | |||
1406 | } | |||
1407 | if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE40) { | |||
1408 | error = EINVAL22; | |||
1409 | break; | |||
1410 | } | |||
1411 | ||||
1412 | if (pcr->action != PF_CHANGE_REMOVE) { | |||
1413 | #ifndef INET1 | |||
1414 | if (pcr->rule.af == AF_INET2) { | |||
1415 | error = EAFNOSUPPORT47; | |||
1416 | break; | |||
1417 | } | |||
1418 | #endif /* INET */ | |||
1419 | #ifndef INET61 | |||
1420 | if (pcr->rule.af == AF_INET628) { | |||
1421 | error = EAFNOSUPPORT47; | |||
1422 | break; | |||
1423 | } | |||
1424 | #endif /* INET6 */ | |||
1425 | newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK0x0002); | |||
1426 | bcopy(&pcr->rule, newrule, sizeof(struct pf_rule)); | |||
1427 | if (newrule->ifname[0]) | |||
1428 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
1429 | newrule->states_cur = counter_u64_alloc(M_WAITOK0x0002); | |||
1430 | newrule->states_tot = counter_u64_alloc(M_WAITOK0x0002); | |||
1431 | newrule->src_nodes = counter_u64_alloc(M_WAITOK0x0002); | |||
1432 | newrule->cuid = td->td_ucred->cr_ruid; | |||
1433 | newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0; | |||
1434 | 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); | |||
1435 | } | |||
1436 | ||||
1437 | #define ERROUT(x) { error = (x); goto DIOCCHANGERULE_error; } | |||
1438 | ||||
1439 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1439); | |||
1440 | if (!(pcr->action == PF_CHANGE_REMOVE || | |||
1441 | pcr->action == PF_CHANGE_GET_TICKET) && | |||
1442 | pcr->pool_ticket != V_ticket_pabuf(ticket_pabuf)) | |||
1443 | ERROUT(EBUSY16); | |||
1444 | ||||
1445 | ruleset = pf_find_ruleset(pcr->anchor); | |||
1446 | if (ruleset == NULL((void *)0)) | |||
1447 | ERROUT(EINVAL22); | |||
1448 | ||||
1449 | rs_num = pf_get_ruleset_number(pcr->rule.action); | |||
1450 | if (rs_num >= PF_RULESET_MAX) | |||
1451 | ERROUT(EINVAL22); | |||
1452 | ||||
1453 | if (pcr->action == PF_CHANGE_GET_TICKET) { | |||
1454 | pcr->ticket = ++ruleset->rules[rs_num].active.ticket; | |||
1455 | ERROUT(0); | |||
1456 | } else if (pcr->ticket != | |||
1457 | ruleset->rules[rs_num].active.ticket) | |||
1458 | ERROUT(EINVAL22); | |||
1459 | ||||
1460 | if (pcr->action != PF_CHANGE_REMOVE) { | |||
1461 | if (newrule->ifname[0]) { | |||
1462 | newrule->kif = pfi_kif_attach(kif, | |||
1463 | newrule->ifname); | |||
1464 | pfi_kif_ref(newrule->kif); | |||
1465 | } else | |||
1466 | newrule->kif = NULL((void *)0); | |||
1467 | ||||
1468 | if (newrule->rtableid > 0 && | |||
1469 | newrule->rtableid >= rt_numfibs) | |||
1470 | error = EBUSY16; | |||
1471 | ||||
1472 | #ifdef ALTQ | |||
1473 | /* set queue IDs */ | |||
1474 | if (newrule->qname[0] != 0) { | |||
1475 | if ((newrule->qid = | |||
1476 | pf_qname2qid(newrule->qname)) == 0) | |||
1477 | error = EBUSY16; | |||
1478 | else if (newrule->pqname[0] != 0) { | |||
1479 | if ((newrule->pqid = | |||
1480 | pf_qname2qid(newrule->pqname)) == 0) | |||
1481 | error = EBUSY16; | |||
1482 | } else | |||
1483 | newrule->pqid = newrule->qid; | |||
1484 | } | |||
1485 | #endif /* ALTQ */ | |||
1486 | if (newrule->tagname[0]) | |||
1487 | if ((newrule->tag = | |||
1488 | pf_tagname2tag(newrule->tagname)) == 0) | |||
1489 | error = EBUSY16; | |||
1490 | if (newrule->match_tagname[0]) | |||
1491 | if ((newrule->match_tag = pf_tagname2tag( | |||
1492 | newrule->match_tagname)) == 0) | |||
1493 | error = EBUSY16; | |||
1494 | if (newrule->rt && !newrule->direction) | |||
1495 | error = EINVAL22; | |||
1496 | if (!newrule->log) | |||
1497 | newrule->logif = 0; | |||
1498 | if (newrule->logif >= PFLOGIFS_MAX16) | |||
1499 | error = EINVAL22; | |||
1500 | if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af)) | |||
1501 | error = ENOMEM12; | |||
1502 | if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af)) | |||
1503 | error = ENOMEM12; | |||
1504 | if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call)) | |||
1505 | error = EINVAL22; | |||
1506 | TAILQ_FOREACH(pa, &V_pf_pabuf, entries)for ((pa) = (((&(pf_pabuf)))->tqh_first); (pa); (pa) = (((pa))->entries.tqe_next)) | |||
1507 | if (pa->addr.type == PF_ADDR_TABLE) { | |||
1508 | pa->addr.p.tbl = | |||
1509 | pfr_attach_table(ruleset, | |||
1510 | pa->addr.v.tblname); | |||
1511 | if (pa->addr.p.tbl == NULL((void *)0)) | |||
1512 | error = ENOMEM12; | |||
1513 | } | |||
1514 | ||||
1515 | newrule->overload_tbl = NULL((void *)0); | |||
1516 | if (newrule->overload_tblname[0]) { | |||
1517 | if ((newrule->overload_tbl = pfr_attach_table( | |||
1518 | ruleset, newrule->overload_tblname)) == | |||
1519 | NULL((void *)0)) | |||
1520 | error = EINVAL22; | |||
1521 | else | |||
1522 | newrule->overload_tbl->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags |= | |||
1523 | PFR_TFLAG_ACTIVE0x00000004; | |||
1524 | } | |||
1525 | ||||
1526 | pf_mv_pool(&V_pf_pabuf(pf_pabuf), &newrule->rpool.list); | |||
1527 | if (((((newrule->action == PF_NAT) || | |||
1528 | (newrule->action == PF_RDR) || | |||
1529 | (newrule->action == PF_BINAT) || | |||
1530 | (newrule->rt > PF_FASTROUTE)) && | |||
1531 | !newrule->anchor)) && | |||
1532 | (TAILQ_FIRST(&newrule->rpool.list)((&newrule->rpool.list)->tqh_first) == NULL((void *)0))) | |||
1533 | error = EINVAL22; | |||
1534 | ||||
1535 | if (error) { | |||
1536 | pf_free_rule(newrule); | |||
1537 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1537); | |||
1538 | break; | |||
1539 | } | |||
1540 | ||||
1541 | newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list)((&newrule->rpool.list)->tqh_first); | |||
1542 | newrule->evaluations = 0; | |||
1543 | newrule->packets[0] = newrule->packets[1] = 0; | |||
1544 | newrule->bytes[0] = newrule->bytes[1] = 0; | |||
1545 | } | |||
1546 | pf_empty_pool(&V_pf_pabuf(pf_pabuf)); | |||
1547 | ||||
1548 | if (pcr->action == PF_CHANGE_ADD_HEAD) | |||
1549 | oldrule = TAILQ_FIRST(((ruleset->rules[rs_num].active.ptr)->tqh_first) | |||
1550 | ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
1551 | else if (pcr->action == PF_CHANGE_ADD_TAIL) | |||
1552 | oldrule = TAILQ_LAST((*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)) | |||
1553 | ruleset->rules[rs_num].active.ptr, pf_rulequeue)(*(((struct pf_rulequeue *)((ruleset->rules[rs_num].active .ptr)->tqh_last))->tqh_last)); | |||
1554 | else { | |||
1555 | oldrule = TAILQ_FIRST(((ruleset->rules[rs_num].active.ptr)->tqh_first) | |||
1556 | ruleset->rules[rs_num].active.ptr)((ruleset->rules[rs_num].active.ptr)->tqh_first); | |||
1557 | while ((oldrule != NULL((void *)0)) && (oldrule->nr != pcr->nr)) | |||
1558 | oldrule = TAILQ_NEXT(oldrule, entries)((oldrule)->entries.tqe_next); | |||
1559 | if (oldrule == NULL((void *)0)) { | |||
1560 | if (newrule != NULL((void *)0)) | |||
1561 | pf_free_rule(newrule); | |||
1562 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1562); | |||
1563 | error = EINVAL22; | |||
1564 | break; | |||
1565 | } | |||
1566 | } | |||
1567 | ||||
1568 | if (pcr->action == PF_CHANGE_REMOVE) { | |||
1569 | pf_unlink_rule(ruleset->rules[rs_num].active.ptr, | |||
1570 | oldrule); | |||
1571 | ruleset->rules[rs_num].active.rcount--; | |||
1572 | } else { | |||
1573 | if (oldrule == NULL((void *)0)) | |||
1574 | TAILQ_INSERT_TAIL(do { ; (((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) | |||
1575 | ruleset->rules[rs_num].active.ptr,do { ; (((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) | |||
1576 | newrule, entries)do { ; (((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); | |||
1577 | else if (pcr->action == PF_CHANGE_ADD_HEAD || | |||
1578 | pcr->action == PF_CHANGE_ADD_BEFORE) | |||
1579 | TAILQ_INSERT_BEFORE(oldrule, newrule, entries)do { ; (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); | |||
1580 | else | |||
1581 | TAILQ_INSERT_AFTER(do { ; 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) | |||
1582 | ruleset->rules[rs_num].active.ptr,do { ; 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) | |||
1583 | oldrule, newrule, entries)do { ; 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); | |||
1584 | ruleset->rules[rs_num].active.rcount++; | |||
1585 | } | |||
1586 | ||||
1587 | nr = 0; | |||
1588 | TAILQ_FOREACH(oldrule,for ((oldrule) = (((ruleset->rules[rs_num].active.ptr))-> tqh_first); (oldrule); (oldrule) = (((oldrule))->entries.tqe_next )) | |||
1589 | ruleset->rules[rs_num].active.ptr, entries)for ((oldrule) = (((ruleset->rules[rs_num].active.ptr))-> tqh_first); (oldrule); (oldrule) = (((oldrule))->entries.tqe_next )) | |||
1590 | oldrule->nr = nr++; | |||
1591 | ||||
1592 | ruleset->rules[rs_num].active.ticket++; | |||
1593 | ||||
1594 | pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr); | |||
1595 | pf_remove_if_empty_ruleset(ruleset); | |||
1596 | ||||
1597 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1597); | |||
1598 | break; | |||
1599 | ||||
1600 | #undef ERROUT | |||
1601 | DIOCCHANGERULE_error: | |||
1602 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1602); | |||
1603 | if (newrule != NULL((void *)0)) { | |||
1604 | counter_u64_free(newrule->states_cur); | |||
1605 | counter_u64_free(newrule->states_tot); | |||
1606 | counter_u64_free(newrule->src_nodes); | |||
1607 | free(newrule, M_PFRULE); | |||
1608 | } | |||
1609 | if (kif != NULL((void *)0)) | |||
1610 | free(kif, PFI_MTYPE); | |||
1611 | break; | |||
1612 | } | |||
1613 | ||||
1614 | case DIOCCLRSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state_kill)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((18)))): { | |||
1615 | struct pf_state *s; | |||
1616 | struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; | |||
1617 | u_int i, killed = 0; | |||
1618 | ||||
1619 | for (i = 0; i <= pf_hashmask; i++) { | |||
1620 | struct pf_idhash *ih = &V_pf_idhash(pf_idhash)[i]; | |||
1621 | ||||
1622 | relock_DIOCCLRSTATES: | |||
1623 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1623)); | |||
1624 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) | |||
1625 | if (!psk->psk_ifname[0] || | |||
1626 | !strcmp(psk->psk_ifname, | |||
1627 | s->kif->pfik_name)) { | |||
1628 | /* | |||
1629 | * Don't send out individual | |||
1630 | * delete messages. | |||
1631 | */ | |||
1632 | s->state_flags |= PFSTATE_NOSYNC0x08; | |||
1633 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
1634 | killed++; | |||
1635 | goto relock_DIOCCLRSTATES; | |||
1636 | } | |||
1637 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1637)); | |||
1638 | } | |||
1639 | psk->psk_killed = killed; | |||
1640 | if (pfsync_clear_states_ptr != NULL((void *)0)) | |||
1641 | pfsync_clear_states_ptr(V_pf_status(pf_status).hostid, psk->psk_ifname); | |||
1642 | break; | |||
1643 | } | |||
1644 | ||||
1645 | case DIOCKILLSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state_kill)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((41)))): { | |||
1646 | struct pf_state *s; | |||
1647 | struct pf_state_key *sk; | |||
1648 | struct pf_addr *srcaddr, *dstaddr; | |||
1649 | u_int16_t srcport, dstport; | |||
1650 | struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; | |||
1651 | u_int i, killed = 0; | |||
1652 | ||||
1653 | if (psk->psk_pfcmp.id) { | |||
1654 | if (psk->psk_pfcmp.creatorid == 0) | |||
1655 | psk->psk_pfcmp.creatorid = V_pf_status(pf_status).hostid; | |||
1656 | if ((s = pf_find_state_byid(psk->psk_pfcmp.id, | |||
1657 | psk->psk_pfcmp.creatorid))) { | |||
1658 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
1659 | psk->psk_killed = 1; | |||
1660 | } | |||
1661 | break; | |||
1662 | } | |||
1663 | ||||
1664 | for (i = 0; i <= pf_hashmask; i++) { | |||
1665 | struct pf_idhash *ih = &V_pf_idhash(pf_idhash)[i]; | |||
1666 | ||||
1667 | relock_DIOCKILLSTATES: | |||
1668 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1668)); | |||
1669 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
1670 | sk = s->key[PF_SK_WIRE]; | |||
1671 | if (s->direction == PF_OUT) { | |||
1672 | srcaddr = &sk->addr[1]; | |||
1673 | dstaddr = &sk->addr[0]; | |||
1674 | srcport = sk->port[1]; | |||
1675 | dstport = sk->port[0]; | |||
1676 | } else { | |||
1677 | srcaddr = &sk->addr[0]; | |||
1678 | dstaddr = &sk->addr[1]; | |||
1679 | srcport = sk->port[0]; | |||
1680 | dstport = sk->port[1]; | |||
1681 | } | |||
1682 | ||||
1683 | if ((!psk->psk_af || sk->af == psk->psk_af) | |||
1684 | && (!psk->psk_proto || psk->psk_proto == | |||
1685 | sk->proto) && | |||
1686 | 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) | |||
1687 | &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) | |||
1688 | &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) | |||
1689 | 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) && | |||
1690 | 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) | |||
1691 | &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) | |||
1692 | &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) | |||
1693 | 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) && | |||
1694 | (psk->psk_src.port_op == 0 || | |||
1695 | pf_match_port(psk->psk_src.port_op, | |||
1696 | psk->psk_src.port[0], psk->psk_src.port[1], | |||
1697 | srcport)) && | |||
1698 | (psk->psk_dst.port_op == 0 || | |||
1699 | pf_match_port(psk->psk_dst.port_op, | |||
1700 | psk->psk_dst.port[0], psk->psk_dst.port[1], | |||
1701 | dstport)) && | |||
1702 | (!psk->psk_label[0] || | |||
1703 | (s->rule.ptr->label[0] && | |||
1704 | !strcmp(psk->psk_label, | |||
1705 | s->rule.ptr->label))) && | |||
1706 | (!psk->psk_ifname[0] || | |||
1707 | !strcmp(psk->psk_ifname, | |||
1708 | s->kif->pfik_name))) { | |||
1709 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
1710 | killed++; | |||
1711 | goto relock_DIOCKILLSTATES; | |||
1712 | } | |||
1713 | } | |||
1714 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1714)); | |||
1715 | } | |||
1716 | psk->psk_killed = killed; | |||
1717 | break; | |||
1718 | } | |||
1719 | ||||
1720 | case DIOCADDSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((37)))): { | |||
1721 | struct pfioc_state *ps = (struct pfioc_state *)addr; | |||
1722 | struct pfsync_state *sp = &ps->state; | |||
1723 | ||||
1724 | if (sp->timeout >= PFTM_MAX) { | |||
1725 | error = EINVAL22; | |||
1726 | break; | |||
1727 | } | |||
1728 | if (pfsync_state_import_ptr != NULL((void *)0)) { | |||
1729 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1729); | |||
1730 | error = pfsync_state_import_ptr(sp, PFSYNC_SI_IOCTL0x01); | |||
1731 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1731); | |||
1732 | } else | |||
1733 | error = EOPNOTSUPP45; | |||
1734 | break; | |||
1735 | } | |||
1736 | ||||
1737 | case DIOCGETSTATE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_state)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((19)))): { | |||
1738 | struct pfioc_state *ps = (struct pfioc_state *)addr; | |||
1739 | struct pf_state *s; | |||
1740 | ||||
1741 | s = pf_find_state_byid(ps->state.id, ps->state.creatorid); | |||
1742 | if (s == NULL((void *)0)) { | |||
1743 | error = ENOENT2; | |||
1744 | break; | |||
1745 | } | |||
1746 | ||||
1747 | pfsync_state_export(&ps->state, s); | |||
1748 | PF_STATE_UNLOCK(s)do { struct pf_idhash *_ih = &(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)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1748)); } while (0); | |||
1749 | break; | |||
1750 | } | |||
1751 | ||||
1752 | case DIOCGETSTATES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_states)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((25)))): { | |||
1753 | struct pfioc_states *ps = (struct pfioc_states *)addr; | |||
1754 | struct pf_state *s; | |||
1755 | struct pfsync_state *pstore, *p; | |||
1756 | int i, nr; | |||
1757 | ||||
1758 | if (ps->ps_len == 0) { | |||
1759 | nr = uma_zone_get_cur(V_pf_state_z(pf_state_z)); | |||
1760 | ps->ps_len = sizeof(struct pfsync_state) * nr; | |||
1761 | break; | |||
1762 | } | |||
1763 | ||||
1764 | p = pstore = malloc(ps->ps_len, M_TEMP, M_WAITOK0x0002); | |||
1765 | nr = 0; | |||
1766 | ||||
1767 | for (i = 0; i <= pf_hashmask; i++) { | |||
1768 | struct pf_idhash *ih = &V_pf_idhash(pf_idhash)[i]; | |||
1769 | ||||
1770 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1770)); | |||
1771 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
1772 | ||||
1773 | if (s->timeout == PFTM_UNLINKED) | |||
1774 | continue; | |||
1775 | ||||
1776 | if ((nr+1) * sizeof(*p) > ps->ps_len) { | |||
1777 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1777)); | |||
1778 | goto DIOCGETSTATES_full; | |||
1779 | } | |||
1780 | pfsync_state_export(p, s); | |||
1781 | p++; | |||
1782 | nr++; | |||
1783 | } | |||
1784 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (1784)); | |||
1785 | } | |||
1786 | DIOCGETSTATES_full: | |||
1787 | error = copyout(pstore, ps->ps_statesps_u.psu_states, | |||
1788 | sizeof(struct pfsync_state) * nr); | |||
1789 | if (error) { | |||
1790 | free(pstore, M_TEMP); | |||
1791 | break; | |||
1792 | } | |||
1793 | ps->ps_len = sizeof(struct pfsync_state) * nr; | |||
1794 | free(pstore, M_TEMP); | |||
1795 | ||||
1796 | break; | |||
1797 | } | |||
1798 | ||||
1799 | case DIOCGETSTATUS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_status)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((21)))): { | |||
1800 | struct pf_status *s = (struct pf_status *)addr; | |||
1801 | ||||
1802 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1802); | |||
1803 | s->running = V_pf_status(pf_status).running; | |||
1804 | s->since = V_pf_status(pf_status).since; | |||
1805 | s->debug = V_pf_status(pf_status).debug; | |||
1806 | s->hostid = V_pf_status(pf_status).hostid; | |||
1807 | s->states = V_pf_status(pf_status).states; | |||
1808 | s->src_nodes = V_pf_status(pf_status).src_nodes; | |||
1809 | ||||
1810 | for (int i = 0; i < PFRES_MAX16; i++) | |||
1811 | s->counters[i] = | |||
1812 | counter_u64_fetch(V_pf_status(pf_status).counters[i]); | |||
1813 | for (int i = 0; i < LCNT_MAX7; i++) | |||
1814 | s->lcounters[i] = | |||
1815 | counter_u64_fetch(V_pf_status(pf_status).lcounters[i]); | |||
1816 | for (int i = 0; i < FCNT_MAX3; i++) | |||
1817 | s->fcounters[i] = | |||
1818 | counter_u64_fetch(V_pf_status(pf_status).fcounters[i]); | |||
1819 | for (int i = 0; i < SCNT_MAX3; i++) | |||
1820 | s->scounters[i] = | |||
1821 | counter_u64_fetch(V_pf_status(pf_status).scounters[i]); | |||
1822 | ||||
1823 | bcopy(V_pf_status(pf_status).ifname, s->ifname, IFNAMSIZ16); | |||
1824 | bcopy(V_pf_status(pf_status).pf_chksum, s->pf_chksum, | |||
1825 | PF_MD5_DIGEST_LENGTH16); | |||
1826 | ||||
1827 | pfi_update_status(s->ifname, s); | |||
1828 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1828); | |||
1829 | break; | |||
1830 | } | |||
1831 | ||||
1832 | case DIOCSETSTATUSIF((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_if)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((20)))): { | |||
1833 | struct pfioc_if *pi = (struct pfioc_if *)addr; | |||
1834 | ||||
1835 | if (pi->ifname[0] == 0) { | |||
1836 | bzero(V_pf_status(pf_status).ifname, IFNAMSIZ16); | |||
1837 | break; | |||
1838 | } | |||
1839 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1839); | |||
1840 | strlcpy(V_pf_status(pf_status).ifname, pi->ifname, IFNAMSIZ16); | |||
1841 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1841); | |||
1842 | break; | |||
1843 | } | |||
1844 | ||||
1845 | case DIOCCLRSTATUS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((22)))): { | |||
1846 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1846); | |||
1847 | for (int i = 0; i < PFRES_MAX16; i++) | |||
1848 | counter_u64_zero(V_pf_status(pf_status).counters[i]); | |||
1849 | for (int i = 0; i < FCNT_MAX3; i++) | |||
1850 | counter_u64_zero(V_pf_status(pf_status).fcounters[i]); | |||
1851 | for (int i = 0; i < SCNT_MAX3; i++) | |||
1852 | counter_u64_zero(V_pf_status(pf_status).scounters[i]); | |||
1853 | V_pf_status(pf_status).since = time_second; | |||
1854 | if (*V_pf_status(pf_status).ifname) | |||
1855 | pfi_update_status(V_pf_status(pf_status).ifname, NULL((void *)0)); | |||
1856 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1856); | |||
1857 | break; | |||
1858 | } | |||
1859 | ||||
1860 | case DIOCNATLOOK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_natlook)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((23)))): { | |||
1861 | struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; | |||
1862 | struct pf_state_key *sk; | |||
1863 | struct pf_state *state; | |||
1864 | struct pf_state_key_cmp key; | |||
1865 | int m = 0, direction = pnl->direction; | |||
1866 | int sidx, didx; | |||
1867 | ||||
1868 | /* NATLOOK src and dst are reversed, so reverse sidx/didx */ | |||
1869 | sidx = (direction == PF_IN) ? 1 : 0; | |||
1870 | didx = (direction == PF_IN) ? 0 : 1; | |||
1871 | ||||
1872 | if (!pnl->proto || | |||
1873 | 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] )) || | |||
1874 | 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] )) || | |||
1875 | ((pnl->proto == IPPROTO_TCP6 || | |||
1876 | pnl->proto == IPPROTO_UDP17) && | |||
1877 | (!pnl->dport || !pnl->sport))) | |||
1878 | error = EINVAL22; | |||
1879 | else { | |||
1880 | bzero(&key, sizeof(key)); | |||
1881 | key.af = pnl->af; | |||
1882 | key.proto = pnl->proto; | |||
1883 | PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af)pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af ); | |||
1884 | key.port[sidx] = pnl->sport; | |||
1885 | PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af)pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af ); | |||
1886 | key.port[didx] = pnl->dport; | |||
1887 | ||||
1888 | state = pf_find_state_all(&key, direction, &m); | |||
1889 | ||||
1890 | if (m > 1) | |||
1891 | error = E2BIG7; /* more than one state */ | |||
1892 | else if (state != NULL((void *)0)) { | |||
1893 | /* XXXGL: not locked read */ | |||
1894 | sk = state->key[sidx]; | |||
1895 | PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af)pf_addrcpy(&pnl->rsaddr, &sk->addr[sidx], sk-> af); | |||
1896 | pnl->rsport = sk->port[sidx]; | |||
1897 | PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af)pf_addrcpy(&pnl->rdaddr, &sk->addr[didx], sk-> af); | |||
1898 | pnl->rdport = sk->port[didx]; | |||
1899 | } else | |||
1900 | error = ENOENT2; | |||
1901 | } | |||
1902 | break; | |||
1903 | } | |||
1904 | ||||
1905 | case DIOCSETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((29)))): { | |||
1906 | struct pfioc_tm *pt = (struct pfioc_tm *)addr; | |||
1907 | int old; | |||
1908 | ||||
1909 | if (pt->timeout < 0 || pt->timeout >= PFTM_MAX || | |||
1910 | pt->seconds < 0) { | |||
1911 | error = EINVAL22; | |||
1912 | break; | |||
1913 | } | |||
1914 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1914); | |||
1915 | old = V_pf_default_rule(pf_default_rule).timeout[pt->timeout]; | |||
1916 | if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0) | |||
1917 | pt->seconds = 1; | |||
1918 | V_pf_default_rule(pf_default_rule).timeout[pt->timeout] = pt->seconds; | |||
1919 | if (pt->timeout == PFTM_INTERVAL && pt->seconds < old) | |||
1920 | wakeup(pf_purge_thread); | |||
1921 | pt->seconds = old; | |||
1922 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1922); | |||
1923 | break; | |||
1924 | } | |||
1925 | ||||
1926 | case DIOCGETTIMEOUT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_tm)) & ((1 << 13) - 1)) << 16) | ((('D' )) << 8) | ((30)))): { | |||
1927 | struct pfioc_tm *pt = (struct pfioc_tm *)addr; | |||
1928 | ||||
1929 | if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) { | |||
1930 | error = EINVAL22; | |||
1931 | break; | |||
1932 | } | |||
1933 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1933); | |||
1934 | pt->seconds = V_pf_default_rule(pf_default_rule).timeout[pt->timeout]; | |||
1935 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1935); | |||
1936 | break; | |||
1937 | } | |||
1938 | ||||
1939 | case DIOCGETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((39)))): { | |||
1940 | struct pfioc_limit *pl = (struct pfioc_limit *)addr; | |||
1941 | ||||
1942 | if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { | |||
1943 | error = EINVAL22; | |||
1944 | break; | |||
1945 | } | |||
1946 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1946); | |||
1947 | pl->limit = V_pf_limits(pf_limits)[pl->index].limit; | |||
1948 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1948); | |||
1949 | break; | |||
1950 | } | |||
1951 | ||||
1952 | case DIOCSETLIMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_limit)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((40)))): { | |||
1953 | struct pfioc_limit *pl = (struct pfioc_limit *)addr; | |||
1954 | int old_limit; | |||
1955 | ||||
1956 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1956); | |||
1957 | if (pl->index < 0 || pl->index >= PF_LIMIT_MAX || | |||
1958 | V_pf_limits(pf_limits)[pl->index].zone == NULL((void *)0)) { | |||
1959 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1959); | |||
1960 | error = EINVAL22; | |||
1961 | break; | |||
1962 | } | |||
1963 | uma_zone_set_max(V_pf_limits(pf_limits)[pl->index].zone, pl->limit); | |||
1964 | old_limit = V_pf_limits(pf_limits)[pl->index].limit; | |||
1965 | V_pf_limits(pf_limits)[pl->index].limit = pl->limit; | |||
1966 | pl->limit = old_limit; | |||
1967 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1967); | |||
1968 | break; | |||
1969 | } | |||
1970 | ||||
1971 | case DIOCSETDEBUG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(u_int32_t )) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((24)))): { | |||
1972 | u_int32_t *level = (u_int32_t *)addr; | |||
1973 | ||||
1974 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1974); | |||
1975 | V_pf_status(pf_status).debug = *level; | |||
1976 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1976); | |||
1977 | break; | |||
1978 | } | |||
1979 | ||||
1980 | case DIOCCLRRULECTRS((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((38)))): { | |||
1981 | /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */ | |||
1982 | struct pf_ruleset *ruleset = &pf_main_ruleset(pf_main_anchor).ruleset; | |||
1983 | struct pf_rule *rule; | |||
1984 | ||||
1985 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1985); | |||
1986 | TAILQ_FOREACH(rule,for ((rule) = (((ruleset->rules[PF_RULESET_FILTER].active. ptr))->tqh_first); (rule); (rule) = (((rule))->entries. tqe_next)) | |||
1987 | 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)) { | |||
1988 | rule->evaluations = 0; | |||
1989 | rule->packets[0] = rule->packets[1] = 0; | |||
1990 | rule->bytes[0] = rule->bytes[1] = 0; | |||
1991 | } | |||
1992 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 1992); | |||
1993 | break; | |||
1994 | } | |||
1995 | ||||
1996 | case DIOCGIFSPEED((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_ifspeed)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((92)))): { | |||
1997 | struct pf_ifspeed *psp = (struct pf_ifspeed *)addr; | |||
1998 | struct pf_ifspeed ps; | |||
1999 | struct ifnet *ifp; | |||
2000 | ||||
2001 | if (psp->ifname[0] != 0) { | |||
2002 | /* Can we completely trust user-land? */ | |||
2003 | strlcpy(ps.ifname, psp->ifname, IFNAMSIZ16); | |||
2004 | ifp = ifunit(ps.ifname); | |||
2005 | if (ifp != NULL((void *)0)) | |||
2006 | psp->baudrate = ifp->if_baudrate; | |||
2007 | else | |||
2008 | error = EINVAL22; | |||
2009 | } else | |||
2010 | error = EINVAL22; | |||
2011 | break; | |||
2012 | } | |||
2013 | ||||
2014 | #ifdef ALTQ | |||
2015 | case DIOCSTARTALTQ((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((42)))): { | |||
2016 | struct pf_altq *altq; | |||
2017 | ||||
2018 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2018); | |||
2019 | /* enable all altq interfaces on active list */ | |||
2020 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((pf_altqs_active)))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) { | |||
2021 | if (altq->qname[0] == 0 && (altq->local_flags & | |||
2022 | PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
2023 | error = pf_enable_altq(altq); | |||
2024 | if (error != 0) | |||
2025 | break; | |||
2026 | } | |||
2027 | } | |||
2028 | if (error == 0) | |||
2029 | V_pf_altq_running = 1; | |||
2030 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2030); | |||
2031 | DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("altq: started\n" ); | |||
2032 | break; | |||
2033 | } | |||
2034 | ||||
2035 | case DIOCSTOPALTQ((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((43)))): { | |||
2036 | struct pf_altq *altq; | |||
2037 | ||||
2038 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2038); | |||
2039 | /* disable all altq interfaces on active list */ | |||
2040 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((pf_altqs_active)))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) { | |||
2041 | if (altq->qname[0] == 0 && (altq->local_flags & | |||
2042 | PFALTQ_FLAG_IF_REMOVED0x01) == 0) { | |||
2043 | error = pf_disable_altq(altq); | |||
2044 | if (error != 0) | |||
2045 | break; | |||
2046 | } | |||
2047 | } | |||
2048 | if (error == 0) | |||
2049 | V_pf_altq_running = 0; | |||
2050 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2050); | |||
2051 | DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("altq: stopped\n" ); | |||
2052 | break; | |||
2053 | } | |||
2054 | ||||
2055 | case DIOCADDALTQ((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((45)))): { | |||
2056 | struct pfioc_altq *pa = (struct pfioc_altq *)addr; | |||
2057 | struct pf_altq *altq, *a; | |||
2058 | struct ifnet *ifp; | |||
2059 | ||||
2060 | altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK0x0002); | |||
2061 | bcopy(&pa->altq, altq, sizeof(struct pf_altq)); | |||
2062 | altq->local_flags = 0; | |||
2063 | ||||
2064 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2064); | |||
2065 | if (pa->ticket != V_ticket_altqs_inactive(ticket_altqs_inactive)) { | |||
2066 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2066); | |||
2067 | free(altq, M_PFALTQ); | |||
2068 | error = EBUSY16; | |||
2069 | break; | |||
2070 | } | |||
2071 | ||||
2072 | /* | |||
2073 | * if this is for a queue, find the discipline and | |||
2074 | * copy the necessary fields | |||
2075 | */ | |||
2076 | if (altq->qname[0] != 0) { | |||
2077 | if ((altq->qid = pf_qname2qid(altq->qname)) == 0) { | |||
2078 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2078); | |||
2079 | error = EBUSY16; | |||
2080 | free(altq, M_PFALTQ); | |||
2081 | break; | |||
2082 | } | |||
2083 | altq->altq_disc = NULL((void *)0); | |||
2084 | TAILQ_FOREACH(a, V_pf_altqs_inactive, entries)for ((a) = ((((pf_altqs_inactive)))->tqh_first); (a); (a) = (((a))->entries.tqe_next)) { | |||
2085 | if (strncmp(a->ifname, altq->ifname, | |||
2086 | IFNAMSIZ16) == 0 && a->qname[0] == 0) { | |||
2087 | altq->altq_disc = a->altq_disc; | |||
2088 | break; | |||
2089 | } | |||
2090 | } | |||
2091 | } | |||
2092 | ||||
2093 | if ((ifp = ifunit(altq->ifname)) == NULL((void *)0)) | |||
2094 | altq->local_flags |= PFALTQ_FLAG_IF_REMOVED0x01; | |||
2095 | else | |||
2096 | error = altq_add(altq); | |||
2097 | ||||
2098 | if (error) { | |||
2099 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2099); | |||
2100 | free(altq, M_PFALTQ); | |||
2101 | break; | |||
2102 | } | |||
2103 | ||||
2104 | TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries)do { ; (((altq))->entries.tqe_next) = ((void *)0); (altq)-> entries.tqe_prev = ((pf_altqs_inactive))->tqh_last; *((pf_altqs_inactive ))->tqh_last = (altq); ((pf_altqs_inactive))->tqh_last = &(((altq))->entries.tqe_next); ; ; } while (0); | |||
2105 | bcopy(altq, &pa->altq, sizeof(struct pf_altq)); | |||
2106 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2106); | |||
2107 | break; | |||
2108 | } | |||
2109 | ||||
2110 | case DIOCGETALTQS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((47)))): { | |||
2111 | struct pfioc_altq *pa = (struct pfioc_altq *)addr; | |||
2112 | struct pf_altq *altq; | |||
2113 | ||||
2114 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2114); | |||
2115 | pa->nr = 0; | |||
2116 | TAILQ_FOREACH(altq, V_pf_altqs_active, entries)for ((altq) = ((((pf_altqs_active)))->tqh_first); (altq); ( altq) = (((altq))->entries.tqe_next)) | |||
2117 | pa->nr++; | |||
2118 | pa->ticket = V_ticket_altqs_active(ticket_altqs_active); | |||
2119 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2119); | |||
2120 | break; | |||
2121 | } | |||
2122 | ||||
2123 | case DIOCGETALTQ((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((48)))): { | |||
2124 | struct pfioc_altq *pa = (struct pfioc_altq *)addr; | |||
2125 | struct pf_altq *altq; | |||
2126 | u_int32_t nr; | |||
2127 | ||||
2128 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2128); | |||
2129 | if (pa->ticket != V_ticket_altqs_active(ticket_altqs_active)) { | |||
2130 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2130); | |||
2131 | error = EBUSY16; | |||
2132 | break; | |||
2133 | } | |||
2134 | nr = 0; | |||
2135 | altq = TAILQ_FIRST(V_pf_altqs_active)(((pf_altqs_active))->tqh_first); | |||
2136 | while ((altq != NULL((void *)0)) && (nr < pa->nr)) { | |||
2137 | altq = TAILQ_NEXT(altq, entries)((altq)->entries.tqe_next); | |||
2138 | nr++; | |||
2139 | } | |||
2140 | if (altq == NULL((void *)0)) { | |||
2141 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2141); | |||
2142 | error = EBUSY16; | |||
2143 | break; | |||
2144 | } | |||
2145 | bcopy(altq, &pa->altq, sizeof(struct pf_altq)); | |||
2146 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2146); | |||
2147 | break; | |||
2148 | } | |||
2149 | ||||
2150 | case DIOCCHANGEALTQ((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_altq)) & ((1 << 13) - 1)) << 16) | ((( 'D')) << 8) | ((49)))): | |||
2151 | /* CHANGEALTQ not supported yet! */ | |||
2152 | error = ENODEV19; | |||
2153 | break; | |||
2154 | ||||
2155 | case DIOCGETQSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_qstats)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((50)))): { | |||
2156 | struct pfioc_qstats *pq = (struct pfioc_qstats *)addr; | |||
2157 | struct pf_altq *altq; | |||
2158 | u_int32_t nr; | |||
2159 | int nbytes; | |||
2160 | ||||
2161 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2161); | |||
2162 | if (pq->ticket != V_ticket_altqs_active(ticket_altqs_active)) { | |||
2163 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2163); | |||
2164 | error = EBUSY16; | |||
2165 | break; | |||
2166 | } | |||
2167 | nbytes = pq->nbytes; | |||
2168 | nr = 0; | |||
2169 | altq = TAILQ_FIRST(V_pf_altqs_active)(((pf_altqs_active))->tqh_first); | |||
2170 | while ((altq != NULL((void *)0)) && (nr < pq->nr)) { | |||
2171 | altq = TAILQ_NEXT(altq, entries)((altq)->entries.tqe_next); | |||
2172 | nr++; | |||
2173 | } | |||
2174 | if (altq == NULL((void *)0)) { | |||
2175 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2175); | |||
2176 | error = EBUSY16; | |||
2177 | break; | |||
2178 | } | |||
2179 | ||||
2180 | if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED0x01) != 0) { | |||
2181 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2181); | |||
2182 | error = ENXIO6; | |||
2183 | break; | |||
2184 | } | |||
2185 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2185); | |||
2186 | error = altq_getqstats(altq, pq->buf, &nbytes); | |||
2187 | if (error == 0) { | |||
2188 | pq->scheduler = altq->scheduler; | |||
2189 | pq->nbytes = nbytes; | |||
2190 | } | |||
2191 | break; | |||
2192 | } | |||
2193 | #endif /* ALTQ */ | |||
2194 | ||||
2195 | case DIOCBEGINADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((51)))): { | |||
2196 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
2197 | ||||
2198 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2198); | |||
2199 | pf_empty_pool(&V_pf_pabuf(pf_pabuf)); | |||
2200 | pp->ticket = ++V_ticket_pabuf(ticket_pabuf); | |||
2201 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2201); | |||
2202 | break; | |||
2203 | } | |||
2204 | ||||
2205 | case DIOCADDADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((52)))): { | |||
2206 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
2207 | struct pf_pooladdr *pa; | |||
2208 | struct pfi_kif *kif = NULL((void *)0); | |||
2209 | ||||
2210 | #ifndef INET1 | |||
2211 | if (pp->af == AF_INET2) { | |||
2212 | error = EAFNOSUPPORT47; | |||
2213 | break; | |||
2214 | } | |||
2215 | #endif /* INET */ | |||
2216 | #ifndef INET61 | |||
2217 | if (pp->af == AF_INET628) { | |||
2218 | error = EAFNOSUPPORT47; | |||
2219 | break; | |||
2220 | } | |||
2221 | #endif /* INET6 */ | |||
2222 | if (pp->addr.addr.type != PF_ADDR_ADDRMASK && | |||
2223 | pp->addr.addr.type != PF_ADDR_DYNIFTL && | |||
2224 | pp->addr.addr.type != PF_ADDR_TABLE) { | |||
2225 | error = EINVAL22; | |||
2226 | break; | |||
2227 | } | |||
2228 | pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK0x0002); | |||
2229 | bcopy(&pp->addr, pa, sizeof(struct pf_pooladdr)); | |||
2230 | if (pa->ifname[0]) | |||
2231 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
2232 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2232); | |||
2233 | if (pp->ticket != V_ticket_pabuf(ticket_pabuf)) { | |||
2234 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2234); | |||
2235 | if (pa->ifname[0]) | |||
2236 | free(kif, PFI_MTYPE); | |||
2237 | free(pa, M_PFRULE); | |||
2238 | error = EBUSY16; | |||
2239 | break; | |||
2240 | } | |||
2241 | if (pa->ifname[0]) { | |||
2242 | pa->kif = pfi_kif_attach(kif, pa->ifname); | |||
2243 | pfi_kif_ref(pa->kif); | |||
2244 | } else | |||
2245 | pa->kif = NULL((void *)0); | |||
2246 | if (pa->addr.type == PF_ADDR_DYNIFTL && ((error = | |||
2247 | pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) { | |||
2248 | if (pa->ifname[0]) | |||
2249 | pfi_kif_unref(pa->kif); | |||
2250 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2250); | |||
2251 | free(pa, M_PFRULE); | |||
2252 | break; | |||
2253 | } | |||
2254 | TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries)do { ; (((pa))->entries.tqe_next) = ((void *)0); (pa)-> entries.tqe_prev = (&(pf_pabuf))->tqh_last; *(&(pf_pabuf ))->tqh_last = (pa); (&(pf_pabuf))->tqh_last = & (((pa))->entries.tqe_next); ; ; } while (0); | |||
2255 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2255); | |||
2256 | break; | |||
2257 | } | |||
2258 | ||||
2259 | case DIOCGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((53)))): { | |||
2260 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
2261 | struct pf_pool *pool; | |||
2262 | struct pf_pooladdr *pa; | |||
2263 | ||||
2264 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2264); | |||
2265 | pp->nr = 0; | |||
2266 | pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action, | |||
2267 | pp->r_num, 0, 1, 0); | |||
2268 | if (pool == NULL((void *)0)) { | |||
2269 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2269); | |||
2270 | error = EBUSY16; | |||
2271 | break; | |||
2272 | } | |||
2273 | TAILQ_FOREACH(pa, &pool->list, entries)for ((pa) = (((&pool->list))->tqh_first); (pa); (pa ) = (((pa))->entries.tqe_next)) | |||
2274 | pp->nr++; | |||
2275 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2275); | |||
2276 | break; | |||
2277 | } | |||
2278 | ||||
2279 | case DIOCGETADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((54)))): { | |||
2280 | struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; | |||
2281 | struct pf_pool *pool; | |||
2282 | struct pf_pooladdr *pa; | |||
2283 | u_int32_t nr = 0; | |||
2284 | ||||
2285 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2285); | |||
2286 | pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action, | |||
2287 | pp->r_num, 0, 1, 1); | |||
2288 | if (pool == NULL((void *)0)) { | |||
2289 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2289); | |||
2290 | error = EBUSY16; | |||
2291 | break; | |||
2292 | } | |||
2293 | pa = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
2294 | while ((pa != NULL((void *)0)) && (nr < pp->nr)) { | |||
2295 | pa = TAILQ_NEXT(pa, entries)((pa)->entries.tqe_next); | |||
2296 | nr++; | |||
2297 | } | |||
2298 | if (pa == NULL((void *)0)) { | |||
2299 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2299); | |||
2300 | error = EBUSY16; | |||
2301 | break; | |||
2302 | } | |||
2303 | bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr)); | |||
2304 | pf_addr_copyout(&pp->addr.addr); | |||
2305 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2305); | |||
2306 | break; | |||
2307 | } | |||
2308 | ||||
2309 | case DIOCCHANGEADDR((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_pooladdr)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((55)))): { | |||
2310 | struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr; | |||
2311 | struct pf_pool *pool; | |||
2312 | struct pf_pooladdr *oldpa = NULL((void *)0), *newpa = NULL((void *)0); | |||
2313 | struct pf_ruleset *ruleset; | |||
2314 | struct pfi_kif *kif = NULL((void *)0); | |||
2315 | ||||
2316 | if (pca->action < PF_CHANGE_ADD_HEAD || | |||
2317 | pca->action > PF_CHANGE_REMOVE) { | |||
2318 | error = EINVAL22; | |||
2319 | break; | |||
2320 | } | |||
2321 | if (pca->addr.addr.type != PF_ADDR_ADDRMASK && | |||
2322 | pca->addr.addr.type != PF_ADDR_DYNIFTL && | |||
2323 | pca->addr.addr.type != PF_ADDR_TABLE) { | |||
2324 | error = EINVAL22; | |||
2325 | break; | |||
2326 | } | |||
2327 | ||||
2328 | if (pca->action != PF_CHANGE_REMOVE) { | |||
2329 | #ifndef INET1 | |||
2330 | if (pca->af == AF_INET2) { | |||
2331 | error = EAFNOSUPPORT47; | |||
2332 | break; | |||
2333 | } | |||
2334 | #endif /* INET */ | |||
2335 | #ifndef INET61 | |||
2336 | if (pca->af == AF_INET628) { | |||
2337 | error = EAFNOSUPPORT47; | |||
2338 | break; | |||
2339 | } | |||
2340 | #endif /* INET6 */ | |||
2341 | newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK0x0002); | |||
2342 | bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr)); | |||
2343 | if (newpa->ifname[0]) | |||
2344 | kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK0x0002); | |||
2345 | newpa->kif = NULL((void *)0); | |||
2346 | } | |||
2347 | ||||
2348 | #define ERROUT(x) { error = (x); goto DIOCCHANGEADDR_error; } | |||
2349 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2349); | |||
2350 | ruleset = pf_find_ruleset(pca->anchor); | |||
2351 | if (ruleset == NULL((void *)0)) | |||
2352 | ERROUT(EBUSY16); | |||
2353 | ||||
2354 | pool = pf_get_pool(pca->anchor, pca->ticket, pca->r_action, | |||
2355 | pca->r_num, pca->r_last, 1, 1); | |||
2356 | if (pool == NULL((void *)0)) | |||
2357 | ERROUT(EBUSY16); | |||
2358 | ||||
2359 | if (pca->action != PF_CHANGE_REMOVE) { | |||
2360 | if (newpa->ifname[0]) { | |||
2361 | newpa->kif = pfi_kif_attach(kif, newpa->ifname); | |||
2362 | pfi_kif_ref(newpa->kif); | |||
2363 | kif = NULL((void *)0); | |||
2364 | } | |||
2365 | ||||
2366 | switch (newpa->addr.type) { | |||
2367 | case PF_ADDR_DYNIFTL: | |||
2368 | error = pfi_dynaddr_setup(&newpa->addr, | |||
2369 | pca->af); | |||
2370 | break; | |||
2371 | case PF_ADDR_TABLE: | |||
2372 | newpa->addr.p.tbl = pfr_attach_table(ruleset, | |||
2373 | newpa->addr.v.tblname); | |||
2374 | if (newpa->addr.p.tbl == NULL((void *)0)) | |||
2375 | error = ENOMEM12; | |||
2376 | break; | |||
2377 | } | |||
2378 | if (error) | |||
2379 | goto DIOCCHANGEADDR_error; | |||
2380 | } | |||
2381 | ||||
2382 | switch (pca->action) { | |||
2383 | case PF_CHANGE_ADD_HEAD: | |||
2384 | oldpa = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
2385 | break; | |||
2386 | case PF_CHANGE_ADD_TAIL: | |||
2387 | oldpa = TAILQ_LAST(&pool->list, pf_palist)(*(((struct pf_palist *)((&pool->list)->tqh_last))-> tqh_last)); | |||
2388 | break; | |||
2389 | default: | |||
2390 | oldpa = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
2391 | for (int i = 0; oldpa && i < pca->nr; i++) | |||
2392 | oldpa = TAILQ_NEXT(oldpa, entries)((oldpa)->entries.tqe_next); | |||
2393 | ||||
2394 | if (oldpa == NULL((void *)0)) | |||
2395 | ERROUT(EINVAL22); | |||
2396 | } | |||
2397 | ||||
2398 | if (pca->action == PF_CHANGE_REMOVE) { | |||
2399 | TAILQ_REMOVE(&pool->list, oldpa, entries)do { ; ; ; ; 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); | |||
2400 | switch (oldpa->addr.type) { | |||
2401 | case PF_ADDR_DYNIFTL: | |||
2402 | pfi_dynaddr_remove(oldpa->addr.p.dyn); | |||
2403 | break; | |||
2404 | case PF_ADDR_TABLE: | |||
2405 | pfr_detach_table(oldpa->addr.p.tbl); | |||
2406 | break; | |||
2407 | } | |||
2408 | if (oldpa->kif) | |||
2409 | pfi_kif_unref(oldpa->kif); | |||
2410 | free(oldpa, M_PFRULE); | |||
2411 | } else { | |||
2412 | if (oldpa == NULL((void *)0)) | |||
2413 | TAILQ_INSERT_TAIL(&pool->list, newpa, entries)do { ; (((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); | |||
2414 | else if (pca->action == PF_CHANGE_ADD_HEAD || | |||
2415 | pca->action == PF_CHANGE_ADD_BEFORE) | |||
2416 | TAILQ_INSERT_BEFORE(oldpa, newpa, entries)do { ; (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); | |||
2417 | else | |||
2418 | TAILQ_INSERT_AFTER(&pool->list, oldpa,do { ; 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) | |||
2419 | newpa, entries)do { ; 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); | |||
2420 | } | |||
2421 | ||||
2422 | pool->cur = TAILQ_FIRST(&pool->list)((&pool->list)->tqh_first); | |||
2423 | PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af)pf_addrcpy(&pool->counter, &pool->cur->addr. v.a.addr, pca->af); | |||
2424 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2424); | |||
2425 | break; | |||
2426 | ||||
2427 | #undef ERROUT | |||
2428 | DIOCCHANGEADDR_error: | |||
2429 | if (newpa->kif) | |||
2430 | pfi_kif_unref(newpa->kif); | |||
2431 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2431); | |||
2432 | if (newpa != NULL((void *)0)) | |||
2433 | free(newpa, M_PFRULE); | |||
2434 | if (kif != NULL((void *)0)) | |||
2435 | free(kif, PFI_MTYPE); | |||
2436 | break; | |||
2437 | } | |||
2438 | ||||
2439 | case DIOCGETRULESETS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((58)))): { | |||
2440 | struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; | |||
2441 | struct pf_ruleset *ruleset; | |||
2442 | struct pf_anchor *anchor; | |||
2443 | ||||
2444 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2444); | |||
2445 | pr->path[sizeof(pr->path) - 1] = 0; | |||
2446 | if ((ruleset = pf_find_ruleset(pr->path)) == NULL((void *)0)) { | |||
2447 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2447); | |||
2448 | error = ENOENT2; | |||
2449 | break; | |||
2450 | } | |||
2451 | pr->nr = 0; | |||
2452 | if (ruleset->anchor == NULL((void *)0)) { | |||
2453 | /* XXX kludge for pf_main_ruleset */ | |||
2454 | RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)for ((anchor) = pf_anchor_global_RB_MINMAX(&(pf_anchors), -1); (anchor) != ((void *)0); (anchor) = pf_anchor_global_RB_NEXT (anchor)) | |||
2455 | if (anchor->parent == NULL((void *)0)) | |||
2456 | pr->nr++; | |||
2457 | } else { | |||
2458 | 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)) | |||
2459 | &ruleset->anchor->children)for ((anchor) = pf_anchor_node_RB_MINMAX(&ruleset->anchor ->children, -1); (anchor) != ((void *)0); (anchor) = pf_anchor_node_RB_NEXT (anchor)) | |||
2460 | pr->nr++; | |||
2461 | } | |||
2462 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2462); | |||
2463 | break; | |||
2464 | } | |||
2465 | ||||
2466 | case DIOCGETRULESET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_ruleset)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((59)))): { | |||
2467 | struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; | |||
2468 | struct pf_ruleset *ruleset; | |||
2469 | struct pf_anchor *anchor; | |||
2470 | u_int32_t nr = 0; | |||
2471 | ||||
2472 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2472); | |||
2473 | pr->path[sizeof(pr->path) - 1] = 0; | |||
2474 | if ((ruleset = pf_find_ruleset(pr->path)) == NULL((void *)0)) { | |||
2475 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2475); | |||
2476 | error = ENOENT2; | |||
2477 | break; | |||
2478 | } | |||
2479 | pr->name[0] = 0; | |||
2480 | if (ruleset->anchor == NULL((void *)0)) { | |||
2481 | /* XXX kludge for pf_main_ruleset */ | |||
2482 | RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)for ((anchor) = pf_anchor_global_RB_MINMAX(&(pf_anchors), -1); (anchor) != ((void *)0); (anchor) = pf_anchor_global_RB_NEXT (anchor)) | |||
2483 | if (anchor->parent == NULL((void *)0) && nr++ == pr->nr) { | |||
2484 | strlcpy(pr->name, anchor->name, | |||
2485 | sizeof(pr->name)); | |||
2486 | break; | |||
2487 | } | |||
2488 | } else { | |||
2489 | 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)) | |||
2490 | &ruleset->anchor->children)for ((anchor) = pf_anchor_node_RB_MINMAX(&ruleset->anchor ->children, -1); (anchor) != ((void *)0); (anchor) = pf_anchor_node_RB_NEXT (anchor)) | |||
2491 | if (nr++ == pr->nr) { | |||
2492 | strlcpy(pr->name, anchor->name, | |||
2493 | sizeof(pr->name)); | |||
2494 | break; | |||
2495 | } | |||
2496 | } | |||
2497 | if (!pr->name[0]) | |||
2498 | error = EBUSY16; | |||
2499 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2499); | |||
2500 | break; | |||
2501 | } | |||
2502 | ||||
2503 | case DIOCRCLRTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((60)))): { | |||
2504 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2505 | ||||
2506 | if (io->pfrio_esize != 0) { | |||
2507 | error = ENODEV19; | |||
2508 | break; | |||
2509 | } | |||
2510 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2510); | |||
2511 | error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, | |||
2512 | io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2513 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2513); | |||
2514 | break; | |||
2515 | } | |||
2516 | ||||
2517 | case DIOCRADDTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((61)))): { | |||
2518 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2519 | struct pfr_table *pfrts; | |||
2520 | size_t totlen; | |||
2521 | ||||
2522 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
2523 | error = ENODEV19; | |||
2524 | break; | |||
2525 | } | |||
2526 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
2527 | pfrts = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2528 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
2529 | if (error) { | |||
2530 | free(pfrts, M_TEMP); | |||
2531 | break; | |||
2532 | } | |||
2533 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2533); | |||
2534 | error = pfr_add_tables(pfrts, io->pfrio_size, | |||
2535 | &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2536 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2536); | |||
2537 | free(pfrts, M_TEMP); | |||
2538 | break; | |||
2539 | } | |||
2540 | ||||
2541 | case DIOCRDELTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((62)))): { | |||
2542 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2543 | struct pfr_table *pfrts; | |||
2544 | size_t totlen; | |||
2545 | ||||
2546 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
2547 | error = ENODEV19; | |||
2548 | break; | |||
2549 | } | |||
2550 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
2551 | pfrts = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2552 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
2553 | if (error) { | |||
2554 | free(pfrts, M_TEMP); | |||
2555 | break; | |||
2556 | } | |||
2557 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2557); | |||
2558 | error = pfr_del_tables(pfrts, io->pfrio_size, | |||
2559 | &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2560 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2560); | |||
2561 | free(pfrts, M_TEMP); | |||
2562 | break; | |||
2563 | } | |||
2564 | ||||
2565 | case DIOCRGETTABLES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((63)))): { | |||
2566 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2567 | struct pfr_table *pfrts; | |||
2568 | size_t totlen; | |||
2569 | ||||
2570 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
2571 | error = ENODEV19; | |||
2572 | break; | |||
2573 | } | |||
2574 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
2575 | pfrts = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2576 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2576); | |||
2577 | error = pfr_get_tables(&io->pfrio_table, pfrts, | |||
2578 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2579 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2579); | |||
2580 | if (error == 0) | |||
2581 | error = copyout(pfrts, io->pfrio_buffer, totlen); | |||
2582 | free(pfrts, M_TEMP); | |||
2583 | break; | |||
2584 | } | |||
2585 | ||||
2586 | case DIOCRGETTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((64)))): { | |||
2587 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2588 | struct pfr_tstats *pfrtstats; | |||
2589 | size_t totlen; | |||
2590 | ||||
2591 | if (io->pfrio_esize != sizeof(struct pfr_tstats)) { | |||
2592 | error = ENODEV19; | |||
2593 | break; | |||
2594 | } | |||
2595 | totlen = io->pfrio_size * sizeof(struct pfr_tstats); | |||
2596 | pfrtstats = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2597 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2597); | |||
2598 | error = pfr_get_tstats(&io->pfrio_table, pfrtstats, | |||
2599 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2600 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2600); | |||
2601 | if (error == 0) | |||
2602 | error = copyout(pfrtstats, io->pfrio_buffer, totlen); | |||
2603 | free(pfrtstats, M_TEMP); | |||
2604 | break; | |||
2605 | } | |||
2606 | ||||
2607 | case DIOCRCLRTSTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((65)))): { | |||
2608 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2609 | struct pfr_table *pfrts; | |||
2610 | size_t totlen; | |||
2611 | ||||
2612 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
2613 | error = ENODEV19; | |||
2614 | break; | |||
2615 | } | |||
2616 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
2617 | pfrts = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2618 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
2619 | if (error) { | |||
2620 | free(pfrts, M_TEMP); | |||
2621 | break; | |||
2622 | } | |||
2623 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2623); | |||
2624 | error = pfr_clr_tstats(pfrts, io->pfrio_size, | |||
2625 | &io->pfrio_nzeropfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2626 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2626); | |||
2627 | free(pfrts, M_TEMP); | |||
2628 | break; | |||
2629 | } | |||
2630 | ||||
2631 | case DIOCRSETTFLAGS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((74)))): { | |||
2632 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2633 | struct pfr_table *pfrts; | |||
2634 | size_t totlen; | |||
2635 | ||||
2636 | if (io->pfrio_esize != sizeof(struct pfr_table)) { | |||
2637 | error = ENODEV19; | |||
2638 | break; | |||
2639 | } | |||
2640 | totlen = io->pfrio_size * sizeof(struct pfr_table); | |||
2641 | pfrts = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2642 | error = copyin(io->pfrio_buffer, pfrts, totlen); | |||
2643 | if (error) { | |||
2644 | free(pfrts, M_TEMP); | |||
2645 | break; | |||
2646 | } | |||
2647 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2647); | |||
2648 | error = pfr_set_tflags(pfrts, io->pfrio_size, | |||
2649 | io->pfrio_setflagpfrio_size2, io->pfrio_clrflagpfrio_nadd, &io->pfrio_nchange, | |||
2650 | &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2651 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2651); | |||
2652 | free(pfrts, M_TEMP); | |||
2653 | break; | |||
2654 | } | |||
2655 | ||||
2656 | case DIOCRCLRADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((66)))): { | |||
2657 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2658 | ||||
2659 | if (io->pfrio_esize != 0) { | |||
2660 | error = ENODEV19; | |||
2661 | break; | |||
2662 | } | |||
2663 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2663); | |||
2664 | error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel, | |||
2665 | io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2666 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2666); | |||
2667 | break; | |||
2668 | } | |||
2669 | ||||
2670 | case DIOCRADDADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((67)))): { | |||
2671 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2672 | struct pfr_addr *pfras; | |||
2673 | size_t totlen; | |||
2674 | ||||
2675 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2676 | error = ENODEV19; | |||
2677 | break; | |||
2678 | } | |||
2679 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
2680 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2681 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
2682 | if (error) { | |||
2683 | free(pfras, M_TEMP); | |||
2684 | break; | |||
2685 | } | |||
2686 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2686); | |||
2687 | error = pfr_add_addrs(&io->pfrio_table, pfras, | |||
2688 | io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags | | |||
2689 | PFR_FLAG_USERIOCTL0x10000000); | |||
2690 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2690); | |||
2691 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
2692 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
2693 | free(pfras, M_TEMP); | |||
2694 | break; | |||
2695 | } | |||
2696 | ||||
2697 | case DIOCRDELADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((68)))): { | |||
2698 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2699 | struct pfr_addr *pfras; | |||
2700 | size_t totlen; | |||
2701 | ||||
2702 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2703 | error = ENODEV19; | |||
2704 | break; | |||
2705 | } | |||
2706 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
2707 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2708 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
2709 | if (error) { | |||
2710 | free(pfras, M_TEMP); | |||
2711 | break; | |||
2712 | } | |||
2713 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2713); | |||
2714 | error = pfr_del_addrs(&io->pfrio_table, pfras, | |||
2715 | io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags | | |||
2716 | PFR_FLAG_USERIOCTL0x10000000); | |||
2717 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2717); | |||
2718 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
2719 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
2720 | free(pfras, M_TEMP); | |||
2721 | break; | |||
2722 | } | |||
2723 | ||||
2724 | case DIOCRSETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((69)))): { | |||
2725 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2726 | struct pfr_addr *pfras; | |||
2727 | size_t totlen, count; | |||
2728 | ||||
2729 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2730 | error = ENODEV19; | |||
2731 | break; | |||
2732 | } | |||
2733 | count = max(io->pfrio_size, io->pfrio_size2); | |||
2734 | totlen = count * sizeof(struct pfr_addr); | |||
2735 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2736 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
2737 | if (error) { | |||
2738 | free(pfras, M_TEMP); | |||
2739 | break; | |||
2740 | } | |||
2741 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2741); | |||
2742 | error = pfr_set_addrs(&io->pfrio_table, pfras, | |||
2743 | io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd, | |||
2744 | &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags | | |||
2745 | PFR_FLAG_USERIOCTL0x10000000, 0); | |||
2746 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2746); | |||
2747 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
2748 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
2749 | free(pfras, M_TEMP); | |||
2750 | break; | |||
2751 | } | |||
2752 | ||||
2753 | case DIOCRGETADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((70)))): { | |||
2754 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2755 | struct pfr_addr *pfras; | |||
2756 | size_t totlen; | |||
2757 | ||||
2758 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2759 | error = ENODEV19; | |||
2760 | break; | |||
2761 | } | |||
2762 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
2763 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2764 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2764); | |||
2765 | error = pfr_get_addrs(&io->pfrio_table, pfras, | |||
2766 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2767 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2767); | |||
2768 | if (error == 0) | |||
2769 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
2770 | free(pfras, M_TEMP); | |||
2771 | break; | |||
2772 | } | |||
2773 | ||||
2774 | case DIOCRGETASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((71)))): { | |||
2775 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2776 | struct pfr_astats *pfrastats; | |||
2777 | size_t totlen; | |||
2778 | ||||
2779 | if (io->pfrio_esize != sizeof(struct pfr_astats)) { | |||
2780 | error = ENODEV19; | |||
2781 | break; | |||
2782 | } | |||
2783 | totlen = io->pfrio_size * sizeof(struct pfr_astats); | |||
2784 | pfrastats = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2785 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2785); | |||
2786 | error = pfr_get_astats(&io->pfrio_table, pfrastats, | |||
2787 | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2788 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2788); | |||
2789 | if (error == 0) | |||
2790 | error = copyout(pfrastats, io->pfrio_buffer, totlen); | |||
2791 | free(pfrastats, M_TEMP); | |||
2792 | break; | |||
2793 | } | |||
2794 | ||||
2795 | case DIOCRCLRASTATS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((72)))): { | |||
2796 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2797 | struct pfr_addr *pfras; | |||
2798 | size_t totlen; | |||
2799 | ||||
2800 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2801 | error = ENODEV19; | |||
2802 | break; | |||
2803 | } | |||
2804 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
2805 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2806 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
2807 | if (error) { | |||
2808 | free(pfras, M_TEMP); | |||
2809 | break; | |||
2810 | } | |||
2811 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2811); | |||
2812 | error = pfr_clr_astats(&io->pfrio_table, pfras, | |||
2813 | io->pfrio_size, &io->pfrio_nzeropfrio_nadd, io->pfrio_flags | | |||
2814 | PFR_FLAG_USERIOCTL0x10000000); | |||
2815 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2815); | |||
2816 | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK0x00000004) | |||
2817 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
2818 | free(pfras, M_TEMP); | |||
2819 | break; | |||
2820 | } | |||
2821 | ||||
2822 | case DIOCRTSTADDRS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((73)))): { | |||
2823 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2824 | struct pfr_addr *pfras; | |||
2825 | size_t totlen; | |||
2826 | ||||
2827 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2828 | error = ENODEV19; | |||
2829 | break; | |||
2830 | } | |||
2831 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
2832 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2833 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
2834 | if (error) { | |||
2835 | free(pfras, M_TEMP); | |||
2836 | break; | |||
2837 | } | |||
2838 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2838); | |||
2839 | error = pfr_tst_addrs(&io->pfrio_table, pfras, | |||
2840 | io->pfrio_size, &io->pfrio_nmatchpfrio_nadd, io->pfrio_flags | | |||
2841 | PFR_FLAG_USERIOCTL0x10000000); | |||
2842 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2842); | |||
2843 | if (error == 0) | |||
2844 | error = copyout(pfras, io->pfrio_buffer, totlen); | |||
2845 | free(pfras, M_TEMP); | |||
2846 | break; | |||
2847 | } | |||
2848 | ||||
2849 | case DIOCRINADEFINE((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_table)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((77)))): { | |||
2850 | struct pfioc_table *io = (struct pfioc_table *)addr; | |||
2851 | struct pfr_addr *pfras; | |||
2852 | size_t totlen; | |||
2853 | ||||
2854 | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | |||
2855 | error = ENODEV19; | |||
2856 | break; | |||
2857 | } | |||
2858 | totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||
2859 | pfras = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2860 | error = copyin(io->pfrio_buffer, pfras, totlen); | |||
2861 | if (error) { | |||
2862 | free(pfras, M_TEMP); | |||
2863 | break; | |||
2864 | } | |||
2865 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2865); | |||
2866 | error = pfr_ina_define(&io->pfrio_table, pfras, | |||
2867 | io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddrpfrio_size2, | |||
2868 | io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL0x10000000); | |||
2869 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2869); | |||
2870 | free(pfras, M_TEMP); | |||
2871 | break; | |||
2872 | } | |||
2873 | ||||
2874 | case DIOCOSFPADD((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((79)))): { | |||
2875 | struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; | |||
2876 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2876); | |||
2877 | error = pf_osfp_add(io); | |||
2878 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2878); | |||
2879 | break; | |||
2880 | } | |||
2881 | ||||
2882 | case DIOCOSFPGET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pf_osfp_ioctl)) & ((1 << 13) - 1)) << 16) | ( (('D')) << 8) | ((80)))): { | |||
2883 | struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; | |||
2884 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2884); | |||
2885 | error = pf_osfp_get(io); | |||
2886 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2886); | |||
2887 | break; | |||
2888 | } | |||
2889 | ||||
2890 | case DIOCXBEGIN((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_trans)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((81)))): { | |||
2891 | struct pfioc_trans *io = (struct pfioc_trans *)addr; | |||
2892 | struct pfioc_trans_e *ioes, *ioe; | |||
2893 | size_t totlen; | |||
2894 | int i; | |||
2895 | ||||
2896 | if (io->esize != sizeof(*ioe)) { | |||
2897 | error = ENODEV19; | |||
2898 | break; | |||
2899 | } | |||
2900 | totlen = sizeof(struct pfioc_trans_e) * io->size; | |||
2901 | ioes = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2902 | error = copyin(io->array, ioes, totlen); | |||
2903 | if (error) { | |||
2904 | free(ioes, M_TEMP); | |||
2905 | break; | |||
2906 | } | |||
2907 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2907); | |||
2908 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
2909 | switch (ioe->rs_num) { | |||
2910 | #ifdef ALTQ | |||
2911 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
2912 | if (ioe->anchor[0]) { | |||
2913 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2913); | |||
2914 | free(ioes, M_TEMP); | |||
2915 | error = EINVAL22; | |||
2916 | goto fail; | |||
2917 | } | |||
2918 | if ((error = pf_begin_altq(&ioe->ticket))) { | |||
2919 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2919); | |||
2920 | free(ioes, M_TEMP); | |||
2921 | goto fail; | |||
2922 | } | |||
2923 | break; | |||
2924 | #endif /* ALTQ */ | |||
2925 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
2926 | { | |||
2927 | struct pfr_table table; | |||
2928 | ||||
2929 | bzero(&table, sizeof(table)); | |||
2930 | strlcpy(table.pfrt_anchor, ioe->anchor, | |||
2931 | sizeof(table.pfrt_anchor)); | |||
2932 | if ((error = pfr_ina_begin(&table, | |||
2933 | &ioe->ticket, NULL((void *)0), 0))) { | |||
2934 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2934); | |||
2935 | free(ioes, M_TEMP); | |||
2936 | goto fail; | |||
2937 | } | |||
2938 | break; | |||
2939 | } | |||
2940 | default: | |||
2941 | if ((error = pf_begin_rules(&ioe->ticket, | |||
2942 | ioe->rs_num, ioe->anchor))) { | |||
2943 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2943); | |||
2944 | free(ioes, M_TEMP); | |||
2945 | goto fail; | |||
2946 | } | |||
2947 | break; | |||
2948 | } | |||
2949 | } | |||
2950 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2950); | |||
2951 | error = copyout(ioes, io->array, totlen); | |||
2952 | free(ioes, M_TEMP); | |||
2953 | break; | |||
2954 | } | |||
2955 | ||||
2956 | case DIOCXROLLBACK((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_trans)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((83)))): { | |||
2957 | struct pfioc_trans *io = (struct pfioc_trans *)addr; | |||
2958 | struct pfioc_trans_e *ioe, *ioes; | |||
2959 | size_t totlen; | |||
2960 | int i; | |||
2961 | ||||
2962 | if (io->esize != sizeof(*ioe)) { | |||
2963 | error = ENODEV19; | |||
2964 | break; | |||
2965 | } | |||
2966 | totlen = sizeof(struct pfioc_trans_e) * io->size; | |||
2967 | ioes = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
2968 | error = copyin(io->array, ioes, totlen); | |||
2969 | if (error) { | |||
2970 | free(ioes, M_TEMP); | |||
2971 | break; | |||
2972 | } | |||
2973 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2973); | |||
2974 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
2975 | switch (ioe->rs_num) { | |||
2976 | #ifdef ALTQ | |||
2977 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
2978 | if (ioe->anchor[0]) { | |||
2979 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2979); | |||
2980 | free(ioes, M_TEMP); | |||
2981 | error = EINVAL22; | |||
2982 | goto fail; | |||
2983 | } | |||
2984 | if ((error = pf_rollback_altq(ioe->ticket))) { | |||
2985 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 2985); | |||
2986 | free(ioes, M_TEMP); | |||
2987 | goto fail; /* really bad */ | |||
2988 | } | |||
2989 | break; | |||
2990 | #endif /* ALTQ */ | |||
2991 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
2992 | { | |||
2993 | struct pfr_table table; | |||
2994 | ||||
2995 | bzero(&table, sizeof(table)); | |||
2996 | strlcpy(table.pfrt_anchor, ioe->anchor, | |||
2997 | sizeof(table.pfrt_anchor)); | |||
2998 | if ((error = pfr_ina_rollback(&table, | |||
2999 | ioe->ticket, NULL((void *)0), 0))) { | |||
3000 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3000); | |||
3001 | free(ioes, M_TEMP); | |||
3002 | goto fail; /* really bad */ | |||
3003 | } | |||
3004 | break; | |||
3005 | } | |||
3006 | default: | |||
3007 | if ((error = pf_rollback_rules(ioe->ticket, | |||
3008 | ioe->rs_num, ioe->anchor))) { | |||
3009 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3009); | |||
3010 | free(ioes, M_TEMP); | |||
3011 | goto fail; /* really bad */ | |||
3012 | } | |||
3013 | break; | |||
3014 | } | |||
3015 | } | |||
3016 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3016); | |||
3017 | free(ioes, M_TEMP); | |||
3018 | break; | |||
3019 | } | |||
3020 | ||||
3021 | case DIOCXCOMMIT((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_trans)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((82)))): { | |||
3022 | struct pfioc_trans *io = (struct pfioc_trans *)addr; | |||
3023 | struct pfioc_trans_e *ioe, *ioes; | |||
3024 | struct pf_ruleset *rs; | |||
3025 | size_t totlen; | |||
3026 | int i; | |||
3027 | ||||
3028 | if (io->esize != sizeof(*ioe)) { | |||
3029 | error = ENODEV19; | |||
3030 | break; | |||
3031 | } | |||
3032 | totlen = sizeof(struct pfioc_trans_e) * io->size; | |||
3033 | ioes = malloc(totlen, M_TEMP, M_WAITOK0x0002); | |||
3034 | error = copyin(io->array, ioes, totlen); | |||
3035 | if (error) { | |||
3036 | free(ioes, M_TEMP); | |||
3037 | break; | |||
3038 | } | |||
3039 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3039); | |||
3040 | /* First makes sure everything will succeed. */ | |||
3041 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
3042 | switch (ioe->rs_num) { | |||
3043 | #ifdef ALTQ | |||
3044 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
3045 | if (ioe->anchor[0]) { | |||
3046 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3046); | |||
3047 | free(ioes, M_TEMP); | |||
3048 | error = EINVAL22; | |||
3049 | goto fail; | |||
3050 | } | |||
3051 | if (!V_altqs_inactive_open(altqs_inactive_open) || ioe->ticket != | |||
3052 | V_ticket_altqs_inactive(ticket_altqs_inactive)) { | |||
3053 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3053); | |||
3054 | free(ioes, M_TEMP); | |||
3055 | error = EBUSY16; | |||
3056 | goto fail; | |||
3057 | } | |||
3058 | break; | |||
3059 | #endif /* ALTQ */ | |||
3060 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
3061 | rs = pf_find_ruleset(ioe->anchor); | |||
3062 | if (rs == NULL((void *)0) || !rs->topen || ioe->ticket != | |||
3063 | rs->tticket) { | |||
3064 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3064); | |||
3065 | free(ioes, M_TEMP); | |||
3066 | error = EBUSY16; | |||
3067 | goto fail; | |||
3068 | } | |||
3069 | break; | |||
3070 | default: | |||
3071 | if (ioe->rs_num < 0 || ioe->rs_num >= | |||
3072 | PF_RULESET_MAX) { | |||
3073 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3073); | |||
3074 | free(ioes, M_TEMP); | |||
3075 | error = EINVAL22; | |||
3076 | goto fail; | |||
3077 | } | |||
3078 | rs = pf_find_ruleset(ioe->anchor); | |||
3079 | if (rs == NULL((void *)0) || | |||
3080 | !rs->rules[ioe->rs_num].inactive.open || | |||
3081 | rs->rules[ioe->rs_num].inactive.ticket != | |||
3082 | ioe->ticket) { | |||
3083 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3083); | |||
3084 | free(ioes, M_TEMP); | |||
3085 | error = EBUSY16; | |||
3086 | goto fail; | |||
3087 | } | |||
3088 | break; | |||
3089 | } | |||
3090 | } | |||
3091 | /* Now do the commit - no errors should happen here. */ | |||
3092 | for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { | |||
3093 | switch (ioe->rs_num) { | |||
3094 | #ifdef ALTQ | |||
3095 | case PF_RULESET_ALTQ(PF_RULESET_MAX): | |||
3096 | if ((error = pf_commit_altq(ioe->ticket))) { | |||
3097 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3097); | |||
3098 | free(ioes, M_TEMP); | |||
3099 | goto fail; /* really bad */ | |||
3100 | } | |||
3101 | break; | |||
3102 | #endif /* ALTQ */ | |||
3103 | case PF_RULESET_TABLE(PF_RULESET_MAX+1): | |||
3104 | { | |||
3105 | struct pfr_table table; | |||
3106 | ||||
3107 | bzero(&table, sizeof(table)); | |||
3108 | strlcpy(table.pfrt_anchor, ioe->anchor, | |||
3109 | sizeof(table.pfrt_anchor)); | |||
3110 | if ((error = pfr_ina_commit(&table, | |||
3111 | ioe->ticket, NULL((void *)0), NULL((void *)0), 0))) { | |||
3112 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3112); | |||
3113 | free(ioes, M_TEMP); | |||
3114 | goto fail; /* really bad */ | |||
3115 | } | |||
3116 | break; | |||
3117 | } | |||
3118 | default: | |||
3119 | if ((error = pf_commit_rules(ioe->ticket, | |||
3120 | ioe->rs_num, ioe->anchor))) { | |||
3121 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3121); | |||
3122 | free(ioes, M_TEMP); | |||
3123 | goto fail; /* really bad */ | |||
3124 | } | |||
3125 | break; | |||
3126 | } | |||
3127 | } | |||
3128 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3128); | |||
3129 | free(ioes, M_TEMP); | |||
3130 | break; | |||
3131 | } | |||
3132 | ||||
3133 | case DIOCGETSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_nodes)) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((84)))): { | |||
3134 | struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr; | |||
3135 | struct pf_srchash *sh; | |||
3136 | struct pf_src_node *n, *p, *pstore; | |||
3137 | uint32_t i, nr = 0; | |||
3138 | ||||
3139 | if (psn->psn_len == 0) { | |||
3140 | for (i = 0, sh = V_pf_srchash(pf_srchash); i <= pf_srchashmask; | |||
3141 | i++, sh++) { | |||
3142 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3142)); | |||
3143 | LIST_FOREACH(n, &sh->nodes, entry)for ((n) = (((&sh->nodes))->lh_first); (n); (n) = ( ((n))->entry.le_next)) | |||
3144 | nr++; | |||
3145 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3145)); | |||
3146 | } | |||
3147 | psn->psn_len = sizeof(struct pf_src_node) * nr; | |||
3148 | break; | |||
3149 | } | |||
3150 | ||||
3151 | p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK0x0002); | |||
3152 | for (i = 0, sh = V_pf_srchash(pf_srchash); i <= pf_srchashmask; | |||
3153 | i++, sh++) { | |||
3154 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3154)); | |||
3155 | LIST_FOREACH(n, &sh->nodes, entry)for ((n) = (((&sh->nodes))->lh_first); (n); (n) = ( ((n))->entry.le_next)) { | |||
3156 | int secs = time_uptime, diff; | |||
3157 | ||||
3158 | if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len) | |||
3159 | break; | |||
3160 | ||||
3161 | bcopy(n, p, sizeof(struct pf_src_node)); | |||
3162 | if (n->rule.ptr != NULL((void *)0)) | |||
3163 | p->rule.nr = n->rule.ptr->nr; | |||
3164 | p->creation = secs - p->creation; | |||
3165 | if (p->expire > secs) | |||
3166 | p->expire -= secs; | |||
3167 | else | |||
3168 | p->expire = 0; | |||
3169 | ||||
3170 | /* Adjust the connection rate estimate. */ | |||
3171 | diff = secs - n->conn_rate.last; | |||
3172 | if (diff >= n->conn_rate.seconds) | |||
3173 | p->conn_rate.count = 0; | |||
3174 | else | |||
3175 | p->conn_rate.count -= | |||
3176 | n->conn_rate.count * diff / | |||
3177 | n->conn_rate.seconds; | |||
3178 | p++; | |||
3179 | nr++; | |||
3180 | } | |||
3181 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3181)); | |||
3182 | } | |||
3183 | error = copyout(pstore, psn->psn_src_nodespsn_u.psu_src_nodes, | |||
3184 | sizeof(struct pf_src_node) * nr); | |||
3185 | if (error) { | |||
3186 | free(pstore, M_TEMP); | |||
3187 | break; | |||
3188 | } | |||
3189 | psn->psn_len = sizeof(struct pf_src_node) * nr; | |||
3190 | free(pstore, M_TEMP); | |||
3191 | break; | |||
3192 | } | |||
3193 | ||||
3194 | case DIOCCLRSRCNODES((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((85)))): { | |||
3195 | ||||
3196 | pf_clear_srcnodes(NULL((void *)0)); | |||
3197 | pf_purge_expired_src_nodes(); | |||
3198 | break; | |||
3199 | } | |||
3200 | ||||
3201 | case DIOCKILLSRCNODES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_src_node_kill)) & ((1 << 13) - 1)) << 16 ) | ((('D')) << 8) | ((91)))): | |||
3202 | pf_kill_srcnodes((struct pfioc_src_node_kill *)addr); | |||
3203 | break; | |||
3204 | ||||
3205 | case DIOCSETHOSTID((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(u_int32_t )) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((86)))): { | |||
3206 | u_int32_t *hostid = (u_int32_t *)addr; | |||
3207 | ||||
3208 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3208); | |||
3209 | if (*hostid == 0) | |||
3210 | V_pf_status(pf_status).hostid = arc4random(); | |||
3211 | else | |||
3212 | V_pf_status(pf_status).hostid = *hostid; | |||
3213 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3213); | |||
3214 | break; | |||
3215 | } | |||
3216 | ||||
3217 | case DIOCOSFPFLUSH((unsigned long) ((0x20000000) | (((0) & ((1 << 13) - 1)) << 16) | ((('D')) << 8) | ((78)))): | |||
3218 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3218); | |||
3219 | pf_osfp_flush(); | |||
3220 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3220); | |||
3221 | break; | |||
3222 | ||||
3223 | case DIOCIGETIFACES((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((87)))): { | |||
3224 | struct pfioc_iface *io = (struct pfioc_iface *)addr; | |||
3225 | struct pfi_kif *ifstore; | |||
3226 | size_t bufsiz; | |||
3227 | ||||
3228 | if (io->pfiio_esize != sizeof(struct pfi_kif)) { | |||
3229 | error = ENODEV19; | |||
3230 | break; | |||
3231 | } | |||
3232 | ||||
3233 | bufsiz = io->pfiio_size * sizeof(struct pfi_kif); | |||
3234 | ifstore = malloc(bufsiz, M_TEMP, M_WAITOK0x0002); | |||
3235 | PF_RULES_RLOCK()__rw_rlock(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3235); | |||
3236 | pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size); | |||
3237 | PF_RULES_RUNLOCK()_rw_runlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3237); | |||
3238 | error = copyout(ifstore, io->pfiio_buffer, bufsiz); | |||
| ||||
3239 | free(ifstore, M_TEMP); | |||
3240 | break; | |||
3241 | } | |||
3242 | ||||
3243 | case DIOCSETIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((89)))): { | |||
3244 | struct pfioc_iface *io = (struct pfioc_iface *)addr; | |||
3245 | ||||
3246 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3246); | |||
3247 | error = pfi_set_flags(io->pfiio_name, io->pfiio_flags); | |||
3248 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3248); | |||
3249 | break; | |||
3250 | } | |||
3251 | ||||
3252 | case DIOCCLRIFFLAG((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pfioc_iface)) & ((1 << 13) - 1)) << 16) | (( ('D')) << 8) | ((90)))): { | |||
3253 | struct pfioc_iface *io = (struct pfioc_iface *)addr; | |||
3254 | ||||
3255 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3255); | |||
3256 | error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags); | |||
3257 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3257); | |||
3258 | break; | |||
3259 | } | |||
3260 | ||||
3261 | default: | |||
3262 | error = ENODEV19; | |||
3263 | break; | |||
3264 | } | |||
3265 | fail: | |||
3266 | if (sx_xlocked(&pf_ioctl_lock)(((&pf_ioctl_lock)->sx_lock & ~((0x01 | 0x02 | 0x04 | 0x08) & ~0x01)) == (uintptr_t)(__curthread()))) | |||
3267 | sx_xunlock(&pf_ioctl_lock)_sx_xunlock(((&pf_ioctl_lock)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3267)); | |||
3268 | CURVNET_RESTORE(); | |||
3269 | ||||
3270 | return (error); | |||
3271 | } | |||
3272 | ||||
3273 | void | |||
3274 | pfsync_state_export(struct pfsync_state *sp, struct pf_state *st) | |||
3275 | { | |||
3276 | bzero(sp, sizeof(struct pfsync_state)); | |||
3277 | ||||
3278 | /* copy from state key */ | |||
3279 | sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0]; | |||
3280 | sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1]; | |||
3281 | sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0]; | |||
3282 | sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1]; | |||
3283 | sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0]; | |||
3284 | sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1]; | |||
3285 | sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0]; | |||
3286 | sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1]; | |||
3287 | sp->proto = st->key[PF_SK_WIRE]->proto; | |||
3288 | sp->af = st->key[PF_SK_WIRE]->af; | |||
3289 | ||||
3290 | /* copy from state */ | |||
3291 | strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); | |||
3292 | bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); | |||
3293 | 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)); | |||
3294 | sp->expire = pf_state_expires(st); | |||
3295 | if (sp->expire <= time_uptime) | |||
3296 | 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)); | |||
3297 | else | |||
3298 | 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)); | |||
3299 | ||||
3300 | sp->direction = st->direction; | |||
3301 | sp->log = st->log; | |||
3302 | sp->timeout = st->timeout; | |||
3303 | sp->state_flags = st->state_flags; | |||
3304 | if (st->src_node) | |||
3305 | sp->sync_flags |= PFSYNC_FLAG_SRCNODE0x04; | |||
3306 | if (st->nat_src_node) | |||
3307 | sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE0x08; | |||
3308 | ||||
3309 | sp->id = st->id; | |||
3310 | sp->creatorid = st->creatorid; | |||
3311 | 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); | |||
3312 | 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); | |||
3313 | ||||
3314 | if (st->rule.ptr == NULL((void *)0)) | |||
3315 | 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)); | |||
3316 | else | |||
3317 | 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)); | |||
3318 | if (st->anchor.ptr == NULL((void *)0)) | |||
3319 | 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)); | |||
3320 | else | |||
3321 | 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)); | |||
3322 | if (st->nat_rule.ptr == NULL((void *)0)) | |||
3323 | 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)); | |||
3324 | else | |||
3325 | 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)); | |||
3326 | ||||
3327 | 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); | |||
3328 | 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); | |||
3329 | 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); | |||
3330 | 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); | |||
3331 | ||||
3332 | } | |||
3333 | ||||
3334 | static void | |||
3335 | pf_tbladdr_copyout(struct pf_addr_wrap *aw) | |||
3336 | { | |||
3337 | struct pfr_ktable *kt; | |||
3338 | ||||
3339 | KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type))do { } while (0); | |||
3340 | ||||
3341 | kt = aw->p.tbl; | |||
3342 | if (!(kt->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags & PFR_TFLAG_ACTIVE0x00000004) && kt->pfrkt_root != NULL((void *)0)) | |||
3343 | kt = kt->pfrkt_root; | |||
3344 | aw->p.tbl = NULL((void *)0); | |||
3345 | aw->p.tblcnt = (kt->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags & PFR_TFLAG_ACTIVE0x00000004) ? | |||
3346 | kt->pfrkt_cntpfrkt_ts.pfrts_cnt : -1; | |||
3347 | } | |||
3348 | ||||
3349 | /* | |||
3350 | * XXX - Check for version missmatch!!! | |||
3351 | */ | |||
3352 | static void | |||
3353 | pf_clear_states(void) | |||
3354 | { | |||
3355 | struct pf_state *s; | |||
3356 | u_int i; | |||
3357 | ||||
3358 | for (i = 0; i <= pf_hashmask; i++) { | |||
3359 | struct pf_idhash *ih = &V_pf_idhash(pf_idhash)[i]; | |||
3360 | relock: | |||
3361 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3361)); | |||
3362 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
3363 | s->timeout = PFTM_PURGE; | |||
3364 | /* Don't send out individual delete messages. */ | |||
3365 | s->state_flags |= PFSTATE_NOSYNC0x08; | |||
3366 | pf_unlink_state(s, PF_ENTER_LOCKED0x00000001); | |||
3367 | goto relock; | |||
3368 | } | |||
3369 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3369)); | |||
3370 | } | |||
3371 | } | |||
3372 | ||||
3373 | static int | |||
3374 | pf_clear_tables(void) | |||
3375 | { | |||
3376 | struct pfioc_table io; | |||
3377 | int error; | |||
3378 | ||||
3379 | bzero(&io, sizeof(io)); | |||
3380 | ||||
3381 | error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel, | |||
3382 | io.pfrio_flags); | |||
3383 | ||||
3384 | return (error); | |||
3385 | } | |||
3386 | ||||
3387 | static void | |||
3388 | pf_clear_srcnodes(struct pf_src_node *n) | |||
3389 | { | |||
3390 | struct pf_state *s; | |||
3391 | int i; | |||
3392 | ||||
3393 | for (i = 0; i <= pf_hashmask; i++) { | |||
3394 | struct pf_idhash *ih = &V_pf_idhash(pf_idhash)[i]; | |||
3395 | ||||
3396 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3396)); | |||
3397 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
3398 | if (n == NULL((void *)0) || n == s->src_node) | |||
3399 | s->src_node = NULL((void *)0); | |||
3400 | if (n == NULL((void *)0) || n == s->nat_src_node) | |||
3401 | s->nat_src_node = NULL((void *)0); | |||
3402 | } | |||
3403 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3403)); | |||
3404 | } | |||
3405 | ||||
3406 | if (n == NULL((void *)0)) { | |||
3407 | struct pf_srchash *sh; | |||
3408 | ||||
3409 | for (i = 0, sh = V_pf_srchash(pf_srchash); i <= pf_srchashmask; | |||
3410 | i++, sh++) { | |||
3411 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3411)); | |||
3412 | LIST_FOREACH(n, &sh->nodes, entry)for ((n) = (((&sh->nodes))->lh_first); (n); (n) = ( ((n))->entry.le_next)) { | |||
3413 | n->expire = 1; | |||
3414 | n->states = 0; | |||
3415 | } | |||
3416 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3416)); | |||
3417 | } | |||
3418 | } else { | |||
3419 | /* XXX: hash slot should already be locked here. */ | |||
3420 | n->expire = 1; | |||
3421 | n->states = 0; | |||
3422 | } | |||
3423 | } | |||
3424 | ||||
3425 | static void | |||
3426 | pf_kill_srcnodes(struct pfioc_src_node_kill *psnk) | |||
3427 | { | |||
3428 | struct pf_src_node_list kill; | |||
3429 | ||||
3430 | LIST_INIT(&kill)do { (((&kill))->lh_first) = ((void *)0); } while (0); | |||
3431 | for (int i = 0; i <= pf_srchashmask; i++) { | |||
3432 | struct pf_srchash *sh = &V_pf_srchash(pf_srchash)[i]; | |||
3433 | struct pf_src_node *sn, *tmp; | |||
3434 | ||||
3435 | PF_HASHROW_LOCK(sh)__mtx_lock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3435)); | |||
3436 | LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)for ((sn) = (((&sh->nodes))->lh_first); (sn) && ((tmp) = (((sn))->entry.le_next), 1); (sn) = (tmp)) | |||
3437 | 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) | |||
3438 | &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) | |||
3439 | &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) | |||
3440 | &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) && | |||
3441 | 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) | |||
3442 | &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) | |||
3443 | &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) | |||
3444 | &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)) { | |||
3445 | pf_unlink_src_node(sn); | |||
3446 | LIST_INSERT_HEAD(&kill, sn, entry)do { ; 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); | |||
3447 | sn->expire = 1; | |||
3448 | } | |||
3449 | PF_HASHROW_UNLOCK(sh)__mtx_unlock_flags(&((((&(sh)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3449)); | |||
3450 | } | |||
3451 | ||||
3452 | for (int i = 0; i <= pf_hashmask; i++) { | |||
3453 | struct pf_idhash *ih = &V_pf_idhash(pf_idhash)[i]; | |||
3454 | struct pf_state *s; | |||
3455 | ||||
3456 | PF_HASHROW_LOCK(ih)__mtx_lock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3456)); | |||
3457 | LIST_FOREACH(s, &ih->states, entry)for ((s) = (((&ih->states))->lh_first); (s); (s) = ( ((s))->entry.le_next)) { | |||
3458 | if (s->src_node && s->src_node->expire == 1) | |||
3459 | s->src_node = NULL((void *)0); | |||
3460 | if (s->nat_src_node && s->nat_src_node->expire == 1) | |||
3461 | s->nat_src_node = NULL((void *)0); | |||
3462 | } | |||
3463 | PF_HASHROW_UNLOCK(ih)__mtx_unlock_flags(&((((&(ih)->lock))))->mtx_lock , ((0)), ("/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" ), (3463)); | |||
3464 | } | |||
3465 | ||||
3466 | psnk->psnk_killed = pf_free_src_nodes(&kill); | |||
3467 | } | |||
3468 | ||||
3469 | /* | |||
3470 | * XXX - Check for version missmatch!!! | |||
3471 | */ | |||
3472 | ||||
3473 | /* | |||
3474 | * Duplicate pfctl -Fa operation to get rid of as much as we can. | |||
3475 | */ | |||
3476 | static int | |||
3477 | shutdown_pf(void) | |||
3478 | { | |||
3479 | int error = 0; | |||
3480 | u_int32_t t[5]; | |||
3481 | char nn = '\0'; | |||
3482 | ||||
3483 | do { | |||
3484 | if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn)) | |||
3485 | != 0) { | |||
3486 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: SCRUB\n" ); | |||
3487 | break; | |||
3488 | } | |||
3489 | if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn)) | |||
3490 | != 0) { | |||
3491 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: FILTER\n" ); | |||
3492 | break; /* XXX: rollback? */ | |||
3493 | } | |||
3494 | if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn)) | |||
3495 | != 0) { | |||
3496 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: NAT\n" ); | |||
3497 | break; /* XXX: rollback? */ | |||
3498 | } | |||
3499 | if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn)) | |||
3500 | != 0) { | |||
3501 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: BINAT\n" ); | |||
3502 | break; /* XXX: rollback? */ | |||
3503 | } | |||
3504 | if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn)) | |||
3505 | != 0) { | |||
3506 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: RDR\n" ); | |||
3507 | break; /* XXX: rollback? */ | |||
3508 | } | |||
3509 | ||||
3510 | /* XXX: these should always succeed here */ | |||
3511 | pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn); | |||
3512 | pf_commit_rules(t[1], PF_RULESET_FILTER, &nn); | |||
3513 | pf_commit_rules(t[2], PF_RULESET_NAT, &nn); | |||
3514 | pf_commit_rules(t[3], PF_RULESET_BINAT, &nn); | |||
3515 | pf_commit_rules(t[4], PF_RULESET_RDR, &nn); | |||
3516 | ||||
3517 | if ((error = pf_clear_tables()) != 0) | |||
3518 | break; | |||
3519 | ||||
3520 | #ifdef ALTQ | |||
3521 | if ((error = pf_begin_altq(&t[0])) != 0) { | |||
3522 | DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"))if ((pf_status).debug >= (PF_DEBUG_MISC)) printf ("shutdown_pf: ALTQ\n" ); | |||
3523 | break; | |||
3524 | } | |||
3525 | pf_commit_altq(t[0]); | |||
3526 | #endif | |||
3527 | ||||
3528 | pf_clear_states(); | |||
3529 | ||||
3530 | pf_clear_srcnodes(NULL((void *)0)); | |||
3531 | ||||
3532 | /* status does not use malloced mem so no need to cleanup */ | |||
3533 | /* fingerprints and interfaces have their own cleanup code */ | |||
3534 | ||||
3535 | /* Free counters last as we updated them during shutdown. */ | |||
3536 | counter_u64_free(V_pf_default_rule(pf_default_rule).states_cur); | |||
3537 | counter_u64_free(V_pf_default_rule(pf_default_rule).states_tot); | |||
3538 | counter_u64_free(V_pf_default_rule(pf_default_rule).src_nodes); | |||
3539 | ||||
3540 | for (int i = 0; i < PFRES_MAX16; i++) | |||
3541 | counter_u64_free(V_pf_status(pf_status).counters[i]); | |||
3542 | for (int i = 0; i < LCNT_MAX7; i++) | |||
3543 | counter_u64_free(V_pf_status(pf_status).lcounters[i]); | |||
3544 | for (int i = 0; i < FCNT_MAX3; i++) | |||
3545 | counter_u64_free(V_pf_status(pf_status).fcounters[i]); | |||
3546 | for (int i = 0; i < SCNT_MAX3; i++) | |||
3547 | counter_u64_free(V_pf_status(pf_status).scounters[i]); | |||
3548 | } while(0); | |||
3549 | ||||
3550 | return (error); | |||
3551 | } | |||
3552 | ||||
3553 | #ifdef INET1 | |||
3554 | static int | |||
3555 | pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, | |||
3556 | struct inpcb *inp) | |||
3557 | { | |||
3558 | int chk; | |||
3559 | ||||
3560 | chk = pf_test(PF_IN, ifp, m, inp); | |||
3561 | if (chk && *m) { | |||
3562 | m_freem(*m); | |||
3563 | *m = NULL((void *)0); | |||
3564 | } | |||
3565 | ||||
3566 | return (chk); | |||
3567 | } | |||
3568 | ||||
3569 | static int | |||
3570 | pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, | |||
3571 | struct inpcb *inp) | |||
3572 | { | |||
3573 | int chk; | |||
3574 | ||||
3575 | chk = pf_test(PF_OUT, ifp, m, inp); | |||
3576 | if (chk && *m) { | |||
3577 | m_freem(*m); | |||
3578 | *m = NULL((void *)0); | |||
3579 | } | |||
3580 | ||||
3581 | return (chk); | |||
3582 | } | |||
3583 | #endif | |||
3584 | ||||
3585 | #ifdef INET61 | |||
3586 | static int | |||
3587 | pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, | |||
3588 | struct inpcb *inp) | |||
3589 | { | |||
3590 | int chk; | |||
3591 | ||||
3592 | /* | |||
3593 | * In case of loopback traffic IPv6 uses the real interface in | |||
3594 | * order to support scoped addresses. In order to support stateful | |||
3595 | * filtering we have change this to lo0 as it is the case in IPv4. | |||
3596 | */ | |||
3597 | CURVNET_SET(ifp->if_vnet); | |||
3598 | chk = pf_test6(PF_IN, (*m)->m_flags & M_LOOP0x00020000 ? V_loif(loif) : ifp, m, inp); | |||
3599 | CURVNET_RESTORE(); | |||
3600 | if (chk && *m) { | |||
3601 | m_freem(*m); | |||
3602 | *m = NULL((void *)0); | |||
3603 | } | |||
3604 | return chk; | |||
3605 | } | |||
3606 | ||||
3607 | static int | |||
3608 | pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, | |||
3609 | struct inpcb *inp) | |||
3610 | { | |||
3611 | int chk; | |||
3612 | ||||
3613 | CURVNET_SET(ifp->if_vnet); | |||
3614 | chk = pf_test6(PF_OUT, ifp, m, inp); | |||
3615 | CURVNET_RESTORE(); | |||
3616 | if (chk && *m) { | |||
3617 | m_freem(*m); | |||
3618 | *m = NULL((void *)0); | |||
3619 | } | |||
3620 | return chk; | |||
3621 | } | |||
3622 | #endif /* INET6 */ | |||
3623 | ||||
3624 | static int | |||
3625 | hook_pf(void) | |||
3626 | { | |||
3627 | #ifdef INET1 | |||
3628 | struct pfil_head *pfh_inet; | |||
3629 | #endif | |||
3630 | #ifdef INET61 | |||
3631 | struct pfil_head *pfh_inet6; | |||
3632 | #endif | |||
3633 | ||||
3634 | if (V_pf_pfil_hooked(pf_pfil_hooked)) | |||
3635 | return (0); | |||
3636 | ||||
3637 | #ifdef INET1 | |||
3638 | pfh_inet = pfil_head_get(PFIL_TYPE_AF1, AF_INET2); | |||
3639 | if (pfh_inet == NULL((void *)0)) | |||
3640 | return (ESRCH3); /* XXX */ | |||
3641 | pfil_add_hook(pf_check_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, pfh_inet); | |||
3642 | pfil_add_hook(pf_check_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, pfh_inet); | |||
3643 | #endif | |||
3644 | #ifdef INET61 | |||
3645 | pfh_inet6 = pfil_head_get(PFIL_TYPE_AF1, AF_INET628); | |||
3646 | if (pfh_inet6 == NULL((void *)0)) { | |||
3647 | #ifdef INET1 | |||
3648 | pfil_remove_hook(pf_check_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, | |||
3649 | pfh_inet); | |||
3650 | pfil_remove_hook(pf_check_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, | |||
3651 | pfh_inet); | |||
3652 | #endif | |||
3653 | return (ESRCH3); /* XXX */ | |||
3654 | } | |||
3655 | pfil_add_hook(pf_check6_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, pfh_inet6); | |||
3656 | pfil_add_hook(pf_check6_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, pfh_inet6); | |||
3657 | #endif | |||
3658 | ||||
3659 | V_pf_pfil_hooked(pf_pfil_hooked) = 1; | |||
3660 | return (0); | |||
3661 | } | |||
3662 | ||||
3663 | static int | |||
3664 | dehook_pf(void) | |||
3665 | { | |||
3666 | #ifdef INET1 | |||
3667 | struct pfil_head *pfh_inet; | |||
3668 | #endif | |||
3669 | #ifdef INET61 | |||
3670 | struct pfil_head *pfh_inet6; | |||
3671 | #endif | |||
3672 | ||||
3673 | if (V_pf_pfil_hooked(pf_pfil_hooked) == 0) | |||
3674 | return (0); | |||
3675 | ||||
3676 | #ifdef INET1 | |||
3677 | pfh_inet = pfil_head_get(PFIL_TYPE_AF1, AF_INET2); | |||
3678 | if (pfh_inet == NULL((void *)0)) | |||
3679 | return (ESRCH3); /* XXX */ | |||
3680 | pfil_remove_hook(pf_check_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, | |||
3681 | pfh_inet); | |||
3682 | pfil_remove_hook(pf_check_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, | |||
3683 | pfh_inet); | |||
3684 | #endif | |||
3685 | #ifdef INET61 | |||
3686 | pfh_inet6 = pfil_head_get(PFIL_TYPE_AF1, AF_INET628); | |||
3687 | if (pfh_inet6 == NULL((void *)0)) | |||
3688 | return (ESRCH3); /* XXX */ | |||
3689 | pfil_remove_hook(pf_check6_in, NULL((void *)0), PFIL_IN0x00000001 | PFIL_WAITOK0x00000004, | |||
3690 | pfh_inet6); | |||
3691 | pfil_remove_hook(pf_check6_out, NULL((void *)0), PFIL_OUT0x00000002 | PFIL_WAITOK0x00000004, | |||
3692 | pfh_inet6); | |||
3693 | #endif | |||
3694 | ||||
3695 | V_pf_pfil_hooked(pf_pfil_hooked) = 0; | |||
3696 | return (0); | |||
3697 | } | |||
3698 | ||||
3699 | static void | |||
3700 | pf_load_vnet(void) | |||
3701 | { | |||
3702 | VNET_ITERATOR_DECL(vnet_iter); | |||
3703 | ||||
3704 | VNET_LIST_RLOCK(); | |||
3705 | VNET_FOREACH(vnet_iter) { | |||
3706 | CURVNET_SET(vnet_iter); | |||
3707 | V_pf_pfil_hooked(pf_pfil_hooked) = 0; | |||
3708 | TAILQ_INIT(&V_pf_tags)do { (((&(pf_tags)))->tqh_first) = ((void *)0); (& (pf_tags))->tqh_last = &(((&(pf_tags)))->tqh_first ); ; } while (0); | |||
3709 | TAILQ_INIT(&V_pf_qids)do { (((&(pf_qids)))->tqh_first) = ((void *)0); (& (pf_qids))->tqh_last = &(((&(pf_qids)))->tqh_first ); ; } while (0); | |||
3710 | CURVNET_RESTORE(); | |||
3711 | } | |||
3712 | VNET_LIST_RUNLOCK(); | |||
3713 | ||||
3714 | pfattach_vnet(); | |||
3715 | V_pf_vnet_active(pf_vnet_active) = 1; | |||
3716 | } | |||
3717 | ||||
3718 | static int | |||
3719 | pf_load(void) | |||
3720 | { | |||
3721 | int error; | |||
3722 | ||||
3723 | rw_init(&pf_rules_lock, "pf rulesets")_rw_init_flags(&(&pf_rules_lock)->rw_lock, "pf rulesets" , 0); | |||
3724 | sx_init(&pf_ioctl_lock, "pf ioctl")sx_init_flags((&pf_ioctl_lock), ("pf ioctl"), 0); | |||
3725 | ||||
3726 | pf_mtag_initialize(); | |||
3727 | ||||
3728 | pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME"pf"); | |||
3729 | if (pf_dev == NULL((void *)0)) | |||
3730 | return (ENOMEM12); | |||
3731 | ||||
3732 | pf_end_threads = 0; | |||
3733 | error = kproc_create(pf_purge_thread, NULL((void *)0), NULL((void *)0), 0, 0, "pf purge"); | |||
3734 | if (error != 0) | |||
3735 | return (error); | |||
3736 | ||||
3737 | pfi_initialize(); | |||
3738 | ||||
3739 | return (0); | |||
3740 | } | |||
3741 | ||||
3742 | static void | |||
3743 | pf_unload_vnet(void) | |||
3744 | { | |||
3745 | int error; | |||
3746 | ||||
3747 | V_pf_vnet_active(pf_vnet_active) = 0; | |||
3748 | V_pf_status(pf_status).running = 0; | |||
3749 | swi_remove(V_pf_swi_cookie(pf_swi_cookie)); | |||
3750 | error = dehook_pf(); | |||
3751 | if (error) { | |||
3752 | /* | |||
3753 | * Should not happen! | |||
3754 | * XXX Due to error code ESRCH, kldunload will show | |||
3755 | * a message like 'No such process'. | |||
3756 | */ | |||
3757 | printf("%s : pfil unregisteration fail\n", __FUNCTION__); | |||
3758 | return; | |||
3759 | } | |||
3760 | ||||
3761 | pf_unload_vnet_purge(); | |||
3762 | ||||
3763 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3763); | |||
3764 | shutdown_pf(); | |||
3765 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3765); | |||
3766 | ||||
3767 | pf_normalize_cleanup(); | |||
3768 | PF_RULES_WLOCK()_rw_wlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3768); | |||
3769 | pfi_cleanup_vnet(); | |||
3770 | PF_RULES_WUNLOCK()_rw_wunlock_cookie(&((&pf_rules_lock))->rw_lock, "/usr/src/sys/modules/pf/../../netpfil/pf/pf_ioctl.c" , 3770); | |||
3771 | pfr_cleanup(); | |||
3772 | pf_osfp_flush(); | |||
3773 | pf_cleanup(); | |||
3774 | if (IS_DEFAULT_VNET(curvnet)1) | |||
3775 | pf_mtag_cleanup(); | |||
3776 | } | |||
3777 | ||||
3778 | static int | |||
3779 | pf_unload(void) | |||
3780 | { | |||
3781 | int error = 0; | |||
3782 | ||||
3783 | pf_end_threads = 1; | |||
3784 | while (pf_end_threads < 2) { | |||
3785 | wakeup_one(pf_purge_thread); | |||
3786 | rw_sleep(pf_purge_thread, &pf_rules_lock, 0, "pftmo", 0)_sleep((pf_purge_thread), &(&pf_rules_lock)->lock_object , (0), ("pftmo"), tick_sbt * (0), 0, 0x0100); | |||
3787 | } | |||
3788 | ||||
3789 | if (pf_dev != NULL((void *)0)) | |||
3790 | destroy_dev(pf_dev); | |||
3791 | ||||
3792 | pfi_cleanup(); | |||
3793 | ||||
3794 | rw_destroy(&pf_rules_lock)_rw_destroy(&(&pf_rules_lock)->rw_lock); | |||
3795 | sx_destroy(&pf_ioctl_lock); | |||
3796 | ||||
3797 | return (error); | |||
3798 | } | |||
3799 | ||||
3800 | static void | |||
3801 | vnet_pf_init(void *unused __unused__attribute__((__unused__))) | |||
3802 | { | |||
3803 | ||||
3804 | pf_load_vnet(); | |||
3805 | } | |||
3806 | VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,static struct sysinit vnet_pf_init_sys_init = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_init , ((void *)(((void *)0))) }; __asm__(".globl " "__start_set_sysinit_set" ); __asm__(".globl " "__stop_set_sysinit_set"); static void const * const __set_sysinit_set_sym_vnet_pf_init_sys_init __attribute__ ((__section__("set_" "sysinit_set"))) __attribute__((__used__ )) = &(vnet_pf_init_sys_init) | |||
3807 | vnet_pf_init, NULL)static struct sysinit vnet_pf_init_sys_init = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_init , ((void *)(((void *)0))) }; __asm__(".globl " "__start_set_sysinit_set" ); __asm__(".globl " "__stop_set_sysinit_set"); static void const * const __set_sysinit_set_sym_vnet_pf_init_sys_init __attribute__ ((__section__("set_" "sysinit_set"))) __attribute__((__used__ )) = &(vnet_pf_init_sys_init); | |||
3808 | ||||
3809 | static void | |||
3810 | vnet_pf_uninit(const void *unused __unused__attribute__((__unused__))) | |||
3811 | { | |||
3812 | ||||
3813 | pf_unload_vnet(); | |||
3814 | } | |||
3815 | VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,static struct sysinit vnet_pf_uninit_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_uninit , ((void *)(((void *)0))) }; __asm__(".globl " "__start_set_sysuninit_set" ); __asm__(".globl " "__stop_set_sysuninit_set"); static void const * const __set_sysuninit_set_sym_vnet_pf_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(vnet_pf_uninit_sys_uninit) | |||
3816 | vnet_pf_uninit, NULL)static struct sysinit vnet_pf_uninit_sys_uninit = { SI_SUB_PROTO_FIREWALL , SI_ORDER_THIRD, (sysinit_cfunc_t)(sysinit_nfunc_t)vnet_pf_uninit , ((void *)(((void *)0))) }; __asm__(".globl " "__start_set_sysuninit_set" ); __asm__(".globl " "__stop_set_sysuninit_set"); static void const * const __set_sysuninit_set_sym_vnet_pf_uninit_sys_uninit __attribute__((__section__("set_" "sysuninit_set"))) __attribute__ ((__used__)) = &(vnet_pf_uninit_sys_uninit); | |||
3817 | ||||
3818 | ||||
3819 | static int | |||
3820 | pf_modevent(module_t mod, int type, void *data) | |||
3821 | { | |||
3822 | int error = 0; | |||
3823 | ||||
3824 | switch(type) { | |||
3825 | case MOD_LOAD: | |||
3826 | error = pf_load(); | |||
3827 | break; | |||
3828 | case MOD_QUIESCE: | |||
3829 | /* | |||
3830 | * Module should not be unloaded due to race conditions. | |||
3831 | */ | |||
3832 | error = EBUSY16; | |||
3833 | break; | |||
3834 | case MOD_UNLOAD: | |||
3835 | error = pf_unload(); | |||
3836 | break; | |||
3837 | default: | |||
3838 | error = EINVAL22; | |||
3839 | break; | |||
3840 | } | |||
3841 | ||||
3842 | return (error); | |||
3843 | } | |||
3844 | ||||
3845 | static moduledata_t pf_mod = { | |||
3846 | "pf", | |||
3847 | pf_modevent, | |||
3848 | 0 | |||
3849 | }; | |||
3850 | ||||
3851 | DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND)static struct mod_depend _pf_depend_on_kernel __attribute__(( __section__(".data"))) = { 1100122, 1100122, (((((1100122)+(( 100000)-1))/(100000))*(100000)) - 1) }; 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 * const __set_sysinit_set_sym_pfmodule_sys_init __attribute__((__section__("set_" "sysinit_set"))) __attribute__ ((__used__)) = &(pfmodule_sys_init); struct __hack; | |||
3852 | 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); |