1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2001 Daniel Hartmeier
5 * Copyright (c) 2002,2003 Henning Brauer
6 * Copyright (c) 2012 Gleb Smirnoff <[email protected]>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Effort sponsored in part by the Defense Advanced Research Projects
34 * Agency (DARPA) and Air Force Research Laboratory, Air Force
35 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36 *
37 * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $
38 */
39
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42
43 #include "opt_inet.h"
44 #include "opt_inet6.h"
45 #include "opt_bpf.h"
46 #include "opt_pf.h"
47
48 #include <sys/param.h>
49 #include <sys/_bitset.h>
50 #include <sys/bitset.h>
51 #include <sys/bus.h>
52 #include <sys/conf.h>
53 #include <sys/endian.h>
54 #include <sys/fcntl.h>
55 #include <sys/filio.h>
56 #include <sys/hash.h>
57 #include <sys/interrupt.h>
58 #include <sys/jail.h>
59 #include <sys/kernel.h>
60 #include <sys/kthread.h>
61 #include <sys/lock.h>
62 #include <sys/mbuf.h>
63 #include <sys/module.h>
64 #include <sys/nv.h>
65 #include <sys/proc.h>
66 #include <sys/sdt.h>
67 #include <sys/smp.h>
68 #include <sys/socket.h>
69 #include <sys/sysctl.h>
70 #include <sys/md5.h>
71 #include <sys/ucred.h>
72
73 #include <net/if.h>
74 #include <net/if_var.h>
75 #include <net/vnet.h>
76 #include <net/route.h>
77 #include <net/pfil.h>
78 #include <net/pfvar.h>
79 #include <net/if_pfsync.h>
80 #include <net/if_pflog.h>
81
82 #include <netinet/in.h>
83 #include <netinet/ip.h>
84 #include <netinet/ip_var.h>
85 #include <netinet6/ip6_var.h>
86 #include <netinet/ip_icmp.h>
87 #include <netpfil/pf/pf_nv.h>
88
89 #ifdef INET6
90 #include <netinet/ip6.h>
91 #endif /* INET6 */
92
93 #ifdef ALTQ
94 #include <net/altq/altq.h>
95 #endif
96
97 SDT_PROVIDER_DECLARE(pf);
98 SDT_PROBE_DEFINE3(pf, ioctl, ioctl, error, "int", "int", "int");
99 SDT_PROBE_DEFINE3(pf, ioctl, function, error, "char *", "int", "int");
100 SDT_PROBE_DEFINE2(pf, ioctl, addrule, error, "int", "int");
101 SDT_PROBE_DEFINE2(pf, ioctl, nvchk, error, "int", "int");
102
103 static struct pf_kpool *pf_get_kpool(const char *, u_int32_t, u_int8_t,
104 u_int32_t, u_int8_t, u_int8_t, u_int8_t);
105
106 static void pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *);
107 static void pf_empty_kpool(struct pf_kpalist *);
108 static int pfioctl(struct cdev *, u_long, caddr_t, int,
109 struct thread *);
110 #ifdef ALTQ
111 static int pf_begin_altq(u_int32_t *);
112 static int pf_rollback_altq(u_int32_t);
113 static int pf_commit_altq(u_int32_t);
114 static int pf_enable_altq(struct pf_altq *);
115 static int pf_disable_altq(struct pf_altq *);
116 static uint16_t pf_qname2qid(const char *);
117 static void pf_qid_unref(uint16_t);
118 #endif /* ALTQ */
119 static int pf_begin_rules(u_int32_t *, int, const char *);
120 static int pf_rollback_rules(u_int32_t, int, char *);
121 static int pf_setup_pfsync_matching(struct pf_kruleset *);
122 static void pf_hash_rule(MD5_CTX *, struct pf_krule *);
123 static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
124 static int pf_commit_rules(u_int32_t, int, char *);
125 static int pf_addr_setup(struct pf_kruleset *,
126 struct pf_addr_wrap *, sa_family_t);
127 static void pf_addr_copyout(struct pf_addr_wrap *);
128 static void pf_src_node_copy(const struct pf_ksrc_node *,
129 struct pf_src_node *);
130 #ifdef ALTQ
131 static int pf_export_kaltq(struct pf_altq *,
132 struct pfioc_altq_v1 *, size_t);
133 static int pf_import_kaltq(struct pfioc_altq_v1 *,
134 struct pf_altq *, size_t);
135 #endif /* ALTQ */
136
137 VNET_DEFINE(struct pf_krule, pf_default_rule);
138
139 #ifdef ALTQ
140 VNET_DEFINE_STATIC(int, pf_altq_running);
141 #define V_pf_altq_running VNET(pf_altq_running)
142 #endif
143
144 #define TAGID_MAX 50000
145 struct pf_tagname {
146 TAILQ_ENTRY(pf_tagname) namehash_entries;
147 TAILQ_ENTRY(pf_tagname) taghash_entries;
148 char name[PF_TAG_NAME_SIZE];
149 uint16_t tag;
150 int ref;
151 };
152
153 struct pf_tagset {
154 TAILQ_HEAD(, pf_tagname) *namehash;
155 TAILQ_HEAD(, pf_tagname) *taghash;
156 unsigned int mask;
157 uint32_t seed;
158 BITSET_DEFINE(, TAGID_MAX) avail;
159 };
160
161 VNET_DEFINE(struct pf_tagset, pf_tags);
162 #define V_pf_tags VNET(pf_tags)
163 static unsigned int pf_rule_tag_hashsize;
164 #define PF_RULE_TAG_HASH_SIZE_DEFAULT 128
165 SYSCTL_UINT(_net_pf, OID_AUTO, rule_tag_hashsize, CTLFLAG_RDTUN,
166 &pf_rule_tag_hashsize, PF_RULE_TAG_HASH_SIZE_DEFAULT,
167 "Size of pf(4) rule tag hashtable");
168
169 #ifdef ALTQ
170 VNET_DEFINE(struct pf_tagset, pf_qids);
171 #define V_pf_qids VNET(pf_qids)
172 static unsigned int pf_queue_tag_hashsize;
173 #define PF_QUEUE_TAG_HASH_SIZE_DEFAULT 128
174 SYSCTL_UINT(_net_pf, OID_AUTO, queue_tag_hashsize, CTLFLAG_RDTUN,
175 &pf_queue_tag_hashsize, PF_QUEUE_TAG_HASH_SIZE_DEFAULT,
176 "Size of pf(4) queue tag hashtable");
177 #endif
178 VNET_DEFINE(uma_zone_t, pf_tag_z);
179 #define V_pf_tag_z VNET(pf_tag_z)
180 static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db");
181 static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules");
182
183 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
184 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
185 #endif
186
187 static void pf_init_tagset(struct pf_tagset *, unsigned int *,
188 unsigned int);
189 static void pf_cleanup_tagset(struct pf_tagset *);
190 static uint16_t tagname2hashindex(const struct pf_tagset *, const char *);
191 static uint16_t tag2hashindex(const struct pf_tagset *, uint16_t);
192 static u_int16_t tagname2tag(struct pf_tagset *, const char *);
193 static u_int16_t pf_tagname2tag(const char *);
194 static void tag_unref(struct pf_tagset *, u_int16_t);
195
196 #define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
197
198 struct cdev *pf_dev;
199
200 /*
201 * XXX - These are new and need to be checked when moveing to a new version
202 */
203 static void pf_clear_all_states(void);
204 static unsigned int pf_clear_states(const struct pf_kstate_kill *);
205 static void pf_killstates(struct pf_kstate_kill *,
206 unsigned int *);
207 static int pf_killstates_row(struct pf_kstate_kill *,
208 struct pf_idhash *);
209 static int pf_killstates_nv(struct pfioc_nv *);
210 static int pf_clearstates_nv(struct pfioc_nv *);
211 static int pf_getstate(struct pfioc_nv *);
212 static int pf_getstatus(struct pfioc_nv *);
213 static int pf_clear_tables(void);
214 static void pf_clear_srcnodes(struct pf_ksrc_node *);
215 static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
216 static int pf_keepcounters(struct pfioc_nv *);
217 static void pf_tbladdr_copyout(struct pf_addr_wrap *);
218
219 /*
220 * Wrapper functions for pfil(9) hooks
221 */
222 #ifdef INET
223 static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp,
224 int flags, void *ruleset __unused, struct inpcb *inp);
225 static pfil_return_t pf_check_out(struct mbuf **m, struct ifnet *ifp,
226 int flags, void *ruleset __unused, struct inpcb *inp);
227 #endif
228 #ifdef INET6
229 static pfil_return_t pf_check6_in(struct mbuf **m, struct ifnet *ifp,
230 int flags, void *ruleset __unused, struct inpcb *inp);
231 static pfil_return_t pf_check6_out(struct mbuf **m, struct ifnet *ifp,
232 int flags, void *ruleset __unused, struct inpcb *inp);
233 #endif
234
235 static void hook_pf(void);
236 static void dehook_pf(void);
237 static int shutdown_pf(void);
238 static int pf_load(void);
239 static void pf_unload(void);
240
241 static struct cdevsw pf_cdevsw = {
242 .d_ioctl = pfioctl,
243 .d_name = PF_NAME,
244 .d_version = D_VERSION,
245 };
246
247 volatile VNET_DEFINE_STATIC(int, pf_pfil_hooked);
248 #define V_pf_pfil_hooked VNET(pf_pfil_hooked)
249
250 /*
251 * We need a flag that is neither hooked nor running to know when
252 * the VNET is "valid". We primarily need this to control (global)
253 * external event, e.g., eventhandlers.
254 */
255 VNET_DEFINE(int, pf_vnet_active);
256 #define V_pf_vnet_active VNET(pf_vnet_active)
257
258 int pf_end_threads;
259 struct proc *pf_purge_proc;
260
261 struct rmlock pf_rules_lock;
262 struct sx pf_ioctl_lock;
263 struct sx pf_end_lock;
264
265 /* pfsync */
266 VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr);
267 VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr);
268 VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr);
269 VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr);
270 VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr);
271 VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr);
272 pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
273
274 /* pflog */
275 pflog_packet_t *pflog_packet_ptr = NULL;
276
277 #define ERROUT_FUNCTION(target, x) \
278 do { \
279 error = (x); \
280 SDT_PROBE3(pf, ioctl, function, error, __func__, error, \
281 __LINE__); \
282 goto target; \
283 } while (0)
284
285 /*
286 * Copy a user-provided string, returning an error if truncation would occur.
287 * Avoid scanning past "sz" bytes in the source string since there's no
288 * guarantee that it's nul-terminated.
289 */
290 static int
pf_user_strcpy(char * dst,const char * src,size_t sz)291 pf_user_strcpy(char *dst, const char *src, size_t sz)
292 {
293 if (strnlen(src, sz) == sz)
294 return (EINVAL);
295 (void)strlcpy(dst, src, sz);
296 return (0);
297 }
298
299 static void
pfattach_vnet(void)300 pfattach_vnet(void)
301 {
302 u_int32_t *my_timeout = V_pf_default_rule.timeout;
303
304 pf_initialize();
305 pfr_initialize();
306 pfi_initialize_vnet();
307 pf_normalize_init();
308 pf_syncookies_init();
309
310 V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
311 V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
312
313 RB_INIT(&V_pf_anchors);
314 pf_init_kruleset(&pf_main_ruleset);
315
316 /* default rule should never be garbage collected */
317 V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
318 #ifdef PF_DEFAULT_TO_DROP
319 V_pf_default_rule.action = PF_DROP;
320 #else
321 V_pf_default_rule.action = PF_PASS;
322 #endif
323 V_pf_default_rule.nr = -1;
324 V_pf_default_rule.rtableid = -1;
325
326 pf_counter_u64_init(&V_pf_default_rule.evaluations, M_WAITOK);
327 for (int i = 0; i < 2; i++) {
328 pf_counter_u64_init(&V_pf_default_rule.packets[i], M_WAITOK);
329 pf_counter_u64_init(&V_pf_default_rule.bytes[i], M_WAITOK);
330 }
331 V_pf_default_rule.states_cur = counter_u64_alloc(M_WAITOK);
332 V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
333 V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK);
334
335 #ifdef PF_WANT_32_TO_64_COUNTER
336 V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO);
337 V_pf_rulemarker = malloc(sizeof(*V_pf_rulemarker), M_PFRULE, M_WAITOK | M_ZERO);
338 PF_RULES_WLOCK();
339 LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
340 LIST_INSERT_HEAD(&V_pf_allrulelist, &V_pf_default_rule, allrulelist);
341 V_pf_allrulecount++;
342 LIST_INSERT_HEAD(&V_pf_allrulelist, V_pf_rulemarker, allrulelist);
343 PF_RULES_WUNLOCK();
344 #endif
345
346 /* initialize default timeouts */
347 my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
348 my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
349 my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
350 my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
351 my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
352 my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
353 my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
354 my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
355 my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
356 my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
357 my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
358 my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
359 my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
360 my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
361 my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
362 my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
363 my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
364 my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
365 my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
366 my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
367
368 bzero(&V_pf_status, sizeof(V_pf_status));
369 V_pf_status.debug = PF_DEBUG_URGENT;
370
371 V_pf_pfil_hooked = 0;
372
373 /* XXX do our best to avoid a conflict */
374 V_pf_status.hostid = arc4random();
375
376 for (int i = 0; i < PFRES_MAX; i++)
377 V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK);
378 for (int i = 0; i < KLCNT_MAX; i++)
379 V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
380 for (int i = 0; i < FCNT_MAX; i++)
381 pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK);
382 for (int i = 0; i < SCNT_MAX; i++)
383 V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
384
385 if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET,
386 INTR_MPSAFE, &V_pf_swi_cookie) != 0)
387 /* XXXGL: leaked all above. */
388 return;
389 }
390
391 static struct pf_kpool *
pf_get_kpool(const char * anchor,u_int32_t ticket,u_int8_t rule_action,u_int32_t rule_number,u_int8_t r_last,u_int8_t active,u_int8_t check_ticket)392 pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action,
393 u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
394 u_int8_t check_ticket)
395 {
396 struct pf_kruleset *ruleset;
397 struct pf_krule *rule;
398 int rs_num;
399
400 ruleset = pf_find_kruleset(anchor);
401 if (ruleset == NULL)
402 return (NULL);
403 rs_num = pf_get_ruleset_number(rule_action);
404 if (rs_num >= PF_RULESET_MAX)
405 return (NULL);
406 if (active) {
407 if (check_ticket && ticket !=
408 ruleset->rules[rs_num].active.ticket)
409 return (NULL);
410 if (r_last)
411 rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
412 pf_krulequeue);
413 else
414 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
415 } else {
416 if (check_ticket && ticket !=
417 ruleset->rules[rs_num].inactive.ticket)
418 return (NULL);
419 if (r_last)
420 rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
421 pf_krulequeue);
422 else
423 rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
424 }
425 if (!r_last) {
426 while ((rule != NULL) && (rule->nr != rule_number))
427 rule = TAILQ_NEXT(rule, entries);
428 }
429 if (rule == NULL)
430 return (NULL);
431
432 return (&rule->rpool);
433 }
434
435 static void
pf_mv_kpool(struct pf_kpalist * poola,struct pf_kpalist * poolb)436 pf_mv_kpool(struct pf_kpalist *poola, struct pf_kpalist *poolb)
437 {
438 struct pf_kpooladdr *mv_pool_pa;
439
440 while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
441 TAILQ_REMOVE(poola, mv_pool_pa, entries);
442 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
443 }
444 }
445
446 static void
pf_empty_kpool(struct pf_kpalist * poola)447 pf_empty_kpool(struct pf_kpalist *poola)
448 {
449 struct pf_kpooladdr *pa;
450
451 while ((pa = TAILQ_FIRST(poola)) != NULL) {
452 switch (pa->addr.type) {
453 case PF_ADDR_DYNIFTL:
454 pfi_dynaddr_remove(pa->addr.p.dyn);
455 break;
456 case PF_ADDR_TABLE:
457 /* XXX: this could be unfinished pooladdr on pabuf */
458 if (pa->addr.p.tbl != NULL)
459 pfr_detach_table(pa->addr.p.tbl);
460 break;
461 }
462 if (pa->kif)
463 pfi_kkif_unref(pa->kif);
464 TAILQ_REMOVE(poola, pa, entries);
465 free(pa, M_PFRULE);
466 }
467 }
468
469 static void
pf_unlink_rule(struct pf_krulequeue * rulequeue,struct pf_krule * rule)470 pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
471 {
472
473 PF_RULES_WASSERT();
474
475 TAILQ_REMOVE(rulequeue, rule, entries);
476
477 PF_UNLNKDRULES_LOCK();
478 rule->rule_ref |= PFRULE_REFS;
479 TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries);
480 PF_UNLNKDRULES_UNLOCK();
481 }
482
483 void
pf_free_rule(struct pf_krule * rule)484 pf_free_rule(struct pf_krule *rule)
485 {
486
487 PF_RULES_WASSERT();
488
489 if (rule->tag)
490 tag_unref(&V_pf_tags, rule->tag);
491 if (rule->match_tag)
492 tag_unref(&V_pf_tags, rule->match_tag);
493 #ifdef ALTQ
494 if (rule->pqid != rule->qid)
495 pf_qid_unref(rule->pqid);
496 pf_qid_unref(rule->qid);
497 #endif
498 switch (rule->src.addr.type) {
499 case PF_ADDR_DYNIFTL:
500 pfi_dynaddr_remove(rule->src.addr.p.dyn);
501 break;
502 case PF_ADDR_TABLE:
503 pfr_detach_table(rule->src.addr.p.tbl);
504 break;
505 }
506 switch (rule->dst.addr.type) {
507 case PF_ADDR_DYNIFTL:
508 pfi_dynaddr_remove(rule->dst.addr.p.dyn);
509 break;
510 case PF_ADDR_TABLE:
511 pfr_detach_table(rule->dst.addr.p.tbl);
512 break;
513 }
514 if (rule->overload_tbl)
515 pfr_detach_table(rule->overload_tbl);
516 if (rule->kif)
517 pfi_kkif_unref(rule->kif);
518 pf_kanchor_remove(rule);
519 pf_empty_kpool(&rule->rpool.list);
520
521 pf_krule_free(rule);
522 }
523
524 static void
pf_init_tagset(struct pf_tagset * ts,unsigned int * tunable_size,unsigned int default_size)525 pf_init_tagset(struct pf_tagset *ts, unsigned int *tunable_size,
526 unsigned int default_size)
527 {
528 unsigned int i;
529 unsigned int hashsize;
530
531 if (*tunable_size == 0 || !powerof2(*tunable_size))
532 *tunable_size = default_size;
533
534 hashsize = *tunable_size;
535 ts->namehash = mallocarray(hashsize, sizeof(*ts->namehash), M_PFHASH,
536 M_WAITOK);
537 ts->taghash = mallocarray(hashsize, sizeof(*ts->taghash), M_PFHASH,
538 M_WAITOK);
539 ts->mask = hashsize - 1;
540 ts->seed = arc4random();
541 for (i = 0; i < hashsize; i++) {
542 TAILQ_INIT(&ts->namehash[i]);
543 TAILQ_INIT(&ts->taghash[i]);
544 }
545 BIT_FILL(TAGID_MAX, &ts->avail);
546 }
547
548 static void
pf_cleanup_tagset(struct pf_tagset * ts)549 pf_cleanup_tagset(struct pf_tagset *ts)
550 {
551 unsigned int i;
552 unsigned int hashsize;
553 struct pf_tagname *t, *tmp;
554
555 /*
556 * Only need to clean up one of the hashes as each tag is hashed
557 * into each table.
558 */
559 hashsize = ts->mask + 1;
560 for (i = 0; i < hashsize; i++)
561 TAILQ_FOREACH_SAFE(t, &ts->namehash[i], namehash_entries, tmp)
562 uma_zfree(V_pf_tag_z, t);
563
564 free(ts->namehash, M_PFHASH);
565 free(ts->taghash, M_PFHASH);
566 }
567
568 static uint16_t
tagname2hashindex(const struct pf_tagset * ts,const char * tagname)569 tagname2hashindex(const struct pf_tagset *ts, const char *tagname)
570 {
571 size_t len;
572
573 len = strnlen(tagname, PF_TAG_NAME_SIZE - 1);
574 return (murmur3_32_hash(tagname, len, ts->seed) & ts->mask);
575 }
576
577 static uint16_t
tag2hashindex(const struct pf_tagset * ts,uint16_t tag)578 tag2hashindex(const struct pf_tagset *ts, uint16_t tag)
579 {
580
581 return (tag & ts->mask);
582 }
583
584 static u_int16_t
tagname2tag(struct pf_tagset * ts,const char * tagname)585 tagname2tag(struct pf_tagset *ts, const char *tagname)
586 {
587 struct pf_tagname *tag;
588 u_int32_t index;
589 u_int16_t new_tagid;
590
591 PF_RULES_WASSERT();
592
593 index = tagname2hashindex(ts, tagname);
594 TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries)
595 if (strcmp(tagname, tag->name) == 0) {
596 tag->ref++;
597 return (tag->tag);
598 }
599
600 /*
601 * new entry
602 *
603 * to avoid fragmentation, we do a linear search from the beginning
604 * and take the first free slot we find.
605 */
606 new_tagid = BIT_FFS(TAGID_MAX, &ts->avail);
607 /*
608 * Tags are 1-based, with valid tags in the range [1..TAGID_MAX].
609 * BIT_FFS() returns a 1-based bit number, with 0 indicating no bits
610 * set. It may also return a bit number greater than TAGID_MAX due
611 * to rounding of the number of bits in the vector up to a multiple
612 * of the vector word size at declaration/allocation time.
613 */
614 if ((new_tagid == 0) || (new_tagid > TAGID_MAX))
615 return (0);
616
617 /* Mark the tag as in use. Bits are 0-based for BIT_CLR() */
618 BIT_CLR(TAGID_MAX, new_tagid - 1, &ts->avail);
619
620 /* allocate and fill new struct pf_tagname */
621 tag = uma_zalloc(V_pf_tag_z, M_NOWAIT);
622 if (tag == NULL)
623 return (0);
624 strlcpy(tag->name, tagname, sizeof(tag->name));
625 tag->tag = new_tagid;
626 tag->ref = 1;
627
628 /* Insert into namehash */
629 TAILQ_INSERT_TAIL(&ts->namehash[index], tag, namehash_entries);
630
631 /* Insert into taghash */
632 index = tag2hashindex(ts, new_tagid);
633 TAILQ_INSERT_TAIL(&ts->taghash[index], tag, taghash_entries);
634
635 return (tag->tag);
636 }
637
638 static void
tag_unref(struct pf_tagset * ts,u_int16_t tag)639 tag_unref(struct pf_tagset *ts, u_int16_t tag)
640 {
641 struct pf_tagname *t;
642 uint16_t index;
643
644 PF_RULES_WASSERT();
645
646 index = tag2hashindex(ts, tag);
647 TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries)
648 if (tag == t->tag) {
649 if (--t->ref == 0) {
650 TAILQ_REMOVE(&ts->taghash[index], t,
651 taghash_entries);
652 index = tagname2hashindex(ts, t->name);
653 TAILQ_REMOVE(&ts->namehash[index], t,
654 namehash_entries);
655 /* Bits are 0-based for BIT_SET() */
656 BIT_SET(TAGID_MAX, tag - 1, &ts->avail);
657 uma_zfree(V_pf_tag_z, t);
658 }
659 break;
660 }
661 }
662
663 static uint16_t
pf_tagname2tag(const char * tagname)664 pf_tagname2tag(const char *tagname)
665 {
666 return (tagname2tag(&V_pf_tags, tagname));
667 }
668
669 #ifdef ALTQ
670 static uint16_t
pf_qname2qid(const char * qname)671 pf_qname2qid(const char *qname)
672 {
673 return (tagname2tag(&V_pf_qids, qname));
674 }
675
676 static void
pf_qid_unref(uint16_t qid)677 pf_qid_unref(uint16_t qid)
678 {
679 tag_unref(&V_pf_qids, qid);
680 }
681
682 static int
pf_begin_altq(u_int32_t * ticket)683 pf_begin_altq(u_int32_t *ticket)
684 {
685 struct pf_altq *altq, *tmp;
686 int error = 0;
687
688 PF_RULES_WASSERT();
689
690 /* Purge the old altq lists */
691 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
692 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
693 /* detach and destroy the discipline */
694 error = altq_remove(altq);
695 }
696 free(altq, M_PFALTQ);
697 }
698 TAILQ_INIT(V_pf_altq_ifs_inactive);
699 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
700 pf_qid_unref(altq->qid);
701 free(altq, M_PFALTQ);
702 }
703 TAILQ_INIT(V_pf_altqs_inactive);
704 if (error)
705 return (error);
706 *ticket = ++V_ticket_altqs_inactive;
707 V_altqs_inactive_open = 1;
708 return (0);
709 }
710
711 static int
pf_rollback_altq(u_int32_t ticket)712 pf_rollback_altq(u_int32_t ticket)
713 {
714 struct pf_altq *altq, *tmp;
715 int error = 0;
716
717 PF_RULES_WASSERT();
718
719 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
720 return (0);
721 /* Purge the old altq lists */
722 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
723 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
724 /* detach and destroy the discipline */
725 error = altq_remove(altq);
726 }
727 free(altq, M_PFALTQ);
728 }
729 TAILQ_INIT(V_pf_altq_ifs_inactive);
730 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
731 pf_qid_unref(altq->qid);
732 free(altq, M_PFALTQ);
733 }
734 TAILQ_INIT(V_pf_altqs_inactive);
735 V_altqs_inactive_open = 0;
736 return (error);
737 }
738
739 static int
pf_commit_altq(u_int32_t ticket)740 pf_commit_altq(u_int32_t ticket)
741 {
742 struct pf_altqqueue *old_altqs, *old_altq_ifs;
743 struct pf_altq *altq, *tmp;
744 int err, error = 0;
745
746 PF_RULES_WASSERT();
747
748 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
749 return (EBUSY);
750
751 /* swap altqs, keep the old. */
752 old_altqs = V_pf_altqs_active;
753 old_altq_ifs = V_pf_altq_ifs_active;
754 V_pf_altqs_active = V_pf_altqs_inactive;
755 V_pf_altq_ifs_active = V_pf_altq_ifs_inactive;
756 V_pf_altqs_inactive = old_altqs;
757 V_pf_altq_ifs_inactive = old_altq_ifs;
758 V_ticket_altqs_active = V_ticket_altqs_inactive;
759
760 /* Attach new disciplines */
761 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
762 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
763 /* attach the discipline */
764 error = altq_pfattach(altq);
765 if (error == 0 && V_pf_altq_running)
766 error = pf_enable_altq(altq);
767 if (error != 0)
768 return (error);
769 }
770 }
771
772 /* Purge the old altq lists */
773 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
774 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
775 /* detach and destroy the discipline */
776 if (V_pf_altq_running)
777 error = pf_disable_altq(altq);
778 err = altq_pfdetach(altq);
779 if (err != 0 && error == 0)
780 error = err;
781 err = altq_remove(altq);
782 if (err != 0 && error == 0)
783 error = err;
784 }
785 free(altq, M_PFALTQ);
786 }
787 TAILQ_INIT(V_pf_altq_ifs_inactive);
788 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
789 pf_qid_unref(altq->qid);
790 free(altq, M_PFALTQ);
791 }
792 TAILQ_INIT(V_pf_altqs_inactive);
793
794 V_altqs_inactive_open = 0;
795 return (error);
796 }
797
798 static int
pf_enable_altq(struct pf_altq * altq)799 pf_enable_altq(struct pf_altq *altq)
800 {
801 struct ifnet *ifp;
802 struct tb_profile tb;
803 int error = 0;
804
805 if ((ifp = ifunit(altq->ifname)) == NULL)
806 return (EINVAL);
807
808 if (ifp->if_snd.altq_type != ALTQT_NONE)
809 error = altq_enable(&ifp->if_snd);
810
811 /* set tokenbucket regulator */
812 if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
813 tb.rate = altq->ifbandwidth;
814 tb.depth = altq->tbrsize;
815 error = tbr_set(&ifp->if_snd, &tb);
816 }
817
818 return (error);
819 }
820
821 static int
pf_disable_altq(struct pf_altq * altq)822 pf_disable_altq(struct pf_altq *altq)
823 {
824 struct ifnet *ifp;
825 struct tb_profile tb;
826 int error;
827
828 if ((ifp = ifunit(altq->ifname)) == NULL)
829 return (EINVAL);
830
831 /*
832 * when the discipline is no longer referenced, it was overridden
833 * by a new one. if so, just return.
834 */
835 if (altq->altq_disc != ifp->if_snd.altq_disc)
836 return (0);
837
838 error = altq_disable(&ifp->if_snd);
839
840 if (error == 0) {
841 /* clear tokenbucket regulator */
842 tb.rate = 0;
843 error = tbr_set(&ifp->if_snd, &tb);
844 }
845
846 return (error);
847 }
848
849 static int
pf_altq_ifnet_event_add(struct ifnet * ifp,int remove,u_int32_t ticket,struct pf_altq * altq)850 pf_altq_ifnet_event_add(struct ifnet *ifp, int remove, u_int32_t ticket,
851 struct pf_altq *altq)
852 {
853 struct ifnet *ifp1;
854 int error = 0;
855
856 /* Deactivate the interface in question */
857 altq->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
858 if ((ifp1 = ifunit(altq->ifname)) == NULL ||
859 (remove && ifp1 == ifp)) {
860 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
861 } else {
862 error = altq_add(ifp1, altq);
863
864 if (ticket != V_ticket_altqs_inactive)
865 error = EBUSY;
866
867 if (error)
868 free(altq, M_PFALTQ);
869 }
870
871 return (error);
872 }
873
874 void
pf_altq_ifnet_event(struct ifnet * ifp,int remove)875 pf_altq_ifnet_event(struct ifnet *ifp, int remove)
876 {
877 struct pf_altq *a1, *a2, *a3;
878 u_int32_t ticket;
879 int error = 0;
880
881 /*
882 * No need to re-evaluate the configuration for events on interfaces
883 * that do not support ALTQ, as it's not possible for such
884 * interfaces to be part of the configuration.
885 */
886 if (!ALTQ_IS_READY(&ifp->if_snd))
887 return;
888
889 /* Interrupt userland queue modifications */
890 if (V_altqs_inactive_open)
891 pf_rollback_altq(V_ticket_altqs_inactive);
892
893 /* Start new altq ruleset */
894 if (pf_begin_altq(&ticket))
895 return;
896
897 /* Copy the current active set */
898 TAILQ_FOREACH(a1, V_pf_altq_ifs_active, entries) {
899 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
900 if (a2 == NULL) {
901 error = ENOMEM;
902 break;
903 }
904 bcopy(a1, a2, sizeof(struct pf_altq));
905
906 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
907 if (error)
908 break;
909
910 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, a2, entries);
911 }
912 if (error)
913 goto out;
914 TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
915 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
916 if (a2 == NULL) {
917 error = ENOMEM;
918 break;
919 }
920 bcopy(a1, a2, sizeof(struct pf_altq));
921
922 if ((a2->qid = pf_qname2qid(a2->qname)) == 0) {
923 error = EBUSY;
924 free(a2, M_PFALTQ);
925 break;
926 }
927 a2->altq_disc = NULL;
928 TAILQ_FOREACH(a3, V_pf_altq_ifs_inactive, entries) {
929 if (strncmp(a3->ifname, a2->ifname,
930 IFNAMSIZ) == 0) {
931 a2->altq_disc = a3->altq_disc;
932 break;
933 }
934 }
935 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
936 if (error)
937 break;
938
939 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
940 }
941
942 out:
943 if (error != 0)
944 pf_rollback_altq(ticket);
945 else
946 pf_commit_altq(ticket);
947 }
948 #endif /* ALTQ */
949
950 static int
pf_begin_rules(u_int32_t * ticket,int rs_num,const char * anchor)951 pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
952 {
953 struct pf_kruleset *rs;
954 struct pf_krule *rule;
955
956 PF_RULES_WASSERT();
957
958 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
959 return (EINVAL);
960 rs = pf_find_or_create_kruleset(anchor);
961 if (rs == NULL)
962 return (EINVAL);
963 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
964 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
965 rs->rules[rs_num].inactive.rcount--;
966 }
967 *ticket = ++rs->rules[rs_num].inactive.ticket;
968 rs->rules[rs_num].inactive.open = 1;
969 return (0);
970 }
971
972 static int
pf_rollback_rules(u_int32_t ticket,int rs_num,char * anchor)973 pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
974 {
975 struct pf_kruleset *rs;
976 struct pf_krule *rule;
977
978 PF_RULES_WASSERT();
979
980 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
981 return (EINVAL);
982 rs = pf_find_kruleset(anchor);
983 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
984 rs->rules[rs_num].inactive.ticket != ticket)
985 return (0);
986 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
987 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
988 rs->rules[rs_num].inactive.rcount--;
989 }
990 rs->rules[rs_num].inactive.open = 0;
991 return (0);
992 }
993
994 #define PF_MD5_UPD(st, elm) \
995 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
996
997 #define PF_MD5_UPD_STR(st, elm) \
998 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
999
1000 #define PF_MD5_UPD_HTONL(st, elm, stor) do { \
1001 (stor) = htonl((st)->elm); \
1002 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
1003 } while (0)
1004
1005 #define PF_MD5_UPD_HTONS(st, elm, stor) do { \
1006 (stor) = htons((st)->elm); \
1007 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
1008 } while (0)
1009
1010 static void
pf_hash_rule_addr(MD5_CTX * ctx,struct pf_rule_addr * pfr)1011 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
1012 {
1013 PF_MD5_UPD(pfr, addr.type);
1014 switch (pfr->addr.type) {
1015 case PF_ADDR_DYNIFTL:
1016 PF_MD5_UPD(pfr, addr.v.ifname);
1017 PF_MD5_UPD(pfr, addr.iflags);
1018 break;
1019 case PF_ADDR_TABLE:
1020 PF_MD5_UPD(pfr, addr.v.tblname);
1021 break;
1022 case PF_ADDR_ADDRMASK:
1023 /* XXX ignore af? */
1024 PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
1025 PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
1026 break;
1027 }
1028
1029 PF_MD5_UPD(pfr, port[0]);
1030 PF_MD5_UPD(pfr, port[1]);
1031 PF_MD5_UPD(pfr, neg);
1032 PF_MD5_UPD(pfr, port_op);
1033 }
1034
1035 static void
pf_hash_rule(MD5_CTX * ctx,struct pf_krule * rule)1036 pf_hash_rule(MD5_CTX *ctx, struct pf_krule *rule)
1037 {
1038 u_int16_t x;
1039 u_int32_t y;
1040
1041 pf_hash_rule_addr(ctx, &rule->src);
1042 pf_hash_rule_addr(ctx, &rule->dst);
1043 for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
1044 PF_MD5_UPD_STR(rule, label[i]);
1045 PF_MD5_UPD_STR(rule, ifname);
1046 PF_MD5_UPD_STR(rule, match_tagname);
1047 PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
1048 PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
1049 PF_MD5_UPD_HTONL(rule, prob, y);
1050 PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
1051 PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
1052 PF_MD5_UPD(rule, uid.op);
1053 PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
1054 PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
1055 PF_MD5_UPD(rule, gid.op);
1056 PF_MD5_UPD_HTONL(rule, rule_flag, y);
1057 PF_MD5_UPD(rule, action);
1058 PF_MD5_UPD(rule, direction);
1059 PF_MD5_UPD(rule, af);
1060 PF_MD5_UPD(rule, quick);
1061 PF_MD5_UPD(rule, ifnot);
1062 PF_MD5_UPD(rule, match_tag_not);
1063 PF_MD5_UPD(rule, natpass);
1064 PF_MD5_UPD(rule, keep_state);
1065 PF_MD5_UPD(rule, proto);
1066 PF_MD5_UPD(rule, type);
1067 PF_MD5_UPD(rule, code);
1068 PF_MD5_UPD(rule, flags);
1069 PF_MD5_UPD(rule, flagset);
1070 PF_MD5_UPD(rule, allow_opts);
1071 PF_MD5_UPD(rule, rt);
1072 PF_MD5_UPD(rule, tos);
1073 }
1074
1075 static bool
pf_krule_compare(struct pf_krule * a,struct pf_krule * b)1076 pf_krule_compare(struct pf_krule *a, struct pf_krule *b)
1077 {
1078 MD5_CTX ctx[2];
1079 u_int8_t digest[2][PF_MD5_DIGEST_LENGTH];
1080
1081 MD5Init(&ctx[0]);
1082 MD5Init(&ctx[1]);
1083 pf_hash_rule(&ctx[0], a);
1084 pf_hash_rule(&ctx[1], b);
1085 MD5Final(digest[0], &ctx[0]);
1086 MD5Final(digest[1], &ctx[1]);
1087
1088 return (memcmp(digest[0], digest[1], PF_MD5_DIGEST_LENGTH) == 0);
1089 }
1090
1091 static int
pf_commit_rules(u_int32_t ticket,int rs_num,char * anchor)1092 pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
1093 {
1094 struct pf_kruleset *rs;
1095 struct pf_krule *rule, **old_array, *tail;
1096 struct pf_krulequeue *old_rules;
1097 int error;
1098 u_int32_t old_rcount;
1099
1100 PF_RULES_WASSERT();
1101
1102 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1103 return (EINVAL);
1104 rs = pf_find_kruleset(anchor);
1105 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1106 ticket != rs->rules[rs_num].inactive.ticket)
1107 return (EBUSY);
1108
1109 /* Calculate checksum for the main ruleset */
1110 if (rs == &pf_main_ruleset) {
1111 error = pf_setup_pfsync_matching(rs);
1112 if (error != 0)
1113 return (error);
1114 }
1115
1116 /* Swap rules, keep the old. */
1117 old_rules = rs->rules[rs_num].active.ptr;
1118 old_rcount = rs->rules[rs_num].active.rcount;
1119 old_array = rs->rules[rs_num].active.ptr_array;
1120
1121 rs->rules[rs_num].active.ptr =
1122 rs->rules[rs_num].inactive.ptr;
1123 rs->rules[rs_num].active.ptr_array =
1124 rs->rules[rs_num].inactive.ptr_array;
1125 rs->rules[rs_num].active.rcount =
1126 rs->rules[rs_num].inactive.rcount;
1127
1128 /* Attempt to preserve counter information. */
1129 if (V_pf_status.keep_counters) {
1130 TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr,
1131 entries) {
1132 tail = TAILQ_FIRST(old_rules);
1133 while ((tail != NULL) && ! pf_krule_compare(tail, rule))
1134 tail = TAILQ_NEXT(tail, entries);
1135 if (tail != NULL) {
1136 pf_counter_u64_critical_enter();
1137 pf_counter_u64_add_protected(&rule->evaluations,
1138 pf_counter_u64_fetch(&tail->evaluations));
1139 pf_counter_u64_add_protected(&rule->packets[0],
1140 pf_counter_u64_fetch(&tail->packets[0]));
1141 pf_counter_u64_add_protected(&rule->packets[1],
1142 pf_counter_u64_fetch(&tail->packets[1]));
1143 pf_counter_u64_add_protected(&rule->bytes[0],
1144 pf_counter_u64_fetch(&tail->bytes[0]));
1145 pf_counter_u64_add_protected(&rule->bytes[1],
1146 pf_counter_u64_fetch(&tail->bytes[1]));
1147 pf_counter_u64_critical_exit();
1148 }
1149 }
1150 }
1151
1152 rs->rules[rs_num].inactive.ptr = old_rules;
1153 rs->rules[rs_num].inactive.ptr_array = old_array;
1154 rs->rules[rs_num].inactive.rcount = old_rcount;
1155
1156 rs->rules[rs_num].active.ticket =
1157 rs->rules[rs_num].inactive.ticket;
1158 pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1159
1160 /* Purge the old rule list. */
1161 while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1162 pf_unlink_rule(old_rules, rule);
1163 if (rs->rules[rs_num].inactive.ptr_array)
1164 free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
1165 rs->rules[rs_num].inactive.ptr_array = NULL;
1166 rs->rules[rs_num].inactive.rcount = 0;
1167 rs->rules[rs_num].inactive.open = 0;
1168 pf_remove_if_empty_kruleset(rs);
1169
1170 return (0);
1171 }
1172
1173 static int
pf_setup_pfsync_matching(struct pf_kruleset * rs)1174 pf_setup_pfsync_matching(struct pf_kruleset *rs)
1175 {
1176 MD5_CTX ctx;
1177 struct pf_krule *rule;
1178 int rs_cnt;
1179 u_int8_t digest[PF_MD5_DIGEST_LENGTH];
1180
1181 MD5Init(&ctx);
1182 for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
1183 /* XXX PF_RULESET_SCRUB as well? */
1184 if (rs_cnt == PF_RULESET_SCRUB)
1185 continue;
1186
1187 if (rs->rules[rs_cnt].inactive.ptr_array)
1188 free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
1189 rs->rules[rs_cnt].inactive.ptr_array = NULL;
1190
1191 if (rs->rules[rs_cnt].inactive.rcount) {
1192 rs->rules[rs_cnt].inactive.ptr_array =
1193 malloc(sizeof(caddr_t) *
1194 rs->rules[rs_cnt].inactive.rcount,
1195 M_TEMP, M_NOWAIT);
1196
1197 if (!rs->rules[rs_cnt].inactive.ptr_array)
1198 return (ENOMEM);
1199 }
1200
1201 TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
1202 entries) {
1203 pf_hash_rule(&ctx, rule);
1204 (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
1205 }
1206 }
1207
1208 MD5Final(digest, &ctx);
1209 memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
1210 return (0);
1211 }
1212
1213 static int
pf_addr_setup(struct pf_kruleset * ruleset,struct pf_addr_wrap * addr,sa_family_t af)1214 pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
1215 sa_family_t af)
1216 {
1217 int error = 0;
1218
1219 switch (addr->type) {
1220 case PF_ADDR_TABLE:
1221 addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname);
1222 if (addr->p.tbl == NULL)
1223 error = ENOMEM;
1224 break;
1225 case PF_ADDR_DYNIFTL:
1226 error = pfi_dynaddr_setup(addr, af);
1227 break;
1228 }
1229
1230 return (error);
1231 }
1232
1233 static void
pf_addr_copyout(struct pf_addr_wrap * addr)1234 pf_addr_copyout(struct pf_addr_wrap *addr)
1235 {
1236
1237 switch (addr->type) {
1238 case PF_ADDR_DYNIFTL:
1239 pfi_dynaddr_copyout(addr);
1240 break;
1241 case PF_ADDR_TABLE:
1242 pf_tbladdr_copyout(addr);
1243 break;
1244 }
1245 }
1246
1247 static void
pf_src_node_copy(const struct pf_ksrc_node * in,struct pf_src_node * out)1248 pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out)
1249 {
1250 int secs = time_uptime, diff;
1251
1252 bzero(out, sizeof(struct pf_src_node));
1253
1254 bcopy(&in->addr, &out->addr, sizeof(struct pf_addr));
1255 bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr));
1256
1257 if (in->rule.ptr != NULL)
1258 out->rule.nr = in->rule.ptr->nr;
1259
1260 for (int i = 0; i < 2; i++) {
1261 out->bytes[i] = counter_u64_fetch(in->bytes[i]);
1262 out->packets[i] = counter_u64_fetch(in->packets[i]);
1263 }
1264
1265 out->states = in->states;
1266 out->conn = in->conn;
1267 out->af = in->af;
1268 out->ruletype = in->ruletype;
1269
1270 out->creation = secs - in->creation;
1271 if (out->expire > secs)
1272 out->expire -= secs;
1273 else
1274 out->expire = 0;
1275
1276 /* Adjust the connection rate estimate. */
1277 diff = secs - in->conn_rate.last;
1278 if (diff >= in->conn_rate.seconds)
1279 out->conn_rate.count = 0;
1280 else
1281 out->conn_rate.count -=
1282 in->conn_rate.count * diff /
1283 in->conn_rate.seconds;
1284 }
1285
1286 #ifdef ALTQ
1287 /*
1288 * Handle export of struct pf_kaltq to user binaries that may be using any
1289 * version of struct pf_altq.
1290 */
1291 static int
pf_export_kaltq(struct pf_altq * q,struct pfioc_altq_v1 * pa,size_t ioc_size)1292 pf_export_kaltq(struct pf_altq *q, struct pfioc_altq_v1 *pa, size_t ioc_size)
1293 {
1294 u_int32_t version;
1295
1296 if (ioc_size == sizeof(struct pfioc_altq_v0))
1297 version = 0;
1298 else
1299 version = pa->version;
1300
1301 if (version > PFIOC_ALTQ_VERSION)
1302 return (EINVAL);
1303
1304 #define ASSIGN(x) exported_q->x = q->x
1305 #define COPY(x) \
1306 bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x)))
1307 #define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX)
1308 #define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX)
1309
1310 switch (version) {
1311 case 0: {
1312 struct pf_altq_v0 *exported_q =
1313 &((struct pfioc_altq_v0 *)pa)->altq;
1314
1315 COPY(ifname);
1316
1317 ASSIGN(scheduler);
1318 ASSIGN(tbrsize);
1319 exported_q->tbrsize = SATU16(q->tbrsize);
1320 exported_q->ifbandwidth = SATU32(q->ifbandwidth);
1321
1322 COPY(qname);
1323 COPY(parent);
1324 ASSIGN(parent_qid);
1325 exported_q->bandwidth = SATU32(q->bandwidth);
1326 ASSIGN(priority);
1327 ASSIGN(local_flags);
1328
1329 ASSIGN(qlimit);
1330 ASSIGN(flags);
1331
1332 if (q->scheduler == ALTQT_HFSC) {
1333 #define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x
1334 #define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \
1335 SATU32(q->pq_u.hfsc_opts.x)
1336
1337 ASSIGN_OPT_SATU32(rtsc_m1);
1338 ASSIGN_OPT(rtsc_d);
1339 ASSIGN_OPT_SATU32(rtsc_m2);
1340
1341 ASSIGN_OPT_SATU32(lssc_m1);
1342 ASSIGN_OPT(lssc_d);
1343 ASSIGN_OPT_SATU32(lssc_m2);
1344
1345 ASSIGN_OPT_SATU32(ulsc_m1);
1346 ASSIGN_OPT(ulsc_d);
1347 ASSIGN_OPT_SATU32(ulsc_m2);
1348
1349 ASSIGN_OPT(flags);
1350
1351 #undef ASSIGN_OPT
1352 #undef ASSIGN_OPT_SATU32
1353 } else
1354 COPY(pq_u);
1355
1356 ASSIGN(qid);
1357 break;
1358 }
1359 case 1: {
1360 struct pf_altq_v1 *exported_q =
1361 &((struct pfioc_altq_v1 *)pa)->altq;
1362
1363 COPY(ifname);
1364
1365 ASSIGN(scheduler);
1366 ASSIGN(tbrsize);
1367 ASSIGN(ifbandwidth);
1368
1369 COPY(qname);
1370 COPY(parent);
1371 ASSIGN(parent_qid);
1372 ASSIGN(bandwidth);
1373 ASSIGN(priority);
1374 ASSIGN(local_flags);
1375
1376 ASSIGN(qlimit);
1377 ASSIGN(flags);
1378 COPY(pq_u);
1379
1380 ASSIGN(qid);
1381 break;
1382 }
1383 default:
1384 panic("%s: unhandled struct pfioc_altq version", __func__);
1385 break;
1386 }
1387
1388 #undef ASSIGN
1389 #undef COPY
1390 #undef SATU16
1391 #undef SATU32
1392
1393 return (0);
1394 }
1395
1396 /*
1397 * Handle import to struct pf_kaltq of struct pf_altq from user binaries
1398 * that may be using any version of it.
1399 */
1400 static int
pf_import_kaltq(struct pfioc_altq_v1 * pa,struct pf_altq * q,size_t ioc_size)1401 pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altq *q, size_t ioc_size)
1402 {
1403 u_int32_t version;
1404
1405 if (ioc_size == sizeof(struct pfioc_altq_v0))
1406 version = 0;
1407 else
1408 version = pa->version;
1409
1410 if (version > PFIOC_ALTQ_VERSION)
1411 return (EINVAL);
1412
1413 #define ASSIGN(x) q->x = imported_q->x
1414 #define COPY(x) \
1415 bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x)))
1416
1417 switch (version) {
1418 case 0: {
1419 struct pf_altq_v0 *imported_q =
1420 &((struct pfioc_altq_v0 *)pa)->altq;
1421
1422 COPY(ifname);
1423
1424 ASSIGN(scheduler);
1425 ASSIGN(tbrsize); /* 16-bit -> 32-bit */
1426 ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */
1427
1428 COPY(qname);
1429 COPY(parent);
1430 ASSIGN(parent_qid);
1431 ASSIGN(bandwidth); /* 32-bit -> 64-bit */
1432 ASSIGN(priority);
1433 ASSIGN(local_flags);
1434
1435 ASSIGN(qlimit);
1436 ASSIGN(flags);
1437
1438 if (imported_q->scheduler == ALTQT_HFSC) {
1439 #define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x
1440
1441 /*
1442 * The m1 and m2 parameters are being copied from
1443 * 32-bit to 64-bit.
1444 */
1445 ASSIGN_OPT(rtsc_m1);
1446 ASSIGN_OPT(rtsc_d);
1447 ASSIGN_OPT(rtsc_m2);
1448
1449 ASSIGN_OPT(lssc_m1);
1450 ASSIGN_OPT(lssc_d);
1451 ASSIGN_OPT(lssc_m2);
1452
1453 ASSIGN_OPT(ulsc_m1);
1454 ASSIGN_OPT(ulsc_d);
1455 ASSIGN_OPT(ulsc_m2);
1456
1457 ASSIGN_OPT(flags);
1458
1459 #undef ASSIGN_OPT
1460 } else
1461 COPY(pq_u);
1462
1463 ASSIGN(qid);
1464 break;
1465 }
1466 case 1: {
1467 struct pf_altq_v1 *imported_q =
1468 &((struct pfioc_altq_v1 *)pa)->altq;
1469
1470 COPY(ifname);
1471
1472 ASSIGN(scheduler);
1473 ASSIGN(tbrsize);
1474 ASSIGN(ifbandwidth);
1475
1476 COPY(qname);
1477 COPY(parent);
1478 ASSIGN(parent_qid);
1479 ASSIGN(bandwidth);
1480 ASSIGN(priority);
1481 ASSIGN(local_flags);
1482
1483 ASSIGN(qlimit);
1484 ASSIGN(flags);
1485 COPY(pq_u);
1486
1487 ASSIGN(qid);
1488 break;
1489 }
1490 default:
1491 panic("%s: unhandled struct pfioc_altq version", __func__);
1492 break;
1493 }
1494
1495 #undef ASSIGN
1496 #undef COPY
1497
1498 return (0);
1499 }
1500
1501 static struct pf_altq *
pf_altq_get_nth_active(u_int32_t n)1502 pf_altq_get_nth_active(u_int32_t n)
1503 {
1504 struct pf_altq *altq;
1505 u_int32_t nr;
1506
1507 nr = 0;
1508 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
1509 if (nr == n)
1510 return (altq);
1511 nr++;
1512 }
1513
1514 TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
1515 if (nr == n)
1516 return (altq);
1517 nr++;
1518 }
1519
1520 return (NULL);
1521 }
1522 #endif /* ALTQ */
1523
1524 struct pf_krule *
pf_krule_alloc(void)1525 pf_krule_alloc(void)
1526 {
1527 struct pf_krule *rule;
1528
1529 rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO);
1530 mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF);
1531 return (rule);
1532 }
1533
1534 void
pf_krule_free(struct pf_krule * rule)1535 pf_krule_free(struct pf_krule *rule)
1536 {
1537 #ifdef PF_WANT_32_TO_64_COUNTER
1538 bool wowned;
1539 #endif
1540
1541 if (rule == NULL)
1542 return;
1543
1544 #ifdef PF_WANT_32_TO_64_COUNTER
1545 if (rule->allrulelinked) {
1546 wowned = PF_RULES_WOWNED();
1547 if (!wowned)
1548 PF_RULES_WLOCK();
1549 LIST_REMOVE(rule, allrulelist);
1550 V_pf_allrulecount--;
1551 if (!wowned)
1552 PF_RULES_WUNLOCK();
1553 }
1554 #endif
1555
1556 pf_counter_u64_deinit(&rule->evaluations);
1557 for (int i = 0; i < 2; i++) {
1558 pf_counter_u64_deinit(&rule->packets[i]);
1559 pf_counter_u64_deinit(&rule->bytes[i]);
1560 }
1561 counter_u64_free(rule->states_cur);
1562 counter_u64_free(rule->states_tot);
1563 counter_u64_free(rule->src_nodes);
1564
1565 mtx_destroy(&rule->rpool.mtx);
1566 free(rule, M_PFRULE);
1567 }
1568
1569 static void
pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr * kpool,struct pf_pooladdr * pool)1570 pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool,
1571 struct pf_pooladdr *pool)
1572 {
1573
1574 bzero(pool, sizeof(*pool));
1575 bcopy(&kpool->addr, &pool->addr, sizeof(pool->addr));
1576 strlcpy(pool->ifname, kpool->ifname, sizeof(pool->ifname));
1577 }
1578
1579 static int
pf_pooladdr_to_kpooladdr(const struct pf_pooladdr * pool,struct pf_kpooladdr * kpool)1580 pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
1581 struct pf_kpooladdr *kpool)
1582 {
1583 int ret;
1584
1585 bzero(kpool, sizeof(*kpool));
1586 bcopy(&pool->addr, &kpool->addr, sizeof(kpool->addr));
1587 ret = pf_user_strcpy(kpool->ifname, pool->ifname,
1588 sizeof(kpool->ifname));
1589 return (ret);
1590 }
1591
1592 static void
pf_kpool_to_pool(const struct pf_kpool * kpool,struct pf_pool * pool)1593 pf_kpool_to_pool(const struct pf_kpool *kpool, struct pf_pool *pool)
1594 {
1595 bzero(pool, sizeof(*pool));
1596
1597 bcopy(&kpool->key, &pool->key, sizeof(pool->key));
1598 bcopy(&kpool->counter, &pool->counter, sizeof(pool->counter));
1599
1600 pool->tblidx = kpool->tblidx;
1601 pool->proxy_port[0] = kpool->proxy_port[0];
1602 pool->proxy_port[1] = kpool->proxy_port[1];
1603 pool->opts = kpool->opts;
1604 }
1605
1606 static void
pf_pool_to_kpool(const struct pf_pool * pool,struct pf_kpool * kpool)1607 pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool)
1608 {
1609 _Static_assert(sizeof(pool->key) == sizeof(kpool->key), "");
1610 _Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), "");
1611
1612 bcopy(&pool->key, &kpool->key, sizeof(kpool->key));
1613 bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter));
1614
1615 kpool->tblidx = pool->tblidx;
1616 kpool->proxy_port[0] = pool->proxy_port[0];
1617 kpool->proxy_port[1] = pool->proxy_port[1];
1618 kpool->opts = pool->opts;
1619 }
1620
1621 static void
pf_krule_to_rule(const struct pf_krule * krule,struct pf_rule * rule)1622 pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule)
1623 {
1624
1625 bzero(rule, sizeof(*rule));
1626
1627 bcopy(&krule->src, &rule->src, sizeof(rule->src));
1628 bcopy(&krule->dst, &rule->dst, sizeof(rule->dst));
1629
1630 for (int i = 0; i < PF_SKIP_COUNT; ++i) {
1631 if (rule->skip[i].ptr == NULL)
1632 rule->skip[i].nr = -1;
1633 else
1634 rule->skip[i].nr = krule->skip[i].ptr->nr;
1635 }
1636
1637 strlcpy(rule->label, krule->label[0], sizeof(rule->label));
1638 strlcpy(rule->ifname, krule->ifname, sizeof(rule->ifname));
1639 strlcpy(rule->qname, krule->qname, sizeof(rule->qname));
1640 strlcpy(rule->pqname, krule->pqname, sizeof(rule->pqname));
1641 strlcpy(rule->tagname, krule->tagname, sizeof(rule->tagname));
1642 strlcpy(rule->match_tagname, krule->match_tagname,
1643 sizeof(rule->match_tagname));
1644 strlcpy(rule->overload_tblname, krule->overload_tblname,
1645 sizeof(rule->overload_tblname));
1646
1647 pf_kpool_to_pool(&krule->rpool, &rule->rpool);
1648
1649 rule->evaluations = pf_counter_u64_fetch(&krule->evaluations);
1650 for (int i = 0; i < 2; i++) {
1651 rule->packets[i] = pf_counter_u64_fetch(&krule->packets[i]);
1652 rule->bytes[i] = pf_counter_u64_fetch(&krule->bytes[i]);
1653 }
1654
1655 /* kif, anchor, overload_tbl are not copied over. */
1656
1657 rule->os_fingerprint = krule->os_fingerprint;
1658
1659 rule->rtableid = krule->rtableid;
1660 bcopy(krule->timeout, rule->timeout, sizeof(krule->timeout));
1661 rule->max_states = krule->max_states;
1662 rule->max_src_nodes = krule->max_src_nodes;
1663 rule->max_src_states = krule->max_src_states;
1664 rule->max_src_conn = krule->max_src_conn;
1665 rule->max_src_conn_rate.limit = krule->max_src_conn_rate.limit;
1666 rule->max_src_conn_rate.seconds = krule->max_src_conn_rate.seconds;
1667 rule->qid = krule->qid;
1668 rule->pqid = krule->pqid;
1669 rule->nr = krule->nr;
1670 rule->prob = krule->prob;
1671 rule->cuid = krule->cuid;
1672 rule->cpid = krule->cpid;
1673
1674 rule->return_icmp = krule->return_icmp;
1675 rule->return_icmp6 = krule->return_icmp6;
1676 rule->max_mss = krule->max_mss;
1677 rule->tag = krule->tag;
1678 rule->match_tag = krule->match_tag;
1679 rule->scrub_flags = krule->scrub_flags;
1680
1681 bcopy(&krule->uid, &rule->uid, sizeof(krule->uid));
1682 bcopy(&krule->gid, &rule->gid, sizeof(krule->gid));
1683
1684 rule->rule_flag = krule->rule_flag;
1685 rule->action = krule->action;
1686 rule->direction = krule->direction;
1687 rule->log = krule->log;
1688 rule->logif = krule->logif;
1689 rule->quick = krule->quick;
1690 rule->ifnot = krule->ifnot;
1691 rule->match_tag_not = krule->match_tag_not;
1692 rule->natpass = krule->natpass;
1693
1694 rule->keep_state = krule->keep_state;
1695 rule->af = krule->af;
1696 rule->proto = krule->proto;
1697 rule->type = krule->type;
1698 rule->code = krule->code;
1699 rule->flags = krule->flags;
1700 rule->flagset = krule->flagset;
1701 rule->min_ttl = krule->min_ttl;
1702 rule->allow_opts = krule->allow_opts;
1703 rule->rt = krule->rt;
1704 rule->return_ttl = krule->return_ttl;
1705 rule->tos = krule->tos;
1706 rule->set_tos = krule->set_tos;
1707 rule->anchor_relative = krule->anchor_relative;
1708 rule->anchor_wildcard = krule->anchor_wildcard;
1709
1710 rule->flush = krule->flush;
1711 rule->prio = krule->prio;
1712 rule->set_prio[0] = krule->set_prio[0];
1713 rule->set_prio[1] = krule->set_prio[1];
1714
1715 bcopy(&krule->divert, &rule->divert, sizeof(krule->divert));
1716
1717 rule->u_states_cur = counter_u64_fetch(krule->states_cur);
1718 rule->u_states_tot = counter_u64_fetch(krule->states_tot);
1719 rule->u_src_nodes = counter_u64_fetch(krule->src_nodes);
1720 }
1721
1722 static int
pf_rule_to_krule(const struct pf_rule * rule,struct pf_krule * krule)1723 pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
1724 {
1725 int ret;
1726
1727 #ifndef INET
1728 if (rule->af == AF_INET) {
1729 return (EAFNOSUPPORT);
1730 }
1731 #endif /* INET */
1732 #ifndef INET6
1733 if (rule->af == AF_INET6) {
1734 return (EAFNOSUPPORT);
1735 }
1736 #endif /* INET6 */
1737
1738 ret = pf_check_rule_addr(&rule->src);
1739 if (ret != 0)
1740 return (ret);
1741 ret = pf_check_rule_addr(&rule->dst);
1742 if (ret != 0)
1743 return (ret);
1744
1745 bcopy(&rule->src, &krule->src, sizeof(rule->src));
1746 bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
1747
1748 ret = pf_user_strcpy(krule->label[0], rule->label, sizeof(rule->label));
1749 if (ret != 0)
1750 return (ret);
1751 ret = pf_user_strcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
1752 if (ret != 0)
1753 return (ret);
1754 ret = pf_user_strcpy(krule->qname, rule->qname, sizeof(rule->qname));
1755 if (ret != 0)
1756 return (ret);
1757 ret = pf_user_strcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
1758 if (ret != 0)
1759 return (ret);
1760 ret = pf_user_strcpy(krule->tagname, rule->tagname,
1761 sizeof(rule->tagname));
1762 if (ret != 0)
1763 return (ret);
1764 ret = pf_user_strcpy(krule->match_tagname, rule->match_tagname,
1765 sizeof(rule->match_tagname));
1766 if (ret != 0)
1767 return (ret);
1768 ret = pf_user_strcpy(krule->overload_tblname, rule->overload_tblname,
1769 sizeof(rule->overload_tblname));
1770 if (ret != 0)
1771 return (ret);
1772
1773 pf_pool_to_kpool(&rule->rpool, &krule->rpool);
1774
1775 /* Don't allow userspace to set evaulations, packets or bytes. */
1776 /* kif, anchor, overload_tbl are not copied over. */
1777
1778 krule->os_fingerprint = rule->os_fingerprint;
1779
1780 krule->rtableid = rule->rtableid;
1781 bcopy(rule->timeout, krule->timeout, sizeof(krule->timeout));
1782 krule->max_states = rule->max_states;
1783 krule->max_src_nodes = rule->max_src_nodes;
1784 krule->max_src_states = rule->max_src_states;
1785 krule->max_src_conn = rule->max_src_conn;
1786 krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit;
1787 krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds;
1788 krule->qid = rule->qid;
1789 krule->pqid = rule->pqid;
1790 krule->nr = rule->nr;
1791 krule->prob = rule->prob;
1792 krule->cuid = rule->cuid;
1793 krule->cpid = rule->cpid;
1794
1795 krule->return_icmp = rule->return_icmp;
1796 krule->return_icmp6 = rule->return_icmp6;
1797 krule->max_mss = rule->max_mss;
1798 krule->tag = rule->tag;
1799 krule->match_tag = rule->match_tag;
1800 krule->scrub_flags = rule->scrub_flags;
1801
1802 bcopy(&rule->uid, &krule->uid, sizeof(krule->uid));
1803 bcopy(&rule->gid, &krule->gid, sizeof(krule->gid));
1804
1805 krule->rule_flag = rule->rule_flag;
1806 krule->action = rule->action;
1807 krule->direction = rule->direction;
1808 krule->log = rule->log;
1809 krule->logif = rule->logif;
1810 krule->quick = rule->quick;
1811 krule->ifnot = rule->ifnot;
1812 krule->match_tag_not = rule->match_tag_not;
1813 krule->natpass = rule->natpass;
1814
1815 krule->keep_state = rule->keep_state;
1816 krule->af = rule->af;
1817 krule->proto = rule->proto;
1818 krule->type = rule->type;
1819 krule->code = rule->code;
1820 krule->flags = rule->flags;
1821 krule->flagset = rule->flagset;
1822 krule->min_ttl = rule->min_ttl;
1823 krule->allow_opts = rule->allow_opts;
1824 krule->rt = rule->rt;
1825 krule->return_ttl = rule->return_ttl;
1826 krule->tos = rule->tos;
1827 krule->set_tos = rule->set_tos;
1828
1829 krule->flush = rule->flush;
1830 krule->prio = rule->prio;
1831 krule->set_prio[0] = rule->set_prio[0];
1832 krule->set_prio[1] = rule->set_prio[1];
1833
1834 bcopy(&rule->divert, &krule->divert, sizeof(krule->divert));
1835
1836 return (0);
1837 }
1838
1839 static bool
pf_label_match(const struct pf_krule * rule,const char * label)1840 pf_label_match(const struct pf_krule *rule, const char *label)
1841 {
1842 int i = 0;
1843
1844 while (*rule->label[i]) {
1845 if (strcmp(rule->label[i], label) == 0)
1846 return (true);
1847 i++;
1848 }
1849
1850 return (false);
1851 }
1852
1853 static unsigned int
pf_kill_matching_state(struct pf_state_key_cmp * key,int dir)1854 pf_kill_matching_state(struct pf_state_key_cmp *key, int dir)
1855 {
1856 struct pf_kstate *match;
1857 int more = 0;
1858 unsigned int killed = 0;
1859
1860 /* Call with unlocked hashrow */
1861
1862 match = pf_find_state_all(key, dir, &more);
1863 if (match && !more) {
1864 pf_unlink_state(match, 0);
1865 killed++;
1866 }
1867
1868 return (killed);
1869 }
1870
1871 static int
pf_killstates_row(struct pf_kstate_kill * psk,struct pf_idhash * ih)1872 pf_killstates_row(struct pf_kstate_kill *psk, struct pf_idhash *ih)
1873 {
1874 struct pf_kstate *s;
1875 struct pf_state_key *sk;
1876 struct pf_addr *srcaddr, *dstaddr;
1877 struct pf_state_key_cmp match_key;
1878 int idx, killed = 0;
1879 unsigned int dir;
1880 u_int16_t srcport, dstport;
1881 struct pfi_kkif *kif;
1882
1883 relock_DIOCKILLSTATES:
1884 PF_HASHROW_LOCK(ih);
1885 LIST_FOREACH(s, &ih->states, entry) {
1886 /* For floating states look at the original kif. */
1887 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
1888
1889 sk = s->key[PF_SK_WIRE];
1890 if (s->direction == PF_OUT) {
1891 srcaddr = &sk->addr[1];
1892 dstaddr = &sk->addr[0];
1893 srcport = sk->port[1];
1894 dstport = sk->port[0];
1895 } else {
1896 srcaddr = &sk->addr[0];
1897 dstaddr = &sk->addr[1];
1898 srcport = sk->port[0];
1899 dstport = sk->port[1];
1900 }
1901
1902 if (psk->psk_af && sk->af != psk->psk_af)
1903 continue;
1904
1905 if (psk->psk_proto && psk->psk_proto != sk->proto)
1906 continue;
1907
1908 if (! PF_MATCHA(psk->psk_src.neg, &psk->psk_src.addr.v.a.addr,
1909 &psk->psk_src.addr.v.a.mask, srcaddr, sk->af))
1910 continue;
1911
1912 if (! PF_MATCHA(psk->psk_dst.neg, &psk->psk_dst.addr.v.a.addr,
1913 &psk->psk_dst.addr.v.a.mask, dstaddr, sk->af))
1914 continue;
1915
1916 if (! PF_MATCHA(psk->psk_rt_addr.neg,
1917 &psk->psk_rt_addr.addr.v.a.addr,
1918 &psk->psk_rt_addr.addr.v.a.mask,
1919 &s->rt_addr, sk->af))
1920 continue;
1921
1922 if (psk->psk_src.port_op != 0 &&
1923 ! pf_match_port(psk->psk_src.port_op,
1924 psk->psk_src.port[0], psk->psk_src.port[1], srcport))
1925 continue;
1926
1927 if (psk->psk_dst.port_op != 0 &&
1928 ! pf_match_port(psk->psk_dst.port_op,
1929 psk->psk_dst.port[0], psk->psk_dst.port[1], dstport))
1930 continue;
1931
1932 if (psk->psk_label[0] &&
1933 ! pf_label_match(s->rule.ptr, psk->psk_label))
1934 continue;
1935
1936 if (psk->psk_ifname[0] && strcmp(psk->psk_ifname,
1937 kif->pfik_name))
1938 continue;
1939
1940 if (psk->psk_kill_match) {
1941 /* Create the key to find matching states, with lock
1942 * held. */
1943
1944 bzero(&match_key, sizeof(match_key));
1945
1946 if (s->direction == PF_OUT) {
1947 dir = PF_IN;
1948 idx = PF_SK_STACK;
1949 } else {
1950 dir = PF_OUT;
1951 idx = PF_SK_WIRE;
1952 }
1953
1954 match_key.af = s->key[idx]->af;
1955 match_key.proto = s->key[idx]->proto;
1956 PF_ACPY(&match_key.addr[0],
1957 &s->key[idx]->addr[1], match_key.af);
1958 match_key.port[0] = s->key[idx]->port[1];
1959 PF_ACPY(&match_key.addr[1],
1960 &s->key[idx]->addr[0], match_key.af);
1961 match_key.port[1] = s->key[idx]->port[0];
1962 }
1963
1964 pf_unlink_state(s, PF_ENTER_LOCKED);
1965 killed++;
1966
1967 if (psk->psk_kill_match)
1968 killed += pf_kill_matching_state(&match_key, dir);
1969
1970 goto relock_DIOCKILLSTATES;
1971 }
1972 PF_HASHROW_UNLOCK(ih);
1973
1974 return (killed);
1975 }
1976
1977 static int
pf_state_kill_to_kstate_kill(const struct pfioc_state_kill * psk,struct pf_kstate_kill * kill)1978 pf_state_kill_to_kstate_kill(const struct pfioc_state_kill *psk,
1979 struct pf_kstate_kill *kill)
1980 {
1981 int ret;
1982
1983 bzero(kill, sizeof(*kill));
1984
1985 bcopy(&psk->psk_pfcmp, &kill->psk_pfcmp, sizeof(kill->psk_pfcmp));
1986 kill->psk_af = psk->psk_af;
1987 kill->psk_proto = psk->psk_proto;
1988 bcopy(&psk->psk_src, &kill->psk_src, sizeof(kill->psk_src));
1989 bcopy(&psk->psk_dst, &kill->psk_dst, sizeof(kill->psk_dst));
1990 ret = pf_user_strcpy(kill->psk_ifname, psk->psk_ifname,
1991 sizeof(kill->psk_ifname));
1992 if (ret != 0)
1993 return (ret);
1994 ret = pf_user_strcpy(kill->psk_label, psk->psk_label,
1995 sizeof(kill->psk_label));
1996 if (ret != 0)
1997 return (ret);
1998
1999 return (0);
2000 }
2001
2002 static int
pf_ioctl_addrule(struct pf_krule * rule,uint32_t ticket,uint32_t pool_ticket,const char * anchor,const char * anchor_call,struct thread * td)2003 pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
2004 uint32_t pool_ticket, const char *anchor, const char *anchor_call,
2005 struct thread *td)
2006 {
2007 struct pf_kruleset *ruleset;
2008 struct pf_krule *tail;
2009 struct pf_kpooladdr *pa;
2010 struct pfi_kkif *kif = NULL;
2011 int rs_num;
2012 int error = 0;
2013
2014 if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) {
2015 error = EINVAL;
2016 goto errout_unlocked;
2017 }
2018
2019 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
2020
2021 if (rule->ifname[0])
2022 kif = pf_kkif_create(M_WAITOK);
2023 pf_counter_u64_init(&rule->evaluations, M_WAITOK);
2024 for (int i = 0; i < 2; i++) {
2025 pf_counter_u64_init(&rule->packets[i], M_WAITOK);
2026 pf_counter_u64_init(&rule->bytes[i], M_WAITOK);
2027 }
2028 rule->states_cur = counter_u64_alloc(M_WAITOK);
2029 rule->states_tot = counter_u64_alloc(M_WAITOK);
2030 rule->src_nodes = counter_u64_alloc(M_WAITOK);
2031 rule->cuid = td->td_ucred->cr_ruid;
2032 rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
2033 TAILQ_INIT(&rule->rpool.list);
2034
2035 PF_RULES_WLOCK();
2036 #ifdef PF_WANT_32_TO_64_COUNTER
2037 LIST_INSERT_HEAD(&V_pf_allrulelist, rule, allrulelist);
2038 MPASS(!rule->allrulelinked);
2039 rule->allrulelinked = true;
2040 V_pf_allrulecount++;
2041 #endif
2042 ruleset = pf_find_kruleset(anchor);
2043 if (ruleset == NULL)
2044 ERROUT(EINVAL);
2045 rs_num = pf_get_ruleset_number(rule->action);
2046 if (rs_num >= PF_RULESET_MAX)
2047 ERROUT(EINVAL);
2048 if (ticket != ruleset->rules[rs_num].inactive.ticket) {
2049 DPFPRINTF(PF_DEBUG_MISC,
2050 ("ticket: %d != [%d]%d\n", ticket, rs_num,
2051 ruleset->rules[rs_num].inactive.ticket));
2052 ERROUT(EBUSY);
2053 }
2054 if (pool_ticket != V_ticket_pabuf) {
2055 DPFPRINTF(PF_DEBUG_MISC,
2056 ("pool_ticket: %d != %d\n", pool_ticket,
2057 V_ticket_pabuf));
2058 ERROUT(EBUSY);
2059 }
2060
2061 tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
2062 pf_krulequeue);
2063 if (tail)
2064 rule->nr = tail->nr + 1;
2065 else
2066 rule->nr = 0;
2067 if (rule->ifname[0]) {
2068 rule->kif = pfi_kkif_attach(kif, rule->ifname);
2069 kif = NULL;
2070 pfi_kkif_ref(rule->kif);
2071 } else
2072 rule->kif = NULL;
2073
2074 if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
2075 error = EBUSY;
2076
2077 #ifdef ALTQ
2078 /* set queue IDs */
2079 if (rule->qname[0] != 0) {
2080 if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
2081 error = EBUSY;
2082 else if (rule->pqname[0] != 0) {
2083 if ((rule->pqid =
2084 pf_qname2qid(rule->pqname)) == 0)
2085 error = EBUSY;
2086 } else
2087 rule->pqid = rule->qid;
2088 }
2089 #endif
2090 if (rule->tagname[0])
2091 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
2092 error = EBUSY;
2093 if (rule->match_tagname[0])
2094 if ((rule->match_tag =
2095 pf_tagname2tag(rule->match_tagname)) == 0)
2096 error = EBUSY;
2097 if (rule->rt && !rule->direction)
2098 error = EINVAL;
2099 if (!rule->log)
2100 rule->logif = 0;
2101 if (rule->logif >= PFLOGIFS_MAX)
2102 error = EINVAL;
2103 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
2104 error = ENOMEM;
2105 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
2106 error = ENOMEM;
2107 if (pf_kanchor_setup(rule, ruleset, anchor_call))
2108 error = EINVAL;
2109 if (rule->scrub_flags & PFSTATE_SETPRIO &&
2110 (rule->set_prio[0] > PF_PRIO_MAX ||
2111 rule->set_prio[1] > PF_PRIO_MAX))
2112 error = EINVAL;
2113 TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
2114 if (pa->addr.type == PF_ADDR_TABLE) {
2115 pa->addr.p.tbl = pfr_attach_table(ruleset,
2116 pa->addr.v.tblname);
2117 if (pa->addr.p.tbl == NULL)
2118 error = ENOMEM;
2119 }
2120
2121 rule->overload_tbl = NULL;
2122 if (rule->overload_tblname[0]) {
2123 if ((rule->overload_tbl = pfr_attach_table(ruleset,
2124 rule->overload_tblname)) == NULL)
2125 error = EINVAL;
2126 else
2127 rule->overload_tbl->pfrkt_flags |=
2128 PFR_TFLAG_ACTIVE;
2129 }
2130
2131 pf_mv_kpool(&V_pf_pabuf, &rule->rpool.list);
2132 if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
2133 (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
2134 (rule->rt > PF_NOPFROUTE)) &&
2135 (TAILQ_FIRST(&rule->rpool.list) == NULL))
2136 error = EINVAL;
2137
2138 if (error) {
2139 pf_free_rule(rule);
2140 rule = NULL;
2141 ERROUT(error);
2142 }
2143
2144 rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
2145 pf_counter_u64_zero(&rule->evaluations);
2146 for (int i = 0; i < 2; i++) {
2147 pf_counter_u64_zero(&rule->packets[i]);
2148 pf_counter_u64_zero(&rule->bytes[i]);
2149 }
2150 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
2151 rule, entries);
2152 ruleset->rules[rs_num].inactive.rcount++;
2153
2154 PF_RULES_WUNLOCK();
2155
2156 return (0);
2157
2158 #undef ERROUT
2159 errout:
2160 PF_RULES_WUNLOCK();
2161 errout_unlocked:
2162 pf_kkif_free(kif);
2163 pf_krule_free(rule);
2164 return (error);
2165 }
2166
2167 static int
pfioctl(struct cdev * dev,u_long cmd,caddr_t addr,int flags,struct thread * td)2168 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
2169 {
2170 int error = 0;
2171 PF_RULES_RLOCK_TRACKER;
2172
2173 #define ERROUT_IOCTL(target, x) \
2174 do { \
2175 error = (x); \
2176 SDT_PROBE3(pf, ioctl, ioctl, error, cmd, error, __LINE__); \
2177 goto target; \
2178 } while (0)
2179
2180
2181 /* XXX keep in sync with switch() below */
2182 if (securelevel_gt(td->td_ucred, 2))
2183 switch (cmd) {
2184 case DIOCGETRULES:
2185 case DIOCGETRULE:
2186 case DIOCGETRULENV:
2187 case DIOCGETADDRS:
2188 case DIOCGETADDR:
2189 case DIOCGETSTATE:
2190 case DIOCGETSTATENV:
2191 case DIOCSETSTATUSIF:
2192 case DIOCGETSTATUS:
2193 case DIOCGETSTATUSNV:
2194 case DIOCCLRSTATUS:
2195 case DIOCNATLOOK:
2196 case DIOCSETDEBUG:
2197 case DIOCGETSTATES:
2198 case DIOCGETSTATESV2:
2199 case DIOCGETTIMEOUT:
2200 case DIOCCLRRULECTRS:
2201 case DIOCGETLIMIT:
2202 case DIOCGETALTQSV0:
2203 case DIOCGETALTQSV1:
2204 case DIOCGETALTQV0:
2205 case DIOCGETALTQV1:
2206 case DIOCGETQSTATSV0:
2207 case DIOCGETQSTATSV1:
2208 case DIOCGETRULESETS:
2209 case DIOCGETRULESET:
2210 case DIOCRGETTABLES:
2211 case DIOCRGETTSTATS:
2212 case DIOCRCLRTSTATS:
2213 case DIOCRCLRADDRS:
2214 case DIOCRADDADDRS:
2215 case DIOCRDELADDRS:
2216 case DIOCRSETADDRS:
2217 case DIOCRGETADDRS:
2218 case DIOCRGETASTATS:
2219 case DIOCRCLRASTATS:
2220 case DIOCRTSTADDRS:
2221 case DIOCOSFPGET:
2222 case DIOCGETSRCNODES:
2223 case DIOCCLRSRCNODES:
2224 case DIOCGETSYNCOOKIES:
2225 case DIOCIGETIFACES:
2226 case DIOCGIFSPEEDV0:
2227 case DIOCGIFSPEEDV1:
2228 case DIOCSETIFFLAG:
2229 case DIOCCLRIFFLAG:
2230 break;
2231 case DIOCRCLRTABLES:
2232 case DIOCRADDTABLES:
2233 case DIOCRDELTABLES:
2234 case DIOCRSETTFLAGS:
2235 if (((struct pfioc_table *)addr)->pfrio_flags &
2236 PFR_FLAG_DUMMY)
2237 break; /* dummy operation ok */
2238 return (EPERM);
2239 default:
2240 return (EPERM);
2241 }
2242
2243 if (!(flags & FWRITE))
2244 switch (cmd) {
2245 case DIOCGETRULES:
2246 case DIOCGETADDRS:
2247 case DIOCGETADDR:
2248 case DIOCGETSTATE:
2249 case DIOCGETSTATENV:
2250 case DIOCGETSTATUS:
2251 case DIOCGETSTATUSNV:
2252 case DIOCGETSTATES:
2253 case DIOCGETSTATESV2:
2254 case DIOCGETTIMEOUT:
2255 case DIOCGETLIMIT:
2256 case DIOCGETALTQSV0:
2257 case DIOCGETALTQSV1:
2258 case DIOCGETALTQV0:
2259 case DIOCGETALTQV1:
2260 case DIOCGETQSTATSV0:
2261 case DIOCGETQSTATSV1:
2262 case DIOCGETRULESETS:
2263 case DIOCGETRULESET:
2264 case DIOCNATLOOK:
2265 case DIOCRGETTABLES:
2266 case DIOCRGETTSTATS:
2267 case DIOCRGETADDRS:
2268 case DIOCRGETASTATS:
2269 case DIOCRTSTADDRS:
2270 case DIOCOSFPGET:
2271 case DIOCGETSRCNODES:
2272 case DIOCGETSYNCOOKIES:
2273 case DIOCIGETIFACES:
2274 case DIOCGIFSPEEDV1:
2275 case DIOCGIFSPEEDV0:
2276 case DIOCGETRULENV:
2277 break;
2278 case DIOCRCLRTABLES:
2279 case DIOCRADDTABLES:
2280 case DIOCRDELTABLES:
2281 case DIOCRCLRTSTATS:
2282 case DIOCRCLRADDRS:
2283 case DIOCRADDADDRS:
2284 case DIOCRDELADDRS:
2285 case DIOCRSETADDRS:
2286 case DIOCRSETTFLAGS:
2287 if (((struct pfioc_table *)addr)->pfrio_flags &
2288 PFR_FLAG_DUMMY) {
2289 flags |= FWRITE; /* need write lock for dummy */
2290 break; /* dummy operation ok */
2291 }
2292 return (EACCES);
2293 case DIOCGETRULE:
2294 if (((struct pfioc_rule *)addr)->action ==
2295 PF_GET_CLR_CNTR)
2296 return (EACCES);
2297 break;
2298 default:
2299 return (EACCES);
2300 }
2301
2302 CURVNET_SET(TD_TO_VNET(td));
2303
2304 switch (cmd) {
2305 case DIOCSTART:
2306 sx_xlock(&pf_ioctl_lock);
2307 if (V_pf_status.running)
2308 error = EEXIST;
2309 else {
2310 int cpu;
2311
2312 hook_pf();
2313 V_pf_status.running = 1;
2314 V_pf_status.since = time_second;
2315
2316 CPU_FOREACH(cpu)
2317 V_pf_stateid[cpu] = time_second;
2318
2319 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
2320 }
2321 break;
2322
2323 case DIOCSTOP:
2324 sx_xlock(&pf_ioctl_lock);
2325 if (!V_pf_status.running)
2326 error = ENOENT;
2327 else {
2328 V_pf_status.running = 0;
2329 dehook_pf();
2330 V_pf_status.since = time_second;
2331 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
2332 }
2333 break;
2334
2335 case DIOCADDRULENV: {
2336 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2337 nvlist_t *nvl = NULL;
2338 void *nvlpacked = NULL;
2339 struct pf_krule *rule = NULL;
2340 const char *anchor = "", *anchor_call = "";
2341 uint32_t ticket = 0, pool_ticket = 0;
2342
2343 #define ERROUT(x) ERROUT_IOCTL(DIOCADDRULENV_error, x)
2344
2345 if (nv->len > pf_ioctl_maxcount)
2346 ERROUT(ENOMEM);
2347
2348 nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
2349 error = copyin(nv->data, nvlpacked, nv->len);
2350 if (error)
2351 ERROUT(error);
2352
2353 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2354 if (nvl == NULL)
2355 ERROUT(EBADMSG);
2356
2357 if (! nvlist_exists_number(nvl, "ticket"))
2358 ERROUT(EINVAL);
2359 ticket = nvlist_get_number(nvl, "ticket");
2360
2361 if (! nvlist_exists_number(nvl, "pool_ticket"))
2362 ERROUT(EINVAL);
2363 pool_ticket = nvlist_get_number(nvl, "pool_ticket");
2364
2365 if (! nvlist_exists_nvlist(nvl, "rule"))
2366 ERROUT(EINVAL);
2367
2368 rule = pf_krule_alloc();
2369 error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"),
2370 rule);
2371 if (error)
2372 ERROUT(error);
2373
2374 if (nvlist_exists_string(nvl, "anchor"))
2375 anchor = nvlist_get_string(nvl, "anchor");
2376 if (nvlist_exists_string(nvl, "anchor_call"))
2377 anchor_call = nvlist_get_string(nvl, "anchor_call");
2378
2379 if ((error = nvlist_error(nvl)))
2380 ERROUT(error);
2381
2382 /* Frees rule on error */
2383 error = pf_ioctl_addrule(rule, ticket, pool_ticket, anchor,
2384 anchor_call, td);
2385
2386 nvlist_destroy(nvl);
2387 free(nvlpacked, M_TEMP);
2388 break;
2389 #undef ERROUT
2390 DIOCADDRULENV_error:
2391 pf_krule_free(rule);
2392 nvlist_destroy(nvl);
2393 free(nvlpacked, M_TEMP);
2394
2395 break;
2396 }
2397 case DIOCADDRULE: {
2398 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
2399 struct pf_krule *rule;
2400
2401 rule = pf_krule_alloc();
2402 error = pf_rule_to_krule(&pr->rule, rule);
2403 if (error != 0) {
2404 pf_krule_free(rule);
2405 break;
2406 }
2407
2408 pr->anchor[sizeof(pr->anchor) - 1] = 0;
2409
2410 /* Frees rule on error */
2411 error = pf_ioctl_addrule(rule, pr->ticket, pr->pool_ticket,
2412 pr->anchor, pr->anchor_call, td);
2413 break;
2414 }
2415
2416 case DIOCGETRULES: {
2417 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
2418 struct pf_kruleset *ruleset;
2419 struct pf_krule *tail;
2420 int rs_num;
2421
2422 pr->anchor[sizeof(pr->anchor) - 1] = 0;
2423
2424 PF_RULES_WLOCK();
2425 ruleset = pf_find_kruleset(pr->anchor);
2426 if (ruleset == NULL) {
2427 PF_RULES_WUNLOCK();
2428 error = EINVAL;
2429 break;
2430 }
2431 rs_num = pf_get_ruleset_number(pr->rule.action);
2432 if (rs_num >= PF_RULESET_MAX) {
2433 PF_RULES_WUNLOCK();
2434 error = EINVAL;
2435 break;
2436 }
2437 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
2438 pf_krulequeue);
2439 if (tail)
2440 pr->nr = tail->nr + 1;
2441 else
2442 pr->nr = 0;
2443 pr->ticket = ruleset->rules[rs_num].active.ticket;
2444 PF_RULES_WUNLOCK();
2445 break;
2446 }
2447
2448 case DIOCGETRULE: {
2449 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
2450 struct pf_kruleset *ruleset;
2451 struct pf_krule *rule;
2452 int rs_num;
2453
2454 pr->anchor[sizeof(pr->anchor) - 1] = 0;
2455
2456 PF_RULES_WLOCK();
2457 ruleset = pf_find_kruleset(pr->anchor);
2458 if (ruleset == NULL) {
2459 PF_RULES_WUNLOCK();
2460 error = EINVAL;
2461 break;
2462 }
2463 rs_num = pf_get_ruleset_number(pr->rule.action);
2464 if (rs_num >= PF_RULESET_MAX) {
2465 PF_RULES_WUNLOCK();
2466 error = EINVAL;
2467 break;
2468 }
2469 if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
2470 PF_RULES_WUNLOCK();
2471 error = EBUSY;
2472 break;
2473 }
2474 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
2475 while ((rule != NULL) && (rule->nr != pr->nr))
2476 rule = TAILQ_NEXT(rule, entries);
2477 if (rule == NULL) {
2478 PF_RULES_WUNLOCK();
2479 error = EBUSY;
2480 break;
2481 }
2482
2483 pf_krule_to_rule(rule, &pr->rule);
2484
2485 if (pf_kanchor_copyout(ruleset, rule, pr)) {
2486 PF_RULES_WUNLOCK();
2487 error = EBUSY;
2488 break;
2489 }
2490 pf_addr_copyout(&pr->rule.src.addr);
2491 pf_addr_copyout(&pr->rule.dst.addr);
2492
2493 if (pr->action == PF_GET_CLR_CNTR) {
2494 pf_counter_u64_zero(&rule->evaluations);
2495 for (int i = 0; i < 2; i++) {
2496 pf_counter_u64_zero(&rule->packets[i]);
2497 pf_counter_u64_zero(&rule->bytes[i]);
2498 }
2499 counter_u64_zero(rule->states_tot);
2500 }
2501 PF_RULES_WUNLOCK();
2502 break;
2503 }
2504
2505 case DIOCGETRULENV: {
2506 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2507 nvlist_t *nvrule = NULL;
2508 nvlist_t *nvl = NULL;
2509 struct pf_kruleset *ruleset;
2510 struct pf_krule *rule;
2511 void *nvlpacked = NULL;
2512 int rs_num, nr;
2513 bool clear_counter = false;
2514
2515 #define ERROUT(x) ERROUT_IOCTL(DIOCGETRULENV_error, x)
2516
2517 if (nv->len > pf_ioctl_maxcount)
2518 ERROUT(ENOMEM);
2519
2520 /* Copy the request in */
2521 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2522 if (nvlpacked == NULL)
2523 ERROUT(ENOMEM);
2524
2525 error = copyin(nv->data, nvlpacked, nv->len);
2526 if (error)
2527 ERROUT(error);
2528
2529 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2530 if (nvl == NULL)
2531 ERROUT(EBADMSG);
2532
2533 if (! nvlist_exists_string(nvl, "anchor"))
2534 ERROUT(EBADMSG);
2535 if (! nvlist_exists_number(nvl, "ruleset"))
2536 ERROUT(EBADMSG);
2537 if (! nvlist_exists_number(nvl, "ticket"))
2538 ERROUT(EBADMSG);
2539 if (! nvlist_exists_number(nvl, "nr"))
2540 ERROUT(EBADMSG);
2541
2542 if (nvlist_exists_bool(nvl, "clear_counter"))
2543 clear_counter = nvlist_get_bool(nvl, "clear_counter");
2544
2545 if (clear_counter && !(flags & FWRITE))
2546 ERROUT(EACCES);
2547
2548 nr = nvlist_get_number(nvl, "nr");
2549
2550 PF_RULES_WLOCK();
2551 ruleset = pf_find_kruleset(nvlist_get_string(nvl, "anchor"));
2552 if (ruleset == NULL) {
2553 PF_RULES_WUNLOCK();
2554 ERROUT(ENOENT);
2555 }
2556
2557 rs_num = pf_get_ruleset_number(nvlist_get_number(nvl, "ruleset"));
2558 if (rs_num >= PF_RULESET_MAX) {
2559 PF_RULES_WUNLOCK();
2560 ERROUT(EINVAL);
2561 }
2562
2563 if (nvlist_get_number(nvl, "ticket") !=
2564 ruleset->rules[rs_num].active.ticket) {
2565 PF_RULES_WUNLOCK();
2566 ERROUT(EBUSY);
2567 }
2568
2569 if ((error = nvlist_error(nvl))) {
2570 PF_RULES_WUNLOCK();
2571 ERROUT(error);
2572 }
2573
2574 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
2575 while ((rule != NULL) && (rule->nr != nr))
2576 rule = TAILQ_NEXT(rule, entries);
2577 if (rule == NULL) {
2578 PF_RULES_WUNLOCK();
2579 ERROUT(EBUSY);
2580 }
2581
2582 nvrule = pf_krule_to_nvrule(rule);
2583
2584 nvlist_destroy(nvl);
2585 nvl = nvlist_create(0);
2586 if (nvl == NULL) {
2587 PF_RULES_WUNLOCK();
2588 ERROUT(ENOMEM);
2589 }
2590 nvlist_add_number(nvl, "nr", nr);
2591 nvlist_add_nvlist(nvl, "rule", nvrule);
2592 nvlist_destroy(nvrule);
2593 nvrule = NULL;
2594 if (pf_kanchor_nvcopyout(ruleset, rule, nvl)) {
2595 PF_RULES_WUNLOCK();
2596 ERROUT(EBUSY);
2597 }
2598
2599 free(nvlpacked, M_NVLIST);
2600 nvlpacked = nvlist_pack(nvl, &nv->len);
2601 if (nvlpacked == NULL) {
2602 PF_RULES_WUNLOCK();
2603 ERROUT(ENOMEM);
2604 }
2605
2606 if (nv->size == 0) {
2607 PF_RULES_WUNLOCK();
2608 ERROUT(0);
2609 }
2610 else if (nv->size < nv->len) {
2611 PF_RULES_WUNLOCK();
2612 ERROUT(ENOSPC);
2613 }
2614
2615 if (clear_counter) {
2616 pf_counter_u64_zero(&rule->evaluations);
2617 for (int i = 0; i < 2; i++) {
2618 pf_counter_u64_zero(&rule->packets[i]);
2619 pf_counter_u64_zero(&rule->bytes[i]);
2620 }
2621 counter_u64_zero(rule->states_tot);
2622 }
2623 PF_RULES_WUNLOCK();
2624
2625 error = copyout(nvlpacked, nv->data, nv->len);
2626
2627 #undef ERROUT
2628 DIOCGETRULENV_error:
2629 free(nvlpacked, M_NVLIST);
2630 nvlist_destroy(nvrule);
2631 nvlist_destroy(nvl);
2632
2633 break;
2634 }
2635
2636 case DIOCCHANGERULE: {
2637 struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
2638 struct pf_kruleset *ruleset;
2639 struct pf_krule *oldrule = NULL, *newrule = NULL;
2640 struct pfi_kkif *kif = NULL;
2641 struct pf_kpooladdr *pa;
2642 u_int32_t nr = 0;
2643 int rs_num;
2644
2645 pcr->anchor[sizeof(pcr->anchor) - 1] = 0;
2646
2647 if (pcr->action < PF_CHANGE_ADD_HEAD ||
2648 pcr->action > PF_CHANGE_GET_TICKET) {
2649 error = EINVAL;
2650 break;
2651 }
2652 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
2653 error = EINVAL;
2654 break;
2655 }
2656
2657 if (pcr->action != PF_CHANGE_REMOVE) {
2658 newrule = pf_krule_alloc();
2659 error = pf_rule_to_krule(&pcr->rule, newrule);
2660 if (error != 0) {
2661 free(newrule, M_PFRULE);
2662 break;
2663 }
2664
2665 if (newrule->ifname[0])
2666 kif = pf_kkif_create(M_WAITOK);
2667 pf_counter_u64_init(&newrule->evaluations, M_WAITOK);
2668 for (int i = 0; i < 2; i++) {
2669 pf_counter_u64_init(&newrule->packets[i], M_WAITOK);
2670 pf_counter_u64_init(&newrule->bytes[i], M_WAITOK);
2671 }
2672 newrule->states_cur = counter_u64_alloc(M_WAITOK);
2673 newrule->states_tot = counter_u64_alloc(M_WAITOK);
2674 newrule->src_nodes = counter_u64_alloc(M_WAITOK);
2675 newrule->cuid = td->td_ucred->cr_ruid;
2676 newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
2677 TAILQ_INIT(&newrule->rpool.list);
2678 }
2679 #define ERROUT(x) { error = (x); goto DIOCCHANGERULE_error; }
2680
2681 PF_RULES_WLOCK();
2682 #ifdef PF_WANT_32_TO_64_COUNTER
2683 if (newrule != NULL) {
2684 LIST_INSERT_HEAD(&V_pf_allrulelist, newrule, allrulelist);
2685 newrule->allrulelinked = true;
2686 V_pf_allrulecount++;
2687 }
2688 #endif
2689
2690 if (!(pcr->action == PF_CHANGE_REMOVE ||
2691 pcr->action == PF_CHANGE_GET_TICKET) &&
2692 pcr->pool_ticket != V_ticket_pabuf)
2693 ERROUT(EBUSY);
2694
2695 ruleset = pf_find_kruleset(pcr->anchor);
2696 if (ruleset == NULL)
2697 ERROUT(EINVAL);
2698
2699 rs_num = pf_get_ruleset_number(pcr->rule.action);
2700 if (rs_num >= PF_RULESET_MAX)
2701 ERROUT(EINVAL);
2702
2703 if (pcr->action == PF_CHANGE_GET_TICKET) {
2704 pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
2705 ERROUT(0);
2706 } else if (pcr->ticket !=
2707 ruleset->rules[rs_num].active.ticket)
2708 ERROUT(EINVAL);
2709
2710 if (pcr->action != PF_CHANGE_REMOVE) {
2711 if (newrule->ifname[0]) {
2712 newrule->kif = pfi_kkif_attach(kif,
2713 newrule->ifname);
2714 kif = NULL;
2715 pfi_kkif_ref(newrule->kif);
2716 } else
2717 newrule->kif = NULL;
2718
2719 if (newrule->rtableid > 0 &&
2720 newrule->rtableid >= rt_numfibs)
2721 error = EBUSY;
2722
2723 #ifdef ALTQ
2724 /* set queue IDs */
2725 if (newrule->qname[0] != 0) {
2726 if ((newrule->qid =
2727 pf_qname2qid(newrule->qname)) == 0)
2728 error = EBUSY;
2729 else if (newrule->pqname[0] != 0) {
2730 if ((newrule->pqid =
2731 pf_qname2qid(newrule->pqname)) == 0)
2732 error = EBUSY;
2733 } else
2734 newrule->pqid = newrule->qid;
2735 }
2736 #endif /* ALTQ */
2737 if (newrule->tagname[0])
2738 if ((newrule->tag =
2739 pf_tagname2tag(newrule->tagname)) == 0)
2740 error = EBUSY;
2741 if (newrule->match_tagname[0])
2742 if ((newrule->match_tag = pf_tagname2tag(
2743 newrule->match_tagname)) == 0)
2744 error = EBUSY;
2745 if (newrule->rt && !newrule->direction)
2746 error = EINVAL;
2747 if (!newrule->log)
2748 newrule->logif = 0;
2749 if (newrule->logif >= PFLOGIFS_MAX)
2750 error = EINVAL;
2751 if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
2752 error = ENOMEM;
2753 if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
2754 error = ENOMEM;
2755 if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
2756 error = EINVAL;
2757 TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
2758 if (pa->addr.type == PF_ADDR_TABLE) {
2759 pa->addr.p.tbl =
2760 pfr_attach_table(ruleset,
2761 pa->addr.v.tblname);
2762 if (pa->addr.p.tbl == NULL)
2763 error = ENOMEM;
2764 }
2765
2766 newrule->overload_tbl = NULL;
2767 if (newrule->overload_tblname[0]) {
2768 if ((newrule->overload_tbl = pfr_attach_table(
2769 ruleset, newrule->overload_tblname)) ==
2770 NULL)
2771 error = EINVAL;
2772 else
2773 newrule->overload_tbl->pfrkt_flags |=
2774 PFR_TFLAG_ACTIVE;
2775 }
2776
2777 pf_mv_kpool(&V_pf_pabuf, &newrule->rpool.list);
2778 if (((((newrule->action == PF_NAT) ||
2779 (newrule->action == PF_RDR) ||
2780 (newrule->action == PF_BINAT) ||
2781 (newrule->rt > PF_NOPFROUTE)) &&
2782 !newrule->anchor)) &&
2783 (TAILQ_FIRST(&newrule->rpool.list) == NULL))
2784 error = EINVAL;
2785
2786 if (error) {
2787 pf_free_rule(newrule);
2788 PF_RULES_WUNLOCK();
2789 break;
2790 }
2791
2792 newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
2793 }
2794 pf_empty_kpool(&V_pf_pabuf);
2795
2796 if (pcr->action == PF_CHANGE_ADD_HEAD)
2797 oldrule = TAILQ_FIRST(
2798 ruleset->rules[rs_num].active.ptr);
2799 else if (pcr->action == PF_CHANGE_ADD_TAIL)
2800 oldrule = TAILQ_LAST(
2801 ruleset->rules[rs_num].active.ptr, pf_krulequeue);
2802 else {
2803 oldrule = TAILQ_FIRST(
2804 ruleset->rules[rs_num].active.ptr);
2805 while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
2806 oldrule = TAILQ_NEXT(oldrule, entries);
2807 if (oldrule == NULL) {
2808 if (newrule != NULL)
2809 pf_free_rule(newrule);
2810 PF_RULES_WUNLOCK();
2811 error = EINVAL;
2812 break;
2813 }
2814 }
2815
2816 if (pcr->action == PF_CHANGE_REMOVE) {
2817 pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
2818 oldrule);
2819 ruleset->rules[rs_num].active.rcount--;
2820 } else {
2821 if (oldrule == NULL)
2822 TAILQ_INSERT_TAIL(
2823 ruleset->rules[rs_num].active.ptr,
2824 newrule, entries);
2825 else if (pcr->action == PF_CHANGE_ADD_HEAD ||
2826 pcr->action == PF_CHANGE_ADD_BEFORE)
2827 TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
2828 else
2829 TAILQ_INSERT_AFTER(
2830 ruleset->rules[rs_num].active.ptr,
2831 oldrule, newrule, entries);
2832 ruleset->rules[rs_num].active.rcount++;
2833 }
2834
2835 nr = 0;
2836 TAILQ_FOREACH(oldrule,
2837 ruleset->rules[rs_num].active.ptr, entries)
2838 oldrule->nr = nr++;
2839
2840 ruleset->rules[rs_num].active.ticket++;
2841
2842 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
2843 pf_remove_if_empty_kruleset(ruleset);
2844
2845 PF_RULES_WUNLOCK();
2846 break;
2847
2848 #undef ERROUT
2849 DIOCCHANGERULE_error:
2850 PF_RULES_WUNLOCK();
2851 pf_krule_free(newrule);
2852 pf_kkif_free(kif);
2853 break;
2854 }
2855
2856 case DIOCCLRSTATES: {
2857 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
2858 struct pf_kstate_kill kill;
2859
2860 error = pf_state_kill_to_kstate_kill(psk, &kill);
2861 if (error)
2862 break;
2863
2864 psk->psk_killed = pf_clear_states(&kill);
2865 break;
2866 }
2867
2868 case DIOCCLRSTATESNV: {
2869 error = pf_clearstates_nv((struct pfioc_nv *)addr);
2870 break;
2871 }
2872
2873 case DIOCKILLSTATES: {
2874 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
2875 struct pf_kstate_kill kill;
2876
2877 error = pf_state_kill_to_kstate_kill(psk, &kill);
2878 if (error)
2879 break;
2880
2881 psk->psk_killed = 0;
2882 pf_killstates(&kill, &psk->psk_killed);
2883 break;
2884 }
2885
2886 case DIOCKILLSTATESNV: {
2887 error = pf_killstates_nv((struct pfioc_nv *)addr);
2888 break;
2889 }
2890
2891 case DIOCADDSTATE: {
2892 struct pfioc_state *ps = (struct pfioc_state *)addr;
2893 struct pfsync_state *sp = &ps->state;
2894
2895 if (sp->timeout >= PFTM_MAX) {
2896 error = EINVAL;
2897 break;
2898 }
2899 if (V_pfsync_state_import_ptr != NULL) {
2900 PF_RULES_RLOCK();
2901 error = V_pfsync_state_import_ptr(sp, PFSYNC_SI_IOCTL);
2902 PF_RULES_RUNLOCK();
2903 } else
2904 error = EOPNOTSUPP;
2905 break;
2906 }
2907
2908 case DIOCGETSTATE: {
2909 struct pfioc_state *ps = (struct pfioc_state *)addr;
2910 struct pf_kstate *s;
2911
2912 s = pf_find_state_byid(ps->state.id, ps->state.creatorid);
2913 if (s == NULL) {
2914 error = ENOENT;
2915 break;
2916 }
2917
2918 pfsync_state_export(&ps->state, s);
2919 PF_STATE_UNLOCK(s);
2920 break;
2921 }
2922
2923 case DIOCGETSTATENV: {
2924 error = pf_getstate((struct pfioc_nv *)addr);
2925 break;
2926 }
2927
2928 case DIOCGETSTATES: {
2929 struct pfioc_states *ps = (struct pfioc_states *)addr;
2930 struct pf_kstate *s;
2931 struct pfsync_state *pstore, *p;
2932 int i, nr;
2933 size_t slice_count = 16, count;
2934 void *out;
2935
2936 if (ps->ps_len <= 0) {
2937 nr = uma_zone_get_cur(V_pf_state_z);
2938 ps->ps_len = sizeof(struct pfsync_state) * nr;
2939 break;
2940 }
2941
2942 out = ps->ps_states;
2943 pstore = mallocarray(slice_count,
2944 sizeof(struct pfsync_state), M_TEMP, M_WAITOK | M_ZERO);
2945 nr = 0;
2946
2947 for (i = 0; i <= pf_hashmask; i++) {
2948 struct pf_idhash *ih = &V_pf_idhash[i];
2949
2950 DIOCGETSTATES_retry:
2951 p = pstore;
2952
2953 if (LIST_EMPTY(&ih->states))
2954 continue;
2955
2956 PF_HASHROW_LOCK(ih);
2957 count = 0;
2958 LIST_FOREACH(s, &ih->states, entry) {
2959 if (s->timeout == PFTM_UNLINKED)
2960 continue;
2961 count++;
2962 }
2963
2964 if (count > slice_count) {
2965 PF_HASHROW_UNLOCK(ih);
2966 free(pstore, M_TEMP);
2967 slice_count = count * 2;
2968 pstore = mallocarray(slice_count,
2969 sizeof(struct pfsync_state), M_TEMP,
2970 M_WAITOK | M_ZERO);
2971 goto DIOCGETSTATES_retry;
2972 }
2973
2974 if ((nr+count) * sizeof(*p) > ps->ps_len) {
2975 PF_HASHROW_UNLOCK(ih);
2976 goto DIOCGETSTATES_full;
2977 }
2978
2979 LIST_FOREACH(s, &ih->states, entry) {
2980 if (s->timeout == PFTM_UNLINKED)
2981 continue;
2982
2983 pfsync_state_export(p, s);
2984 p++;
2985 nr++;
2986 }
2987 PF_HASHROW_UNLOCK(ih);
2988 error = copyout(pstore, out,
2989 sizeof(struct pfsync_state) * count);
2990 if (error)
2991 break;
2992 out = ps->ps_states + nr;
2993 }
2994 DIOCGETSTATES_full:
2995 ps->ps_len = sizeof(struct pfsync_state) * nr;
2996 free(pstore, M_TEMP);
2997
2998 break;
2999 }
3000
3001 case DIOCGETSTATESV2: {
3002 struct pfioc_states_v2 *ps = (struct pfioc_states_v2 *)addr;
3003 struct pf_kstate *s;
3004 struct pf_state_export *pstore, *p;
3005 int i, nr;
3006 size_t slice_count = 16, count;
3007 void *out;
3008
3009 if (ps->ps_req_version > PF_STATE_VERSION) {
3010 error = ENOTSUP;
3011 break;
3012 }
3013
3014 if (ps->ps_len <= 0) {
3015 nr = uma_zone_get_cur(V_pf_state_z);
3016 ps->ps_len = sizeof(struct pf_state_export) * nr;
3017 break;
3018 }
3019
3020 out = ps->ps_states;
3021 pstore = mallocarray(slice_count,
3022 sizeof(struct pf_state_export), M_TEMP, M_WAITOK | M_ZERO);
3023 nr = 0;
3024
3025 for (i = 0; i <= pf_hashmask; i++) {
3026 struct pf_idhash *ih = &V_pf_idhash[i];
3027
3028 DIOCGETSTATESV2_retry:
3029 p = pstore;
3030
3031 if (LIST_EMPTY(&ih->states))
3032 continue;
3033
3034 PF_HASHROW_LOCK(ih);
3035 count = 0;
3036 LIST_FOREACH(s, &ih->states, entry) {
3037 if (s->timeout == PFTM_UNLINKED)
3038 continue;
3039 count++;
3040 }
3041
3042 if (count > slice_count) {
3043 PF_HASHROW_UNLOCK(ih);
3044 free(pstore, M_TEMP);
3045 slice_count = count * 2;
3046 pstore = mallocarray(slice_count,
3047 sizeof(struct pf_state_export), M_TEMP,
3048 M_WAITOK | M_ZERO);
3049 goto DIOCGETSTATESV2_retry;
3050 }
3051
3052 if ((nr+count) * sizeof(*p) > ps->ps_len) {
3053 PF_HASHROW_UNLOCK(ih);
3054 goto DIOCGETSTATESV2_full;
3055 }
3056
3057 LIST_FOREACH(s, &ih->states, entry) {
3058 if (s->timeout == PFTM_UNLINKED)
3059 continue;
3060
3061 pf_state_export(p, s);
3062 p++;
3063 nr++;
3064 }
3065 PF_HASHROW_UNLOCK(ih);
3066 error = copyout(pstore, out,
3067 sizeof(struct pf_state_export) * count);
3068 if (error)
3069 break;
3070 out = ps->ps_states + nr;
3071 }
3072 DIOCGETSTATESV2_full:
3073 ps->ps_len = nr * sizeof(struct pf_state_export);
3074 free(pstore, M_TEMP);
3075
3076 break;
3077 }
3078
3079 case DIOCGETSTATUS: {
3080 struct pf_status *s = (struct pf_status *)addr;
3081
3082 PF_RULES_RLOCK();
3083 s->running = V_pf_status.running;
3084 s->since = V_pf_status.since;
3085 s->debug = V_pf_status.debug;
3086 s->hostid = V_pf_status.hostid;
3087 s->states = V_pf_status.states;
3088 s->src_nodes = V_pf_status.src_nodes;
3089
3090 for (int i = 0; i < PFRES_MAX; i++)
3091 s->counters[i] =
3092 counter_u64_fetch(V_pf_status.counters[i]);
3093 for (int i = 0; i < LCNT_MAX; i++)
3094 s->lcounters[i] =
3095 counter_u64_fetch(V_pf_status.lcounters[i]);
3096 for (int i = 0; i < FCNT_MAX; i++)
3097 s->fcounters[i] =
3098 pf_counter_u64_fetch(&V_pf_status.fcounters[i]);
3099 for (int i = 0; i < SCNT_MAX; i++)
3100 s->scounters[i] =
3101 counter_u64_fetch(V_pf_status.scounters[i]);
3102
3103 bcopy(V_pf_status.ifname, s->ifname, IFNAMSIZ);
3104 bcopy(V_pf_status.pf_chksum, s->pf_chksum,
3105 PF_MD5_DIGEST_LENGTH);
3106
3107 pfi_update_status(s->ifname, s);
3108 PF_RULES_RUNLOCK();
3109 break;
3110 }
3111
3112 case DIOCGETSTATUSNV: {
3113 error = pf_getstatus((struct pfioc_nv *)addr);
3114 break;
3115 }
3116
3117 case DIOCSETSTATUSIF: {
3118 struct pfioc_if *pi = (struct pfioc_if *)addr;
3119
3120 if (pi->ifname[0] == 0) {
3121 bzero(V_pf_status.ifname, IFNAMSIZ);
3122 break;
3123 }
3124 PF_RULES_WLOCK();
3125 error = pf_user_strcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
3126 PF_RULES_WUNLOCK();
3127 break;
3128 }
3129
3130 case DIOCCLRSTATUS: {
3131 PF_RULES_WLOCK();
3132 for (int i = 0; i < PFRES_MAX; i++)
3133 counter_u64_zero(V_pf_status.counters[i]);
3134 for (int i = 0; i < FCNT_MAX; i++)
3135 pf_counter_u64_zero(&V_pf_status.fcounters[i]);
3136 for (int i = 0; i < SCNT_MAX; i++)
3137 counter_u64_zero(V_pf_status.scounters[i]);
3138 for (int i = 0; i < KLCNT_MAX; i++)
3139 counter_u64_zero(V_pf_status.lcounters[i]);
3140 V_pf_status.since = time_second;
3141 if (*V_pf_status.ifname)
3142 pfi_update_status(V_pf_status.ifname, NULL);
3143 PF_RULES_WUNLOCK();
3144 break;
3145 }
3146
3147 case DIOCNATLOOK: {
3148 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr;
3149 struct pf_state_key *sk;
3150 struct pf_kstate *state;
3151 struct pf_state_key_cmp key;
3152 int m = 0, direction = pnl->direction;
3153 int sidx, didx;
3154
3155 /* NATLOOK src and dst are reversed, so reverse sidx/didx */
3156 sidx = (direction == PF_IN) ? 1 : 0;
3157 didx = (direction == PF_IN) ? 0 : 1;
3158
3159 if (!pnl->proto ||
3160 PF_AZERO(&pnl->saddr, pnl->af) ||
3161 PF_AZERO(&pnl->daddr, pnl->af) ||
3162 ((pnl->proto == IPPROTO_TCP ||
3163 pnl->proto == IPPROTO_UDP) &&
3164 (!pnl->dport || !pnl->sport)))
3165 error = EINVAL;
3166 else {
3167 bzero(&key, sizeof(key));
3168 key.af = pnl->af;
3169 key.proto = pnl->proto;
3170 PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af);
3171 key.port[sidx] = pnl->sport;
3172 PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af);
3173 key.port[didx] = pnl->dport;
3174
3175 state = pf_find_state_all(&key, direction, &m);
3176
3177 if (m > 1)
3178 error = E2BIG; /* more than one state */
3179 else if (state != NULL) {
3180 /* XXXGL: not locked read */
3181 sk = state->key[sidx];
3182 PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af);
3183 pnl->rsport = sk->port[sidx];
3184 PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af);
3185 pnl->rdport = sk->port[didx];
3186 } else
3187 error = ENOENT;
3188 }
3189 break;
3190 }
3191
3192 case DIOCSETTIMEOUT: {
3193 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
3194 int old;
3195
3196 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
3197 pt->seconds < 0) {
3198 error = EINVAL;
3199 break;
3200 }
3201 PF_RULES_WLOCK();
3202 old = V_pf_default_rule.timeout[pt->timeout];
3203 if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0)
3204 pt->seconds = 1;
3205 V_pf_default_rule.timeout[pt->timeout] = pt->seconds;
3206 if (pt->timeout == PFTM_INTERVAL && pt->seconds < old)
3207 wakeup(pf_purge_thread);
3208 pt->seconds = old;
3209 PF_RULES_WUNLOCK();
3210 break;
3211 }
3212
3213 case DIOCGETTIMEOUT: {
3214 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
3215
3216 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
3217 error = EINVAL;
3218 break;
3219 }
3220 PF_RULES_RLOCK();
3221 pt->seconds = V_pf_default_rule.timeout[pt->timeout];
3222 PF_RULES_RUNLOCK();
3223 break;
3224 }
3225
3226 case DIOCGETLIMIT: {
3227 struct pfioc_limit *pl = (struct pfioc_limit *)addr;
3228
3229 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
3230 error = EINVAL;
3231 break;
3232 }
3233 PF_RULES_RLOCK();
3234 pl->limit = V_pf_limits[pl->index].limit;
3235 PF_RULES_RUNLOCK();
3236 break;
3237 }
3238
3239 case DIOCSETLIMIT: {
3240 struct pfioc_limit *pl = (struct pfioc_limit *)addr;
3241 int old_limit;
3242
3243 PF_RULES_WLOCK();
3244 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
3245 V_pf_limits[pl->index].zone == NULL) {
3246 PF_RULES_WUNLOCK();
3247 error = EINVAL;
3248 break;
3249 }
3250 uma_zone_set_max(V_pf_limits[pl->index].zone, pl->limit);
3251 old_limit = V_pf_limits[pl->index].limit;
3252 V_pf_limits[pl->index].limit = pl->limit;
3253 pl->limit = old_limit;
3254 PF_RULES_WUNLOCK();
3255 break;
3256 }
3257
3258 case DIOCSETDEBUG: {
3259 u_int32_t *level = (u_int32_t *)addr;
3260
3261 PF_RULES_WLOCK();
3262 V_pf_status.debug = *level;
3263 PF_RULES_WUNLOCK();
3264 break;
3265 }
3266
3267 case DIOCCLRRULECTRS: {
3268 /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
3269 struct pf_kruleset *ruleset = &pf_main_ruleset;
3270 struct pf_krule *rule;
3271
3272 PF_RULES_WLOCK();
3273 TAILQ_FOREACH(rule,
3274 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
3275 pf_counter_u64_zero(&rule->evaluations);
3276 for (int i = 0; i < 2; i++) {
3277 pf_counter_u64_zero(&rule->packets[i]);
3278 pf_counter_u64_zero(&rule->bytes[i]);
3279 }
3280 }
3281 PF_RULES_WUNLOCK();
3282 break;
3283 }
3284
3285 case DIOCGIFSPEEDV0:
3286 case DIOCGIFSPEEDV1: {
3287 struct pf_ifspeed_v1 *psp = (struct pf_ifspeed_v1 *)addr;
3288 struct pf_ifspeed_v1 ps;
3289 struct ifnet *ifp;
3290
3291 if (psp->ifname[0] == '\0') {
3292 error = EINVAL;
3293 break;
3294 }
3295
3296 error = pf_user_strcpy(ps.ifname, psp->ifname, IFNAMSIZ);
3297 if (error != 0)
3298 break;
3299 ifp = ifunit(ps.ifname);
3300 if (ifp != NULL) {
3301 psp->baudrate32 =
3302 (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX);
3303 if (cmd == DIOCGIFSPEEDV1)
3304 psp->baudrate = ifp->if_baudrate;
3305 } else {
3306 error = EINVAL;
3307 }
3308 break;
3309 }
3310
3311 #ifdef ALTQ
3312 case DIOCSTARTALTQ: {
3313 struct pf_altq *altq;
3314
3315 PF_RULES_WLOCK();
3316 /* enable all altq interfaces on active list */
3317 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
3318 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
3319 error = pf_enable_altq(altq);
3320 if (error != 0)
3321 break;
3322 }
3323 }
3324 if (error == 0)
3325 V_pf_altq_running = 1;
3326 PF_RULES_WUNLOCK();
3327 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
3328 break;
3329 }
3330
3331 case DIOCSTOPALTQ: {
3332 struct pf_altq *altq;
3333
3334 PF_RULES_WLOCK();
3335 /* disable all altq interfaces on active list */
3336 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
3337 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
3338 error = pf_disable_altq(altq);
3339 if (error != 0)
3340 break;
3341 }
3342 }
3343 if (error == 0)
3344 V_pf_altq_running = 0;
3345 PF_RULES_WUNLOCK();
3346 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
3347 break;
3348 }
3349
3350 case DIOCADDALTQV0:
3351 case DIOCADDALTQV1: {
3352 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
3353 struct pf_altq *altq, *a;
3354 struct ifnet *ifp;
3355
3356 altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK | M_ZERO);
3357 error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd));
3358 if (error)
3359 break;
3360 altq->local_flags = 0;
3361
3362 PF_RULES_WLOCK();
3363 if (pa->ticket != V_ticket_altqs_inactive) {
3364 PF_RULES_WUNLOCK();
3365 free(altq, M_PFALTQ);
3366 error = EBUSY;
3367 break;
3368 }
3369
3370 /*
3371 * if this is for a queue, find the discipline and
3372 * copy the necessary fields
3373 */
3374 if (altq->qname[0] != 0) {
3375 if ((altq->qid = pf_qname2qid(altq->qname)) == 0) {
3376 PF_RULES_WUNLOCK();
3377 error = EBUSY;
3378 free(altq, M_PFALTQ);
3379 break;
3380 }
3381 altq->altq_disc = NULL;
3382 TAILQ_FOREACH(a, V_pf_altq_ifs_inactive, entries) {
3383 if (strncmp(a->ifname, altq->ifname,
3384 IFNAMSIZ) == 0) {
3385 altq->altq_disc = a->altq_disc;
3386 break;
3387 }
3388 }
3389 }
3390
3391 if ((ifp = ifunit(altq->ifname)) == NULL)
3392 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
3393 else
3394 error = altq_add(ifp, altq);
3395
3396 if (error) {
3397 PF_RULES_WUNLOCK();
3398 free(altq, M_PFALTQ);
3399 break;
3400 }
3401
3402 if (altq->qname[0] != 0)
3403 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
3404 else
3405 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, altq, entries);
3406 /* version error check done on import above */
3407 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
3408 PF_RULES_WUNLOCK();
3409 break;
3410 }
3411
3412 case DIOCGETALTQSV0:
3413 case DIOCGETALTQSV1: {
3414 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
3415 struct pf_altq *altq;
3416
3417 PF_RULES_RLOCK();
3418 pa->nr = 0;
3419 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries)
3420 pa->nr++;
3421 TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
3422 pa->nr++;
3423 pa->ticket = V_ticket_altqs_active;
3424 PF_RULES_RUNLOCK();
3425 break;
3426 }
3427
3428 case DIOCGETALTQV0:
3429 case DIOCGETALTQV1: {
3430 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
3431 struct pf_altq *altq;
3432
3433 PF_RULES_RLOCK();
3434 if (pa->ticket != V_ticket_altqs_active) {
3435 PF_RULES_RUNLOCK();
3436 error = EBUSY;
3437 break;
3438 }
3439 altq = pf_altq_get_nth_active(pa->nr);
3440 if (altq == NULL) {
3441 PF_RULES_RUNLOCK();
3442 error = EBUSY;
3443 break;
3444 }
3445 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
3446 PF_RULES_RUNLOCK();
3447 break;
3448 }
3449
3450 case DIOCCHANGEALTQV0:
3451 case DIOCCHANGEALTQV1:
3452 /* CHANGEALTQ not supported yet! */
3453 error = ENODEV;
3454 break;
3455
3456 case DIOCGETQSTATSV0:
3457 case DIOCGETQSTATSV1: {
3458 struct pfioc_qstats_v1 *pq = (struct pfioc_qstats_v1 *)addr;
3459 struct pf_altq *altq;
3460 int nbytes;
3461 u_int32_t version;
3462
3463 PF_RULES_RLOCK();
3464 if (pq->ticket != V_ticket_altqs_active) {
3465 PF_RULES_RUNLOCK();
3466 error = EBUSY;
3467 break;
3468 }
3469 nbytes = pq->nbytes;
3470 altq = pf_altq_get_nth_active(pq->nr);
3471 if (altq == NULL) {
3472 PF_RULES_RUNLOCK();
3473 error = EBUSY;
3474 break;
3475 }
3476
3477 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
3478 PF_RULES_RUNLOCK();
3479 error = ENXIO;
3480 break;
3481 }
3482 PF_RULES_RUNLOCK();
3483 if (cmd == DIOCGETQSTATSV0)
3484 version = 0; /* DIOCGETQSTATSV0 means stats struct v0 */
3485 else
3486 version = pq->version;
3487 error = altq_getqstats(altq, pq->buf, &nbytes, version);
3488 if (error == 0) {
3489 pq->scheduler = altq->scheduler;
3490 pq->nbytes = nbytes;
3491 }
3492 break;
3493 }
3494 #endif /* ALTQ */
3495
3496 case DIOCBEGINADDRS: {
3497 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
3498
3499 PF_RULES_WLOCK();
3500 pf_empty_kpool(&V_pf_pabuf);
3501 pp->ticket = ++V_ticket_pabuf;
3502 PF_RULES_WUNLOCK();
3503 break;
3504 }
3505
3506 case DIOCADDADDR: {
3507 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
3508 struct pf_kpooladdr *pa;
3509 struct pfi_kkif *kif = NULL;
3510
3511 #ifndef INET
3512 if (pp->af == AF_INET) {
3513 error = EAFNOSUPPORT;
3514 break;
3515 }
3516 #endif /* INET */
3517 #ifndef INET6
3518 if (pp->af == AF_INET6) {
3519 error = EAFNOSUPPORT;
3520 break;
3521 }
3522 #endif /* INET6 */
3523 if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
3524 pp->addr.addr.type != PF_ADDR_DYNIFTL &&
3525 pp->addr.addr.type != PF_ADDR_TABLE) {
3526 error = EINVAL;
3527 break;
3528 }
3529 if (pp->addr.addr.p.dyn != NULL) {
3530 error = EINVAL;
3531 break;
3532 }
3533 pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK);
3534 error = pf_pooladdr_to_kpooladdr(&pp->addr, pa);
3535 if (error != 0)
3536 break;
3537 if (pa->ifname[0])
3538 kif = pf_kkif_create(M_WAITOK);
3539 PF_RULES_WLOCK();
3540 if (pp->ticket != V_ticket_pabuf) {
3541 PF_RULES_WUNLOCK();
3542 if (pa->ifname[0])
3543 pf_kkif_free(kif);
3544 free(pa, M_PFRULE);
3545 error = EBUSY;
3546 break;
3547 }
3548 if (pa->ifname[0]) {
3549 pa->kif = pfi_kkif_attach(kif, pa->ifname);
3550 kif = NULL;
3551 pfi_kkif_ref(pa->kif);
3552 } else
3553 pa->kif = NULL;
3554 if (pa->addr.type == PF_ADDR_DYNIFTL && ((error =
3555 pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) {
3556 if (pa->ifname[0])
3557 pfi_kkif_unref(pa->kif);
3558 PF_RULES_WUNLOCK();
3559 free(pa, M_PFRULE);
3560 break;
3561 }
3562 TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
3563 PF_RULES_WUNLOCK();
3564 break;
3565 }
3566
3567 case DIOCGETADDRS: {
3568 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
3569 struct pf_kpool *pool;
3570 struct pf_kpooladdr *pa;
3571
3572 pp->anchor[sizeof(pp->anchor) - 1] = 0;
3573 pp->nr = 0;
3574
3575 PF_RULES_RLOCK();
3576 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
3577 pp->r_num, 0, 1, 0);
3578 if (pool == NULL) {
3579 PF_RULES_RUNLOCK();
3580 error = EBUSY;
3581 break;
3582 }
3583 TAILQ_FOREACH(pa, &pool->list, entries)
3584 pp->nr++;
3585 PF_RULES_RUNLOCK();
3586 break;
3587 }
3588
3589 case DIOCGETADDR: {
3590 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
3591 struct pf_kpool *pool;
3592 struct pf_kpooladdr *pa;
3593 u_int32_t nr = 0;
3594
3595 pp->anchor[sizeof(pp->anchor) - 1] = 0;
3596
3597 PF_RULES_RLOCK();
3598 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
3599 pp->r_num, 0, 1, 1);
3600 if (pool == NULL) {
3601 PF_RULES_RUNLOCK();
3602 error = EBUSY;
3603 break;
3604 }
3605 pa = TAILQ_FIRST(&pool->list);
3606 while ((pa != NULL) && (nr < pp->nr)) {
3607 pa = TAILQ_NEXT(pa, entries);
3608 nr++;
3609 }
3610 if (pa == NULL) {
3611 PF_RULES_RUNLOCK();
3612 error = EBUSY;
3613 break;
3614 }
3615 pf_kpooladdr_to_pooladdr(pa, &pp->addr);
3616 pf_addr_copyout(&pp->addr.addr);
3617 PF_RULES_RUNLOCK();
3618 break;
3619 }
3620
3621 case DIOCCHANGEADDR: {
3622 struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
3623 struct pf_kpool *pool;
3624 struct pf_kpooladdr *oldpa = NULL, *newpa = NULL;
3625 struct pf_kruleset *ruleset;
3626 struct pfi_kkif *kif = NULL;
3627
3628 pca->anchor[sizeof(pca->anchor) - 1] = 0;
3629
3630 if (pca->action < PF_CHANGE_ADD_HEAD ||
3631 pca->action > PF_CHANGE_REMOVE) {
3632 error = EINVAL;
3633 break;
3634 }
3635 if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
3636 pca->addr.addr.type != PF_ADDR_DYNIFTL &&
3637 pca->addr.addr.type != PF_ADDR_TABLE) {
3638 error = EINVAL;
3639 break;
3640 }
3641 if (pca->addr.addr.p.dyn != NULL) {
3642 error = EINVAL;
3643 break;
3644 }
3645
3646 if (pca->action != PF_CHANGE_REMOVE) {
3647 #ifndef INET
3648 if (pca->af == AF_INET) {
3649 error = EAFNOSUPPORT;
3650 break;
3651 }
3652 #endif /* INET */
3653 #ifndef INET6
3654 if (pca->af == AF_INET6) {
3655 error = EAFNOSUPPORT;
3656 break;
3657 }
3658 #endif /* INET6 */
3659 newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK);
3660 bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
3661 if (newpa->ifname[0])
3662 kif = pf_kkif_create(M_WAITOK);
3663 newpa->kif = NULL;
3664 }
3665 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGEADDR_error, x)
3666 PF_RULES_WLOCK();
3667 ruleset = pf_find_kruleset(pca->anchor);
3668 if (ruleset == NULL)
3669 ERROUT(EBUSY);
3670
3671 pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action,
3672 pca->r_num, pca->r_last, 1, 1);
3673 if (pool == NULL)
3674 ERROUT(EBUSY);
3675
3676 if (pca->action != PF_CHANGE_REMOVE) {
3677 if (newpa->ifname[0]) {
3678 newpa->kif = pfi_kkif_attach(kif, newpa->ifname);
3679 pfi_kkif_ref(newpa->kif);
3680 kif = NULL;
3681 }
3682
3683 switch (newpa->addr.type) {
3684 case PF_ADDR_DYNIFTL:
3685 error = pfi_dynaddr_setup(&newpa->addr,
3686 pca->af);
3687 break;
3688 case PF_ADDR_TABLE:
3689 newpa->addr.p.tbl = pfr_attach_table(ruleset,
3690 newpa->addr.v.tblname);
3691 if (newpa->addr.p.tbl == NULL)
3692 error = ENOMEM;
3693 break;
3694 }
3695 if (error)
3696 goto DIOCCHANGEADDR_error;
3697 }
3698
3699 switch (pca->action) {
3700 case PF_CHANGE_ADD_HEAD:
3701 oldpa = TAILQ_FIRST(&pool->list);
3702 break;
3703 case PF_CHANGE_ADD_TAIL:
3704 oldpa = TAILQ_LAST(&pool->list, pf_kpalist);
3705 break;
3706 default:
3707 oldpa = TAILQ_FIRST(&pool->list);
3708 for (int i = 0; oldpa && i < pca->nr; i++)
3709 oldpa = TAILQ_NEXT(oldpa, entries);
3710
3711 if (oldpa == NULL)
3712 ERROUT(EINVAL);
3713 }
3714
3715 if (pca->action == PF_CHANGE_REMOVE) {
3716 TAILQ_REMOVE(&pool->list, oldpa, entries);
3717 switch (oldpa->addr.type) {
3718 case PF_ADDR_DYNIFTL:
3719 pfi_dynaddr_remove(oldpa->addr.p.dyn);
3720 break;
3721 case PF_ADDR_TABLE:
3722 pfr_detach_table(oldpa->addr.p.tbl);
3723 break;
3724 }
3725 if (oldpa->kif)
3726 pfi_kkif_unref(oldpa->kif);
3727 free(oldpa, M_PFRULE);
3728 } else {
3729 if (oldpa == NULL)
3730 TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
3731 else if (pca->action == PF_CHANGE_ADD_HEAD ||
3732 pca->action == PF_CHANGE_ADD_BEFORE)
3733 TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
3734 else
3735 TAILQ_INSERT_AFTER(&pool->list, oldpa,
3736 newpa, entries);
3737 }
3738
3739 pool->cur = TAILQ_FIRST(&pool->list);
3740 PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af);
3741 PF_RULES_WUNLOCK();
3742 break;
3743
3744 #undef ERROUT
3745 DIOCCHANGEADDR_error:
3746 if (newpa != NULL) {
3747 if (newpa->kif)
3748 pfi_kkif_unref(newpa->kif);
3749 free(newpa, M_PFRULE);
3750 }
3751 PF_RULES_WUNLOCK();
3752 pf_kkif_free(kif);
3753 break;
3754 }
3755
3756 case DIOCGETRULESETS: {
3757 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
3758 struct pf_kruleset *ruleset;
3759 struct pf_kanchor *anchor;
3760
3761 pr->path[sizeof(pr->path) - 1] = 0;
3762
3763 PF_RULES_RLOCK();
3764 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
3765 PF_RULES_RUNLOCK();
3766 error = ENOENT;
3767 break;
3768 }
3769 pr->nr = 0;
3770 if (ruleset->anchor == NULL) {
3771 /* XXX kludge for pf_main_ruleset */
3772 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
3773 if (anchor->parent == NULL)
3774 pr->nr++;
3775 } else {
3776 RB_FOREACH(anchor, pf_kanchor_node,
3777 &ruleset->anchor->children)
3778 pr->nr++;
3779 }
3780 PF_RULES_RUNLOCK();
3781 break;
3782 }
3783
3784 case DIOCGETRULESET: {
3785 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
3786 struct pf_kruleset *ruleset;
3787 struct pf_kanchor *anchor;
3788 u_int32_t nr = 0;
3789
3790 pr->path[sizeof(pr->path) - 1] = 0;
3791
3792 PF_RULES_RLOCK();
3793 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
3794 PF_RULES_RUNLOCK();
3795 error = ENOENT;
3796 break;
3797 }
3798 pr->name[0] = 0;
3799 if (ruleset->anchor == NULL) {
3800 /* XXX kludge for pf_main_ruleset */
3801 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
3802 if (anchor->parent == NULL && nr++ == pr->nr) {
3803 strlcpy(pr->name, anchor->name,
3804 sizeof(pr->name));
3805 break;
3806 }
3807 } else {
3808 RB_FOREACH(anchor, pf_kanchor_node,
3809 &ruleset->anchor->children)
3810 if (nr++ == pr->nr) {
3811 strlcpy(pr->name, anchor->name,
3812 sizeof(pr->name));
3813 break;
3814 }
3815 }
3816 if (!pr->name[0])
3817 error = EBUSY;
3818 PF_RULES_RUNLOCK();
3819 break;
3820 }
3821
3822 case DIOCRCLRTABLES: {
3823 struct pfioc_table *io = (struct pfioc_table *)addr;
3824
3825 if (io->pfrio_esize != 0) {
3826 error = ENODEV;
3827 break;
3828 }
3829 PF_RULES_WLOCK();
3830 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
3831 io->pfrio_flags | PFR_FLAG_USERIOCTL);
3832 PF_RULES_WUNLOCK();
3833 break;
3834 }
3835
3836 case DIOCRADDTABLES: {
3837 struct pfioc_table *io = (struct pfioc_table *)addr;
3838 struct pfr_table *pfrts;
3839 size_t totlen;
3840
3841 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3842 error = ENODEV;
3843 break;
3844 }
3845
3846 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3847 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3848 error = ENOMEM;
3849 break;
3850 }
3851
3852 totlen = io->pfrio_size * sizeof(struct pfr_table);
3853 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3854 M_TEMP, M_WAITOK);
3855 error = copyin(io->pfrio_buffer, pfrts, totlen);
3856 if (error) {
3857 free(pfrts, M_TEMP);
3858 break;
3859 }
3860 PF_RULES_WLOCK();
3861 error = pfr_add_tables(pfrts, io->pfrio_size,
3862 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3863 PF_RULES_WUNLOCK();
3864 free(pfrts, M_TEMP);
3865 break;
3866 }
3867
3868 case DIOCRDELTABLES: {
3869 struct pfioc_table *io = (struct pfioc_table *)addr;
3870 struct pfr_table *pfrts;
3871 size_t totlen;
3872
3873 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3874 error = ENODEV;
3875 break;
3876 }
3877
3878 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3879 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3880 error = ENOMEM;
3881 break;
3882 }
3883
3884 totlen = io->pfrio_size * sizeof(struct pfr_table);
3885 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3886 M_TEMP, M_WAITOK);
3887 error = copyin(io->pfrio_buffer, pfrts, totlen);
3888 if (error) {
3889 free(pfrts, M_TEMP);
3890 break;
3891 }
3892 PF_RULES_WLOCK();
3893 error = pfr_del_tables(pfrts, io->pfrio_size,
3894 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3895 PF_RULES_WUNLOCK();
3896 free(pfrts, M_TEMP);
3897 break;
3898 }
3899
3900 case DIOCRGETTABLES: {
3901 struct pfioc_table *io = (struct pfioc_table *)addr;
3902 struct pfr_table *pfrts;
3903 size_t totlen;
3904 int n;
3905
3906 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3907 error = ENODEV;
3908 break;
3909 }
3910 PF_RULES_RLOCK();
3911 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3912 if (n < 0) {
3913 PF_RULES_RUNLOCK();
3914 error = EINVAL;
3915 break;
3916 }
3917 io->pfrio_size = min(io->pfrio_size, n);
3918
3919 totlen = io->pfrio_size * sizeof(struct pfr_table);
3920
3921 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3922 M_TEMP, M_NOWAIT | M_ZERO);
3923 if (pfrts == NULL) {
3924 error = ENOMEM;
3925 PF_RULES_RUNLOCK();
3926 break;
3927 }
3928 error = pfr_get_tables(&io->pfrio_table, pfrts,
3929 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3930 PF_RULES_RUNLOCK();
3931 if (error == 0)
3932 error = copyout(pfrts, io->pfrio_buffer, totlen);
3933 free(pfrts, M_TEMP);
3934 break;
3935 }
3936
3937 case DIOCRGETTSTATS: {
3938 struct pfioc_table *io = (struct pfioc_table *)addr;
3939 struct pfr_tstats *pfrtstats;
3940 size_t totlen;
3941 int n;
3942
3943 if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
3944 error = ENODEV;
3945 break;
3946 }
3947 PF_TABLE_STATS_LOCK();
3948 PF_RULES_RLOCK();
3949 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3950 if (n < 0) {
3951 PF_RULES_RUNLOCK();
3952 PF_TABLE_STATS_UNLOCK();
3953 error = EINVAL;
3954 break;
3955 }
3956 io->pfrio_size = min(io->pfrio_size, n);
3957
3958 totlen = io->pfrio_size * sizeof(struct pfr_tstats);
3959 pfrtstats = mallocarray(io->pfrio_size,
3960 sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT | M_ZERO);
3961 if (pfrtstats == NULL) {
3962 error = ENOMEM;
3963 PF_RULES_RUNLOCK();
3964 PF_TABLE_STATS_UNLOCK();
3965 break;
3966 }
3967 error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
3968 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3969 PF_RULES_RUNLOCK();
3970 PF_TABLE_STATS_UNLOCK();
3971 if (error == 0)
3972 error = copyout(pfrtstats, io->pfrio_buffer, totlen);
3973 free(pfrtstats, M_TEMP);
3974 break;
3975 }
3976
3977 case DIOCRCLRTSTATS: {
3978 struct pfioc_table *io = (struct pfioc_table *)addr;
3979 struct pfr_table *pfrts;
3980 size_t totlen;
3981
3982 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3983 error = ENODEV;
3984 break;
3985 }
3986
3987 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3988 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3989 /* We used to count tables and use the minimum required
3990 * size, so we didn't fail on overly large requests.
3991 * Keep doing so. */
3992 io->pfrio_size = pf_ioctl_maxcount;
3993 break;
3994 }
3995
3996 totlen = io->pfrio_size * sizeof(struct pfr_table);
3997 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3998 M_TEMP, M_WAITOK);
3999 error = copyin(io->pfrio_buffer, pfrts, totlen);
4000 if (error) {
4001 free(pfrts, M_TEMP);
4002 break;
4003 }
4004
4005 PF_TABLE_STATS_LOCK();
4006 PF_RULES_RLOCK();
4007 error = pfr_clr_tstats(pfrts, io->pfrio_size,
4008 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4009 PF_RULES_RUNLOCK();
4010 PF_TABLE_STATS_UNLOCK();
4011 free(pfrts, M_TEMP);
4012 break;
4013 }
4014
4015 case DIOCRSETTFLAGS: {
4016 struct pfioc_table *io = (struct pfioc_table *)addr;
4017 struct pfr_table *pfrts;
4018 size_t totlen;
4019 int n;
4020
4021 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4022 error = ENODEV;
4023 break;
4024 }
4025
4026 PF_RULES_RLOCK();
4027 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4028 if (n < 0) {
4029 PF_RULES_RUNLOCK();
4030 error = EINVAL;
4031 break;
4032 }
4033
4034 io->pfrio_size = min(io->pfrio_size, n);
4035 PF_RULES_RUNLOCK();
4036
4037 totlen = io->pfrio_size * sizeof(struct pfr_table);
4038 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4039 M_TEMP, M_WAITOK);
4040 error = copyin(io->pfrio_buffer, pfrts, totlen);
4041 if (error) {
4042 free(pfrts, M_TEMP);
4043 break;
4044 }
4045 PF_RULES_WLOCK();
4046 error = pfr_set_tflags(pfrts, io->pfrio_size,
4047 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
4048 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4049 PF_RULES_WUNLOCK();
4050 free(pfrts, M_TEMP);
4051 break;
4052 }
4053
4054 case DIOCRCLRADDRS: {
4055 struct pfioc_table *io = (struct pfioc_table *)addr;
4056
4057 if (io->pfrio_esize != 0) {
4058 error = ENODEV;
4059 break;
4060 }
4061 PF_RULES_WLOCK();
4062 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
4063 io->pfrio_flags | PFR_FLAG_USERIOCTL);
4064 PF_RULES_WUNLOCK();
4065 break;
4066 }
4067
4068 case DIOCRADDADDRS: {
4069 struct pfioc_table *io = (struct pfioc_table *)addr;
4070 struct pfr_addr *pfras;
4071 size_t totlen;
4072
4073 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4074 error = ENODEV;
4075 break;
4076 }
4077 if (io->pfrio_size < 0 ||
4078 io->pfrio_size > pf_ioctl_maxcount ||
4079 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4080 error = EINVAL;
4081 break;
4082 }
4083 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4084 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4085 M_TEMP, M_WAITOK);
4086 error = copyin(io->pfrio_buffer, pfras, totlen);
4087 if (error) {
4088 free(pfras, M_TEMP);
4089 break;
4090 }
4091 PF_RULES_WLOCK();
4092 error = pfr_add_addrs(&io->pfrio_table, pfras,
4093 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
4094 PFR_FLAG_USERIOCTL);
4095 PF_RULES_WUNLOCK();
4096 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4097 error = copyout(pfras, io->pfrio_buffer, totlen);
4098 free(pfras, M_TEMP);
4099 break;
4100 }
4101
4102 case DIOCRDELADDRS: {
4103 struct pfioc_table *io = (struct pfioc_table *)addr;
4104 struct pfr_addr *pfras;
4105 size_t totlen;
4106
4107 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4108 error = ENODEV;
4109 break;
4110 }
4111 if (io->pfrio_size < 0 ||
4112 io->pfrio_size > pf_ioctl_maxcount ||
4113 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4114 error = EINVAL;
4115 break;
4116 }
4117 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4118 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4119 M_TEMP, M_WAITOK);
4120 error = copyin(io->pfrio_buffer, pfras, totlen);
4121 if (error) {
4122 free(pfras, M_TEMP);
4123 break;
4124 }
4125 PF_RULES_WLOCK();
4126 error = pfr_del_addrs(&io->pfrio_table, pfras,
4127 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
4128 PFR_FLAG_USERIOCTL);
4129 PF_RULES_WUNLOCK();
4130 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4131 error = copyout(pfras, io->pfrio_buffer, totlen);
4132 free(pfras, M_TEMP);
4133 break;
4134 }
4135
4136 case DIOCRSETADDRS: {
4137 struct pfioc_table *io = (struct pfioc_table *)addr;
4138 struct pfr_addr *pfras;
4139 size_t totlen, count;
4140
4141 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4142 error = ENODEV;
4143 break;
4144 }
4145 if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
4146 error = EINVAL;
4147 break;
4148 }
4149 count = max(io->pfrio_size, io->pfrio_size2);
4150 if (count > pf_ioctl_maxcount ||
4151 WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
4152 error = EINVAL;
4153 break;
4154 }
4155 totlen = count * sizeof(struct pfr_addr);
4156 pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
4157 M_WAITOK);
4158 error = copyin(io->pfrio_buffer, pfras, totlen);
4159 if (error) {
4160 free(pfras, M_TEMP);
4161 break;
4162 }
4163 PF_RULES_WLOCK();
4164 error = pfr_set_addrs(&io->pfrio_table, pfras,
4165 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
4166 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
4167 PFR_FLAG_USERIOCTL, 0);
4168 PF_RULES_WUNLOCK();
4169 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4170 error = copyout(pfras, io->pfrio_buffer, totlen);
4171 free(pfras, M_TEMP);
4172 break;
4173 }
4174
4175 case DIOCRGETADDRS: {
4176 struct pfioc_table *io = (struct pfioc_table *)addr;
4177 struct pfr_addr *pfras;
4178 size_t totlen;
4179
4180 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4181 error = ENODEV;
4182 break;
4183 }
4184 if (io->pfrio_size < 0 ||
4185 io->pfrio_size > pf_ioctl_maxcount ||
4186 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4187 error = EINVAL;
4188 break;
4189 }
4190 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4191 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4192 M_TEMP, M_WAITOK | M_ZERO);
4193 PF_RULES_RLOCK();
4194 error = pfr_get_addrs(&io->pfrio_table, pfras,
4195 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4196 PF_RULES_RUNLOCK();
4197 if (error == 0)
4198 error = copyout(pfras, io->pfrio_buffer, totlen);
4199 free(pfras, M_TEMP);
4200 break;
4201 }
4202
4203 case DIOCRGETASTATS: {
4204 struct pfioc_table *io = (struct pfioc_table *)addr;
4205 struct pfr_astats *pfrastats;
4206 size_t totlen;
4207
4208 if (io->pfrio_esize != sizeof(struct pfr_astats)) {
4209 error = ENODEV;
4210 break;
4211 }
4212 if (io->pfrio_size < 0 ||
4213 io->pfrio_size > pf_ioctl_maxcount ||
4214 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
4215 error = EINVAL;
4216 break;
4217 }
4218 totlen = io->pfrio_size * sizeof(struct pfr_astats);
4219 pfrastats = mallocarray(io->pfrio_size,
4220 sizeof(struct pfr_astats), M_TEMP, M_WAITOK | M_ZERO);
4221 PF_RULES_RLOCK();
4222 error = pfr_get_astats(&io->pfrio_table, pfrastats,
4223 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4224 PF_RULES_RUNLOCK();
4225 if (error == 0)
4226 error = copyout(pfrastats, io->pfrio_buffer, totlen);
4227 free(pfrastats, M_TEMP);
4228 break;
4229 }
4230
4231 case DIOCRCLRASTATS: {
4232 struct pfioc_table *io = (struct pfioc_table *)addr;
4233 struct pfr_addr *pfras;
4234 size_t totlen;
4235
4236 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4237 error = ENODEV;
4238 break;
4239 }
4240 if (io->pfrio_size < 0 ||
4241 io->pfrio_size > pf_ioctl_maxcount ||
4242 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4243 error = EINVAL;
4244 break;
4245 }
4246 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4247 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4248 M_TEMP, M_WAITOK);
4249 error = copyin(io->pfrio_buffer, pfras, totlen);
4250 if (error) {
4251 free(pfras, M_TEMP);
4252 break;
4253 }
4254 PF_RULES_WLOCK();
4255 error = pfr_clr_astats(&io->pfrio_table, pfras,
4256 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
4257 PFR_FLAG_USERIOCTL);
4258 PF_RULES_WUNLOCK();
4259 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4260 error = copyout(pfras, io->pfrio_buffer, totlen);
4261 free(pfras, M_TEMP);
4262 break;
4263 }
4264
4265 case DIOCRTSTADDRS: {
4266 struct pfioc_table *io = (struct pfioc_table *)addr;
4267 struct pfr_addr *pfras;
4268 size_t totlen;
4269
4270 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4271 error = ENODEV;
4272 break;
4273 }
4274 if (io->pfrio_size < 0 ||
4275 io->pfrio_size > pf_ioctl_maxcount ||
4276 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4277 error = EINVAL;
4278 break;
4279 }
4280 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4281 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4282 M_TEMP, M_WAITOK);
4283 error = copyin(io->pfrio_buffer, pfras, totlen);
4284 if (error) {
4285 free(pfras, M_TEMP);
4286 break;
4287 }
4288 PF_RULES_RLOCK();
4289 error = pfr_tst_addrs(&io->pfrio_table, pfras,
4290 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
4291 PFR_FLAG_USERIOCTL);
4292 PF_RULES_RUNLOCK();
4293 if (error == 0)
4294 error = copyout(pfras, io->pfrio_buffer, totlen);
4295 free(pfras, M_TEMP);
4296 break;
4297 }
4298
4299 case DIOCRINADEFINE: {
4300 struct pfioc_table *io = (struct pfioc_table *)addr;
4301 struct pfr_addr *pfras;
4302 size_t totlen;
4303
4304 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4305 error = ENODEV;
4306 break;
4307 }
4308 if (io->pfrio_size < 0 ||
4309 io->pfrio_size > pf_ioctl_maxcount ||
4310 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4311 error = EINVAL;
4312 break;
4313 }
4314 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4315 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4316 M_TEMP, M_WAITOK);
4317 error = copyin(io->pfrio_buffer, pfras, totlen);
4318 if (error) {
4319 free(pfras, M_TEMP);
4320 break;
4321 }
4322 PF_RULES_WLOCK();
4323 error = pfr_ina_define(&io->pfrio_table, pfras,
4324 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
4325 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4326 PF_RULES_WUNLOCK();
4327 free(pfras, M_TEMP);
4328 break;
4329 }
4330
4331 case DIOCOSFPADD: {
4332 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
4333 PF_RULES_WLOCK();
4334 error = pf_osfp_add(io);
4335 PF_RULES_WUNLOCK();
4336 break;
4337 }
4338
4339 case DIOCOSFPGET: {
4340 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
4341 PF_RULES_RLOCK();
4342 error = pf_osfp_get(io);
4343 PF_RULES_RUNLOCK();
4344 break;
4345 }
4346
4347 case DIOCXBEGIN: {
4348 struct pfioc_trans *io = (struct pfioc_trans *)addr;
4349 struct pfioc_trans_e *ioes, *ioe;
4350 size_t totlen;
4351 int i;
4352
4353 if (io->esize != sizeof(*ioe)) {
4354 error = ENODEV;
4355 break;
4356 }
4357 if (io->size < 0 ||
4358 io->size > pf_ioctl_maxcount ||
4359 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4360 error = EINVAL;
4361 break;
4362 }
4363 totlen = sizeof(struct pfioc_trans_e) * io->size;
4364 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4365 M_TEMP, M_WAITOK);
4366 error = copyin(io->array, ioes, totlen);
4367 if (error) {
4368 free(ioes, M_TEMP);
4369 break;
4370 }
4371 PF_RULES_WLOCK();
4372 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4373 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
4374 switch (ioe->rs_num) {
4375 #ifdef ALTQ
4376 case PF_RULESET_ALTQ:
4377 if (ioe->anchor[0]) {
4378 PF_RULES_WUNLOCK();
4379 free(ioes, M_TEMP);
4380 error = EINVAL;
4381 goto fail;
4382 }
4383 if ((error = pf_begin_altq(&ioe->ticket))) {
4384 PF_RULES_WUNLOCK();
4385 free(ioes, M_TEMP);
4386 goto fail;
4387 }
4388 break;
4389 #endif /* ALTQ */
4390 case PF_RULESET_TABLE:
4391 {
4392 struct pfr_table table;
4393
4394 bzero(&table, sizeof(table));
4395 strlcpy(table.pfrt_anchor, ioe->anchor,
4396 sizeof(table.pfrt_anchor));
4397 if ((error = pfr_ina_begin(&table,
4398 &ioe->ticket, NULL, 0))) {
4399 PF_RULES_WUNLOCK();
4400 free(ioes, M_TEMP);
4401 goto fail;
4402 }
4403 break;
4404 }
4405 default:
4406 if ((error = pf_begin_rules(&ioe->ticket,
4407 ioe->rs_num, ioe->anchor))) {
4408 PF_RULES_WUNLOCK();
4409 free(ioes, M_TEMP);
4410 goto fail;
4411 }
4412 break;
4413 }
4414 }
4415 PF_RULES_WUNLOCK();
4416 error = copyout(ioes, io->array, totlen);
4417 free(ioes, M_TEMP);
4418 break;
4419 }
4420
4421 case DIOCXROLLBACK: {
4422 struct pfioc_trans *io = (struct pfioc_trans *)addr;
4423 struct pfioc_trans_e *ioe, *ioes;
4424 size_t totlen;
4425 int i;
4426
4427 if (io->esize != sizeof(*ioe)) {
4428 error = ENODEV;
4429 break;
4430 }
4431 if (io->size < 0 ||
4432 io->size > pf_ioctl_maxcount ||
4433 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4434 error = EINVAL;
4435 break;
4436 }
4437 totlen = sizeof(struct pfioc_trans_e) * io->size;
4438 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4439 M_TEMP, M_WAITOK);
4440 error = copyin(io->array, ioes, totlen);
4441 if (error) {
4442 free(ioes, M_TEMP);
4443 break;
4444 }
4445 PF_RULES_WLOCK();
4446 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4447 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
4448 switch (ioe->rs_num) {
4449 #ifdef ALTQ
4450 case PF_RULESET_ALTQ:
4451 if (ioe->anchor[0]) {
4452 PF_RULES_WUNLOCK();
4453 free(ioes, M_TEMP);
4454 error = EINVAL;
4455 goto fail;
4456 }
4457 if ((error = pf_rollback_altq(ioe->ticket))) {
4458 PF_RULES_WUNLOCK();
4459 free(ioes, M_TEMP);
4460 goto fail; /* really bad */
4461 }
4462 break;
4463 #endif /* ALTQ */
4464 case PF_RULESET_TABLE:
4465 {
4466 struct pfr_table table;
4467
4468 bzero(&table, sizeof(table));
4469 strlcpy(table.pfrt_anchor, ioe->anchor,
4470 sizeof(table.pfrt_anchor));
4471 if ((error = pfr_ina_rollback(&table,
4472 ioe->ticket, NULL, 0))) {
4473 PF_RULES_WUNLOCK();
4474 free(ioes, M_TEMP);
4475 goto fail; /* really bad */
4476 }
4477 break;
4478 }
4479 default:
4480 if ((error = pf_rollback_rules(ioe->ticket,
4481 ioe->rs_num, ioe->anchor))) {
4482 PF_RULES_WUNLOCK();
4483 free(ioes, M_TEMP);
4484 goto fail; /* really bad */
4485 }
4486 break;
4487 }
4488 }
4489 PF_RULES_WUNLOCK();
4490 free(ioes, M_TEMP);
4491 break;
4492 }
4493
4494 case DIOCXCOMMIT: {
4495 struct pfioc_trans *io = (struct pfioc_trans *)addr;
4496 struct pfioc_trans_e *ioe, *ioes;
4497 struct pf_kruleset *rs;
4498 size_t totlen;
4499 int i;
4500
4501 if (io->esize != sizeof(*ioe)) {
4502 error = ENODEV;
4503 break;
4504 }
4505
4506 if (io->size < 0 ||
4507 io->size > pf_ioctl_maxcount ||
4508 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4509 error = EINVAL;
4510 break;
4511 }
4512
4513 totlen = sizeof(struct pfioc_trans_e) * io->size;
4514 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4515 M_TEMP, M_WAITOK);
4516 error = copyin(io->array, ioes, totlen);
4517 if (error) {
4518 free(ioes, M_TEMP);
4519 break;
4520 }
4521 PF_RULES_WLOCK();
4522 /* First makes sure everything will succeed. */
4523 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4524 ioe->anchor[sizeof(ioe->anchor) - 1] = 0;
4525 switch (ioe->rs_num) {
4526 #ifdef ALTQ
4527 case PF_RULESET_ALTQ:
4528 if (ioe->anchor[0]) {
4529 PF_RULES_WUNLOCK();
4530 free(ioes, M_TEMP);
4531 error = EINVAL;
4532 goto fail;
4533 }
4534 if (!V_altqs_inactive_open || ioe->ticket !=
4535 V_ticket_altqs_inactive) {
4536 PF_RULES_WUNLOCK();
4537 free(ioes, M_TEMP);
4538 error = EBUSY;
4539 goto fail;
4540 }
4541 break;
4542 #endif /* ALTQ */
4543 case PF_RULESET_TABLE:
4544 rs = pf_find_kruleset(ioe->anchor);
4545 if (rs == NULL || !rs->topen || ioe->ticket !=
4546 rs->tticket) {
4547 PF_RULES_WUNLOCK();
4548 free(ioes, M_TEMP);
4549 error = EBUSY;
4550 goto fail;
4551 }
4552 break;
4553 default:
4554 if (ioe->rs_num < 0 || ioe->rs_num >=
4555 PF_RULESET_MAX) {
4556 PF_RULES_WUNLOCK();
4557 free(ioes, M_TEMP);
4558 error = EINVAL;
4559 goto fail;
4560 }
4561 rs = pf_find_kruleset(ioe->anchor);
4562 if (rs == NULL ||
4563 !rs->rules[ioe->rs_num].inactive.open ||
4564 rs->rules[ioe->rs_num].inactive.ticket !=
4565 ioe->ticket) {
4566 PF_RULES_WUNLOCK();
4567 free(ioes, M_TEMP);
4568 error = EBUSY;
4569 goto fail;
4570 }
4571 break;
4572 }
4573 }
4574 /* Now do the commit - no errors should happen here. */
4575 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4576 switch (ioe->rs_num) {
4577 #ifdef ALTQ
4578 case PF_RULESET_ALTQ:
4579 if ((error = pf_commit_altq(ioe->ticket))) {
4580 PF_RULES_WUNLOCK();
4581 free(ioes, M_TEMP);
4582 goto fail; /* really bad */
4583 }
4584 break;
4585 #endif /* ALTQ */
4586 case PF_RULESET_TABLE:
4587 {
4588 struct pfr_table table;
4589
4590 bzero(&table, sizeof(table));
4591 (void)strlcpy(table.pfrt_anchor, ioe->anchor,
4592 sizeof(table.pfrt_anchor));
4593 if ((error = pfr_ina_commit(&table,
4594 ioe->ticket, NULL, NULL, 0))) {
4595 PF_RULES_WUNLOCK();
4596 free(ioes, M_TEMP);
4597 goto fail; /* really bad */
4598 }
4599 break;
4600 }
4601 default:
4602 if ((error = pf_commit_rules(ioe->ticket,
4603 ioe->rs_num, ioe->anchor))) {
4604 PF_RULES_WUNLOCK();
4605 free(ioes, M_TEMP);
4606 goto fail; /* really bad */
4607 }
4608 break;
4609 }
4610 }
4611 PF_RULES_WUNLOCK();
4612 free(ioes, M_TEMP);
4613 break;
4614 }
4615
4616 case DIOCGETSRCNODES: {
4617 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
4618 struct pf_srchash *sh;
4619 struct pf_ksrc_node *n;
4620 struct pf_src_node *p, *pstore;
4621 uint32_t i, nr = 0;
4622
4623 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4624 i++, sh++) {
4625 PF_HASHROW_LOCK(sh);
4626 LIST_FOREACH(n, &sh->nodes, entry)
4627 nr++;
4628 PF_HASHROW_UNLOCK(sh);
4629 }
4630
4631 psn->psn_len = min(psn->psn_len,
4632 sizeof(struct pf_src_node) * nr);
4633
4634 if (psn->psn_len == 0) {
4635 psn->psn_len = sizeof(struct pf_src_node) * nr;
4636 break;
4637 }
4638
4639 nr = 0;
4640
4641 p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK | M_ZERO);
4642 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4643 i++, sh++) {
4644 PF_HASHROW_LOCK(sh);
4645 LIST_FOREACH(n, &sh->nodes, entry) {
4646
4647 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
4648 break;
4649
4650 pf_src_node_copy(n, p);
4651
4652 p++;
4653 nr++;
4654 }
4655 PF_HASHROW_UNLOCK(sh);
4656 }
4657 error = copyout(pstore, psn->psn_src_nodes,
4658 sizeof(struct pf_src_node) * nr);
4659 if (error) {
4660 free(pstore, M_TEMP);
4661 break;
4662 }
4663 psn->psn_len = sizeof(struct pf_src_node) * nr;
4664 free(pstore, M_TEMP);
4665 break;
4666 }
4667
4668 case DIOCCLRSRCNODES: {
4669 pf_clear_srcnodes(NULL);
4670 pf_purge_expired_src_nodes();
4671 break;
4672 }
4673
4674 case DIOCKILLSRCNODES:
4675 pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
4676 break;
4677
4678 case DIOCKEEPCOUNTERS:
4679 error = pf_keepcounters((struct pfioc_nv *)addr);
4680 break;
4681
4682 case DIOCGETSYNCOOKIES:
4683 error = pf_get_syncookies((struct pfioc_nv *)addr);
4684 break;
4685
4686 case DIOCSETSYNCOOKIES:
4687 error = pf_set_syncookies((struct pfioc_nv *)addr);
4688 break;
4689
4690 case DIOCSETHOSTID: {
4691 u_int32_t *hostid = (u_int32_t *)addr;
4692
4693 PF_RULES_WLOCK();
4694 if (*hostid == 0)
4695 V_pf_status.hostid = arc4random();
4696 else
4697 V_pf_status.hostid = *hostid;
4698 PF_RULES_WUNLOCK();
4699 break;
4700 }
4701
4702 case DIOCOSFPFLUSH:
4703 PF_RULES_WLOCK();
4704 pf_osfp_flush();
4705 PF_RULES_WUNLOCK();
4706 break;
4707
4708 case DIOCIGETIFACES: {
4709 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4710 struct pfi_kif *ifstore;
4711 size_t bufsiz;
4712
4713 if (io->pfiio_esize != sizeof(struct pfi_kif)) {
4714 error = ENODEV;
4715 break;
4716 }
4717
4718 if (io->pfiio_size < 0 ||
4719 io->pfiio_size > pf_ioctl_maxcount ||
4720 WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
4721 error = EINVAL;
4722 break;
4723 }
4724
4725 bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
4726 ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
4727 M_TEMP, M_WAITOK | M_ZERO);
4728
4729 PF_RULES_RLOCK();
4730 pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
4731 PF_RULES_RUNLOCK();
4732 error = copyout(ifstore, io->pfiio_buffer, bufsiz);
4733 free(ifstore, M_TEMP);
4734 break;
4735 }
4736
4737 case DIOCSETIFFLAG: {
4738 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4739
4740 PF_RULES_WLOCK();
4741 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
4742 PF_RULES_WUNLOCK();
4743 break;
4744 }
4745
4746 case DIOCCLRIFFLAG: {
4747 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4748
4749 PF_RULES_WLOCK();
4750 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
4751 PF_RULES_WUNLOCK();
4752 break;
4753 }
4754
4755 default:
4756 error = ENODEV;
4757 break;
4758 }
4759 fail:
4760 if (sx_xlocked(&pf_ioctl_lock))
4761 sx_xunlock(&pf_ioctl_lock);
4762 CURVNET_RESTORE();
4763
4764 #undef ERROUT_IOCTL
4765
4766 return (error);
4767 }
4768
4769 void
pfsync_state_export(struct pfsync_state * sp,struct pf_kstate * st)4770 pfsync_state_export(struct pfsync_state *sp, struct pf_kstate *st)
4771 {
4772 bzero(sp, sizeof(struct pfsync_state));
4773
4774 /* copy from state key */
4775 sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
4776 sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
4777 sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
4778 sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
4779 sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
4780 sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
4781 sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
4782 sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
4783 sp->proto = st->key[PF_SK_WIRE]->proto;
4784 sp->af = st->key[PF_SK_WIRE]->af;
4785
4786 /* copy from state */
4787 strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
4788 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
4789 sp->creation = htonl(time_uptime - st->creation);
4790 sp->expire = pf_state_expires(st);
4791 if (sp->expire <= time_uptime)
4792 sp->expire = htonl(0);
4793 else
4794 sp->expire = htonl(sp->expire - time_uptime);
4795
4796 sp->direction = st->direction;
4797 sp->log = st->log;
4798 sp->timeout = st->timeout;
4799 sp->state_flags = st->state_flags;
4800 if (st->src_node)
4801 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
4802 if (st->nat_src_node)
4803 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
4804
4805 sp->id = st->id;
4806 sp->creatorid = st->creatorid;
4807 pf_state_peer_hton(&st->src, &sp->src);
4808 pf_state_peer_hton(&st->dst, &sp->dst);
4809
4810 if (st->rule.ptr == NULL)
4811 sp->rule = htonl(-1);
4812 else
4813 sp->rule = htonl(st->rule.ptr->nr);
4814 if (st->anchor.ptr == NULL)
4815 sp->anchor = htonl(-1);
4816 else
4817 sp->anchor = htonl(st->anchor.ptr->nr);
4818 if (st->nat_rule.ptr == NULL)
4819 sp->nat_rule = htonl(-1);
4820 else
4821 sp->nat_rule = htonl(st->nat_rule.ptr->nr);
4822
4823 pf_state_counter_hton(st->packets[0], sp->packets[0]);
4824 pf_state_counter_hton(st->packets[1], sp->packets[1]);
4825 pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
4826 pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
4827 }
4828
4829 void
pf_state_export(struct pf_state_export * sp,struct pf_kstate * st)4830 pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
4831 {
4832 bzero(sp, sizeof(*sp));
4833
4834 sp->version = PF_STATE_VERSION;
4835
4836 /* copy from state key */
4837 sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
4838 sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
4839 sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
4840 sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
4841 sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
4842 sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
4843 sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
4844 sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
4845 sp->proto = st->key[PF_SK_WIRE]->proto;
4846 sp->af = st->key[PF_SK_WIRE]->af;
4847
4848 /* copy from state */
4849 strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
4850 strlcpy(sp->orig_ifname, st->orig_kif->pfik_name,
4851 sizeof(sp->orig_ifname));
4852 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
4853 sp->creation = htonl(time_uptime - st->creation);
4854 sp->expire = pf_state_expires(st);
4855 if (sp->expire <= time_uptime)
4856 sp->expire = htonl(0);
4857 else
4858 sp->expire = htonl(sp->expire - time_uptime);
4859
4860 sp->direction = st->direction;
4861 sp->log = st->log;
4862 sp->timeout = st->timeout;
4863 sp->state_flags = st->state_flags;
4864 if (st->src_node)
4865 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
4866 if (st->nat_src_node)
4867 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
4868
4869 sp->id = st->id;
4870 sp->creatorid = st->creatorid;
4871 pf_state_peer_hton(&st->src, &sp->src);
4872 pf_state_peer_hton(&st->dst, &sp->dst);
4873
4874 if (st->rule.ptr == NULL)
4875 sp->rule = htonl(-1);
4876 else
4877 sp->rule = htonl(st->rule.ptr->nr);
4878 if (st->anchor.ptr == NULL)
4879 sp->anchor = htonl(-1);
4880 else
4881 sp->anchor = htonl(st->anchor.ptr->nr);
4882 if (st->nat_rule.ptr == NULL)
4883 sp->nat_rule = htonl(-1);
4884 else
4885 sp->nat_rule = htonl(st->nat_rule.ptr->nr);
4886
4887 sp->packets[0] = st->packets[0];
4888 sp->packets[1] = st->packets[1];
4889 sp->bytes[0] = st->bytes[0];
4890 sp->bytes[1] = st->bytes[1];
4891 }
4892
4893 static void
pf_tbladdr_copyout(struct pf_addr_wrap * aw)4894 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
4895 {
4896 struct pfr_ktable *kt;
4897
4898 KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type));
4899
4900 kt = aw->p.tbl;
4901 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
4902 kt = kt->pfrkt_root;
4903 aw->p.tbl = NULL;
4904 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
4905 kt->pfrkt_cnt : -1;
4906 }
4907
4908 static int
pf_add_status_counters(nvlist_t * nvl,const char * name,counter_u64_t * counters,size_t number,char ** names)4909 pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t *counters,
4910 size_t number, char **names)
4911 {
4912 nvlist_t *nvc;
4913
4914 nvc = nvlist_create(0);
4915 if (nvc == NULL)
4916 return (ENOMEM);
4917
4918 for (int i = 0; i < number; i++) {
4919 nvlist_append_number_array(nvc, "counters",
4920 counter_u64_fetch(counters[i]));
4921 nvlist_append_string_array(nvc, "names",
4922 names[i]);
4923 nvlist_append_number_array(nvc, "ids",
4924 i);
4925 }
4926 nvlist_add_nvlist(nvl, name, nvc);
4927 nvlist_destroy(nvc);
4928
4929 return (0);
4930 }
4931
4932 static int
pf_getstatus(struct pfioc_nv * nv)4933 pf_getstatus(struct pfioc_nv *nv)
4934 {
4935 nvlist_t *nvl = NULL, *nvc = NULL;
4936 void *nvlpacked = NULL;
4937 int error;
4938 struct pf_status s;
4939 char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
4940 char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES;
4941 char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
4942 PF_RULES_RLOCK_TRACKER;
4943
4944 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
4945
4946 PF_RULES_RLOCK();
4947
4948 nvl = nvlist_create(0);
4949 if (nvl == NULL)
4950 ERROUT(ENOMEM);
4951
4952 nvlist_add_bool(nvl, "running", V_pf_status.running);
4953 nvlist_add_number(nvl, "since", V_pf_status.since);
4954 nvlist_add_number(nvl, "debug", V_pf_status.debug);
4955 nvlist_add_number(nvl, "hostid", V_pf_status.hostid);
4956 nvlist_add_number(nvl, "states", V_pf_status.states);
4957 nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes);
4958
4959 /* counters */
4960 error = pf_add_status_counters(nvl, "counters", V_pf_status.counters,
4961 PFRES_MAX, pf_reasons);
4962 if (error != 0)
4963 ERROUT(error);
4964
4965 /* lcounters */
4966 error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters,
4967 KLCNT_MAX, pf_lcounter);
4968 if (error != 0)
4969 ERROUT(error);
4970
4971 /* fcounters */
4972 nvc = nvlist_create(0);
4973 if (nvc == NULL)
4974 ERROUT(ENOMEM);
4975
4976 for (int i = 0; i < FCNT_MAX; i++) {
4977 nvlist_append_number_array(nvc, "counters",
4978 pf_counter_u64_fetch(&V_pf_status.fcounters[i]));
4979 nvlist_append_string_array(nvc, "names",
4980 pf_fcounter[i]);
4981 nvlist_append_number_array(nvc, "ids",
4982 i);
4983 }
4984 nvlist_add_nvlist(nvl, "fcounters", nvc);
4985 nvlist_destroy(nvc);
4986 nvc = NULL;
4987
4988 /* scounters */
4989 error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters,
4990 SCNT_MAX, pf_fcounter);
4991 if (error != 0)
4992 ERROUT(error);
4993
4994 nvlist_add_string(nvl, "ifname", V_pf_status.ifname);
4995 nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum,
4996 PF_MD5_DIGEST_LENGTH);
4997
4998 pfi_update_status(V_pf_status.ifname, &s);
4999
5000 /* pcounters / bcounters */
5001 for (int i = 0; i < 2; i++) {
5002 for (int j = 0; j < 2; j++) {
5003 for (int k = 0; k < 2; k++) {
5004 nvlist_append_number_array(nvl, "pcounters",
5005 s.pcounters[i][j][k]);
5006 }
5007 nvlist_append_number_array(nvl, "bcounters",
5008 s.bcounters[i][j]);
5009 }
5010 }
5011
5012 nvlpacked = nvlist_pack(nvl, &nv->len);
5013 if (nvlpacked == NULL)
5014 ERROUT(ENOMEM);
5015
5016 if (nv->size == 0)
5017 ERROUT(0);
5018 else if (nv->size < nv->len)
5019 ERROUT(ENOSPC);
5020
5021 PF_RULES_RUNLOCK();
5022 error = copyout(nvlpacked, nv->data, nv->len);
5023 goto done;
5024
5025 #undef ERROUT
5026 errout:
5027 PF_RULES_RUNLOCK();
5028 done:
5029 free(nvlpacked, M_NVLIST);
5030 nvlist_destroy(nvc);
5031 nvlist_destroy(nvl);
5032
5033 return (error);
5034 }
5035
5036 /*
5037 * XXX - Check for version missmatch!!!
5038 */
5039 static void
pf_clear_all_states(void)5040 pf_clear_all_states(void)
5041 {
5042 struct pf_kstate *s;
5043 u_int i;
5044
5045 for (i = 0; i <= pf_hashmask; i++) {
5046 struct pf_idhash *ih = &V_pf_idhash[i];
5047 relock:
5048 PF_HASHROW_LOCK(ih);
5049 LIST_FOREACH(s, &ih->states, entry) {
5050 s->timeout = PFTM_PURGE;
5051 /* Don't send out individual delete messages. */
5052 s->state_flags |= PFSTATE_NOSYNC;
5053 pf_unlink_state(s, PF_ENTER_LOCKED);
5054 goto relock;
5055 }
5056 PF_HASHROW_UNLOCK(ih);
5057 }
5058 }
5059
5060 static int
pf_clear_tables(void)5061 pf_clear_tables(void)
5062 {
5063 struct pfioc_table io;
5064 int error;
5065
5066 bzero(&io, sizeof(io));
5067
5068 error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
5069 io.pfrio_flags);
5070
5071 return (error);
5072 }
5073
5074 static void
pf_clear_srcnodes(struct pf_ksrc_node * n)5075 pf_clear_srcnodes(struct pf_ksrc_node *n)
5076 {
5077 struct pf_kstate *s;
5078 int i;
5079
5080 for (i = 0; i <= pf_hashmask; i++) {
5081 struct pf_idhash *ih = &V_pf_idhash[i];
5082
5083 PF_HASHROW_LOCK(ih);
5084 LIST_FOREACH(s, &ih->states, entry) {
5085 if (n == NULL || n == s->src_node)
5086 s->src_node = NULL;
5087 if (n == NULL || n == s->nat_src_node)
5088 s->nat_src_node = NULL;
5089 }
5090 PF_HASHROW_UNLOCK(ih);
5091 }
5092
5093 if (n == NULL) {
5094 struct pf_srchash *sh;
5095
5096 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5097 i++, sh++) {
5098 PF_HASHROW_LOCK(sh);
5099 LIST_FOREACH(n, &sh->nodes, entry) {
5100 n->expire = 1;
5101 n->states = 0;
5102 }
5103 PF_HASHROW_UNLOCK(sh);
5104 }
5105 } else {
5106 /* XXX: hash slot should already be locked here. */
5107 n->expire = 1;
5108 n->states = 0;
5109 }
5110 }
5111
5112 static void
pf_kill_srcnodes(struct pfioc_src_node_kill * psnk)5113 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
5114 {
5115 struct pf_ksrc_node_list kill;
5116
5117 LIST_INIT(&kill);
5118 for (int i = 0; i <= pf_srchashmask; i++) {
5119 struct pf_srchash *sh = &V_pf_srchash[i];
5120 struct pf_ksrc_node *sn, *tmp;
5121
5122 PF_HASHROW_LOCK(sh);
5123 LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
5124 if (PF_MATCHA(psnk->psnk_src.neg,
5125 &psnk->psnk_src.addr.v.a.addr,
5126 &psnk->psnk_src.addr.v.a.mask,
5127 &sn->addr, sn->af) &&
5128 PF_MATCHA(psnk->psnk_dst.neg,
5129 &psnk->psnk_dst.addr.v.a.addr,
5130 &psnk->psnk_dst.addr.v.a.mask,
5131 &sn->raddr, sn->af)) {
5132 pf_unlink_src_node(sn);
5133 LIST_INSERT_HEAD(&kill, sn, entry);
5134 sn->expire = 1;
5135 }
5136 PF_HASHROW_UNLOCK(sh);
5137 }
5138
5139 for (int i = 0; i <= pf_hashmask; i++) {
5140 struct pf_idhash *ih = &V_pf_idhash[i];
5141 struct pf_kstate *s;
5142
5143 PF_HASHROW_LOCK(ih);
5144 LIST_FOREACH(s, &ih->states, entry) {
5145 if (s->src_node && s->src_node->expire == 1)
5146 s->src_node = NULL;
5147 if (s->nat_src_node && s->nat_src_node->expire == 1)
5148 s->nat_src_node = NULL;
5149 }
5150 PF_HASHROW_UNLOCK(ih);
5151 }
5152
5153 psnk->psnk_killed = pf_free_src_nodes(&kill);
5154 }
5155
5156 static int
pf_keepcounters(struct pfioc_nv * nv)5157 pf_keepcounters(struct pfioc_nv *nv)
5158 {
5159 nvlist_t *nvl = NULL;
5160 void *nvlpacked = NULL;
5161 int error = 0;
5162
5163 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
5164
5165 if (nv->len > pf_ioctl_maxcount)
5166 ERROUT(ENOMEM);
5167
5168 nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
5169 if (nvlpacked == NULL)
5170 ERROUT(ENOMEM);
5171
5172 error = copyin(nv->data, nvlpacked, nv->len);
5173 if (error)
5174 ERROUT(error);
5175
5176 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5177 if (nvl == NULL)
5178 ERROUT(EBADMSG);
5179
5180 if (! nvlist_exists_bool(nvl, "keep_counters"))
5181 ERROUT(EBADMSG);
5182
5183 V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters");
5184
5185 on_error:
5186 nvlist_destroy(nvl);
5187 free(nvlpacked, M_TEMP);
5188 return (error);
5189 }
5190
5191 static unsigned int
pf_clear_states(const struct pf_kstate_kill * kill)5192 pf_clear_states(const struct pf_kstate_kill *kill)
5193 {
5194 struct pf_state_key_cmp match_key;
5195 struct pf_kstate *s;
5196 struct pfi_kkif *kif;
5197 int idx;
5198 unsigned int killed = 0, dir;
5199
5200 for (unsigned int i = 0; i <= pf_hashmask; i++) {
5201 struct pf_idhash *ih = &V_pf_idhash[i];
5202
5203 relock_DIOCCLRSTATES:
5204 PF_HASHROW_LOCK(ih);
5205 LIST_FOREACH(s, &ih->states, entry) {
5206 /* For floating states look at the original kif. */
5207 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
5208
5209 if (kill->psk_ifname[0] &&
5210 strcmp(kill->psk_ifname,
5211 kif->pfik_name))
5212 continue;
5213
5214 if (kill->psk_kill_match) {
5215 bzero(&match_key, sizeof(match_key));
5216
5217 if (s->direction == PF_OUT) {
5218 dir = PF_IN;
5219 idx = PF_SK_STACK;
5220 } else {
5221 dir = PF_OUT;
5222 idx = PF_SK_WIRE;
5223 }
5224
5225 match_key.af = s->key[idx]->af;
5226 match_key.proto = s->key[idx]->proto;
5227 PF_ACPY(&match_key.addr[0],
5228 &s->key[idx]->addr[1], match_key.af);
5229 match_key.port[0] = s->key[idx]->port[1];
5230 PF_ACPY(&match_key.addr[1],
5231 &s->key[idx]->addr[0], match_key.af);
5232 match_key.port[1] = s->key[idx]->port[0];
5233 }
5234
5235 /*
5236 * Don't send out individual
5237 * delete messages.
5238 */
5239 s->state_flags |= PFSTATE_NOSYNC;
5240 pf_unlink_state(s, PF_ENTER_LOCKED);
5241 killed++;
5242
5243 if (kill->psk_kill_match)
5244 killed += pf_kill_matching_state(&match_key,
5245 dir);
5246
5247 goto relock_DIOCCLRSTATES;
5248 }
5249 PF_HASHROW_UNLOCK(ih);
5250 }
5251
5252 if (V_pfsync_clear_states_ptr != NULL)
5253 V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname);
5254
5255 return (killed);
5256 }
5257
5258 static void
pf_killstates(struct pf_kstate_kill * kill,unsigned int * killed)5259 pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
5260 {
5261 struct pf_kstate *s;
5262
5263 if (kill->psk_pfcmp.id) {
5264 if (kill->psk_pfcmp.creatorid == 0)
5265 kill->psk_pfcmp.creatorid = V_pf_status.hostid;
5266 if ((s = pf_find_state_byid(kill->psk_pfcmp.id,
5267 kill->psk_pfcmp.creatorid))) {
5268 pf_unlink_state(s, PF_ENTER_LOCKED);
5269 *killed = 1;
5270 }
5271 return;
5272 }
5273
5274 for (unsigned int i = 0; i <= pf_hashmask; i++)
5275 *killed += pf_killstates_row(kill, &V_pf_idhash[i]);
5276
5277 return;
5278 }
5279
5280 static int
pf_killstates_nv(struct pfioc_nv * nv)5281 pf_killstates_nv(struct pfioc_nv *nv)
5282 {
5283 struct pf_kstate_kill kill;
5284 nvlist_t *nvl = NULL;
5285 void *nvlpacked = NULL;
5286 int error = 0;
5287 unsigned int killed = 0;
5288
5289 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
5290
5291 if (nv->len > pf_ioctl_maxcount)
5292 ERROUT(ENOMEM);
5293
5294 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
5295 if (nvlpacked == NULL)
5296 ERROUT(ENOMEM);
5297
5298 error = copyin(nv->data, nvlpacked, nv->len);
5299 if (error)
5300 ERROUT(error);
5301
5302 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5303 if (nvl == NULL)
5304 ERROUT(EBADMSG);
5305
5306 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
5307 if (error)
5308 ERROUT(error);
5309
5310 pf_killstates(&kill, &killed);
5311
5312 free(nvlpacked, M_NVLIST);
5313 nvlpacked = NULL;
5314 nvlist_destroy(nvl);
5315 nvl = nvlist_create(0);
5316 if (nvl == NULL)
5317 ERROUT(ENOMEM);
5318
5319 nvlist_add_number(nvl, "killed", killed);
5320
5321 nvlpacked = nvlist_pack(nvl, &nv->len);
5322 if (nvlpacked == NULL)
5323 ERROUT(ENOMEM);
5324
5325 if (nv->size == 0)
5326 ERROUT(0);
5327 else if (nv->size < nv->len)
5328 ERROUT(ENOSPC);
5329
5330 error = copyout(nvlpacked, nv->data, nv->len);
5331
5332 on_error:
5333 nvlist_destroy(nvl);
5334 free(nvlpacked, M_NVLIST);
5335 return (error);
5336 }
5337
5338 static int
pf_clearstates_nv(struct pfioc_nv * nv)5339 pf_clearstates_nv(struct pfioc_nv *nv)
5340 {
5341 struct pf_kstate_kill kill;
5342 nvlist_t *nvl = NULL;
5343 void *nvlpacked = NULL;
5344 int error = 0;
5345 unsigned int killed;
5346
5347 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
5348
5349 if (nv->len > pf_ioctl_maxcount)
5350 ERROUT(ENOMEM);
5351
5352 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
5353 if (nvlpacked == NULL)
5354 ERROUT(ENOMEM);
5355
5356 error = copyin(nv->data, nvlpacked, nv->len);
5357 if (error)
5358 ERROUT(error);
5359
5360 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5361 if (nvl == NULL)
5362 ERROUT(EBADMSG);
5363
5364 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
5365 if (error)
5366 ERROUT(error);
5367
5368 killed = pf_clear_states(&kill);
5369
5370 free(nvlpacked, M_NVLIST);
5371 nvlpacked = NULL;
5372 nvlist_destroy(nvl);
5373 nvl = nvlist_create(0);
5374 if (nvl == NULL)
5375 ERROUT(ENOMEM);
5376
5377 nvlist_add_number(nvl, "killed", killed);
5378
5379 nvlpacked = nvlist_pack(nvl, &nv->len);
5380 if (nvlpacked == NULL)
5381 ERROUT(ENOMEM);
5382
5383 if (nv->size == 0)
5384 ERROUT(0);
5385 else if (nv->size < nv->len)
5386 ERROUT(ENOSPC);
5387
5388 error = copyout(nvlpacked, nv->data, nv->len);
5389
5390 #undef ERROUT
5391 on_error:
5392 nvlist_destroy(nvl);
5393 free(nvlpacked, M_NVLIST);
5394 return (error);
5395 }
5396
5397 static int
pf_getstate(struct pfioc_nv * nv)5398 pf_getstate(struct pfioc_nv *nv)
5399 {
5400 nvlist_t *nvl = NULL, *nvls;
5401 void *nvlpacked = NULL;
5402 struct pf_kstate *s = NULL;
5403 int error = 0;
5404 uint64_t id, creatorid;
5405
5406 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
5407
5408 if (nv->len > pf_ioctl_maxcount)
5409 ERROUT(ENOMEM);
5410
5411 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
5412 if (nvlpacked == NULL)
5413 ERROUT(ENOMEM);
5414
5415 error = copyin(nv->data, nvlpacked, nv->len);
5416 if (error)
5417 ERROUT(error);
5418
5419 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5420 if (nvl == NULL)
5421 ERROUT(EBADMSG);
5422
5423 PFNV_CHK(pf_nvuint64(nvl, "id", &id));
5424 PFNV_CHK(pf_nvuint64(nvl, "creatorid", &creatorid));
5425
5426 s = pf_find_state_byid(id, creatorid);
5427 if (s == NULL)
5428 ERROUT(ENOENT);
5429
5430 free(nvlpacked, M_NVLIST);
5431 nvlpacked = NULL;
5432 nvlist_destroy(nvl);
5433 nvl = nvlist_create(0);
5434 if (nvl == NULL)
5435 ERROUT(ENOMEM);
5436
5437 nvls = pf_state_to_nvstate(s);
5438 if (nvls == NULL)
5439 ERROUT(ENOMEM);
5440
5441 nvlist_add_nvlist(nvl, "state", nvls);
5442 nvlist_destroy(nvls);
5443
5444 nvlpacked = nvlist_pack(nvl, &nv->len);
5445 if (nvlpacked == NULL)
5446 ERROUT(ENOMEM);
5447
5448 if (nv->size == 0)
5449 ERROUT(0);
5450 else if (nv->size < nv->len)
5451 ERROUT(ENOSPC);
5452
5453 error = copyout(nvlpacked, nv->data, nv->len);
5454
5455 #undef ERROUT
5456 errout:
5457 if (s != NULL)
5458 PF_STATE_UNLOCK(s);
5459 free(nvlpacked, M_NVLIST);
5460 nvlist_destroy(nvl);
5461 return (error);
5462 }
5463
5464 /*
5465 * XXX - Check for version missmatch!!!
5466 */
5467
5468 /*
5469 * Duplicate pfctl -Fa operation to get rid of as much as we can.
5470 */
5471 static int
shutdown_pf(void)5472 shutdown_pf(void)
5473 {
5474 int error = 0;
5475 u_int32_t t[5];
5476 char nn = '\0';
5477
5478 do {
5479 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
5480 != 0) {
5481 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
5482 break;
5483 }
5484 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
5485 != 0) {
5486 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
5487 break; /* XXX: rollback? */
5488 }
5489 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
5490 != 0) {
5491 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
5492 break; /* XXX: rollback? */
5493 }
5494 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
5495 != 0) {
5496 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
5497 break; /* XXX: rollback? */
5498 }
5499 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
5500 != 0) {
5501 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
5502 break; /* XXX: rollback? */
5503 }
5504
5505 /* XXX: these should always succeed here */
5506 pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
5507 pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
5508 pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
5509 pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
5510 pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
5511
5512 if ((error = pf_clear_tables()) != 0)
5513 break;
5514
5515 #ifdef ALTQ
5516 if ((error = pf_begin_altq(&t[0])) != 0) {
5517 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
5518 break;
5519 }
5520 pf_commit_altq(t[0]);
5521 #endif
5522
5523 pf_clear_all_states();
5524
5525 pf_clear_srcnodes(NULL);
5526
5527 /* status does not use malloced mem so no need to cleanup */
5528 /* fingerprints and interfaces have their own cleanup code */
5529 } while(0);
5530
5531 return (error);
5532 }
5533
5534 static pfil_return_t
pf_check_return(int chk,struct mbuf ** m)5535 pf_check_return(int chk, struct mbuf **m)
5536 {
5537
5538 switch (chk) {
5539 case PF_PASS:
5540 if (*m == NULL)
5541 return (PFIL_CONSUMED);
5542 else
5543 return (PFIL_PASS);
5544 break;
5545 default:
5546 if (*m != NULL) {
5547 m_freem(*m);
5548 *m = NULL;
5549 }
5550 return (PFIL_DROPPED);
5551 }
5552 }
5553
5554 #ifdef INET
5555 static pfil_return_t
pf_check_in(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)5556 pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
5557 void *ruleset __unused, struct inpcb *inp)
5558 {
5559 int chk;
5560
5561 chk = pf_test(PF_IN, flags, ifp, m, inp);
5562
5563 return (pf_check_return(chk, m));
5564 }
5565
5566 static pfil_return_t
pf_check_out(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)5567 pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
5568 void *ruleset __unused, struct inpcb *inp)
5569 {
5570 int chk;
5571
5572 chk = pf_test(PF_OUT, flags, ifp, m, inp);
5573
5574 return (pf_check_return(chk, m));
5575 }
5576 #endif
5577
5578 #ifdef INET6
5579 static pfil_return_t
pf_check6_in(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)5580 pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
5581 void *ruleset __unused, struct inpcb *inp)
5582 {
5583 int chk;
5584
5585 /*
5586 * In case of loopback traffic IPv6 uses the real interface in
5587 * order to support scoped addresses. In order to support stateful
5588 * filtering we have change this to lo0 as it is the case in IPv4.
5589 */
5590 CURVNET_SET(ifp->if_vnet);
5591 chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp, m, inp);
5592 CURVNET_RESTORE();
5593
5594 return (pf_check_return(chk, m));
5595 }
5596
5597 static pfil_return_t
pf_check6_out(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)5598 pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
5599 void *ruleset __unused, struct inpcb *inp)
5600 {
5601 int chk;
5602
5603 CURVNET_SET(ifp->if_vnet);
5604 chk = pf_test6(PF_OUT, flags, ifp, m, inp);
5605 CURVNET_RESTORE();
5606
5607 return (pf_check_return(chk, m));
5608 }
5609 #endif /* INET6 */
5610
5611 #ifdef INET
5612 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook);
5613 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook);
5614 #define V_pf_ip4_in_hook VNET(pf_ip4_in_hook)
5615 #define V_pf_ip4_out_hook VNET(pf_ip4_out_hook)
5616 #endif
5617 #ifdef INET6
5618 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook);
5619 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook);
5620 #define V_pf_ip6_in_hook VNET(pf_ip6_in_hook)
5621 #define V_pf_ip6_out_hook VNET(pf_ip6_out_hook)
5622 #endif
5623
5624 static void
hook_pf(void)5625 hook_pf(void)
5626 {
5627 struct pfil_hook_args pha;
5628 struct pfil_link_args pla;
5629 int ret;
5630
5631 if (V_pf_pfil_hooked)
5632 return;
5633
5634 pha.pa_version = PFIL_VERSION;
5635 pha.pa_modname = "pf";
5636 pha.pa_ruleset = NULL;
5637
5638 pla.pa_version = PFIL_VERSION;
5639
5640 #ifdef INET
5641 pha.pa_type = PFIL_TYPE_IP4;
5642 pha.pa_func = pf_check_in;
5643 pha.pa_flags = PFIL_IN;
5644 pha.pa_rulname = "default-in";
5645 V_pf_ip4_in_hook = pfil_add_hook(&pha);
5646 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
5647 pla.pa_head = V_inet_pfil_head;
5648 pla.pa_hook = V_pf_ip4_in_hook;
5649 ret = pfil_link(&pla);
5650 MPASS(ret == 0);
5651 pha.pa_func = pf_check_out;
5652 pha.pa_flags = PFIL_OUT;
5653 pha.pa_rulname = "default-out";
5654 V_pf_ip4_out_hook = pfil_add_hook(&pha);
5655 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
5656 pla.pa_head = V_inet_pfil_head;
5657 pla.pa_hook = V_pf_ip4_out_hook;
5658 ret = pfil_link(&pla);
5659 MPASS(ret == 0);
5660 #endif
5661 #ifdef INET6
5662 pha.pa_type = PFIL_TYPE_IP6;
5663 pha.pa_func = pf_check6_in;
5664 pha.pa_flags = PFIL_IN;
5665 pha.pa_rulname = "default-in6";
5666 V_pf_ip6_in_hook = pfil_add_hook(&pha);
5667 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
5668 pla.pa_head = V_inet6_pfil_head;
5669 pla.pa_hook = V_pf_ip6_in_hook;
5670 ret = pfil_link(&pla);
5671 MPASS(ret == 0);
5672 pha.pa_func = pf_check6_out;
5673 pha.pa_rulname = "default-out6";
5674 pha.pa_flags = PFIL_OUT;
5675 V_pf_ip6_out_hook = pfil_add_hook(&pha);
5676 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
5677 pla.pa_head = V_inet6_pfil_head;
5678 pla.pa_hook = V_pf_ip6_out_hook;
5679 ret = pfil_link(&pla);
5680 MPASS(ret == 0);
5681 #endif
5682
5683 V_pf_pfil_hooked = 1;
5684 }
5685
5686 static void
dehook_pf(void)5687 dehook_pf(void)
5688 {
5689
5690 if (V_pf_pfil_hooked == 0)
5691 return;
5692
5693 #ifdef INET
5694 pfil_remove_hook(V_pf_ip4_in_hook);
5695 pfil_remove_hook(V_pf_ip4_out_hook);
5696 #endif
5697 #ifdef INET6
5698 pfil_remove_hook(V_pf_ip6_in_hook);
5699 pfil_remove_hook(V_pf_ip6_out_hook);
5700 #endif
5701
5702 V_pf_pfil_hooked = 0;
5703 }
5704
5705 static void
pf_load_vnet(void)5706 pf_load_vnet(void)
5707 {
5708 V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname),
5709 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
5710
5711 pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize,
5712 PF_RULE_TAG_HASH_SIZE_DEFAULT);
5713 #ifdef ALTQ
5714 pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize,
5715 PF_QUEUE_TAG_HASH_SIZE_DEFAULT);
5716 #endif
5717
5718 pfattach_vnet();
5719 V_pf_vnet_active = 1;
5720 }
5721
5722 static int
pf_load(void)5723 pf_load(void)
5724 {
5725 int error;
5726
5727 rm_init_flags(&pf_rules_lock, "pf rulesets", RM_RECURSE);
5728 sx_init(&pf_ioctl_lock, "pf ioctl");
5729 sx_init(&pf_end_lock, "pf end thread");
5730
5731 pf_mtag_initialize();
5732
5733 pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME);
5734 if (pf_dev == NULL)
5735 return (ENOMEM);
5736
5737 pf_end_threads = 0;
5738 error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
5739 if (error != 0)
5740 return (error);
5741
5742 pfi_initialize();
5743
5744 return (0);
5745 }
5746
5747 static void
pf_unload_vnet(void)5748 pf_unload_vnet(void)
5749 {
5750 int ret;
5751
5752 V_pf_vnet_active = 0;
5753 V_pf_status.running = 0;
5754 dehook_pf();
5755
5756 PF_RULES_WLOCK();
5757 pf_syncookies_cleanup();
5758 shutdown_pf();
5759 PF_RULES_WUNLOCK();
5760
5761 ret = swi_remove(V_pf_swi_cookie);
5762 MPASS(ret == 0);
5763 ret = intr_event_destroy(V_pf_swi_ie);
5764 MPASS(ret == 0);
5765
5766 pf_unload_vnet_purge();
5767
5768 pf_normalize_cleanup();
5769 PF_RULES_WLOCK();
5770 pfi_cleanup_vnet();
5771 PF_RULES_WUNLOCK();
5772 pfr_cleanup();
5773 pf_osfp_flush();
5774 pf_cleanup();
5775 if (IS_DEFAULT_VNET(curvnet))
5776 pf_mtag_cleanup();
5777
5778 pf_cleanup_tagset(&V_pf_tags);
5779 #ifdef ALTQ
5780 pf_cleanup_tagset(&V_pf_qids);
5781 #endif
5782 uma_zdestroy(V_pf_tag_z);
5783
5784 #ifdef PF_WANT_32_TO_64_COUNTER
5785 PF_RULES_WLOCK();
5786 LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
5787
5788 MPASS(LIST_EMPTY(&V_pf_allkiflist));
5789 MPASS(V_pf_allkifcount == 0);
5790
5791 LIST_REMOVE(&V_pf_default_rule, allrulelist);
5792 V_pf_allrulecount--;
5793 LIST_REMOVE(V_pf_rulemarker, allrulelist);
5794
5795 /*
5796 * There are known pf rule leaks when running the test suite.
5797 */
5798 #ifdef notyet
5799 MPASS(LIST_EMPTY(&V_pf_allrulelist));
5800 MPASS(V_pf_allrulecount == 0);
5801 #endif
5802
5803 PF_RULES_WUNLOCK();
5804
5805 free(V_pf_kifmarker, PFI_MTYPE);
5806 free(V_pf_rulemarker, M_PFRULE);
5807 #endif
5808
5809 /* Free counters last as we updated them during shutdown. */
5810 pf_counter_u64_deinit(&V_pf_default_rule.evaluations);
5811 for (int i = 0; i < 2; i++) {
5812 pf_counter_u64_deinit(&V_pf_default_rule.packets[i]);
5813 pf_counter_u64_deinit(&V_pf_default_rule.bytes[i]);
5814 }
5815 counter_u64_free(V_pf_default_rule.states_cur);
5816 counter_u64_free(V_pf_default_rule.states_tot);
5817 counter_u64_free(V_pf_default_rule.src_nodes);
5818
5819 for (int i = 0; i < PFRES_MAX; i++)
5820 counter_u64_free(V_pf_status.counters[i]);
5821 for (int i = 0; i < KLCNT_MAX; i++)
5822 counter_u64_free(V_pf_status.lcounters[i]);
5823 for (int i = 0; i < FCNT_MAX; i++)
5824 pf_counter_u64_deinit(&V_pf_status.fcounters[i]);
5825 for (int i = 0; i < SCNT_MAX; i++)
5826 counter_u64_free(V_pf_status.scounters[i]);
5827 }
5828
5829 static void
pf_unload(void)5830 pf_unload(void)
5831 {
5832
5833 sx_xlock(&pf_end_lock);
5834 pf_end_threads = 1;
5835 while (pf_end_threads < 2) {
5836 wakeup_one(pf_purge_thread);
5837 sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
5838 }
5839 sx_xunlock(&pf_end_lock);
5840
5841 if (pf_dev != NULL)
5842 destroy_dev(pf_dev);
5843
5844 pfi_cleanup();
5845
5846 rm_destroy(&pf_rules_lock);
5847 sx_destroy(&pf_ioctl_lock);
5848 sx_destroy(&pf_end_lock);
5849 }
5850
5851 static void
vnet_pf_init(void * unused __unused)5852 vnet_pf_init(void *unused __unused)
5853 {
5854
5855 pf_load_vnet();
5856 }
5857 VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
5858 vnet_pf_init, NULL);
5859
5860 static void
vnet_pf_uninit(const void * unused __unused)5861 vnet_pf_uninit(const void *unused __unused)
5862 {
5863
5864 pf_unload_vnet();
5865 }
5866 SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
5867 VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
5868 vnet_pf_uninit, NULL);
5869
5870 static int
pf_modevent(module_t mod,int type,void * data)5871 pf_modevent(module_t mod, int type, void *data)
5872 {
5873 int error = 0;
5874
5875 switch(type) {
5876 case MOD_LOAD:
5877 error = pf_load();
5878 break;
5879 case MOD_UNLOAD:
5880 /* Handled in SYSUNINIT(pf_unload) to ensure it's done after
5881 * the vnet_pf_uninit()s */
5882 break;
5883 default:
5884 error = EINVAL;
5885 break;
5886 }
5887
5888 return (error);
5889 }
5890
5891 static moduledata_t pf_mod = {
5892 "pf",
5893 pf_modevent,
5894 0
5895 };
5896
5897 DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
5898 MODULE_VERSION(pf, PF_MODVER);
5899